mirror of
https://github.com/requarks/wiki.git
synced 2026-08-26 13:17:10 -05:00
feat(admin): migrate nav + auth to vue 3 composition, convert lodash to lodash-es
This commit is contained in:
@@ -69,6 +69,7 @@
|
||||
"js-cookie": "3.0.1",
|
||||
"jwt-decode": "3.1.2",
|
||||
"lodash": "4.17.21",
|
||||
"lodash-es": "4.17.21",
|
||||
"luxon": "2.4.0",
|
||||
"pinia": "2.0.14",
|
||||
"pug": "3.0.2",
|
||||
|
||||
@@ -95,7 +95,7 @@ q-layout.admin(view='hHh Lpr lff')
|
||||
q-item-section(avatar)
|
||||
q-icon(name='img:/_assets/icons/fluent-tree-structure.svg')
|
||||
q-item-section {{ t('admin.navigation.title') }}
|
||||
q-item(:to='`/_admin/` + adminStore.currentSiteId + `/rendering`', v-ripple, active-class='bg-primary text-white')
|
||||
q-item(:to='`/_admin/` + adminStore.currentSiteId + `/rendering`', v-ripple, active-class='bg-primary text-white', disabled)
|
||||
q-item-section(avatar)
|
||||
q-icon(name='img:/_assets/icons/fluent-rich-text-converter.svg')
|
||||
q-item-section {{ t('admin.rendering.title') }}
|
||||
|
||||
@@ -116,7 +116,7 @@ q-page.admin-api
|
||||
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { computed, onMounted, reactive, watch } from 'vue'
|
||||
|
||||
+288
-269
@@ -4,8 +4,8 @@ q-page.admin-mail
|
||||
.col-auto
|
||||
img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-security-lock.svg')
|
||||
.col.q-pl-md
|
||||
.text-h5.text-primary.animated.fadeInLeft {{ $t('admin.auth.title') }}
|
||||
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ $t('admin.auth.subtitle') }}
|
||||
.text-h5.text-primary.animated.fadeInLeft {{ t('admin.auth.title') }}
|
||||
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.auth.subtitle') }}
|
||||
.col-auto
|
||||
q-btn.q-mr-sm.acrylic-btn(
|
||||
icon='las la-question-circle'
|
||||
@@ -17,11 +17,11 @@ q-page.admin-mail
|
||||
)
|
||||
q-btn(
|
||||
unelevated
|
||||
icon='mdi-check'
|
||||
:label='$t(`common.actions.apply`)'
|
||||
icon='fa-solid fa-check'
|
||||
:label='t(`common.actions.apply`)'
|
||||
color='secondary'
|
||||
@click='save'
|
||||
:loading='loading'
|
||||
:loading='state.loading > 0'
|
||||
)
|
||||
q-separator(inset)
|
||||
.row.q-pa-md.q-col-gutter-md
|
||||
@@ -33,11 +33,11 @@ q-page.admin-mail
|
||||
dark
|
||||
)
|
||||
q-item(
|
||||
v-for='str of activeStrategies'
|
||||
v-for='str of state.activeStrategies'
|
||||
:key='str.key'
|
||||
active-class='bg-primary text-white'
|
||||
:active='selectedStrategy === str.key'
|
||||
@click='selectedStrategy = str.key'
|
||||
:active='state.selectedStrategy === str.key'
|
||||
@click='state.selectedStrategy = str.key'
|
||||
clickable
|
||||
)
|
||||
q-item-section(side)
|
||||
@@ -52,7 +52,7 @@ q-page.admin-mail
|
||||
q-btn.q-mt-sm.full-width(
|
||||
color='primary'
|
||||
icon='las la-plus'
|
||||
:label='$t(`admin.auth.addStrategy`)'
|
||||
:label='t(`admin.auth.addStrategy`)'
|
||||
)
|
||||
q-menu(auto-close)
|
||||
q-list(style='min-width: 350px;')
|
||||
@@ -261,275 +261,294 @@ q-page.admin-mail
|
||||
//- .body-2 HTTP-POST
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import { find, reject } from 'lodash-es'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { createMetaMixin } from 'quasar'
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { computed, onMounted, reactive, watch, nextTick } from 'vue'
|
||||
|
||||
import { useAdminStore } from 'src/stores/admin'
|
||||
import { useSiteStore } from 'src/stores/site'
|
||||
|
||||
import draggable from 'vuedraggable'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
createMetaMixin(function () {
|
||||
return {
|
||||
title: this.$t('admin.auth.title')
|
||||
// QUASAR
|
||||
|
||||
const $q = useQuasar()
|
||||
|
||||
// STORES
|
||||
|
||||
const adminStore = useAdminStore()
|
||||
const siteStore = useSiteStore()
|
||||
|
||||
// I18N
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
// META
|
||||
|
||||
useMeta({
|
||||
title: t('admin.auth.title')
|
||||
})
|
||||
|
||||
// DATA
|
||||
|
||||
const state = reactive({
|
||||
loading: 0,
|
||||
groups: [],
|
||||
strategies: [],
|
||||
activeStrategies: [
|
||||
{
|
||||
key: 'local',
|
||||
strategy: {
|
||||
key: 'local',
|
||||
title: 'Username-Password Authentication',
|
||||
description: '',
|
||||
useForm: true,
|
||||
icon: '/_assets/icons/ultraviolet-data-protection.svg',
|
||||
website: ''
|
||||
},
|
||||
config: [],
|
||||
isEnabled: true,
|
||||
displayName: 'Local Database',
|
||||
selfRegistration: false,
|
||||
domainWhitelist: '',
|
||||
autoEnrollGroups: []
|
||||
},
|
||||
{
|
||||
key: 'google',
|
||||
strategy: {
|
||||
key: 'google',
|
||||
title: 'Google',
|
||||
description: '',
|
||||
useForm: true,
|
||||
icon: '/_assets/icons/ultraviolet-google.svg',
|
||||
website: ''
|
||||
},
|
||||
config: [],
|
||||
isEnabled: true,
|
||||
displayName: 'Google',
|
||||
selfRegistration: false,
|
||||
domainWhitelist: '',
|
||||
autoEnrollGroups: []
|
||||
},
|
||||
{
|
||||
key: 'slack',
|
||||
strategy: {
|
||||
key: 'slack',
|
||||
title: 'Slack',
|
||||
description: '',
|
||||
useForm: true,
|
||||
icon: '/_assets/icons/ultraviolet-slack.svg',
|
||||
website: ''
|
||||
},
|
||||
config: [],
|
||||
isEnabled: false,
|
||||
displayName: 'Slack',
|
||||
selfRegistration: false,
|
||||
domainWhitelist: '',
|
||||
autoEnrollGroups: []
|
||||
}
|
||||
],
|
||||
selectedStrategy: '',
|
||||
host: '',
|
||||
strategy: {
|
||||
strategy: {}
|
||||
}
|
||||
})
|
||||
|
||||
// WATCHERS
|
||||
|
||||
watch(() => state.selectedStrategy, (newValue, oldValue) => {
|
||||
state.strategy = find(state.activeStrategies, ['key', newValue]) || {}
|
||||
})
|
||||
watch(() => state.activeStrategies, (newValue, oldValue) => {
|
||||
state.selectedStrategy = 'local'
|
||||
})
|
||||
|
||||
// METHODS
|
||||
|
||||
async function refresh () {
|
||||
await this.$apollo.queries.strategies.refetch()
|
||||
await this.$apollo.queries.activeStrategies.refetch()
|
||||
this.$store.commit('showNotification', {
|
||||
message: this.$t('admin.auth.refreshSuccess'),
|
||||
style: 'success',
|
||||
icon: 'cached'
|
||||
})
|
||||
}
|
||||
|
||||
function addStrategy (str) {
|
||||
const newStr = {
|
||||
key: uuid(),
|
||||
strategy: str,
|
||||
config: str.props.map(c => ({
|
||||
key: c.key,
|
||||
value: {
|
||||
...c,
|
||||
value: c.default
|
||||
}
|
||||
})),
|
||||
order: state.activeStrategies.length,
|
||||
isEnabled: true,
|
||||
displayName: str.title,
|
||||
selfRegistration: false,
|
||||
domainWhitelist: [],
|
||||
autoEnrollGroups: []
|
||||
}
|
||||
state.activeStrategies = [...state.activeStrategies, newStr]
|
||||
nextTick(() => {
|
||||
state.selectedStrategy = newStr.key
|
||||
})
|
||||
}
|
||||
|
||||
function deleteStrategy () {
|
||||
state.activeStrategies = reject(state.activeStrategies, ['key', state.strategy.key])
|
||||
}
|
||||
|
||||
async function save () {
|
||||
state.loading++
|
||||
try {
|
||||
const resp = await APOLLO_CLIENT.mutate({
|
||||
mutation: gql`
|
||||
mutation($strategies: [AuthenticationStrategyInput]!) {
|
||||
authentication {
|
||||
updateStrategies(strategies: $strategies) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
strategies: this.activeStrategies.map((str, idx) => ({
|
||||
key: str.key,
|
||||
strategyKey: str.strategy.key,
|
||||
displayName: str.displayName,
|
||||
order: idx,
|
||||
isEnabled: str.isEnabled,
|
||||
config: str.config.map(cfg => ({ ...cfg, value: JSON.stringify({ v: cfg.value.value }) })),
|
||||
selfRegistration: str.selfRegistration,
|
||||
domainWhitelist: str.domainWhitelist,
|
||||
autoEnrollGroups: str.autoEnrollGroups
|
||||
}))
|
||||
}
|
||||
})
|
||||
],
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
filters: {
|
||||
startCase (val) { return _.startCase(val) }
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
groups: [],
|
||||
strategies: [],
|
||||
activeStrategies: [
|
||||
{
|
||||
key: 'local',
|
||||
strategy: {
|
||||
key: 'local',
|
||||
title: 'Username-Password Authentication',
|
||||
description: '',
|
||||
useForm: true,
|
||||
icon: '/_assets/icons/ultraviolet-data-protection.svg',
|
||||
website: ''
|
||||
},
|
||||
config: [],
|
||||
isEnabled: true,
|
||||
displayName: 'Local Database',
|
||||
selfRegistration: false,
|
||||
domainWhitelist: '',
|
||||
autoEnrollGroups: []
|
||||
},
|
||||
{
|
||||
key: 'google',
|
||||
strategy: {
|
||||
key: 'google',
|
||||
title: 'Google',
|
||||
description: '',
|
||||
useForm: true,
|
||||
icon: '/_assets/icons/ultraviolet-google.svg',
|
||||
website: ''
|
||||
},
|
||||
config: [],
|
||||
isEnabled: true,
|
||||
displayName: 'Google',
|
||||
selfRegistration: false,
|
||||
domainWhitelist: '',
|
||||
autoEnrollGroups: []
|
||||
},
|
||||
{
|
||||
key: 'slack',
|
||||
strategy: {
|
||||
key: 'slack',
|
||||
title: 'Slack',
|
||||
description: '',
|
||||
useForm: true,
|
||||
icon: '/_assets/icons/ultraviolet-slack.svg',
|
||||
website: ''
|
||||
},
|
||||
config: [],
|
||||
isEnabled: false,
|
||||
displayName: 'Slack',
|
||||
selfRegistration: false,
|
||||
domainWhitelist: '',
|
||||
autoEnrollGroups: []
|
||||
}
|
||||
],
|
||||
selectedStrategy: '',
|
||||
host: '',
|
||||
strategy: {
|
||||
strategy: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedStrategy (newValue, oldValue) {
|
||||
this.strategy = _.find(this.activeStrategies, ['key', newValue]) || {}
|
||||
},
|
||||
activeStrategies (newValue, oldValue) {
|
||||
this.selectedStrategy = 'local'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async refresh () {
|
||||
await this.$apollo.queries.strategies.refetch()
|
||||
await this.$apollo.queries.activeStrategies.refetch()
|
||||
this.$store.commit('showNotification', {
|
||||
message: this.$t('admin.auth.refreshSuccess'),
|
||||
style: 'success',
|
||||
icon: 'cached'
|
||||
if (resp?.data?.authentication?.updateStrategies?.operation.succeeded) {
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: t('admin.auth.saveSuccess')
|
||||
})
|
||||
},
|
||||
addStrategy (str) {
|
||||
const newStr = {
|
||||
key: uuid(),
|
||||
strategy: str,
|
||||
config: str.props.map(c => ({
|
||||
key: c.key,
|
||||
value: {
|
||||
...c,
|
||||
value: c.default
|
||||
}
|
||||
})),
|
||||
order: this.activeStrategies.length,
|
||||
isEnabled: true,
|
||||
displayName: str.title,
|
||||
selfRegistration: false,
|
||||
domainWhitelist: [],
|
||||
autoEnrollGroups: []
|
||||
}
|
||||
this.activeStrategies = [...this.activeStrategies, newStr]
|
||||
this.$nextTick(() => {
|
||||
this.selectedStrategy = newStr.key
|
||||
})
|
||||
},
|
||||
deleteStrategy () {
|
||||
this.activeStrategies = _.reject(this.activeStrategies, ['key', this.strategy.key])
|
||||
},
|
||||
async save () {
|
||||
this.$store.commit('loadingStart', 'admin-auth-savestrategies')
|
||||
try {
|
||||
const resp = await this.$apollo.mutate({
|
||||
mutation: gql`
|
||||
mutation($strategies: [AuthenticationStrategyInput]!) {
|
||||
authentication {
|
||||
updateStrategies(strategies: $strategies) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
strategies: this.activeStrategies.map((str, idx) => ({
|
||||
key: str.key,
|
||||
strategyKey: str.strategy.key,
|
||||
displayName: str.displayName,
|
||||
order: idx,
|
||||
isEnabled: str.isEnabled,
|
||||
config: str.config.map(cfg => ({ ...cfg, value: JSON.stringify({ v: cfg.value.value }) })),
|
||||
selfRegistration: str.selfRegistration,
|
||||
domainWhitelist: str.domainWhitelist,
|
||||
autoEnrollGroups: str.autoEnrollGroups
|
||||
}))
|
||||
}
|
||||
})
|
||||
if (_.get(resp, 'data.authentication.updateStrategies.responseResult.succeeded', false)) {
|
||||
this.$store.commit('showNotification', {
|
||||
message: this.$t('admin.auth.saveSuccess'),
|
||||
style: 'success',
|
||||
icon: 'check'
|
||||
})
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.authentication.updateStrategies.responseResult.message', this.$t('common.error.unexpected')))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('pushGraphError', err)
|
||||
}
|
||||
this.$store.commit('loadingStop', 'admin-auth-savestrategies')
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
strategies: {
|
||||
query: gql`
|
||||
query {
|
||||
authentication {
|
||||
strategies {
|
||||
key
|
||||
title
|
||||
description
|
||||
isAvailable
|
||||
useForm
|
||||
logo
|
||||
website
|
||||
props {
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
skip: true,
|
||||
fetchPolicy: 'network-only',
|
||||
update: (data) => _.get(data, 'authentication.strategies', []).map(str => ({
|
||||
...str,
|
||||
isDisabled: !str.isAvailable || str.key === 'local',
|
||||
props: _.sortBy(str.props.map(cfg => ({
|
||||
key: cfg.key,
|
||||
...JSON.parse(cfg.value)
|
||||
})), [t => t.order])
|
||||
})),
|
||||
watchLoading (isLoading) {
|
||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-strategies-refresh')
|
||||
}
|
||||
},
|
||||
activeStrategies: {
|
||||
query: gql`
|
||||
query {
|
||||
authentication {
|
||||
activeStrategies {
|
||||
key
|
||||
strategy {
|
||||
key
|
||||
title
|
||||
description
|
||||
useForm
|
||||
logo
|
||||
website
|
||||
}
|
||||
config {
|
||||
key
|
||||
value
|
||||
}
|
||||
order
|
||||
isEnabled
|
||||
displayName
|
||||
selfRegistration
|
||||
domainWhitelist
|
||||
autoEnrollGroups
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
skip: true,
|
||||
fetchPolicy: 'network-only',
|
||||
update: (data) => _.sortBy(_.get(data, 'authentication.activeStrategies', []).map(str => ({
|
||||
...str,
|
||||
config: _.sortBy(str.config.map(cfg => ({
|
||||
...cfg,
|
||||
value: JSON.parse(cfg.value)
|
||||
})), [t => t.value.order])
|
||||
})), ['order']),
|
||||
watchLoading (isLoading) {
|
||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-activestrategies-refresh')
|
||||
}
|
||||
},
|
||||
groups: {
|
||||
query: gql`{ test }`,
|
||||
fetchPolicy: 'network-only',
|
||||
update: (data) => data.groups.list,
|
||||
watchLoading (isLoading) {
|
||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-groups-refresh')
|
||||
}
|
||||
},
|
||||
host: {
|
||||
query: gql`{ test }`,
|
||||
fetchPolicy: 'network-only',
|
||||
update: (data) => _.cloneDeep(data.site.config.host),
|
||||
watchLoading (isLoading) {
|
||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-host-refresh')
|
||||
}
|
||||
} else {
|
||||
throw new Error(resp?.data?.authentication?.updateStrategies?.operation?.message || t('common.error.unexpected'))
|
||||
}
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: 'Failed to save site theme config',
|
||||
caption: err.message
|
||||
})
|
||||
}
|
||||
state.loading--
|
||||
}
|
||||
|
||||
// apollo: {
|
||||
// strategies: {
|
||||
// query: gql`
|
||||
// query {
|
||||
// authentication {
|
||||
// strategies {
|
||||
// key
|
||||
// title
|
||||
// description
|
||||
// isAvailable
|
||||
// useForm
|
||||
// logo
|
||||
// website
|
||||
// props {
|
||||
// key
|
||||
// value
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// skip: true,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => _.get(data, 'authentication.strategies', []).map(str => ({
|
||||
// ...str,
|
||||
// isDisabled: !str.isAvailable || str.key === 'local',
|
||||
// props: _.sortBy(str.props.map(cfg => ({
|
||||
// key: cfg.key,
|
||||
// ...JSON.parse(cfg.value)
|
||||
// })), [t => t.order])
|
||||
// })),
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-strategies-refresh')
|
||||
// }
|
||||
// },
|
||||
// activeStrategies: {
|
||||
// query: gql`
|
||||
// query {
|
||||
// authentication {
|
||||
// activeStrategies {
|
||||
// key
|
||||
// strategy {
|
||||
// key
|
||||
// title
|
||||
// description
|
||||
// useForm
|
||||
// logo
|
||||
// website
|
||||
// }
|
||||
// config {
|
||||
// key
|
||||
// value
|
||||
// }
|
||||
// order
|
||||
// isEnabled
|
||||
// displayName
|
||||
// selfRegistration
|
||||
// domainWhitelist
|
||||
// autoEnrollGroups
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// skip: true,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => _.sortBy(_.get(data, 'authentication.activeStrategies', []).map(str => ({
|
||||
// ...str,
|
||||
// config: _.sortBy(str.config.map(cfg => ({
|
||||
// ...cfg,
|
||||
// value: JSON.parse(cfg.value)
|
||||
// })), [t => t.value.order])
|
||||
// })), ['order']),
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-activestrategies-refresh')
|
||||
// }
|
||||
// },
|
||||
// groups: {
|
||||
// query: gql`{ test }`,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => data.groups.list,
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-groups-refresh')
|
||||
// }
|
||||
// },
|
||||
// host: {
|
||||
// query: gql`{ test }`,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => _.cloneDeep(data.site.config.host),
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-host-refresh')
|
||||
// }
|
||||
// }
|
||||
</script>
|
||||
|
||||
@@ -99,7 +99,7 @@ q-page.admin-extensions
|
||||
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { computed, onMounted, reactive, watch } from 'vue'
|
||||
|
||||
@@ -82,7 +82,7 @@ q-page.admin-flags
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import { defineAsyncComponent, onMounted, reactive, ref, watch } from 'vue'
|
||||
import _transform from 'lodash/transform'
|
||||
import { transform } from 'lodash-es'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
|
||||
@@ -391,7 +391,7 @@ q-page.admin-general
|
||||
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { onMounted, reactive, watch } from 'vue'
|
||||
|
||||
@@ -93,7 +93,7 @@ q-page.admin-groups
|
||||
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { computed, onBeforeUnmount, onMounted, reactive, watch } from 'vue'
|
||||
|
||||
@@ -143,9 +143,7 @@ q-page.admin-locale
|
||||
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import filter from 'lodash/filter'
|
||||
import _get from 'lodash/get'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep, filter } from 'lodash-es'
|
||||
|
||||
import LocaleInstallDialog from '../components/LocaleInstallDialog.vue'
|
||||
|
||||
@@ -278,7 +276,7 @@ async function download (lc) {
|
||||
locale: lc.code
|
||||
}
|
||||
})
|
||||
const resp = _get(respRaw, 'data.localization.downloadLocale.responseResult', {})
|
||||
const resp = respRaw?.data?.localization?.downloadLocale?.responseResult || {}
|
||||
if (resp.succeeded) {
|
||||
lc.isDownloading = false
|
||||
lc.isInstalled = true
|
||||
@@ -331,7 +329,7 @@ async function save () {
|
||||
namespaces: state.namespaces
|
||||
}
|
||||
})
|
||||
const resp = _get(respRaw, 'data.localization.updateLocale.responseResult', {})
|
||||
const resp = respRaw?.data?.localization?.updateLocale?.responseResult || {}
|
||||
if (resp.succeeded) {
|
||||
// Change UI language
|
||||
this.$i18n.locale = state.selectedLocale
|
||||
|
||||
@@ -176,8 +176,7 @@ q-page.admin-login
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { get } from 'vuex-pathify'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import gql from 'graphql-tag'
|
||||
import draggable from 'vuedraggable'
|
||||
|
||||
|
||||
@@ -298,9 +298,7 @@ q-page.admin-mail
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import toSafeInteger from 'lodash/toSafeInteger'
|
||||
import _get from 'lodash/get'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep, toSafeInteger } from 'lodash-es'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
@@ -477,7 +475,7 @@ async function sendTest () {
|
||||
sendMailTest(
|
||||
recipientEmail: $recipientEmail
|
||||
) {
|
||||
status {
|
||||
operation {
|
||||
succeeded
|
||||
slug
|
||||
message
|
||||
@@ -489,8 +487,8 @@ async function sendTest () {
|
||||
recipientEmail: state.testEmail
|
||||
}
|
||||
})
|
||||
if (!_get(resp, 'data.sendMailTest.status.succeeded', false)) {
|
||||
throw new Error(_get(resp, 'data.sendMailTest.status.message', 'An unexpected error occurred.'))
|
||||
if (!resp?.data?.sendMailTest?.operation?.succeeded) {
|
||||
throw new Error(resp?.data?.sendMailTest?.operation?.message || 'An unexpected error occurred.')
|
||||
}
|
||||
|
||||
state.testEmail = ''
|
||||
|
||||
+281
-262
@@ -4,8 +4,8 @@ q-page.admin-navigation
|
||||
.col-auto
|
||||
img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-tree-structure.svg')
|
||||
.col.q-pl-md
|
||||
.text-h5.text-primary.animated.fadeInLeft {{ $t('admin.navigation.title') }}
|
||||
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ $t('admin.navigation.subtitle') }}
|
||||
.text-h5.text-primary.animated.fadeInLeft {{ t('admin.navigation.title') }}
|
||||
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.navigation.subtitle') }}
|
||||
.col-auto
|
||||
q-btn.acrylic-btn.q-mr-sm(
|
||||
icon='las la-question-circle'
|
||||
@@ -19,16 +19,16 @@ q-page.admin-navigation
|
||||
icon='las la-redo-alt'
|
||||
flat
|
||||
color='secondary'
|
||||
:loading='loading > 0'
|
||||
:loading='state.loading > 0'
|
||||
@click='load'
|
||||
)
|
||||
q-btn(
|
||||
unelevated
|
||||
icon='mdi-check'
|
||||
:label='$t(`common.actions.apply`)'
|
||||
icon='fa-solid fa-check'
|
||||
:label='t(`common.actions.apply`)'
|
||||
color='secondary'
|
||||
@click='save'
|
||||
:disabled='loading > 0'
|
||||
:disabled='state.loading > 0'
|
||||
)
|
||||
q-separator(inset)
|
||||
.row.q-pa-md.q-col-gutter-md
|
||||
@@ -306,278 +306,297 @@ q-page.admin-navigation
|
||||
//- page-selector(mode='select', v-model='selectPageModal', :open-handler='selectPageHandle', path='home', :locale='currentLang')
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import { find, intersectionBy, pull, unionBy } from 'lodash-es'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { createMetaMixin } from 'quasar'
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { computed, onMounted, reactive, watch, nextTick } from 'vue'
|
||||
|
||||
import { useAdminStore } from 'src/stores/admin'
|
||||
import { useSiteStore } from 'src/stores/site'
|
||||
|
||||
import draggable from 'vuedraggable'
|
||||
|
||||
// QUASAR
|
||||
|
||||
const $q = useQuasar()
|
||||
|
||||
// STORES
|
||||
|
||||
const adminStore = useAdminStore()
|
||||
const siteStore = useSiteStore()
|
||||
|
||||
// I18N
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
// META
|
||||
|
||||
useMeta({
|
||||
title: t('admin.navigation.title')
|
||||
})
|
||||
|
||||
// DATA
|
||||
|
||||
const siteConfig = { lang: 'en' }
|
||||
const siteLangs = [{ code: 'en' }]
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
createMetaMixin(function () {
|
||||
return {
|
||||
title: this.$t('admin.navigation.title')
|
||||
}
|
||||
})
|
||||
],
|
||||
components: {
|
||||
draggable
|
||||
const state = reactive({
|
||||
loading: 0,
|
||||
selectPageModal: false,
|
||||
trees: [],
|
||||
current: {},
|
||||
currentLang: siteConfig.lang,
|
||||
groups: [],
|
||||
copyFromLocaleDialogIsShown: false,
|
||||
config: {
|
||||
mode: 'NONE'
|
||||
},
|
||||
meta () {
|
||||
return {
|
||||
title: this.$t('admin.navigation.title')
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
selectPageModal: false,
|
||||
trees: [],
|
||||
current: {},
|
||||
currentLang: siteConfig.lang,
|
||||
groups: [],
|
||||
copyFromLocaleDialogIsShown: false,
|
||||
config: {
|
||||
mode: 'NONE'
|
||||
},
|
||||
allLocales: [],
|
||||
copyFromLocaleCode: 'en'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
navTypes () {
|
||||
return [
|
||||
{ text: this.$t('navigation.navType.external'), value: 'external' },
|
||||
{ text: this.$t('navigation.navType.externalblank'), value: 'externalblank' },
|
||||
{ text: this.$t('navigation.navType.home'), value: 'home' },
|
||||
{ text: this.$t('navigation.navType.page'), value: 'page' }
|
||||
// { text: this.$t('navigation.navType.searchQuery'), value: 'search' }
|
||||
]
|
||||
},
|
||||
locales () {
|
||||
return _.intersectionBy(this.allLocales, _.unionBy(siteLangs, [{ code: 'en' }, { code: siteConfig.lang }], 'code'), 'code')
|
||||
},
|
||||
currentTree: {
|
||||
get () {
|
||||
return _.get(_.find(this.trees, ['locale', this.currentLang]), 'items', null) || []
|
||||
},
|
||||
set (val) {
|
||||
const tree = _.find(this.trees, ['locale', this.currentLang])
|
||||
if (tree) {
|
||||
tree.items = val
|
||||
} else {
|
||||
this.trees = [...this.trees, {
|
||||
locale: this.currentLang,
|
||||
items: val
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentLang (newValue, oldValue) {
|
||||
this.$nextTick(() => {
|
||||
if (this.currentTree.length > 0) {
|
||||
this.current = this.currentTree[0]
|
||||
} else {
|
||||
this.current = {}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async load () {
|
||||
allLocales: [],
|
||||
copyFromLocaleCode: 'en'
|
||||
})
|
||||
|
||||
},
|
||||
addItem (kind) {
|
||||
let newItem = {
|
||||
id: uuid(),
|
||||
kind,
|
||||
visibilityMode: 'all',
|
||||
visibilityGroups: []
|
||||
}
|
||||
switch (kind) {
|
||||
case 'link':
|
||||
newItem = {
|
||||
...newItem,
|
||||
label: this.$t('navigation.untitled', { kind: this.$t('navigation.link') }),
|
||||
icon: 'mdi-chevron-right',
|
||||
targetType: 'home',
|
||||
target: ''
|
||||
}
|
||||
break
|
||||
case 'header':
|
||||
newItem.label = this.$t('navigation.untitled', { kind: this.$t('navigation.header') })
|
||||
break
|
||||
}
|
||||
this.currentTree = [...this.currentTree, newItem]
|
||||
this.current = newItem
|
||||
},
|
||||
deleteItem (item) {
|
||||
this.currentTree = _.pull(this.currentTree, item)
|
||||
this.current = {}
|
||||
},
|
||||
selectItem (item) {
|
||||
this.current = item
|
||||
},
|
||||
selectPage () {
|
||||
this.selectPageModal = true
|
||||
},
|
||||
selectPageHandle ({ path, locale }) {
|
||||
this.current.target = `/${locale}/${path}`
|
||||
},
|
||||
copyFromLocale () {
|
||||
this.copyFromLocaleDialogIsShown = false
|
||||
this.currentTree = [...this.currentTree, ..._.get(_.find(this.trees, ['locale', this.copyFromLocaleCode]), 'items', null) || []]
|
||||
},
|
||||
async save () {
|
||||
this.$store.commit('loadingStart', 'admin-navigation-save')
|
||||
try {
|
||||
const resp = await this.$apollo.mutate({
|
||||
mutation: gql`
|
||||
mutation ($tree: [NavigationTreeInput]!, $mode: NavigationMode!) {
|
||||
navigation{
|
||||
updateTree(tree: $tree) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
},
|
||||
updateConfig(mode: $mode) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
tree: this.trees,
|
||||
mode: this.config.mode
|
||||
}
|
||||
})
|
||||
if (_.get(resp, 'data.navigation.updateTree.responseResult.succeeded', false) && _.get(resp, 'data.navigation.updateConfig.responseResult.succeeded', false)) {
|
||||
this.$store.commit('showNotification', {
|
||||
message: this.$t('navigation.saveSuccess'),
|
||||
style: 'success',
|
||||
icon: 'check'
|
||||
})
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.navigation.updateTree.responseResult.message', 'An unexpected error occurred.'))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('pushGraphError', err)
|
||||
}
|
||||
this.$store.commit('loadingStop', 'admin-navigation-save')
|
||||
},
|
||||
async refresh () {
|
||||
await this.$apollo.queries.trees.refetch()
|
||||
this.current = {}
|
||||
this.$store.commit('showNotification', {
|
||||
message: 'Navigation has been refreshed.',
|
||||
style: 'success',
|
||||
icon: 'cached'
|
||||
})
|
||||
// COMPUTED
|
||||
|
||||
const navTypes = computed(() => ([
|
||||
{ text: t('navigation.navType.external'), value: 'external' },
|
||||
{ text: t('navigation.navType.externalblank'), value: 'externalblank' },
|
||||
{ text: t('navigation.navType.home'), value: 'home' },
|
||||
{ text: t('navigation.navType.page'), value: 'page' }
|
||||
// { text: t('navigation.navType.searchQuery'), value: 'search' }
|
||||
]))
|
||||
|
||||
const locales = computed(() => {
|
||||
return intersectionBy(state.allLocales, unionBy(siteLangs, [{ code: 'en' }, { code: siteConfig.lang }], 'code'), 'code')
|
||||
})
|
||||
|
||||
const currentTree = computed({
|
||||
get () {
|
||||
return find(state.trees, ['locale', state.currentLang])?.items || []
|
||||
},
|
||||
set (val) {
|
||||
const tree = find(state.trees, ['locale', state.currentLang])
|
||||
if (tree) {
|
||||
tree.items = val
|
||||
} else {
|
||||
state.trees = [...state.trees, {
|
||||
locale: state.currentLang,
|
||||
items: val
|
||||
}]
|
||||
}
|
||||
}
|
||||
// apollo: {
|
||||
// config: {
|
||||
// query: gql`
|
||||
// {
|
||||
// navigation {
|
||||
// config {
|
||||
// mode
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => _.cloneDeep(data.navigation.config),
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-config')
|
||||
// }
|
||||
// },
|
||||
// trees: {
|
||||
// query: gql`
|
||||
// {
|
||||
// navigation {
|
||||
// tree {
|
||||
// locale
|
||||
// items {
|
||||
// id
|
||||
// kind
|
||||
// label
|
||||
// icon
|
||||
// targetType
|
||||
// target
|
||||
// visibilityMode
|
||||
// visibilityGroups
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => _.cloneDeep(data.navigation.tree),
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-tree')
|
||||
// }
|
||||
// },
|
||||
// groups: {
|
||||
// query: gql`
|
||||
// query {
|
||||
// groups {
|
||||
// list {
|
||||
// id
|
||||
// name
|
||||
// isSystem
|
||||
// userCount
|
||||
// createdAt
|
||||
// updatedAt
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => data.groups.list,
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-groups')
|
||||
// }
|
||||
// },
|
||||
// allLocales: {
|
||||
// query: gql`
|
||||
// {
|
||||
// localization {
|
||||
// locales {
|
||||
// code
|
||||
// name
|
||||
// nativeName
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => data.localization.locales,
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-locales')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
})
|
||||
|
||||
// WATCHERS
|
||||
|
||||
watch(() => state.currentLang, (newValue, oldValue) => {
|
||||
nextTick(() => {
|
||||
if (state.currentTree.length > 0) {
|
||||
state.current = state.currentTree[0]
|
||||
} else {
|
||||
state.current = {}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// METHODS
|
||||
|
||||
async function load () {
|
||||
|
||||
}
|
||||
|
||||
function addItem (kind) {
|
||||
let newItem = {
|
||||
id: uuid(),
|
||||
kind,
|
||||
visibilityMode: 'all',
|
||||
visibilityGroups: []
|
||||
}
|
||||
switch (kind) {
|
||||
case 'link':
|
||||
newItem = {
|
||||
...newItem,
|
||||
label: t('navigation.untitled', { kind: t('navigation.link') }),
|
||||
icon: 'mdi-chevron-right',
|
||||
targetType: 'home',
|
||||
target: ''
|
||||
}
|
||||
break
|
||||
case 'header':
|
||||
newItem.label = t('navigation.untitled', { kind: t('navigation.header') })
|
||||
break
|
||||
}
|
||||
state.currentTree = [...state.currentTree, newItem]
|
||||
state.current = newItem
|
||||
}
|
||||
|
||||
function deleteItem (item) {
|
||||
state.currentTree = pull(state.currentTree, item)
|
||||
state.current = {}
|
||||
}
|
||||
|
||||
function selectItem (item) {
|
||||
state.current = item
|
||||
}
|
||||
|
||||
function selectPage () {
|
||||
state.selectPageModal = true
|
||||
}
|
||||
|
||||
function selectPageHandle ({ path, locale }) {
|
||||
state.current.target = `/${locale}/${path}`
|
||||
}
|
||||
|
||||
function copyFromLocale () {
|
||||
state.copyFromLocaleDialogIsShown = false
|
||||
state.currentTree = [...state.currentTree, ...find(state.trees, ['locale', state.copyFromLocaleCode])?.items || []]
|
||||
}
|
||||
|
||||
async function save () {
|
||||
this.$store.commit('loadingStart', 'admin-navigation-save')
|
||||
try {
|
||||
const resp = await APOLLO_CLIENT.mutate({
|
||||
mutation: gql`
|
||||
mutation ($tree: [NavigationTreeInput]!, $mode: NavigationMode!) {
|
||||
navigation{
|
||||
updateTree(tree: $tree) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
},
|
||||
updateConfig(mode: $mode) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
tree: state.trees,
|
||||
mode: state.config.mode
|
||||
}
|
||||
})
|
||||
if (resp?.data.navigation.updateTree.responseResult.succeeded && resp?.data.navigation.updateConfig.responseResult.succeeded) {
|
||||
this.$store.commit('showNotification', {
|
||||
message: t('navigation.saveSuccess'),
|
||||
style: 'success',
|
||||
icon: 'check'
|
||||
})
|
||||
} else {
|
||||
throw new Error(resp?.data.navigation.updateTree.operation.message || 'An unexpected error occurred.')
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('pushGraphError', err)
|
||||
}
|
||||
this.$store.commit('loadingStop', 'admin-navigation-save')
|
||||
}
|
||||
|
||||
async function refresh () {
|
||||
load()
|
||||
state.current = {}
|
||||
this.$store.commit('showNotification', {
|
||||
message: 'Navigation has been refreshed.',
|
||||
style: 'success',
|
||||
icon: 'cached'
|
||||
})
|
||||
}
|
||||
|
||||
// apollo: {
|
||||
// config: {
|
||||
// query: gql`
|
||||
// {
|
||||
// navigation {
|
||||
// config {
|
||||
// mode
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => _.cloneDeep(data.navigation.config),
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-config')
|
||||
// }
|
||||
// },
|
||||
// trees: {
|
||||
// query: gql`
|
||||
// {
|
||||
// navigation {
|
||||
// tree {
|
||||
// locale
|
||||
// items {
|
||||
// id
|
||||
// kind
|
||||
// label
|
||||
// icon
|
||||
// targetType
|
||||
// target
|
||||
// visibilityMode
|
||||
// visibilityGroups
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => _.cloneDeep(data.navigation.tree),
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-tree')
|
||||
// }
|
||||
// },
|
||||
// groups: {
|
||||
// query: gql`
|
||||
// query {
|
||||
// groups {
|
||||
// list {
|
||||
// id
|
||||
// name
|
||||
// isSystem
|
||||
// userCount
|
||||
// createdAt
|
||||
// updatedAt
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => data.groups.list,
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-groups')
|
||||
// }
|
||||
// },
|
||||
// allLocales: {
|
||||
// query: gql`
|
||||
// {
|
||||
// localization {
|
||||
// locales {
|
||||
// code
|
||||
// name
|
||||
// nativeName
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// fetchPolicy: 'network-only',
|
||||
// update: (data) => data.localization.locales,
|
||||
// watchLoading (isLoading) {
|
||||
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-locales')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
@@ -323,9 +323,8 @@ q-page.admin-mail
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import gql from 'graphql-tag'
|
||||
import _get from 'lodash/get'
|
||||
import filesize from 'filesize'
|
||||
import filesizeParser from 'filesize-parser'
|
||||
|
||||
@@ -492,7 +491,7 @@ async function save () {
|
||||
uploadMaxFileSize: filesizeParser(state.humanUploadMaxFileSize || '0')
|
||||
}
|
||||
})
|
||||
const resp = _get(respRaw, 'data.updateSystemSecurity.status', {})
|
||||
const resp = respRaw?.data?.updateSystemSecurity?.status || {}
|
||||
if (resp.succeeded) {
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
|
||||
@@ -583,10 +583,8 @@ q-page.admin-storage
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import find from 'lodash/find'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep, find, transform } from 'lodash-es'
|
||||
import gql from 'graphql-tag'
|
||||
import transform from 'lodash/transform'
|
||||
import * as VNetworkGraph from 'v-network-graph'
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@@ -227,7 +227,7 @@ q-page.admin-system
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import gql from 'graphql-tag'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
|
||||
@@ -203,8 +203,7 @@ q-page.admin-theme
|
||||
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import startCase from 'lodash/startCase'
|
||||
import { cloneDeep, startCase } from 'lodash-es'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { onMounted, reactive, watch } from 'vue'
|
||||
|
||||
@@ -106,7 +106,7 @@ q-page.admin-groups
|
||||
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { DateTime } from 'luxon'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
|
||||
@@ -92,7 +92,7 @@ q-page.admin-webhooks
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@@ -35,12 +35,12 @@ const routes = [
|
||||
{ path: ':siteid/editors', component: () => import('../pages/AdminEditors.vue') },
|
||||
{ path: ':siteid/locale', component: () => import('../pages/AdminLocale.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/rendering', component: () => import('../pages/AdminRendering.vue') },
|
||||
{ path: ':siteid/storage/:id?', component: () => import('../pages/AdminStorage.vue') },
|
||||
{ path: ':siteid/theme', component: () => import('../pages/AdminTheme.vue') },
|
||||
// -> 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: 'users/:id?/:section?', component: () => import('../pages/AdminUsers.vue') },
|
||||
// -> System
|
||||
|
||||
@@ -4702,6 +4702,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash-es@npm:4.17.21":
|
||||
version: 4.17.21
|
||||
resolution: "lodash-es@npm:4.17.21"
|
||||
checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash._reinterpolate@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "lodash._reinterpolate@npm:3.0.0"
|
||||
@@ -6844,6 +6851,7 @@ __metadata:
|
||||
js-cookie: 3.0.1
|
||||
jwt-decode: 3.1.2
|
||||
lodash: 4.17.21
|
||||
lodash-es: 4.17.21
|
||||
luxon: 2.4.0
|
||||
pinia: 2.0.14
|
||||
pug: 3.0.2
|
||||
|
||||
Reference in New Issue
Block a user