feat: navigation, editor improvements + graphql refactor
This commit is contained in:
parent
8462e18fc5
commit
3f0adc5daf
@ -1,7 +1,5 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import CONSTANTS from './constants'
|
|
||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import VueRouter from 'vue-router'
|
import VueRouter from 'vue-router'
|
||||||
import VueClipboards from 'vue-clipboards'
|
import VueClipboards from 'vue-clipboards'
|
||||||
@ -35,7 +33,6 @@ import helpers from './helpers'
|
|||||||
|
|
||||||
window.WIKI = null
|
window.WIKI = null
|
||||||
window.boot = boot
|
window.boot = boot
|
||||||
window.CONSTANTS = CONSTANTS
|
|
||||||
window.Hammer = Hammer
|
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('editor', () => import(/* webpackChunkName: "editor" */ './components/editor.vue'))
|
||||||
Vue.component('login', () => import(/* webpackMode: "eager" */ './components/login.vue'))
|
Vue.component('login', () => import(/* webpackMode: "eager" */ './components/login.vue'))
|
||||||
Vue.component('nav-header', () => import(/* webpackMode: "eager" */ './components/nav-header.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'))
|
Vue.component('setup', () => import(/* webpackChunkName: "setup" */ './components/setup.vue'))
|
||||||
|
|
||||||
let bootstrap = () => {
|
let bootstrap = () => {
|
||||||
|
@ -66,8 +66,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import gql from 'graphql-tag'
|
||||||
/* global CONSTANTS */
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@ -84,7 +83,23 @@ export default {
|
|||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
providers: {
|
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
|
update: (data) => data.authentication.providers
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -114,5 +114,12 @@ export default {
|
|||||||
|
|
||||||
#voyager {
|
#voyager {
|
||||||
height: calc(100vh - 250px);
|
height: calc(100vh - 250px);
|
||||||
|
|
||||||
|
.title-area {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.type-doc {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -5,54 +5,41 @@
|
|||||||
.subheading.grey--text Manage groups
|
.subheading.grey--text Manage groups
|
||||||
v-card
|
v-card
|
||||||
v-card-title
|
v-card-title
|
||||||
v-btn(color='primary', dark)
|
v-dialog(v-model='newGroupDialog', max-width='500')
|
||||||
v-icon(left) add
|
v-btn(color='primary', dark, slot='activator')
|
||||||
| New Group
|
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-btn(icon)
|
||||||
v-icon.grey--text refresh
|
v-icon.grey--text refresh
|
||||||
v-spacer
|
v-spacer
|
||||||
v-text-field(append-icon='search', label='Search', single-line, hide-details, v-model='search')
|
v-text-field(append-icon='search', label='Search', single-line, hide-details, v-model='search')
|
||||||
v-data-table(
|
v-data-table(
|
||||||
v-model='selected'
|
v-model='selected'
|
||||||
:items='items',
|
:items='groups',
|
||||||
:headers='headers',
|
:headers='headers',
|
||||||
:search='search',
|
:search='search',
|
||||||
:pagination.sync='pagination',
|
:pagination.sync='pagination',
|
||||||
:rows-per-page-items='[15]'
|
:rows-per-page-items='[15]'
|
||||||
select-all,
|
|
||||||
hide-actions,
|
hide-actions,
|
||||||
disable-initial-sort
|
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')
|
template(slot='items', slot-scope='props')
|
||||||
tr(:active='props.selected')
|
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.text-xs-right {{ props.item.id }}
|
||||||
td {{ props.item.name }}
|
td {{ props.item.name }}
|
||||||
td {{ props.item.userCount }}
|
td {{ props.item.userCount }}
|
||||||
td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz
|
td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz
|
||||||
template(slot='no-data')
|
template(slot='no-data')
|
||||||
v-alert(icon='warning', :value='true') No users to display!
|
v-alert.ma-3(icon='warning', :value='true', outline) No groups to display.
|
||||||
.text-xs-center.py-2(v-if='items.length > 15')
|
.text-xs-center.py-2(v-if='groups.length > 15')
|
||||||
v-pagination(v-model='pagination.page', :length='pages')
|
v-pagination(v-model='pagination.page', :length='pages')
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -60,13 +47,13 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
newGroupDialog: false,
|
||||||
|
newGroupName: '',
|
||||||
selected: [],
|
selected: [],
|
||||||
pagination: {},
|
pagination: {},
|
||||||
items: [
|
groups: [],
|
||||||
{ id: 1, name: 'Administrators', userCount: 1 },
|
|
||||||
{ id: 2, name: 'Users', userCount: 23 }
|
|
||||||
],
|
|
||||||
headers: [
|
headers: [
|
||||||
|
{ text: 'ID', value: 'id', width: 50, align: 'right' },
|
||||||
{ text: 'Name', value: 'name' },
|
{ text: 'Name', value: 'name' },
|
||||||
{ text: 'Users', value: 'userCount', width: 200 },
|
{ text: 'Users', value: 'userCount', width: 200 },
|
||||||
{ text: '', value: 'actions', sortable: false, width: 50 }
|
{ text: '', value: 'actions', sortable: false, width: 50 }
|
||||||
@ -84,20 +71,18 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeSort (column) {
|
async createGroup() {
|
||||||
if (this.pagination.sortBy === column) {
|
// try {
|
||||||
this.pagination.descending = !this.pagination.descending
|
// const resp = await this.$apollo.mutate({
|
||||||
} else {
|
// mutation: CONSTANTS.GRAPH.GROUPS.CREATE,
|
||||||
this.pagination.sortBy = column
|
// variables: {
|
||||||
this.pagination.descending = false
|
// name: this.newGroupName
|
||||||
}
|
// }
|
||||||
},
|
// })
|
||||||
toggleAll () {
|
|
||||||
if (this.selected.length) {
|
// } catch (err) {
|
||||||
this.selected = []
|
|
||||||
} else {
|
// }
|
||||||
this.selected = this.items.slice()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
v-list-tile-title Latest Version
|
v-list-tile-title Latest Version
|
||||||
v-list-tile-sub-title {{ info.latestVersion }}
|
v-list-tile-sub-title {{ info.latestVersion }}
|
||||||
v-list-tile-action
|
v-list-tile-action
|
||||||
v-list-tile-action-text Published 4 days ago
|
v-list-tile-action-text Published X days ago
|
||||||
|
|
||||||
v-divider
|
v-divider
|
||||||
|
|
||||||
@ -105,12 +105,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
import IconCube from 'mdi/cube'
|
import IconCube from 'mdi/cube'
|
||||||
import IconDatabase from 'mdi/database'
|
import IconDatabase from 'mdi/database'
|
||||||
import IconNodeJs from 'mdi/nodejs'
|
import IconNodeJs from 'mdi/nodejs'
|
||||||
|
|
||||||
/* global CONSTANTS */
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
IconCube,
|
IconCube,
|
||||||
@ -125,7 +125,29 @@ export default {
|
|||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
info: {
|
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
|
update: (data) => data.system.info
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
<template lang='pug'>
|
<template lang='pug'>
|
||||||
.editor-code
|
.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
|
||||||
.editor-code-toolbar-group
|
.editor-code-toolbar-group
|
||||||
.editor-code-toolbar-item(@click='toggleAround("**", "**")')
|
.editor-code-toolbar-item(@click='toggleAround("**", "**")')
|
||||||
@ -70,7 +67,7 @@
|
|||||||
.editor-code-preview-title(@click='previewShown = false') Preview
|
.editor-code-preview-title(@click='previewShown = false') Preview
|
||||||
.editor-code-preview-content.markdown-content(ref='editorPreview', v-html='previewHTML')
|
.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-btn(color='blue', fab, dark, v-model='fabInsertMenu', slot='activator')
|
||||||
v-icon add_circle
|
v-icon add_circle
|
||||||
v-icon close
|
v-icon close
|
||||||
@ -79,16 +76,6 @@
|
|||||||
v-btn(color='red', fab, dark): v-icon play_circle_outline
|
v-btn(color='red', fab, dark): v-icon play_circle_outline
|
||||||
v-btn(color='purple', fab, dark): v-icon multiline_chart
|
v-btn(color='purple', fab, dark): v-icon multiline_chart
|
||||||
v-btn(color='indigo', fab, dark): v-icon functions
|
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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -184,7 +171,6 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fabMainMenu: false,
|
|
||||||
fabInsertMenu: 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~~',
|
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: {
|
cmOptions: {
|
||||||
@ -210,9 +196,6 @@ export default {
|
|||||||
},
|
},
|
||||||
isMobile() {
|
isMobile() {
|
||||||
return this.$vuetify.breakpoint.smAndDown
|
return this.$vuetify.breakpoint.smAndDown
|
||||||
},
|
|
||||||
saveMenuDirection() {
|
|
||||||
return this.isMobile ? 'top' : 'bottom'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -49,7 +49,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
close() {
|
close() {
|
||||||
this.isShown = false
|
this.isShown = false
|
||||||
this.$parent.closeModal()
|
this.$parent.$parent.closeModal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
close() {
|
close() {
|
||||||
this.isShown = false
|
this.isShown = false
|
||||||
this.$parent.closeModal()
|
this.$parent.$parent.closeModal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,22 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
.editor
|
.editor
|
||||||
editor-code
|
nav-header
|
||||||
component(:is='currentModal')
|
template(slot='actions')
|
||||||
v-dialog(v-model='dialogProgress', persistent, max-width='300')
|
v-btn(outline, color='green', @click.native.stop='save')
|
||||||
v-card
|
v-icon(color='green', left) save
|
||||||
v-progress-linear.my-0(indeterminate, color='primary', height='5')
|
span.white--text Save
|
||||||
v-card-text.text-xs-center
|
v-btn(icon): v-icon(color='red') close
|
||||||
.headline Saving
|
v-btn(icon, @click.native.stop='openModal(`properties`)'): v-icon(color='white') sort_by_alpha
|
||||||
.caption Please wait...
|
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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
v-app
|
v-app
|
||||||
|
nav-header
|
||||||
.login(:class='{ "is-error": error }')
|
.login(:class='{ "is-error": error }')
|
||||||
.login-container(:class='{ "is-expanded": strategies.length > 1, "is-loading": isLoading }')
|
.login-container(:class='{ "is-expanded": strategies.length > 1, "is-loading": isLoading }')
|
||||||
.login-providers(v-show='strategies.length > 1')
|
.login-providers(v-show='strategies.length > 1')
|
||||||
@ -37,9 +38,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/* global CONSTANTS, graphQL, siteConfig */
|
/* global graphQL, siteConfig */
|
||||||
|
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
@ -80,7 +82,21 @@ export default {
|
|||||||
refreshStrategies () {
|
refreshStrategies () {
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
graphQL.query({
|
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 => {
|
}).then(resp => {
|
||||||
if (_.has(resp, 'data.authentication.providers')) {
|
if (_.has(resp, 'data.authentication.providers')) {
|
||||||
this.strategies = _.get(resp, 'data.authentication.providers', [])
|
this.strategies = _.get(resp, 'data.authentication.providers', [])
|
||||||
@ -116,7 +132,22 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
graphQL.mutate({
|
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: {
|
variables: {
|
||||||
username: this.username,
|
username: this.username,
|
||||||
password: this.password,
|
password: this.password,
|
||||||
@ -169,7 +200,20 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
graphQL.mutate({
|
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: {
|
variables: {
|
||||||
loginToken: this.loginToken,
|
loginToken: this.loginToken,
|
||||||
securityCode: this.securityCode
|
securityCode: this.securityCode
|
||||||
|
@ -1,7 +1,40 @@
|
|||||||
<template lang='pug'>
|
<template lang='pug'>
|
||||||
v-toolbar(color='black', dark, app, clipped-left, fixed, flat)
|
v-toolbar(color='black', dark, app, clipped-left, fixed, flat, dense)
|
||||||
v-toolbar-side-icon(@click.native='')
|
v-menu(open-on-hover, offset-y, bottom, left, nudge-top='-18', min-width='250')
|
||||||
v-icon view_module
|
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
|
v-toolbar-title
|
||||||
span.subheading Wiki.js
|
span.subheading Wiki.js
|
||||||
v-spacer
|
v-spacer
|
||||||
@ -29,6 +62,7 @@
|
|||||||
)
|
)
|
||||||
v-spacer
|
v-spacer
|
||||||
v-progress-circular.mr-3(indeterminate, color='blue', v-show='$apollo.loading')
|
v-progress-circular.mr-3(indeterminate, color='blue', v-show='$apollo.loading')
|
||||||
|
slot(name='actions')
|
||||||
transition(name='navHeaderSearch')
|
transition(name='navHeaderSearch')
|
||||||
v-btn(icon, @click='searchToggle', v-if='!searchIsShown')
|
v-btn(icon, @click='searchToggle', v-if='!searchIsShown')
|
||||||
v-icon(color='grey') search
|
v-icon(color='grey') search
|
||||||
@ -57,6 +91,7 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
menuIsShown: true,
|
||||||
searchIsLoading: false,
|
searchIsLoading: false,
|
||||||
searchIsShown: false,
|
searchIsShown: false,
|
||||||
search: ''
|
search: ''
|
||||||
|
@ -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>
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
import GRAPH from './graphql'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
GRAPH
|
|
||||||
}
|
|
@ -2,9 +2,10 @@ import i18next from 'i18next'
|
|||||||
import i18nextXHR from 'i18next-xhr-backend'
|
import i18nextXHR from 'i18next-xhr-backend'
|
||||||
import i18nextCache from 'i18next-localstorage-cache'
|
import i18nextCache from 'i18next-localstorage-cache'
|
||||||
import VueI18Next from '@panter/vue-i18next'
|
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 = {
|
module.exports = {
|
||||||
VueI18Next,
|
VueI18Next,
|
||||||
@ -19,7 +20,14 @@ module.exports = {
|
|||||||
ajax: (url, opts, cb, data) => {
|
ajax: (url, opts, cb, data) => {
|
||||||
let langParams = url.split('/')
|
let langParams = url.split('/')
|
||||||
graphQL.query({
|
graphQL.query({
|
||||||
query: CONSTANTS.GRAPH.TRANSLATIONS.QUERY_NAMESPACE,
|
query: gql`
|
||||||
|
query($locale: String!, $namespace: String!) {
|
||||||
|
translations(locale:$locale, namespace:$namespace) {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
locale: langParams[0],
|
locale: langParams[0],
|
||||||
namespace: langParams[1]
|
namespace: langParams[1]
|
||||||
@ -28,7 +36,7 @@ module.exports = {
|
|||||||
let ns = {}
|
let ns = {}
|
||||||
if (resp.data.translations.length > 0) {
|
if (resp.data.translations.length > 0) {
|
||||||
resp.data.translations.forEach(entry => {
|
resp.data.translations.forEach(entry => {
|
||||||
loSet(ns, entry.key, entry.value)
|
_.set(ns, entry.key, entry.value)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return cb(ns, {status: '200'})
|
return cb(ns, {status: '200'})
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ module.exports = {
|
|||||||
createFolder(obj, args) {
|
createFolder(obj, args) {
|
||||||
return WIKI.db.Folder.create(args)
|
return WIKI.db.Folder.create(args)
|
||||||
},
|
},
|
||||||
deleteGroup(obj, args) {
|
deleteFolder(obj, args) {
|
||||||
return WIKI.db.Folder.destroy({
|
return WIKI.db.Folder.destroy({
|
||||||
where: {
|
where: {
|
||||||
id: args.id
|
id: args.id
|
||||||
|
@ -5,12 +5,18 @@ const gql = require('graphql')
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Query: {
|
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 })
|
return WIKI.db.Group.findAll({ where: args })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Mutation: {
|
GroupMutation: {
|
||||||
assignUserToGroup(obj, args) {
|
assignUser(obj, args) {
|
||||||
return WIKI.db.Group.findById(args.groupId).then(grp => {
|
return WIKI.db.Group.findById(args.groupId).then(grp => {
|
||||||
if (!grp) {
|
if (!grp) {
|
||||||
throw new gql.GraphQLError('Invalid Group ID')
|
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)
|
return WIKI.db.Group.create(args)
|
||||||
},
|
},
|
||||||
deleteGroup(obj, args) {
|
delete(obj, args) {
|
||||||
return WIKI.db.Group.destroy({
|
return WIKI.db.Group.destroy({
|
||||||
where: {
|
where: {
|
||||||
id: args.id
|
id: args.id
|
||||||
@ -34,7 +40,7 @@ module.exports = {
|
|||||||
limit: 1
|
limit: 1
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
removeUserFromGroup(obj, args) {
|
unassignUser(obj, args) {
|
||||||
return WIKI.db.Group.findById(args.groupId).then(grp => {
|
return WIKI.db.Group.findById(args.groupId).then(grp => {
|
||||||
if (!grp) {
|
if (!grp) {
|
||||||
throw new gql.GraphQLError('Invalid Group ID')
|
throw new gql.GraphQLError('Invalid Group ID')
|
||||||
@ -47,7 +53,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
renameGroup(obj, args) {
|
update(obj, args) {
|
||||||
return WIKI.db.Group.update({
|
return WIKI.db.Group.update({
|
||||||
name: args.name
|
name: args.name
|
||||||
}, {
|
}, {
|
||||||
|
@ -95,15 +95,6 @@ type Folder implements Base {
|
|||||||
files: [File]
|
files: [File]
|
||||||
}
|
}
|
||||||
|
|
||||||
type Group implements Base {
|
|
||||||
id: Int!
|
|
||||||
createdAt: Date
|
|
||||||
updatedAt: Date
|
|
||||||
name: String!
|
|
||||||
users: [User]
|
|
||||||
rights: [Right]
|
|
||||||
}
|
|
||||||
|
|
||||||
type Right implements Base {
|
type Right implements Base {
|
||||||
id: Int!
|
id: Int!
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
@ -168,7 +159,6 @@ type Query {
|
|||||||
documents(id: Int, path: String): [Document]
|
documents(id: Int, path: String): [Document]
|
||||||
files(id: Int): [File]
|
files(id: Int): [File]
|
||||||
folders(id: Int, name: String): [Folder]
|
folders(id: Int, name: String): [Folder]
|
||||||
groups(id: Int, name: String): [Group]
|
|
||||||
rights(id: Int): [Right]
|
rights(id: Int): [Right]
|
||||||
search(q: String, tags: [String]): [SearchResult]
|
search(q: String, tags: [String]): [SearchResult]
|
||||||
settings(key: String): [Setting]
|
settings(key: String): [Setting]
|
||||||
@ -192,11 +182,6 @@ type Mutation {
|
|||||||
documentId: Int!
|
documentId: Int!
|
||||||
): OperationResult
|
): OperationResult
|
||||||
|
|
||||||
assignUserToGroup(
|
|
||||||
userId: Int!
|
|
||||||
groupId: Int!
|
|
||||||
): OperationResult
|
|
||||||
|
|
||||||
createComment(
|
createComment(
|
||||||
userId: Int!
|
userId: Int!
|
||||||
documentId: Int!
|
documentId: Int!
|
||||||
@ -213,10 +198,6 @@ type Mutation {
|
|||||||
name: String!
|
name: String!
|
||||||
): Folder
|
): Folder
|
||||||
|
|
||||||
createGroup(
|
|
||||||
name: String!
|
|
||||||
): Group
|
|
||||||
|
|
||||||
createTag(
|
createTag(
|
||||||
name: String!
|
name: String!
|
||||||
): Tag
|
): Tag
|
||||||
@ -246,10 +227,6 @@ type Mutation {
|
|||||||
id: Int!
|
id: Int!
|
||||||
): OperationResult
|
): OperationResult
|
||||||
|
|
||||||
deleteGroup(
|
|
||||||
id: Int!
|
|
||||||
): OperationResult
|
|
||||||
|
|
||||||
deleteTag(
|
deleteTag(
|
||||||
id: Int!
|
id: Int!
|
||||||
): OperationResult
|
): OperationResult
|
||||||
@ -306,11 +283,6 @@ type Mutation {
|
|||||||
name: String!
|
name: String!
|
||||||
): OperationResult
|
): OperationResult
|
||||||
|
|
||||||
renameGroup(
|
|
||||||
id: Int!
|
|
||||||
name: String!
|
|
||||||
): OperationResult
|
|
||||||
|
|
||||||
renameTag(
|
renameTag(
|
||||||
id: Int!
|
id: Int!
|
||||||
key: String!
|
key: String!
|
||||||
@ -325,11 +297,6 @@ type Mutation {
|
|||||||
rightId: Int!
|
rightId: Int!
|
||||||
): OperationResult
|
): OperationResult
|
||||||
|
|
||||||
removeUserFromGroup(
|
|
||||||
userId: Int!
|
|
||||||
groupId: Int!
|
|
||||||
): OperationResult
|
|
||||||
|
|
||||||
resetUserPassword(
|
resetUserPassword(
|
||||||
id: Int!
|
id: Int!
|
||||||
): OperationResult
|
): OperationResult
|
||||||
|
69
server/graph/schemas/group.graphql
Normal file
69
server/graph/schemas/group.graphql
Normal file
@ -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!
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user