Skip to content

Commit

Permalink
feat: edit navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
NGPixel committed Jul 25, 2023
1 parent 5eaba2c commit 607b8d8
Show file tree
Hide file tree
Showing 26 changed files with 832 additions and 170 deletions.
20 changes: 10 additions & 10 deletions server/db/migrations/3.0.0.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ export async function up (knex) {
// NAVIGATION ----------------------------
.createTable('navigation', table => {
table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
table.string('name').notNullable()
table.jsonb('items').notNullable().defaultTo('[]')
})
// PAGE HISTORY ------------------------
Expand Down Expand Up @@ -298,6 +297,8 @@ export async function up (knex) {
table.enu('type', ['folder', 'page', 'asset']).notNullable().index()
table.string('locale', 10).notNullable().defaultTo('en').index()
table.string('title').notNullable()
table.enum('navigationMode', ['inherit', 'override', 'overrideExact', 'hide', 'hideExact']).notNullable().defaultTo('inherit').index()
table.uuid('navigationId').index()
table.jsonb('meta').notNullable().defaultTo('{}')
table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
Expand Down Expand Up @@ -393,7 +394,6 @@ export async function up (knex) {
table.unique(['siteId', 'tag'])
})
.table('tree', table => {
table.uuid('navigationId').references('id').inTable('navigation').index()
table.uuid('siteId').notNullable().references('id').inTable('sites')
})
.table('userKeys', table => {
Expand All @@ -415,7 +415,6 @@ export async function up (knex) {

const groupAdminId = uuid()
const groupGuestId = '10000000-0000-4000-8000-000000000001'
const navDefaultId = uuid()
const siteId = uuid()
const authModuleId = uuid()
const userAdminId = uuid()
Expand Down Expand Up @@ -568,6 +567,7 @@ export async function up (knex) {
}
},
features: {
browse: true,
ratings: false,
ratingsMode: 'off',
comments: false,
Expand Down Expand Up @@ -622,10 +622,6 @@ export async function up (knex) {
config: {}
}
},
nav: {
mode: 'mixed',
defaultId: navDefaultId,
},
theme: {
dark: false,
codeBlocksTheme: 'github-dark',
Expand Down Expand Up @@ -757,13 +753,13 @@ export async function up (knex) {
// -> NAVIGATION

await knex('navigation').insert({
id: navDefaultId,
name: 'Default',
id: siteId,
items: JSON.stringify([
{
id: uuid(),
type: 'header',
label: 'Sample Header'
label: 'Sample Header',
visibilityGroups: []
},
{
id: uuid(),
Expand All @@ -772,6 +768,7 @@ export async function up (knex) {
label: 'Sample Link 1',
target: '/',
openInNewWindow: false,
visibilityGroups: [],
children: []
},
{
Expand All @@ -781,11 +778,13 @@ export async function up (knex) {
label: 'Sample Link 2',
target: '/',
openInNewWindow: false,
visibilityGroups: [],
children: []
},
{
id: uuid(),
type: 'separator',
visibilityGroups: []
},
{
id: uuid(),
Expand All @@ -794,6 +793,7 @@ export async function up (knex) {
label: 'Sample Link 3',
target: '/',
openInNewWindow: false,
visibilityGroups: [],
children: []
}
]),
Expand Down
112 changes: 108 additions & 4 deletions server/graph/resolvers/navigation.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { generateError, generateSuccess } from '../../helpers/graph.mjs'
import { isNil } from 'lodash-es'

export default {
Query: {
Expand All @@ -9,15 +10,118 @@ export default {
Mutation: {
async updateNavigation (obj, args, context) {
try {
// await WIKI.db.navigation.query().patch({
// config: args.tree
// }).where('key', 'site')
let updateInherited = false
let updateInheritedNavId = null
let updateNavId = null
let ancestorNavId = null

const treeEntry = await WIKI.db.knex('tree').where('id', args.pageId).first()
if (!treeEntry) {
throw new Error('Invalid ID')
}
const currentNavId = treeEntry.folderPath === '' && treeEntry.fileName === 'home' ? treeEntry.siteId : treeEntry.id
const treeEntryPath = treeEntry.folderPath ? `${treeEntry.folderPath}.${treeEntry.fileName}` : treeEntry.fileName

// -> Create / Update Nav Menu Items
if (!isNil(args.items)) {
await WIKI.db.knex('navigation').insert({
id: currentNavId,
items: JSON.stringify(args.items),
siteId: treeEntry.siteId
}).onConflict('id').merge({
items: JSON.stringify(args.items)
})
}

// -> Find ancestor nav ID
const ancNavResult = await WIKI.db.knex.raw(`
SELECT "navigationId", "navigationMode", nlevel("folderPath" || "fileName") AS levels
FROM tree
WHERE ("folderPath" || "fileName") @> :currentPath
AND "navigationMode" IN ('override', 'hide')
ORDER BY levels DESC
LIMIT 1
`, {
currentPath: treeEntry.folderPath
})
if (ancNavResult.rowCount > 0) {
ancestorNavId = ancNavResult.rows[0]?.navigationId
} else {
ancestorNavId = treeEntry.siteId
}

// -> Update mode
switch (args.mode) {
case 'inherit': {
updateNavId = ancestorNavId
if (['override', 'hide'].includes(treeEntry.navigationMode)) {
updateInherited = true
updateInheritedNavId = ancestorNavId
}
break
}
case 'override': {
updateNavId = treeEntry.id
updateInherited = true
updateInheritedNavId = treeEntry.id
break
}
case 'overrideExact': {
updateNavId = treeEntry.id
if (['override', 'hide'].includes(treeEntry.navigationMode)) {
updateInherited = true
updateInheritedNavId = ancestorNavId
}
break
}
case 'hide': {
updateInherited = true
updateNavId = null
break
}
case 'hideExact': {
updateNavId = null
if (['override', 'hide'].includes(treeEntry.navigationMode)) {
updateInherited = true
updateInheritedNavId = ancestorNavId
}
break
}
}

// -> Set for current path
await WIKI.db.knex('tree').where('id', treeEntry.id).update({ navigationMode: args.mode, navigationId: updateNavId })

// -> Update nodes that inherit from current
if (updateInherited) {
await WIKI.db.knex.raw(`
UPDATE tree tt
SET "navigationId" = :navId
WHERE type IN ('page', 'folder')
AND "folderPath" <@ :overridePath
AND "navigationMode" = 'inherit'
AND NOT EXISTS (
SELECT 1
FROM tree tc
WHERE type IN ('page', 'folder')
AND tc."folderPath" <@ :overridePath
AND tc."folderPath" @> tt."folderPath"
AND tc."navigationMode" IN ('override', 'hide')
)
`, {
navId: updateInheritedNavId,
overridePath: treeEntryPath
})
}

// for (const tree of args.tree) {
// await WIKI.cache.set(`nav:sidebar:${tree.locale}`, tree.items, 300)
// }

return {
responseResult: generateSuccess('Navigation updated successfully')
operation: generateSuccess('Navigation updated successfully'),
navigationMode: args.mode,
navigationId: updateNavId
}
} catch (err) {
return generateError(err)
Expand Down
42 changes: 37 additions & 5 deletions server/graph/schemas/navigation.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ extend type Query {

extend type Mutation {
updateNavigation(
id: UUID!
name: String!
items: [JSON]!
): DefaultResponse
pageId: UUID!
mode: NavigationMode!
items: [NavigationItemInput!]
): NavigationUpdateResponse
}

# -----------------------------------------------
Expand All @@ -26,10 +26,42 @@ extend type Mutation {

type NavigationItem {
id: UUID
type: String
type: NavigationItemType
label: String
icon: String
target: String
openInNewWindow: Boolean
visibilityGroups: [UUID]
children: [NavigationItem]
}

input NavigationItemInput {
id: UUID!
type: NavigationItemType!
label: String
icon: String
target: String
openInNewWindow: Boolean
visibilityGroups: [UUID!]!
children: [NavigationItemInput!]
}

enum NavigationItemType {
header
link
separator
}

enum NavigationMode {
inherit
override
overrideExact
hide
hideExact
}

type NavigationUpdateResponse {
operation: Operation
navigationMode: NavigationMode
navigationId: UUID
}
1 change: 1 addition & 0 deletions server/graph/schemas/page.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ type Page {
isSearchable: Boolean
locale: String
navigationId: UUID
navigationMode: NavigationMode
password: String
path: String
publishEndDate: Date
Expand Down
2 changes: 2 additions & 0 deletions server/graph/schemas/site.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type SiteRobots {
}

type SiteFeatures {
browse: Boolean
ratings: Boolean
ratingsMode: SitePageRatingMode
comments: Boolean
Expand Down Expand Up @@ -194,6 +195,7 @@ input SiteRobotsInput {
}

input SiteFeaturesInput {
browse: Boolean
ratings: Boolean
ratingsMode: SitePageRatingMode
comments: Boolean
Expand Down
6 changes: 6 additions & 0 deletions server/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@
"admin.flags.title": "Flags",
"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.allowBrowse": "Allow Browsing",
"admin.general.allowBrowseHint": "Can users browse using the tree structure of the site to pages they have access to?",
"admin.general.allowComments": "Allow Comments",
"admin.general.allowCommentsHint": "Can users leave comments on pages? Can be restricted using Page Rules.",
"admin.general.allowContributions": "Allow Contributions",
Expand Down Expand Up @@ -1697,6 +1699,8 @@
"navEdit.noSelection": "Select a menu item from the left to start editing.",
"navEdit.openInNewWindow": "Open in New Window",
"navEdit.openInNewWindowHint": "Whether the link should open in a new window / tab.",
"navEdit.saveModeSuccess": "Navigation mode set successfully.",
"navEdit.saveSuccess": "Menu items saved successfully.",
"navEdit.selectGroups": "Group(s):",
"navEdit.separator": "Separator",
"navEdit.target": "Target",
Expand All @@ -1711,6 +1715,8 @@
"pageDeleteDialog.deleteSuccess": "Page deleted successfully.",
"pageDeleteDialog.pageId": "Page ID {id}",
"pageDeleteDialog.title": "Confirm Page Deletion",
"pageDuplicateDialog.title": "Duplicate and Save As...",
"pageRenameDialog.title": "Rename / Move to...",
"pageSaveDialog.displayModePath": "Browse Using Paths",
"pageSaveDialog.displayModeTitle": "Browse Using Titles",
"pageSaveDialog.title": "Save As...",
Expand Down
1 change: 1 addition & 0 deletions server/models/navigation.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class Navigation extends Model {

static async getNav ({ id, cache = false, userGroups = [] }) {
const result = await WIKI.db.navigation.query().findById(id).select('items')
if (!result) { return [] }
return result.items.filter(item => {
return !item.visibilityGroups?.length || intersection(item.visibilityGroups, userGroups).length > 0
}).map(item => {
Expand Down
8 changes: 0 additions & 8 deletions server/models/pageHistory.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,6 @@ export class PageHistory extends Model {
from: 'pageHistory.authorId',
to: 'users.id'
}
},
locale: {
relation: Model.BelongsToOneRelation,
modelClass: Locale,
join: {
from: 'pageHistory.locale',
to: 'locales.code'
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion server/models/pages.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,8 @@ export class Page extends Model {
creatorName: 'creator.name',
creatorEmail: 'creator.email'
},
'tree.navigationId'
'tree.navigationId',
'tree.navigationMode'
])
.joinRelated('author')
.joinRelated('creator')
Expand Down
Loading

0 comments on commit 607b8d8

Please sign in to comment.