admin-dashboard.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <template lang='pug'>
  2. v-card(tile, flat :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"')
  3. .pa-3.pt-4
  4. .headline.primary--text {{ $t('admin:dashboard.title') }}
  5. .subheading.grey--text {{ $t('admin:dashboard.subtitle') }}
  6. v-container(fluid, grid-list-lg)
  7. v-layout(row, wrap)
  8. v-flex(xs12 md6 lg4 xl3 d-flex)
  9. v-card.primary.dashboard-card(dark)
  10. v-card-text
  11. v-icon.dashboard-icon insert_drive_file
  12. .subheading Pages
  13. animated-number.display-1(
  14. :value='info.pagesTotal'
  15. :duration='2000'
  16. :formatValue='round'
  17. easing='easeOutQuint'
  18. )
  19. v-flex(xs12 md6 lg4 xl3 d-flex)
  20. v-card.indigo.lighten-1.dashboard-card(dark)
  21. v-card-text
  22. v-icon.dashboard-icon person
  23. .subheading Users
  24. animated-number.display-1(
  25. :value='info.usersTotal'
  26. :duration='2000'
  27. :formatValue='round'
  28. easing='easeOutQuint'
  29. )
  30. v-flex(xs12 md6 lg4 xl3 d-flex)
  31. v-card.indigo.lighten-2.dashboard-card(dark)
  32. v-card-text
  33. v-icon.dashboard-icon people
  34. .subheading Groups
  35. animated-number.display-1(
  36. :value='info.groupsTotal'
  37. :duration='2000'
  38. :formatValue='round'
  39. easing='easeOutQuint'
  40. )
  41. v-flex(xs12 md6 lg12 xl3 d-flex)
  42. v-card.dashboard-card(
  43. :class='isLatestVersion ? "teal lighten-2" : "red lighten-2"'
  44. dark
  45. )
  46. v-btn(fab, absolute, right, top, small, light, to='system')
  47. v-icon(v-if='isLatestVersion', color='teal') build
  48. v-icon(v-else, color='red darken-4') get_app
  49. v-card-text
  50. v-icon.dashboard-icon blur_on
  51. .subheading Wiki.js {{info.currentVersion}}
  52. .body-2(v-if='isLatestVersion') You are running the latest version.
  53. .body-2(v-else) A new version is available: {{info.latestVersion}}
  54. v-flex(xs12)
  55. v-card
  56. v-card-title.subheading Recent Pages
  57. v-data-table.pb-2(
  58. :items='recentPages'
  59. hide-actions
  60. hide-headers
  61. )
  62. template(slot='items' slot-scope='props')
  63. td(width='20', style='padding-right: 0;'): v-icon insert_drive_file
  64. td
  65. .body-2.primary--text {{ props.item.title }}
  66. .caption.grey--text.text--darken-2 {{ props.item.description }}
  67. td.caption /{{ props.item.path }}
  68. td.grey--text.text--darken-2(width='250')
  69. .caption: strong Updated {{ props.item.updatedAt | moment('from') }}
  70. .caption Created {{ props.item.createdAt | moment('calendar') }}
  71. v-flex(xs12)
  72. v-card
  73. v-card-title.subheading Most Popular Pages
  74. v-data-table.pb-2(
  75. :items='popularPages'
  76. hide-actions
  77. hide-headers
  78. )
  79. template(slot='items' slot-scope='props')
  80. td(width='20', style='padding-right: 0;'): v-icon insert_drive_file
  81. td
  82. .body-2.primary--text {{ props.item.title }}
  83. .caption.grey--text.text--darken-2 {{ props.item.description }}
  84. td.caption /{{ props.item.path }}
  85. td.grey--text.text--darken-2(width='250')
  86. .caption: strong Updated {{ props.item.updatedAt | moment('from') }}
  87. .caption Created {{ props.item.createdAt | moment('calendar') }}
  88. </template>
  89. <script>
  90. import AnimatedNumber from 'animated-number-vue'
  91. import statsQuery from 'gql/admin/dashboard/dashboard-query-stats.gql'
  92. export default {
  93. components: {
  94. AnimatedNumber
  95. },
  96. data() {
  97. return {
  98. info: {
  99. currentVersion: 'n/a',
  100. latestVersion: 'n/a',
  101. groupsTotal: 0,
  102. pagesTotal: 0,
  103. usersTotal: 0
  104. },
  105. recentPages: [],
  106. popularPages: []
  107. }
  108. },
  109. computed: {
  110. isLatestVersion() {
  111. return this.info.currentVersion === this.info.latestVersion
  112. }
  113. },
  114. methods: {
  115. round(val) { return Math.round(val) }
  116. },
  117. apollo: {
  118. info: {
  119. query: statsQuery,
  120. fetchPolicy: 'network-only',
  121. update: (data) => data.system.info,
  122. watchLoading (isLoading) {
  123. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-system-refresh')
  124. }
  125. }
  126. }
  127. }
  128. </script>
  129. <style lang='scss'>
  130. .dashboard-card {
  131. display: flex;
  132. .v-card__text {
  133. overflow: hidden;
  134. position: relative;
  135. }
  136. }
  137. .dashboard-icon {
  138. position: absolute;
  139. right: 0;
  140. top: 12px;
  141. font-size: 120px;
  142. opacity: .25;
  143. }
  144. </style>