waibu-db 2.6.0 → 2.7.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.
@@ -36,6 +36,7 @@
36
36
  "exportInQueue": "Data export in queue. Please check your download list for progress",
37
37
  "tsv": "TSV",
38
38
  "ndjson": "NDJSON",
39
+ "dataValue": "Data value",
39
40
  "op": {
40
41
  "equals": "Equals",
41
42
  "notEquals": "Not Equals",
@@ -36,6 +36,7 @@
36
36
  "exportInQueue": "Ekspor data sedang dalam antrian. Silahkan cek daftar unduh Anda untuk perkembangan terakhir",
37
37
  "tsv": "TSV",
38
38
  "ndjson": "NDJSON",
39
+ "dataValue": "Nilai data",
39
40
  "op": {
40
41
  "equals": "Sama Dengan",
41
42
  "notEquals": "Tidak Sama Dengan",
@@ -26,10 +26,12 @@ async function btnColumns () {
26
26
  let prop = find(schema.properties, { name: f })
27
27
  if (!prop) prop = find(schema.view.calcFields, { name: f })
28
28
  if (!prop) continue
29
+ /*
29
30
  if (f === 'id') {
30
31
  items.push(await this.component.buildTag({ tag: 'formCheck', attr: { checked: true, label: req.t('ID'), value: f, disabled: true } }))
31
32
  continue
32
33
  }
34
+ */
33
35
  const attr = { 'x-model': 'selected', label: req.t(get(schema, `view.label.${f}`, `field.${f}`)), value: f }
34
36
  if (fields.includes(f)) attr.checked = true
35
37
  items.push(await this.component.buildTag({ tag: 'formCheck', attr }))
@@ -47,8 +47,8 @@ async function btnDelete () {
47
47
  ok: '${this.params.attr.id}:remove',
48
48
  close: 'y',
49
49
  opts: selected,
50
- theme: '${this.component.theme.name}',
51
- iconset: '${this.component.iconset.name}'
50
+ theme: '${get(this, 'component.theme.name', 'default')}',
51
+ iconset: '${get(this, 'component.iconset.name', 'default')}'
52
52
  })
53
53
  `
54
54
  this.params.html = await this.component.buildTag({ tag: 'btn', attr: this.params.attr, html: this.params.html })
@@ -4,6 +4,8 @@ async function table () {
4
4
  const WdbBase = await wdbBase.call(this)
5
5
 
6
6
  return class WdbTable extends WdbBase {
7
+ propValues = {}
8
+
7
9
  isRightAligned = (field, schema) => {
8
10
  const { get, find } = this.app.lib._
9
11
  const prop = find(schema.properties, { name: field })
@@ -20,13 +22,19 @@ async function table () {
20
22
  }
21
23
 
22
24
  _defFormatter = async ({ req, key, value, data, schema }) => {
23
- const { get, find } = this.app.lib._
25
+ const { get, find, camelCase, isEmpty } = this.app.lib._
24
26
  const { escape } = this.app.waibu
25
27
  const prop = find(schema.properties, { name: key })
26
28
  if (!prop) return value
27
29
  if (prop.type === 'boolean') {
28
30
  value = (await this.component.buildTag({ tag: 'icon', attr: { name: `circle${data[key] ? 'Check' : 'Cross'}` } })) +
29
31
  ' ' + (req.t(data[key] ? 'Yes' : 'No'))
32
+ } else if (prop.values) {
33
+ const values = typeof prop.values === 'string' ? this.propValues[key] : prop.values
34
+ const item = find(values, { value }) ?? {}
35
+ const ttext = camelCase(`${prop.name} ${item.text}`)
36
+ value = escape(req.format(!isEmpty(item) ? (req.te(ttext) ? req.t(ttext) : item.text) : value, prop.type))
37
+ if (item) value += ` <sup><a href="#" title="${req.t('dataValue')}: ${data[key]}">*</a></sup>`
30
38
  } else if (['string', 'text'].includes(prop.type)) {
31
39
  if (!get(schema, 'view.noEscape', []).includes(key)) value = escape(value)
32
40
  }
@@ -34,6 +42,7 @@ async function table () {
34
42
  }
35
43
 
36
44
  build = async () => {
45
+ const { callHandler } = this.app.bajo
37
46
  const { req } = this.component
38
47
  const { escape, attrToArray } = this.app.waibu
39
48
  const { formatRecord } = this.app.waibuDb
@@ -48,6 +57,10 @@ async function table () {
48
57
  const fdata = await formatRecord.call(this.plugin, { data, req, schema })
49
58
  const filter = get(this, 'component.locals.list.filter', {})
50
59
  const count = get(this, 'component.locals.list.count', 0)
60
+ // collect prop.values for later use
61
+ for (const prop of schema.properties) {
62
+ if (typeof prop.values === 'string') this.propValues[prop.name] = await callHandler(prop.values)
63
+ }
51
64
  if (count === 0) {
52
65
  const alert = '<c:alert color="warning" t:content="noRecordFound" margin="top-4"/>'
53
66
  this.params.noTag = true
@@ -100,7 +100,6 @@ function applyLayout (action, schema, ext) {
100
100
  if (!prop) continue
101
101
  const result = schema.view.widget[f] ?? {}
102
102
  result.name = result.name ?? f
103
- result.component = result.component ?? 'form-input'
104
103
  result.attr = defaultsDeep(result.attr, { col: '4-md', label: `field.${f}` })
105
104
  if (['array', 'object', 'text'].includes(prop.type)) {
106
105
  result.attr.col = '12'
@@ -112,14 +111,16 @@ function applyLayout (action, schema, ext) {
112
111
  } else {
113
112
  if (prop.type === 'boolean') {
114
113
  result.component = 'form-select'
115
- result.attr.options = 'false:no true:yes'
114
+ result.attr.options = 'false:no;true:yes'
116
115
  }
117
116
  if (prop.values) {
118
- result.component = 'form-select'
119
- result.attr.options = prop.values.map(item => `${item.value}:${item.text}`).join(' ')
117
+ result.component = result.component ?? 'form-select'
118
+ if (typeof prop.values === 'string') result.attr.options = prop.values
119
+ else result.attr.options = prop.values.map(item => `${item.value}:${item.text}`).join(';')
120
120
  }
121
121
  if (['string', 'text'].includes(prop.type) && prop.maxLength) set(result, 'attr.maxlength', prop.maxLength)
122
122
  if (readonly.includes(f)) result.component = 'form-plaintext'
123
+ if (!result.component) result.component = 'form-input'
123
124
  }
124
125
  for (const k in result.attr ?? {}) {
125
126
  const newKey = kebabCase(k)
package/lib/util.js CHANGED
@@ -1,9 +1,12 @@
1
1
  export async function prepCrud ({ model, body, id, req, reply, options = {}, args }) {
2
2
  const { isSet } = this.app.lib.aneka
3
+ const { importModule } = this.app.bajo
3
4
  const { parseFilter } = this.app.waibu
4
5
  const { pascalCase } = this.app.lib.aneka
5
6
  const { cloneDeep, has, isString } = this.app.lib._
6
7
  const { parseObject } = this.app.lib
8
+ const { buildFilterQuery } = await importModule('dobo:/lib/factory/model/_util.js', { asDefaultImport: false })
9
+
7
10
  const cfgWeb = this.app.waibu.getConfig()
8
11
  const opts = cloneDeep(options)
9
12
  const params = this.getParams(req, ...args)
@@ -37,7 +40,8 @@ export async function prepCrud ({ model, body, id, req, reply, options = {}, arg
37
40
 
38
41
  opts.bboxLatField = req.query[cfgWeb.qsKey.bboxLatField]
39
42
  opts.bboxLngField = req.query[cfgWeb.qsKey.bboxLngField]
40
- const filter = parseFilter(req)
43
+ let filter = parseFilter(req)
44
+ filter = buildFilterQuery.call(mdl, filter)
41
45
  if (options.query) filter.query = cloneDeep(options.query)
42
46
  if (options.limit) filter.limit = options.limit
43
47
  if (options.sort) filter.sort = options.sort
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu-db",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "DB Helper",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,9 +1,18 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-02-20
4
+
5
+ - [2.7.0] Update ```WdbBtnColumns``` to allow untick ID field too
6
+ - [2.7.0] Bug fix on theme & iconset resolver
7
+ - [2.7.0] Add capability to set value from ```prop.values``` in ```WdbTable```
8
+ - [2.7.0] Bug fix on query builder
9
+ - [2.7.0] Add capability to handle value from ```prop.values``` in ```getSchemaExt()```
10
+
3
11
  ## 2026-02-18
4
12
 
5
13
  - [2.6.0] Update attribute functions from ```waibu```
6
14
  - [2.6.0] Bug fix on ```getSchemaExt()```'s ```applyLayout()```
15
+ - [2.6.1] Bug fix on ```getSchemaExt()```
7
16
 
8
17
  ## 2026-02-15
9
18