feat(admin): migrate extensions + security to vue 3 composable

parent 3d2e5c9d
...@@ -12,5 +12,6 @@ ...@@ -12,5 +12,6 @@
}, },
"i18n-ally.localesPaths": [ "i18n-ally.localesPaths": [
"ux/src/i18n/locales" "ux/src/i18n/locales"
] ],
"i18n-ally.keystyle": "nested"
} }
...@@ -4,8 +4,8 @@ q-page.admin-extensions ...@@ -4,8 +4,8 @@ q-page.admin-extensions
.col-auto .col-auto
img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-module.svg') img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-module.svg')
.col.q-pl-md .col.q-pl-md
.text-h5.text-primary.animated.fadeInLeft {{ $t('admin.extensions.title') }} .text-h5.text-primary.animated.fadeInLeft {{ t('admin.extensions.title') }}
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ $t('admin.extensions.subtitle') }} .text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.extensions.subtitle') }}
.col-auto .col-auto
q-btn.acrylic-btn.q-mr-sm( q-btn.acrylic-btn.q-mr-sm(
icon='las la-question-circle' icon='las la-question-circle'
...@@ -19,7 +19,7 @@ q-page.admin-extensions ...@@ -19,7 +19,7 @@ q-page.admin-extensions
icon='las la-redo-alt' icon='las la-redo-alt'
flat flat
color='secondary' color='secondary'
:loading='loading > 0' :loading='state.loading > 0'
@click='load' @click='load'
) )
q-separator(inset) q-separator(inset)
...@@ -28,7 +28,7 @@ q-page.admin-extensions ...@@ -28,7 +28,7 @@ q-page.admin-extensions
q-card.shadow-1 q-card.shadow-1
q-list(separator) q-list(separator)
q-item( q-item(
v-for='(ext, idx) of extensions' v-for='(ext, idx) of state.extensions'
:key='`ext-` + ext.key' :key='`ext-` + ext.key'
) )
blueprint-icon(icon='module') blueprint-icon(icon='module')
...@@ -49,9 +49,9 @@ q-page.admin-extensions ...@@ -49,9 +49,9 @@ q-page.admin-extensions
q-tooltip( q-tooltip(
anchor='center left' anchor='center left'
self='center right' self='center right'
) {{$t('admin.extensions.installed')}} ) {{t('admin.extensions.installed')}}
q-btn( q-btn(
:label='$t(`admin.extensions.install`)' :label='t(`admin.extensions.install`)'
color='blue-7' color='blue-7'
v-if='ext.isCompatible && !ext.isInstalled && ext.isInstallable' v-if='ext.isCompatible && !ext.isInstalled && ext.isInstallable'
@click='install(ext)' @click='install(ext)'
...@@ -59,21 +59,21 @@ q-page.admin-extensions ...@@ -59,21 +59,21 @@ q-page.admin-extensions
) )
q-btn( q-btn(
v-else-if='ext.isCompatible && ext.isInstalled && ext.isInstallable' v-else-if='ext.isCompatible && ext.isInstalled && ext.isInstallable'
:label='$t(`admin.extensions.reinstall`)' :label='t(`admin.extensions.reinstall`)'
color='blue-7' color='blue-7'
@click='install(ext)' @click='install(ext)'
no-caps no-caps
) )
q-btn( q-btn(
v-else-if='ext.isCompatible && ext.isInstalled && !ext.isInstallable' v-else-if='ext.isCompatible && ext.isInstalled && !ext.isInstallable'
:label='$t(`admin.extensions.installed`)' :label='t(`admin.extensions.installed`)'
color='positive' color='positive'
no-caps no-caps
:ripple='false' :ripple='false'
) )
q-btn( q-btn(
v-else-if='ext.isCompatible' v-else-if='ext.isCompatible'
:label='$t(`admin.extensions.instructions`)' :label='t(`admin.extensions.instructions`)'
icon='las la-info-circle' icon='las la-info-circle'
color='indigo' color='indigo'
outline outline
...@@ -85,109 +85,132 @@ q-page.admin-extensions ...@@ -85,109 +85,132 @@ q-page.admin-extensions
q-tooltip( q-tooltip(
anchor='center left' anchor='center left'
self='center right' self='center right'
) {{$t('admin.extensions.instructionsHint')}} ) {{t('admin.extensions.instructionsHint')}}
q-btn( q-btn(
v-else v-else
color='negative' color='negative'
outline outline
:label='$t(`admin.extensions.incompatible`)' :label='t(`admin.extensions.incompatible`)'
no-caps no-caps
:ripple='false' :ripple='false'
) )
</template> </template>
<script> <script setup>
import gql from 'graphql-tag' import gql from 'graphql-tag'
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
import { createMetaMixin } from 'quasar' import { useI18n } from 'vue-i18n'
import { useMeta, useQuasar } from 'quasar'
import { computed, onMounted, reactive, watch } from 'vue'
export default { import { useAdminStore } from 'src/stores/admin'
mixins: [ import { useSiteStore } from 'src/stores/site'
createMetaMixin(function () { import { useDataStore } from 'src/stores/data'
return {
title: this.$t('admin.extensions.title') // QUASAR
const $q = useQuasar()
// STORES
const adminStore = useAdminStore()
const siteStore = useSiteStore()
const dataStore = useDataStore()
// I18N
const { t } = useI18n()
// META
useMeta({
title: t('admin.extensions.title')
})
// DATA
const state = reactive({
loading: false,
extensions: []
})
// METHODS
async function load () {
state.loading++
$q.loading.show()
const resp = await APOLLO_CLIENT.query({
query: gql`
query fetchExtensions {
systemExtensions {
key
title
description
isInstalled
isInstallable
isCompatible
}
} }
}) `,
], fetchPolicy: 'network-only'
data () { })
return { state.extensions = cloneDeep(resp?.data?.systemExtensions)
loading: false, $q.loading.hide()
extensions: [] state.loading--
} }
},
mounted () { async function install (ext) {
this.load() $q.loading.show({
}, message: t('admin.extensions.installing') + '<br>' + t('admin.extensions.installingHint'),
methods: { html: true
async load () { })
this.loading++ try {
this.$q.loading.show() const respRaw = await APOLLO_CLIENT.mutate({
const resp = await this.$apollo.query({ mutation: gql`
query: gql` mutation installExtension (
query fetchExtensions { $key: String!
systemExtensions { ) {
key installExtension (
title key: $key
description ) {
isInstalled status {
isInstallable succeeded
isCompatible message
}
}
`,
fetchPolicy: 'network-only'
})
this.extensions = cloneDeep(resp?.data?.systemExtensions)
this.$q.loading.hide()
this.loading--
},
async install (ext) {
this.$q.loading.show({
message: this.$t('admin.extensions.installing') + '<br>' + this.$t('admin.extensions.installingHint'),
html: true
})
try {
const respRaw = await this.$apollo.mutate({
mutation: gql`
mutation installExtension (
$key: String!
) {
installExtension (
key: $key
) {
status {
succeeded
message
}
}
} }
`,
variables: {
key: ext.key
} }
})
if (respRaw.data?.installExtension?.status?.succeeded) {
this.$q.notify({
type: 'positive',
message: this.$t('admin.extensions.installSuccess')
})
ext.isInstalled = true
this.$forceUpdate()
} else {
throw new Error(respRaw.data?.installExtension?.status?.message || 'An unexpected error occured')
} }
} catch (err) { `,
this.$q.notify({ variables: {
type: 'negative', key: ext.key
message: this.$t('admin.extensions.installFailed'),
caption: err.message
})
} }
this.$q.loading.hide() })
if (respRaw.data?.installExtension?.status?.succeeded) {
$q.notify({
type: 'positive',
message: t('admin.extensions.installSuccess')
})
ext.isInstalled = true
// this.$forceUpdate()
} else {
throw new Error(respRaw.data?.installExtension?.status?.message || 'An unexpected error occured')
} }
} catch (err) {
$q.notify({
type: 'negative',
message: t('admin.extensions.installFailed'),
caption: err.message
})
} }
$q.loading.hide()
} }
// MOUNTED
onMounted(() => {
load()
})
</script> </script>
<style lang='scss'> <style lang='scss'>
......
...@@ -45,9 +45,9 @@ const routes = [ ...@@ -45,9 +45,9 @@ const routes = [
// { path: 'users/:id?/:section?', component: () => import('../pages/AdminUsers.vue') }, // { path: 'users/:id?/:section?', component: () => import('../pages/AdminUsers.vue') },
// -> System // -> System
// { path: 'api', component: () => import('../pages/AdminApi.vue') }, // { path: 'api', component: () => import('../pages/AdminApi.vue') },
// { path: 'extensions', component: () => import('../pages/AdminExtensions.vue') }, { path: 'extensions', component: () => import('../pages/AdminExtensions.vue') },
{ path: 'mail', component: () => import('../pages/AdminMail.vue') }, { path: 'mail', component: () => import('../pages/AdminMail.vue') },
// { path: 'security', component: () => import('../pages/AdminSecurity.vue') }, { path: 'security', component: () => import('../pages/AdminSecurity.vue') },
{ path: 'system', component: () => import('../pages/AdminSystem.vue') }, { path: 'system', component: () => import('../pages/AdminSystem.vue') },
// { path: 'utilities', component: () => import('../pages/AdminUtilities.vue') }, // { path: 'utilities', component: () => import('../pages/AdminUtilities.vue') },
// { path: 'webhooks', component: () => import('../pages/AdminWebhooks.vue') }, // { path: 'webhooks', component: () => import('../pages/AdminWebhooks.vue') },
......
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