waibu-db 1.1.11 → 1.1.13
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/lib/crud/list-handler.js
CHANGED
|
@@ -3,7 +3,7 @@ async function listHandler ({ req, reply, model, template, params = {}, addOnsHa
|
|
|
3
3
|
const { recordFind, getSchemaExt } = this.app.waibuDb
|
|
4
4
|
const { get, merge, isArray, upperFirst } = this.lib._
|
|
5
5
|
const qsKey = this.app.waibu.config.qsKey
|
|
6
|
-
const options = { count: true }
|
|
6
|
+
const options = { count: true, rels: '*' }
|
|
7
7
|
model = model ?? pascalCase(req.params.model)
|
|
8
8
|
const { schema } = await getSchemaExt(model, 'list', { params })
|
|
9
9
|
if (schema.disabled.includes('find')) return reply.view(templateDisabled, { action: 'list' })
|
package/package.json
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
async function formatRow ({ data, req, component, schema, options = {} }) {
|
|
2
|
+
const { get, find, isFunction, cloneDeep } = this.lib._
|
|
3
|
+
const { format, callHandler } = this.app.bajo
|
|
4
|
+
const fields = get(schema, 'view.fields', Object.keys(schema.properties))
|
|
5
|
+
const rec = cloneDeep(data)
|
|
6
|
+
for (const f of fields) {
|
|
7
|
+
if (f === '_rel') continue
|
|
8
|
+
let prop = find(schema.properties, { name: f })
|
|
9
|
+
if (!prop) prop = find(schema.view.calcFields, { name: f })
|
|
10
|
+
if (!prop) continue
|
|
11
|
+
const opts = {
|
|
12
|
+
lang: options.lang ?? (req ? req.lang : undefined),
|
|
13
|
+
longitude: ['lng', 'longitude'].includes(f),
|
|
14
|
+
latitude: ['lat', 'latitude'].includes(f),
|
|
15
|
+
speed: ['speed'].includes(f),
|
|
16
|
+
degree: ['course', 'heading'].includes(f),
|
|
17
|
+
distance: ['distance'].includes(f)
|
|
18
|
+
}
|
|
19
|
+
rec[f] = format(data[f], prop.type, opts)
|
|
20
|
+
const vf = get(schema, `view.valueFormatter.${f}`)
|
|
21
|
+
if (vf) {
|
|
22
|
+
if (isFunction(vf)) rec[f] = await vf.call(req ?? this, data[f], data)
|
|
23
|
+
else rec[f] = await callHandler(vf, req, data[f], data)
|
|
24
|
+
}
|
|
25
|
+
const formatter = get(schema, `view.formatter.${f}`)
|
|
26
|
+
if (formatter && component) {
|
|
27
|
+
if (isFunction(formatter)) rec[f] = await formatter.call(req ?? this, data[f], data)
|
|
28
|
+
else rec[f] = await callHandler(formatter, req, data[f], data)
|
|
29
|
+
rec[f] = await component.buildSentence(rec[f])
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return rec
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function formatRecord ({ data, req, schema, component, options = {} }) {
|
|
36
|
+
const { isArray } = this.lib._
|
|
37
|
+
if (!isArray(data)) return await formatRow.call(this, { data, req, schema, component, options })
|
|
38
|
+
const items = []
|
|
39
|
+
for (const d of data) {
|
|
40
|
+
const item = await formatRow.call(this, { data: d, req, schema, component, options })
|
|
41
|
+
items.push(item)
|
|
42
|
+
}
|
|
43
|
+
return items
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default formatRecord
|
|
@@ -2,8 +2,14 @@ import path from 'path'
|
|
|
2
2
|
|
|
3
3
|
const defReadonly = ['id', 'createdAt', 'updatedAt']
|
|
4
4
|
|
|
5
|
+
const defFormatter = {}
|
|
6
|
+
|
|
5
7
|
function getCommons (action, schema, ext, opts = {}) {
|
|
6
|
-
const { map, get, set, without, uniq } = this.lib._
|
|
8
|
+
const { merge, map, get, set, without, uniq } = this.lib._
|
|
9
|
+
const calcFields = get(ext, `view.${action}.calcFields`, get(ext, 'common.calcFields', []))
|
|
10
|
+
const noEscape = get(ext, `view.${action}.noEscape`, get(ext, 'common.noEscape', []))
|
|
11
|
+
const valueFormatter = get(ext, `view.${action}.valueFormatter`, get(ext, 'common.valueFormatter', {}))
|
|
12
|
+
const formatter = get(ext, `view.${action}.formatter`, get(ext, 'common.formatter', {}))
|
|
7
13
|
const label = get(ext, `view.${action}.label`, get(ext, 'common.label', {}))
|
|
8
14
|
const card = get(ext, `view.${action}.card`, get(ext, 'common.card', true))
|
|
9
15
|
const hidden = get(ext, `view.${action}.hidden`, get(ext, 'common.hidden', []))
|
|
@@ -13,15 +19,20 @@ function getCommons (action, schema, ext, opts = {}) {
|
|
|
13
19
|
hidden.push(...schema.hidden, ...(opts.hidden ?? []))
|
|
14
20
|
const allFields = without(map(schema.properties, 'name'), ...hidden)
|
|
15
21
|
const forFields = get(ext, `view.${action}.fields`, get(ext, 'common.fields', allFields))
|
|
22
|
+
set(schema, 'view.calcFields', calcFields)
|
|
23
|
+
set(schema, 'view.noEscape', noEscape)
|
|
24
|
+
set(schema, 'view.valueFormatter', valueFormatter)
|
|
25
|
+
set(schema, 'view.formatter', merge({}, defFormatter, formatter))
|
|
16
26
|
set(schema, 'view.stat.aggregate', aggregate)
|
|
17
27
|
set(schema, 'view.disabled', disabled)
|
|
18
28
|
set(schema, 'view.x', x)
|
|
19
29
|
if (schema.disabled.length > 0) schema.view.disabled.push(...schema.disabled)
|
|
20
30
|
let fields = []
|
|
21
31
|
for (const f of forFields) {
|
|
22
|
-
if (allFields.includes(f)) fields.push(f)
|
|
32
|
+
if (allFields.includes(f) || map(calcFields, 'name').includes(f)) fields.push(f)
|
|
23
33
|
}
|
|
24
34
|
fields = uniq(without(fields, ...hidden))
|
|
35
|
+
|
|
25
36
|
if (action !== 'add' && !fields.includes('id')) fields.unshift('id')
|
|
26
37
|
let noWrap = get(ext, `view.${action}.noWrap`, get(ext, 'common.noWrap', true))
|
|
27
38
|
if (noWrap === true) noWrap = fields
|
|
@@ -21,15 +21,17 @@ async function table () {
|
|
|
21
21
|
|
|
22
22
|
build = async () => {
|
|
23
23
|
const { req } = this.component
|
|
24
|
-
const { callHandler } = this.plugin.app.bajo
|
|
25
24
|
const { escape } = this.plugin.app.waibu
|
|
25
|
+
const { formatRecord } = this.plugin.app.waibuDb
|
|
26
26
|
const { attrToArray, groupAttrs } = this.plugin.app.waibuMpa
|
|
27
|
-
const { get, omit, set, find, isEmpty, without,
|
|
27
|
+
const { get, omit, set, find, isEmpty, without, merge } = this.plugin.app.bajo.lib._
|
|
28
28
|
const group = groupAttrs(this.params.attr, ['body', 'head', 'foot'])
|
|
29
29
|
this.params.attr = group._
|
|
30
30
|
const prettyUrl = this.params.attr.prettyUrl
|
|
31
31
|
|
|
32
|
+
const schema = get(this, 'component.locals.schema', {})
|
|
32
33
|
const data = get(this, 'component.locals.list.data', [])
|
|
34
|
+
const fdata = await formatRecord.call(this.plugin, { data, req, schema, component: this.component })
|
|
33
35
|
const filter = get(this, 'component.locals.list.filter', {})
|
|
34
36
|
const count = get(this, 'component.locals.list.count', 0)
|
|
35
37
|
if (count === 0) {
|
|
@@ -38,7 +40,6 @@ async function table () {
|
|
|
38
40
|
this.params.html = await this.component.buildSentence(alert)
|
|
39
41
|
return
|
|
40
42
|
}
|
|
41
|
-
const schema = get(this, 'component.locals.schema', {})
|
|
42
43
|
const disableds = get(schema, 'view.disabled', [])
|
|
43
44
|
if (disableds.includes('find')) {
|
|
44
45
|
this.params.html = ''
|
|
@@ -112,7 +113,9 @@ async function table () {
|
|
|
112
113
|
html.push(await this.component.buildTag({ tag: 'thead', attr: group.head, html: header }))
|
|
113
114
|
// body
|
|
114
115
|
items = []
|
|
115
|
-
for (const
|
|
116
|
+
for (const idx in data) {
|
|
117
|
+
const d = data[idx]
|
|
118
|
+
const fd = fdata[idx]
|
|
116
119
|
const lines = []
|
|
117
120
|
if (selection) {
|
|
118
121
|
const tag = selection === 'single' ? 'formRadio' : 'formCheck'
|
|
@@ -126,41 +129,29 @@ async function table () {
|
|
|
126
129
|
let prop = find(schema.properties, { name: f })
|
|
127
130
|
if (!prop) prop = find(schema.view.calcFields, { name: f })
|
|
128
131
|
if (!prop) continue
|
|
129
|
-
const opts = {}
|
|
130
|
-
if (f === 'lng') opts.longitude = true
|
|
131
|
-
else if (f === 'lat') opts.latitude = true
|
|
132
|
-
let value = req.format(d[f], prop.type, opts)
|
|
133
|
-
if (prop.type === 'boolean') {
|
|
134
|
-
value = (await this.component.buildTag({ tag: 'icon', attr: { name: `circle${d[f] ? 'Check' : ''}` } })) +
|
|
135
|
-
' ' + (req.t(d[f] ? 'Yes' : 'No'))
|
|
136
|
-
} else value = escape(value)
|
|
137
132
|
let dataValue = d[f] ?? ''
|
|
138
133
|
if (['datetime'].includes(prop.type)) dataValue = escape(dataValue.toISOString())
|
|
139
134
|
if (['string', 'text'].includes(prop.type)) dataValue = escape(dataValue)
|
|
140
135
|
if (['array', 'object'].includes(prop.type)) dataValue = escape(JSON.stringify(d[f]))
|
|
141
|
-
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
136
|
+
let value = fd[f]
|
|
137
|
+
if (prop.type === 'boolean') {
|
|
138
|
+
value = (await this.component.buildTag({ tag: 'icon', attr: { name: `circle${d[f] ? 'Check' : ''}` } })) +
|
|
139
|
+
' ' + (req.t(d[f] ? 'Yes' : 'No'))
|
|
140
|
+
} else {
|
|
141
|
+
if (!get(schema, 'view.noEscape', []).includes(f)) value = escape(value)
|
|
145
142
|
}
|
|
146
143
|
const attr = { dataValue, dataKey: prop.name, dataType: prop.type }
|
|
147
144
|
if (!disableds.includes('get')) attr.style = { cursor: 'pointer' }
|
|
148
145
|
const cellFormatter = get(schema, `view.cellFormatter.${f}`)
|
|
149
|
-
if (cellFormatter) merge(attr, await cellFormatter(dataValue, d))
|
|
146
|
+
if (cellFormatter) merge(attr, await cellFormatter.call(req, dataValue, d))
|
|
150
147
|
const noWrap = this.isNoWrap(f, schema, group.body.nowrap) ? 'nowrap' : ''
|
|
151
148
|
if (this.isRightAligned(f, schema)) attr.text = `align:end ${noWrap}`
|
|
152
149
|
else attr.text = noWrap
|
|
153
150
|
const lookup = get(schema, `view.lookup.${f}`)
|
|
154
151
|
if (lookup) {
|
|
155
|
-
const item = find(lookup.values, set({}, lookup.id ?? 'id',
|
|
152
|
+
const item = find(lookup.values, set({}, lookup.id ?? 'id', d[f]))
|
|
156
153
|
if (item) value = req.t(item[lookup.field ?? 'name'])
|
|
157
154
|
}
|
|
158
|
-
const formatter = get(schema, `view.formatter.${f}`)
|
|
159
|
-
if (formatter) {
|
|
160
|
-
if (isFunction(formatter)) value = await formatter(dataValue, d)
|
|
161
|
-
else value = await callHandler(formatter, req, dataValue, d)
|
|
162
|
-
value = await this.component.buildSentence(value)
|
|
163
|
-
}
|
|
164
155
|
const line = await this.component.buildTag({ tag: 'td', attr, html: value })
|
|
165
156
|
lines.push(line)
|
|
166
157
|
}
|