waibu-db 2.15.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extend/bajoTemplate/partial/crud/_details-btns.html +10 -10
- package/extend/bajoTemplate/partial/crud/_edit-btns.html +11 -11
- package/extend/bajoTemplate/partial/crud/_list-btns.html +2 -2
- package/extend/waibuBootstrap/theme/component/wdb-base.js +4 -4
- package/extend/waibuBootstrap/theme/component/widget/form.js +66 -25
- package/extend/waibuBootstrap/theme/component/widget/query.js +1 -1
- package/extend/waibuBootstrap/theme/component/widget/table.js +10 -2
- package/lib/crud/add-handler.js +2 -2
- package/lib/crud/edit-handler.js +8 -3
- package/lib/method/update-record.js +4 -2
- package/lib/util.js +2 -1
- package/package.json +1 -1
- package/wiki/CHANGES.md +7 -0
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
<c:grid-row gutter="2">
|
|
2
2
|
<c:grid-col col="6-lg">
|
|
3
|
-
<% if (!
|
|
4
|
-
<c:wdb-btn-back href="<%=
|
|
3
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnBack/disabled')) { %>
|
|
4
|
+
<c:wdb-btn-back href="<%= _getSetting('waibuDb:/control/wdbBtnBack/href', 'undefined') %>" />
|
|
5
5
|
<% } %>
|
|
6
6
|
<% if (schema.disabled.includes('remove') && schema.disabled.includes('update')) { %>
|
|
7
|
-
<% if (!
|
|
7
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnExport/disabled')) { %>
|
|
8
8
|
<c:wdb-btn-export selector="#main-form" handler="details" launch-margin="start-1" />
|
|
9
9
|
<% } %>
|
|
10
10
|
<% } else { %>
|
|
11
11
|
<c:btn-group margin="start-1">
|
|
12
|
-
<% if (!
|
|
13
|
-
<c:wdb-btn-edit href="<%=
|
|
12
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnEdit/disabled')) { %>
|
|
13
|
+
<c:wdb-btn-edit href="<%= _getSetting('waibuDb:/control/wdbBtnEdit/href', 'undefined') %>" />
|
|
14
14
|
<% } %>
|
|
15
|
-
<% if (!
|
|
16
|
-
<c:wdb-btn-clone href="<%=
|
|
15
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnClone/disabled')) { %>
|
|
16
|
+
<c:wdb-btn-clone href="<%= _getSetting('waibuDb:/control/wdbBtnClone/href', 'undefined') %>" />
|
|
17
17
|
<% } %>
|
|
18
|
-
<% if (!
|
|
18
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnExport/disabled')) { %>
|
|
19
19
|
<c:wdb-btn-export selector="#main-form" handler="details" launch-on-end no-save/>
|
|
20
20
|
<% } %>
|
|
21
21
|
</c:btn-group>
|
|
22
22
|
<% } %>
|
|
23
23
|
</c:grid-col>
|
|
24
24
|
<c:grid-col col="6-lg" flex="justify-content:end-lg align-items:center">
|
|
25
|
-
<% if (!
|
|
26
|
-
<c:wdb-btn-delete href="<%=
|
|
25
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnDelete/disabled')) { %>
|
|
26
|
+
<c:wdb-btn-delete href="<%= _getSetting('waibuDb:/control/wdbBtnDelete/href', 'undefined') %>" />
|
|
27
27
|
<% } %>
|
|
28
28
|
</c:grid-col>
|
|
29
29
|
</c:grid-row>
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
<c:grid-row gutter="2">
|
|
2
2
|
<c:grid-col col="6-lg">
|
|
3
|
-
<% if (!
|
|
4
|
-
<c:wdb-btn-back href="<%=
|
|
3
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnBack/disabled')) { %>
|
|
4
|
+
<c:wdb-btn-back href="<%= _getSetting('waibuDb:/control/wdbBtnBack/href', 'undefined') %>"/>
|
|
5
5
|
<% } %>
|
|
6
6
|
<c:btn-group margin="start-1">
|
|
7
|
-
<% if (!
|
|
8
|
-
<c:wdb-btn-details href="<%=
|
|
7
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnDetails/disabled')) { %>
|
|
8
|
+
<c:wdb-btn-details href="<%= _getSetting('waibuDb:/control/wdbBtnDetails/href', 'undefined') %>" />
|
|
9
9
|
<% } %>
|
|
10
|
-
<% if (!
|
|
11
|
-
<c:wdb-btn-clone href="<%=
|
|
10
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnClone/disabled')) { %>
|
|
11
|
+
<c:wdb-btn-clone href="<%= _getSetting('waibuDb:/control/wdbBtnClone/href', 'undefined') %>" />
|
|
12
12
|
<% } %>
|
|
13
|
-
<% if (!
|
|
13
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnExport/disabled')) { %>
|
|
14
14
|
<c:wdb-btn-export selector="#main-form" handler="edit" launch-on-end no-save />
|
|
15
15
|
<% } %>
|
|
16
16
|
</c:btn-group>
|
|
17
17
|
</c:grid-col>
|
|
18
18
|
<c:grid-col col="6-lg" flex="justify-content:end-lg align-items:center">
|
|
19
|
-
<% if (!
|
|
20
|
-
<c:wdb-btn-delete href="<%=
|
|
19
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnDelete/disabled')) { %>
|
|
20
|
+
<c:wdb-btn-delete href="<%= _getSetting('waibuDb:/control/wdbBtnDelete/href', 'undefined') %>"/>
|
|
21
21
|
<% } %>
|
|
22
|
-
<% if (!
|
|
22
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnReset/disabled')) { %>
|
|
23
23
|
<c:btn type="reset" color="secondary" t:content="reset" margin="start-2"/>
|
|
24
24
|
<% } %>
|
|
25
|
-
<% if (!
|
|
25
|
+
<% if (!_getSetting('waibuDb:/control/wdbBtnSubmit/disabled')) { %>
|
|
26
26
|
<c:btn type="submit" color="primary" t:content="submit" margin="start-2"/>
|
|
27
27
|
<% } %>
|
|
28
28
|
</c:grid-col>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<c:grid-row gutter="3">
|
|
2
|
-
<c:grid-col col="
|
|
2
|
+
<c:grid-col col="5-lg">
|
|
3
3
|
<c:wdb-query />
|
|
4
4
|
</c:grid-col>
|
|
5
|
-
<c:grid-col col="
|
|
5
|
+
<c:grid-col col="7-lg" flex="justify-content:end-lg">
|
|
6
6
|
<c:btn-group margin="end-2">
|
|
7
7
|
<c:wdb-btn-add text="nowrap"/>
|
|
8
8
|
<c:wdb-btn-details on-list text="nowrap"/>
|
|
@@ -6,6 +6,7 @@ async function wdbBase () {
|
|
|
6
6
|
const { get } = this.app.lib._
|
|
7
7
|
this.schema = get(this, 'component.locals.schema', {})
|
|
8
8
|
this.formData = get(this, 'component.locals.form', {})
|
|
9
|
+
this.oldData = get(this, 'component.locals.oldData', {})
|
|
9
10
|
this.model = getModel(this.schema.name, true)
|
|
10
11
|
}
|
|
11
12
|
|
|
@@ -37,13 +38,12 @@ async function wdbBase () {
|
|
|
37
38
|
return refName
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
getSetting = (key,
|
|
41
|
-
const { req } = this.component
|
|
41
|
+
getSetting = (key, defValue) => {
|
|
42
42
|
const { get, camelCase } = this.app.lib._
|
|
43
43
|
const widgetName = camelCase(this.constructor.name)
|
|
44
44
|
key = key.replaceAll('{self}', widgetName)
|
|
45
|
-
const
|
|
46
|
-
return get(this.schema, `view.${key}`,
|
|
45
|
+
const cfg = this.app.waibu.getSetting(`${this.plugin.ns}:${key}`, { defValue, req: this.component.req })
|
|
46
|
+
return get(this.schema, `view.${key}`, cfg)
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
import wdbBase from '../wdb-base.js'
|
|
2
2
|
|
|
3
|
+
async function handleRo (attr = {}, prop = {}, widget = {}) {
|
|
4
|
+
const { get, camelCase, isEmpty, isString } = this.app.lib._
|
|
5
|
+
const { callHandler } = this.app.bajo
|
|
6
|
+
const { escape } = this.app.waibu
|
|
7
|
+
const { req } = this.component
|
|
8
|
+
const dataValue = get(this.formData, `_orig.${prop.name}`, prop.dataValue ?? '')
|
|
9
|
+
let value = get(this.oldData, prop.name, get(this.formData, prop.name, prop.value ?? ''))
|
|
10
|
+
const format = get(this.schema, `view.format.${prop.name}`)
|
|
11
|
+
const formatValue = get(this.schema, `view.formatValue.${prop.name}`)
|
|
12
|
+
const labelField = get(this.schema, `view.widget.${prop.name}.attr.labelField`)
|
|
13
|
+
if (formatValue) value = await formatValue.call(this, value, this.formData, { req })
|
|
14
|
+
else if (prop.ref) {
|
|
15
|
+
value = this.getRefValue({ field: prop.name, labelField, refName: this.getRefName(prop.name) })
|
|
16
|
+
if (format && !isEmpty(value)) attr.href = await format.call(this, value, this.formData, { linkOnly: true })
|
|
17
|
+
} else if (prop.values) {
|
|
18
|
+
const values = isString(prop.values) ? (await callHandler(prop.values)) : prop.values
|
|
19
|
+
value = values.find(v => v.value === dataValue)
|
|
20
|
+
if (value) {
|
|
21
|
+
const key = camelCase(`${prop.name} ${value.text}`)
|
|
22
|
+
value = req.te(key) ? req.t(key) : value.text
|
|
23
|
+
}
|
|
24
|
+
} else if (format && !isEmpty(value)) value = await format.call(this, value, this.formData)
|
|
25
|
+
attr.dataValue = escape(dataValue)
|
|
26
|
+
attr.value = escape(value)
|
|
27
|
+
attr.dataType = prop.type
|
|
28
|
+
|
|
29
|
+
if (['object', 'array', 'text'].includes(prop.type)) {
|
|
30
|
+
attr.style = 'min-height: 100px'
|
|
31
|
+
return await this.component.buildTag({ tag: 'formTextarea', attr, html: value })
|
|
32
|
+
}
|
|
33
|
+
return await this.component.buildTag({ tag: 'formPlaintext', attr, selfCosing: true, noEscape: true })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function handleRw (attr = {}, prop = {}, widget = {}) {
|
|
37
|
+
const { get, has, isPlainObject, isArray } = this.app.lib._
|
|
38
|
+
const { escape } = this.app.waibu
|
|
39
|
+
const { stringifyAttribs } = this.app.waibuMpa
|
|
40
|
+
if (has(attr, 'name') && !has(attr, 'value')) {
|
|
41
|
+
attr.dataType = attr.dataType ?? prop.type
|
|
42
|
+
attr.dataValue = get(this, `formData.${attr.name}`)
|
|
43
|
+
if (isPlainObject(attr.dataValue) || isArray(attr.dataValue)) attr.dataValue = JSON.stringify(attr.dataValue)
|
|
44
|
+
attr.dataValue = escape(attr.dataValue)
|
|
45
|
+
attr.value = widget.component === 'form-plaintext' ? get(this, `oldData.${attr.name}`, attr.dataValue) : attr.dataValue
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const cmp = prop.ref ? 'wdb-lookup-select' : widget.component
|
|
49
|
+
return `<c:${cmp} ${stringifyAttribs(attr)} data-type="${prop.type}" />`
|
|
50
|
+
}
|
|
51
|
+
|
|
3
52
|
async function form () {
|
|
4
53
|
const WdbBase = await wdbBase.call(this)
|
|
5
54
|
|
|
@@ -7,8 +56,6 @@ async function form () {
|
|
|
7
56
|
build = async () => {
|
|
8
57
|
const { get, find, filter, forOwn, isEmpty } = this.app.lib._
|
|
9
58
|
const { base64JsonEncode } = this.app.waibu
|
|
10
|
-
const { req } = this.component
|
|
11
|
-
const data = get(this, 'component.locals.form', {})
|
|
12
59
|
const body = []
|
|
13
60
|
const xModels = get(this.schema, 'view.x.model', [])
|
|
14
61
|
const xOns = get(this.schema, 'view.x.on', [])
|
|
@@ -17,36 +64,30 @@ async function form () {
|
|
|
17
64
|
if (fields.length === 0) continue
|
|
18
65
|
body.push(`<c:fieldset ${this.schema.view.card === false ? '' : 'card'} ${l.name[0] !== '_' ? ('t:legend="' + l.name + '"') : ''} grid-gutter="2">`)
|
|
19
66
|
for (const f of fields) {
|
|
20
|
-
const
|
|
67
|
+
const widget = this.schema.view.widget[f]
|
|
21
68
|
let prop = find(this.schema.properties, { name: f })
|
|
22
69
|
if (!prop) prop = find(this.schema.view.calcFields, { name: f })
|
|
23
70
|
if (!prop) continue
|
|
24
|
-
const attr =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
71
|
+
const attr = {
|
|
72
|
+
'x-ref': widget.name,
|
|
73
|
+
labelFloating: true,
|
|
74
|
+
name: widget.name
|
|
75
|
+
}
|
|
76
|
+
if (xModels.includes(widget.name)) attr['x-model'] = widget.name
|
|
77
|
+
forOwn(widget.attr, (v, k) => {
|
|
78
|
+
if (v === true) attr[k] = true
|
|
79
|
+
else attr[k] = v
|
|
29
80
|
})
|
|
30
|
-
|
|
81
|
+
attr.label = this.component.req.t(attr.label)
|
|
82
|
+
const xon = filter(xOns, { field: widget.name })
|
|
31
83
|
for (const o of xon) {
|
|
32
|
-
attr
|
|
84
|
+
attr[`@${o.bind}`] = o.handler
|
|
33
85
|
}
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let value
|
|
38
|
-
let link
|
|
39
|
-
if (this.schema.view.formatValue[f]) value = await this.schema.view.formatValue[f].call(this, data[f], data, { req })
|
|
40
|
-
else if (prop.ref) {
|
|
41
|
-
value = this.getRefValue({ field: f, labelField: w.attr.labelField, refName: this.getRefName(f) })
|
|
42
|
-
const format = get(this.schema, `view.format.${f}`)
|
|
43
|
-
if (format && !isEmpty(value)) link = await format.call(this.model, value, data, { linkOnly: true })
|
|
44
|
-
}
|
|
45
|
-
body.push(`<c:${w.component} ${attributes} data-type="${prop.type}" ${value ? `value="${value}"` : ''} ${link ? `href="${link}"` : ''} />`)
|
|
46
|
-
} else if (prop.ref) {
|
|
47
|
-
body.push(`<c:wdb-lookup-select ${attributes} />`)
|
|
86
|
+
if (widget.componentOpts) attr['c-opts'] = base64JsonEncode(widget.componentOpts)
|
|
87
|
+
if (widget.component === 'form-plaintext' || this.params.attr.method !== 'POST') {
|
|
88
|
+
body.push(await handleRo.call(this, attr, prop, widget))
|
|
48
89
|
} else {
|
|
49
|
-
body.push(
|
|
90
|
+
body.push(await handleRw.call(this, attr, prop, widget))
|
|
50
91
|
}
|
|
51
92
|
}
|
|
52
93
|
body.push('</c:fieldset>')
|
|
@@ -63,7 +63,7 @@ async function query () {
|
|
|
63
63
|
const container = this.params.attr.modal ? 'modal' : 'drawer'
|
|
64
64
|
const scanables = (this.model ? this.model.scanables : []).map(item => req.t(`field.${item}`))
|
|
65
65
|
let placeholder = this.params.attr.placeholder
|
|
66
|
-
if (!placeholder) placeholder = scanables.length > 0 ? req.t('queryHint%s', join(scanables, { lastSeparator: 'or' })) : req.t('query')
|
|
66
|
+
if (!placeholder) placeholder = scanables.length > 0 ? req.t('queryHint%s', join(scanables, { separator: ', ', lastSeparator: 'or' })) : req.t('query')
|
|
67
67
|
this.params.html = await this.component.buildSentence(`
|
|
68
68
|
<c:form-input type="search" placeholder="${placeholder}" id="${id}" x-data="{ query: '' }" x-init="
|
|
69
69
|
const url = new URL(window.location.href)
|
|
@@ -26,7 +26,7 @@ async function table () {
|
|
|
26
26
|
const { req } = this.component
|
|
27
27
|
const { escape, attrToArray } = this.app.waibu
|
|
28
28
|
const { groupAttrs } = this.app.waibuMpa
|
|
29
|
-
const { get, omit, set, find, isEmpty, without, merge } = this.app.lib._
|
|
29
|
+
const { get, omit, set, find, isEmpty, without, merge, camelCase } = this.app.lib._
|
|
30
30
|
const group = groupAttrs(this.params.attr, ['body', 'head', 'foot'])
|
|
31
31
|
this.params.attr = group._
|
|
32
32
|
const prettyUrl = this.params.attr.prettyUrl
|
|
@@ -38,6 +38,7 @@ async function table () {
|
|
|
38
38
|
// collect prop.values for later use
|
|
39
39
|
for (const prop of schema.properties) {
|
|
40
40
|
if (typeof prop.values === 'string') this.propValues[prop.name] = await callHandler(prop.values)
|
|
41
|
+
else if (prop.values) this.propValues[prop.name] = prop.values
|
|
41
42
|
}
|
|
42
43
|
if (count === 0 || data.length === 0) {
|
|
43
44
|
const alert = '<c:alert color="warning" t:content="noRecordFound" margin="top-4"/>'
|
|
@@ -156,11 +157,18 @@ async function table () {
|
|
|
156
157
|
else attr.text = noWrap
|
|
157
158
|
const lookup = get(schema, `view.lookup.${f}`)
|
|
158
159
|
if (lookup) {
|
|
159
|
-
const item = find(lookup.values, set({}, lookup.id ?? 'id',
|
|
160
|
+
const item = find(lookup.values, set({}, lookup.id ?? 'id', dataValue))
|
|
160
161
|
if (item) value = req.t(item[lookup.field ?? 'name'])
|
|
161
162
|
}
|
|
162
163
|
const format = get(schema, `view.format.${f}`)
|
|
163
164
|
if (format) value = await format.call(this, value, d, { params: this.params, req })
|
|
165
|
+
if (this.propValues[f]) {
|
|
166
|
+
const item = find(this.propValues[f], { value: dataValue })
|
|
167
|
+
if (item) {
|
|
168
|
+
const key = camelCase(`${f} ${item.text}`)
|
|
169
|
+
value = req.te(key) ? req.t(key) : item.text
|
|
170
|
+
}
|
|
171
|
+
}
|
|
164
172
|
const line = await this.component.buildTag({ tag: 'td', attr, html: value })
|
|
165
173
|
lines.push(line)
|
|
166
174
|
}
|
package/lib/crud/add-handler.js
CHANGED
|
@@ -14,8 +14,8 @@ async function addHandler ({ req, reply, model, params = {}, template, addOnsHan
|
|
|
14
14
|
delete req.query.query
|
|
15
15
|
let def = {}
|
|
16
16
|
if (req.method === 'GET' && req.query.mode === 'clone' && req.query.id) {
|
|
17
|
-
const resp = await getRecord({ model, req, id: req.query.id, options: { fields: map(schema.properties, 'name') } })
|
|
18
|
-
def = omit(resp.data, ['id', 'createdAt', 'updatedAt'])
|
|
17
|
+
const resp = await getRecord({ model, req, id: req.query.id, options: { fields: map(schema.properties, 'name'), ...opts } })
|
|
18
|
+
def = omit(resp.data._orig, ['id', 'createdAt', 'updatedAt'])
|
|
19
19
|
}
|
|
20
20
|
let form = defaultsDeep(req.body, def)
|
|
21
21
|
let error
|
package/lib/crud/edit-handler.js
CHANGED
|
@@ -7,7 +7,7 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
|
|
|
7
7
|
const { buildUrl } = this.app.waibuMpa
|
|
8
8
|
const { fs } = this.app.lib
|
|
9
9
|
const { defaultsDeep } = this.app.lib.aneka
|
|
10
|
-
const { merge, isEmpty, omit } = this.app.lib._
|
|
10
|
+
const { merge, isEmpty, omit, cloneDeep, isArray, isPlainObject } = this.app.lib._
|
|
11
11
|
const opts = merge({}, options.modelOpts)
|
|
12
12
|
let error
|
|
13
13
|
let resp
|
|
@@ -22,7 +22,12 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
|
|
|
22
22
|
delete req.query.query
|
|
23
23
|
const old = await getRecord({ model, req, id, options: opts })
|
|
24
24
|
if (isEmpty(old.data)) return await reply.view(notFoundTpl, params)
|
|
25
|
-
|
|
25
|
+
opts._data = old
|
|
26
|
+
const def = cloneDeep(old.data._orig)
|
|
27
|
+
for (const k in def) {
|
|
28
|
+
if (isArray(def[k]) || isPlainObject(def[k])) def[k] = JSON.stringify(def[k])
|
|
29
|
+
}
|
|
30
|
+
form = defaultsDeep(req.body, def)
|
|
26
31
|
if (req.method !== 'GET') {
|
|
27
32
|
form = omit(form, ['_action', '_value'])
|
|
28
33
|
try {
|
|
@@ -49,7 +54,7 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
|
|
|
49
54
|
}
|
|
50
55
|
const addOns = addOnsHandler ? await addOnsHandler.call(this.app[req.ns], { req, reply, params, data: resp, schema, error, options }) : undefined
|
|
51
56
|
const attachments = await attachmentHandler.call(this, { schema, id, options })
|
|
52
|
-
merge(params, { form, schema, error, addOns, attachments })
|
|
57
|
+
merge(params, { oldData: old.data, form, schema, error, addOns, attachments })
|
|
53
58
|
if (schema.template) template = schema.template
|
|
54
59
|
if (schema.layout) params.page.layout = schema.layout
|
|
55
60
|
return await reply.view(template, params)
|
|
@@ -6,8 +6,10 @@ async function updateRecord ({ model, req, reply, id, body, options = {}, transa
|
|
|
6
6
|
|
|
7
7
|
async function handler (trx) {
|
|
8
8
|
if (opts.trx === true) opts.trx = trx
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
if (!opts._data) {
|
|
10
|
+
const resp = await getOneRecord.call(me, mdl, recId, filter, opts)
|
|
11
|
+
opts._data = resp.data
|
|
12
|
+
}
|
|
11
13
|
const ret = await mdl.updateRecord(recId, input, opts)
|
|
12
14
|
if (attachment) ret.data._attachment = await mdl.findAttachment(id, { stats, mimeType })
|
|
13
15
|
return ret
|
package/lib/util.js
CHANGED
|
@@ -79,7 +79,8 @@ export async function processHandler ({ action, model, handler, options } = {})
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
try {
|
|
82
|
-
|
|
82
|
+
if (options.trx === true) return await model.transaction(handler)
|
|
83
|
+
return await handler()
|
|
83
84
|
} catch (err) {
|
|
84
85
|
if (options.suppressError.includes(action)) return suppressedReturn.call(this, err)
|
|
85
86
|
throw err
|
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-04-13
|
|
4
|
+
|
|
5
|
+
- [2.16.0] Add ```oldData``` propety to ```WdbBase``` widget
|
|
6
|
+
- [2.16.0] Change ```WdbBase.getSetting()``` to also respect setting from ```waibu.getSetting()```
|
|
7
|
+
- [2.16.0] Rewrite ```WdbForm``` widget entirely
|
|
8
|
+
- [2.16.0] Remove redundant call to get old record in ```updateRecord()```
|
|
9
|
+
|
|
3
10
|
## 2026-04-11
|
|
4
11
|
|
|
5
12
|
- [2.15.0] Add ```control``` key in config object
|