You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wiki/client/components/admin/admin-rendering.vue

257 lines
8.3 KiB

<template lang='pug'>
v-container(fluid, grid-list-lg)
v-layout(row, wrap)
v-flex(xs12)
.admin-header
img.animated.fadeInUp(src='/svg/icon-process.svg', alt='Rendering', style='width: 80px;')
.admin-header-title
.headline.primary--text.animated.fadeInLeft Rendering
v-spacer
v-btn.mx-3.animated.fadeInDown.wait-p2s(outlined, color='grey', @click='refresh', large)
v-icon mdi-refresh
v-btn.animated.fadeInDown(color='success', @click='save', depressed, large)
v-icon(left) mdi-check
span {{$t('common:actions.apply')}}
v-flex.animated.fadeInUp(lg3, xs12)
v-toolbar(
color='primary'
dense
flat
dark
)
.subtitle-1 Pipeline
v-expansion-panels.adm-rendering-pipeline(
v-model='selectedCore'
accordion
mandatory
)
v-expansion-panel(
v-for='core in renderers'
:key='core.key'
)
v-expansion-panel-header(
hide-actions
ripple
)
v-toolbar(
color='blue'
dense
dark
flat
)
v-spacer
.body-2 {{core.input}}
v-icon.mx-2 mdi-arrow-right-bold-hexagon-outline
.caption {{core.output}}
v-spacer
v-expansion-panel-content
v-list.py-0(two-line, dense)
template(v-for='(rdr, n) in core.children')
v-list-item(
:key='rdr.key'
@click='selectRenderer(rdr.key)'
:class='currentRenderer.key === rdr.key ? (darkMode ? `grey darken-4-l4` : `blue lighten-5`) : ``'
)
v-list-item-avatar(size='24')
v-icon(:color='currentRenderer.key === rdr.key ? "primary" : "grey"') {{rdr.icon}}
v-list-item-content
v-list-item-title {{rdr.title}}
v-list-item-subtitle: .caption {{rdr.description}}
v-list-item-avatar(size='24')
status-indicator(v-if='rdr.isEnabled', positive, pulse)
status-indicator(v-else, negative, pulse)
v-divider.my-0(v-if='n < core.children.length - 1')
v-flex(lg9, xs12)
v-card.wiki-form.animated.fadeInUp
v-toolbar(
color='grey darken-1'
dark
flat
dense
)
v-icon.mr-2 {{currentRenderer.icon}}
.subtitle-1 {{currentRenderer.title}}
v-spacer
v-switch(
dark
color='white'
label='Enabled'
v-model='currentRenderer.isEnabled'
hide-details
inset
)
v-card-text.pb-4.pt-2.pl-4
.overline.my-5 Rendering Module Configuration
.body-2.ml-3(v-if='!currentRenderer.config || currentRenderer.config.length < 1'): em This rendering module has no configuration options you can modify.
template(v-else, v-for='(cfg, idx) in currentRenderer.config')
v-select(
v-if='cfg.value.type === "string" && cfg.value.enum'
outlined
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
inset
)
v-text-field(
v-else
outlined
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.my-5(v-if='idx < currentRenderer.config.length - 1')
v-card-chin
v-spacer
.caption.pr-3.grey--text Module: {{ currentRenderer.key }}
</template>
<script>
import _ from 'lodash'
import { DepGraph } from 'dependency-graph'
import { get } from 'vuex-pathify'
import { StatusIndicator } from 'vue-status-indicator'
import renderersQuery from 'gql/admin/rendering/rendering-query-renderers.gql'
import renderersSaveMutation from 'gql/admin/rendering/rendering-mutation-save-renderers.gql'
export default {
components: {
StatusIndicator
},
data() {
return {
selectedCore: -1,
renderers: [],
currentRenderer: {}
}
},
computed: {
darkMode: get('site/dark')
},
watch: {
renderers(newValue, oldValue) {
_.delay(() => {
this.selectedCore = _.findIndex(newValue, ['key', 'markdownCore'])
this.selectRenderer('markdownCore')
}, 500)
}
},
methods: {
selectRenderer (key) {
this.renderers.map(rdr => {
if (_.some(rdr.children, ['key', key])) {
this.currentRenderer = _.find(rdr.children, ['key', key])
}
})
},
async refresh () {
await this.$apollo.queries.renderers.refetch()
this.$store.commit('showNotification', {
message: 'Rendering active configuration has been reloaded.',
style: 'success',
icon: 'cached'
})
},
async save () {
this.$store.commit(`loadingStart`, 'admin-rendering-saverenderers')
await this.$apollo.mutate({
mutation: renderersSaveMutation,
variables: {
renderers: _.reduce(this.renderers, (result, core) => {
result = _.concat(result, core.children.map(rd => ({
key: rd.key,
isEnabled: rd.isEnabled,
config: rd.config.map(cfg => ({ key: cfg.key, value: JSON.stringify({ v: cfg.value.value }) }))
})))
return result
}, [])
}
})
this.$store.commit('showNotification', {
message: 'Rendering configuration saved successfully.',
style: 'success',
icon: 'check'
})
this.$store.commit(`loadingStop`, 'admin-rendering-saverenderers')
}
},
apollo: {
renderers: {
query: renderersQuery,
fetchPolicy: 'network-only',
update: (data) => {
let renderers = _.cloneDeep(data.rendering.renderers).map(str => ({
...str,
config: _.sortBy(str.config.map(cfg => ({
...cfg,
value: JSON.parse(cfg.value)
})), [t => t.value.order])
}))
// Build tree
const graph = new DepGraph({ circular: true })
const rawCores = _.filter(renderers, ['dependsOn', null]).map(core => {
core.children = _.concat([_.cloneDeep(core)], _.filter(renderers, ['dependsOn', core.key]))
return core
})
// Build dependency graph
rawCores.map(core => { graph.addNode(core.key) })
rawCores.map(core => {
rawCores.map(coreTarget => {
if (core.key !== coreTarget.key) {
if (core.output === coreTarget.input) {
graph.addDependency(core.key, coreTarget.key)
}
}
})
})
// Reorder cores in reverse dependency order
let orderedCores = []
_.reverse(graph.overallOrder()).map(coreKey => {
orderedCores.push(_.find(rawCores, ['key', coreKey]))
})
return orderedCores
},
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-rendering-refresh')
}
}
}
}
</script>
<style lang='scss'>
.adm-rendering-pipeline {
.v-expansion-panel--active .v-expansion-panel-header {
min-height: 0;
}
.v-expansion-panel-header {
padding: 0;
margin-top: 1px;
}
.v-expansion-panel-content__wrap {
padding: 0;
}
}
</style>