Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
13a99513
Commit
13a99513
authored
Mar 01, 2020
by
NGPixel
Committed by
Nicolas Giard
Mar 01, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: branch off / create from template
parent
e85de927
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
142 additions
and
21 deletions
+142
-21
editor.vue
client/components/editor.vue
+1
-1
editor-markdown.vue
client/components/editor/editor-markdown.vue
+1
-1
history.vue
client/components/history.vue
+18
-1
common.js
server/controllers/common.js
+61
-1
page.js
server/graph/resolvers/page.js
+36
-13
error.js
server/helpers/error.js
+8
-0
pageHistory.js
server/models/pageHistory.js
+17
-4
No files found.
client/components/editor.vue
View file @
13a99513
...
...
@@ -171,7 +171,7 @@ export default {
this
.
initContentParsed
=
this
.
initContent
?
Base64
.
decode
(
this
.
initContent
)
:
''
this
.
$store
.
set
(
'editor/content'
,
this
.
initContentParsed
)
if
(
this
.
mode
===
'create'
)
{
if
(
this
.
mode
===
'create'
&&
!
this
.
initEditor
)
{
_
.
delay
(()
=>
{
this
.
dialogEditorSelector
=
true
},
500
)
...
...
client/components/editor/editor-markdown.vue
View file @
13a99513
...
...
@@ -474,7 +474,7 @@ export default {
mounted() {
this.$store.set('editor/editorKey', 'markdown')
if (this.mode === 'create') {
if (this.mode === 'create'
&& !this.$store.get('editor/content')
) {
this.$store.set('editor/content', '# Header\nYour content here')
}
...
...
client/components/history.vue
View file @
13a99513
...
...
@@ -122,6 +122,8 @@
v-btn(text, @click='isRestoreConfirmDialogShown = false', :disabled='restoreLoading')
{{
$t
(
'common:actions.cancel'
)
}}
v-btn(color='orange darken-2', dark, @click='restoreConfirm', :loading='restoreLoading')
{{
$t
(
'history:restore.confirmButton'
)
}}
page-selector(mode='create', v-model='branchOffOpts.modal', :open-handler='branchOffHandle', :path='branchOffOpts.path', :locale='branchOffOpts.locale')
nav-footer
notify
search-results
...
...
@@ -211,6 +213,12 @@ export default {
versionId
:
0
,
versionDate
:
''
},
branchOffOpts
:
{
versionId
:
0
,
locale
:
'en'
,
path
:
'new-page'
,
modal
:
false
},
isRestoreConfirmDialogShown
:
false
,
restoreLoading
:
false
}
...
...
@@ -408,7 +416,16 @@ export default {
this
.
restoreLoading
=
false
},
branchOff
(
versionId
)
{
const
pathParts
=
this
.
path
.
split
(
'/'
)
this
.
branchOffOpts
=
{
versionId
:
versionId
,
locale
:
this
.
locale
,
path
:
(
pathParts
.
length
>
1
)
?
_
.
initial
(
pathParts
).
join
(
'/'
)
+
`/new-page`
:
`new-page`
,
modal
:
true
}
},
branchOffHandle
({
locale
,
path
})
{
window
.
location
.
assign
(
`/e/
${
locale
}
/
${
path
}
?from=
${
this
.
pageId
}
,
${
this
.
branchOffOpts
.
versionId
}
`
)
},
toggleViewMode
()
{
this
.
viewMode
=
(
this
.
viewMode
===
'line-by-line'
)
?
'side-by-side'
:
'line-by-line'
...
...
server/controllers/common.js
View file @
13a99513
...
...
@@ -5,6 +5,8 @@ const _ = require('lodash')
/* global WIKI */
const
tmplCreateRegex
=
/^
[
0-9
]
+
(
,
[
0-9
]
+
)?
$/
/**
* Robots.txt
*/
...
...
@@ -89,13 +91,16 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
return
res
.
redirect
(
`/e/
${
pageArgs
.
locale
}
/
${
pageArgs
.
path
}
`
)
}
// -> Set Editor Lang
_
.
set
(
res
,
'locals.siteConfig.lang'
,
pageArgs
.
locale
)
_
.
set
(
res
,
'locals.siteConfig.rtl'
,
req
.
i18n
.
dir
()
===
'rtl'
)
// -> Check for reserved path
if
(
pageHelper
.
isReservedPath
(
pageArgs
.
path
))
{
return
next
(
new
Error
(
'Cannot create this page because it starts with a system reserved path.'
))
}
// -> Get page data from DB
let
page
=
await
WIKI
.
models
.
pages
.
getPageFromDb
({
path
:
pageArgs
.
path
,
locale
:
pageArgs
.
locale
,
...
...
@@ -112,11 +117,13 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
}
if
(
page
)
{
// -> EDIT MODE
if
(
!
WIKI
.
auth
.
checkAccess
(
req
.
user
,
[
'write:pages'
,
'manage:pages'
],
pageArgs
))
{
_
.
set
(
res
.
locals
,
'pageMeta.title'
,
'Unauthorized'
)
return
res
.
render
(
'unauthorized'
,
{
action
:
'edit'
})
}
// -> Get page tags
await
page
.
$relatedQuery
(
'tags'
)
page
.
tags
=
_
.
map
(
page
.
tags
,
'tag'
)
...
...
@@ -126,6 +133,7 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
page
.
isPublished
=
(
page
.
isPublished
===
true
||
page
.
isPublished
===
1
)
?
'true'
:
'false'
page
.
content
=
Buffer
.
from
(
page
.
content
).
toString
(
'base64'
)
}
else
{
// -> CREATE MODE
if
(
!
WIKI
.
auth
.
checkAccess
(
req
.
user
,
[
'write:pages'
],
pageArgs
))
{
_
.
set
(
res
.
locals
,
'pageMeta.title'
,
'Unauthorized'
)
return
res
.
render
(
'unauthorized'
,
{
action
:
'create'
})
...
...
@@ -137,7 +145,54 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
localeCode
:
pageArgs
.
locale
,
editorKey
:
null
,
mode
:
'create'
,
content
:
null
content
:
null
,
title
:
null
,
description
:
null
}
// -> From Template
if
(
req
.
query
.
from
&&
tmplCreateRegex
.
test
(
req
.
query
.
from
))
{
let
tmplPageId
=
0
let
tmplVersionId
=
0
if
(
req
.
query
.
from
.
indexOf
(
','
))
{
const
q
=
req
.
query
.
from
.
split
(
','
)
tmplPageId
=
_
.
toSafeInteger
(
q
[
0
])
tmplVersionId
=
_
.
toSafeInteger
(
q
[
1
])
}
else
{
tmplPageId
=
_
.
toSafeInteger
(
req
.
query
.
from
)
}
if
(
tmplVersionId
>
0
)
{
// -> From Page Version
const
pageVersion
=
await
WIKI
.
models
.
pageHistory
.
getVersion
({
pageId
:
tmplPageId
,
versionId
:
tmplVersionId
})
if
(
!
pageVersion
)
{
_
.
set
(
res
.
locals
,
'pageMeta.title'
,
'Page Not Found'
)
return
res
.
status
(
404
).
render
(
'notfound'
,
{
action
:
'template'
})
}
if
(
!
WIKI
.
auth
.
checkAccess
(
req
.
user
,
[
'read:history'
],
{
path
:
pageVersion
.
path
,
locale
:
pageVersion
.
locale
}))
{
_
.
set
(
res
.
locals
,
'pageMeta.title'
,
'Unauthorized'
)
return
res
.
render
(
'unauthorized'
,
{
action
:
'sourceVersion'
})
}
page
.
content
=
Buffer
.
from
(
pageVersion
.
content
).
toString
(
'base64'
)
page
.
editorKey
=
pageVersion
.
editor
page
.
title
=
pageVersion
.
title
page
.
description
=
pageVersion
.
description
}
else
{
// -> From Page Live
const
pageOriginal
=
await
WIKI
.
models
.
pages
.
query
().
findById
(
tmplPageId
)
if
(
!
pageOriginal
)
{
_
.
set
(
res
.
locals
,
'pageMeta.title'
,
'Page Not Found'
)
return
res
.
status
(
404
).
render
(
'notfound'
,
{
action
:
'template'
})
}
if
(
!
WIKI
.
auth
.
checkAccess
(
req
.
user
,
[
'read:source'
],
{
path
:
pageOriginal
.
path
,
locale
:
pageOriginal
.
locale
}))
{
_
.
set
(
res
.
locals
,
'pageMeta.title'
,
'Unauthorized'
)
return
res
.
render
(
'unauthorized'
,
{
action
:
'source'
})
}
page
.
content
=
Buffer
.
from
(
pageOriginal
.
content
).
toString
(
'base64'
)
page
.
editorKey
=
pageOriginal
.
editorKey
page
.
title
=
pageOriginal
.
title
page
.
description
=
pageOriginal
.
description
}
}
}
res
.
render
(
'editor'
,
{
page
,
injectCode
})
...
...
@@ -163,6 +218,11 @@ router.get(['/h', '/h/*'], async (req, res, next) => {
isPrivate
:
false
})
if
(
!
page
)
{
_
.
set
(
res
.
locals
,
'pageMeta.title'
,
'Page Not Found'
)
return
res
.
status
(
404
).
render
(
'notfound'
,
{
action
:
'history'
})
}
pageArgs
.
tags
=
_
.
get
(
page
,
'tags'
,
[])
if
(
!
WIKI
.
auth
.
checkAccess
(
req
.
user
,
[
'read:history'
],
pageArgs
))
{
...
...
server/graph/resolvers/page.js
View file @
13a99513
...
...
@@ -15,20 +15,36 @@ module.exports = {
* PAGE HISTORY
*/
async
history
(
obj
,
args
,
context
,
info
)
{
return
WIKI
.
models
.
pageHistory
.
getHistory
({
pageId
:
args
.
id
,
offsetPage
:
args
.
offsetPage
||
0
,
offsetSize
:
args
.
offsetSize
||
100
})
const
page
=
await
WIKI
.
models
.
pages
.
query
().
select
(
'path'
,
'localeCode'
).
findById
(
args
.
id
)
if
(
WIKI
.
auth
.
checkAccess
(
context
.
req
.
user
,
[
'read:history'
],
{
path
:
page
.
path
,
locale
:
page
.
localeCode
}))
{
return
WIKI
.
models
.
pageHistory
.
getHistory
({
pageId
:
args
.
id
,
offsetPage
:
args
.
offsetPage
||
0
,
offsetSize
:
args
.
offsetSize
||
100
})
}
else
{
throw
new
WIKI
.
Error
.
PageHistoryForbidden
()
}
},
/**
* PAGE VERSION
*/
async
version
(
obj
,
args
,
context
,
info
)
{
return
WIKI
.
models
.
pageHistory
.
getVersion
({
pageId
:
args
.
pageId
,
versionId
:
args
.
versionId
})
const
page
=
await
WIKI
.
models
.
pages
.
query
().
select
(
'path'
,
'localeCode'
).
findById
(
args
.
pageId
)
if
(
WIKI
.
auth
.
checkAccess
(
context
.
req
.
user
,
[
'read:history'
],
{
path
:
page
.
path
,
locale
:
page
.
localeCode
}))
{
return
WIKI
.
models
.
pageHistory
.
getVersion
({
pageId
:
args
.
pageId
,
versionId
:
args
.
versionId
})
}
else
{
throw
new
WIKI
.
Error
.
PageHistoryForbidden
()
}
},
/**
* SEARCH PAGES
...
...
@@ -123,10 +139,17 @@ module.exports = {
async
single
(
obj
,
args
,
context
,
info
)
{
let
page
=
await
WIKI
.
models
.
pages
.
getPageFromDb
(
args
.
id
)
if
(
page
)
{
return
{
...
page
,
locale
:
page
.
localeCode
,
editor
:
page
.
editorKey
if
(
WIKI
.
auth
.
checkAccess
(
context
.
req
.
user
,
[
'read:history'
],
{
path
:
page
.
path
,
locale
:
page
.
localeCode
}))
{
return
{
...
page
,
locale
:
page
.
localeCode
,
editor
:
page
.
editorKey
}
}
else
{
throw
new
WIKI
.
Error
.
PageViewForbidden
()
}
}
else
{
throw
new
WIKI
.
Error
.
PageNotFound
()
...
...
server/helpers/error.js
View file @
13a99513
...
...
@@ -137,6 +137,10 @@ module.exports = {
message
:
'Page content cannot be empty.'
,
code
:
6004
}),
PageHistoryForbidden
:
CustomError
(
'PageHistoryForbidden'
,
{
message
:
'You are not authorized to view the history of this page.'
,
code
:
6012
}),
PageIllegalPath
:
CustomError
(
'PageIllegalPath'
,
{
message
:
'Page path cannot contains illegal characters.'
,
code
:
6005
...
...
@@ -161,6 +165,10 @@ module.exports = {
message
:
'You are not authorized to update this page.'
,
code
:
6009
}),
PageViewForbidden
:
CustomError
(
'PageViewForbidden'
,
{
message
:
'You are not authorized to view this page.'
,
code
:
6013
}),
SearchActivationFailed
:
CustomError
(
'SearchActivationFailed'
,
{
message
:
'Search Engine activation failed.'
,
code
:
4002
...
...
server/models/pageHistory.js
View file @
13a99513
...
...
@@ -84,6 +84,9 @@ module.exports = class PageHistory extends Model {
this
.
createdAt
=
new
Date
().
toISOString
()
}
/**
* Create Page Version
*/
static
async
addVersion
(
opts
)
{
await
WIKI
.
models
.
pageHistory
.
query
().
insert
({
pageId
:
opts
.
id
,
...
...
@@ -105,6 +108,9 @@ module.exports = class PageHistory extends Model {
})
}
/**
* Get Page Version
*/
static
async
getVersion
({
pageId
,
versionId
})
{
const
version
=
await
WIKI
.
models
.
pageHistory
.
query
()
.
column
([
...
...
@@ -134,13 +140,20 @@ module.exports = class PageHistory extends Model {
'pageHistory.id'
:
versionId
,
'pageHistory.pageId'
:
pageId
}).
first
()
return
{
...
version
,
updatedAt
:
version
.
createdAt
,
tags
:
[]
if
(
version
)
{
return
{
...
version
,
updatedAt
:
version
.
createdAt
||
null
,
tags
:
[]
}
}
else
{
return
null
}
}
/**
* Get History Trail of a Page
*/
static
async
getHistory
({
pageId
,
offsetPage
=
0
,
offsetSize
=
100
})
{
const
history
=
await
WIKI
.
models
.
pageHistory
.
query
()
.
column
([
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment