functional editor

This commit is contained in:
Timo Hocker 2020-08-15 15:19:52 +02:00
parent b09e851580
commit d3a19c953a
8 changed files with 638 additions and 302 deletions

View File

@ -5,8 +5,6 @@
* Created by Timo Hocker <timo@scode.ovh>, July 2020 * Created by Timo Hocker <timo@scode.ovh>, July 2020
*/ */
module.exports = { 'use strict';
presets: [
'@vue/cli-plugin-babel/preset' module.exports = { presets: [ '@vue/cli-plugin-babel/preset' ] };
]
}

View File

@ -38,7 +38,7 @@ const user = {
app.use (api); app.use (api);
app.use (history_fallback ()); app.use (history_fallback ());
app.use (http_proxy ('localhost:8081')); app.use (http_proxy ('localhost:8080'));
app.listen (3000, () => { app.listen (3000, () => {
console.log ('listening on 3000'); console.log ('listening on 3000');

View File

@ -15,6 +15,7 @@
"@sapphirecode/crypto-helper": "^1.1.57", "@sapphirecode/crypto-helper": "^1.1.57",
"@sapphirecode/password-helper": "^1.0.47", "@sapphirecode/password-helper": "^1.0.47",
"@sapphirecode/ui-modules": "^0.1.1", "@sapphirecode/ui-modules": "^0.1.1",
"@sapphirecode/utilities": "^1.8.5",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"chart.js": "^2.9.3", "chart.js": "^2.9.3",
"connect-history-api-fallback": "^1.6.0", "connect-history-api-fallback": "^1.6.0",
@ -35,11 +36,11 @@
"devDependencies": { "devDependencies": {
"@sapphirecode/eslint-config": "^2.1.16", "@sapphirecode/eslint-config": "^2.1.16",
"@sapphirecode/eslint-config-vue": "^1.1.16", "@sapphirecode/eslint-config-vue": "^1.1.16",
"@vue/cli-plugin-babel": "~4.4.0", "@vue/cli-plugin-babel": "^4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0", "@vue/cli-plugin-eslint": "^4.4.0",
"@vue/cli-plugin-router": "~4.4.0", "@vue/cli-plugin-router": "^4.4.0",
"@vue/cli-plugin-vuex": "~4.4.0", "@vue/cli-plugin-vuex": "^4.4.0",
"@vue/cli-service": "~4.4.0", "@vue/cli-service": "^4.4.0",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"eslint": "^7.5.0", "eslint": "^7.5.0",
"eslint-plugin-vue": "^6.2.2", "eslint-plugin-vue": "^6.2.2",

View File

@ -18,6 +18,7 @@ function create_log (index, simplex) {
} }
async function seed (knex) { async function seed (knex) {
// eslint-disable-next-line no-console
console.log ('creating seeds'); console.log ('creating seeds');
const simplex = (new sn); const simplex = (new sn);
const log = (Array (20)) const log = (Array (20))

View File

@ -1,7 +1,10 @@
<template> <template>
<div class="config-editor"> <div
v-if="enabled"
class="config-editor"
>
<p <p
clasS="label" class="label"
v-text="template.name" v-text="template.name"
/> />
<!-- editor --> <!-- editor -->
@ -12,8 +15,9 @@
<ConfigEditor <ConfigEditor
v-for="(prop,key) of template.properties" v-for="(prop,key) of template.properties"
:key="key" :key="key"
v-model="config[prop.name]"
:template="prop" :template="prop"
:config="config[prop.name]" :enabled="is_enabled(prop.if)"
/> />
</div> </div>
<div <div
@ -23,12 +27,13 @@
<ConfigEditor <ConfigEditor
v-for="(child,key) of config" v-for="(child,key) of config"
:key="key" :key="key"
:config="child" v-model="config[key]"
:template="template.child" :template="template.child"
:enabled="is_enabled(template.child.if)"
/> />
<button <button
type="button" type="button"
@click="config.push(create_default(template.child))" @click="add_item"
> >
add add
</button> </button>
@ -37,7 +42,18 @@
v-else-if="template.type === 'string'" v-else-if="template.type === 'string'"
class="editor" class="editor"
> >
<select
v-if="Array.isArray(template.choices)"
v-model="config"
>
<option
v-for="(opt,optkey) in template.choices"
:key="optkey"
v-text="opt"
/>
</select>
<input <input
v-else
v-model="config" v-model="config"
type="text" type="text"
> >
@ -67,17 +83,60 @@
</template> </template>
<script> <script>
import { resolve_data } from '../helper';
export default { export default {
name: 'ConfigEditor', name: 'ConfigEditor',
props: { props: {
// eslint-disable-next-line vue/require-prop-types // eslint-disable-next-line vue/require-prop-types
config: { required: true }, value: { required: true },
template: { template: {
type: Object, type: Object,
required: true required: true,
enabled: { type: Boolean, default: true }
},
enabled: {
type: Boolean,
default: true
}
},
data () {
return { temp: this.value };
},
computed: {
config: {
get () {
return this.temp;
},
set (val) {
this.$emit ('input', val);
this.temp = val;
}
} }
}, },
methods: { methods: {
is_enabled (condition) {
if (typeof condition === 'undefined')
return true;
switch (condition.op) {
case '=':
return resolve_data (this.config, condition.prop) === condition.val;
case '<':
return resolve_data (this.config, condition.prop) < condition.val;
case '>':
return resolve_data (this.config, condition.prop) > condition.val;
default:
return false;
}
},
add_item () {
if (
typeof this.config === 'undefined'
|| !Array.isArray (this.config)
)
this.config = [];
this.config.push (this.create_default (this.template.child));
},
create_default (template) { create_default (template) {
if (typeof template.default !== 'undefined') if (typeof template.default !== 'undefined')
return template.default; return template.default;

View File

@ -4,21 +4,28 @@ export default {
type: 'object', type: 'object',
properties: [ properties: [
{ {
type: 'string', type: 'string',
name: 'type' name: 'type',
choices: [
'table',
'chart'
]
}, },
{ {
name: 'columns', name: 'columns',
type: 'array', type: 'array',
child: { type: 'string' } child: { type: 'string' },
if: { prop: 'type', op: '=', val: 'table' }
}, },
{ {
name: 'x', name: 'x',
type: 'string' type: 'string',
if: { prop: 'type', op: '=', val: 'chart' }
}, },
{ {
name: 'y', name: 'y',
type: 'array', type: 'array',
if: { prop: 'type', op: '=', val: 'chart' },
child: { child: {
type: 'object', type: 'object',
properties: [ properties: [

View File

@ -3,11 +3,11 @@
class="grid" class="grid"
> >
<ConfigEditor <ConfigEditor
:config="config" v-model="config"
:template="template" :template="template"
/> />
<ViewComponent <ViewComponent
v-for="(item,key) of config" v-for="(item,key) of saved_config"
:key="key" :key="key"
:config="item" :config="item"
:data="parsed_log" :data="parsed_log"
@ -17,6 +17,7 @@
<script> <script>
import Vuex from 'vuex'; import Vuex from 'vuex';
import { copy_object } from '@sapphirecode/utilities';
import ViewComponent from '../components/ViewComponent.vue'; import ViewComponent from '../components/ViewComponent.vue';
import ConfigEditor from '../components/ConfigEditor.vue'; import ConfigEditor from '../components/ConfigEditor.vue';
import default_config from '../default'; import default_config from '../default';
@ -26,8 +27,9 @@ export default {
components: { ViewComponent, ConfigEditor }, components: { ViewComponent, ConfigEditor },
data () { data () {
return { return {
config: default_config, config: copy_object (default_config),
template: default_template saved_config: copy_object (default_config),
template: default_template
}; };
}, },
computed: { computed: {
@ -41,8 +43,25 @@ export default {
}, },
mounted () { mounted () {
this.get_log (); this.get_log ();
document.body.addEventListener ('keydown', (ev) => {
if (ev.key === 's' && ev.ctrlKey) {
this.save_config ();
ev.preventDefault ();
return false;
}
return true;
});
}, },
methods: { ...Vuex.mapActions ({ get_log: 'get_log' }) } methods: {
save_config () {
fetch ('config', {
method: 'POST',
body: JSON.stringify (this.config)
});
this.saved_config = copy_object (this.config);
},
...Vuex.mapActions ({ get_log: 'get_log' })
}
}; };
</script> </script>

801
yarn.lock

File diff suppressed because it is too large Load Diff