|
|
<template lang='pug'> v-container(fluid, grid-list-lg) v-layout(row, wrap) v-flex(xs12) .admin-header img.animated.fadeInUp(src='/_assets/svg/icon-browse-page.svg', alt='Dashboard', style='width: 80px;') .admin-header-title .headline.primary--text.animated.fadeInLeft {{ $t('admin:dashboard.title') }} .subtitle-1.grey--text.animated.fadeInLeft.wait-p2s {{ $t('admin:dashboard.subtitle') }} v-flex(xs12 md6 lg4 xl3 d-flex) v-card.primary.dashboard-card.animated.fadeInUp(dark) v-card-text v-icon.dashboard-icon mdi-file-document-outline .overline {{$t('admin:dashboard.pages')}} animated-number.display-1( :value='info.pagesTotal' :duration='2000' :formatValue='round' easing='easeOutQuint' ) v-flex(xs12 md6 lg4 xl3 d-flex) v-card.blue.darken-3.dashboard-card.animated.fadeInUp.wait-p2s(dark) v-card-text v-icon.dashboard-icon mdi-account .overline {{$t('admin:dashboard.users')}} animated-number.display-1( :value='info.usersTotal' :duration='2000' :formatValue='round' easing='easeOutQuint' ) v-flex(xs12 md6 lg4 xl3 d-flex) v-card.blue.darken-4.dashboard-card.animated.fadeInUp.wait-p4s(dark) v-card-text v-icon.dashboard-icon mdi-account-group .overline {{$t('admin:dashboard.groups')}} animated-number.display-1( :value='info.groupsTotal' :duration='2000' :formatValue='round' easing='easeOutQuint' ) v-flex(xs12 md6 lg12 xl3 d-flex) v-card.dashboard-card.animated.fadeInUp.wait-p6s( :class='isLatestVersion ? "green" : "red lighten-2"' dark ) v-btn.btn-animate-wrench(fab, absolute, :right='!$vuetify.rtl', :left='$vuetify.rtl', top, small, light, to='system', v-if='hasPermission(`manage:system`)') v-icon(:color='isLatestVersion ? `green` : `red darken-4`', small) mdi-wrench v-card-text v-icon.dashboard-icon mdi-blur .subtitle-1 Wiki.js {{info.currentVersion}} .body-2(v-if='isLatestVersion') {{$t('admin:dashboard.versionLatest')}} .body-2(v-else) {{$t('admin:dashboard.versionNew', { version: info.latestVersion })}} v-flex(xs12, xl6) v-card.radius-7.animated.fadeInUp.wait-p2s v-toolbar(:color='$vuetify.theme.dark ? `grey darken-2` : `grey lighten-5`', dense, flat) v-spacer .overline {{$t('admin:dashboard.recentPages')}} v-spacer v-data-table.pb-2( :items='recentPages' :headers='recentPagesHeaders' :loading='recentPagesLoading' hide-default-footer hide-default-header ) template(slot='item', slot-scope='props') tr.is-clickable(:active='props.selected', @click='$router.push(`/pages/` + props.item.id)') td .body-2: strong {{ props.item.title }} td.admin-pages-path 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 }} td.text-right.caption(width='250') {{ props.item.updatedAt | moment('calendar') }} v-flex(xs12, xl6) v-card.radius-7.animated.fadeInUp.wait-p4s v-toolbar(:color='$vuetify.theme.dark ? `grey darken-2` : `grey lighten-5`', dense, flat) v-spacer .overline {{$t('admin:dashboard.lastLogins')}} v-spacer v-data-table.pb-2( :items='lastLogins' :headers='lastLoginsHeaders' :loading='lastLoginsLoading' hide-default-footer hide-default-header ) template(slot='item', slot-scope='props') tr.is-clickable(:active='props.selected', @click='$router.push(`/users/` + props.item.id)') td .body-2: strong {{ props.item.name }} td.text-right.caption(width='250') {{ props.item.lastLoginAt | moment('calendar') }}
v-flex(xs12) v-card.dashboard-contribute.animated.fadeInUp.wait-p4s v-card-text img(src='/_assets/svg/icon-heart-health.svg', alt='Contribute', style='height: 80px;') .pl-5 .subtitle-1 {{$t('admin:contribute.title')}} .body-2.mt-3: strong {{$t('admin:dashboard.contributeSubtitle')}} .body-2 {{$t('admin:dashboard.contributeHelp')}} v-btn.mx-0.mt-4(:color='$vuetify.theme.dark ? `indigo lighten-3` : `indigo`', outlined, small, to='/contribute') .caption: strong {{$t('admin:dashboard.contributeLearnMore')}}
</template>
<script> import _ from 'lodash' import AnimatedNumber from 'animated-number-vue' import { get } from 'vuex-pathify' import gql from 'graphql-tag' import semverLte from 'semver/functions/lte'
export default { components: { AnimatedNumber }, data() { return { recentPages: [], recentPagesLoading: false, recentPagesHeaders: [ { text: 'Title', value: 'title' }, { text: 'Path', value: 'path' }, { text: 'Last Updated', value: 'updatedAt', width: 250 } ], lastLogins: [], lastLoginsLoading: false, lastLoginsHeaders: [ { text: 'User', value: 'displayName' }, { text: 'Last Login', value: 'lastLoginAt', width: 250 } ] } }, computed: { isLatestVersion() { return semverLte(this.info.latestVersion, this.info.currentVersion) }, info: get('admin/info'), permissions: get('user/permissions') }, methods: { round(val) { return Math.round(val) }, hasPermission(prm) { if (_.isArray(prm)) { return _.some(prm, p => { return _.includes(this.permissions, p) }) } else { return _.includes(this.permissions, prm) } } }, apollo: { recentPages: { query: gql`
query { pages { list(limit: 10, orderBy: UPDATED, orderByDirection: DESC) { id locale path title description contentType isPublished isPrivate privateNS createdAt updatedAt } } } `,
update: (data) => data.pages.list, watchLoading (isLoading) { this.recentPagesLoading = isLoading this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-dashboard-recentpages') } }, lastLogins: { query: gql`
query { users { lastLogins { id name lastLoginAt } } } `,
fetchPolicy: 'network-only', update: (data) => data.users.lastLogins, watchLoading (isLoading) { this.lastLoginsLoading = isLoading this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-dashboard-lastlogins') } } } } </script>
<style lang='scss'>
.dashboard-card { display: flex; width: 100%; border-radius: 7px;
.v-card__text { overflow: hidden; position: relative; } }
.dashboard-contribute { background-color: #FFF; background-image: linear-gradient(to bottom, #FFF 0%, lighten(mc('indigo', '50'), 3%) 100%); border-radius: 7px;
@at-root .theme--dark & { background-color: mc('grey', '800'); background-image: linear-gradient(to bottom, mc('grey', '800') 0%, darken(mc('grey', '800'), 6%) 100%); }
.v-card__text { display: flex; align-items: center; color: mc('indigo', '500') !important;
@at-root .theme--dark & { color: mc('grey', '300') !important; } } }
.v-icon.dashboard-icon { position: absolute !important; right: 0; top: 12px; font-size: 100px !important; opacity: .25;
@at-root .v-application--is-rtl & { left: 0; right: initial; } }
</style>
|