mirror of https://github.com/requarks/wiki
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
446 lines
11 KiB
446 lines
11 KiB
import { defineStore } from 'pinia'
|
|
import gql from 'graphql-tag'
|
|
import { cloneDeep, initial, last, pick, transform } from 'lodash-es'
|
|
import { DateTime } from 'luxon'
|
|
|
|
import { useSiteStore } from './site'
|
|
import { useEditorStore } from './editor'
|
|
|
|
const pagePropsFragment = gql`
|
|
fragment PageRead on Page {
|
|
allowComments
|
|
allowContributions
|
|
allowRatings
|
|
contentType
|
|
createdAt
|
|
description
|
|
editor
|
|
icon
|
|
id
|
|
isBrowsable
|
|
locale
|
|
password
|
|
path
|
|
publishEndDate
|
|
publishStartDate
|
|
publishState
|
|
relations {
|
|
id
|
|
position
|
|
label
|
|
caption
|
|
icon
|
|
target
|
|
}
|
|
render
|
|
scriptJsLoad
|
|
scriptJsUnload
|
|
scriptCss
|
|
showSidebar
|
|
showTags
|
|
showToc
|
|
tags {
|
|
tag
|
|
title
|
|
}
|
|
title
|
|
toc
|
|
tocDepth {
|
|
min
|
|
max
|
|
}
|
|
updatedAt
|
|
}
|
|
`
|
|
const gqlQueries = {
|
|
pageById: gql`
|
|
query loadPage (
|
|
$id: UUID!
|
|
) {
|
|
pageById(
|
|
id: $id
|
|
) {
|
|
...PageRead
|
|
}
|
|
}
|
|
${pagePropsFragment}
|
|
`,
|
|
pageByPath: gql`
|
|
query loadPage (
|
|
$siteId: UUID!
|
|
$path: String!
|
|
) {
|
|
pageByPath(
|
|
siteId: $siteId
|
|
path: $path
|
|
) {
|
|
...PageRead
|
|
}
|
|
}
|
|
${pagePropsFragment}
|
|
`,
|
|
pageByIdWithContent: gql`
|
|
query loadPageWithContent (
|
|
$id: UUID!
|
|
) {
|
|
pageById(
|
|
id: $id
|
|
) {
|
|
...PageRead,
|
|
content
|
|
}
|
|
}
|
|
${pagePropsFragment}
|
|
`,
|
|
pageByPathWithContent: gql`
|
|
query loadPageWithContent (
|
|
$siteId: UUID!
|
|
$path: String!
|
|
) {
|
|
pageByPath(
|
|
siteId: $siteId
|
|
path: $path
|
|
) {
|
|
...PageRead,
|
|
content
|
|
}
|
|
}
|
|
${pagePropsFragment}
|
|
`
|
|
}
|
|
|
|
const gqlMutations = {
|
|
createPage: gql`
|
|
mutation createPage (
|
|
$allowComments: Boolean
|
|
$allowContributions: Boolean
|
|
$allowRatings: Boolean
|
|
$content: String!
|
|
$description: String!
|
|
$editor: String!
|
|
$icon: String
|
|
$isBrowsable: Boolean
|
|
$locale: String!
|
|
$path: String!
|
|
$publishState: PagePublishState!
|
|
$publishEndDate: Date
|
|
$publishStartDate: Date
|
|
$relations: [PageRelationInput!]
|
|
$render: String
|
|
$scriptCss: String
|
|
$scriptJsLoad: String
|
|
$scriptJsUnload: String
|
|
$showSidebar: Boolean
|
|
$showTags: Boolean
|
|
$showToc: Boolean
|
|
$siteId: UUID!
|
|
$tags: [String!]
|
|
$title: String!
|
|
$tocDepth: PageTocDepthInput
|
|
) {
|
|
createPage (
|
|
allowComments: $allowComments
|
|
allowContributions: $allowContributions
|
|
allowRatings: $allowRatings
|
|
content: $content
|
|
description: $description
|
|
editor: $editor
|
|
icon: $icon
|
|
isBrowsable: $isBrowsable
|
|
locale: $locale
|
|
path: $path
|
|
publishState: $publishState
|
|
publishEndDate: $publishEndDate
|
|
publishStartDate: $publishStartDate
|
|
relations: $relations
|
|
render: $render
|
|
scriptCss: $scriptCss
|
|
scriptJsLoad: $scriptJsLoad
|
|
scriptJsUnload: $scriptJsUnload
|
|
showSidebar: $showSidebar
|
|
showTags: $showTags
|
|
showToc: $showToc
|
|
siteId: $siteId
|
|
tags: $tags
|
|
title: $title
|
|
tocDepth: $tocDepth
|
|
) {
|
|
operation {
|
|
succeeded
|
|
message
|
|
}
|
|
page {
|
|
...PageRead
|
|
}
|
|
}
|
|
}
|
|
${pagePropsFragment}
|
|
`
|
|
}
|
|
|
|
export const usePageStore = defineStore('page', {
|
|
state: () => ({
|
|
allowComments: false,
|
|
allowContributions: true,
|
|
allowRatings: true,
|
|
authorId: 0,
|
|
authorName: '',
|
|
commentsCount: 0,
|
|
content: '',
|
|
createdAt: '',
|
|
description: '',
|
|
editor: '',
|
|
icon: 'las la-file-alt',
|
|
id: '',
|
|
isBrowsable: true,
|
|
locale: 'en',
|
|
password: '',
|
|
path: '',
|
|
publishEndDate: '',
|
|
publishStartDate: '',
|
|
publishState: '',
|
|
relations: [],
|
|
render: '',
|
|
scriptJsLoad: '',
|
|
scriptJsUnload: '',
|
|
scriptCss: '',
|
|
showSidebar: true,
|
|
showTags: true,
|
|
showToc: true,
|
|
tags: [],
|
|
title: '',
|
|
toc: [],
|
|
tocDepth: {
|
|
min: 1,
|
|
max: 2
|
|
},
|
|
updatedAt: ''
|
|
}),
|
|
getters: {
|
|
breadcrumbs: (state) => {
|
|
const siteStore = useSiteStore()
|
|
const pathPrefix = siteStore.useLocales ? `/${state.locale}` : ''
|
|
return transform(state.path.split('/'), (result, value, key) => {
|
|
result.push({
|
|
id: key,
|
|
title: value,
|
|
icon: 'las la-file-alt',
|
|
locale: 'en',
|
|
path: (last(result)?.path || pathPrefix) + `/${value}`
|
|
})
|
|
}, [])
|
|
},
|
|
folderPath: (state) => {
|
|
return initial(state.path.split('/')).join('/')
|
|
}
|
|
},
|
|
actions: {
|
|
/**
|
|
* PAGE - LOAD
|
|
*/
|
|
async pageLoad ({ path, id, withContent = false }) {
|
|
const editorStore = useEditorStore()
|
|
const siteStore = useSiteStore()
|
|
try {
|
|
let query
|
|
if (withContent) {
|
|
query = id ? gqlQueries.pageByIdWithContent : gqlQueries.pageByPathWithContent
|
|
} else {
|
|
query = id ? gqlQueries.pageById : gqlQueries.pageByPath
|
|
}
|
|
const resp = await APOLLO_CLIENT.query({
|
|
query,
|
|
variables: id ? { id } : { siteId: siteStore.id, path },
|
|
fetchPolicy: 'network-only'
|
|
})
|
|
const pageData = cloneDeep((id ? resp?.data?.pageById : resp?.data?.pageByPath) ?? {})
|
|
if (!pageData?.id) {
|
|
throw new Error('ERR_PAGE_NOT_FOUND')
|
|
}
|
|
// Update page store
|
|
this.$patch({
|
|
...pageData,
|
|
relations: pageData.relations.map(r => pick(r, ['id', 'position', 'label', 'caption', 'icon', 'target'])),
|
|
tocDepth: pick(pageData.tocDepth, ['min', 'max'])
|
|
})
|
|
// Update editor state timestamps
|
|
const curDate = DateTime.utc()
|
|
editorStore.$patch({
|
|
lastChangeTimestamp: curDate,
|
|
lastSaveTimestamp: curDate
|
|
})
|
|
} catch (err) {
|
|
console.warn(err)
|
|
throw err
|
|
}
|
|
},
|
|
/**
|
|
* PAGE - CREATE
|
|
*/
|
|
pageCreate ({ editor, locale, path, title = '', description = '', content = '' }) {
|
|
const editorStore = useEditorStore()
|
|
|
|
// -> Init editor
|
|
editorStore.$patch({
|
|
originPageId: editorStore.isActive ? editorStore.originPageId : this.id, // Don't replace if already in edit mode
|
|
isActive: true,
|
|
mode: 'create',
|
|
editor
|
|
})
|
|
|
|
// -> Default Page Path
|
|
let newPath = path
|
|
if (!path && path !== '') {
|
|
newPath = this.path.length < 2 ? 'new-page' : `${this.path}/new-page`
|
|
}
|
|
|
|
// -> Set Default Page Data
|
|
this.$patch({
|
|
id: 0,
|
|
locale: locale || this.locale,
|
|
path: newPath,
|
|
title: title ?? '',
|
|
description: description ?? '',
|
|
icon: 'las la-file-alt',
|
|
publishState: 'published',
|
|
relations: [],
|
|
tags: [],
|
|
content: content ?? '',
|
|
render: '',
|
|
mode: 'edit'
|
|
})
|
|
|
|
this.router.push('/_create')
|
|
},
|
|
/**
|
|
* PAGE SAVE
|
|
*/
|
|
async pageSave () {
|
|
const editorStore = useEditorStore()
|
|
const siteStore = useSiteStore()
|
|
try {
|
|
if (editorStore.mode === 'create') {
|
|
const resp = await APOLLO_CLIENT.mutate({
|
|
mutation: gqlMutations.createPage,
|
|
variables: {
|
|
...pick(this, [
|
|
'allowComments',
|
|
'allowContributions',
|
|
'allowRatings',
|
|
'content',
|
|
'description',
|
|
'icon',
|
|
'isBrowsable',
|
|
'locale',
|
|
'password',
|
|
'path',
|
|
'publishEndDate',
|
|
'publishStartDate',
|
|
'publishState',
|
|
'relations',
|
|
'render',
|
|
'scriptJsLoad',
|
|
'scriptJsUnload',
|
|
'scriptCss',
|
|
'showSidebar',
|
|
'showTags',
|
|
'showToc',
|
|
'tags',
|
|
'title',
|
|
'tocDepth'
|
|
]),
|
|
editor: editorStore.editor,
|
|
siteId: siteStore.id
|
|
}
|
|
})
|
|
const result = resp?.data?.createPage?.operation ?? {}
|
|
if (!result.succeeded) {
|
|
throw new Error(result.message)
|
|
}
|
|
const pageData = cloneDeep(resp.data.createPage.page ?? {})
|
|
if (!pageData?.id) {
|
|
throw new Error('ERR_CREATED_PAGE_NOT_FOUND')
|
|
}
|
|
// Update page store
|
|
this.$patch({
|
|
...pageData,
|
|
relations: pageData.relations.map(r => pick(r, ['id', 'position', 'label', 'caption', 'icon', 'target'])),
|
|
tocDepth: pick(pageData.tocDepth, ['min', 'max'])
|
|
})
|
|
|
|
this.router.replace(`/${this.path}`)
|
|
} else {
|
|
const resp = await APOLLO_CLIENT.mutate({
|
|
mutation: gql`
|
|
mutation savePage (
|
|
$id: UUID!
|
|
$patch: PageUpdateInput!
|
|
) {
|
|
updatePage (
|
|
id: $id
|
|
patch: $patch
|
|
) {
|
|
operation {
|
|
succeeded
|
|
message
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
variables: {
|
|
id: this.id,
|
|
patch: pick(this, [
|
|
'allowComments',
|
|
'allowContributions',
|
|
'allowRatings',
|
|
'content',
|
|
'description',
|
|
'icon',
|
|
'isBrowsable',
|
|
'locale',
|
|
'password',
|
|
'path',
|
|
'publishEndDate',
|
|
'publishStartDate',
|
|
'publishState',
|
|
'relations',
|
|
'render',
|
|
'scriptJsLoad',
|
|
'scriptJsUnload',
|
|
'scriptCss',
|
|
'showSidebar',
|
|
'showTags',
|
|
'showToc',
|
|
'tags',
|
|
'title',
|
|
'tocDepth'
|
|
])
|
|
}
|
|
})
|
|
const result = resp?.data?.updatePage?.operation ?? {}
|
|
if (!result.succeeded) {
|
|
throw new Error(result.message)
|
|
}
|
|
}
|
|
// Update editor state timestamps
|
|
const curDate = DateTime.utc()
|
|
editorStore.$patch({
|
|
lastChangeTimestamp: curDate,
|
|
lastSaveTimestamp: curDate
|
|
})
|
|
} catch (err) {
|
|
console.warn(err)
|
|
throw err
|
|
}
|
|
},
|
|
async cancelPageEdit () {
|
|
const editorStore = useEditorStore()
|
|
await this.pageLoad({ id: editorStore.originPageId ? editorStore.originPageId : this.id })
|
|
this.router.replace(`/${this.path}`)
|
|
},
|
|
generateToc () {
|
|
|
|
}
|
|
}
|
|
})
|