feat(admin): migrate theme + api + utilities to vue 3 composition

pull/5698/head
Nicolas Giard 2 years ago
parent 368493c39b
commit 8fb29cfc21
No known key found for this signature in database
GPG Key ID: 85061B8F9D55B7C8

@ -12,26 +12,26 @@
}, },
"dependencies": { "dependencies": {
"@apollo/client": "3.6.8", "@apollo/client": "3.6.8",
"@codemirror/autocomplete": "0.20.3", "@codemirror/autocomplete": "6.0.2",
"@codemirror/basic-setup": "0.20.0", "@codemirror/basic-setup": "0.20.0",
"@codemirror/closebrackets": "0.19.2", "@codemirror/closebrackets": "0.19.2",
"@codemirror/commands": "0.20.0", "@codemirror/commands": "6.0.0",
"@codemirror/comment": "0.19.1", "@codemirror/comment": "0.19.1",
"@codemirror/fold": "0.19.4", "@codemirror/fold": "0.19.4",
"@codemirror/gutter": "0.19.9", "@codemirror/gutter": "0.19.9",
"@codemirror/highlight": "0.19.8", "@codemirror/highlight": "0.19.8",
"@codemirror/history": "0.19.2", "@codemirror/history": "0.19.2",
"@codemirror/lang-css": "0.20.0", "@codemirror/lang-css": "6.0.0",
"@codemirror/lang-html": "0.20.0", "@codemirror/lang-html": "6.0.0",
"@codemirror/lang-javascript": "0.20.1", "@codemirror/lang-javascript": "6.0.0",
"@codemirror/lang-json": "0.20.0", "@codemirror/lang-json": "6.0.0",
"@codemirror/lang-markdown": "0.20.1", "@codemirror/lang-markdown": "6.0.0",
"@codemirror/matchbrackets": "0.19.4", "@codemirror/matchbrackets": "0.19.4",
"@codemirror/search": "0.20.1", "@codemirror/search": "6.0.0",
"@codemirror/state": "0.20.1", "@codemirror/state": "6.0.1",
"@codemirror/tooltip": "0.19.16", "@codemirror/tooltip": "0.19.16",
"@codemirror/view": "0.20.7", "@codemirror/view": "6.0.1",
"@lezer/common": "0.16.1", "@lezer/common": "1.0.0",
"@quasar/extras": "1.14.0", "@quasar/extras": "1.14.0",
"@tiptap/core": "2.0.0-beta.176", "@tiptap/core": "2.0.0-beta.176",
"@tiptap/extension-code-block": "2.0.0-beta.37", "@tiptap/extension-code-block": "2.0.0-beta.37",
@ -61,6 +61,7 @@
"apollo-upload-client": "17.0.0", "apollo-upload-client": "17.0.0",
"browser-fs-access": "0.29.6", "browser-fs-access": "0.29.6",
"clipboard": "2.0.11", "clipboard": "2.0.11",
"codemirror": "6.0.0",
"filesize": "9.0.9", "filesize": "9.0.9",
"filesize-parser": "1.5.0", "filesize-parser": "1.5.0",
"graphql": "16.5.0", "graphql": "16.5.0",
@ -71,12 +72,12 @@
"luxon": "2.4.0", "luxon": "2.4.0",
"pinia": "2.0.14", "pinia": "2.0.14",
"pug": "3.0.2", "pug": "3.0.2",
"quasar": "2.7.2", "quasar": "2.7.3",
"tippy.js": "6.3.7", "tippy.js": "6.3.7",
"uuid": "8.3.2", "uuid": "8.3.2",
"v-network-graph": "0.5.19", "v-network-graph": "0.5.19",
"vue": "3.2.37", "vue": "3.2.37",
"vue-codemirror": "5.1.0", "vue-codemirror": "6.0.0",
"vue-i18n": "9.1.10", "vue-i18n": "9.1.10",
"vue-router": "4.0.16", "vue-router": "4.0.16",
"vuedraggable": "4.1.0", "vuedraggable": "4.1.0",

@ -178,7 +178,6 @@ defineEmits([
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent() const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const $q = useQuasar() const $q = useQuasar()
defineExpose({ $q })
// I18N // I18N

@ -510,7 +510,6 @@ import UtilCodeEditor from './UtilCodeEditor.vue'
// QUASAR // QUASAR
const $q = useQuasar() const $q = useQuasar()
defineExpose({ $q })
// STORES // STORES

@ -12,7 +12,6 @@ import { EditorState } from '@codemirror/state'
import { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands' import { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands'
import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language' import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language'
import { ref, shallowRef, onBeforeMount, onMounted, watch } from 'vue' import { ref, shallowRef, onBeforeMount, onMounted, watch } from 'vue'
import { json } from '@codemirror/lang-json'
// PROPS // PROPS

@ -218,7 +218,6 @@ defineEmits([
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent() const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const $q = useQuasar() const $q = useQuasar()
defineExpose({ $q })
// I18N // I18N

@ -203,7 +203,6 @@ const overlays = {
// QUASAR // QUASAR
const $q = useQuasar() const $q = useQuasar()
defineExpose({ $q })
// STORES // STORES

@ -4,16 +4,16 @@ q-page.admin-api
.col-auto .col-auto
img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-rest-api.svg') img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-rest-api.svg')
.col.q-pl-md .col.q-pl-md
.text-h5.text-primary.animated.fadeInLeft {{ $t('admin.api.title') }} .text-h5.text-primary.animated.fadeInLeft {{ t('admin.api.title') }}
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ $t('admin.api.subtitle') }} .text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.api.subtitle') }}
.col .col
.flex.items-center .flex.items-center
template(v-if='enabled') template(v-if='state.enabled')
q-spinner-rings.q-mr-sm(color='green') q-spinner-rings.q-mr-sm(color='green')
.text-caption.text-green {{$t('admin.api.enabled')}} .text-caption.text-green {{t('admin.api.enabled')}}
template(v-else) template(v-else)
q-spinner-rings.q-mr-sm(color='red', size='md') q-spinner-rings.q-mr-sm(color='red', size='md')
.text-caption.text-red {{$t('admin.api.disabled')}} .text-caption.text-red {{t('admin.api.disabled')}}
.col-auto .col-auto
q-btn.q-mr-sm.q-ml-md.acrylic-btn( q-btn.q-mr-sm.q-ml-md.acrylic-btn(
icon='las la-question-circle' icon='las la-question-circle'
@ -27,24 +27,24 @@ q-page.admin-api
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-btn.q-mr-sm( q-btn.q-mr-sm(
unelevated unelevated
icon='las la-power-off' icon='las la-power-off'
:label='!enabled ? $t(`admin.api.enableButton`) : $t(`admin.api.disableButton`)' :label='!state.enabled ? t(`admin.api.enableButton`) : t(`admin.api.disableButton`)'
:color='!enabled ? `positive` : `negative`' :color='!state.enabled ? `positive` : `negative`'
@click='globalSwitch' @click='globalSwitch'
:disabled='loading > 0' :disabled='state.loading > 0'
) )
q-btn( q-btn(
unelevated unelevated
icon='las la-plus' icon='las la-plus'
:label='$t(`admin.api.newKeyButton`)' :label='t(`admin.api.newKeyButton`)'
color='primary' color='primary'
@click='newKey' @click='newKey'
:disabled='loading > 0' :disabled='state.loading > 0'
) )
q-separator(inset) q-separator(inset)
.row.q-pa-md.q-col-gutter-md .row.q-pa-md.q-col-gutter-md
@ -114,165 +114,166 @@ q-page.admin-api
//- v-btn(color='red', dark, @click='revokeConfirm', :loading='revokeLoading') {{$t('admin.api.revoke')}} //- v-btn(color='red', dark, @click='revokeConfirm', :loading='revokeLoading') {{$t('admin.api.revoke')}}
</template> </template>
<script> <script setup>
import _get from 'lodash/get'
import cloneDeep from 'lodash/cloneDeep'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { createMetaMixin } from 'quasar' import cloneDeep from 'lodash/cloneDeep'
// import { StatusIndicator } from 'vue-status-indicator' import { useI18n } from 'vue-i18n'
import { useMeta, useQuasar } from 'quasar'
import { computed, onMounted, reactive, watch } from 'vue'
// QUASAR
const $q = useQuasar()
// I18N
const { t } = useI18n()
// META
useMeta({
title: t('admin.api.title')
})
// DATA
// import CreateApiKey from './admin-api-create.vue' const state = reactive({
enabled: false,
loading: 0,
keys: [],
isCreateDialogShown: false,
isRevokeConfirmDialogShown: false,
revokeLoading: false,
current: {}
})
export default { // METHODS
components: {
// StatusIndicator, async function load () {
// CreateApiKey state.loading++
}, $q.loading.show()
mixins: [ const resp = await APOLLO_CLIENT.query({
createMetaMixin(function () { query: gql`
return { query getHooks {
title: this.$t('admin.api.title') apiKeys {
id
name
keyShort
expiration
isRevoked
createdAt
updatedAt
}
apiState
} }
}) `,
], fetchPolicy: 'network-only'
data () { })
return { state.keys = cloneDeep(resp?.data?.apiKeys) ?? []
enabled: false, state.enabled = resp?.data?.apiState === true
loading: 0, $q.loading.hide()
keys: [], state.loading--
isCreateDialogShown: false, }
isRevokeConfirmDialogShown: false,
revokeLoading: false, async function globalSwitch () {
current: {} state.isToggleLoading = true
} try {
}, const resp = await APOLLO_CLIENT.mutate({
mounted () { mutation: gql`
this.load() mutation ($enabled: Boolean!) {
}, authentication {
methods: { setApiState (enabled: $enabled) {
async load () { responseResult {
this.loading++ succeeded
this.$q.loading.show() errorCode
const resp = await this.$apollo.query({ slug
query: gql` message
query getHooks {
apiKeys {
id
name
keyShort
expiration
isRevoked
createdAt
updatedAt
}
apiState
}
`,
fetchPolicy: 'network-only'
})
this.keys = cloneDeep(resp?.data?.apiKeys) ?? []
this.enabled = resp?.data?.apiState === true
this.$q.loading.hide()
this.loading--
},
async globalSwitch () {
this.isToggleLoading = true
try {
const resp = await this.$apollo.mutate({
mutation: gql`
mutation ($enabled: Boolean!) {
authentication {
setApiState (enabled: $enabled) {
responseResult {
succeeded
errorCode
slug
message
}
}
} }
} }
`,
variables: {
enabled: !this.enabled
},
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-api-toggle')
} }
})
if (_get(resp, 'data.authentication.setApiState.responseResult.succeeded', false)) {
this.$store.commit('showNotification', {
style: 'success',
message: this.enabled ? this.$t('admin.api.toggleStateDisabledSuccess') : this.$t('admin.api.toggleStateEnabledSuccess'),
icon: 'check'
})
await this.load()
} else {
this.$store.commit('showNotification', {
style: 'red',
message: _get(resp, 'data.authentication.setApiState.responseResult.message', 'An unexpected error occurred.'),
icon: 'alert'
})
} }
} catch (err) { `,
this.$store.commit('pushGraphError', err) variables: {
enabled: !state.enabled
} }
this.isToggleLoading = false })
}, if (resp?.data?.setApiState?.operation?.succeeded) {
async newKey () { $q.notify({
this.isCreateDialogShown = true type: 'positive',
}, message: state.enabled ? t('admin.api.toggleStateDisabledSuccess') : t('admin.api.toggleStateEnabledSuccess')
revoke (key) { })
this.current = key await load()
this.isRevokeConfirmDialogShown = true } else {
}, throw new Error(resp?.data?.setApiState?.operation.message || 'An unexpected error occurred.')
async revokeConfirm () { }
this.revokeLoading = true } catch (err) {
try { $q.notify({
const resp = await this.$apollo.mutate({ type: 'negative',
mutation: gql` message: 'Failed to switch API state.',
mutation ($id: Int!) { caption: err.message
authentication { })
revokeApiKey (id: $id) { }
responseResult { state.isToggleLoading = false
succeeded }
errorCode
slug async function newKey () {
message state.isCreateDialogShown = true
} }
}
function revoke (key) {
state.current = key
state.isRevokeConfirmDialogShown = true
}
async function revokeConfirm () {
state.revokeLoading = true
try {
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation ($id: Int!) {
authentication {
revokeApiKey (id: $id) {
responseResult {
succeeded
errorCode
slug
message
} }
} }
`,
variables: {
id: this.current.id
},
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-api-revoke')
} }
})
if (_get(resp, 'data.authentication.revokeApiKey.responseResult.succeeded', false)) {
this.$store.commit('showNotification', {
style: 'success',
message: this.$t('admin.api.revokeSuccess'),
icon: 'check'
})
this.load()
} else {
this.$store.commit('showNotification', {
style: 'red',
message: _get(resp, 'data.authentication.revokeApiKey.responseResult.message', 'An unexpected error occurred.'),
icon: 'alert'
})
} }
} catch (err) { `,
this.$store.commit('pushGraphError', err) variables: {
id: state.current.id
} }
this.isRevokeConfirmDialogShown = false })
this.revokeLoading = false // if (_get(resp, 'data.authentication.revokeApiKey.responseResult.succeeded', false)) {
} // this.$store.commit('showNotification', {
// style: 'success',
// message: this.$t('admin.api.revokeSuccess'),
// icon: 'check'
// })
// this.load()
// } else {
// this.$store.commit('showNotification', {
// style: 'red',
// message: _get(resp, 'data.authentication.revokeApiKey.responseResult.message', 'An unexpected error occurred.'),
// icon: 'alert'
// })
// }
} catch (err) {
// this.$store.commit('pushGraphError', err)
} }
state.isRevokeConfirmDialogShown = false
state.revokeLoading = false
} }
// MOUNTED
onMounted(() => {
load()
})
</script> </script>
<style lang='scss'> <style lang='scss'>

@ -4,8 +4,8 @@ q-page.admin-theme
.col-auto .col-auto
img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-paint-roller.svg') img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-paint-roller.svg')
.col.q-pl-md .col.q-pl-md
.text-h5.text-primary.animated.fadeInLeft {{ $t('admin.theme.title') }} .text-h5.text-primary.animated.fadeInLeft {{ t('admin.theme.title') }}
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ $t('admin.theme.subtitle') }} .text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.theme.subtitle') }}
.col-auto .col-auto
q-btn.q-mr-sm.acrylic-btn( q-btn.q-mr-sm.acrylic-btn(
icon='las la-question-circle' icon='las la-question-circle'
@ -19,16 +19,16 @@ q-page.admin-theme
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-btn( q-btn(
unelevated unelevated
icon='mdi-check' icon='fa-solid fa-check'
:label='$t(`common.actions.apply`)' :label='t(`common.actions.apply`)'
color='secondary' color='secondary'
@click='save' @click='save'
:loading='loading > 0' :loading='state.loading > 0'
) )
q-separator(inset) q-separator(inset)
.row.q-pa-md.q-col-gutter-md .row.q-pa-md.q-col-gutter-md
@ -38,11 +38,11 @@ q-page.admin-theme
//- ----------------------- //- -----------------------
q-card.shadow-1.q-pb-sm q-card.shadow-1.q-pb-sm
q-card-section.flex.items-center q-card-section.flex.items-center
.text-subtitle1 {{$t('admin.theme.options')}} .text-subtitle1 {{t('admin.theme.options')}}
q-space q-space
q-btn.acrylic-btn( q-btn.acrylic-btn(
icon='las la-redo-alt' icon='las la-redo-alt'
:label='$t(`admin.theme.resetDefaults`)' :label='t(`admin.theme.resetDefaults`)'
flat flat
size='sm' size='sm'
color='pink' color='pink'
@ -51,25 +51,25 @@ q-page.admin-theme
q-item(tag='label', v-ripple) q-item(tag='label', v-ripple)
blueprint-icon(icon='light-on') blueprint-icon(icon='light-on')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.darkMode`)}} q-item-label {{t(`admin.theme.darkMode`)}}
q-item-label(caption) {{$t(`admin.theme.darkModeHint`)}} q-item-label(caption) {{t(`admin.theme.darkModeHint`)}}
q-item-section(avatar) q-item-section(avatar)
q-toggle( q-toggle(
v-model='config.dark' v-model='state.config.dark'
color='primary' color='primary'
checked-icon='las la-check' checked-icon='las la-check'
unchecked-icon='las la-times' unchecked-icon='las la-times'
:aria-label='$t(`admin.theme.darkMode`)' :aria-label='t(`admin.theme.darkMode`)'
) )
template(v-for='(cl, idx) of colorKeys', :key='cl') template(v-for='(cl, idx) of colorKeys', :key='cl')
q-separator.q-my-sm(inset) q-separator.q-my-sm(inset)
q-item q-item
blueprint-icon(icon='fill-color') blueprint-icon(icon='fill-color')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.` + cl + `Color`)}} q-item-label {{t(`admin.theme.` + cl + `Color`)}}
q-item-label(caption) {{$t(`admin.theme.` + cl + `ColorHint`)}} q-item-label(caption) {{t(`admin.theme.` + cl + `ColorHint`)}}
q-item-section(side) q-item-section(side)
.text-caption.text-grey-6 {{config[`color` + startCase(cl)]}} .text-caption.text-grey-6 {{state.config[`color` + startCase(cl)]}}
q-item-section(side) q-item-section(side)
q-btn.q-mr-sm( q-btn.q-mr-sm(
:key='`btnpick-` + cl' :key='`btnpick-` + cl'
@ -77,14 +77,14 @@ q-page.admin-theme
padding='xs md' padding='xs md'
no-caps no-caps
size='sm' size='sm'
:style='`background-color: ` + config[`color` + startCase(cl)] + `;`' :style='`background-color: ` + state.config[`color` + startCase(cl)] + `;`'
text-color='white' text-color='white'
) )
q-icon(name='las la-fill', size='xs', left) q-icon(name='las la-fill', size='xs', left)
span Pick... span Pick...
q-menu q-menu
q-color( q-color(
v-model='config[`color` + startCase(cl)]' v-model='state.config[`color` + startCase(cl)]'
) )
//- ----------------------- //- -----------------------
@ -92,69 +92,63 @@ q-page.admin-theme
//- ----------------------- //- -----------------------
q-card.shadow-1.q-pb-sm.q-mt-md q-card.shadow-1.q-pb-sm.q-mt-md
q-card-section q-card-section
.text-subtitle1 {{$t('admin.theme.layout')}} .text-subtitle1 {{t('admin.theme.layout')}}
q-item q-item
blueprint-icon(icon='right-navigation-toolbar') blueprint-icon(icon='right-navigation-toolbar')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.sidebarPosition`)}} q-item-label {{t(`admin.theme.sidebarPosition`)}}
q-item-label(caption) {{$t(`admin.theme.sidebarPositionHint`)}} q-item-label(caption) {{t(`admin.theme.sidebarPositionHint`)}}
q-item-section.col-auto q-item-section.col-auto
q-btn-toggle( q-btn-toggle(
v-model='config.sidebarPosition' v-model='state.config.sidebarPosition'
push push
glossy glossy
no-caps no-caps
toggle-color='primary' toggle-color='primary'
:options=`[ :options='rightLeftOptions'
{ label: 'Left', value: 'left' },
{ label: 'Right', value: 'right' }
]`
) )
q-separator.q-my-sm(inset) q-separator.q-my-sm(inset)
q-item q-item
blueprint-icon(icon='index') blueprint-icon(icon='index')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.tocPosition`)}} q-item-label {{t(`admin.theme.tocPosition`)}}
q-item-label(caption) {{$t(`admin.theme.tocPositionHint`)}} q-item-label(caption) {{t(`admin.theme.tocPositionHint`)}}
q-item-section.col-auto q-item-section.col-auto
q-btn-toggle( q-btn-toggle(
v-model='config.tocPosition' v-model='state.config.tocPosition'
push push
glossy glossy
no-caps no-caps
toggle-color='primary' toggle-color='primary'
:options=`[ :options='rightLeftOptions'
{ label: 'Left', value: 'left' },
{ label: 'Right', value: 'right' }
]`
) )
q-separator.q-my-sm(inset) q-separator.q-my-sm(inset)
q-item(tag='label', v-ripple) q-item(tag='label', v-ripple)
blueprint-icon(icon='share') blueprint-icon(icon='share')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.showSharingMenu`)}} q-item-label {{t(`admin.theme.showSharingMenu`)}}
q-item-label(caption) {{$t(`admin.theme.showSharingMenuHint`)}} q-item-label(caption) {{t(`admin.theme.showSharingMenuHint`)}}
q-item-section(avatar) q-item-section(avatar)
q-toggle( q-toggle(
v-model='config.showSharingMenu' v-model='state.config.showSharingMenu'
color='primary' color='primary'
checked-icon='las la-check' checked-icon='las la-check'
unchecked-icon='las la-times' unchecked-icon='las la-times'
:aria-label='$t(`admin.theme.showSharingMenu`)' :aria-label='t(`admin.theme.showSharingMenu`)'
) )
q-separator.q-my-sm(inset) q-separator.q-my-sm(inset)
q-item(tag='label', v-ripple) q-item(tag='label', v-ripple)
blueprint-icon(icon='print') blueprint-icon(icon='print')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.showPrintBtn`)}} q-item-label {{t(`admin.theme.showPrintBtn`)}}
q-item-label(caption) {{$t(`admin.theme.showPrintBtnHint`)}} q-item-label(caption) {{t(`admin.theme.showPrintBtnHint`)}}
q-item-section(avatar) q-item-section(avatar)
q-toggle( q-toggle(
v-model='config.showPrintBtn' v-model='state.config.showPrintBtn'
color='primary' color='primary'
checked-icon='las la-check' checked-icon='las la-check'
unchecked-icon='las la-times' unchecked-icon='las la-times'
:aria-label='$t(`admin.theme.showPrintBtn`)' :aria-label='t(`admin.theme.showPrintBtn`)'
) )
.col-6 .col-6
@ -163,234 +157,257 @@ q-page.admin-theme
//- ----------------------- //- -----------------------
q-card.shadow-1.q-pb-sm q-card.shadow-1.q-pb-sm
q-card-section q-card-section
.text-subtitle1 {{$t('admin.theme.codeInjection')}} .text-subtitle1 {{t('admin.theme.codeInjection')}}
q-item q-item
blueprint-icon(icon='css') blueprint-icon(icon='css')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.cssOverride`)}} q-item-label {{t(`admin.theme.cssOverride`)}}
q-item-label(caption) {{$t(`admin.theme.cssOverrideHint`)}} q-item-label(caption) {{t(`admin.theme.cssOverrideHint`)}}
q-item q-item
q-item-section q-item-section
q-no-ssr(:placeholder='$t(`common.loading`)') q-no-ssr(:placeholder='t(`common.loading`)')
util-code-editor.admin-theme-cm( util-code-editor.admin-theme-cm(
ref='cmCSS' ref='cmCSS'
v-model='config.injectCSS' v-model='state.config.injectCSS'
language='css' language='css'
) )
q-separator.q-my-sm(inset) q-separator.q-my-sm(inset)
q-item q-item
blueprint-icon(icon='html') blueprint-icon(icon='html')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.headHtmlInjection`)}} q-item-label {{t(`admin.theme.headHtmlInjection`)}}
q-item-label(caption) {{$t(`admin.theme.headHtmlInjectionHint`)}} q-item-label(caption) {{t(`admin.theme.headHtmlInjectionHint`)}}
q-item q-item
q-item-section q-item-section
q-no-ssr(:placeholder='$t(`common.loading`)') q-no-ssr(:placeholder='t(`common.loading`)')
util-code-editor.admin-theme-cm( util-code-editor.admin-theme-cm(
ref='cmHead' ref='cmHead'
v-model='config.injectHead' v-model='state.config.injectHead'
language='html' language='html'
) )
q-separator.q-my-sm(inset) q-separator.q-my-sm(inset)
q-item q-item
blueprint-icon(icon='html') blueprint-icon(icon='html')
q-item-section q-item-section
q-item-label {{$t(`admin.theme.bodyHtmlInjection`)}} q-item-label {{t(`admin.theme.bodyHtmlInjection`)}}
q-item-label(caption) {{$t(`admin.theme.bodyHtmlInjectionHint`)}} q-item-label(caption) {{t(`admin.theme.bodyHtmlInjectionHint`)}}
q-item q-item
q-item-section q-item-section
q-no-ssr(:placeholder='$t(`common.loading`)') q-no-ssr(:placeholder='t(`common.loading`)')
util-code-editor.admin-theme-cm( util-code-editor.admin-theme-cm(
ref='cmBody' ref='cmBody'
v-model='config.injectBody' v-model='state.config.injectBody'
language='html' language='html'
) )
</template> </template>
<script> <script setup>
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { get } from 'vuex-pathify'
import _get from 'lodash/get'
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
import startCase from 'lodash/startCase' import startCase from 'lodash/startCase'
import { createMetaMixin, useQuasar } from 'quasar' import { useI18n } from 'vue-i18n'
import { useMeta, useQuasar } from 'quasar'
import { onMounted, reactive, watch } from 'vue'
import { useAdminStore } from 'src/stores/admin'
import { useSiteStore } from 'src/stores/site'
import UtilCodeEditor from '../components/UtilCodeEditor.vue' import UtilCodeEditor from '../components/UtilCodeEditor.vue'
export default { // QUASAR
components: {
UtilCodeEditor const $q = useQuasar()
},
mixins: [ // STORES
createMetaMixin(function () {
return { const adminStore = useAdminStore()
title: this.$t('admin.theme.title') const siteStore = useSiteStore()
}
// I18N
const { t } = useI18n()
// META
useMeta({
title: t('admin.theme.title')
})
// DATA
const state = reactive({
loading: 0,
config: {
dark: false,
injectCSS: '',
injectHead: '',
injectBody: '',
colorPrimary: '#1976D2',
colorSecondary: '#02C39A',
colorAccent: '#f03a47',
colorHeader: '#000',
colorSidebar: '#1976D2',
sidebarPosition: 'left',
tocPosition: 'right',
showSharingMenu: true,
showPrintBtn: true
}
})
const colorKeys = [
'primary',
'secondary',
'accent',
'header',
'sidebar'
]
const rightLeftOptions = [
{ label: 'Left', value: 'left' },
{ label: 'Right', value: 'right' }
]
// WATCHERS
watch(() => adminStore.currentSiteId, (newValue) => {
load()
})
// METHODS
function resetColors () {
state.config.dark = false
state.config.colorPrimary = '#1976D2'
state.config.colorSecondary = '#02C39A'
state.config.colorAccent = '#f03a47'
state.config.colorHeader = '#000'
state.config.colorSidebar = '#1976D2'
}
async function load () {
state.loading++
$q.loading.show()
try {
const resp = await APOLLO_CLIENT.query({
query: gql`
query fetchThemeConfig (
$id: UUID!
) {
siteById(
id: $id
) {
theme {
dark
colorPrimary
colorSecondary
colorAccent
colorHeader
colorSidebar
injectCSS
injectHead
injectBody
sidebarPosition
tocPosition
showSharingMenu
showPrintBtn
}
}
}
`,
variables: {
id: adminStore.currentSiteId
},
fetchPolicy: 'network-only'
}) })
], if (!resp?.data?.siteById?.theme) {
data () { throw new Error('Failed to fetch theme config.')
return {
qsr: useQuasar(),
loading: 0,
colorKeys: [
'primary',
'secondary',
'accent',
'header',
'sidebar'
],
config: {
dark: false,
injectCSS: '',
injectHead: '',
injectBody: '',
colorPrimary: '#1976D2',
colorSecondary: '#02C39A',
colorAccent: '#f03a47',
colorHeader: '#000',
colorSidebar: '#1976D2',
sidebarPosition: 'left',
tocPosition: 'right',
showSharingMenu: true,
showPrintBtn: true
}
}
},
computed: {
currentSiteId: get('admin/currentSiteId', false)
},
watch: {
currentSiteId () {
this.load()
} }
}, state.config = cloneDeep(resp.data.siteById.theme)
mounted () { } catch (err) {
this.load() $q.notify({
}, type: 'negative',
methods: { message: 'Failed to fetch site theme config'
startCase, })
resetColors () { }
this.config.dark = false $q.loading.hide()
this.config.colorPrimary = '#1976D2' state.loading--
this.config.colorSecondary = '#02C39A' }
this.config.colorAccent = '#f03a47'
this.config.colorHeader = '#000'
this.config.colorSidebar = '#1976D2'
},
async load () {
if (!this.currentSiteId) { return }
this.loading++ async function save () {
try { state.loading++
const resp = await this.$apollo.query({ try {
query: gql` const patchTheme = {
query fetchThemeConfig ( dark: state.config.dark,
$id: UUID! colorPrimary: state.config.colorPrimary,
colorSecondary: state.config.colorSecondary,
colorAccent: state.config.colorAccent,
colorHeader: state.config.colorHeader,
colorSidebar: state.config.colorSidebar,
injectCSS: state.config.injectCSS,
injectHead: state.config.injectHead,
injectBody: state.config.injectBody,
sidebarPosition: state.config.sidebarPosition,
tocPosition: state.config.tocPosition,
showSharingMenu: state.config.showSharingMenu,
showPrintBtn: state.config.showPrintBtn
}
const respRaw = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation saveTheme (
$id: UUID!
$patch: SiteUpdateInput!
) {
updateSite (
id: $id,
patch: $patch
) { ) {
siteById( operation {
id: $id succeeded
) { slug
theme { message
dark
colorPrimary
colorSecondary
colorAccent
colorHeader
colorSidebar
injectCSS
injectHead
injectBody
sidebarPosition
tocPosition
showSharingMenu
showPrintBtn
}
}
}
`,
variables: {
id: this.currentSiteId
},
fetchPolicy: 'network-only'
})
if (!resp?.data?.siteById?.theme) {
throw new Error('Failed to fetch theme config.')
}
this.config = cloneDeep(resp.data.siteById.theme)
} catch (err) {
this.$q.notify({
type: 'negative',
message: 'Failed to fetch site theme config'
})
}
this.loading--
},
async save () {
this.loading++
try {
const patchTheme = {
dark: this.config.dark,
colorPrimary: this.config.colorPrimary,
colorSecondary: this.config.colorSecondary,
colorAccent: this.config.colorAccent,
colorHeader: this.config.colorHeader,
colorSidebar: this.config.colorSidebar,
injectCSS: this.config.injectCSS,
injectHead: this.config.injectHead,
injectBody: this.config.injectBody,
sidebarPosition: this.config.sidebarPosition,
tocPosition: this.config.tocPosition,
showSharingMenu: this.config.showSharingMenu,
showPrintBtn: this.config.showPrintBtn
}
const respRaw = await this.$apollo.mutate({
mutation: gql`
mutation saveTheme (
$id: UUID!
$patch: SiteUpdateInput!
) {
updateSite (
id: $id,
patch: $patch
) {
status {
succeeded
slug
message
}
}
} }
`,
variables: {
id: this.currentSiteId,
patch: {
theme: patchTheme
}
}
})
const resp = _get(respRaw, 'data.updateSite.status', {})
if (resp.succeeded) {
if (this.currentSiteId === this.$store.get('site/id')) {
this.$store.set('site/theme', patchTheme)
this.$q.dark.set(this.config.dark)
} }
this.$q.notify({
type: 'positive',
message: this.$t('admin.theme.saveSuccess')
})
} else {
throw new Error(resp.message)
} }
} catch (err) { `,
this.$q.notify({ variables: {
type: 'negative', id: adminStore.currentSiteId,
message: 'Failed to save site theme config', patch: {
caption: err.message theme: patchTheme
}
}
})
if (respRaw?.data?.updateSite?.operation?.succeeded) {
if (adminStore.currentSiteId === siteStore.id) {
siteStore.$patch({
theme: patchTheme
}) })
$q.dark.set(state.config.dark)
} }
this.loading-- $q.notify({
type: 'positive',
message: t('admin.theme.saveSuccess')
})
} else {
throw new Error(respRaw?.data?.updateSite?.operation?.message || 'An unexpected error occured.')
} }
} catch (err) {
$q.notify({
type: 'negative',
message: 'Failed to save site theme config',
caption: err.message
})
} }
state.loading--
} }
// MOUNTED
onMounted(() => {
if (adminStore.currentSiteId) {
load()
}
})
</script> </script>
<style lang='scss'> <style lang='scss'>

@ -4,14 +4,14 @@ q-page.admin-utilities
.col-auto .col-auto
img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-swiss-army-knife.svg') img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-swiss-army-knife.svg')
.col.q-pl-md .col.q-pl-md
.text-h5.text-primary.animated.fadeInLeft {{ $t('admin.utilities.title') }} .text-h5.text-primary.animated.fadeInLeft {{ t('admin.utilities.title') }}
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ $t('admin.utilities.subtitle') }} .text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.utilities.subtitle') }}
.col-auto .col-auto
q-btn.q-mr-sm.acrylic-btn( q-btn.q-mr-sm.acrylic-btn(
icon='las la-question-circle' icon='las la-question-circle'
flat flat
color='grey' color='grey'
href='https://docs.requarks.io/admin/utilities' href='https://docs.js.wiki/admin/utilities'
target='_blank' target='_blank'
type='a' type='a'
) )
@ -22,38 +22,31 @@ q-page.admin-utilities
q-item q-item
blueprint-icon(icon='matches', :hue-rotate='45') blueprint-icon(icon='matches', :hue-rotate='45')
q-item-section q-item-section
q-item-label {{$t(`admin.utilities.invalidAuthCertificates`)}} q-item-label {{t(`admin.utilities.invalidAuthCertificates`)}}
q-item-label(caption) {{$t(`admin.utilities.invalidAuthCertificatesHint`)}} q-item-label(caption) {{t(`admin.utilities.invalidAuthCertificatesHint`)}}
q-item-section(side) q-item-section(side)
q-btn.acrylic-btn( q-btn.acrylic-btn(
flat flat
icon='las la-arrow-circle-right' icon='las la-arrow-circle-right'
color='primary' color='primary'
@click='' @click=''
:label='$t(`common.actions.proceed`)' :label='t(`common.actions.proceed`)'
) )
q-item q-item
blueprint-icon(icon='historical', :hue-rotate='45') blueprint-icon(icon='historical', :hue-rotate='45')
q-item-section q-item-section
q-item-label {{$t(`admin.utilities.purgeHistory`)}} q-item-label {{t(`admin.utilities.purgeHistory`)}}
q-item-label(caption) {{$t(`admin.utilities.purgeHistoryHint`)}} q-item-label(caption) {{t(`admin.utilities.purgeHistoryHint`)}}
q-item-section(side) q-item-section(side)
q-select( q-select(
outlined outlined
:label='$t(`admin.utilities.purgeHistoryTimeframe`)' :label='t(`admin.utilities.purgeHistoryTimeframe`)'
v-model='purgeHistoryTimeframe' v-model='state.purgeHistoryTimeframe'
style='min-width: 175px;' style='min-width: 175px;'
emit-value emit-value
map-options map-options
dense dense
:options=`[ :options='purgeHistoryTimeframes'
{ value: '24h', label: $t('admin.utitilies.purgeHistoryToday') },
{ value: '1m', label: $tc('admin.utitilies.purgeHistoryMonth', 1, { count: 1 }) },
{ value: '3m', label: $tc('admin.utitilies.purgeHistoryMonth', 3, { count: 3 }) },
{ value: '6m', label: $tc('admin.utitilies.purgeHistoryMonth', 6, { count: 6 }) },
{ value: '1y', label: $tc('admin.utitilies.purgeHistoryYear', 1, { count: 1 }) },
{ value: '2y', label: $tc('admin.utitilies.purgeHistoryYear', 2, { count: 2 }) }
]`
) )
q-separator.q-ml-sm(vertical) q-separator.q-ml-sm(vertical)
q-item-section(side) q-item-section(side)
@ -62,20 +55,46 @@ q-page.admin-utilities
icon='las la-arrow-circle-right' icon='las la-arrow-circle-right'
color='primary' color='primary'
@click='' @click=''
:label='$t(`common.actions.proceed`)' :label='t(`common.actions.proceed`)'
) )
</template> </template>
<script> <script setup>
import { computed, reactive } from 'vue'
import { useMeta, useQuasar } from 'quasar'
import { useI18n } from 'vue-i18n'
export default { // QUASAR
data () {
return { const $q = useQuasar()
purgeHistoryTimeframe: '1y'
} // STORES / ROUTERS / i18n
}
} const { t } = useI18n()
// META
useMeta({
title: t('admin.utilities.title')
})
// DATA
const state = reactive({
purgeHistoryTimeframe: '1y'
})
// COMPUTED
const purgeHistoryTimeframes = computed(() => ([
{ value: '24h', label: t('admin.utitilies.purgeHistoryToday') },
{ value: '1m', label: t('admin.utitilies.purgeHistoryMonth', 1, { count: 1 }) },
{ value: '3m', label: t('admin.utitilies.purgeHistoryMonth', 3, { count: 3 }) },
{ value: '6m', label: t('admin.utitilies.purgeHistoryMonth', 6, { count: 6 }) },
{ value: '1y', label: t('admin.utitilies.purgeHistoryYear', 1, { count: 1 }) },
{ value: '2y', label: t('admin.utitilies.purgeHistoryYear', 2, { count: 2 }) }
]))
</script> </script>
<style lang='scss'> <style lang='scss'>

@ -36,20 +36,20 @@ const routes = [
{ path: ':siteid/locale', component: () => import('../pages/AdminLocale.vue') }, { path: ':siteid/locale', component: () => import('../pages/AdminLocale.vue') },
{ path: ':siteid/login', component: () => import('../pages/AdminLogin.vue') }, { path: ':siteid/login', component: () => import('../pages/AdminLogin.vue') },
// { path: ':siteid/navigation', component: () => import('../pages/AdminNavigation.vue') }, // { path: ':siteid/navigation', component: () => import('../pages/AdminNavigation.vue') },
{ path: ':siteid/storage/:id?', component: () => import('../pages/AdminStorage.vue') },
// { path: ':siteid/rendering', component: () => import('../pages/AdminRendering.vue') }, // { path: ':siteid/rendering', component: () => import('../pages/AdminRendering.vue') },
// { path: ':siteid/theme', component: () => import('../pages/AdminTheme.vue') }, { path: ':siteid/storage/:id?', component: () => import('../pages/AdminStorage.vue') },
{ path: ':siteid/theme', component: () => import('../pages/AdminTheme.vue') },
// -> Users // -> Users
// { path: 'auth', component: () => import('../pages/AdminAuth.vue') }, // { path: 'auth', component: () => import('../pages/AdminAuth.vue') },
{ path: 'groups/:id?/:section?', component: () => import('../pages/AdminGroups.vue') }, { path: 'groups/:id?/:section?', component: () => import('../pages/AdminGroups.vue') },
{ 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') },
{ path: 'flags', component: () => import('../pages/AdminFlags.vue') } { path: 'flags', component: () => import('../pages/AdminFlags.vue') }
] ]

@ -73,31 +73,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/autocomplete@npm:0.20.3": "@codemirror/autocomplete@npm:6.0.2, @codemirror/autocomplete@npm:^6.0.0":
version: 0.20.3
resolution: "@codemirror/autocomplete@npm:0.20.3"
dependencies:
"@codemirror/language": ^0.20.0
"@codemirror/state": ^0.20.0
"@codemirror/view": ^0.20.0
"@lezer/common": ^0.16.0
checksum: 7dfc6b98f343382845b4bf074a7a449fbdd4d204309f4a492209395ac560c92aa6cd24824735606263de1efc25ea6a67c2cd5a46a56a4ff4d4351e1e3c953bf6
languageName: node
linkType: hard
"@codemirror/autocomplete@npm:^0.20.0":
version: 0.20.0
resolution: "@codemirror/autocomplete@npm:0.20.0"
dependencies:
"@codemirror/language": ^0.20.0
"@codemirror/state": ^0.20.0
"@codemirror/view": ^0.20.0
"@lezer/common": ^0.16.0
checksum: aeb8fd255c110650853789851ae59270c1aad5ccb2228a62a76575c2220957cccf11e6004e17cc7466a714a2c1fc44d529cff146b381e719af3a0f78c67a5297
languageName: node
linkType: hard
"@codemirror/autocomplete@npm:^6.0.0":
version: 6.0.2 version: 6.0.2
resolution: "@codemirror/autocomplete@npm:6.0.2" resolution: "@codemirror/autocomplete@npm:6.0.2"
dependencies: dependencies:
@ -114,6 +90,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/autocomplete@npm:^0.20.0":
version: 0.20.0
resolution: "@codemirror/autocomplete@npm:0.20.0"
dependencies:
"@codemirror/language": ^0.20.0
"@codemirror/state": ^0.20.0
"@codemirror/view": ^0.20.0
"@lezer/common": ^0.16.0
checksum: aeb8fd255c110650853789851ae59270c1aad5ccb2228a62a76575c2220957cccf11e6004e17cc7466a714a2c1fc44d529cff146b381e719af3a0f78c67a5297
languageName: node
linkType: hard
"@codemirror/basic-setup@npm:0.20.0": "@codemirror/basic-setup@npm:0.20.0":
version: 0.20.0 version: 0.20.0
resolution: "@codemirror/basic-setup@npm:0.20.0" resolution: "@codemirror/basic-setup@npm:0.20.0"
@ -142,19 +130,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/commands@npm:0.20.0, @codemirror/commands@npm:^0.20.0": "@codemirror/commands@npm:6.0.0, @codemirror/commands@npm:6.x, @codemirror/commands@npm:^6.0.0":
version: 0.20.0
resolution: "@codemirror/commands@npm:0.20.0"
dependencies:
"@codemirror/language": ^0.20.0
"@codemirror/state": ^0.20.0
"@codemirror/view": ^0.20.0
"@lezer/common": ^0.16.0
checksum: 4538de7200f9ac4c8482fd99bee8d49ae983ca2be3b81d5f1f3e3cf7d7821f64f3ddf396213dd56b2fd9bd46f6d72467846dad0e4c42a3b9c8ba8243522e0bc6
languageName: node
linkType: hard
"@codemirror/commands@npm:6.x, @codemirror/commands@npm:^6.0.0":
version: 6.0.0 version: 6.0.0
resolution: "@codemirror/commands@npm:6.0.0" resolution: "@codemirror/commands@npm:6.0.0"
dependencies: dependencies:
@ -166,6 +142,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/commands@npm:^0.20.0":
version: 0.20.0
resolution: "@codemirror/commands@npm:0.20.0"
dependencies:
"@codemirror/language": ^0.20.0
"@codemirror/state": ^0.20.0
"@codemirror/view": ^0.20.0
"@lezer/common": ^0.16.0
checksum: 4538de7200f9ac4c8482fd99bee8d49ae983ca2be3b81d5f1f3e3cf7d7821f64f3ddf396213dd56b2fd9bd46f6d72467846dad0e4c42a3b9c8ba8243522e0bc6
languageName: node
linkType: hard
"@codemirror/comment@npm:0.19.1": "@codemirror/comment@npm:0.19.1":
version: 0.19.1 version: 0.19.1
resolution: "@codemirror/comment@npm:0.19.1" resolution: "@codemirror/comment@npm:0.19.1"
@ -225,83 +213,69 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/lang-css@npm:0.20.0, @codemirror/lang-css@npm:^0.20.0": "@codemirror/lang-css@npm:6.0.0, @codemirror/lang-css@npm:^6.0.0":
version: 0.20.0 version: 6.0.0
resolution: "@codemirror/lang-css@npm:0.20.0" resolution: "@codemirror/lang-css@npm:6.0.0"
dependencies:
"@codemirror/autocomplete": ^0.20.0
"@codemirror/language": ^0.20.0
"@codemirror/state": ^0.20.0
"@lezer/css": ^0.16.0
checksum: a922c76fe51a13d5af6e019fe36cd344d9d855aeb8a6ee8b01d2c757d015b3615907984c99dfa1866a81ef1fac465251b959a08e4d15d79b8ed2a4a35f3eed5e
languageName: node
linkType: hard
"@codemirror/lang-html@npm:0.20.0, @codemirror/lang-html@npm:^0.20.0":
version: 0.20.0
resolution: "@codemirror/lang-html@npm:0.20.0"
dependencies: dependencies:
"@codemirror/autocomplete": ^0.20.0 "@codemirror/autocomplete": ^6.0.0
"@codemirror/lang-css": ^0.20.0 "@codemirror/language": ^6.0.0
"@codemirror/lang-javascript": ^0.20.0 "@codemirror/state": ^6.0.0
"@codemirror/language": ^0.20.0 "@lezer/css": ^1.0.0
"@codemirror/state": ^0.20.0 checksum: 855a040ec2e22cf074fe1ef433488911b6f628878cdaf94c6deaa30df188860bfbf0f629ca339b56ad66549f00c8011df81d570245266c86ad8311367a448f92
"@lezer/common": ^0.16.0
"@lezer/html": ^0.16.0
checksum: ee02952c0409da4040e6f8aa522e69b2f5f7b0c16c704360cf0c7b2ac6010e8aed2a643f6096ccc877f8c3f784d1b5ce7136c92300dc63ddf5e971793aad0944
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/lang-javascript@npm:0.20.1": "@codemirror/lang-html@npm:6.0.0, @codemirror/lang-html@npm:^6.0.0":
version: 0.20.1 version: 6.0.0
resolution: "@codemirror/lang-javascript@npm:0.20.1" resolution: "@codemirror/lang-html@npm:6.0.0"
dependencies: dependencies:
"@codemirror/autocomplete": ^0.20.0 "@codemirror/autocomplete": ^6.0.0
"@codemirror/language": ^0.20.0 "@codemirror/lang-css": ^6.0.0
"@codemirror/lint": ^0.20.0 "@codemirror/lang-javascript": ^6.0.0
"@codemirror/state": ^0.20.0 "@codemirror/language": ^6.0.0
"@codemirror/view": ^0.20.0 "@codemirror/state": ^6.0.0
"@lezer/common": ^0.16.1 "@lezer/common": ^1.0.0
"@lezer/javascript": ^0.16.0 "@lezer/html": ^1.0.0
checksum: 169ed50ec2ef0171cc0719c48a971371a12b2a36180d42151f592bae3611f13331f422f67dd0cbbfc6938a5840fe8a96c90278de5606234896345391f15eff46 checksum: 1cb0aa2ed481d2ef644a23afc8a706f745201c67a22da6f214cdaff1b2c7173e8933dfb9f3b60522b777cdcdd74cb5f88786ef4df61e6a640439eb155cc1c777
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/lang-javascript@npm:^0.20.0": "@codemirror/lang-javascript@npm:6.0.0, @codemirror/lang-javascript@npm:^6.0.0":
version: 0.20.0 version: 6.0.0
resolution: "@codemirror/lang-javascript@npm:0.20.0" resolution: "@codemirror/lang-javascript@npm:6.0.0"
dependencies: dependencies:
"@codemirror/autocomplete": ^0.20.0 "@codemirror/autocomplete": ^6.0.0
"@codemirror/language": ^0.20.0 "@codemirror/language": ^6.0.0
"@codemirror/lint": ^0.20.0 "@codemirror/lint": ^6.0.0
"@codemirror/state": ^0.20.0 "@codemirror/state": ^6.0.0
"@codemirror/view": ^0.20.0 "@codemirror/view": ^6.0.0
"@lezer/javascript": ^0.16.0 "@lezer/common": ^1.0.0
checksum: 5de37bcdb8c7410d4530663c9038a02f0b318fdf1f32b8b720e46dc65aea9e51d46acce5a219506379dd8fc10b96c42f22b9aca588b5ff1dcdae6ff974d17d51 "@lezer/javascript": ^1.0.0
checksum: 6ec2f286c685b8e6556e207fb278637b8918a763344504c8e13c8a00bef06bc05e744858df9c21fbd47cb01bb7a4cbeb7bb5ef6ba2608eb57dfe1b8192d6736e
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/lang-json@npm:0.20.0": "@codemirror/lang-json@npm:6.0.0":
version: 0.20.0 version: 6.0.0
resolution: "@codemirror/lang-json@npm:0.20.0" resolution: "@codemirror/lang-json@npm:6.0.0"
dependencies: dependencies:
"@codemirror/language": ^0.20.0 "@codemirror/language": ^6.0.0
"@lezer/json": ^0.16.0 "@lezer/json": ^1.0.0
checksum: 20bbf0a480852fd11b0904561d4c7fe151f7a5cbe49b36516890ce7d729b4fd51e7c0443fb27463fd25e69e5ed693c3ce5e346ba60669a012f313cf8b06db13e checksum: 9eb7b1842e407f87683420ac74c06af224142719daf4d8dad254bffc34e826deaee2a318481b3e875e87051acaac8a56e85b4cc2ed7de53bd0297fc630e8452f
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/lang-markdown@npm:0.20.1": "@codemirror/lang-markdown@npm:6.0.0":
version: 0.20.1 version: 6.0.0
resolution: "@codemirror/lang-markdown@npm:0.20.1" resolution: "@codemirror/lang-markdown@npm:6.0.0"
dependencies: dependencies:
"@codemirror/lang-html": ^0.20.0 "@codemirror/lang-html": ^6.0.0
"@codemirror/language": ^0.20.0 "@codemirror/language": ^6.0.0
"@codemirror/state": ^0.20.0 "@codemirror/state": ^6.0.0
"@codemirror/view": ^0.20.0 "@codemirror/view": ^6.0.0
"@lezer/common": ^0.16.0 "@lezer/common": ^1.0.0
"@lezer/markdown": ^0.16.0 "@lezer/markdown": ^1.0.0
checksum: cc8ba82f8d5c1e279ad5d64d096c476327b9b83e5f9dda70c63258fcf21d97be3d66ada90d32af7f4fdd6f6bea51bf493e247a5875f0d05b8a34c34b701bcab3 checksum: 5cb9ee7053e758745e9376b67d4b22011329f3f74d8642870567d307018a0e823be8d8f59dac2002704f04908e329cb1bd206bcbcfd8111572e0a7e7819cb890
languageName: node languageName: node
linkType: hard linkType: hard
@ -388,18 +362,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/search@npm:0.20.1, @codemirror/search@npm:^0.20.0": "@codemirror/search@npm:6.0.0, @codemirror/search@npm:^6.0.0":
version: 0.20.1
resolution: "@codemirror/search@npm:0.20.1"
dependencies:
"@codemirror/state": ^0.20.0
"@codemirror/view": ^0.20.0
crelt: ^1.0.5
checksum: eb324d7967183652bc4c636f1b3c7f5bc7266a0d36d1138f03f2aa05585ee17c45666fe4d0e9b8d6e55b39f9338d06b76a333048b5e6ff523400cabad8fbd19f
languageName: node
linkType: hard
"@codemirror/search@npm:^6.0.0":
version: 6.0.0 version: 6.0.0
resolution: "@codemirror/search@npm:6.0.0" resolution: "@codemirror/search@npm:6.0.0"
dependencies: dependencies:
@ -410,14 +373,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/state@npm:0.20.1": "@codemirror/search@npm:^0.20.0":
version: 0.20.1 version: 0.20.1
resolution: "@codemirror/state@npm:0.20.1" resolution: "@codemirror/search@npm:0.20.1"
checksum: 9ad924314d2b88eecfdf7aac6da89e9c92154ab2fb2afb8b4de1581bdc24fcafbd3cdf1c435d592042cf4c044815c2306265e39cb22f8041e76f0f7121d7ebd5 dependencies:
"@codemirror/state": ^0.20.0
"@codemirror/view": ^0.20.0
crelt: ^1.0.5
checksum: eb324d7967183652bc4c636f1b3c7f5bc7266a0d36d1138f03f2aa05585ee17c45666fe4d0e9b8d6e55b39f9338d06b76a333048b5e6ff523400cabad8fbd19f
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/state@npm:6.x, @codemirror/state@npm:^6.0.0": "@codemirror/state@npm:6.0.1, @codemirror/state@npm:6.x, @codemirror/state@npm:^6.0.0":
version: 6.0.1 version: 6.0.1
resolution: "@codemirror/state@npm:6.0.1" resolution: "@codemirror/state@npm:6.0.1"
checksum: fcb5aa5e1ce455ed1261616beb6cdb9e855f9cf11618a1ef7f61142622a0aba4551605356d381d2fa96f021f932b71323808369bf8edadfa69d745252b7e6ccd checksum: fcb5aa5e1ce455ed1261616beb6cdb9e855f9cf11618a1ef7f61142622a0aba4551605356d381d2fa96f021f932b71323808369bf8edadfa69d745252b7e6ccd
@ -457,18 +424,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@codemirror/view@npm:0.20.7": "@codemirror/view@npm:6.0.1, @codemirror/view@npm:6.x, @codemirror/view@npm:^6.0.0":
version: 0.20.7
resolution: "@codemirror/view@npm:0.20.7"
dependencies:
"@codemirror/state": ^0.20.0
style-mod: ^4.0.0
w3c-keyname: ^2.2.4
checksum: 51799e4e53d0ec0c2cee28e4462abef5542b7dee2551b0fe1c69c1fe3622033243130c04c2b7bc6080561d74950188814660b1bc8eebdb4ce2ea173a9e48f11a
languageName: node
linkType: hard
"@codemirror/view@npm:6.x, @codemirror/view@npm:^6.0.0":
version: 6.0.1 version: 6.0.1
resolution: "@codemirror/view@npm:6.0.1" resolution: "@codemirror/view@npm:6.0.1"
dependencies: dependencies:
@ -697,10 +653,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@lezer/common@npm:0.16.1, @lezer/common@npm:^0.16.1": "@lezer/common@npm:1.0.0, @lezer/common@npm:^1.0.0":
version: 0.16.1 version: 1.0.0
resolution: "@lezer/common@npm:0.16.1" resolution: "@lezer/common@npm:1.0.0"
checksum: ee27598a8c2a4e5bcba285cf091b7c1aee36e5a5e8352b63ce65520e7279f6305e1272d8adede150fc4aee0073c1e3e93fb11271d538815db72bdff341c4be65 checksum: 0ba652b39f9ff073a6a8a3376a74279f2c2d2ccdd4d2bb57c7b607341dbdbf64baf9c23a196314f09349d175623bc73a6a0b6a0eeb2cc63f3a1190fd631f7c31
languageName: node languageName: node
linkType: hard linkType: hard
@ -718,20 +674,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@lezer/common@npm:^1.0.0": "@lezer/css@npm:^1.0.0":
version: 1.0.0 version: 1.0.0
resolution: "@lezer/common@npm:1.0.0" resolution: "@lezer/css@npm:1.0.0"
checksum: 0ba652b39f9ff073a6a8a3376a74279f2c2d2ccdd4d2bb57c7b607341dbdbf64baf9c23a196314f09349d175623bc73a6a0b6a0eeb2cc63f3a1190fd631f7c31
languageName: node
linkType: hard
"@lezer/css@npm:^0.16.0":
version: 0.16.0
resolution: "@lezer/css@npm:0.16.0"
dependencies: dependencies:
"@lezer/highlight": ^0.16.0 "@lezer/highlight": ^1.0.0
"@lezer/lr": ^0.16.0 "@lezer/lr": ^1.0.0
checksum: c88151f2d0f3cbc00e21a9f2f18960298ffe566a321996fa0e2b676b804535c1b20053bc8f81f8510c8523169a00cbbabe808775b5e980c371b64912d19c6dc9 checksum: 094b178254c509b3236d0e3a5c21831d5cfe00884328a6990dcb8aa913f5096ad37ed1b4adce9d7cc2d8a1b14bac1f7b8e6455a23249d9a5fbd9ee6c094f75a2
languageName: node languageName: node
linkType: hard linkType: hard
@ -753,33 +702,33 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@lezer/html@npm:^0.16.0": "@lezer/html@npm:^1.0.0":
version: 0.16.0 version: 1.0.0
resolution: "@lezer/html@npm:0.16.0" resolution: "@lezer/html@npm:1.0.0"
dependencies: dependencies:
"@lezer/highlight": ^0.16.0 "@lezer/highlight": ^1.0.0
"@lezer/lr": ^0.16.0 "@lezer/lr": ^1.0.0
checksum: 31124c7619cecc79fc43639abdd7229dafa36636d00c95b32f6b6a41e5e04f7dc898e45ba5fca2c456356b920bb11deacc61b07edb0737313a7fa5573754d940 checksum: 91e2716ec2850d62238b01c1af4170c1102ecec7c8726fc658182a44de524aa376d2743ee147a8d455d1dde51f0c2255c1993f5a393d6e3aa9e3ac41cc109a2c
languageName: node languageName: node
linkType: hard linkType: hard
"@lezer/javascript@npm:^0.16.0": "@lezer/javascript@npm:^1.0.0":
version: 0.16.0 version: 1.0.0
resolution: "@lezer/javascript@npm:0.16.0" resolution: "@lezer/javascript@npm:1.0.0"
dependencies: dependencies:
"@lezer/highlight": ^0.16.0 "@lezer/highlight": ^1.0.0
"@lezer/lr": ^0.16.0 "@lezer/lr": ^1.0.0
checksum: 164c1dcadc47610e588fee1e1c1f1cb478a296373ab3654e04b41dd6feb375f0abe0df6b5d339e70aaa444df573873cf2302d21abe3f372cbaa0bebfd1cf7f5a checksum: f6e104791f124e592f7343e4405224cd4a793b688db378b7e7878ddaa1b78525873fadb895fda10b1959fe83a01b498f4c48571eb827c4510b9e1f87f2327970
languageName: node languageName: node
linkType: hard linkType: hard
"@lezer/json@npm:^0.16.0": "@lezer/json@npm:^1.0.0":
version: 0.16.0 version: 1.0.0
resolution: "@lezer/json@npm:0.16.0" resolution: "@lezer/json@npm:1.0.0"
dependencies: dependencies:
"@lezer/highlight": ^0.16.0 "@lezer/highlight": ^1.0.0
"@lezer/lr": ^0.16.0 "@lezer/lr": ^1.0.0
checksum: 3fe14dcd8879c9318dc74e77c3543fff21e2f7b45b344b93e58e67eae48ea0c603c6b602129967d85a8ade1fa88b2c6abe43b3772b57829890fd91b111676f13 checksum: c1ca0cdf681415b58a383a669944bed66da3aa830870d32d1e471d545cff0fe43d9ac8a0d2a318a96daa99cd5a645b1d58ba8fbdd2e8d7ca4d33a62c7582cbab
languageName: node languageName: node
linkType: hard linkType: hard
@ -810,13 +759,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@lezer/markdown@npm:^0.16.0": "@lezer/markdown@npm:^1.0.0":
version: 0.16.0 version: 1.0.0
resolution: "@lezer/markdown@npm:0.16.0" resolution: "@lezer/markdown@npm:1.0.0"
dependencies: dependencies:
"@lezer/common": ^0.16.0 "@lezer/common": ^1.0.0
"@lezer/highlight": ^0.16.0 "@lezer/highlight": ^1.0.0
checksum: ad60b95cfcbadadd626464227dfa11803d86888721c759ca9f3f9c62d3e587c495d87cabdeb0617c726830aa904dc548e68fa939cfd8a81e4b9877754dc805a0 checksum: 6d5ff7df69c720d7d25e7b7e527c678a0958948a4c4e004b1c5d737353d21f4b42a8ce7e02c05ac747b51afe8ca16d6a7f58916110c5d3af511d3752e87f0a02
languageName: node languageName: node
linkType: hard linkType: hard
@ -2473,7 +2422,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"codemirror@npm:6.x": "codemirror@npm:6.0.0":
version: 6.0.0 version: 6.0.0
resolution: "codemirror@npm:6.0.0" resolution: "codemirror@npm:6.0.0"
dependencies: dependencies:
@ -5914,10 +5863,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"quasar@npm:2.7.2": "quasar@npm:2.7.3":
version: 2.7.2 version: 2.7.3
resolution: "quasar@npm:2.7.2" resolution: "quasar@npm:2.7.3"
checksum: 6f1bbed4bf9b5df0067581dd81f1ec751dfed776a6c50394821169825a281d1e9598aa8aa447c48fdae12a9cba8989b1831e72cf8e28128f95cd4c9f2af0c176 checksum: 42ae066c7a7e477731e3063bfa6b097bc89a670dac4781dd3e72d3c16e0db61a909f09eea21ef342592953fd6167f80a4c9add20722d4df0229616d3a86f5810
languageName: node languageName: node
linkType: hard linkType: hard
@ -6828,27 +6777,27 @@ __metadata:
resolution: "ux@workspace:." resolution: "ux@workspace:."
dependencies: dependencies:
"@apollo/client": 3.6.8 "@apollo/client": 3.6.8
"@codemirror/autocomplete": 0.20.3 "@codemirror/autocomplete": 6.0.2
"@codemirror/basic-setup": 0.20.0 "@codemirror/basic-setup": 0.20.0
"@codemirror/closebrackets": 0.19.2 "@codemirror/closebrackets": 0.19.2
"@codemirror/commands": 0.20.0 "@codemirror/commands": 6.0.0
"@codemirror/comment": 0.19.1 "@codemirror/comment": 0.19.1
"@codemirror/fold": 0.19.4 "@codemirror/fold": 0.19.4
"@codemirror/gutter": 0.19.9 "@codemirror/gutter": 0.19.9
"@codemirror/highlight": 0.19.8 "@codemirror/highlight": 0.19.8
"@codemirror/history": 0.19.2 "@codemirror/history": 0.19.2
"@codemirror/lang-css": 0.20.0 "@codemirror/lang-css": 6.0.0
"@codemirror/lang-html": 0.20.0 "@codemirror/lang-html": 6.0.0
"@codemirror/lang-javascript": 0.20.1 "@codemirror/lang-javascript": 6.0.0
"@codemirror/lang-json": 0.20.0 "@codemirror/lang-json": 6.0.0
"@codemirror/lang-markdown": 0.20.1 "@codemirror/lang-markdown": 6.0.0
"@codemirror/matchbrackets": 0.19.4 "@codemirror/matchbrackets": 0.19.4
"@codemirror/search": 0.20.1 "@codemirror/search": 6.0.0
"@codemirror/state": 0.20.1 "@codemirror/state": 6.0.1
"@codemirror/tooltip": 0.19.16 "@codemirror/tooltip": 0.19.16
"@codemirror/view": 0.20.7 "@codemirror/view": 6.0.1
"@intlify/vite-plugin-vue-i18n": 3.4.0 "@intlify/vite-plugin-vue-i18n": 3.4.0
"@lezer/common": 0.16.1 "@lezer/common": 1.0.0
"@quasar/app-vite": 1.0.2 "@quasar/app-vite": 1.0.2
"@quasar/extras": 1.14.0 "@quasar/extras": 1.14.0
"@tiptap/core": 2.0.0-beta.176 "@tiptap/core": 2.0.0-beta.176
@ -6881,6 +6830,7 @@ __metadata:
autoprefixer: 10.4.7 autoprefixer: 10.4.7
browser-fs-access: 0.29.6 browser-fs-access: 0.29.6
clipboard: 2.0.11 clipboard: 2.0.11
codemirror: 6.0.0
eslint: 8.18.0 eslint: 8.18.0
eslint-config-standard: 17.0.0 eslint-config-standard: 17.0.0
eslint-plugin-import: 2.26.0 eslint-plugin-import: 2.26.0
@ -6897,12 +6847,12 @@ __metadata:
luxon: 2.4.0 luxon: 2.4.0
pinia: 2.0.14 pinia: 2.0.14
pug: 3.0.2 pug: 3.0.2
quasar: 2.7.2 quasar: 2.7.3
tippy.js: 6.3.7 tippy.js: 6.3.7
uuid: 8.3.2 uuid: 8.3.2
v-network-graph: 0.5.19 v-network-graph: 0.5.19
vue: 3.2.37 vue: 3.2.37
vue-codemirror: 5.1.0 vue-codemirror: 6.0.0
vue-i18n: 9.1.10 vue-i18n: 9.1.10
vue-router: 4.0.16 vue-router: 4.0.16
vuedraggable: 4.1.0 vuedraggable: 4.1.0
@ -7002,19 +6952,19 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vue-codemirror@npm:5.1.0": "vue-codemirror@npm:6.0.0":
version: 5.1.0 version: 6.0.0
resolution: "vue-codemirror@npm:5.1.0" resolution: "vue-codemirror@npm:6.0.0"
dependencies: dependencies:
"@codemirror/commands": 6.x "@codemirror/commands": 6.x
"@codemirror/language": 6.x "@codemirror/language": 6.x
"@codemirror/state": 6.x "@codemirror/state": 6.x
"@codemirror/view": 6.x "@codemirror/view": 6.x
codemirror: 6.x
csstype: ^2.6.8 csstype: ^2.6.8
peerDependencies: peerDependencies:
codemirror: 6.x
vue: 3.x vue: 3.x
checksum: 6eeee0dfee3352cb1dbf9dc822f8f2ebc64413760abc12bcc91fae23ddeed1086585add2d0591a491d1b03c5393361b87db6d1af4a934445da2cd855017777f2 checksum: aa762ebfe8b8f9f43c98b76ba822842c79af2fc16be1b2639142d3c85d86f73376c1467d0372bdae1b5e73fd4b76405f23b0266d6e5c72505408677164505e0e
languageName: node languageName: node
linkType: hard linkType: hard

Loading…
Cancel
Save