waibu-db 2.8.1 → 2.9.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/not-found.html +1 -0
- package/extend/bajoTemplate/template/crud/not-found.html +2 -0
- package/extend/waibuBootstrap/theme/component/widget/btn-columns.js +1 -8
- package/extend/waibuBootstrap/theme/component/widget/table.js +1 -1
- package/lib/crud/all-handler.js +1 -2
- package/lib/crud/details-handler.js +3 -2
- package/lib/crud/edit-handler.js +2 -1
- package/lib/crud/{helper/add-ons-handler.js → helper.js} +66 -47
- package/lib/method/get-schema-ext.js +1 -1
- package/lib/util.js +1 -1
- package/package.json +1 -1
- package/wiki/CHANGES.md +8 -0
- package/lib/crud/helper/attachment-handler.js +0 -7
- package/lib/crud/helper/build-params.js +0 -14
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<c:alert color="warning" t:content="noRecordFound" margin="top-4"/>
|
|
@@ -17,21 +17,14 @@ async function btnColumns () {
|
|
|
17
17
|
return
|
|
18
18
|
}
|
|
19
19
|
let fields = without(get(this, `component.locals._meta.query.${qsKey.fields}`, '').split(','), '')
|
|
20
|
-
if (isEmpty(fields)) fields = schema.view.fields
|
|
20
|
+
if (isEmpty(fields)) fields = without(schema.view.fields, 'id')
|
|
21
21
|
const items = []
|
|
22
22
|
this.params.attr.color = this.params.attr.color ?? 'secondary-outline'
|
|
23
23
|
if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('columns')
|
|
24
24
|
for (const f of schema.view.fields) {
|
|
25
|
-
if (!fields.includes(f)) continue
|
|
26
25
|
let prop = find(schema.properties, { name: f })
|
|
27
26
|
if (!prop) prop = find(schema.view.calcFields, { name: f })
|
|
28
27
|
if (!prop) continue
|
|
29
|
-
/*
|
|
30
|
-
if (f === 'id') {
|
|
31
|
-
items.push(await this.component.buildTag({ tag: 'formCheck', attr: { checked: true, label: req.t('ID'), value: f, disabled: true } }))
|
|
32
|
-
continue
|
|
33
|
-
}
|
|
34
|
-
*/
|
|
35
28
|
const attr = { 'x-model': 'selected', label: req.t(get(schema, `view.label.${f}`, `field.${f}`)), value: f }
|
|
36
29
|
if (fields.includes(f)) attr.checked = true
|
|
37
30
|
items.push(await this.component.buildTag({ tag: 'formCheck', attr }))
|
|
@@ -74,7 +74,7 @@ async function table () {
|
|
|
74
74
|
}
|
|
75
75
|
const qsKey = this.app.waibu.config.qsKey
|
|
76
76
|
let fields = without(get(this, `component.locals._meta.query.${qsKey.fields}`, '').split(','), '')
|
|
77
|
-
if (isEmpty(fields)) fields = schema.view.fields
|
|
77
|
+
if (isEmpty(fields)) fields = without(schema.view.fields, 'id')
|
|
78
78
|
let sort = this.params.attr.sort ? attrToArray(this.params.attr.sort) : get(this, `component.locals._meta.query.${qsKey.sort}`, '')
|
|
79
79
|
if (isEmpty(sort) && filter.sort) {
|
|
80
80
|
const keys = Object.keys(filter.sort)
|
package/lib/crud/all-handler.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import attachmentHandler from './helper
|
|
1
|
+
import { attachmentHandler, notFoundTpl } from './helper.js'
|
|
2
2
|
|
|
3
3
|
async function detailsHandler ({ req, reply, model, params = {}, id, template, addOnsHandler, templateDisabled = 'waibuDb.template:/disabled.html', options = {} } = {}) {
|
|
4
4
|
const { pascalCase } = this.app.lib.aneka
|
|
5
5
|
const { getRecord, getSchemaExt } = this.app.waibuDb
|
|
6
|
-
const { merge } = this.app.lib._
|
|
6
|
+
const { merge, isEmpty } = this.app.lib._
|
|
7
7
|
const opts = merge({ refs: '*' }, options.modelOpts)
|
|
8
8
|
model = pascalCase(model ?? req.params.model)
|
|
9
9
|
const { schema } = await getSchemaExt(model, 'details', merge({}, { params }, options))
|
|
@@ -13,6 +13,7 @@ async function detailsHandler ({ req, reply, model, params = {}, id, template, a
|
|
|
13
13
|
id = id ?? req.params.id ?? req.query.id
|
|
14
14
|
delete req.query.query
|
|
15
15
|
const resp = await getRecord({ model, req, id, options: opts })
|
|
16
|
+
if (isEmpty(resp.data)) return await reply.view(notFoundTpl, params)
|
|
16
17
|
const form = resp.data
|
|
17
18
|
const addOns = addOnsHandler ? await addOnsHandler.call(this.app[req.ns], { req, reply, params, data: resp, schema, options }) : undefined
|
|
18
19
|
const attachments = await attachmentHandler.call(this, { schema, id, options })
|
package/lib/crud/edit-handler.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import attachmentHandler from './helper
|
|
1
|
+
import { attachmentHandler, notFoundTpl } from './helper.js'
|
|
2
2
|
|
|
3
3
|
async function editHandler ({ req, reply, model, id, params = {}, template, addOnsHandler, templateDisabled = 'waibuDb.template:/disabled.html', options = {} } = {}) {
|
|
4
4
|
const { pascalCase } = this.app.lib.aneka
|
|
@@ -20,6 +20,7 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
|
|
|
20
20
|
id = id ?? req.params.id ?? req.query.id
|
|
21
21
|
delete req.query.query
|
|
22
22
|
const old = await getRecord({ model, req, id, options: opts })
|
|
23
|
+
if (isEmpty(old.data)) return await reply.view(notFoundTpl, params)
|
|
23
24
|
form = defaultsDeep(req.body, old.data)
|
|
24
25
|
if (req.method !== 'GET') {
|
|
25
26
|
form = omit(form, ['_action', '_value'])
|
|
@@ -1,47 +1,66 @@
|
|
|
1
|
-
async function addOnsHandler ({ req, reply, data, schema, options = {} }) {
|
|
2
|
-
const { escape } = this.app.waibu
|
|
3
|
-
const { base64JsonEncode } = this.app.waibu
|
|
4
|
-
const { createAggregate } = this.app.waibuDb
|
|
5
|
-
const { get, map, pick, pullAt } = this.app.lib._
|
|
6
|
-
const opts = map(get(schema, 'view.stat.aggregate', []), item => {
|
|
7
|
-
const dbOpts = pick(item, ['fields', 'group', 'aggregate'])
|
|
8
|
-
const name = item.name ?? `field.${item.fields[0]}`
|
|
9
|
-
return { name, dbOpts }
|
|
10
|
-
})
|
|
11
|
-
if (opts.length === 0) return []
|
|
12
|
-
const dropped = []
|
|
13
|
-
for (const idx in opts) {
|
|
14
|
-
const o = opts[idx]
|
|
15
|
-
try {
|
|
16
|
-
const resp = await createAggregate({ model: schema.name, req, reply, options: o.dbOpts })
|
|
17
|
-
const data = []
|
|
18
|
-
for (const d of resp.data) {
|
|
19
|
-
const key = o.dbOpts.fields[0]
|
|
20
|
-
data.push({
|
|
21
|
-
name: escape(d[key]),
|
|
22
|
-
value: d[key + 'Count']
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
opts[idx].chartOpts = base64JsonEncode({
|
|
26
|
-
tooltip: {
|
|
27
|
-
trigger: 'item'
|
|
28
|
-
},
|
|
29
|
-
series: [{
|
|
30
|
-
type: 'pie',
|
|
31
|
-
data
|
|
32
|
-
}]
|
|
33
|
-
})
|
|
34
|
-
} catch (err) {
|
|
35
|
-
dropped.push(idx)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (dropped.length > 0) pullAt(opts, dropped)
|
|
39
|
-
return map(opts, o => {
|
|
40
|
-
return {
|
|
41
|
-
data: { setting: o.chartOpts, name: o.name },
|
|
42
|
-
resource: 'waibuDb.partial:/crud/~echarts-window.html'
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export
|
|
1
|
+
export async function addOnsHandler ({ req, reply, data, schema, options = {} }) {
|
|
2
|
+
const { escape } = this.app.waibu
|
|
3
|
+
const { base64JsonEncode } = this.app.waibu
|
|
4
|
+
const { createAggregate } = this.app.waibuDb
|
|
5
|
+
const { get, map, pick, pullAt } = this.app.lib._
|
|
6
|
+
const opts = map(get(schema, 'view.stat.aggregate', []), item => {
|
|
7
|
+
const dbOpts = pick(item, ['fields', 'group', 'aggregate'])
|
|
8
|
+
const name = item.name ?? `field.${item.fields[0]}`
|
|
9
|
+
return { name, dbOpts }
|
|
10
|
+
})
|
|
11
|
+
if (opts.length === 0) return []
|
|
12
|
+
const dropped = []
|
|
13
|
+
for (const idx in opts) {
|
|
14
|
+
const o = opts[idx]
|
|
15
|
+
try {
|
|
16
|
+
const resp = await createAggregate({ model: schema.name, req, reply, options: o.dbOpts })
|
|
17
|
+
const data = []
|
|
18
|
+
for (const d of resp.data) {
|
|
19
|
+
const key = o.dbOpts.fields[0]
|
|
20
|
+
data.push({
|
|
21
|
+
name: escape(d[key]),
|
|
22
|
+
value: d[key + 'Count']
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
opts[idx].chartOpts = base64JsonEncode({
|
|
26
|
+
tooltip: {
|
|
27
|
+
trigger: 'item'
|
|
28
|
+
},
|
|
29
|
+
series: [{
|
|
30
|
+
type: 'pie',
|
|
31
|
+
data
|
|
32
|
+
}]
|
|
33
|
+
})
|
|
34
|
+
} catch (err) {
|
|
35
|
+
dropped.push(idx)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (dropped.length > 0) pullAt(opts, dropped)
|
|
39
|
+
return map(opts, o => {
|
|
40
|
+
return {
|
|
41
|
+
data: { setting: o.chartOpts, name: o.name },
|
|
42
|
+
resource: 'waibuDb.partial:/crud/~echarts-window.html'
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function attachmentHandler ({ schema, id, options = {} }) {
|
|
48
|
+
if (!schema.view.attachment) return []
|
|
49
|
+
const model = this.app.dobo.getModel(schema.name)
|
|
50
|
+
return await model.listAttachment({ id })
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function buildParams ({ model, req, reply, action, options = {} }) {
|
|
54
|
+
const { camelCase, kebabCase, map, upperFirst, get } = this.app.lib._
|
|
55
|
+
const [, ...names] = map(kebabCase(model).split('-'), n => upperFirst(n))
|
|
56
|
+
const mdl = this.app.dobo.getModel(model)
|
|
57
|
+
const prefix = this.app.waibuMpa ? this.app.waibuMpa.getPluginTitle(mdl.plugin.ns, req) : mdl.plugin.ns
|
|
58
|
+
const modelTitle = req.t(prefix) + ': ' + req.t(camelCase(names.join(' ')))
|
|
59
|
+
const page = {
|
|
60
|
+
title: req.t(get(req, 'routeOptions.config.title', this.app[mdl.plugin.ns].title)),
|
|
61
|
+
modelTitle
|
|
62
|
+
}
|
|
63
|
+
return { page }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const notFoundTpl = 'waibuDb.template:/crud/not-found.html'
|
|
@@ -175,7 +175,7 @@ async function getSchemaExt (modelName, view, options = {}) {
|
|
|
175
175
|
|
|
176
176
|
const model = isString(modelName) ? this.app.dobo.getModel(modelName) : modelName
|
|
177
177
|
const schema = pick(model, ['name', 'properties', 'indexes', 'disabled', 'attachment', 'sortables', 'view', 'hidden'])
|
|
178
|
-
const base = path.basename(model.file, path.extname(model.file))
|
|
178
|
+
const base = options.base ?? path.basename(model.file, path.extname(model.file))
|
|
179
179
|
let ext = await readConfig(`${model.plugin.ns}:/extend/waibuDb/schema/${base}.*`, { ignoreError: true, options })
|
|
180
180
|
const over = await readConfig(`main:/extend/waibuDb/extend/${model.plugin.ns}/schema/${base}.*`, { ignoreError: true, options })
|
|
181
181
|
ext = defaultsDeep(options.schema ?? {}, over, ext)
|
package/lib/util.js
CHANGED
|
@@ -57,7 +57,7 @@ export async function getOneRecord (model, id, filter, options) {
|
|
|
57
57
|
const { cloneDeep } = this.app.lib._
|
|
58
58
|
let query = cloneDeep(filter.query || {})
|
|
59
59
|
query = { $and: [query, { id }] }
|
|
60
|
-
const data = await model.findOneRecord({ query }, { dataOnly: true,
|
|
60
|
+
const data = await model.findOneRecord({ query }, { dataOnly: true, forceNoHidden: options.forceNoHidden, trx: options.trx, req: options.req })
|
|
61
61
|
if (!data && options.throwNotFound) throw this.error('_notFound')
|
|
62
62
|
return data
|
|
63
63
|
}
|
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-03-15
|
|
4
|
+
|
|
5
|
+
- [2.9.0] Add ability to overwrite ```base``` through ```options```
|
|
6
|
+
- [2.9.0] Bug fix in ```wdb-btn-columns``` widget
|
|
7
|
+
- [2.9.0] Bug fix in ```wdb-table``` widget
|
|
8
|
+
|
|
3
9
|
## 2026-03-08
|
|
4
10
|
|
|
5
11
|
- [2.8.1] Bug fix in ```build-params.js```
|
|
12
|
+
- [2.8.2] Bug fixes for record not found
|
|
13
|
+
- [2.8.3] Compine all helpers into one single file ```helper.js```
|
|
6
14
|
|
|
7
15
|
## 2026-03-05
|
|
8
16
|
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
function buildParams ({ model, req, reply, action, options = {} }) {
|
|
2
|
-
const { camelCase, kebabCase, map, upperFirst, get } = this.app.lib._
|
|
3
|
-
const [, ...names] = map(kebabCase(model).split('-'), n => upperFirst(n))
|
|
4
|
-
const mdl = this.app.dobo.getModel(model)
|
|
5
|
-
const prefix = this.app.waibuMpa ? this.app.waibuMpa.getPluginTitle(mdl.plugin.ns, req) : mdl.plugin.ns
|
|
6
|
-
const modelTitle = req.t(prefix) + ': ' + req.t(camelCase(names.join(' ')))
|
|
7
|
-
const page = {
|
|
8
|
-
title: req.t(get(req, 'routeOptions.config.title', this.app[mdl.plugin.ns].title)),
|
|
9
|
-
modelTitle
|
|
10
|
-
}
|
|
11
|
-
return { page }
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default buildParams
|