move Data component to separate module comp-data.ts

This commit is contained in:
Helmut Merz 2023-03-22 09:35:50 +01:00
parent 71c683a9f7
commit 2e767754e5
4 changed files with 114 additions and 110 deletions

View file

@ -1,4 +1,7 @@
// common.ts - common stuff like config and app setup
import { createApp } from 'petite-vue'
import { Data } from './comp-data'
import { domain, nopoll } from '@params'
@ -40,91 +43,12 @@ const appdata = {
$delimiters: ['{|', '|}'],
conf: {} as Config,
components: {},
output: '',
output: '', // debug output space
handle,
poll,
mounted(name: string) {
console.log('app mounted: ', name)
},
Data
}
// Data component
// (move to comp_data.ts)
function Data(name, action, domain: string): object {
domain = domain || this.conf.domain
const comp = {
id: this.conf.itemid,
name: name, // -> class of incoming/outgoing message
action: action, // (default) action of outgoing message
domain: domain, // domain of incoming/outgoing message
data: {}, // model (2-way data store)
data_bak: {}, // backup copy when leaving view or edit mode
meta: {}, // metadata (params) for each data field
mode: 'view',
mounted,
chmode,
copynew,
exec // default function to execute upon button click
}
this.components[name] = comp
if (comp.id) {
sendMsg(this.conf, [domain, 'query', name, comp.id], {})
}
return comp
}
// Data methods
// (move to comp_data.ts)
function mounted(name: string, meta: any) {
if (meta.defexpr) {
meta.default = eval(meta.defexpr)
}
this.data[name] = meta.default || ""
this.meta[name] = meta
}
function chmode(action: string) {
if (this.mode == action) {
return
}
if (this.mode == 'view') {
Object.assign(this.data_bak, this.data)
}
switch(action) {
case 'query':
setQuery(this)
break
case 'new':
setNew(this)
break
default:
Object.assign(this.data, this.data_bak)
}
this.mode = action
}
function copynew(action: string) {
Object.assign(this.data, this.data_bak)
this.data.id = ''
this.mode = 'new'
}
function exec(action: string) {
action = action || this.action
const data = this.data
const conf = this.conf
let value = ''
for (const k of Object.keys(data)) {
value += `${k}: ${data[k]}, `
}
this.output += '\n' + value
console.log('exec:', value)
sendMsg(conf, [this.domain, action, this.name, data.id], data)
}
// App (appdata) methods
function handle(msg) {
@ -136,9 +60,7 @@ function handle(msg) {
return
}
if (comp) {
// TODO: use more generic comp.update(data)
// ... or even more generic comp.handle(msg)
Object.assign(comp.data, data)
comp.handle(domain, action, class_, item, data)
}
}
@ -146,29 +68,9 @@ function poll() {
dopoll(this)
}
// helper functions for data manipulation (used by Data component)
// (move to comp_data.ts)
function setQuery(obj) {
for (const key in obj.data) {
obj.data[key] = ''
}
}
function setNew(obj) {
for (const key in obj.data) {
obj.data[key] = ''
const meta = obj.meta[key]
if (meta) {
obj.data[key] = meta.default || ''
}
}
obj.data.id = ''
}
// basic functions - move to api.ts
async function sendMsg(conf: Config, basemsg: string[], data: any) {
export async function sendMsg(conf: Config, basemsg: string[], data: any) {
const url = `${conf.apiurl}/${basemsg.join('/')}`
await send(url, conf, data)
}

104
assets/js/comp-data.ts Normal file
View file

@ -0,0 +1,104 @@
// comp-data.ts - definition and methods of the Data component
import { sendMsg } from './common'
// Data component
export function Data(name, action, domain: string): object {
domain = domain || this.conf.domain
const comp = {
id: this.conf.itemid,
name: name, // also used as class of incoming/outgoing message
action: action, // (default) action of outgoing message
domain: domain, // domain of incoming/outgoing message
data: {}, // model (2-way data store)
data_bak: {}, // backup copy when leaving view or edit mode
meta: {}, // metadata (params) for each data field
mode: 'view',
handle, // handle incoming messages
exec, // default function to execute upon button click
initField, // initialize field (= @mounted)
chmode,
copynew
}
this.components[name] = comp
if (comp.id) {
sendMsg(this.conf, [domain, 'query', name, comp.id], {})
}
return comp
}
// Data methods
function handle(domain, action, class_, item: string, data: Object) {
if (action == 'data') {
Object.assign(this.data, data)
}
}
function exec(action: string) {
action = action || this.action
const data = this.data
const conf = this.conf
let value = ''
for (const k of Object.keys(data)) {
value += `${k}: ${data[k]}, `
}
this.output += '\n' + value
console.log('exec:', value)
sendMsg(conf, [this.domain, action, this.name, data.id], data)
}
function initField(name: string, meta: any) {
if (meta.defexpr) {
meta.default = eval(meta.defexpr)
}
this.data[name] = meta.default || ""
this.meta[name] = meta
}
function chmode(action: string) {
if (this.mode == action) {
return
}
if (this.mode == 'view') {
Object.assign(this.data_bak, this.data)
}
switch(action) {
case 'query':
setQuery(this)
break
case 'new':
setNew(this)
break
default:
Object.assign(this.data, this.data_bak)
}
this.mode = action
}
function copynew(action: string) {
Object.assign(this.data, this.data_bak)
this.data.id = ''
this.mode = 'new'
}
// helper functions for data manipulation (used by Data component)
function setQuery(obj) {
for (const key in obj.data) {
obj.data[key] = ''
}
}
function setNew(obj) {
for (const key in obj.data) {
obj.data[key] = ''
const meta = obj.meta[key]
if (meta) {
obj.data[key] = meta.default || ''
}
}
obj.data.id = ''
}

View file

@ -1,14 +1,14 @@
<div v-scope>
<h3>Debug Information</h3>
<div @vue:mounted="mounted('conf')">
<div>
<div>domain: {| conf.domain |}</div>
<div>item id: {| conf.itemid |}</div>
<div>session id: {| conf.sid |}</div>
<div>interaction id: {| conf.iid |}</div>
</div>
<div @vue:mounted="mounted('output')">
<div>
<pre v-text="output"></pre>
</div>

View file

@ -1,13 +1,11 @@
{{- $type := .Get "type" | default "text" -}}
{{- $name := .Get "name" | default "textline" -}}
{{- $default := .Get "default" | default "" -}}
{{- $defexpr := .Get "defexpr" | default (printf "'%s'" $default) -}}
{{- $meta := $.Params | jsonify -}}
{{- $meta := merge $.Params (dict "name" $name "type" $type) | jsonify -}}
<div>
<input type="{{ $type }}" name="{{ $name }}"
{{- with .Get "attrs" }} {{ . }}{{ end }}
:readonly="mode == 'view' ? '' : null"
v-model="data.{{ $name }}"
@vue:mounted="mounted('{{ $name }}', {{ $meta }})"
@vue:mounted="initField('{{ $name }}', {{ $meta }})"
{{- with .Get "onchange" }} @change="{{ . }}"{{ end }} />
</div>