feat: rename / move page + code styling fixes

vega
NGPixel 21 hours ago
parent 7425a74b6a
commit d9523fe393
No known key found for this signature in database
GPG Key ID: B755FB6870B30F63

@ -86,7 +86,7 @@ export default {
// -> Add Highlighting if enabled
if (WIKI.config.search.termHighlighting && hasQuery) {
searchCols.push(WIKI.db.knex.raw(`ts_headline(?, "searchContent", query, 'MaxWords=5, MinWords=3, MaxFragments=5') AS highlight`, [dictName]))
searchCols.push(WIKI.db.knex.raw('ts_headline(?, "searchContent", query, \'MaxWords=5, MinWords=3, MaxFragments=5\') AS highlight', [dictName]))
}
const results = await WIKI.db.knex
@ -408,7 +408,7 @@ export default {
* CHECK FOR EDITING CONFLICT
*/
async checkConflicts (obj, args, context, info) {
let page = await WIKI.db.pages.query().select('path', 'locale', 'updatedAt').findById(args.id)
const page = await WIKI.db.pages.query().select('path', 'locale', 'updatedAt').findById(args.id)
if (page) {
if (WIKI.auth.checkAccess(context.req.user, ['write:pages', 'manage:pages'], {
path: page.path,
@ -426,7 +426,7 @@ export default {
* FETCH LATEST VERSION FOR CONFLICT COMPARISON
*/
async checkConflictsLatest (obj, args, context, info) {
let page = await WIKI.db.pages.getPageFromDb(args.id)
const page = await WIKI.db.pages.getPageFromDb(args.id)
if (page) {
if (WIKI.auth.checkAccess(context.req.user, ['write:pages', 'manage:pages'], {
path: page.path,
@ -449,7 +449,7 @@ export default {
/**
* CREATE PAGE
*/
async createPage(obj, args, context) {
async createPage (obj, args, context) {
try {
const page = await WIKI.db.pages.createPage({
...args,
@ -466,7 +466,7 @@ export default {
/**
* UPDATE PAGE
*/
async updatePage(obj, args, context) {
async updatePage (obj, args, context) {
try {
const page = await WIKI.db.pages.updatePage({
...args,
@ -483,7 +483,7 @@ export default {
/**
* CONVERT PAGE
*/
async convertPage(obj, args, context) {
async convertPage (obj, args, context) {
try {
await WIKI.db.pages.convertPage({
...args,
@ -497,9 +497,9 @@ export default {
}
},
/**
* RENAME PAGE
* MOVE PAGE
*/
async renamePage(obj, args, context) {
async movePage (obj, args, context) {
try {
await WIKI.db.pages.movePage({
...args,
@ -515,7 +515,7 @@ export default {
/**
* DELETE PAGE
*/
async deletePage(obj, args, context) {
async deletePage (obj, args, context) {
try {
await WIKI.db.pages.deletePage({
...args,
@ -571,7 +571,7 @@ export default {
/**
* FLUSH PAGE CACHE
*/
async flushCache(obj, args, context) {
async flushCache (obj, args, context) {
try {
await WIKI.db.pages.flushCache()
WIKI.events.outbound.emit('flushCache')
@ -585,7 +585,7 @@ export default {
/**
* MIGRATE ALL PAGES FROM SOURCE LOCALE TO TARGET LOCALE
*/
async migrateToLocale(obj, args, context) {
async migrateToLocale (obj, args, context) {
try {
const count = await WIKI.db.pages.migrateToLocale(args)
return {
@ -599,7 +599,7 @@ export default {
/**
* REBUILD TREE
*/
async rebuildPageTree(obj, args, context) {
async rebuildPageTree (obj, args, context) {
try {
await WIKI.db.pages.rebuildTree()
return {

@ -162,10 +162,11 @@ extend type Mutation {
editor: String!
): DefaultResponse
renamePage(
id: Int!
destinationPath: String!
movePage(
id: UUID!
destinationLocale: String!
destinationPath: String!
title: String
): DefaultResponse
deletePage(

@ -1,5 +1,5 @@
import { Model } from 'objection'
import { find, get, has, initial, isEmpty, isString, last, pick } from 'lodash-es'
import { cloneDeep, find, get, has, initial, isEmpty, isString, last, pick } from 'lodash-es'
import { Type as JSBinType } from 'js-binary'
import { getDictNameFromLocale } from '../helpers/common.mjs'
import { generateHash, getFileExtension, injectPageMetadata } from '../helpers/page.mjs'
@ -888,15 +888,10 @@ export class Page extends Model {
* @returns {Promise} Promise with no value
*/
static async movePage (opts) {
let page
if (has(opts, 'id')) {
page = await WIKI.db.pages.query().findById(opts.id)
} else {
page = await WIKI.db.pages.query().findOne({
path: opts.path,
locale: opts.locale
})
if (!has(opts, 'id')) {
throw new Error('Missing page ID')
}
const page = await WIKI.db.pages.query().findById(opts.id)
if (!page) {
throw new WIKI.Error.PageNotFound()
}
@ -947,63 +942,83 @@ export class Page extends Model {
versionDate: page.updatedAt
})
const destinationHash = generateHash({ path: opts.destinationPath, locale: opts.destinationLocale })
// -> Update page object
const updatedPage = cloneDeep(page)
updatedPage.path = opts.destinationPath
updatedPage.locale = opts.destinationLocale
updatedPage.title = opts.title ?? page.title
updatedPage.hash = generateHash({ path: opts.destinationPath, locale: opts.destinationLocale })
updatedPage.authorId = opts.user.id
// -> Move page
const destinationTitle = (page.title === page.path ? opts.destinationPath : page.title)
await WIKI.db.pages.query().patch({
path: opts.destinationPath,
locale: opts.destinationLocale,
title: destinationTitle,
hash: destinationHash
path: updatedPage.path,
locale: updatedPage.locale,
title: updatedPage.title,
hash: updatedPage.hash,
authorId: updatedPage.authorId
}).findById(page.id)
await WIKI.db.pages.deletePageFromCache(page.hash)
WIKI.events.outbound.emit('deletePageFromCache', page.hash)
// -> Rebuild page tree
await WIKI.db.pages.rebuildTree()
// -> Replace tree node
const pathParts = updatedPage.path.split('/')
await WIKI.db.knex('tree').where('id', page.id).del()
await WIKI.db.tree.addPage({
id: page.id,
parentPath: initial(pathParts).join('/'),
fileName: last(pathParts),
locale: updatedPage.locale,
title: updatedPage.title,
tags: updatedPage.tags,
meta: {
authorId: updatedPage.authorId,
contentType: updatedPage.contentType,
creatorId: updatedPage.creatorId,
description: updatedPage.description,
isBrowsable: updatedPage.isBrowsable,
ownerId: updatedPage.ownerId,
publishState: updatedPage.publishState,
publishEndDate: updatedPage.publishEndDate,
publishStartDate: updatedPage.publishStartDate
},
siteId: updatedPage.siteId
})
// -> Rename in Search Index
const pageContents = await WIKI.db.pages.query().findById(page.id).select('render')
page.safeContent = WIKI.db.pages.cleanHTML(pageContents.render)
await WIKI.data.searchEngine.renamed({
...page,
destinationPath: opts.destinationPath,
destinationLocale: opts.destinationLocale,
destinationHash
})
WIKI.db.pages.updatePageSearchVector({ id: page.id })
// -> Rename in Storage
if (!opts.skipStorage) {
await WIKI.db.storage.pageEvent({
event: 'renamed',
page: {
...page,
destinationPath: opts.destinationPath,
destinationLocale: opts.destinationLocale,
destinationHash,
moveAuthorId: opts.user.id,
moveAuthorName: opts.user.name,
moveAuthorEmail: opts.user.email
}
})
// await WIKI.db.storage.pageEvent({
// event: 'renamed',
// page: {
// ...page,
// destinationPath: updatedPage.path,
// destinationLocale: updatedPage.locale,
// destinationHash: updatedPage.hash,
// moveAuthorId: opts.user.id,
// moveAuthorName: opts.user.name,
// moveAuthorEmail: opts.user.email
// }
// })
}
// -> Reconnect Links : Changing old links to the new path
await WIKI.db.pages.reconnectLinks({
sourceLocale: page.locale,
sourcePath: page.path,
locale: opts.destinationLocale,
path: opts.destinationPath,
mode: 'move'
})
// // -> Reconnect Links : Changing old links to the new path
// await WIKI.db.pages.reconnectLinks({
// sourceLocale: page.locale,
// sourcePath: page.path,
// locale: opts.destinationLocale,
// path: opts.destinationPath,
// mode: 'move'
// })
// -> Reconnect Links : Validate invalid links to the new path
await WIKI.db.pages.reconnectLinks({
locale: opts.destinationLocale,
path: opts.destinationPath,
mode: 'create'
})
// // -> Reconnect Links : Validate invalid links to the new path
// await WIKI.db.pages.reconnectLinks({
// locale: opts.destinationLocale,
// path: opts.destinationPath,
// mode: 'create'
// })
}
/**

@ -17,7 +17,7 @@ const reTitle = /^[^<>"]+$/
* Tree model
*/
export class Tree extends Model {
static get tableName() { return 'tree' }
static get tableName () { return 'tree' }
static get jsonSchema () {
return {
@ -25,22 +25,22 @@ export class Tree extends Model {
required: ['fileName'],
properties: {
id: {type: 'string'},
folderPath: {type: 'string'},
fileName: {type: 'string'},
type: {type: 'string'},
title: {type: 'string'},
createdAt: {type: 'string'},
updatedAt: {type: 'string'}
id: { type: 'string' },
folderPath: { type: 'string' },
fileName: { type: 'string' },
type: { type: 'string' },
title: { type: 'string' },
createdAt: { type: 'string' },
updatedAt: { type: 'string' }
}
}
}
static get jsonAttributes() {
static get jsonAttributes () {
return ['meta']
}
static get relationMappings() {
static get relationMappings () {
return {
site: {
relation: Model.BelongsToOneRelation,
@ -53,10 +53,11 @@ export class Tree extends Model {
}
}
$beforeUpdate() {
$beforeUpdate () {
this.updatedAt = new Date().toISOString()
}
$beforeInsert() {
$beforeInsert () {
this.createdAt = new Date().toISOString()
this.updatedAt = new Date().toISOString()
}
@ -90,7 +91,7 @@ export class Tree extends Model {
const parent = await WIKI.db.knex('tree').where({
...parentFilter,
type: 'folder',
locale: locale,
locale,
siteId
}).first()
if (parent) {
@ -123,16 +124,18 @@ export class Tree extends Model {
* @param {Object} [args.meta] - Extra metadata
*/
static async addPage ({ id, parentId, parentPath, fileName, title, locale, siteId, tags = [], meta = {} }) {
const folder = (parentId || parentPath) ? await WIKI.db.tree.getFolder({
id: parentId,
path: parentPath,
locale,
siteId,
createIfMissing: true
}) : {
folderPath: '',
fileName: ''
}
const folder = (parentId || parentPath)
? await WIKI.db.tree.getFolder({
id: parentId,
path: parentPath,
locale,
siteId,
createIfMissing: true
})
: {
folderPath: '',
fileName: ''
}
const folderPath = folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName
const fullPath = folderPath ? `${folderPath}/${fileName}` : fileName
@ -143,9 +146,9 @@ export class Tree extends Model {
folderPath: encodeFolderPath(folderPath),
fileName,
type: 'page',
title: title,
title,
hash: generateHash(fullPath),
locale: locale,
locale,
siteId,
tags,
meta,
@ -169,16 +172,18 @@ export class Tree extends Model {
* @param {Object} [args.meta] - Extra metadata
*/
static async addAsset ({ id, parentId, parentPath, fileName, title, locale, siteId, tags = [], meta = {} }) {
const folder = (parentId || parentPath) ? await WIKI.db.tree.getFolder({
id: parentId,
path: parentPath,
locale,
siteId,
createIfMissing: true
}) : {
folderPath: '',
fileName: ''
}
const folder = (parentId || parentPath)
? await WIKI.db.tree.getFolder({
id: parentId,
path: parentPath,
locale,
siteId,
createIfMissing: true
})
: {
folderPath: '',
fileName: ''
}
const folderPath = folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName
const fullPath = folderPath ? `${folderPath}/${fileName}` : fileName
@ -189,9 +194,9 @@ export class Tree extends Model {
folderPath: encodeFolderPath(folderPath),
fileName,
type: 'asset',
title: title,
title,
hash: generateHash(fullPath),
locale: locale,
locale,
siteId,
tags,
meta
@ -246,8 +251,8 @@ export class Tree extends Model {
// Check for collision
const existingFolder = await WIKI.db.knex('tree').select('id').where({
siteId: siteId,
locale: locale,
siteId,
locale,
folderPath: encodeFolderPath(parentPath),
fileName: pathName,
type: 'folder'
@ -281,8 +286,8 @@ export class Tree extends Model {
type: 'folder',
title: ancestor.fileName,
hash: generateHash(newAncestorFullPath),
locale: locale,
siteId: siteId,
locale,
siteId,
meta: {
children: 1
}
@ -301,10 +306,10 @@ export class Tree extends Model {
folderPath: encodeFolderPath(parentPath),
fileName: pathName,
type: 'folder',
title: title,
title,
hash: generateHash(fullPath),
locale: locale,
siteId: siteId,
locale,
siteId,
meta: {
children: 0
}
@ -383,13 +388,13 @@ export class Tree extends Model {
const fullPath = folder.folderPath ? `${decodeFolderPath(folder.folderPath)}/${pathName}` : pathName
await WIKI.db.knex('tree').where('id', folder.id).update({
fileName: pathName,
title: title,
title,
hash: generateHash(fullPath)
})
} else {
// Update the folder title only
await WIKI.db.knex('tree').where('id', folder.id).update({
title: title
title
})
}

@ -244,8 +244,27 @@ function renamePage () {
itemTitle: pageStore.title,
itemFileName: pageStore.path
}
}).onOk(() => {
// TODO: change route to new location
}).onOk(async (renamedPageOpts) => {
try {
if (renamedPageOpts.path === pageStore.path) {
await pageStore.pageRename({ id: pageStore.id, title: renamedPageOpts.title })
$q.notify({
type: 'positive',
message: 'Page renamed successfully.'
})
} else {
await pageStore.pageMove({ id: pageStore.id, path: renamedPageOpts.path, title: renamedPageOpts.title })
$q.notify({
type: 'positive',
message: 'Page moved successfully.'
})
}
} catch (err) {
$q.notify({
type: 'negative',
message: err.message
})
}
})
}

@ -64,7 +64,9 @@ q-dialog(ref='dialogRef', @hide='onDialogHide')
dense
outlined
@focus='state.pathDirty = true; state.currentFileId = null'
)
)
//- template(#append)
//- q-badge(outline, color='grey', label='valid')
q-card-actions.card-actions.q-px-md
q-btn.acrylic-btn(
icon='las la-ellipsis-h'
@ -408,8 +410,17 @@ onMounted(() => {
fName = last(fParts)
}
switch (props.mode) {
case 'pageSave': {
case 'savePage': {
state.typesToFetch = ['folder', 'page']
break
}
case 'duplicatePage': {
state.typesToFetch = ['folder', 'page']
break
}
case 'renamePage': {
state.typesToFetch = ['folder', 'page']
state.pathDirty = true
break
}
}

@ -452,6 +452,83 @@ export const usePageStore = defineStore('page', {
editor: this.editor
})
},
/**
* PAGE - MOVE
*/
async pageMove ({ id, title, path } = {}) {
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation movePage (
$id: UUID!
$destinationLocale: String!
$destinationPath: String!
$title: String
) {
movePage (
id: $id
destinationLocale: $destinationLocale
destinationPath: $destinationPath
title: $title
) {
operation {
succeeded
message
}
}
}
`,
variables: {
id,
destinationLocale: this.locale,
destinationPath: path,
title
}
})
const result = resp?.data?.movePage?.operation ?? {}
if (!result.succeeded) {
throw new Error(result.message)
} else {
this.router.replace(`/${path}`)
}
},
/**
* PAGE - Rename
*/
async pageRename ({ id, title } = {}) {
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation renamePage (
$id: UUID!
$patch: PageUpdateInput!
) {
updatePage (
id: $id
patch: $patch
) {
operation {
succeeded
message
}
}
}
`,
variables: {
id: id,
patch: {
title
}
}
})
const result = resp?.data?.updatePage?.operation ?? {}
if (!result.succeeded) {
throw new Error(result.message)
}
// Update page store
if (id === this.id) {
this.$patch({ title })
}
},
/**
* PAGE SAVE
*/

Loading…
Cancel
Save