AdminMetrics.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template lang='pug'>
  2. q-page.admin-api
  3. .row.q-pa-md.items-center
  4. .col-auto
  5. img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-graph.svg')
  6. .col.q-pl-md
  7. .text-h5.text-primary.animated.fadeInLeft {{ t('admin.metrics.title') }}
  8. .text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.metrics.subtitle') }}
  9. .col
  10. .flex.items-center
  11. template(v-if='state.enabled')
  12. q-spinner-rings.q-mr-sm(color='green', size='md')
  13. .text-caption.text-green {{t('admin.metrics.enabled')}}
  14. template(v-else)
  15. q-spinner-rings.q-mr-sm(color='red', size='md')
  16. .text-caption.text-red {{t('admin.metrics.disabled')}}
  17. .col-auto
  18. q-btn.q-mr-sm.q-ml-md.acrylic-btn(
  19. icon='las la-question-circle'
  20. flat
  21. color='grey'
  22. :aria-label='t(`common.actions.viewDocs`)'
  23. :href='siteStore.docsBase + `/system/metrics`'
  24. target='_blank'
  25. type='a'
  26. )
  27. q-tooltip {{ t(`common.actions.viewDocs`) }}
  28. q-btn.acrylic-btn.q-mr-sm(
  29. icon='las la-redo-alt'
  30. flat
  31. color='secondary'
  32. :loading='state.loading > 0'
  33. :aria-label='t(`common.actions.refresh`)'
  34. @click='refresh'
  35. )
  36. q-tooltip {{ t(`common.actions.refresh`) }}
  37. q-btn.q-mr-sm(
  38. unelevated
  39. icon='las la-power-off'
  40. :label='!state.enabled ? t(`common.actions.activate`) : t(`common.actions.deactivate`)'
  41. :color='!state.enabled ? `positive` : `negative`'
  42. @click='globalSwitch'
  43. :loading='state.isToggleLoading'
  44. :disabled='state.loading > 0'
  45. )
  46. q-separator(inset)
  47. .row.q-pa-md.q-col-gutter-md
  48. .col-12
  49. q-card.rounded-borders(
  50. flat
  51. :class='$q.dark.isActive ? `bg-dark-5 text-white` : `bg-grey-3 text-dark`'
  52. )
  53. q-card-section.items-center(horizontal)
  54. q-card-section.col-auto.q-pr-none
  55. q-icon(name='las la-info-circle', size='sm')
  56. q-card-section
  57. i18n-t(tag='span', keypath='admin.metrics.endpoint', scope='global')
  58. template(#endpoint)
  59. strong.font-robotomono /metrics
  60. .text-caption {{ t('admin.metrics.endpointWarning') }}
  61. q-card.rounded-borders.q-mt-md(
  62. flat
  63. :class='$q.dark.isActive ? `bg-dark-5 text-white` : `bg-grey-3 text-dark`'
  64. )
  65. q-card-section.items-center(horizontal)
  66. q-card-section.col-auto.q-pr-none
  67. q-icon(name='las la-key', size='sm')
  68. q-card-section
  69. i18n-t(tag='span', keypath='admin.metrics.auth', scope='global')
  70. template(#headerName)
  71. strong.font-robotomono Authorization
  72. template(#tokenType)
  73. strong.font-robotomono Bearer
  74. template(#permission)
  75. strong.font-robotomono read:metrics
  76. .text-caption.font-robotomono Authorization: Bearer API-KEY-VALUE
  77. </template>
  78. <script setup>
  79. import gql from 'graphql-tag'
  80. import { cloneDeep } from 'lodash-es'
  81. import { useI18n } from 'vue-i18n'
  82. import { useMeta, useQuasar } from 'quasar'
  83. import { computed, onMounted, reactive, watch } from 'vue'
  84. import { useAdminStore } from '@/stores/admin'
  85. import { useSiteStore } from '@/stores/site'
  86. // QUASAR
  87. const $q = useQuasar()
  88. // STORES
  89. const adminStore = useAdminStore()
  90. const siteStore = useSiteStore()
  91. // I18N
  92. const { t } = useI18n()
  93. // META
  94. useMeta({
  95. title: t('admin.metrics.title')
  96. })
  97. // DATA
  98. const state = reactive({
  99. enabled: false,
  100. loading: 0,
  101. isToggleLoading: false
  102. })
  103. // METHODS
  104. async function load () {
  105. state.loading++
  106. $q.loading.show()
  107. const resp = await APOLLO_CLIENT.query({
  108. query: gql`
  109. query getMetricsState {
  110. metricsState
  111. }
  112. `,
  113. fetchPolicy: 'network-only'
  114. })
  115. state.enabled = resp?.data?.metricsState === true
  116. adminStore.info.isMetricsEnabled = state.enabled
  117. $q.loading.hide()
  118. state.loading--
  119. }
  120. async function refresh () {
  121. await load()
  122. $q.notify({
  123. type: 'positive',
  124. message: t('admin.metrics.refreshSuccess')
  125. })
  126. }
  127. async function globalSwitch () {
  128. state.isToggleLoading = true
  129. try {
  130. const resp = await APOLLO_CLIENT.mutate({
  131. mutation: gql`
  132. mutation ($enabled: Boolean!) {
  133. setMetricsState (enabled: $enabled) {
  134. operation {
  135. succeeded
  136. message
  137. }
  138. }
  139. }
  140. `,
  141. variables: {
  142. enabled: !state.enabled
  143. }
  144. })
  145. if (resp?.data?.setMetricsState?.operation?.succeeded) {
  146. $q.notify({
  147. type: 'positive',
  148. message: state.enabled ? t('admin.metrics.toggleStateDisabledSuccess') : t('admin.metrics.toggleStateEnabledSuccess')
  149. })
  150. await load()
  151. } else {
  152. throw new Error(resp?.data?.setMetricsState?.operation?.message || 'An unexpected error occurred.')
  153. }
  154. } catch (err) {
  155. $q.notify({
  156. type: 'negative',
  157. message: 'Failed to switch metrics endpoint state.',
  158. caption: err.message
  159. })
  160. }
  161. state.isToggleLoading = false
  162. }
  163. // MOUNTED
  164. onMounted(load)
  165. </script>
  166. <style lang='scss'>
  167. </style>