Browse Source

feat: save conflict check polling

pull/1561/head
NGPixel 4 years ago
parent
commit
4398573645
5 changed files with 60 additions and 1 deletions
  1. 34
      client/components/editor.vue
  2. 3
      server/controllers/common.js
  3. 18
      server/graph/resolvers/page.js
  4. 5
      server/graph/schemas/page.graphql
  5. 1
      server/views/editor.pug

34
client/components/editor.vue

@ -13,6 +13,9 @@
full-width
)
template(slot='actions')
v-btn.mr-3.animated.fadeIn(color='amber', outlined, small, v-if='isConflict')
.overline.amber--text.mr-3 Conflict
status-indicator(intermediary, pulse)
v-btn.animated.fadeInDown(
text
color='green'
@ -55,9 +58,11 @@
<script>
import _ from 'lodash'
import gql from 'graphql-tag'
import { get, sync } from 'vuex-pathify'
import { AtomSpinner } from 'epic-spinners'
import { Base64 } from 'js-base64'
import { StatusIndicator } from 'vue-status-indicator'
import createPageMutation from 'gql/editor/create.gql'
import updatePageMutation from 'gql/editor/update.gql'
@ -72,6 +77,7 @@ export default {
i18nOptions: { namespaces: 'editor' },
components: {
AtomSpinner,
StatusIndicator,
editorApi: () => import(/* webpackChunkName: "editor-api", webpackMode: "lazy" */ './editor/editor-api.vue'),
editorCode: () => import(/* webpackChunkName: "editor-code", webpackMode: "lazy" */ './editor/editor-code.vue'),
editorCkeditor: () => import(/* webpackChunkName: "editor-ckeditor", webpackMode: "lazy" */ './editor/editor-ckeditor.vue'),
@ -122,10 +128,15 @@ export default {
pageId: {
type: Number,
default: 0
},
checkoutDate: {
type: String,
default: new Date().toISOString()
}
},
data() {
return {
isConflict: false,
dialogProps: false,
dialogProgress: false,
dialogEditorSelector: false,
@ -322,6 +333,29 @@ export default {
}
}, 500)
}
},
apollo: {
isConflict: {
query: gql`
query ($id: Int!, $checkoutDate: Date!) {
pages {
checkConflicts(id: $id, checkoutDate: $checkoutDate)
}
}
`,
fetchPolicy: 'network-only',
pollInterval: 5000,
variables () {
return {
id: this.pageId,
checkoutDate: this.checkoutDate
}
},
update: (data) => _.cloneDeep(data.pages.checkConflicts),
skip () {
return this.mode === 'create' || !this.isDirty
}
}
}
}
</script>

3
server/controllers/common.js

@ -147,7 +147,8 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
mode: 'create',
content: null,
title: null,
description: null
description: null,
updatedAt: new Date().toISOString()
}
// -> From Template

18
server/graph/resolvers/page.js

@ -252,6 +252,24 @@ module.exports = {
}
return result
}, [])
},
/**
* CHECK FOR EDITING CONFLICT
*/
async checkConflicts (obj, args, context, info) {
let page = await WIKI.models.pages.query().select('path', 'localeCode', 'updatedAt').findById(args.id)
if (page) {
if (WIKI.auth.checkAccess(context.req.user, ['write:pages', 'manage:pages'], {
path: page.path,
locale: page.localeCode
})) {
return page.updatedAt !== args.checkoutDate
} else {
throw new WIKI.Error.PageUpdateForbidden()
}
} else {
throw new WIKI.Error.PageNotFound()
}
}
},
PageMutation: {

5
server/graph/schemas/page.graphql

@ -61,6 +61,11 @@ type PageQuery {
links(
locale: String!
): [PageLinkItem] @auth(requires: ["manage:system", "read:pages"])
checkConflicts(
id: Int!
checkoutDate: Date!
): Boolean! @auth(requires: ["write:pages", "manage:pages", "manage:system"])
}
# -----------------------------------------------

1
server/views/editor.pug

@ -17,4 +17,5 @@ block body
init-mode=page.mode
init-editor=page.editorKey
init-content=page.content
checkout-date=page.updatedAt
)
Loading…
Cancel
Save