AdminWebhooks.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template lang='pug'>
  2. q-page.admin-webhooks
  3. .row.q-pa-md.items-center
  4. .col-auto
  5. img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-lightning-bolt.svg')
  6. .col.q-pl-md
  7. .text-h5.text-primary.animated.fadeInLeft {{ t('admin.webhooks.title') }}
  8. .text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.webhooks.subtitle') }}
  9. .col-auto
  10. q-btn.q-mr-sm.acrylic-btn(
  11. icon='las la-question-circle'
  12. flat
  13. color='grey'
  14. :href='siteStore.docsBase + `/system/webhooks`'
  15. target='_blank'
  16. type='a'
  17. )
  18. q-btn.acrylic-btn.q-mr-sm(
  19. icon='las la-redo-alt'
  20. flat
  21. color='secondary'
  22. :loading='state.loading > 0'
  23. @click='load'
  24. )
  25. q-btn(
  26. unelevated
  27. icon='las la-plus'
  28. :label='t(`admin.webhooks.new`)'
  29. color='primary'
  30. @click='createHook'
  31. )
  32. q-separator(inset)
  33. .row.q-pa-md.q-col-gutter-md
  34. .col-12(v-if='state.hooks.length < 1')
  35. q-card.rounded-borders(
  36. flat
  37. :class='$q.dark.isActive ? `bg-dark-5 text-white` : `bg-grey-3 text-dark`'
  38. )
  39. q-card-section.items-center(horizontal)
  40. q-card-section.col-auto.q-pr-none
  41. q-icon(name='las la-info-circle', size='sm')
  42. q-card-section.text-caption {{ t('admin.webhooks.none') }}
  43. .col-12(v-else)
  44. q-card
  45. q-list(separator)
  46. q-item(v-for='hook of state.hooks', :key='hook.id')
  47. q-item-section(side)
  48. q-icon(name='las la-bolt', color='primary')
  49. q-item-section
  50. q-item-label {{hook.name}}
  51. q-item-label(caption) {{hook.url}}
  52. q-item-section(side, style='flex-direction: row; align-items: center;')
  53. template(v-if='hook.state === `pending`')
  54. q-spinner-clock.q-mr-sm(
  55. color='indigo'
  56. size='xs'
  57. )
  58. .text-caption.text-indigo {{t('admin.webhooks.statePending')}}
  59. q-tooltip(anchor='center left', self='center right') {{t('admin.webhooks.statePendingHint')}}
  60. template(v-else-if='hook.state === `success`')
  61. q-spinner-infinity.q-mr-sm(
  62. color='positive'
  63. size='xs'
  64. )
  65. .text-caption.text-positive {{t('admin.webhooks.stateSuccess')}}
  66. q-tooltip(anchor='center left', self='center right') {{t('admin.webhooks.stateSuccessHint')}}
  67. template(v-else-if='hook.state === `error`')
  68. q-icon.q-mr-sm(
  69. color='negative'
  70. size='xs'
  71. name='las la-exclamation-triangle'
  72. )
  73. .text-caption.text-negative {{t('admin.webhooks.stateError')}}
  74. q-tooltip(anchor='center left', self='center right') {{t('admin.webhooks.stateErrorHint')}}
  75. q-separator.q-ml-md(vertical)
  76. q-item-section(side, style='flex-direction: row; align-items: center;')
  77. q-btn.acrylic-btn.q-mr-sm(
  78. color='indigo'
  79. icon='las la-pen'
  80. label='Edit'
  81. flat
  82. no-caps
  83. @click='editHook(hook.id)'
  84. )
  85. q-btn.acrylic-btn(
  86. color='red'
  87. icon='las la-trash'
  88. flat
  89. @click='deleteHook(hook)'
  90. )
  91. </template>
  92. <script setup>
  93. import { cloneDeep } from 'lodash-es'
  94. import gql from 'graphql-tag'
  95. import { useI18n } from 'vue-i18n'
  96. import { useMeta, useQuasar } from 'quasar'
  97. import { onMounted, reactive } from 'vue'
  98. import { useSiteStore } from 'src/stores/site'
  99. import WebhookEditDialog from 'src/components/WebhookEditDialog.vue'
  100. import WebhookDeleteDialog from 'src/components/WebhookDeleteDialog.vue'
  101. // QUASAR
  102. const $q = useQuasar()
  103. // STORES
  104. const siteStore = useSiteStore()
  105. // I18N
  106. const { t } = useI18n()
  107. // META
  108. useMeta({
  109. title: t('admin.webhooks.title')
  110. })
  111. // DATA
  112. const state = reactive({
  113. hooks: [],
  114. loading: 0
  115. })
  116. // METHODS
  117. async function load () {
  118. state.loading++
  119. $q.loading.show()
  120. const resp = await APOLLO_CLIENT.query({
  121. query: gql`
  122. query getHooks {
  123. hooks {
  124. id
  125. name
  126. url
  127. state
  128. }
  129. }
  130. `,
  131. fetchPolicy: 'network-only'
  132. })
  133. state.hooks = cloneDeep(resp?.data?.hooks) ?? []
  134. $q.loading.hide()
  135. state.loading--
  136. }
  137. function createHook () {
  138. $q.dialog({
  139. component: WebhookEditDialog,
  140. componentProps: {
  141. hookId: null
  142. }
  143. }).onOk(() => {
  144. load()
  145. })
  146. }
  147. function editHook (id) {
  148. $q.dialog({
  149. component: WebhookEditDialog,
  150. componentProps: {
  151. hookId: id
  152. }
  153. }).onOk(() => {
  154. load()
  155. })
  156. }
  157. function deleteHook (hook) {
  158. $q.dialog({
  159. component: WebhookDeleteDialog,
  160. componentProps: {
  161. hook
  162. }
  163. }).onOk(() => {
  164. load()
  165. })
  166. }
  167. // MOUNTED
  168. onMounted(() => {
  169. load()
  170. })
  171. </script>
  172. <style lang='scss'>
  173. </style>