waibu-db 2.18.3 → 2.19.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.
@@ -1,4 +1,4 @@
1
- <% if (schema && schema.attachment) { %>
1
+ <% if (schema && schema.options.attachment) { %>
2
2
  <c:fieldset <%= schema.view.card === false ? '' : 'card' %> t:legend="attachment" grid-gutter="3">
3
3
  <!-- include waibuDb.partial:/crud/_list-attachment.html|<%= JSON.stringify({ readonly: true }) %> -->
4
4
  </c:fieldset>
@@ -51,7 +51,7 @@ async function btnExport () {
51
51
  let item = {}
52
52
  const els = document.querySelectorAll(selector + ' [data-value]')
53
53
  for (const el of els) {
54
- const value = this.options.includes('fvalue') ? el.getAttribute('value') : wmpa.parseValue(el.dataset.value, el.dataset.type)
54
+ const value = this.options.includes('fvalue') ? el.innerText : wmpa.parseValue(el.dataset.value, el.dataset.type)
55
55
  let key = el.getAttribute('name')
56
56
  if (this.options.includes('fkey')) {
57
57
  try {
@@ -25,6 +25,7 @@ async function table () {
25
25
  const { groupAttrs } = this.app.waibuMpa
26
26
  const { isHtmlLink } = this.app.bajoExtra
27
27
  const { get, omit, set, find, isEmpty, without, merge } = this.app.lib._
28
+ const { isSet } = this.app.lib.aneka
28
29
  const group = groupAttrs(this.params.attr, ['body', 'head', 'foot'])
29
30
  this.params.attr = group._
30
31
  const prettyUrl = this.params.attr.prettyUrl
@@ -56,13 +57,15 @@ async function table () {
56
57
  let [sortCol, sortDir] = sort.split(':')
57
58
  if (!['-1', '1'].includes(sortDir)) sortDir = '1'
58
59
 
59
- let selection
60
- const canDelete = !disableds.includes('remove')
61
- const canEdit = !disableds.includes('update')
62
- const canDetails = !disableds.includes('get')
63
- if (canEdit || canDetails) selection = 'single'
64
- if (canDelete) selection = 'multi'
65
- if (selection) this.params.attr.hover = true
60
+ let selection = this.params.attr.selection
61
+ if (!isSet(selection)) {
62
+ const canDelete = !disableds.includes('remove')
63
+ const canEdit = !disableds.includes('update')
64
+ const canDetails = !disableds.includes('get')
65
+ if (canEdit || canDetails) selection = 'single'
66
+ if (canDelete) selection = 'multi'
67
+ if (selection) this.params.attr.hover = true
68
+ } else if (!['single', 'multi'].includes(selection)) selection = false
66
69
 
67
70
  this.params.noTag = true
68
71
  const html = []
@@ -128,10 +131,8 @@ async function table () {
128
131
  if (!prop) continue
129
132
  let dataValue = d[f]
130
133
  if (['datetime'].includes(prop.type) && dataValue instanceof Date && !isNaN(dataValue)) dataValue = escape(dataValue.toISOString())
131
- else if (['string', 'text'].includes(prop.type)) dataValue = escape(dataValue)
132
- else if (['array', 'object'].includes(prop.type)) dataValue = escape(JSON.stringify(dataValue))
133
- const refName = get(schema, `view.widget.${f}.attr.refName`)
134
- let value = this.getRefValue({ field: f, data: d, refName }) ?? get(d, `_fmt.${f}`, d[f])
134
+ else if (['string', 'text', 'array', 'object'].includes(prop.type)) dataValue = escape(dataValue)
135
+ let value = this.getRefValue({ field: f, data: d, refName: this.getRefName(f) }) ?? get(d, `_fmt.${f}`, d[f])
135
136
  const attr = { dataValue, dataKey: prop.name, dataType: prop.type }
136
137
  if (!disableds.includes('get')) attr.style = { cursor: 'pointer' }
137
138
  const formatCell = get(schema, `view.formatCell.${f}`)
@@ -20,7 +20,7 @@ async function form () {
20
20
  }
21
21
 
22
22
  build = async () => {
23
- const { get, find, filter, forOwn, isEmpty } = this.app.lib._
23
+ const { get, find, filter, forOwn, isEmpty, omit } = this.app.lib._
24
24
  const { base64JsonEncode } = this.app.waibu
25
25
  const body = []
26
26
  const xModels = get(this.schema, 'view.x.model', [])
@@ -40,7 +40,7 @@ async function form () {
40
40
  name: widget.name
41
41
  }
42
42
  if (xModels.includes(widget.name)) attr['x-model'] = widget.name
43
- forOwn(widget.attr, (v, k) => {
43
+ forOwn(omit(widget.attr, ['url', 'refUrl', 'refName']), (v, k) => {
44
44
  if (v === true) attr[k] = true
45
45
  else attr[k] = v
46
46
  })
@@ -5,7 +5,7 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
5
5
  const { updateRecord, getRecord, getSchemaExt } = this.app.waibuDb
6
6
  const { buildUrl } = this.app.waibuMpa
7
7
  const { defaultsDeep } = this.app.lib.aneka
8
- const { merge, isEmpty, omit, cloneDeep, isArray, isPlainObject } = this.app.lib._
8
+ const { merge, isEmpty, omit, cloneDeep } = this.app.lib._
9
9
  const opts = merge({}, options.modelOpts)
10
10
  let error
11
11
  let resp
@@ -22,9 +22,6 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
22
22
  if (isEmpty(old.data)) return await reply.view(notFoundTpl, params)
23
23
  opts._data = old
24
24
  const def = cloneDeep(old.data)
25
- for (const k in def) {
26
- if (isArray(def[k]) || isPlainObject(def[k])) def[k] = JSON.stringify(def[k])
27
- }
28
25
  form = defaultsDeep({}, req.body, def)
29
26
  if (req.method !== 'GET') {
30
27
  form = omit(form, ['_action', '_value'])
@@ -19,7 +19,7 @@ function getCommons (action, schema, ext, options = {}) {
19
19
  const x = defaultsDeep(get(ext, `view.${action}.x`), get(ext, 'common.x', {}))
20
20
  const aggregate = get(ext, `view.${action}.stat.aggregate`, get(ext, 'common.stat.aggregate', []))
21
21
  let attachment = get(ext, `view.${action}.attachment`, get(ext, 'common.attachment', schema.attachment))
22
- if (!schema.attachment || action === 'list') attachment = false
22
+ if (!schema.options.attachment || action === 'list') attachment = false
23
23
  hidden.push('siteId', ...schema.hidden, ...(options.hidden ?? []))
24
24
  hidden = uniq(hidden)
25
25
  pull(hidden, ...forceVisible)
@@ -97,16 +97,22 @@ function applyLayout (action, schema, ext) {
97
97
  const result = schema.view.widget[f] ?? {}
98
98
  result.name = result.name ?? f
99
99
  result.attr = defaultsDeep(result.attr, { col: '4-md', label: `field.${f}` })
100
- if (['array', 'object', 'text'].includes(prop.type)) {
100
+ const orgCol = result.attr.col
101
+ if (!prop.ref && ['array', 'object', 'text'].includes(prop.type)) {
101
102
  result.attr.col = '12'
102
103
  result.component = 'form-textarea'
103
104
  result.attr.rows = '3'
104
105
  }
105
106
  if (action === 'details') {
106
107
  result.component = 'form-plaintext'
108
+ result.attr.col = orgCol
107
109
  } else {
108
110
  if (prop.ref) {
109
111
  result.component = result.component ?? 'wdb-lookup-select'
112
+ if (prop.type === 'array') {
113
+ result.attr.multiple = true
114
+ result.attr.removeBtn = true
115
+ }
110
116
  }
111
117
  if (prop.type === 'boolean') {
112
118
  result.component = result.component ?? 'form-select'
@@ -115,6 +121,13 @@ function applyLayout (action, schema, ext) {
115
121
  if (prop.values) {
116
122
  const orgCmp = result.component
117
123
  result.component = orgCmp ?? 'form-select'
124
+ if (prop.type === 'array') {
125
+ result.component = 'form-select-ext'
126
+ result.attr.multiple = true
127
+ result.attr.col = orgCol
128
+ result.attr.removeBtn = true
129
+ delete result.attr.rows
130
+ }
118
131
  if (typeof prop.values === 'string') result.attr.options = prop.values
119
132
  else result.attr.options = prop.values.map(item => `${item.value}:${item.text}`).join(';')
120
133
  if (result.attr.options.split(';').length > 8 && !orgCmp) result.component = 'form-select-ext'
@@ -181,8 +194,9 @@ async function getSchemaExt (modelName, view, options = {}) {
181
194
 
182
195
  const model = isString(modelName) ? this.app.dobo.getModel(modelName) : modelName
183
196
  const ns = model.plugin.ns
184
- const schema = pick(model, ['name', 'properties', 'indexes', 'disabled', 'attachment', 'sortables', 'scanables', 'view', 'hidden', 'attachment'])
185
- const base = options.base ?? path.basename(model.file, path.extname(model.file))
197
+ const schema = pick(model, ['name', 'properties', 'indexes', 'disabled', 'sortables', 'scanables', 'view', 'hidden', 'options'])
198
+ schema.ns = ns
199
+ const base = options.base ?? path.basename(model.options.file, path.extname(model.options.file))
186
200
  const parserOpts = { args: options.args }
187
201
  let ext = await readConfig(`${ns}:/extend/waibuDb/schema/${base}.*`, { ns, baseNs: 'waibuDb', parserOpts })
188
202
  ext = defaultsDeep(options.schema ?? {}, ext)
package/lib/util.js CHANGED
@@ -11,6 +11,7 @@ export async function prepCrud ({ model, id, req, reply, transaction, options =
11
11
 
12
12
  const cfgWeb = this.app.waibu.getConfig()
13
13
  const opts = cloneDeep(omit(options, ['trx']))
14
+ opts.throwNotFound = true
14
15
  if (opts.suppressError === true) opts.suppressError = actions
15
16
  else if (isString(opts.suppressError)) opts.suppressError = [opts.suppressError]
16
17
  else opts.suppressError = opts.suppressError ?? []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu-db",
3
- "version": "2.18.3",
3
+ "version": "2.19.0",
4
4
  "description": "DB Helper",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,8 +1,14 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-05-11
4
+
5
+ - [2.19.0] Updates to match ```dobo@2.23.0``` specs
6
+ - [2.19.0] Bug fix in ```wdb-btn-export``` widget
7
+
3
8
  ## 2026-05-03
4
9
 
5
10
  - [2.18.3] Bug fix in ```wdb-data-table``` widget
11
+ - [2.18.4] Bug fix in ```wdb-data-table``` widget
6
12
 
7
13
  ## 2026-05-02
8
14