diff --git a/client/app.js b/client/app.js index 1f5914e2..9091a7ee 100644 --- a/client/app.js +++ b/client/app.js @@ -1,7 +1,5 @@ 'use strict' -import CONSTANTS from './constants' - import Vue from 'vue' import VueRouter from 'vue-router' import VueClipboards from 'vue-clipboards' @@ -35,7 +33,6 @@ import helpers from './helpers' window.WIKI = null window.boot = boot -window.CONSTANTS = CONSTANTS window.Hammer = Hammer // ==================================== @@ -78,7 +75,6 @@ Vue.component('admin', () => import(/* webpackChunkName: "admin" */ './component Vue.component('editor', () => import(/* webpackChunkName: "editor" */ './components/editor.vue')) Vue.component('login', () => import(/* webpackMode: "eager" */ './components/login.vue')) Vue.component('nav-header', () => import(/* webpackMode: "eager" */ './components/nav-header.vue')) -Vue.component('navigator', () => import(/* webpackMode: "eager" */ './components/navigator.vue')) Vue.component('setup', () => import(/* webpackChunkName: "setup" */ './components/setup.vue')) let bootstrap = () => { diff --git a/client/components/admin-auth.vue b/client/components/admin-auth.vue index cd1a2ef2..2e02e106 100644 --- a/client/components/admin-auth.vue +++ b/client/components/admin-auth.vue @@ -66,8 +66,7 @@ <script> import _ from 'lodash' - -/* global CONSTANTS */ +import gql from 'graphql-tag' export default { data() { @@ -84,7 +83,23 @@ export default { }, apollo: { providers: { - query: CONSTANTS.GRAPH.AUTHENTICATION.QUERY_PROVIDERS, + query: gql` + query { + authentication { + providers { + isEnabled + key + props + title + useForm + config { + key + value + } + } + } + } + `, update: (data) => data.authentication.providers } }, diff --git a/client/components/admin-dev.vue b/client/components/admin-dev.vue index 43458664..1bd73675 100644 --- a/client/components/admin-dev.vue +++ b/client/components/admin-dev.vue @@ -114,5 +114,12 @@ export default { #voyager { height: calc(100vh - 250px); + + .title-area { + display: none; + } + .type-doc { + margin-top: 5px; + } } </style> diff --git a/client/components/admin-groups.vue b/client/components/admin-groups.vue index dbab6f95..c03bf0da 100644 --- a/client/components/admin-groups.vue +++ b/client/components/admin-groups.vue @@ -5,54 +5,41 @@ .subheading.grey--text Manage groups v-card v-card-title - v-btn(color='primary', dark) - v-icon(left) add - | New Group + v-dialog(v-model='newGroupDialog', max-width='500') + v-btn(color='primary', dark, slot='activator') + v-icon(left) add + | New Group + v-card + v-card-title.headline.grey--text.text--darken-2 New Group + v-card-text + v-text-field(v-model='newGroupName', label='Group Name', autofocus, counter='255') + v-card-actions + v-spacer + v-btn(flat, @click='newGroupDialog = false') Cancel + v-btn(color='primary', @click='createGroup') Create v-btn(icon) v-icon.grey--text refresh v-spacer v-text-field(append-icon='search', label='Search', single-line, hide-details, v-model='search') v-data-table( v-model='selected' - :items='items', + :items='groups', :headers='headers', :search='search', :pagination.sync='pagination', :rows-per-page-items='[15]' - select-all, hide-actions, disable-initial-sort ) - template(slot='headers', slot-scope='props') - tr - th(width='50') - th.text-xs-right( - width='80' - :class='[`column sortable`, pagination.descending ? `desc` : `asc`, pagination.sortBy === `id` ? `active` : ``]' - @click='changeSort(`id`)' - ) - v-icon(small) arrow_upward - | ID - th.text-xs-left( - v-for='header in props.headers' - :key='header.text' - :width='header.width' - :class='[`column sortable`, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]' - @click='changeSort(header.value)' - ) - | {{ header.text }} - v-icon(small) arrow_upward template(slot='items', slot-scope='props') tr(:active='props.selected') - td - v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected') td.text-xs-right {{ props.item.id }} td {{ props.item.name }} td {{ props.item.userCount }} td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz template(slot='no-data') - v-alert(icon='warning', :value='true') No users to display! - .text-xs-center.py-2(v-if='items.length > 15') + v-alert.ma-3(icon='warning', :value='true', outline) No groups to display. + .text-xs-center.py-2(v-if='groups.length > 15') v-pagination(v-model='pagination.page', :length='pages') </template> @@ -60,13 +47,13 @@ export default { data() { return { + newGroupDialog: false, + newGroupName: '', selected: [], pagination: {}, - items: [ - { id: 1, name: 'Administrators', userCount: 1 }, - { id: 2, name: 'Users', userCount: 23 } - ], + groups: [], headers: [ + { text: 'ID', value: 'id', width: 50, align: 'right' }, { text: 'Name', value: 'name' }, { text: 'Users', value: 'userCount', width: 200 }, { text: '', value: 'actions', sortable: false, width: 50 } @@ -84,20 +71,18 @@ export default { } }, methods: { - changeSort (column) { - if (this.pagination.sortBy === column) { - this.pagination.descending = !this.pagination.descending - } else { - this.pagination.sortBy = column - this.pagination.descending = false - } - }, - toggleAll () { - if (this.selected.length) { - this.selected = [] - } else { - this.selected = this.items.slice() - } + async createGroup() { + // try { + // const resp = await this.$apollo.mutate({ + // mutation: CONSTANTS.GRAPH.GROUPS.CREATE, + // variables: { + // name: this.newGroupName + // } + // }) + + // } catch (err) { + + // } } } } diff --git a/client/components/admin-system.vue b/client/components/admin-system.vue index 5b2009fe..85b91389 100644 --- a/client/components/admin-system.vue +++ b/client/components/admin-system.vue @@ -23,7 +23,7 @@ v-list-tile-title Latest Version v-list-tile-sub-title {{ info.latestVersion }} v-list-tile-action - v-list-tile-action-text Published 4 days ago + v-list-tile-action-text Published X days ago v-divider @@ -105,12 +105,12 @@ </template> <script> +import gql from 'graphql-tag' + import IconCube from 'mdi/cube' import IconDatabase from 'mdi/database' import IconNodeJs from 'mdi/nodejs' -/* global CONSTANTS */ - export default { components: { IconCube, @@ -125,7 +125,29 @@ export default { }, apollo: { info: { - query: CONSTANTS.GRAPH.SYSTEM.QUERY_INFO, + query: gql` + query { + system { + info { + currentVersion + latestVersion + latestVersionReleaseDate + operatingSystem + hostname + cpuCores + ramTotal + workingDirectory + nodeVersion + redisVersion + redisUsedRAM + redisTotalRAM + redisHost + postgreVersion + postgreHost + } + } + } + `, update: (data) => data.system.info } }, diff --git a/client/components/editor-code.vue b/client/components/editor-code.vue index df3b2f7b..abe986ef 100644 --- a/client/components/editor-code.vue +++ b/client/components/editor-code.vue @@ -1,8 +1,5 @@ <template lang='pug'> .editor-code - v-toolbar(color='blue', flat, dense, dark) - v-icon(color='blue lighten-5') edit - v-toolbar-title.white--text Sample Page .editor-code-toolbar .editor-code-toolbar-group .editor-code-toolbar-item(@click='toggleAround("**", "**")') @@ -70,7 +67,7 @@ .editor-code-preview-title(@click='previewShown = false') Preview .editor-code-preview-content.markdown-content(ref='editorPreview', v-html='previewHTML') - v-speed-dial(v-model='fabInsertMenu', :open-on-hover='true', direction='top', transition='slide-y-reverse-transition', :fixed='true', :right='!isMobile', :left='isMobile', :bottom='true') + v-speed-dial(v-model='fabInsertMenu', :open-on-hover='true', direction='top', transition='slide-y-reverse-transition', fixed, right, bottom) v-btn(color='blue', fab, dark, v-model='fabInsertMenu', slot='activator') v-icon add_circle v-icon close @@ -79,16 +76,6 @@ v-btn(color='red', fab, dark): v-icon play_circle_outline v-btn(color='purple', fab, dark): v-icon multiline_chart v-btn(color='indigo', fab, dark): v-icon functions - v-speed-dial(v-model='fabMainMenu', :open-on-hover='true', :direction='saveMenuDirection', transition='slide-x-reverse-transition', :fixed='true', :right='true', :top='!isMobile', :bottom='isMobile') - v-btn(color='white', fab, light, v-model='fabMainMenu' slot='activator') - v-icon(color='blue darken-2') blur_on - v-icon(color='blue darken-2') close - v-btn(color='blue-grey', fab, dark, @click.native.stop='$parent.openModal(`properties`)'): v-icon sort_by_alpha - v-btn(color='green', fab, dark, @click.native.stop='$parent.save()'): v-icon save - v-btn(color='red', fab, dark, small): v-icon not_interested - v-btn(color='orange', fab, dark, small, @click.native.stop='$parent.openModal(`access`)'): v-icon vpn_lock - v-btn(color='indigo', fab, dark, small): v-icon restore - v-btn(color='brown', fab, dark, small): v-icon archive </template> <script> @@ -184,7 +171,6 @@ export default { }, data() { return { - fabMainMenu: false, fabInsertMenu: false, code: '# Header 1\n\nSample **Text**\nhttp://wiki.js.org\n:rocket: :) :( :| :P\n\n## Header 2\nSample Text\n\n```javascript\nvar test = require("test");\n\n// some comment\nconst foo = bar(\'param\') + 1.234;\n```\n\n### Header 3\nLorem *ipsum* ~~text~~', cmOptions: { @@ -210,9 +196,6 @@ export default { }, isMobile() { return this.$vuetify.breakpoint.smAndDown - }, - saveMenuDirection() { - return this.isMobile ? 'top' : 'bottom' } }, methods: { diff --git a/client/components/editor-modal-access.vue b/client/components/editor-modal-access.vue index ffe85536..5ca5a7e0 100644 --- a/client/components/editor-modal-access.vue +++ b/client/components/editor-modal-access.vue @@ -49,7 +49,7 @@ export default { methods: { close() { this.isShown = false - this.$parent.closeModal() + this.$parent.$parent.closeModal() } } } diff --git a/client/components/editor-modal-properties.vue b/client/components/editor-modal-properties.vue index 23a683f2..27e228b2 100644 --- a/client/components/editor-modal-properties.vue +++ b/client/components/editor-modal-properties.vue @@ -31,7 +31,7 @@ export default { methods: { close() { this.isShown = false - this.$parent.closeModal() + this.$parent.$parent.closeModal() } } } diff --git a/client/components/editor.vue b/client/components/editor.vue index 8d36a62b..2b6739a3 100644 --- a/client/components/editor.vue +++ b/client/components/editor.vue @@ -1,13 +1,22 @@ <template lang="pug"> .editor - editor-code - component(:is='currentModal') - v-dialog(v-model='dialogProgress', persistent, max-width='300') - v-card - v-progress-linear.my-0(indeterminate, color='primary', height='5') - v-card-text.text-xs-center - .headline Saving - .caption Please wait... + nav-header + template(slot='actions') + v-btn(outline, color='green', @click.native.stop='save') + v-icon(color='green', left) save + span.white--text Save + v-btn(icon): v-icon(color='red') close + v-btn(icon, @click.native.stop='openModal(`properties`)'): v-icon(color='white') sort_by_alpha + v-btn(icon, @click.native.stop='openModal(`access`)'): v-icon(color='white') vpn_lock + v-content + editor-code + component(:is='currentModal') + v-dialog(v-model='dialogProgress', persistent, max-width='300') + v-card + v-progress-linear.my-0(indeterminate, color='primary', height='5') + v-card-text.text-xs-center + .headline Saving + .caption Please wait... </template> <script> diff --git a/client/components/login.vue b/client/components/login.vue index 50bf3d37..48c2ad6c 100644 --- a/client/components/login.vue +++ b/client/components/login.vue @@ -1,5 +1,6 @@ <template lang="pug"> v-app + nav-header .login(:class='{ "is-error": error }') .login-container(:class='{ "is-expanded": strategies.length > 1, "is-loading": isLoading }') .login-providers(v-show='strategies.length > 1') @@ -37,9 +38,10 @@ </template> <script> -/* global CONSTANTS, graphQL, siteConfig */ +/* global graphQL, siteConfig */ import _ from 'lodash' +import gql from 'graphql-tag' export default { data () { @@ -80,7 +82,21 @@ export default { refreshStrategies () { this.isLoading = true graphQL.query({ - query: CONSTANTS.GRAPH.AUTHENTICATION.QUERY_LOGIN_PROVIDERS + query: gql` + query { + authentication { + providers( + filter: "isEnabled eq true", + orderBy: "title ASC" + ) { + key + title + useForm + icon + } + } + } + ` }).then(resp => { if (_.has(resp, 'data.authentication.providers')) { this.strategies = _.get(resp, 'data.authentication.providers', []) @@ -116,7 +132,22 @@ export default { } else { this.isLoading = true graphQL.mutate({ - mutation: CONSTANTS.GRAPH.AUTHENTICATION.MUTATION_LOGIN, + mutation: gql` + mutation($username: String!, $password: String!, $provider: String!) { + authentication { + login(username: $username, password: $password, provider: $provider) { + operation { + succeeded + code + slug + message + } + tfaRequired + tfaLoginToken + } + } + } + `, variables: { username: this.username, password: this.password, @@ -169,7 +200,20 @@ export default { } else { this.isLoading = true graphQL.mutate({ - mutation: CONSTANTS.GRAPH.AUTHENTICATION.MUTATION_LOGINTFA, + mutation: gql` + mutation($loginToken: String!, $securityCode: String!) { + authentication { + loginTFA(loginToken: $loginToken, securityCode: $securityCode) { + operation { + succeeded + code + slug + message + } + } + } + } + `, variables: { loginToken: this.loginToken, securityCode: this.securityCode diff --git a/client/components/nav-header.vue b/client/components/nav-header.vue index b00945ea..7268d84f 100644 --- a/client/components/nav-header.vue +++ b/client/components/nav-header.vue @@ -1,7 +1,40 @@ <template lang='pug'> - v-toolbar(color='black', dark, app, clipped-left, fixed, flat) - v-toolbar-side-icon(@click.native='') - v-icon view_module + v-toolbar(color='black', dark, app, clipped-left, fixed, flat, dense) + v-menu(open-on-hover, offset-y, bottom, left, nudge-top='-18', min-width='250') + v-toolbar-side-icon(slot='activator') + v-icon view_module + v-list(dense) + v-list-tile(avatar, href='/') + v-list-tile-avatar: v-icon(color='blue') home + v-list-tile-content Home + v-list-tile(avatar, @click='') + v-list-tile-avatar: v-icon(color='green') add_box + v-list-tile-content New Page + v-divider.my-0 + v-subheader Current Page + v-list-tile(avatar, @click='') + v-list-tile-avatar: v-icon(color='indigo') edit + v-list-tile-content Edit + v-list-tile(avatar, @click='') + v-list-tile-avatar: v-icon(color='indigo') history + v-list-tile-content History + v-list-tile(avatar, @click='') + v-list-tile-avatar: v-icon(color='indigo') code + v-list-tile-content View Source + v-list-tile(avatar, @click='') + v-list-tile-avatar: v-icon(color='indigo') forward + v-list-tile-content Move / Rename + v-list-tile(avatar, @click='') + v-list-tile-avatar: v-icon(color='red darken-2') delete + v-list-tile-content Delete + v-divider.my-0 + v-subheader Assets + v-list-tile(avatar, @click='') + v-list-tile-avatar: v-icon(color='blue-grey') burst_mode + v-list-tile-content Images + v-list-tile(avatar, @click='') + v-list-tile-avatar: v-icon(color='blue-grey') description + v-list-tile-content Files v-toolbar-title span.subheading Wiki.js v-spacer @@ -29,6 +62,7 @@ ) v-spacer v-progress-circular.mr-3(indeterminate, color='blue', v-show='$apollo.loading') + slot(name='actions') transition(name='navHeaderSearch') v-btn(icon, @click='searchToggle', v-if='!searchIsShown') v-icon(color='grey') search @@ -57,6 +91,7 @@ export default { data() { return { + menuIsShown: true, searchIsLoading: false, searchIsShown: false, search: '' diff --git a/client/components/navigator.vue b/client/components/navigator.vue deleted file mode 100644 index 3820a201..00000000 --- a/client/components/navigator.vue +++ /dev/null @@ -1,155 +0,0 @@ -<template lang="pug"> - .navigator - .navigator-bar - .navigator-fab - .navigator-fab-button(@click='toggleMainMenu') - svg.icons.is-24(role='img') - title Navigation - use(xlink:href='#gg-apps-grid') - .navigator-title - h1 {{ siteTitle }} - .navigator-subtitle(:class='subtitleClass') - transition(name='navigator-subtitle-icon') - svg.icons.is-24.navigator-subtitle-icon(role='img', v-if='subtitleIcon') - title {{subtitleText}} - use(:xlink:href='subtitleIconClass') - h2 {{subtitleText}} - .navigator-action - .navigator-action-item(:class='{"is-active": userMenuShown}', @click='toggleUserMenu') - svg.icons.is-32(role='img') - title User - use(xlink:href='#nc-user-circle') - transition(name='navigator-action-item-dropdown') - ul.navigator-action-item-dropdown(v-show='userMenuShown', v-cloak) - li - label Account - svg.icons.is-24(role='img') - title Account - use(xlink:href='#nc-man-green') - li(@click='logout') - label Sign out - svg.icons.is-24(role='img') - title Sign Out - use(xlink:href='#nc-exit') - transition(name='navigator-sd') - .navigator-sd(v-show='sdShown', v-cloak) - .navigator-sd-actions - a.is-active(href='', title='Search') - svg.icons.is-24(role='img') - title Search - use(xlink:href='#gg-search') - a(href='', title='New Document') - svg.icons.is-24(role='img') - title New Document - use(xlink:href='#nc-plus-circle') - a(href='', title='Edit Document') - svg.icons.is-24(role='img') - title Edit Document - use(xlink:href='#nc-pen-red') - a(href='', title='History') - svg.icons.is-24(role='img') - title History - use(xlink:href='#nc-restore') - a(href='', title='View Source') - svg.icons.is-24(role='img') - title View Source - use(xlink:href='#nc-code-editor') - a(href='', title='Move Document') - svg.icons.is-24(role='img') - title Move Document - use(xlink:href='#nc-move') - a(href='', title='Delete Document') - svg.icons.is-24(role='img') - title Delete Document - use(xlink:href='#nc-trash') - .navigator-sd-search - input(type='text', ref='iptSearch', placeholder='Search') - .navigator-sd-results - .navigator-sd-footer - a(href='', title='Settings') - svg.icons.is-24(role='img') - title Settings - use(xlink:href='#nc-gear') - a(href='', title='Users') - svg.icons.is-24(role='img') - title Users - use(xlink:href='#nc-users') - a(href='', title='Assets') - svg.icons.is-24(role='img') - title Assets - use(xlink:href='#nc-image') -</template> - -<script> -/* global siteConfig */ - -import { mapState } from 'vuex' - -export default { - data() { - return { - sdShown: false, - userMenuShown: false - } - }, - computed: { - ...mapState('navigator', [ - 'subtitleShown', - 'subtitleStyle', - 'subtitleText', - 'subtitleIcon' - ]), - siteTitle() { - return siteConfig.title - }, - subtitleClass() { - return { - 'is-active': this.subtitleShown, - 'is-error': this.subtitleStyle === 'error', - 'is-warning': this.subtitleStyle === 'warning', - 'is-success': this.subtitleStyle === 'success', - 'is-info': this.subtitleStyle === 'info' - } - }, - subtitleIconClass() { return '#' + this.subtitleIcon } - }, - methods: { - toggleMainMenu() { - this.sdShown = !this.sdShown - this.userMenuShown = false - if (this.sdShown) { - this.$nextTick(() => { - this.bindOutsideClick() - this.$refs.iptSearch.focus() - }) - } else { - this.unbindOutsideClick() - } - }, - toggleUserMenu() { - this.userMenuShown = !this.userMenuShown - this.sdShown = false - if (this.userMenuShown) { - this.bindOutsideClick() - } else { - this.unbindOutsideClick() - } - }, - bindOutsideClick() { - document.addEventListener('mousedown', this.handleOutsideClick, false) - }, - unbindOutsideClick() { - document.removeEventListener('mousedown', this.handleOutsideClick, false) - }, - handleOutsideClick(ev) { - if (!this.$el.contains(ev.target)) { - this.sdShown = false - this.userMenuShown = false - } - }, - logout() { - window.location.assign(this.$helpers.resolvePath('logout')) - } - } -} -</script> diff --git a/client/constants/graphql.js b/client/constants/graphql.js deleted file mode 100644 index 94cb8b0b..00000000 --- a/client/constants/graphql.js +++ /dev/null @@ -1,103 +0,0 @@ -import gql from 'graphql-tag' - -export default { - AUTHENTICATION: { - QUERY_PROVIDERS: gql` - query { - authentication { - providers { - isEnabled - key - props - title - useForm - config { - key - value - } - } - } - } - `, - QUERY_LOGIN_PROVIDERS: gql` - query { - authentication { - providers( - filter: "isEnabled eq true", - orderBy: "title ASC" - ) { - key - title - useForm - icon - } - } - } - `, - MUTATION_LOGIN: gql` - mutation($username: String!, $password: String!, $provider: String!) { - authentication { - login(username: $username, password: $password, provider: $provider) { - operation { - succeeded - code - slug - message - } - tfaRequired - tfaLoginToken - } - } - } - `, - MUTATION_LOGINTFA: gql` - mutation($loginToken: String!, $securityCode: String!) { - authentication { - loginTFA(loginToken: $loginToken, securityCode: $securityCode) { - operation { - succeeded - code - slug - message - } - } - } - } - ` - }, - SYSTEM: { - QUERY_INFO: gql` - query { - system { - info { - currentVersion - latestVersion - latestVersionReleaseDate - operatingSystem - hostname - cpuCores - ramTotal - workingDirectory - nodeVersion - redisVersion - redisUsedRAM - redisTotalRAM - redisHost - postgreVersion - postgreHost - } - } - } - ` - }, - TRANSLATIONS: { - QUERY_NAMESPACE: gql` - query($locale: String!, $namespace: String!) { - translations(locale:$locale, namespace:$namespace) { - key - value - } - } - ` - } -} diff --git a/client/constants/index.js b/client/constants/index.js deleted file mode 100644 index 267f49dd..00000000 --- a/client/constants/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import GRAPH from './graphql' - -export default { - GRAPH -} diff --git a/client/modules/localization.js b/client/modules/localization.js index 26e36c9c..47f32519 100644 --- a/client/modules/localization.js +++ b/client/modules/localization.js @@ -2,9 +2,10 @@ import i18next from 'i18next' import i18nextXHR from 'i18next-xhr-backend' import i18nextCache from 'i18next-localstorage-cache' import VueI18Next from '@panter/vue-i18next' -import loSet from 'lodash/set' +import _ from 'lodash' +import gql from 'graphql-tag' -/* global siteConfig, graphQL, CONSTANTS */ +/* global siteConfig, graphQL */ module.exports = { VueI18Next, @@ -19,7 +20,14 @@ module.exports = { ajax: (url, opts, cb, data) => { let langParams = url.split('/') graphQL.query({ - query: CONSTANTS.GRAPH.TRANSLATIONS.QUERY_NAMESPACE, + query: gql` + query($locale: String!, $namespace: String!) { + translations(locale:$locale, namespace:$namespace) { + key + value + } + } + `, variables: { locale: langParams[0], namespace: langParams[1] @@ -28,7 +36,7 @@ module.exports = { let ns = {} if (resp.data.translations.length > 0) { resp.data.translations.forEach(entry => { - loSet(ns, entry.key, entry.value) + _.set(ns, entry.key, entry.value) }) } return cb(ns, {status: '200'}) diff --git a/client/scss/pages/_welcome.scss b/client/scss/pages/_welcome.scss index e8c72cf2..fe72345b 100644 --- a/client/scss/pages/_welcome.scss +++ b/client/scss/pages/_welcome.scss @@ -44,6 +44,7 @@ } } h1 { + font-size: 1.5rem; margin-bottom: 1rem; z-index: 2; } diff --git a/server/graph/resolvers/folder.js b/server/graph/resolvers/folder.js index f1e341dd..5a28f603 100644 --- a/server/graph/resolvers/folder.js +++ b/server/graph/resolvers/folder.js @@ -11,7 +11,7 @@ module.exports = { createFolder(obj, args) { return WIKI.db.Folder.create(args) }, - deleteGroup(obj, args) { + deleteFolder(obj, args) { return WIKI.db.Folder.destroy({ where: { id: args.id diff --git a/server/graph/resolvers/group.js b/server/graph/resolvers/group.js index ee4852de..f27d1b96 100644 --- a/server/graph/resolvers/group.js +++ b/server/graph/resolvers/group.js @@ -5,12 +5,18 @@ const gql = require('graphql') module.exports = { Query: { - groups(obj, args, context, info) { + async groups() { return {} } + }, + Mutation: { + async groups() { return {} } + }, + GroupQuery: { + list(obj, args, context, info) { return WIKI.db.Group.findAll({ where: args }) } }, - Mutation: { - assignUserToGroup(obj, args) { + GroupMutation: { + assignUser(obj, args) { return WIKI.db.Group.findById(args.groupId).then(grp => { if (!grp) { throw new gql.GraphQLError('Invalid Group ID') @@ -23,10 +29,10 @@ module.exports = { }) }) }, - createGroup(obj, args) { + create(obj, args) { return WIKI.db.Group.create(args) }, - deleteGroup(obj, args) { + delete(obj, args) { return WIKI.db.Group.destroy({ where: { id: args.id @@ -34,7 +40,7 @@ module.exports = { limit: 1 }) }, - removeUserFromGroup(obj, args) { + unassignUser(obj, args) { return WIKI.db.Group.findById(args.groupId).then(grp => { if (!grp) { throw new gql.GraphQLError('Invalid Group ID') @@ -47,7 +53,7 @@ module.exports = { }) }) }, - renameGroup(obj, args) { + update(obj, args) { return WIKI.db.Group.update({ name: args.name }, { diff --git a/server/graph/schemas/common.graphql b/server/graph/schemas/common.graphql index ce687589..bd79e557 100644 --- a/server/graph/schemas/common.graphql +++ b/server/graph/schemas/common.graphql @@ -95,15 +95,6 @@ type Folder implements Base { files: [File] } -type Group implements Base { - id: Int! - createdAt: Date - updatedAt: Date - name: String! - users: [User] - rights: [Right] -} - type Right implements Base { id: Int! createdAt: Date @@ -168,7 +159,6 @@ type Query { documents(id: Int, path: String): [Document] files(id: Int): [File] folders(id: Int, name: String): [Folder] - groups(id: Int, name: String): [Group] rights(id: Int): [Right] search(q: String, tags: [String]): [SearchResult] settings(key: String): [Setting] @@ -192,11 +182,6 @@ type Mutation { documentId: Int! ): OperationResult - assignUserToGroup( - userId: Int! - groupId: Int! - ): OperationResult - createComment( userId: Int! documentId: Int! @@ -213,10 +198,6 @@ type Mutation { name: String! ): Folder - createGroup( - name: String! - ): Group - createTag( name: String! ): Tag @@ -246,10 +227,6 @@ type Mutation { id: Int! ): OperationResult - deleteGroup( - id: Int! - ): OperationResult - deleteTag( id: Int! ): OperationResult @@ -306,11 +283,6 @@ type Mutation { name: String! ): OperationResult - renameGroup( - id: Int! - name: String! - ): OperationResult - renameTag( id: Int! key: String! @@ -325,11 +297,6 @@ type Mutation { rightId: Int! ): OperationResult - removeUserFromGroup( - userId: Int! - groupId: Int! - ): OperationResult - resetUserPassword( id: Int! ): OperationResult diff --git a/server/graph/schemas/group.graphql b/server/graph/schemas/group.graphql new file mode 100644 index 00000000..082f0bd5 --- /dev/null +++ b/server/graph/schemas/group.graphql @@ -0,0 +1,69 @@ +# =============================================== +# GROUPS +# =============================================== + +extend type Query { + groups: GroupQuery +} + +extend type Mutation { + groups: GroupMutation +} + +# ----------------------------------------------- +# QUERIES +# ----------------------------------------------- + +type GroupQuery { + list( + filter: String + orderBy: String + ): [Group] +} + +# ----------------------------------------------- +# MUTATIONS +# ----------------------------------------------- + +type GroupMutation { + create( + name: String! + ): GroupResponse + + update( + id: Int! + name: String! + ): GroupResponse + + delete( + id: Int! + ): DefaultResponse + + assignUser( + groupId: Int! + userId: Int! + ): DefaultResponse + + unassignUser( + groupId: Int! + userId: Int! + ): DefaultResponse +} + +# ----------------------------------------------- +# TYPES +# ----------------------------------------------- + +type GroupResponse { + operation: ResponseStatus! + group: Group +} + +type Group { + id: Int! + name: String! + rights: [String] + users: [User] + createdAt: Date! + updatedAt: Date! +}