waibu-db 2.17.2 → 2.18.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/waibuBootstrap/theme/component/widget/data-table.js +7 -12
- package/extend/waibuBootstrap/theme/component/widget/lookup-select.js +5 -5
- package/extend/waibuRestApi/route/@model/@id/get.js +2 -2
- package/extend/waibuRestApi/route/@model/@id/remove.js +2 -2
- package/extend/waibuRestApi/route/@model/@id/update.js +2 -2
- package/extend/waibuRestApi/route/@model/create.js +2 -2
- package/extend/waibuRestApi/route/@model/find.js +2 -2
- package/extend/waibuRestApi/route/@model/stat/@stat/find.js +2 -2
- package/index.js +1 -5
- package/lib/crud/add-handler.js +1 -1
- package/lib/crud/all-handler.js +1 -2
- package/lib/crud/edit-handler.js +1 -1
- package/lib/method/get-schema-ext.js +0 -2
- package/lib/util.js +2 -2
- package/package.json +1 -1
- package/wiki/CHANGES.md +6 -0
|
@@ -116,9 +116,9 @@ async function table () {
|
|
|
116
116
|
const lines = []
|
|
117
117
|
if (selection) {
|
|
118
118
|
const tag = selection === 'single' ? 'formRadio' : 'formCheck'
|
|
119
|
-
const attr = { 'x-model': 'selected', name: '_rt', value: d.
|
|
119
|
+
const attr = { 'x-model': 'selected', name: '_rt', value: d.id, noLabel: true, noWrapper: true }
|
|
120
120
|
const type = find(schema.properties, { name: 'id' }).type
|
|
121
|
-
const prepend = `<td data-value="${d.
|
|
121
|
+
const prepend = `<td data-value="${d.id}" data-key="id" data-type="${type}">`
|
|
122
122
|
lines.push(await this.component.buildTag({ tag, attr, prepend, append: '</td>' }))
|
|
123
123
|
}
|
|
124
124
|
for (const f of schema.view.fields) {
|
|
@@ -126,17 +126,12 @@ async function table () {
|
|
|
126
126
|
let prop = find(schema.properties, { name: f })
|
|
127
127
|
if (!prop) prop = find(schema.view.calcFields, { name: f })
|
|
128
128
|
if (!prop) continue
|
|
129
|
-
let dataValue = d
|
|
129
|
+
let dataValue = d[f]
|
|
130
130
|
if (['datetime'].includes(prop.type) && dataValue instanceof Date && !isNaN(dataValue)) dataValue = escape(dataValue.toISOString())
|
|
131
131
|
else if (['string', 'text'].includes(prop.type)) dataValue = escape(dataValue)
|
|
132
132
|
else if (['array', 'object'].includes(prop.type)) dataValue = escape(JSON.stringify(dataValue))
|
|
133
133
|
const refName = get(schema, `view.widget.${f}.attr.refName`)
|
|
134
|
-
let value = this.getRefValue({ field: f, data: d, refName }) ?? d
|
|
135
|
-
const formatValue = get(schema, `view.formatValue.${f}`)
|
|
136
|
-
if (formatValue) {
|
|
137
|
-
value = await formatValue.call(this, value, d, { params: this.params, req })
|
|
138
|
-
dataValue = value
|
|
139
|
-
}
|
|
134
|
+
let value = this.getRefValue({ field: f, data: d, refName }) ?? get(d, `_fmt.${f}`)
|
|
140
135
|
if (!get(schema, 'view.noEscape', []).includes(f)) value = escape(value)
|
|
141
136
|
const attr = { dataValue, dataKey: prop.name, dataType: prop.type }
|
|
142
137
|
if (!disableds.includes('get')) attr.style = { cursor: 'pointer' }
|
|
@@ -150,9 +145,9 @@ async function table () {
|
|
|
150
145
|
const line = await this.component.buildTag({ tag: 'td', attr, html: value })
|
|
151
146
|
lines.push(line)
|
|
152
147
|
}
|
|
153
|
-
const attr = { id: `rec-${d.
|
|
154
|
-
if (!disableds.includes('update') || !disableds.includes('remove') || !disableds.includes('get')) attr['@click'] = `toggle('${d.
|
|
155
|
-
if (!disableds.includes('get')) attr['@dblclick'] = `goDetails('${d.
|
|
148
|
+
const attr = { id: `rec-${d.id}` }
|
|
149
|
+
if (!disableds.includes('update') || !disableds.includes('remove') || !disableds.includes('get')) attr['@click'] = `toggle('${d.id}')`
|
|
150
|
+
if (!disableds.includes('get')) attr['@dblclick'] = `goDetails('${d.id}')`
|
|
156
151
|
items.push(await this.component.buildTag({ tag: 'tr', attr, html: lines.join('\n') }))
|
|
157
152
|
}
|
|
158
153
|
html.push(await this.component.buildTag({ tag: 'tbody', attr: group.body, html: items.join('\n') }))
|
|
@@ -21,10 +21,10 @@ async function lookupSelect () {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
this.params.attr.url = this.params.attr.url ?? `waibuDb.restapi:/lookup/${kebabCase(ref.model)}`
|
|
24
|
-
const
|
|
25
|
-
const attr = omit(this.params.attr,
|
|
26
|
-
for (const k of
|
|
27
|
-
attr[camelCase(`remote ${k}`)] = this.params.attr[k] ?? ref[k]
|
|
24
|
+
const keys = ['url', 'searchField', 'labelField', 'valueField']
|
|
25
|
+
const attr = omit(this.params.attr, keys)
|
|
26
|
+
for (const k of keys) {
|
|
27
|
+
attr[camelCase(`remote ${k}`)] = this.params.attr[k] ?? ref[k] ?? ref.field
|
|
28
28
|
}
|
|
29
29
|
const q = set({}, this.params.attr.searchField ?? get(ref, 'searchField', 'id'), ['__REGEXP__', '{searchItem}', 'i'])
|
|
30
30
|
attr.remoteQuery = base64JsonEncode({ $and: [parseQuery(get(ref, 'query', {})), q] })
|
|
@@ -32,7 +32,7 @@ async function lookupSelect () {
|
|
|
32
32
|
attr.clearBtn = true
|
|
33
33
|
const sentence = `<c:form-select-ext ${Object.entries(attr).map(([k, v]) => `${kebabCase(k)}="${v}"`).join(' ')} />`
|
|
34
34
|
this.params.html = await this.component.buildSentence(sentence, this.component.locals)
|
|
35
|
-
this.params.attr = omit(this.params.attr, ['model', 'field', ...
|
|
35
|
+
this.params.attr = omit(this.params.attr, ['model', 'field', ...keys])
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
async function stat (req, reply) {
|
|
1
|
+
async function stat (req, reply, options) {
|
|
2
2
|
const { camelCase } = this.app.lib._
|
|
3
3
|
const method = camelCase(`create ${req.params.stat}`)
|
|
4
4
|
if (!this[method]) throw this.error('_notFound')
|
|
5
|
-
return await this[method]({ req, reply })
|
|
5
|
+
return await this[method]({ req, reply, options })
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export default stat
|
package/index.js
CHANGED
|
@@ -205,11 +205,7 @@ async function factory (pkgName) {
|
|
|
205
205
|
time: options.time ?? { timeZone }
|
|
206
206
|
}
|
|
207
207
|
rec[f] = format(data[f], prop.type, opts)
|
|
208
|
-
|
|
209
|
-
if (vf) {
|
|
210
|
-
if (isFunction(vf)) rec[f] = await vf.call(this, data[f], data, { req })
|
|
211
|
-
else rec[f] = await callHandler(vf, { req, value: data[f], data })
|
|
212
|
-
} else if (['string', 'text'].includes(prop.type)) rec[f] = escape(rec[f])
|
|
208
|
+
if (['string', 'text'].includes(prop.type)) rec[f] = escape(rec[f])
|
|
213
209
|
}
|
|
214
210
|
return rec
|
|
215
211
|
}
|
package/lib/crud/add-handler.js
CHANGED
|
@@ -17,7 +17,7 @@ async function addHandler ({ req, reply, model, params = {}, template, addOnsHan
|
|
|
17
17
|
const omitted = ['id', 'createdAt', 'updatedAt']
|
|
18
18
|
if (req.query.mode === 'clone' && req.query.id) {
|
|
19
19
|
const resp = await getRecord({ model, req, id: req.query.id, options: { fields: map(schema.properties, 'name'), ...opts } })
|
|
20
|
-
def = omit(resp.data
|
|
20
|
+
def = omit(resp.data, omitted)
|
|
21
21
|
} else {
|
|
22
22
|
const picked = map(schema.properties, 'name')
|
|
23
23
|
def = omit(pick(req.query, picked), omitted)
|
package/lib/crud/all-handler.js
CHANGED
|
@@ -20,8 +20,7 @@ async function allHandler ({ model, action, req, reply, template, params = {}, o
|
|
|
20
20
|
const { upperFirst, merge, keys } = this.app.lib._
|
|
21
21
|
if (!keys(handler).includes(action)) throw this.error('_notFound')
|
|
22
22
|
options.modelOpts = options.modelOpts ?? {}
|
|
23
|
-
options.modelOpts.
|
|
24
|
-
options.modelOpts.retainOriginalValue = true
|
|
23
|
+
options.modelOpts.fmt = true
|
|
25
24
|
if (['delete', 'export'].includes(action)) {
|
|
26
25
|
if (req.method === 'GET') throw this.error('_notFound')
|
|
27
26
|
return await handler[action].call(this, { model, req, reply, options })
|
package/lib/crud/edit-handler.js
CHANGED
|
@@ -23,7 +23,7 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
|
|
|
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
|
|
26
|
+
const def = cloneDeep(old.data)
|
|
27
27
|
for (const k in def) {
|
|
28
28
|
if (isArray(def[k]) || isPlainObject(def[k])) def[k] = JSON.stringify(def[k])
|
|
29
29
|
}
|
|
@@ -12,7 +12,6 @@ function getCommons (action, schema, ext, options = {}) {
|
|
|
12
12
|
const widget = defaultsDeep(get(ext, `view.${action}.widget`), get(ext, 'common.widget', {}))
|
|
13
13
|
const noEscape = get(ext, `view.${action}.noEscape`, get(ext, 'common.noEscape', []))
|
|
14
14
|
const control = defaultsDeep(get(ext, `view.${action}.control`), get(ext, 'common.control', {}))
|
|
15
|
-
const formatValue = defaultsDeep(get(ext, `view.${action}.formatValue`), get(ext, 'common.formatValue', {}))
|
|
16
15
|
const formatCell = defaultsDeep(get(ext, `view.${action}.formatCell`), get(ext, 'common.formatCell', {}))
|
|
17
16
|
const format = defaultsDeep(get(ext, `view.${action}.format`), get(ext, 'common.format', {}))
|
|
18
17
|
const card = get(ext, `view.${action}.card`, get(ext, 'common.card', true))
|
|
@@ -31,7 +30,6 @@ function getCommons (action, schema, ext, options = {}) {
|
|
|
31
30
|
set(schema, 'view.calcFields', calcFields)
|
|
32
31
|
set(schema, 'view.noEscape', noEscape)
|
|
33
32
|
set(schema, 'view.widget', widget)
|
|
34
|
-
set(schema, 'view.formatValue', formatValue)
|
|
35
33
|
set(schema, 'view.formatCell', formatCell)
|
|
36
34
|
set(schema, 'view.format', merge({}, defFormatter, format))
|
|
37
35
|
set(schema, 'view.stat.aggregate', aggregate)
|
package/lib/util.js
CHANGED
|
@@ -38,7 +38,7 @@ export async function prepCrud ({ model, id, req, reply, transaction, options =
|
|
|
38
38
|
|
|
39
39
|
const recId = id ?? params.id ?? req.query.id
|
|
40
40
|
let mdl = model
|
|
41
|
-
if (isString(model)) {
|
|
41
|
+
if (!model || isString(model)) {
|
|
42
42
|
model = model ?? pascalCase(params.model)
|
|
43
43
|
mdl = this.app.dobo.getModel(model)
|
|
44
44
|
}
|
|
@@ -59,7 +59,7 @@ export async function getOneRecord (model, id, filter, options) {
|
|
|
59
59
|
const { cloneDeep, pick, isEmpty } = this.app.lib._
|
|
60
60
|
let query = cloneDeep(filter.query || {})
|
|
61
61
|
query = { $and: [query, { id }] }
|
|
62
|
-
const opts = pick(options, ['forceNoHidden', 'trx', 'req', 'refs', '
|
|
62
|
+
const opts = pick(options, ['forceNoHidden', 'trx', 'req', 'refs', 'fmt'])
|
|
63
63
|
opts.dataOnly = false
|
|
64
64
|
const data = await model.findOneRecord({ query }, opts)
|
|
65
65
|
if (isEmpty(data.data) && options.throwNotFound) throw this.error('_notFound')
|
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-04-25
|
|
4
|
+
|
|
5
|
+
- [2.18.0] Change options to format value using the new key set by dobo
|
|
6
|
+
- [2.18.0] Remove ```options.retainOriginalValue``` since it is not needed anymore
|
|
7
|
+
- [2.18.0] Add all necessary ```options``` for all auto generated api endpoints
|
|
8
|
+
|
|
3
9
|
## 2026-04-23
|
|
4
10
|
|
|
5
11
|
- [2.17.2] Bug fix in ```getSchemaExt()```
|