diff --git a/server/app/data.yml b/server/app/data.yml
index cb66ecbd..96aacea1 100644
--- a/server/app/data.yml
+++ b/server/app/data.yml
@@ -71,8 +71,9 @@ defaults:
authJwtRenewablePeriod: '14d'
enforceSameOriginReferrerPolicy: true
flags:
- ldapdebug: false
- sqllog: false
+ experimental: false
+ authDebug: false
+ sqlLog: false
# System defaults
channel: NEXT
cors:
diff --git a/server/core/config.js b/server/core/config.js
index 6108a54a..bd535147 100644
--- a/server/core/config.js
+++ b/server/core/config.js
@@ -133,7 +133,7 @@ module.exports = {
* Apply Dev Flags
*/
async applyFlags() {
- WIKI.db.knex.client.config.debug = WIKI.config.flags.sqllog
+ WIKI.db.knex.client.config.debug = WIKI.config.flags.sqlLog
},
/**
diff --git a/server/db/migrations/3.0.0.js b/server/db/migrations/3.0.0.js
index c7e4e3eb..64217a2b 100644
--- a/server/db/migrations/3.0.0.js
+++ b/server/db/migrations/3.0.0.js
@@ -285,7 +285,7 @@ exports.up = async knex => {
table.specificType('folderPath', 'ltree').index().index('tree_folderpath_gist_index', { indexType: 'GIST' })
table.string('fileName').notNullable().index()
table.enu('type', ['folder', 'page', 'asset']).notNullable().index()
- table.uuid('targetId').index()
+ table.string('localeCode', 5).notNullable().defaultTo('en').index()
table.string('title').notNullable()
table.jsonb('meta').notNullable().defaultTo('{}')
table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
@@ -372,6 +372,7 @@ exports.up = async knex => {
table.string('localeCode', 5).references('code').inTable('locales').index()
table.uuid('authorId').notNullable().references('id').inTable('users').index()
table.uuid('creatorId').notNullable().references('id').inTable('users').index()
+ table.uuid('ownerId').notNullable().references('id').inTable('users').index()
table.uuid('siteId').notNullable().references('id').inTable('sites').index()
})
.table('storage', table => {
@@ -439,6 +440,14 @@ exports.up = async knex => {
guestUserId: userGuestId
}
},
+ {
+ key: 'flags',
+ value: {
+ experimental: false,
+ authDebug: false,
+ sqlLog: false
+ }
+ },
{
key: 'icons',
value: {
diff --git a/server/graph/resolvers/system.js b/server/graph/resolvers/system.js
index 36d777b3..8e636890 100644
--- a/server/graph/resolvers/system.js
+++ b/server/graph/resolvers/system.js
@@ -11,9 +11,7 @@ const graphHelper = require('../../helpers/graph')
module.exports = {
Query: {
systemFlags () {
- return _.transform(WIKI.config.flags, (result, value, key) => {
- result.push({ key, value })
- }, [])
+ return WIKI.config.flags
},
async systemInfo () { return {} },
async systemExtensions () {
@@ -150,9 +148,10 @@ module.exports = {
}
},
async updateSystemFlags (obj, args, context) {
- WIKI.config.flags = _.transform(args.flags, (result, row) => {
- _.set(result, row.key, row.value)
- }, {})
+ WIKI.config.flags = {
+ ...WIKI.config.flags,
+ ...args.flags
+ }
await WIKI.configSvc.applyFlags()
await WIKI.configSvc.saveToDb(['flags'])
return {
@@ -164,7 +163,7 @@ module.exports = {
// TODO: broadcast config update
await WIKI.configSvc.saveToDb(['security'])
return {
- status: graphHelper.generateSuccess('System Security configuration applied successfully')
+ operation: graphHelper.generateSuccess('System Security configuration applied successfully')
}
}
},
diff --git a/server/graph/resolvers/tree.js b/server/graph/resolvers/tree.js
index 5e9a600e..7787d280 100644
--- a/server/graph/resolvers/tree.js
+++ b/server/graph/resolvers/tree.js
@@ -7,7 +7,7 @@ const typeResolvers = {
asset: 'TreeItemAsset'
}
-const rePathName = /^[a-z0-9_]+$/
+const rePathName = /^[a-z0-9-]+$/
const reTitle = /^[^<>"]+$/
module.exports = {
@@ -41,7 +41,7 @@ module.exports = {
if (args.parentId) {
const parent = await WIKI.db.knex('tree').where('id', args.parentId).first()
if (parent) {
- parentPath = parent.folderPath ? `${parent.folderPath}.${parent.fileName}` : parent.fileName
+ parentPath = (parent.folderPath ? `${parent.folderPath}.${parent.fileName}` : parent.fileName).replaceAll('-', '_')
}
} else if (args.parentPath) {
parentPath = args.parentPath.replaceAll('/', '.').replaceAll('-', '_').toLowerCase()
@@ -101,11 +101,11 @@ module.exports = {
if (parent) {
parentPath = parent.folderPath ? `${parent.folderPath}.${parent.fileName}` : parent.fileName
}
+ parentPath = parentPath.replaceAll('-', '_')
}
// Validate path name
- const pathName = args.pathName.replaceAll('-', '_')
- if (!rePathName.test(pathName)) {
+ if (!rePathName.test(args.pathName)) {
throw new Error('ERR_INVALID_PATH_NAME')
}
@@ -118,7 +118,7 @@ module.exports = {
const existingFolder = await WIKI.db.knex('tree').where({
siteId: args.siteId,
folderPath: parentPath,
- fileName: pathName
+ fileName: args.pathName
}).first()
if (existingFolder) {
throw new Error('ERR_FOLDER_ALREADY_EXISTS')
@@ -127,7 +127,7 @@ module.exports = {
// Create folder
await WIKI.db.knex('tree').insert({
folderPath: parentPath,
- fileName: pathName,
+ fileName: args.pathName,
type: 'folder',
title: args.title,
siteId: args.siteId
diff --git a/server/graph/schemas/system.graphql b/server/graph/schemas/system.graphql
index c79428ae..8b71030f 100644
--- a/server/graph/schemas/system.graphql
+++ b/server/graph/schemas/system.graphql
@@ -4,7 +4,7 @@
extend type Query {
systemExtensions: [SystemExtension]
- systemFlags: [SystemFlag]
+ systemFlags: JSON
systemInfo: SystemInfo
systemInstances: [SystemInstance]
systemSecurity: SystemSecurity
@@ -31,7 +31,7 @@ extend type Mutation {
): DefaultResponse
updateSystemFlags(
- flags: [SystemFlagInput]!
+ flags: JSON!
): DefaultResponse
updateSystemSecurity(
@@ -60,16 +60,6 @@ extend type Mutation {
# TYPES
# -----------------------------------------------
-type SystemFlag {
- key: String
- value: Boolean
-}
-
-input SystemFlagInput {
- key: String!
- value: Boolean!
-}
-
type SystemInfo {
configFile: String
cpuCores: Int
diff --git a/server/models/pages.js b/server/models/pages.js
index a7bac632..9356239a 100644
--- a/server/models/pages.js
+++ b/server/models/pages.js
@@ -310,12 +310,12 @@ module.exports = class Page extends Model {
},
contentType: WIKI.data.editors[opts.editor]?.contentType ?? 'text',
description: opts.description,
- // dotPath: dotPath,
editor: opts.editor,
hash: pageHelper.generateHash({ path: opts.path, locale: opts.locale }),
icon: opts.icon,
isBrowsable: opts.isBrowsable ?? true,
localeCode: opts.locale,
+ ownerId: opts.user.id,
path: opts.path,
publishState: opts.publishState,
publishEndDate: opts.publishEndDate?.toISO(),
@@ -339,6 +339,29 @@ module.exports = class Page extends Model {
// -> Render page to HTML
await WIKI.db.pages.renderPage(page)
+ // -> Add to tree
+ const pathParts = page.path.split('/')
+ await WIKI.db.knex('tree').insert({
+ id: page.id,
+ folderPath: _.initial(pathParts).join('/'),
+ fileName: _.last(pathParts),
+ type: 'page',
+ localeCode: page.localeCode,
+ title: page.title,
+ meta: {
+ authorId: page.authorId,
+ contentType: page.contentType,
+ creatorId: page.creatorId,
+ description: page.description,
+ isBrowsable: page.isBrowsable,
+ ownerId: page.ownerId,
+ publishState: page.publishState,
+ publishEndDate: page.publishEndDate,
+ publishStartDate: page.publishStartDate
+ },
+ siteId: page.siteId
+ })
+
return page
// TODO: Handle remaining flow
@@ -590,6 +613,23 @@ module.exports = class Page extends Model {
}
WIKI.events.outbound.emit('deletePageFromCache', page.hash)
+ // -> Update tree
+ await WIKI.db.knex('tree').where('id', page.id).update({
+ title: page.title,
+ meta: {
+ authorId: page.authorId,
+ contentType: page.contentType,
+ creatorId: page.creatorId,
+ description: page.description,
+ isBrowsable: page.isBrowsable,
+ ownerId: page.ownerId,
+ publishState: page.publishState,
+ publishEndDate: page.publishEndDate,
+ publishStartDate: page.publishStartDate
+ },
+ updatedAt: page.updatedAt
+ })
+
// // -> Update Search Index
// const pageContents = await WIKI.db.pages.query().findById(page.id).select('render')
// page.safeContent = WIKI.db.pages.cleanHTML(pageContents.render)
@@ -948,12 +988,10 @@ module.exports = class Page extends Model {
// -> Delete page
await WIKI.db.pages.query().delete().where('id', page.id)
+ await WIKI.db.knex('tree').where('id', page.id).del()
await WIKI.db.pages.deletePageFromCache(page.hash)
WIKI.events.outbound.emit('deletePageFromCache', page.hash)
- // -> Rebuild page tree
- await WIKI.db.pages.rebuildTree()
-
// -> Delete from Search Index
await WIKI.data.searchEngine.deleted(page)
diff --git a/ux/public/_assets/icons/ultraviolet-administrative-tools.svg b/ux/public/_assets/icons/ultraviolet-administrative-tools.svg
new file mode 100644
index 00000000..9c924a18
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-administrative-tools.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ux/public/_assets/icons/ultraviolet-asciidoc.svg b/ux/public/_assets/icons/ultraviolet-asciidoc.svg
new file mode 100644
index 00000000..b423da0b
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-asciidoc.svg
@@ -0,0 +1,8 @@
+
+
+
diff --git a/ux/src/App.vue b/ux/src/App.vue
index b88ec1bf..74c2e44d 100644
--- a/ux/src/App.vue
+++ b/ux/src/App.vue
@@ -5,6 +5,7 @@ router-view
diff --git a/ux/src/components/PageNewMenu.vue b/ux/src/components/PageNewMenu.vue
index 1f2ec6a4..867162af 100644
--- a/ux/src/components/PageNewMenu.vue
+++ b/ux/src/components/PageNewMenu.vue
@@ -11,15 +11,19 @@ q-menu.translucent-menu(
q-item(clickable, @click='create(`markdown`)')
blueprint-icon(icon='markdown')
q-item-section.q-pr-sm New Markdown Page
- q-item(clickable, @click='create(`channel`)')
- blueprint-icon(icon='chat')
- q-item-section.q-pr-sm New Discussion Space
- q-item(clickable, @click='create(`blog`)')
- blueprint-icon(icon='typewriter-with-paper')
- q-item-section.q-pr-sm New Blog Page
- q-item(clickable, @click='create(`api`)')
- blueprint-icon(icon='api')
- q-item-section.q-pr-sm New API Documentation
+ q-item(clickable, @click='create(`asciidoc`)')
+ blueprint-icon(icon='asciidoc')
+ q-item-section.q-pr-sm New AsciiDoc Page
+ template(v-if='flagsStore.experimental')
+ q-item(clickable, @click='create(`channel`)')
+ blueprint-icon(icon='chat')
+ q-item-section.q-pr-sm New Discussion Space
+ q-item(clickable, @click='create(`blog`)')
+ blueprint-icon(icon='typewriter-with-paper')
+ q-item-section.q-pr-sm New Blog Page
+ q-item(clickable, @click='create(`api`)')
+ blueprint-icon(icon='api')
+ q-item-section.q-pr-sm New API Documentation
q-item(clickable, @click='create(`redirect`)')
blueprint-icon(icon='advance')
q-item-section.q-pr-sm New Redirection
@@ -41,6 +45,7 @@ import { useQuasar } from 'quasar'
import { usePageStore } from 'src/stores/page'
import { useSiteStore } from 'src/stores/site'
+import { useFlagsStore } from 'src/stores/flags'
// PROPS
@@ -65,6 +70,7 @@ const $q = useQuasar()
// STORES
+const flagsStore = useFlagsStore()
const pageStore = usePageStore()
const siteStore = useSiteStore()
diff --git a/ux/src/components/PageSaveDialog.vue b/ux/src/components/PageSaveDialog.vue
index a929fdfc..357cd8c5 100644
--- a/ux/src/components/PageSaveDialog.vue
+++ b/ux/src/components/PageSaveDialog.vue
@@ -5,17 +5,23 @@ q-dialog(ref='dialogRef', @hide='onDialogHide')
q-icon(name='img:/_assets/icons/fluent-save-as.svg', left, size='sm')
span {{t('pageSaveDialog.title')}}
.row.page-save-dialog-browser
- .col-4.q-px-sm
- tree(
- :nodes='state.treeNodes'
- :roots='state.treeRoots'
- v-model:selected='state.currentFolderId'
- @lazy-load='treeLazyLoad'
- :use-lazy-load='true'
- @context-action='treeContextAction'
- :context-action-list='[`newFolder`]'
- :display-mode='state.displayMode'
- )
+ .col-4
+ q-scroll-area(
+ :thumb-style='thumbStyle'
+ :bar-style='barStyle'
+ style='height: 300px'
+ )
+ .q-px-sm
+ tree(
+ :nodes='state.treeNodes'
+ :roots='state.treeRoots'
+ v-model:selected='state.currentFolderId'
+ @lazy-load='treeLazyLoad'
+ :use-lazy-load='true'
+ @context-action='treeContextAction'
+ :context-action-list='[`newFolder`]'
+ :display-mode='state.displayMode'
+ )
.col-8
q-list.page-save-dialog-filelist(dense)
q-item(
@@ -31,6 +37,7 @@ q-dialog(ref='dialogRef', @hide='onDialogHide')
q-icon(:name='item.icon', size='sm')
q-item-section
q-item-label {{item.title}}
+ .page-save-dialog-path.font-robotomono {{folderPath}}
q-list.q-py-sm
q-item
blueprint-icon(icon='new-document')
@@ -197,8 +204,28 @@ const displayModes = [
{ value: 'path', label: t('pageSaveDialog.displayModePath') }
]
+const thumbStyle = {
+ right: '1px',
+ borderRadius: '5px',
+ backgroundColor: '#666',
+ width: '5px',
+ opacity: 0.5
+}
+const barStyle = {
+ width: '7px'
+}
+
// COMPUTED
+const folderPath = computed(() => {
+ if (!state.currentFolderId) {
+ return '/'
+ } else {
+ const folderNode = state.treeNodes[state.currentFolderId] ?? {}
+ return folderNode.folderPath ? `/${folderNode.folderPath}/${folderNode.fileName}/` : `/${folderNode.fileName}/`
+ }
+})
+
const files = computed(() => {
return state.fileList.map(f => {
switch (f.type) {
@@ -274,8 +301,9 @@ async function loadTree (parentId, types) {
switch (item.__typename) {
case 'TreeItemFolder': {
state.treeNodes[item.id] = {
- text: item.title,
+ folderPath: item.folderPath,
fileName: item.fileName,
+ title: item.title,
children: []
}
if (!item.folderPath) {
@@ -336,16 +364,23 @@ onMounted(() => {
&-browser {
height: 300px;
max-height: 90vh;
- border-bottom: 1px solid $blue-grey-1;
+ border-bottom: 1px solid #FFF;
+
+ @at-root .body--light & {
+ border-bottom-color: $blue-grey-1;
+ }
+ @at-root .body--dark & {
+ border-bottom-color: $dark-3;
+ }
> .col-4 {
+ height: 300px;
+
@at-root .body--light & {
background-color: $blue-grey-1;
- border-bottom-color: $blue-grey-1;
}
@at-root .body--dark & {
background-color: $dark-4;
- border-bottom-color: $dark-4;
}
}
}
@@ -372,5 +407,22 @@ onMounted(() => {
}
}
+ &-path {
+ padding: 5px 16px;
+ font-size: 12px;
+ border-bottom: 1px solid #FFF;
+
+ @at-root .body--light & {
+ background-color: lighten($blue-grey-1, 4%);
+ border-bottom-color: $blue-grey-1;
+ color: $blue-grey-9;
+ }
+ @at-root .body--dark & {
+ background-color: darken($dark-4, 1%);
+ border-bottom-color: $dark-1;
+ color: $blue-grey-3;
+ }
+ }
+
}
diff --git a/ux/src/components/TreeNav.vue b/ux/src/components/TreeNav.vue
index 4b42de0e..45d651ce 100644
--- a/ux/src/components/TreeNav.vue
+++ b/ux/src/components/TreeNav.vue
@@ -95,7 +95,7 @@ const state = reactive({
opened: {}
})
-// COMPOUTED
+// COMPUTED
const selection = computed({
get () {
@@ -120,6 +120,16 @@ function emitContextAction (nodeId, action) {
emit('contextAction', nodeId, action)
}
+function setOpened (nodeId) {
+ state.opened[nodeId] = true
+}
+function isLoaded (nodeId) {
+ return state.loaded[nodeId]
+}
+function resetLoaded (nodeId) {
+ state.loaded[nodeId] = false
+}
+
// PROVIDE
provide('roots', toRef(props, 'roots'))
@@ -131,6 +141,14 @@ provide('selection', selection)
provide('emitLazyLoad', emitLazyLoad)
provide('emitContextAction', emitContextAction)
+// EXPOSE
+
+defineExpose({
+ setOpened,
+ isLoaded,
+ resetLoaded
+})
+
// MOUNTED
onMounted(() => {
diff --git a/ux/src/components/TreeNode.vue b/ux/src/components/TreeNode.vue
index 29f991d0..5e969edf 100644
--- a/ux/src/components/TreeNode.vue
+++ b/ux/src/components/TreeNode.vue
@@ -7,7 +7,7 @@ li.treeview-node
size='sm'
@click.stop='hasChildren ? toggleNode() : openNode()'
)
- .treeview-label-text {{displayMode === 'path' ? node.fileName : node.text}}
+ .treeview-label-text {{displayMode === 'path' ? node.fileName : node.title}}
q-spinner.q-mr-xs(
color='primary'
v-if='state.isLoading'
diff --git a/ux/src/i18n/locales/en.json b/ux/src/i18n/locales/en.json
index 66e08e82..50d2ac4e 100644
--- a/ux/src/i18n/locales/en.json
+++ b/ux/src/i18n/locales/en.json
@@ -157,15 +157,13 @@
"admin.extensions.requiresSharp": "Requires Sharp extension",
"admin.extensions.subtitle": "Install extensions for extra functionality",
"admin.extensions.title": "Extensions",
- "admin.flags.hidedonatebtn.hint": "You have already donated to this project (thank you!) and want to hide the button from the administration area.",
- "admin.flags.hidedonatebtn.label": "Hide Donate Button",
- "admin.flags.ldapdebug.hint": "Log detailed debug info on LDAP/AD login attempts.",
- "admin.flags.ldapdebug.label": "LDAP Debug",
- "admin.flags.sqllog.hint": "Log all queries made to the database to console.",
- "admin.flags.sqllog.label": "SQL Query Logging",
+ "admin.flags.authDebug.hint": "Log detailed debug info of all login / registration attempts.",
+ "admin.flags.authDebug.label": "Auth Debug",
+ "admin.flags.sqlLog.hint": "Log all queries made to the database to console.",
+ "admin.flags.sqlLog.label": "SQL Query Logging",
"admin.flags.subtitle": "Low-level system flags for debugging or experimental purposes",
"admin.flags.title": "Flags",
- "admin.flags.warn.hint": "Doing so may result in data loss or broken installation!",
+ "admin.flags.warn.hint": "Doing so may result in data loss, performance issues or a broken installation!",
"admin.flags.warn.label": "Do NOT enable these flags unless you know what you're doing!",
"admin.general.allowComments": "Allow Comments",
"admin.general.allowCommentsHint": "Can users leave comments on pages? Can be restricted using Page Rules.",
@@ -1603,5 +1601,14 @@
"common.actions.duplicate": "Duplicate",
"common.actions.moveTo": "Move To",
"pageSaveDialog.displayModeTitle": "Title",
- "pageSaveDialog.displayModePath": "Path"
+ "pageSaveDialog.displayModePath": "Path",
+ "folderDeleteDialog.title": "Confirm Delete Folder",
+ "folderDeleteDialog.confirm": "Are you sure you want to delete folder {name} and all its content?",
+ "folderDeleteDialog.folderId": "Folder ID {id}",
+ "folderDeleteDialog.deleteSuccess": "Folder has been deleted successfully.",
+ "admin.flags.experimental.label": "Experimental Features",
+ "admin.flags.experimental.hint": "Enable unstable / unfinished features. DO NOT enable in a production environment!",
+ "admin.flags.advanced.label": "Custom Configuration",
+ "admin.flags.advanced.hint": "Set custom configuration flags. Note that all values are public to all users! Do not insert senstive data.",
+ "admin.flags.saveSuccess": "Flags have been updated successfully."
}
diff --git a/ux/src/layouts/AdminLayout.vue b/ux/src/layouts/AdminLayout.vue
index b39f64a1..41560247 100644
--- a/ux/src/layouts/AdminLayout.vue
+++ b/ux/src/layouts/AdminLayout.vue
@@ -29,7 +29,7 @@ q-layout.admin(view='hHh Lpr lff')
:thumb-style='thumbStyle'
:bar-style='barStyle'
)
- q-list.text-white(padding, dense)
+ q-list.text-white.q-pb-lg(padding, dense)
q-item.q-mb-sm
q-item-section
q-btn.acrylic-btn(
diff --git a/ux/src/layouts/ProfileLayout.vue b/ux/src/layouts/ProfileLayout.vue
index 2d8fb3db..126d1687 100644
--- a/ux/src/layouts/ProfileLayout.vue
+++ b/ux/src/layouts/ProfileLayout.vue
@@ -5,19 +5,19 @@ q-layout(view='hHh Lpr lff')
.layout-profile-card
.layout-profile-sd
q-list
- q-item(
- v-for='navItem of sidenav'
- :key='navItem.key'
- clickable
- :to='`/_profile/` + navItem.key'
- active-class='is-active'
- :disabled='navItem.disabled'
- v-ripple
- )
- q-item-section(side)
- q-icon(:name='navItem.icon')
- q-item-section
- q-item-label {{navItem.label}}
+ template(v-for='navItem of sidenav' :key='navItem.key')
+ q-item(
+ v-if='!navItem.disabled || flagsStore.experimental'
+ clickable
+ :to='`/_profile/` + navItem.key'
+ active-class='is-active'
+ :disabled='navItem.disabled'
+ v-ripple
+ )
+ q-item-section(side)
+ q-icon(:name='navItem.icon')
+ q-item-section
+ q-item-label {{navItem.label}}
q-separator.q-my-sm(inset)
q-item(
clickable
@@ -48,6 +48,7 @@ import { useI18n } from 'vue-i18n'
import { useMeta, useQuasar } from 'quasar'
import { onMounted, reactive, watch } from 'vue'
+import { useFlagsStore } from 'src/stores/flags'
import { useSiteStore } from 'src/stores/site'
import { useUserStore } from 'src/stores/user'
@@ -61,6 +62,7 @@ const $q = useQuasar()
// STORES
+const flagsStore = useFlagsStore()
const siteStore = useSiteStore()
const userStore = useUserStore()
diff --git a/ux/src/pages/AdminFlags.vue b/ux/src/pages/AdminFlags.vue
index 3c7893ad..4123f9ef 100644
--- a/ux/src/pages/AdminFlags.vue
+++ b/ux/src/pages/AdminFlags.vue
@@ -15,13 +15,20 @@ q-page.admin-flags
target='_blank'
type='a'
)
+ q-btn.q-mr-sm.acrylic-btn(
+ icon='las la-redo-alt'
+ flat
+ color='secondary'
+ :loading='state.loading > 0'
+ @click='load'
+ )
q-btn(
unelevated
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
@@ -39,44 +46,60 @@ q-page.admin-flags
q-item(tag='label')
blueprint-icon(icon='flag-filled')
q-item-section
- q-item-label {{t(`admin.flags.ldapdebug.label`)}}
- q-item-label(caption) {{t(`admin.flags.ldapdebug.hint`)}}
+ q-item-label {{t(`admin.flags.experimental.label`)}}
+ q-item-label(caption) {{t(`admin.flags.experimental.hint`)}}
q-item-section(avatar)
q-toggle(
- v-model='flags.ldapdebug'
- color='primary'
+ v-model='state.flags.experimental'
+ color='negative'
checked-icon='las la-check'
unchecked-icon='las la-times'
- :aria-label='t(`admin.flags.ldapdebug.label`)'
+ :aria-label='t(`admin.flags.experimental.label`)'
)
q-separator.q-my-sm(inset)
q-item(tag='label')
blueprint-icon(icon='flag-filled')
q-item-section
- q-item-label {{t(`admin.flags.sqllog.label`)}}
- q-item-label(caption) {{t(`admin.flags.sqllog.hint`)}}
+ q-item-label {{t(`admin.flags.authDebug.label`)}}
+ q-item-label(caption) {{t(`admin.flags.authDebug.hint`)}}
q-item-section(avatar)
q-toggle(
- v-model='flags.sqllog'
- color='primary'
+ v-model='state.flags.authDebug'
+ color='negative'
checked-icon='las la-check'
unchecked-icon='las la-times'
- :aria-label='t(`admin.flags.sqllog.label`)'
+ :aria-label='t(`admin.flags.authDebug.label`)'
)
- q-card.shadow-1.q-py-sm.q-mt-md
+ q-separator.q-my-sm(inset)
q-item(tag='label')
- blueprint-icon(icon='heart-outline')
+ blueprint-icon(icon='flag-filled')
q-item-section
- q-item-label {{t(`admin.flags.hidedonatebtn.label`)}}
- q-item-label(caption) {{t(`admin.flags.hidedonatebtn.hint`)}}
+ q-item-label {{t(`admin.flags.sqlLog.label`)}}
+ q-item-label(caption) {{t(`admin.flags.sqlLog.hint`)}}
q-item-section(avatar)
q-toggle(
- v-model='flags.hidedonatebtn'
- color='primary'
+ v-model='state.flags.sqlLog'
+ color='negative'
checked-icon='las la-check'
unchecked-icon='las la-times'
- :aria-label='t(`admin.flags.hidedonatebtn.label`)'
+ :aria-label='t(`admin.flags.sqlLog.label`)'
)
+ q-card.shadow-1.q-py-sm.q-mt-md
+ q-item
+ blueprint-icon(icon='administrative-tools')
+ q-item-section
+ q-item-label {{t(`admin.flags.advanced.label`)}}
+ q-item-label(caption) {{t(`admin.flags.advanced.hint`)}}
+ q-item-section(avatar)
+ q-btn(
+ :label='t(`common.actions.edit`)'
+ unelevated
+ icon='las la-code'
+ color='primary'
+ text-color='white'
+ @click=''
+ disabled
+ )
.col-12.col-lg-5.gt-md
.q-pa-md.text-center
@@ -85,12 +108,13 @@ q-page.admin-flags