feat: delete page
This commit is contained in:
parent
faa1f389d9
commit
658c105ab5
1
.gitignore
vendored
1
.gitignore
vendored
@ -29,6 +29,7 @@ npm-debug.log*
|
||||
/repo
|
||||
/data
|
||||
/uploads
|
||||
/content
|
||||
*.sqlite
|
||||
|
||||
# IDE exclude
|
||||
|
@ -5,8 +5,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
## [2.0.0-beta.12] - 2018-01-27
|
||||
### Added
|
||||
- Added Patreon link in Contribute admin page
|
||||
- Added Theme Code Injection feature
|
||||
- Added Theme Code Injection functionality
|
||||
- Added Theme CSS Injection code minification
|
||||
- Added Page Delete functionality
|
||||
|
||||
### Fixed
|
||||
- Fixed root admin refresh token fail
|
||||
@ -14,6 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
### Changed
|
||||
- Moved Insert Media button in Markdown editor
|
||||
- Use semver for DB migrations ordering
|
||||
|
||||
## [2.0.0-beta.11] - 2018-01-20
|
||||
- First beta release
|
||||
|
5
Makefile
5
Makefile
@ -35,9 +35,12 @@ docker-dev-rebuild: ## Rebuild dockerized dev image
|
||||
|
||||
docker-dev-clean: ## Clean DB, redis and data folders
|
||||
rm -rf ./data
|
||||
docker-compose -f ./dev/docker/docker-compose.yml -p wiki --project-directory . exec db psql --dbname=wiki --username=postgres --command='DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public'
|
||||
docker-compose -f ./dev/docker/docker-compose.yml -p wiki --project-directory . exec db psql --dbname=wiki --username=wikijs --command='DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public'
|
||||
docker-compose -f ./dev/docker/docker-compose.yml -p wiki --project-directory . exec redis redis-cli flushall
|
||||
|
||||
docker-dev-bash: ## Rebuild dockerized dev image
|
||||
docker-compose -f ./dev/docker/docker-compose.yml -p wiki --project-directory . exec wiki bash
|
||||
|
||||
docker-build: ## Run assets generation build in docker
|
||||
docker-compose -f ./dev/docker/docker-compose.yml -p wiki --project-directory . run wiki yarn build
|
||||
docker-compose -f ./dev/docker/docker-compose.yml -p wiki --project-directory . down
|
||||
|
@ -203,7 +203,7 @@ export default {
|
||||
<style lang='scss'>
|
||||
|
||||
.admin {
|
||||
&.theme--light {
|
||||
&.theme--light .application--wrap {
|
||||
background-color: lighten(mc('grey', '200'), 2%);
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,20 @@ export default {
|
||||
restrictedForSystem: false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
permission: 'read:source',
|
||||
hint: 'Can view pages source, as specified in the Page Rules',
|
||||
warning: false,
|
||||
restrictedForSystem: false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
permission: 'read:history',
|
||||
hint: 'Can view pages history, as specified in the Page Rules',
|
||||
warning: false,
|
||||
restrictedForSystem: false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
permission: 'read:assets',
|
||||
hint: 'Can view / use assets (such as images and files), as specified in the Page Rules',
|
||||
|
@ -206,6 +206,8 @@ export default {
|
||||
{ text: 'Create Pages', value: 'write:pages', icon: 'insert_drive_file' },
|
||||
{ text: 'Edit + Move Pages', value: 'manage:pages', icon: 'insert_drive_file' },
|
||||
{ text: 'Delete Pages', value: 'delete:pages', icon: 'insert_drive_file' },
|
||||
{ text: 'View Pages Source', value: 'read:source', icon: 'code' },
|
||||
{ text: 'View Pages History', value: 'read:history', icon: 'restore' },
|
||||
{ text: 'Read / Use Assets', value: 'read:assets', icon: 'camera' },
|
||||
{ text: 'Upload Assets', value: 'write:assets', icon: 'camera' },
|
||||
{ text: 'Edit + Delete Assets', value: 'manage:assets', icon: 'camera' },
|
||||
|
@ -131,6 +131,7 @@
|
||||
span Login
|
||||
|
||||
page-selector(mode='create', v-model='newPageModal', :open-handler='pageNewCreate')
|
||||
page-delete(v-model='deletePageModal', v-if='path && path.length')
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -139,6 +140,9 @@ import _ from 'lodash'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PageDelete: () => import('./page-delete.vue')
|
||||
},
|
||||
props: {
|
||||
dense: {
|
||||
type: Boolean,
|
||||
@ -155,7 +159,8 @@ export default {
|
||||
searchIsLoading: false,
|
||||
searchIsShown: true,
|
||||
search: '',
|
||||
newPageModal: false
|
||||
newPageModal: false,
|
||||
deletePageModal: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -233,11 +238,7 @@ export default {
|
||||
})
|
||||
},
|
||||
pageDelete () {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'indigo',
|
||||
message: `Coming soon...`,
|
||||
icon: 'directions_boat'
|
||||
})
|
||||
this.deletePageModal = true
|
||||
},
|
||||
assets () {
|
||||
this.$store.commit('showNotification', {
|
||||
|
110
client/components/common/page-delete.vue
Normal file
110
client/components/common/page-delete.vue
Normal file
@ -0,0 +1,110 @@
|
||||
<template lang='pug'>
|
||||
v-dialog(v-model='isShown', max-width='550', persistent)
|
||||
v-card.wiki-form
|
||||
.dialog-header.is-short.is-red
|
||||
v-icon.mr-2(color='white') highlight_off
|
||||
span Delete Page
|
||||
v-card-text
|
||||
.body-2 Are you sure you want to delete page #[span.red--text.text--darken-2 {{pageTitle}}]?
|
||||
.caption The page can be restored from the administration area.
|
||||
v-chip.mt-3.ml-0.mr-1(label, color='red lighten-4', disabled, small)
|
||||
.caption.red--text.text--darken-2 {{pageLocale.toUpperCase()}}
|
||||
v-chip.mt-3.mx-0(label, color='red lighten-5', disabled, small)
|
||||
span.red--text.text--darken-2 /{{pagePath}}
|
||||
v-card-chin
|
||||
v-spacer
|
||||
v-btn(flat, @click='discard', :disabled='loading') Cancel
|
||||
v-btn(color='red darken-2', @click='deletePage', :loading='loading').white--text Delete
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import { get } from 'vuex-pathify'
|
||||
|
||||
import deletePageMutation from 'gql/common/common-pages-mutation-delete.gql'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isShown: {
|
||||
get() { return this.value },
|
||||
set(val) { this.$emit('input', val) }
|
||||
},
|
||||
pageTitle: get('page/title'),
|
||||
pagePath: get('page/path'),
|
||||
pageLocale: get('page/locale'),
|
||||
pageId: get('page/id')
|
||||
},
|
||||
watch: {
|
||||
isShown(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
document.body.classList.add('page-deleted-pending')
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
discard() {
|
||||
document.body.classList.remove('page-deleted-pending')
|
||||
this.isShown = false
|
||||
},
|
||||
async deletePage() {
|
||||
this.loading = true
|
||||
this.$store.commit(`loadingStart`, 'page-delete')
|
||||
this.$nextTick(async () => {
|
||||
try {
|
||||
const resp = await this.$apollo.mutate({
|
||||
mutation: deletePageMutation,
|
||||
variables: {
|
||||
id: this.pageId
|
||||
}
|
||||
})
|
||||
if (_.get(resp, 'data.pages.delete.responseResult.succeeded', false)) {
|
||||
this.isShown = false
|
||||
_.delay(() => {
|
||||
document.body.classList.add('page-deleted')
|
||||
_.delay(() => {
|
||||
window.location.assign('/')
|
||||
}, 1200)
|
||||
}, 400)
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.pages.delete.responseResult.message', 'An unexpected error occured.'))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('pushGraphError', err)
|
||||
}
|
||||
this.$store.commit(`loadingStop`, 'page-delete')
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
body.page-deleted-pending {
|
||||
.application {
|
||||
background-color: mc('grey', '900');
|
||||
}
|
||||
.application--wrap {
|
||||
transform: translateZ(-5vw) rotateX(2deg);
|
||||
border-radius: 7px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
body.page-deleted {
|
||||
.application--wrap {
|
||||
transform: translateZ(-1000vw) rotateX(60deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -14,7 +14,7 @@
|
||||
outline
|
||||
color='blue'
|
||||
@click.native.stop='openPropsModal'
|
||||
:class='{ "is-icon": $vuetify.breakpoint.mdAndDown, "mx-0": !welcomeMode, "ml-0": !welcomeMode }'
|
||||
:class='{ "is-icon": $vuetify.breakpoint.mdAndDown, "mx-0": !welcomeMode, "ml-0": welcomeMode }'
|
||||
)
|
||||
v-icon(color='blue', :left='$vuetify.breakpoint.lgAndUp') sort_by_alpha
|
||||
span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:page') }}
|
||||
@ -282,6 +282,10 @@ export default {
|
||||
.editor {
|
||||
background-color: mc('grey', '900') !important;
|
||||
min-height: 100vh;
|
||||
|
||||
.application--wrap {
|
||||
background-color: mc('grey', '900');
|
||||
}
|
||||
}
|
||||
|
||||
.atom-spinner.is-inline {
|
||||
|
12
client/graph/common/common-pages-mutation-delete.gql
Normal file
12
client/graph/common/common-pages-mutation-delete.gql
Normal file
@ -0,0 +1,12 @@
|
||||
mutation($id: Int!) {
|
||||
pages {
|
||||
delete(id: $id) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
perspective: 50vw;
|
||||
background-color: mc('grey', '900');
|
||||
}
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
@ -19,6 +21,17 @@ html {
|
||||
}
|
||||
}
|
||||
|
||||
.application--wrap {
|
||||
transition: all 1.2s ease;
|
||||
transform-style: preserve-3d;
|
||||
transform-origin: 50% 50%;
|
||||
background-color: #FFF;
|
||||
|
||||
@at-root .theme--dark & {
|
||||
background-color: mc('grey', '900');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@for $i from 0 through 25 {
|
||||
.radius-#{$i} {
|
||||
|
@ -132,6 +132,10 @@ export default {
|
||||
StatusIndicator
|
||||
},
|
||||
props: {
|
||||
pageId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
locale: {
|
||||
type: String,
|
||||
default: 'en'
|
||||
@ -229,6 +233,7 @@ export default {
|
||||
this.$store.commit('page/SET_CREATED_AT', this.createdAt)
|
||||
this.$store.commit('page/SET_DESCRIPTION', this.description)
|
||||
this.$store.commit('page/SET_IS_PUBLISHED', this.isPublished)
|
||||
this.$store.commit('page/SET_ID', this.pageId)
|
||||
this.$store.commit('page/SET_LOCALE', this.locale)
|
||||
this.$store.commit('page/SET_PATH', this.path)
|
||||
this.$store.commit('page/SET_TAGS', this.tags)
|
||||
|
@ -5,7 +5,7 @@ FROM node:10-alpine
|
||||
LABEL maintainer "requarks.io"
|
||||
|
||||
RUN apk update && \
|
||||
apk add bash curl git python make g++ --no-cache && \
|
||||
apk add bash curl git python make g++ nano --no-cache && \
|
||||
mkdir -p /wiki
|
||||
|
||||
WORKDIR /wiki
|
||||
|
@ -1,6 +1,3 @@
|
||||
# -- DEV DOCKER-COMPOSE --
|
||||
# -- DO NOT USE IN PRODUCTION! --
|
||||
|
||||
version: "3"
|
||||
services:
|
||||
|
||||
|
200
package.json
200
package.json
@ -40,17 +40,16 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"apollo-fetch": "0.7.0",
|
||||
"apollo-server": "2.2.2",
|
||||
"apollo-server-express": "2.2.2",
|
||||
"apollo-server": "2.3.2",
|
||||
"apollo-server-express": "2.3.2",
|
||||
"auto-load": "3.0.4",
|
||||
"axios": "0.18.0",
|
||||
"js-base64": "2.5.0",
|
||||
"bcryptjs-then": "1.0.1",
|
||||
"bluebird": "3.5.3",
|
||||
"body-parser": "1.18.3",
|
||||
"bugsnag": "2.4.3",
|
||||
"bull": "3.5.2",
|
||||
"chalk": "2.4.1",
|
||||
"bull": "3.6.0",
|
||||
"chalk": "2.4.2",
|
||||
"cheerio": "1.0.0-rc.2",
|
||||
"child-process-promise": "2.2.1",
|
||||
"chokidar": "2.0.4",
|
||||
@ -60,36 +59,37 @@
|
||||
"cookie-parser": "1.4.3",
|
||||
"cors": "2.8.5",
|
||||
"custom-error-instance": "2.1.1",
|
||||
"dependency-graph": "0.7.2",
|
||||
"diff": "3.5.0",
|
||||
"diff2html": "2.5.0",
|
||||
"dependency-graph": "0.8.0",
|
||||
"diff": "4.0.1",
|
||||
"diff2html": "2.7.0",
|
||||
"dotize": "^0.2.0",
|
||||
"execa": "1.0.0",
|
||||
"express": "4.16.4",
|
||||
"express-brute": "1.0.1",
|
||||
"express-brute-redis": "0.0.1",
|
||||
"express-session": "1.15.6",
|
||||
"file-type": "10.4.0",
|
||||
"filesize": "3.6.1",
|
||||
"follow-redirects": "1.5.9",
|
||||
"file-type": "10.7.1",
|
||||
"filesize": "4.0.0",
|
||||
"follow-redirects": "1.6.1",
|
||||
"fs-extra": "7.0.1",
|
||||
"getos": "3.1.0",
|
||||
"graphql": "14.0.2",
|
||||
"getos": "3.1.1",
|
||||
"graphql": "14.1.1",
|
||||
"graphql-list-fields": "2.0.2",
|
||||
"graphql-subscriptions": "1.0.0",
|
||||
"graphql-tools": "4.0.3",
|
||||
"graphql-tools": "4.0.4",
|
||||
"highlight.js": "9.13.1",
|
||||
"i18next": "12.0.0",
|
||||
"i18next-express-middleware": "1.5.0",
|
||||
"i18next": "14.0.1",
|
||||
"i18next-express-middleware": "1.7.1",
|
||||
"i18next-localstorage-cache": "1.1.1",
|
||||
"i18next-node-fs-backend": "2.1.0",
|
||||
"image-size": "0.6.3",
|
||||
"ioredis": "4.2.0",
|
||||
"i18next-node-fs-backend": "2.1.1",
|
||||
"image-size": "0.7.1",
|
||||
"ioredis": "4.5.1",
|
||||
"js-base64": "2.5.1",
|
||||
"js-binary": "1.2.0",
|
||||
"js-yaml": "3.12.0",
|
||||
"js-yaml": "3.12.1",
|
||||
"jsonwebtoken": "8.4.0",
|
||||
"klaw": "3.0.0",
|
||||
"knex": "0.15.2",
|
||||
"knex": "0.16.3",
|
||||
"lodash": "4.17.11",
|
||||
"markdown-it": "8.4.2",
|
||||
"markdown-it-abbr": "1.0.4",
|
||||
@ -107,18 +107,18 @@
|
||||
"markdown-it-task-lists": "2.1.1",
|
||||
"mathjax-node": "2.1.1",
|
||||
"mime-types": "2.1.21",
|
||||
"moment": "2.22.2",
|
||||
"moment": "2.24.0",
|
||||
"moment-timezone": "0.5.23",
|
||||
"mongodb": "3.1.10",
|
||||
"mssql": "4.2.3",
|
||||
"mongodb": "3.1.13",
|
||||
"mssql": "4.3.0",
|
||||
"multer": "1.4.1",
|
||||
"mysql2": "1.6.4",
|
||||
"nanoid": "2.0.0",
|
||||
"nanoid": "2.0.1",
|
||||
"node-2fa": "1.1.2",
|
||||
"node-cache": "4.2.0",
|
||||
"nodemailer": "4.7.0",
|
||||
"nodemailer": "5.1.1",
|
||||
"oauth2orize": "1.11.0",
|
||||
"objection": "1.4.0",
|
||||
"objection": "1.5.3",
|
||||
"ora": "3.0.0",
|
||||
"passport": "0.4.0",
|
||||
"passport-auth0": "1.1.0",
|
||||
@ -126,23 +126,23 @@
|
||||
"passport-cas": "0.1.1",
|
||||
"passport-discord": "0.1.3",
|
||||
"passport-dropbox-oauth2": "1.1.0",
|
||||
"passport-facebook": "2.1.1",
|
||||
"passport-facebook": "3.0.0",
|
||||
"passport-github2": "0.1.11",
|
||||
"passport-google-oauth20": "1.0.0",
|
||||
"passport-jwt": "4.0.0",
|
||||
"passport-ldapauth": "2.1.0",
|
||||
"passport-ldapauth": "2.1.1",
|
||||
"passport-local": "1.0.0",
|
||||
"passport-oauth2": "1.4.0",
|
||||
"passport-okta-oauth": "0.0.1",
|
||||
"passport-openidconnect": "0.0.2",
|
||||
"passport-saml": "0.35.0",
|
||||
"passport-saml": "1.0.0",
|
||||
"passport-slack": "0.0.7",
|
||||
"passport-twitch": "1.0.3",
|
||||
"passport-windowslive": "1.0.2",
|
||||
"pem-jwk": "1.5.1",
|
||||
"pg": "7.6.1",
|
||||
"pem-jwk": "2.0.0",
|
||||
"pg": "7.8.0",
|
||||
"pg-hstore": "2.3.2",
|
||||
"pm2": "3.2.2",
|
||||
"pm2": "3.2.9",
|
||||
"pug": "2.0.3",
|
||||
"qr-image": "3.2.0",
|
||||
"raven": "2.6.4",
|
||||
@ -154,73 +154,73 @@
|
||||
"scim-query-filter-parser": "1.1.0",
|
||||
"semver": "5.6.0",
|
||||
"serve-favicon": "2.5.0",
|
||||
"sqlite3": "4.0.4",
|
||||
"sqlite3": "4.0.6",
|
||||
"subscriptions-transport-ws": "0.9.15",
|
||||
"twemoji": "11.2.0",
|
||||
"uslug": "1.0.4",
|
||||
"uuid": "3.3.2",
|
||||
"validate.js": "0.12.0",
|
||||
"validator": "10.9.0",
|
||||
"validator": "10.11.0",
|
||||
"validator-as-promised": "1.0.2",
|
||||
"winston": "3.1.0",
|
||||
"yargs": "12.0.4"
|
||||
"yargs": "12.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.1.5",
|
||||
"@babel/core": "^7.1.6",
|
||||
"@babel/plugin-proposal-class-properties": "^7.1.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.1.6",
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
|
||||
"@babel/plugin-proposal-function-sent": "^7.1.0",
|
||||
"@babel/plugin-proposal-json-strings": "^7.0.0",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||
"@babel/plugin-syntax-import-meta": "^7.0.0",
|
||||
"@babel/polyfill": "^7.0.0",
|
||||
"@babel/preset-env": "^7.1.6",
|
||||
"@panter/vue-i18next": "0.13.0",
|
||||
"animated-number-vue": "0.1.3",
|
||||
"apollo-cache-inmemory": "1.3.10",
|
||||
"apollo-client": "2.4.6",
|
||||
"apollo-link": "1.2.3",
|
||||
"apollo-link-batch-http": "1.2.3",
|
||||
"apollo-link-error": "1.1.1",
|
||||
"apollo-link-http": "1.5.5",
|
||||
"@babel/cli": "^7.2.3",
|
||||
"@babel/core": "^7.2.2",
|
||||
"@babel/plugin-proposal-class-properties": "^7.3.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.3.0",
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.2.0",
|
||||
"@babel/plugin-proposal-function-sent": "^7.2.0",
|
||||
"@babel/plugin-proposal-json-strings": "^7.2.0",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/plugin-syntax-import-meta": "^7.2.0",
|
||||
"@babel/polyfill": "^7.2.5",
|
||||
"@babel/preset-env": "^7.3.1",
|
||||
"@panter/vue-i18next": "0.15.0",
|
||||
"animated-number-vue": "0.1.4",
|
||||
"apollo-cache-inmemory": "1.4.2",
|
||||
"apollo-client": "2.4.12",
|
||||
"apollo-link": "1.2.6",
|
||||
"apollo-link-batch-http": "1.2.6",
|
||||
"apollo-link-error": "1.1.5",
|
||||
"apollo-link-http": "1.5.9",
|
||||
"apollo-link-persisted-queries": "0.2.2",
|
||||
"apollo-link-ws": "1.0.9",
|
||||
"apollo-utilities": "1.0.25",
|
||||
"autoprefixer": "9.3.1",
|
||||
"apollo-link-ws": "1.0.12",
|
||||
"apollo-utilities": "1.1.2",
|
||||
"autoprefixer": "9.4.6",
|
||||
"babel-eslint": "10.0.1",
|
||||
"babel-jest": "23.6.0",
|
||||
"babel-loader": "^8.0.4",
|
||||
"babel-jest": "24.0.0",
|
||||
"babel-loader": "^8.0.5",
|
||||
"babel-plugin-graphql-tag": "1.6.0",
|
||||
"babel-plugin-lodash": "3.3.4",
|
||||
"babel-plugin-transform-imports": "1.5.1",
|
||||
"brace": "0.11.1",
|
||||
"cache-loader": "1.2.5",
|
||||
"cache-loader": "2.0.1",
|
||||
"chart.js": "2.7.3",
|
||||
"clean-webpack-plugin": "1.0.0",
|
||||
"clean-webpack-plugin": "1.0.1",
|
||||
"copy-webpack-plugin": "4.6.0",
|
||||
"core-js": "2.5.7",
|
||||
"css-loader": "1.0.1",
|
||||
"cssnano": "4.1.7",
|
||||
"core-js": "2.6.3",
|
||||
"css-loader": "2.1.0",
|
||||
"cssnano": "4.1.8",
|
||||
"duplicate-package-checker-webpack-plugin": "3.0.0",
|
||||
"epic-spinners": "1.0.4",
|
||||
"eslint": "5.9.0",
|
||||
"eslint": "5.12.1",
|
||||
"eslint-config-requarks": "1.0.7",
|
||||
"eslint-config-standard": "12.0.0",
|
||||
"eslint-plugin-import": "2.14.0",
|
||||
"eslint-plugin-node": "8.0.0",
|
||||
"eslint-plugin-import": "2.15.0",
|
||||
"eslint-plugin-node": "8.0.1",
|
||||
"eslint-plugin-promise": "4.0.1",
|
||||
"eslint-plugin-standard": "4.0.0",
|
||||
"eslint-plugin-vue": "4.7.1",
|
||||
"file-loader": "2.0.0",
|
||||
"eslint-plugin-vue": "5.1.0",
|
||||
"file-loader": "3.0.1",
|
||||
"filesize.js": "1.0.2",
|
||||
"grapesjs": "0.14.40",
|
||||
"grapesjs": "0.14.50",
|
||||
"graphiql": "0.12.0",
|
||||
"graphql-persisted-document-loader": "1.0.1",
|
||||
"graphql-tag": "^2.10.0",
|
||||
"graphql-tag": "^2.10.1",
|
||||
"graphql-voyager": "1.0.0-rc.26",
|
||||
"hammerjs": "2.0.8",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
@ -228,8 +228,8 @@
|
||||
"i18next-xhr-backend": "1.5.1",
|
||||
"ignore-loader": "0.1.2",
|
||||
"js-cookie": "2.2.0",
|
||||
"mini-css-extract-plugin": "0.4.4",
|
||||
"node-sass": "4.9.4",
|
||||
"mini-css-extract-plugin": "0.5.0",
|
||||
"node-sass": "4.11.0",
|
||||
"offline-plugin": "5.0.6",
|
||||
"optimize-css-assets-webpack-plugin": "5.0.1",
|
||||
"postcss-cssnext": "3.1.0",
|
||||
@ -237,14 +237,14 @@
|
||||
"postcss-flexibility": "2.0.0",
|
||||
"postcss-import": "12.0.1",
|
||||
"postcss-loader": "3.0.0",
|
||||
"postcss-preset-env": "6.4.0",
|
||||
"postcss-selector-parser": "5.0.0-rc.4",
|
||||
"postcss-preset-env": "6.5.0",
|
||||
"postcss-selector-parser": "5.0.0",
|
||||
"pug-lint": "2.5.0",
|
||||
"pug-loader": "2.4.0",
|
||||
"pug-plain-loader": "1.0.0",
|
||||
"raw-loader": "0.5.1",
|
||||
"react": "16.6.3",
|
||||
"react-dom": "16.6.3",
|
||||
"raw-loader": "1.0.0",
|
||||
"react": "16.7.0",
|
||||
"react-dom": "16.7.0",
|
||||
"resolve-url-loader": "3.0.0",
|
||||
"sass-loader": "7.1.0",
|
||||
"sass-resources-loader": "2.0.0",
|
||||
@ -255,40 +255,40 @@
|
||||
"stylus-loader": "3.0.2",
|
||||
"twemoji-awesome": "1.0.6",
|
||||
"url-loader": "1.1.2",
|
||||
"vee-validate": "2.1.3",
|
||||
"vee-validate": "2.1.5",
|
||||
"velocity-animate": "1.5.2",
|
||||
"viz.js": "2.1.1",
|
||||
"vue": "2.5.17",
|
||||
"vue-apollo": "3.0.0-beta.26",
|
||||
"viz.js": "2.1.2",
|
||||
"vue": "2.5.22",
|
||||
"vue-apollo": "3.0.0-beta.27",
|
||||
"vue-chartjs": "3.4.0",
|
||||
"vue-clipboards": "1.2.4",
|
||||
"vue-codemirror": "4.0.6",
|
||||
"vue-hot-reload-api": "2.3.1",
|
||||
"vue-loader": "15.4.2",
|
||||
"vue-material-design-icons": "2.4.0",
|
||||
"vue-loader": "15.6.1",
|
||||
"vue-material-design-icons": "2.6.0",
|
||||
"vue-moment": "4.0.0",
|
||||
"vue-router": "3.0.1",
|
||||
"vue-router": "3.0.2",
|
||||
"vue-simple-breakpoints": "1.0.3",
|
||||
"vue-status-indicator": "1.1.1",
|
||||
"vue-template-compiler": "2.5.17",
|
||||
"vue-template-compiler": "2.5.22",
|
||||
"vue-tour": "1.1.0",
|
||||
"vue2-animate": "2.1.0",
|
||||
"vuedraggable": "2.16.0",
|
||||
"vuescroll": "4.9.0-beta.14",
|
||||
"vuetify": "1.3.8",
|
||||
"vuex": "3.0.1",
|
||||
"vuedraggable": "2.17.0",
|
||||
"vuescroll": "4.9.6",
|
||||
"vuetify": "1.4.3",
|
||||
"vuex": "3.1.0",
|
||||
"vuex-pathify": "1.1.3",
|
||||
"vuex-persistedstate": "2.5.4",
|
||||
"webpack": "4.25.1",
|
||||
"webpack": "4.29.0",
|
||||
"webpack-bundle-analyzer": "3.0.3",
|
||||
"webpack-cli": "3.1.2",
|
||||
"webpack-dev-middleware": "3.4.0",
|
||||
"webpack-cli": "3.2.1",
|
||||
"webpack-dev-middleware": "3.5.1",
|
||||
"webpack-hot-middleware": "2.24.3",
|
||||
"webpack-merge": "4.1.4",
|
||||
"webpack-subresource-integrity": "1.3.0",
|
||||
"webpack-merge": "4.2.1",
|
||||
"webpack-subresource-integrity": "1.3.1",
|
||||
"whatwg-fetch": "3.0.0",
|
||||
"write-file-webpack-plugin": "4.4.1",
|
||||
"xterm": "3.8.0",
|
||||
"write-file-webpack-plugin": "4.5.0",
|
||||
"xterm": "3.10.1",
|
||||
"zxcvbn": "4.4.2"
|
||||
},
|
||||
"browserslist": [
|
||||
|
@ -5,6 +5,8 @@ const Promise = require('bluebird')
|
||||
const Knex = require('knex')
|
||||
const Objection = require('objection')
|
||||
|
||||
const migrationSource = require('../db/migrator-source')
|
||||
|
||||
/* global WIKI */
|
||||
|
||||
/**
|
||||
@ -89,12 +91,14 @@ module.exports = {
|
||||
|
||||
// Set init tasks
|
||||
|
||||
console.info(migrationSource)
|
||||
|
||||
let initTasks = {
|
||||
// -> Migrate DB Schemas
|
||||
async syncSchemas() {
|
||||
return self.knex.migrate.latest({
|
||||
directory: path.join(WIKI.SERVERPATH, 'db/migrations'),
|
||||
tableName: 'migrations'
|
||||
tableName: 'migrations',
|
||||
migrationSource
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
const _ = require('lodash')
|
||||
const cfgHelper = require('../helpers/config')
|
||||
const Promise = require('bluebird')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
/* global WIKI */
|
||||
|
||||
@ -22,6 +24,9 @@ module.exports = {
|
||||
}
|
||||
})
|
||||
|
||||
// Clear content cache
|
||||
fs.emptyDir(path.join(WIKI.ROOTPATH, 'data/cache'))
|
||||
|
||||
return this
|
||||
},
|
||||
/**
|
||||
|
15
server/db/migrations/2.0.0-beta.11.js
Normal file
15
server/db/migrations/2.0.0-beta.11.js
Normal file
@ -0,0 +1,15 @@
|
||||
exports.up = knex => {
|
||||
return knex.schema
|
||||
.table('pageHistory', table => {
|
||||
table.string('action').defaultTo('updated')
|
||||
table.dropForeign('pageId')
|
||||
})
|
||||
}
|
||||
|
||||
exports.down = knex => {
|
||||
return knex.schema
|
||||
.table('pageHistory', table => {
|
||||
table.dropColumn('action')
|
||||
table.integer('pageId').unsigned().references('id').inTable('pages')
|
||||
})
|
||||
}
|
28
server/db/migrator-source.js
Normal file
28
server/db/migrator-source.js
Normal file
@ -0,0 +1,28 @@
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const semver = require('semver')
|
||||
|
||||
/* global WIKI */
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Gets the migration names
|
||||
* @returns Promise<string[]>
|
||||
*/
|
||||
async getMigrations() {
|
||||
const absoluteDir = path.join(WIKI.SERVERPATH, 'db/migrations')
|
||||
const migrationFiles = await fs.readdirAsync(absoluteDir)
|
||||
return migrationFiles.sort(semver.compare).map(m => ({
|
||||
file: m,
|
||||
directory: absoluteDir
|
||||
}))
|
||||
},
|
||||
|
||||
getMigrationName(migration) {
|
||||
return migration.file;
|
||||
},
|
||||
|
||||
getMigration(migration) {
|
||||
return require(path.join(WIKI.SERVERPATH, 'db/migrations', migration.file));
|
||||
}
|
||||
}
|
@ -29,8 +29,11 @@ module.exports = {
|
||||
page
|
||||
}
|
||||
},
|
||||
async delete(obj, args) {
|
||||
await WIKI.models.groups.query().deleteById(args.id)
|
||||
async delete(obj, args, context) {
|
||||
await WIKI.models.pages.deletePage({
|
||||
...args,
|
||||
authorId: context.req.user.id
|
||||
})
|
||||
return {
|
||||
responseResult: graphHelper.generateSuccess('Page has been deleted.')
|
||||
}
|
||||
|
@ -99,7 +99,8 @@ module.exports = class PageHistory extends Model {
|
||||
path: opts.path,
|
||||
publishEndDate: opts.publishEndDate || '',
|
||||
publishStartDate: opts.publishStartDate || '',
|
||||
title: opts.title
|
||||
title: opts.title,
|
||||
action: opts.action || 'updated'
|
||||
})
|
||||
}
|
||||
|
||||
@ -109,6 +110,7 @@ module.exports = class PageHistory extends Model {
|
||||
'pageHistory.id',
|
||||
'pageHistory.path',
|
||||
'pageHistory.authorId',
|
||||
'pageHistory.action',
|
||||
'pageHistory.createdAt',
|
||||
{
|
||||
authorName: 'author.name'
|
||||
@ -130,6 +132,7 @@ module.exports = class PageHistory extends Model {
|
||||
'pageHistory.id',
|
||||
'pageHistory.path',
|
||||
'pageHistory.authorId',
|
||||
'pageHistory.action',
|
||||
'pageHistory.createdAt',
|
||||
{
|
||||
authorName: 'author.name'
|
||||
|
@ -96,6 +96,7 @@ module.exports = class Page extends Model {
|
||||
|
||||
static get cacheSchema() {
|
||||
return new JSBinType({
|
||||
id: 'uint',
|
||||
authorId: 'uint',
|
||||
authorName: 'string',
|
||||
createdAt: 'string',
|
||||
@ -150,7 +151,10 @@ module.exports = class Page extends Model {
|
||||
if (!ogPage) {
|
||||
throw new Error('Invalid Page Id')
|
||||
}
|
||||
await WIKI.models.pageHistory.addVersion(ogPage)
|
||||
await WIKI.models.pageHistory.addVersion({
|
||||
...ogPage,
|
||||
action: 'updated'
|
||||
})
|
||||
await WIKI.models.pages.query().patch({
|
||||
authorId: opts.authorId,
|
||||
content: opts.content,
|
||||
@ -174,6 +178,23 @@ module.exports = class Page extends Model {
|
||||
return page
|
||||
}
|
||||
|
||||
static async deletePage(opts) {
|
||||
const page = await WIKI.models.pages.query().findById(opts.id)
|
||||
if (!page) {
|
||||
throw new Error('Invalid Page Id')
|
||||
}
|
||||
await WIKI.models.pageHistory.addVersion({
|
||||
...page,
|
||||
action: 'deleted'
|
||||
})
|
||||
await WIKI.models.pages.query().delete().where('id', page.id)
|
||||
await WIKI.models.pages.deletePageFromCache(page)
|
||||
await WIKI.models.storage.pageEvent({
|
||||
event: 'deleted',
|
||||
page
|
||||
})
|
||||
}
|
||||
|
||||
static async renderPage(page) {
|
||||
const pipeline = await WIKI.models.renderers.getRenderingPipeline(page.contentType)
|
||||
WIKI.queue.job.renderPage.add({
|
||||
@ -232,6 +253,7 @@ module.exports = class Page extends Model {
|
||||
static async savePageToCache(page) {
|
||||
const cachePath = path.join(process.cwd(), `data/cache/${page.hash}.bin`)
|
||||
await fs.outputFile(cachePath, WIKI.models.pages.cacheSchema.encode({
|
||||
id: page.id,
|
||||
authorId: page.authorId,
|
||||
authorName: page.authorName,
|
||||
createdAt: page.createdAt,
|
||||
@ -270,4 +292,8 @@ module.exports = class Page extends Model {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
static async deletePageFromCache(page) {
|
||||
return fs.remove(path.join(process.cwd(), `data/cache/${page.hash}.bin`))
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ block body
|
||||
:author-id=page.authorId
|
||||
:is-published=page.isPublished.toString()
|
||||
:toc=page.toc
|
||||
:page-id=page.id
|
||||
)
|
||||
template(slot='sidebar')
|
||||
each navItem in sidebar
|
||||
|
Loading…
Reference in New Issue
Block a user