Commit 28c443c3 authored by Nick's avatar Nick

feat: admin dashboard recent pages + update deps

parent 3b02d701
...@@ -54,24 +54,31 @@ ...@@ -54,24 +54,31 @@
.body-2(v-else) {{$t('admin:dashboard.versionNew', { version: info.latestVersion })}} .body-2(v-else) {{$t('admin:dashboard.versionNew', { version: info.latestVersion })}}
v-flex(xs12, xl6) v-flex(xs12, xl6)
v-card.radius-7.animated.fadeInUp.wait-p2s v-card.radius-7.animated.fadeInUp.wait-p2s
v-card-title.subtitle-1(:class='$vuetify.theme.dark ? `grey darken-2` : `grey lighten-5`') Recent Pages v-toolbar(:color='$vuetify.theme.dark ? `grey darken-2` : `grey lighten-5`', dense, flat)
v-spacer
.overline Recent Pages
v-spacer
v-data-table.pb-2( v-data-table.pb-2(
:items='recentPages' :items='recentPages'
:headers='headers'
:loading='recentPagesLoading'
hide-default-footer hide-default-footer
hide-default-header hide-default-header
) )
template(slot='items' slot-scope='props') template(slot='item', slot-scope='props')
td(width='20', style='padding-right: 0;'): v-icon insert_drive_file tr.is-clickable(:active='props.selected', @click='$router.push(`/pages/` + props.item.id)')
td td
.body-2.primary--text {{ props.item.title }} .body-2: strong {{ props.item.title }}
.caption.grey--text.text--darken-2 {{ props.item.description }} td.admin-pages-path
td.caption /{{ props.item.path }} v-chip(label, small, :color='$vuetify.theme.dark ? `grey darken-4` : `grey lighten-4`') {{ props.item.locale }}
td.grey--text.text--darken-2(width='250') span.ml-2.grey--text(:class='$vuetify.theme.dark ? `text--lighten-1` : `text--darken-2`') / {{ props.item.path }}
.caption: strong Updated {{ props.item.updatedAt | moment('from') }} td.text-right(width='250') {{ props.item.updatedAt | moment('calendar') }}
.caption Created {{ props.item.createdAt | moment('calendar') }}
v-flex(xs12, xl6) v-flex(xs12, xl6)
v-card.radius-7.animated.fadeInUp.wait-p4s v-card.radius-7.animated.fadeInUp.wait-p4s
v-card-title.subtitle-1(:class='$vuetify.theme.dark ? `grey darken-2` : `grey lighten-5`') Most Popular Pages v-toolbar(:color='$vuetify.theme.dark ? `grey darken-2` : `grey lighten-5`', dense, flat)
v-spacer
.overline Most Popular Pages
v-spacer
v-data-table.pb-2( v-data-table.pb-2(
:items='popularPages' :items='popularPages'
hide-default-footer hide-default-footer
...@@ -105,6 +112,8 @@ import _ from 'lodash' ...@@ -105,6 +112,8 @@ import _ from 'lodash'
import AnimatedNumber from 'animated-number-vue' import AnimatedNumber from 'animated-number-vue'
import { get } from 'vuex-pathify' import { get } from 'vuex-pathify'
import recentPagesQuery from 'gql/admin/dashboard/dashboard-query-recentpages.gql'
export default { export default {
components: { components: {
AnimatedNumber AnimatedNumber
...@@ -112,7 +121,14 @@ export default { ...@@ -112,7 +121,14 @@ export default {
data() { data() {
return { return {
recentPages: [], recentPages: [],
popularPages: [] recentPagesLoading: false,
popularPages: [],
headers: [
{ text: 'ID', value: 'id', width: 80 },
{ text: 'Title', value: 'title' },
{ text: 'Path', value: 'path' },
{ text: 'Last Updated', value: 'updatedAt', width: 250 }
]
} }
}, },
computed: { computed: {
...@@ -133,6 +149,16 @@ export default { ...@@ -133,6 +149,16 @@ export default {
return _.includes(this.permissions, prm) return _.includes(this.permissions, prm)
} }
} }
},
apollo: {
recentPages: {
query: recentPagesQuery,
update: (data) => data.pages.list,
watchLoading (isLoading) {
this.recentPagesLoading = isLoading
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-dashboard-recentpages')
}
}
} }
} }
</script> </script>
......
...@@ -78,7 +78,7 @@ export default { ...@@ -78,7 +78,7 @@ export default {
pageCount: 0, pageCount: 0,
groups: [], groups: [],
headers: [ headers: [
{ text: 'ID', value: 'id', width: 50, align: 'right' }, { text: 'ID', value: 'id', width: 80, sortable: true },
{ text: 'Name', value: 'name' }, { text: 'Name', value: 'name' },
{ text: 'Users', value: 'userCount', width: 200 }, { text: 'Users', value: 'userCount', width: 200 },
{ text: 'Created', value: 'createdAt', width: 250 }, { text: 'Created', value: 'createdAt', width: 250 },
......
...@@ -187,7 +187,7 @@ export default { ...@@ -187,7 +187,7 @@ export default {
align: 'center', align: 'center',
value: 'availability', value: 'availability',
sortable: false, sortable: false,
width: 100 width: 120
}, },
{ {
text: this.$t('admin:locale.download'), text: this.$t('admin:locale.download'),
......
...@@ -56,11 +56,11 @@ ...@@ -56,11 +56,11 @@
tr.is-clickable(:active='props.selected', @click='$router.push(`/pages/` + props.item.id)') tr.is-clickable(:active='props.selected', @click='$router.push(`/pages/` + props.item.id)')
td.text-xs-right {{ props.item.id }} td.text-xs-right {{ props.item.id }}
td td
.body-2 {{ props.item.title }} .body-2: strong {{ props.item.title }}
.caption {{ props.item.description }} .caption {{ props.item.description }}
td.admin-pages-path td.admin-pages-path
v-chip(label, small, :color='$vuetify.theme.dark ? `grey darken-4` : `grey lighten-4`') {{ props.item.locale }} v-chip(label, small, :color='$vuetify.theme.dark ? `grey darken-4` : `grey lighten-4`') {{ props.item.locale }}
span.ml-2.grey--text(:class='$vuetify.theme.dark ? `text--lighten-1` : `text--darken-2`') {{ props.item.path }} span.ml-2.grey--text(:class='$vuetify.theme.dark ? `text--lighten-1` : `text--darken-2`') / {{ props.item.path }}
td {{ props.item.createdAt | moment('calendar') }} td {{ props.item.createdAt | moment('calendar') }}
td {{ props.item.updatedAt | moment('calendar') }} td {{ props.item.updatedAt | moment('calendar') }}
template(slot='no-data') template(slot='no-data')
...@@ -80,7 +80,7 @@ export default { ...@@ -80,7 +80,7 @@ export default {
pagination: 1, pagination: 1,
pages: [], pages: [],
headers: [ headers: [
{ text: 'ID', value: 'id', width: 50, align: 'right' }, { text: 'ID', value: 'id', width: 80, sortable: true },
{ text: 'Title', value: 'title' }, { text: 'Title', value: 'title' },
{ text: 'Path', value: 'path' }, { text: 'Path', value: 'path' },
{ text: 'Created', value: 'createdAt', width: 250 }, { text: 'Created', value: 'createdAt', width: 250 },
......
query {
pages {
list(limit: 10, orderBy: UPDATED, orderByDirection: DESC) {
id
locale
path
title
description
contentType
isPublished
isPrivate
privateNS
createdAt
updatedAt
}
}
}
...@@ -3,7 +3,6 @@ const path = require('path') ...@@ -3,7 +3,6 @@ const path = require('path')
const fs = require('fs-extra') const fs = require('fs-extra')
const yargs = require('yargs').argv const yargs = require('yargs').argv
const _ = require('lodash') const _ = require('lodash')
const Fiber = require('fibers')
const { VueLoaderPlugin } = require('vue-loader') const { VueLoaderPlugin } = require('vue-loader')
const CopyWebpackPlugin = require('copy-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin')
...@@ -85,7 +84,6 @@ module.exports = { ...@@ -85,7 +84,6 @@ module.exports = {
loader: 'sass-loader', loader: 'sass-loader',
options: { options: {
implementation: require('sass'), implementation: require('sass'),
fiber: Fiber,
sourceMap: false sourceMap: false
} }
} }
...@@ -107,7 +105,6 @@ module.exports = { ...@@ -107,7 +105,6 @@ module.exports = {
loader: 'sass-loader', loader: 'sass-loader',
options: { options: {
implementation: require('sass'), implementation: require('sass'),
fiber: Fiber,
sourceMap: false sourceMap: false
} }
}, },
......
...@@ -3,7 +3,6 @@ const path = require('path') ...@@ -3,7 +3,6 @@ const path = require('path')
const fs = require('fs-extra') const fs = require('fs-extra')
const yargs = require('yargs').argv const yargs = require('yargs').argv
const _ = require('lodash') const _ = require('lodash')
const Fiber = require('fibers')
const { VueLoaderPlugin } = require('vue-loader') const { VueLoaderPlugin } = require('vue-loader')
const { CleanWebpackPlugin } = require('clean-webpack-plugin') const { CleanWebpackPlugin } = require('clean-webpack-plugin')
...@@ -88,7 +87,6 @@ module.exports = { ...@@ -88,7 +87,6 @@ module.exports = {
loader: 'sass-loader', loader: 'sass-loader',
options: { options: {
implementation: require('sass'), implementation: require('sass'),
fiber: Fiber,
sourceMap: false sourceMap: false
} }
} }
...@@ -111,7 +109,6 @@ module.exports = { ...@@ -111,7 +109,6 @@ module.exports = {
loader: 'sass-loader', loader: 'sass-loader',
options: { options: {
implementation: require('sass'), implementation: require('sass'),
fiber: Fiber,
sourceMap: false sourceMap: false
} }
}, },
......
...@@ -37,12 +37,12 @@ ...@@ -37,12 +37,12 @@
"@aoberoi/passport-slack": "1.0.5", "@aoberoi/passport-slack": "1.0.5",
"@bugsnag/js": "6.4.0", "@bugsnag/js": "6.4.0",
"@exlinc/keycloak-passport": "1.0.2", "@exlinc/keycloak-passport": "1.0.2",
"algoliasearch": "3.33.0", "algoliasearch": "3.34.0",
"apollo-fetch": "0.7.0", "apollo-fetch": "0.7.0",
"apollo-server": "2.9.0", "apollo-server": "2.9.2",
"apollo-server-express": "2.9.0", "apollo-server-express": "2.9.2",
"auto-load": "3.0.4", "auto-load": "3.0.4",
"aws-sdk": "2.518.0", "aws-sdk": "2.521.0",
"axios": "0.19.0", "axios": "0.19.0",
"azure-search-client": "3.1.5", "azure-search-client": "3.1.5",
"bcryptjs-then": "1.0.1", "bcryptjs-then": "1.0.1",
...@@ -72,13 +72,13 @@ ...@@ -72,13 +72,13 @@
"filesize": "4.1.2", "filesize": "4.1.2",
"fs-extra": "8.1.0", "fs-extra": "8.1.0",
"getos": "3.1.1", "getos": "3.1.1",
"graphql": "14.5.3", "graphql": "14.5.4",
"graphql-list-fields": "2.0.2", "graphql-list-fields": "2.0.2",
"graphql-rate-limit-directive": "1.1.0", "graphql-rate-limit-directive": "1.1.0",
"graphql-subscriptions": "1.1.0", "graphql-subscriptions": "1.1.0",
"graphql-tools": "4.0.5", "graphql-tools": "4.0.5",
"highlight.js": "9.15.10", "highlight.js": "9.15.10",
"i18next": "17.0.12", "i18next": "17.0.13",
"i18next-express-middleware": "1.8.1", "i18next-express-middleware": "1.8.1",
"i18next-node-fs-backend": "2.1.3", "i18next-node-fs-backend": "2.1.3",
"image-size": "0.7.4", "image-size": "0.7.4",
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
"js-yaml": "3.13.1", "js-yaml": "3.13.1",
"jsonwebtoken": "8.5.1", "jsonwebtoken": "8.5.1",
"klaw": "3.0.0", "klaw": "3.0.0",
"knex": "0.19.2", "knex": "0.19.3",
"lodash": "4.17.15", "lodash": "4.17.15",
"markdown-it": "9.1.0", "markdown-it": "9.1.0",
"markdown-it-abbr": "1.0.4", "markdown-it-abbr": "1.0.4",
...@@ -107,11 +107,11 @@ ...@@ -107,11 +107,11 @@
"mime-types": "2.1.24", "mime-types": "2.1.24",
"moment": "2.24.0", "moment": "2.24.0",
"moment-timezone": "0.5.26", "moment-timezone": "0.5.26",
"mongodb": "3.3.1", "mongodb": "3.3.2",
"mssql": "5.1.0", "mssql": "5.1.0",
"multer": "1.4.2", "multer": "1.4.2",
"mysql2": "1.6.5", "mysql2": "1.7.0",
"nanoid": "2.0.4", "nanoid": "2.1.0",
"node-2fa": "1.1.2", "node-2fa": "1.1.2",
"node-cache": "4.2.1", "node-cache": "4.2.1",
"nodemailer": "6.3.0", "nodemailer": "6.3.0",
...@@ -148,10 +148,10 @@ ...@@ -148,10 +148,10 @@
"request-promise": "4.2.4", "request-promise": "4.2.4",
"safe-regex": "2.0.2", "safe-regex": "2.0.2",
"sanitize-filename": "1.6.3", "sanitize-filename": "1.6.3",
"scim-query-filter-parser": "1.1.0", "scim-query-filter-parser": "1.1.1",
"semver": "6.3.0", "semver": "6.3.0",
"serve-favicon": "2.5.0", "serve-favicon": "2.5.0",
"simple-git": "1.124.0", "simple-git": "1.126.0",
"solr-node": "1.2.1", "solr-node": "1.2.1",
"sqlite3": "4.1.0", "sqlite3": "4.1.0",
"striptags": "3.1.1", "striptags": "3.1.1",
...@@ -212,17 +212,17 @@ ...@@ -212,17 +212,17 @@
"cssnano": "4.1.10", "cssnano": "4.1.10",
"duplicate-package-checker-webpack-plugin": "3.0.0", "duplicate-package-checker-webpack-plugin": "3.0.0",
"epic-spinners": "1.1.0", "epic-spinners": "1.1.0",
"eslint": "6.2.2", "eslint": "6.3.0",
"eslint-config-requarks": "1.0.7", "eslint-config-requarks": "1.0.7",
"eslint-config-standard": "14.0.1", "eslint-config-standard": "14.1.0",
"eslint-plugin-import": "2.18.2", "eslint-plugin-import": "2.18.2",
"eslint-plugin-node": "9.1.0", "eslint-plugin-node": "9.2.0",
"eslint-plugin-promise": "4.2.1", "eslint-plugin-promise": "4.2.1",
"eslint-plugin-standard": "4.0.1", "eslint-plugin-standard": "4.0.1",
"eslint-plugin-vue": "5.2.3", "eslint-plugin-vue": "5.2.3",
"fibers": "4.0.1", "fibers": "4.0.1",
"file-loader": "4.2.0", "file-loader": "4.2.0",
"filepond": "4.5.0", "filepond": "4.5.1",
"filepond-plugin-file-validate-type": "1.2.4", "filepond-plugin-file-validate-type": "1.2.4",
"filesize.js": "1.0.2", "filesize.js": "1.0.2",
"grapesjs": "0.15.3", "grapesjs": "0.15.3",
...@@ -259,7 +259,7 @@ ...@@ -259,7 +259,7 @@
"react-dom": "16.9.0", "react-dom": "16.9.0",
"resolve-url-loader": "3.1.0", "resolve-url-loader": "3.1.0",
"sass": "1.22.10", "sass": "1.22.10",
"sass-loader": "7.3.1", "sass-loader": "8.0.0",
"sass-resources-loader": "2.0.1", "sass-resources-loader": "2.0.1",
"script-ext-html-webpack-plugin": "2.1.4", "script-ext-html-webpack-plugin": "2.1.4",
"simple-progress-webpack-plugin": "1.1.2", "simple-progress-webpack-plugin": "1.1.2",
...@@ -280,7 +280,7 @@ ...@@ -280,7 +280,7 @@
"vue-loader": "15.7.1", "vue-loader": "15.7.1",
"vue-material-design-icons": "3.4.0", "vue-material-design-icons": "3.4.0",
"vue-moment": "4.0.0", "vue-moment": "4.0.0",
"vue-router": "3.1.2", "vue-router": "3.1.3",
"vue-simple-breakpoints": "1.0.3", "vue-simple-breakpoints": "1.0.3",
"vue-status-indicator": "1.2.1", "vue-status-indicator": "1.2.1",
"vue-template-compiler": "2.6.10", "vue-template-compiler": "2.6.10",
...@@ -288,17 +288,17 @@ ...@@ -288,17 +288,17 @@
"vue2-animate": "2.1.2", "vue2-animate": "2.1.2",
"vuedraggable": "2.23.0", "vuedraggable": "2.23.0",
"vuescroll": "4.14.0", "vuescroll": "4.14.0",
"vuetify": "2.0.10", "vuetify": "2.0.11",
"vuetify-loader": "1.3.0", "vuetify-loader": "1.3.0",
"vuex": "3.1.1", "vuex": "3.1.1",
"vuex-pathify": "1.2.4", "vuex-pathify": "1.2.4",
"vuex-persistedstate": "2.5.4", "vuex-persistedstate": "2.5.4",
"webpack": "4.39.2", "webpack": "4.39.3",
"webpack-bundle-analyzer": "3.4.1", "webpack-bundle-analyzer": "3.4.1",
"webpack-cli": "3.3.7", "webpack-cli": "3.3.7",
"webpack-dev-middleware": "3.7.0", "webpack-dev-middleware": "3.7.0",
"webpack-hot-middleware": "2.25.0", "webpack-hot-middleware": "2.25.0",
"webpack-merge": "4.2.1", "webpack-merge": "4.2.2",
"webpack-subresource-integrity": "1.3.2", "webpack-subresource-integrity": "1.3.2",
"webpackbar": "4.0.0", "webpackbar": "4.0.0",
"whatwg-fetch": "3.0.0", "whatwg-fetch": "3.0.0",
......
...@@ -41,7 +41,29 @@ module.exports = { ...@@ -41,7 +41,29 @@ module.exports = {
'contentType', 'contentType',
'createdAt', 'createdAt',
'updatedAt' 'updatedAt'
]) ]).modify(queryBuilder => {
if (args.limit) {
queryBuilder.limit(args.limit)
}
const orderDir = args.orderByDirection === 'DESC' ? 'desc' : 'asc'
switch (args.orderBy) {
case 'CREATED':
queryBuilder.orderBy('createdAt', orderDir)
break
case 'PATH':
queryBuilder.orderBy('path', orderDir)
break
case 'TITLE':
queryBuilder.orderBy('title', orderDir)
break
case 'UPDATED':
queryBuilder.orderBy('updatedAt', orderDir)
break
default:
queryBuilder.orderBy('id', orderDir)
break
}
})
}, },
async single (obj, args, context, info) { async single (obj, args, context, info) {
let page = await WIKI.models.pages.getPageFromDb(args.id) let page = await WIKI.models.pages.getPageFromDb(args.id)
......
...@@ -27,7 +27,11 @@ type PageQuery { ...@@ -27,7 +27,11 @@ type PageQuery {
locale: String locale: String
): PageSearchResponse! @auth(requires: ["manage:system", "read:pages"]) ): PageSearchResponse! @auth(requires: ["manage:system", "read:pages"])
list: [PageListItem!]! @auth(requires: ["manage:system"]) list(
limit: Int
orderBy: PageOrderBy
orderByDirection: PageOrderByDirection
): [PageListItem!]! @auth(requires: ["manage:system"])
single( single(
id: Int! id: Int!
...@@ -163,3 +167,16 @@ type PageListItem { ...@@ -163,3 +167,16 @@ type PageListItem {
createdAt: Date! createdAt: Date!
updatedAt: Date! updatedAt: Date!
} }
enum PageOrderBy {
CREATED
ID
PATH
TITLE
UPDATED
}
enum PageOrderByDirection {
ASC
DESC
}
This diff was suppressed by a .gitattributes entry.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment