wiki/ux/src/pages/AdminExtensions.vue

228 lines
5.9 KiB

<template lang='pug'>
q-page.admin-extensions
.row.q-pa-md.items-center
.col-auto
img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-module.svg')
.col.q-pl-md
.text-h5.text-primary.animated.fadeInLeft {{ t('admin.extensions.title') }}
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.extensions.subtitle') }}
.col-auto
q-btn.acrylic-btn.q-mr-sm(
icon='las la-question-circle'
flat
color='grey'
:href='siteStore.docsBase + `/system/extensions`'
target='_blank'
type='a'
)
q-btn.acrylic-btn(
icon='las la-redo-alt'
flat
color='secondary'
:loading='state.loading > 0'
@click='load'
)
q-separator(inset)
.row.q-pa-md.q-col-gutter-md
.col-12
q-card.shadow-1
q-list(separator)
q-item(
v-for='(ext, idx) of state.extensions'
:key='`ext-` + ext.key'
)
blueprint-icon(icon='module')
q-item-section
q-item-label {{ext.title}}
q-item-label(caption) {{ext.description}}
q-item-section(side)
.row
q-btn-group(unelevated)
q-btn(
icon='las la-check'
size='sm'
color='positive'
padding='xs sm'
v-if='ext.isInstalled'
:ripple='false'
)
q-tooltip(
anchor='center left'
self='center right'
) {{t('admin.extensions.installed')}}
q-btn(
:label='t(`admin.extensions.install`)'
color='blue-7'
v-if='ext.isCompatible && !ext.isInstalled && ext.isInstallable'
@click='install(ext)'
no-caps
)
q-btn(
v-else-if='ext.isCompatible && ext.isInstalled && ext.isInstallable'
:label='t(`admin.extensions.reinstall`)'
color='blue-7'
@click='install(ext)'
no-caps
)
q-btn(
v-else-if='ext.isCompatible && ext.isInstalled && !ext.isInstallable'
:label='t(`admin.extensions.installed`)'
color='positive'
no-caps
:ripple='false'
)
q-btn(
v-else-if='ext.isCompatible'
:label='t(`admin.extensions.instructions`)'
icon='las la-info-circle'
color='indigo'
outline
type='a'
:href='`https://docs.js.wiki/admin/extensions/` + ext.key'
target='_blank'
no-caps
)
q-tooltip(
anchor='center left'
self='center right'
) {{t('admin.extensions.instructionsHint')}}
q-btn(
v-else
color='negative'
outline
:label='t(`admin.extensions.incompatible`)'
no-caps
:ripple='false'
)
</template>
<script setup>
import gql from 'graphql-tag'
import { cloneDeep } from 'lodash-es'
import { useI18n } from 'vue-i18n'
import { useMeta, useQuasar } from 'quasar'
import { computed, onMounted, reactive, watch } from 'vue'
import { useAdminStore } from 'src/stores/admin'
import { useSiteStore } from 'src/stores/site'
import { useDataStore } from 'src/stores/data'
// 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'
})
state.extensions = cloneDeep(resp?.data?.systemExtensions)
$q.loading.hide()
state.loading--
}
async function install (ext) {
$q.loading.show({
message: t('admin.extensions.installing') + '<br>' + t('admin.extensions.installingHint'),
html: true
})
try {
const respRaw = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation installExtension (
$key: String!
) {
installExtension (
key: $key
) {
status {
succeeded
message
}
}
}
`,
variables: {
key: ext.key
}
})
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>
<style lang='scss'>
.admin-extensions {
.q-expansion-item__content .q-card {
@at-root .body--light & {
background-color: $grey-1;
}
@at-root .body--dark & {
background-color: $dark-3;
}
}
}
</style>