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
cb84df7a
Commit
cb84df7a
authored
Jul 22, 2018
by
NGPixel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: save page
parent
c7b675bb
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
192 additions
and
66 deletions
+192
-66
settings.json
.vscode/settings.json
+0
-1
editor.vue
client/components/editor.vue
+46
-10
editor-modal-properties.vue
client/components/editor/editor-modal-properties.vue
+39
-12
create.gql
client/graph/editor/create.gql
+15
-0
save.gql
client/graph/editor/save.gql
+0
-7
index.js
client/store/index.js
+14
-10
2.0.0.js
server/db/migrations/2.0.0.js
+5
-5
pages.js
server/db/models/pages.js
+9
-1
users.js
server/db/models/users.js
+24
-2
page.js
server/graph/resolvers/page.js
+20
-11
page.graphql
server/graph/schemas/page.graphql
+17
-4
authentication.js
server/modules/authentication/local/authentication.js
+1
-1
setup.js
server/setup.js
+2
-2
No files found.
.vscode/settings.json
View file @
cb84df7a
...
...
@@ -2,7 +2,6 @@
"eslint.enable"
:
true
,
"eslint.autoFixOnSave"
:
true
,
"puglint.enable"
:
true
,
"standard.enable"
:
false
,
"editor.formatOnSave"
:
false
,
"editor.tabSize"
:
2
,
"eslint.validate"
:
[
...
...
client/components/editor.vue
View file @
cb84df7a
...
...
@@ -21,16 +21,27 @@
:size='60'
color='#FFF'
)
.subheading Processing
.caption.blue--text.text--lighten-3 Please wait...
.subheading
{{
$t
(
'editor:save.processing'
)
}}
.caption.blue--text.text--lighten-3
{{
$t
(
'editor:save.pleaseWait'
)
}}
v-snackbar(
:color='notification.style'
bottom,
right,
multi-line,
v-model='notificationState'
)
.text-xs-left
v-icon.mr-3(dark)
{{
notification
.
icon
}}
span
{{
notification
.
message
}}
</
template
>
<
script
>
import
_
from
'lodash'
import
{
get
}
from
'vuex-pathify'
import
{
get
,
sync
}
from
'vuex-pathify'
import
{
AtomSpinner
}
from
'epic-spinners'
import
savePageMutation
from
'gql/editor/sav
e.gql'
import
createPageMutation
from
'gql/editor/creat
e.gql'
import
editorStore
from
'@/store/editor'
...
...
@@ -51,7 +62,9 @@ export default {
}
},
computed
:
{
mode
:
get
(
'editor/mode'
)
mode
:
get
(
'editor/mode'
),
notification
:
get
(
'notification'
),
notificationState
:
sync
(
'notification@isActive'
)
},
mounted
()
{
if
(
this
.
mode
===
'create'
)
{
...
...
@@ -77,12 +90,35 @@ export default {
},
async
save
()
{
this
.
showProgressDialog
(
'saving'
)
// const resp = await this.$apollo.mutate({
// mutation: savePageMutation,
// variables: {
if
(
this
.
$store
.
get
(
'editor/mode'
)
===
'create'
)
{
const
resp
=
await
this
.
$apollo
.
mutate
({
mutation
:
createPageMutation
,
variables
:
{
description
:
this
.
$store
.
get
(
'editor/description'
),
editor
:
'markdown'
,
locale
:
this
.
$store
.
get
(
'editor/locale'
),
isPublished
:
this
.
$store
.
get
(
'editor/isPublished'
),
path
:
this
.
$store
.
get
(
'editor/path'
),
publishEndDate
:
this
.
$store
.
get
(
'editor/publishEndDate'
),
publishStartDate
:
this
.
$store
.
get
(
'editor/publishStartDate'
),
tags
:
this
.
$store
.
get
(
'editor/tags'
),
title
:
this
.
$store
.
get
(
'editor/title'
)
}
})
if
(
_
.
get
(
resp
,
'data.pages.create.responseResult.succeeded'
))
{
this
.
$store
.
commit
(
'showNotification'
,
{
message
:
this
.
$t
(
'editor:save.success'
),
style
:
'success'
,
icon
:
'check'
})
this
.
$store
.
set
(
'editor/mode'
,
'update'
)
}
else
{
}
}
else
{
//
}
// }
)
}
this
.
hideProgressDialog
(
)
}
}
}
...
...
client/components/editor/editor-modal-properties.vue
View file @
cb84df7a
...
...
@@ -32,30 +32,46 @@
counter='255'
v-model='description'
)
v-text-field(
outline
background-color='grey lighten-2'
label='Path'
prefix='/'
append-icon='folder'
v-model='path'
)
v-divider
v-card-text
v-subheader.pl-0 Tags
v-card-text.grey.lighten-5
v-subheader.pl-0 Path & Categorization
v-container.pa-0(fluid, grid-list-lg)
v-layout(row, wrap)
v-flex(xs12, md2)
v-select(
outline
background-color='grey lighten-2'
label='Locale'
suffix='/'
:items='namespaces'
v-model='locale'
hide-details
)
v-flex(xs12, md10)
v-text-field(
outline
background-color='grey lighten-2'
label='Path'
append-icon='folder'
v-model='path'
hint='Do not include any leading or trailing slashes.'
persistent-hint
@click:append='showPathSelector'
)
v-combobox(
background-color='grey lighten-2'
chips
deletable-chips
hide-details
label='Tags'
outline
multiple
v-model='tags'
single-line
hint='Use tags to categorize your pages and make them easier to find.'
persistent-hint
)
v-divider
v-card-text.pb-5
v-card-text.pb-5
.grey.lighten-4
v-subheader.pl-0 Publishing State
v-container.pa-0(fluid, grid-list-lg)
v-layout(row, wrap)
...
...
@@ -64,6 +80,8 @@
label='Published'
v-model='isPublished'
color='primary'
hint='Unpublished pages can still be seen by users having write permissions.'
persistent-hint
)
v-flex(xs12, md4)
v-dialog(
...
...
@@ -165,6 +183,7 @@ export default {
isShown
:
false
,
isPublishStartShown
:
false
,
isPublishEndShown
:
false
,
namespaces
:
[
'en'
],
tourSteps
:
[
{
target
:
'.dialog-header'
,
...
...
@@ -176,6 +195,7 @@ export default {
computed
:
{
title
:
sync
(
'editor/title'
),
description
:
sync
(
'editor/description'
),
locale
:
sync
(
'editor/locale'
),
tags
:
sync
(
'editor/tags'
),
path
:
sync
(
'editor/path'
),
isPublished
:
sync
(
'editor/isPublished'
),
...
...
@@ -193,6 +213,13 @@ export default {
close
()
{
this
.
isShown
=
false
this
.
$parent
.
$parent
.
closeModal
()
},
showPathSelector
()
{
this
.
$store
.
commit
(
'showNotification'
,
{
message
:
'Coming soon!'
,
style
:
'purple'
,
icon
:
'directions_boat'
})
}
}
}
...
...
client/graph/editor/create.gql
0 → 100644
View file @
cb84df7a
mutation
(
$description
:
String
,
$editor
:
String
,
$isPublished
:
Boolean
!,
$locale
:
String
!,
$path
:
String
!,
$publishEndDate
:
Date
,
$publishStartDate
:
Date
,
$tags
:
[
String
],
$title
:
String
!)
{
pages
{
create
(
description
:
$description
,
editor
:
$editor
,
isPublished
:
$isPublished
,
locale
:
$locale
,
path
:
$path
,
publishEndDate
:
$publishEndDate
,
publishStartDate
:
$publishStartDate
,
tags
:
$tags
,
title
:
$title
)
{
responseResult
{
succeeded
errorCode
slug
message
}
page
{
id
}
}
}
}
client/graph/editor/save.gql
deleted
100644 → 0
View file @
c7b675bb
mutation
{
page
{
create
{
page
}
}
}
client/store/index.js
View file @
cb84df7a
import
_
from
'lodash'
import
Vue
from
'vue'
import
Vuex
from
'vuex'
import
pathify
from
'vuex-pathify'
import
pathify
from
'vuex-pathify'
// eslint-disable-line import/no-duplicates
import
{
make
}
from
'vuex-pathify'
// eslint-disable-line import/no-duplicates
Vue
.
use
(
Vuex
)
const
state
=
{
loadingStack
:
[],
notification
:
{
message
:
''
,
style
:
'primary'
,
icon
:
'cached'
,
isActive
:
false
}
}
export
default
new
Vuex
.
Store
({
strict
:
process
.
env
.
NODE_ENV
!==
'production'
,
plugins
:
[
pathify
.
plugin
],
state
:
{
loadingStack
:
[],
notification
:
{
message
:
''
,
style
:
'primary'
,
icon
:
'cached'
,
isActive
:
false
}
},
state
,
getters
:
{
isLoading
:
state
=>
{
return
state
.
loadingStack
.
length
>
0
}
},
mutations
:
{
...
make
.
mutations
(
state
),
loadingStart
(
state
,
stackName
)
{
state
.
loadingStack
=
_
.
union
(
state
.
loadingStack
,
[
stackName
])
},
...
...
server/db/migrations/2.0.0.js
View file @
cb84df7a
...
...
@@ -150,16 +150,16 @@ exports.up = knex => {
table
.
integer
(
'authorId'
).
unsigned
().
references
(
'id'
).
inTable
(
'users'
)
})
.
table
(
'pages'
,
table
=>
{
table
.
string
(
'editor'
).
references
(
'key'
).
inTable
(
'editors'
)
table
.
string
(
'locale'
,
2
).
references
(
'code'
).
inTable
(
'locales'
)
table
.
string
(
'editor
Key
'
).
references
(
'key'
).
inTable
(
'editors'
)
table
.
string
(
'locale
Code
'
,
2
).
references
(
'code'
).
inTable
(
'locales'
)
table
.
integer
(
'authorId'
).
unsigned
().
references
(
'id'
).
inTable
(
'users'
)
})
.
table
(
'users'
,
table
=>
{
table
.
string
(
'provider'
).
references
(
'key'
).
inTable
(
'authentication'
).
notNullable
().
defaultTo
(
'local'
)
table
.
string
(
'locale'
,
2
).
references
(
'code'
).
inTable
(
'locales'
).
notNullable
().
defaultTo
(
'en'
)
table
.
string
(
'provider
Key
'
).
references
(
'key'
).
inTable
(
'authentication'
).
notNullable
().
defaultTo
(
'local'
)
table
.
string
(
'locale
Code
'
,
2
).
references
(
'code'
).
inTable
(
'locales'
).
notNullable
().
defaultTo
(
'en'
)
table
.
string
(
'defaultEditor'
).
references
(
'key'
).
inTable
(
'editors'
).
notNullable
().
defaultTo
(
'markdown'
)
table
.
unique
([
'provider'
,
'email'
])
table
.
unique
([
'provider
Key
'
,
'email'
])
})
}
...
...
server/db/models/pages.js
View file @
cb84df7a
...
...
@@ -49,11 +49,19 @@ module.exports = class Page extends Model {
to
:
'users.id'
}
},
editor
:
{
relation
:
Model
.
BelongsToOneRelation
,
modelClass
:
require
(
'./editors'
),
join
:
{
from
:
'pages.editorKey'
,
to
:
'editors.key'
}
},
locale
:
{
relation
:
Model
.
BelongsToOneRelation
,
modelClass
:
require
(
'./locales'
),
join
:
{
from
:
'
users.local
e'
,
from
:
'
pages.localeCod
e'
,
to
:
'locales.code'
}
}
...
...
server/db/models/users.js
View file @
cb84df7a
...
...
@@ -23,13 +23,11 @@ module.exports = class User extends Model {
id
:
{
type
:
'integer'
},
email
:
{
type
:
'string'
,
format
:
'email'
},
name
:
{
type
:
'string'
,
minLength
:
1
,
maxLength
:
255
},
provider
:
{
type
:
'string'
,
minLength
:
1
,
maxLength
:
255
},
providerId
:
{
type
:
'number'
},
password
:
{
type
:
'string'
},
role
:
{
type
:
'string'
,
enum
:
[
'admin'
,
'guest'
,
'user'
]},
tfaIsActive
:
{
type
:
'boolean'
,
default
:
false
},
tfaSecret
:
{
type
:
'string'
},
locale
:
{
type
:
'string'
},
jobTitle
:
{
type
:
'string'
},
location
:
{
type
:
'string'
},
pictureUrl
:
{
type
:
'string'
},
...
...
@@ -52,6 +50,30 @@ module.exports = class User extends Model {
},
to
:
'groups.id'
}
},
provider
:
{
relation
:
Model
.
BelongsToOneRelation
,
modelClass
:
require
(
'./authentication'
),
join
:
{
from
:
'users.providerKey'
,
to
:
'authentication.key'
}
},
defaultEditor
:
{
relation
:
Model
.
BelongsToOneRelation
,
modelClass
:
require
(
'./editors'
),
join
:
{
from
:
'users.editorKey'
,
to
:
'editors.key'
}
},
locale
:
{
relation
:
Model
.
BelongsToOneRelation
,
modelClass
:
require
(
'./locales'
),
join
:
{
from
:
'users.localeCode'
,
to
:
'locales.code'
}
}
}
}
...
...
server/graph/resolvers/page.js
View file @
cb84df7a
...
...
@@ -11,35 +11,44 @@ module.exports = {
},
PageQuery
:
{
async
list
(
obj
,
args
,
context
,
info
)
{
return
WIKI
.
db
.
group
s
.
query
().
select
(
'
group
s.*'
,
WIKI
.
db
.
group
s
.
relatedQuery
(
'users'
).
count
().
as
(
'userCount'
)
return
WIKI
.
db
.
page
s
.
query
().
select
(
'
page
s.*'
,
WIKI
.
db
.
page
s
.
relatedQuery
(
'users'
).
count
().
as
(
'userCount'
)
)
},
async
single
(
obj
,
args
,
context
,
info
)
{
return
WIKI
.
db
.
group
s
.
query
().
findById
(
args
.
id
)
return
WIKI
.
db
.
page
s
.
query
().
findById
(
args
.
id
)
}
},
PageMutation
:
{
async
create
(
obj
,
args
)
{
const
group
=
await
WIKI
.
db
.
pages
.
query
().
insertAndFetch
({
name
:
args
.
name
async
create
(
obj
,
args
,
context
)
{
const
page
=
await
WIKI
.
db
.
pages
.
query
().
insertAndFetch
({
path
:
args
.
path
,
title
:
args
.
title
,
description
:
args
.
description
,
isPrivate
:
false
,
isPublished
:
args
.
isPublished
,
publishStartDate
:
args
.
publishStartDate
,
publishEndDate
:
args
.
publishEndDate
,
localeCode
:
args
.
locale
,
editorKey
:
args
.
editor
,
authorId
:
context
.
req
.
user
.
id
})
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'
Group
created successfully.'
),
group
responseResult
:
graphHelper
.
generateSuccess
(
'
Page
created successfully.'
),
page
}
},
async
delete
(
obj
,
args
)
{
await
WIKI
.
db
.
groups
.
query
().
deleteById
(
args
.
id
)
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'
Group
has been deleted.'
)
responseResult
:
graphHelper
.
generateSuccess
(
'
Page
has been deleted.'
)
}
},
async
update
(
obj
,
args
)
{
await
WIKI
.
db
.
groups
.
query
().
patch
({
name
:
args
.
name
}).
where
(
'id'
,
args
.
id
)
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'
Group
has been updated.'
)
responseResult
:
graphHelper
.
generateSuccess
(
'
Page
has been updated.'
)
}
}
},
...
...
server/graph/schemas/page.graphql
View file @
cb84df7a
...
...
@@ -21,7 +21,10 @@ type PageQuery {
):
[
PageMinimal
]
single
(
id
:
Int
!
id
:
Int
path
:
String
locale
:
String
isPrivate
:
Boolean
):
Page
}
...
...
@@ -32,8 +35,10 @@ type PageQuery {
type
PageMutation
{
create
(
description
:
String
isPublished
:
Boolean
locale
:
String
editor
:
String
isPublished
:
Boolean
!
isPrivate
:
Boolean
locale
:
String
!
path
:
String
!
publishEndDate
:
Date
publishStartDate
:
Date
...
...
@@ -43,7 +48,15 @@ type PageMutation {
update
(
id
:
Int
!
name
:
String
!
description
:
String
editor
:
String
isPublished
:
Boolean
locale
:
String
path
:
String
publishEndDate
:
Date
publishStartDate
:
Date
tags
:
[
String
]
title
:
String
):
DefaultResponse
delete
(
...
...
server/modules/authentication/local/authentication.js
View file @
cb84df7a
...
...
@@ -15,7 +15,7 @@ module.exports = {
},
(
uEmail
,
uPassword
,
done
)
=>
{
WIKI
.
db
.
users
.
query
().
findOne
({
email
:
uEmail
,
provider
:
'local'
provider
Key
:
'local'
}).
then
((
user
)
=>
{
if
(
user
)
{
return
user
.
verifyPassword
(
uPassword
).
then
(()
=>
{
...
...
server/setup.js
View file @
cb84df7a
...
...
@@ -325,7 +325,7 @@ module.exports = () => {
// Create root administrator
WIKI
.
logger
.
info
(
'Creating root administrator...'
)
await
WIKI
.
db
.
users
.
query
().
delete
().
where
({
provider
:
'local'
,
provider
Key
:
'local'
,
email
:
req
.
body
.
adminEmail
})
await
WIKI
.
db
.
users
.
query
().
insert
({
...
...
@@ -342,7 +342,7 @@ module.exports = () => {
// Create Guest account
WIKI
.
logger
.
info
(
'Creating guest account...'
)
const
guestUsr
=
await
WIKI
.
db
.
users
.
query
().
findOne
({
provider
:
'local'
,
provider
Key
:
'local'
,
email
:
'guest@example.com'
})
if
(
!
guestUsr
)
{
...
...
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