waibu-db 2.12.4 → 2.12.6
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/bajo/intl/en-US.json +15 -14
- package/extend/bajo/intl/id.json +15 -14
- package/extend/waibuBootstrap/theme/component/widget/btn-columns.js +1 -1
- package/extend/waibuBootstrap/theme/component/widget/pagination.js +2 -1
- package/extend/waibuBootstrap/theme/component/widget/query.js +45 -18
- package/extend/waibuBootstrap/theme/component/widget/recs-info.js +2 -1
- package/extend/waibuBootstrap/theme/component/widget/table.js +1 -1
- package/lib/crud/edit-handler.js +3 -0
- package/package.json +1 -1
- package/wiki/CHANGES.md +13 -0
|
@@ -39,19 +39,20 @@
|
|
|
39
39
|
"dataValue": "Data value",
|
|
40
40
|
"suppressedError": "Error occured and suppressed. Please check error log for details",
|
|
41
41
|
"op": {
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
42
|
+
"eq": "=",
|
|
43
|
+
"neq": "≠",
|
|
44
|
+
"gt": ">",
|
|
45
|
+
"gte": "≥",
|
|
46
|
+
"lt": "<",
|
|
47
|
+
"lte": "≤",
|
|
48
|
+
"between": "between",
|
|
49
|
+
"in": "includes",
|
|
50
|
+
"!in": "not includes",
|
|
51
|
+
"contains": "contains",
|
|
52
|
+
"!contains": "not contains",
|
|
53
|
+
"starts": "starts with",
|
|
54
|
+
"!starts": "not starts with",
|
|
55
|
+
"ends": "ends with",
|
|
56
|
+
"!ends": "not ends with"
|
|
56
57
|
}
|
|
57
58
|
}
|
package/extend/bajo/intl/id.json
CHANGED
|
@@ -39,19 +39,20 @@
|
|
|
39
39
|
"dataValue": "Nilai data",
|
|
40
40
|
"suppressedError": "Kesalahan terjadi dan tidak ditampilkan. Silahkan cek log kesalahan untuk detilnya",
|
|
41
41
|
"op": {
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
42
|
+
"eq": "=",
|
|
43
|
+
"neq": "≠",
|
|
44
|
+
"gt": ">",
|
|
45
|
+
"gte": "≥",
|
|
46
|
+
"lt": "<",
|
|
47
|
+
"lte": "≤",
|
|
48
|
+
"between": "between",
|
|
49
|
+
"in": "termasuk",
|
|
50
|
+
"!in": "tidak termasuk",
|
|
51
|
+
"contains": "mengandung",
|
|
52
|
+
"!contains": "tidak mengandung",
|
|
53
|
+
"starts": "dimulai dengan",
|
|
54
|
+
"!starts": "tidak dimulai dengan",
|
|
55
|
+
"ends": "diakhiri dengan",
|
|
56
|
+
"!ends": "tidak diakhiri dengan"
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -49,7 +49,7 @@ async function btnColumns () {
|
|
|
49
49
|
this.params.attr.autoClose = 'outside'
|
|
50
50
|
this.params.attr.triggerColor = this.params.attr.color
|
|
51
51
|
this.params.attr.menuDir = this.params.attr.menuDir ?? 'end'
|
|
52
|
-
this.params.attr.menuMax = this.params.attr.menuMax ?? '
|
|
52
|
+
this.params.attr.menuMax = this.params.attr.menuMax ?? '20'
|
|
53
53
|
const html = [...items]
|
|
54
54
|
this.params.html = await this.component.buildTag({ tag: 'dropdown', attr: this.params.attr, html: html.join('\n') })
|
|
55
55
|
this.params.noTag = true
|
|
@@ -27,7 +27,8 @@ async function pagination () {
|
|
|
27
27
|
}
|
|
28
28
|
let { count, limit, page } = attrToObject(this.params.attr.options)
|
|
29
29
|
count = count ?? get(this, 'component.locals.list.count', 0)
|
|
30
|
-
|
|
30
|
+
const data = get(this, 'component.locals.list.data', [])
|
|
31
|
+
if (count === 0 || data.length === 0) {
|
|
31
32
|
this.params.noTag = true
|
|
32
33
|
this.params.html = ''
|
|
33
34
|
return
|
|
@@ -5,6 +5,7 @@ async function query () {
|
|
|
5
5
|
|
|
6
6
|
return class WdbQuery extends WdbBase {
|
|
7
7
|
build = async () => {
|
|
8
|
+
const { req } = this.component
|
|
8
9
|
const { generateId } = this.app.lib.aneka
|
|
9
10
|
const { jsonStringify } = this.app.waibuMpa
|
|
10
11
|
const { find, get, without, isEmpty, filter, upperFirst } = this.app.lib._
|
|
@@ -24,27 +25,38 @@ async function query () {
|
|
|
24
25
|
if (!fields.includes(f)) continue
|
|
25
26
|
const prop = find(schema.properties, { name: f })
|
|
26
27
|
const ops = []
|
|
27
|
-
if (['float', 'double', 'integer', 'smallint'].includes(prop.type)) ops.push('eq', 'neq', 'gt', 'gte', 'lt', 'lte')
|
|
28
|
-
else if (['datetime', 'date', 'time'].includes(prop.type)) ops.push('eq', 'neq', 'gt', 'gte', 'lt', 'lte')
|
|
28
|
+
if (['float', 'double', 'integer', 'smallint'].includes(prop.type)) ops.push('eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'between')
|
|
29
|
+
else if (['datetime', 'date', 'time'].includes(prop.type)) ops.push('eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'between', 'in')
|
|
29
30
|
else if (['boolean'].includes(prop.type)) ops.push('eq', 'neq')
|
|
30
31
|
else ops.push('eq', 'neq', 'in', 'contains', 'starts', 'ends', '!in', '!contains', '!starts', '!ends')
|
|
31
32
|
if (ops.length === 0) continue
|
|
32
|
-
const sels = ops.map(o => `<c:option>${o}</c:option>`)
|
|
33
|
-
models.push(`${f}Op: 'eq'`, `${f}Val: ''`)
|
|
33
|
+
const sels = ops.map(o => `<c:option value="${o}">${req.t('op.' + o)}</c:option>`)
|
|
34
|
+
models.push(`${f}Op: 'eq'`, `${f}Val: ''`, `${f}Val2: ''`)
|
|
34
35
|
const label = this.component.req.t(get(schema, `view.label.${f}`, `field.${f}`))
|
|
35
|
-
|
|
36
|
+
const items = [`
|
|
36
37
|
<c:grid-col col="4-md" flex="align-items:center">
|
|
37
38
|
<c:form-check x-model="selected" t:label="${label}" value="${f}" />
|
|
38
39
|
</c:grid-col>
|
|
39
|
-
<c:grid-col col="
|
|
40
|
+
<c:grid-col col="2-md">
|
|
40
41
|
<c:form-select x-model="${f}Op">
|
|
41
42
|
${sels.join('\n')}
|
|
42
43
|
</c:form-select>
|
|
43
44
|
</c:grid-col>
|
|
44
|
-
<c:grid-col col="
|
|
45
|
-
<c:
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
<c:grid-col col="6-md">
|
|
46
|
+
<c:grid-row gutter="1"><c:grid-col>`]
|
|
47
|
+
if (prop.type === 'datetime') {
|
|
48
|
+
items.push(`<c:form-datetime x-model="${f}Val" />`)
|
|
49
|
+
} else {
|
|
50
|
+
items.push(`<c:form-input x-model="${f}Val" />`)
|
|
51
|
+
}
|
|
52
|
+
items.push(`</c:grid-col><c:grid-col x-show="${f}Op === 'between'">`)
|
|
53
|
+
if (prop.type === 'datetime') {
|
|
54
|
+
items.push(`<c:form-datetime x-model="${f}Val2" wrapper-margin="start-2"/>`)
|
|
55
|
+
} else {
|
|
56
|
+
items.push(`<c:form-input x-model="${f}Val2" wrapper-margin="start-2" />`)
|
|
57
|
+
}
|
|
58
|
+
items.push('</c:grid-col></c:grid-row></c:grid-col>')
|
|
59
|
+
columns.push(items.join('\n'))
|
|
48
60
|
}
|
|
49
61
|
this.params.noTag = true
|
|
50
62
|
const container = this.params.attr.modal ? 'modal' : 'drawer'
|
|
@@ -61,40 +73,50 @@ async function query () {
|
|
|
61
73
|
${models.join(',\n')},
|
|
62
74
|
ops: { eq: ':', neq: ':-', gt: ':>', gte: ':>=', lt: ':<', lte: ':<=' },
|
|
63
75
|
opsIn (v, neg) { return ':' + (neg ? '-' : '') + '[' + this.expandArray(v) + ']' },
|
|
76
|
+
opsBetween (v, v2, neg) { return ':' + (neg ? '-' : '') + '{' + this.expandArray(v) + ',' + this.expandArray(v2) + '}' },
|
|
64
77
|
opsExt (v, neg, ext) {
|
|
65
78
|
let prefix = (neg ? '-' : '') + '~'
|
|
66
79
|
if (ext) prefix += ext
|
|
67
80
|
return ':' + prefix + '\\'' + v + '\\''
|
|
68
81
|
},
|
|
69
|
-
|
|
82
|
+
parse () {
|
|
70
83
|
this.builder = document.getElementById('${id}').value
|
|
71
84
|
if (!this.builder.includes(':')) this.builder = ''
|
|
72
85
|
if (_.isEmpty(this.builder)) return
|
|
73
86
|
const tokens = _.merge({}, this.ops, {
|
|
74
87
|
in: ':[',
|
|
88
|
+
between: ':{',
|
|
75
89
|
contains: ':~',
|
|
76
90
|
starts: ':~^',
|
|
77
91
|
ends: ':~$$',
|
|
78
92
|
'!in': ':-[',
|
|
93
|
+
'!between': ':-{',
|
|
79
94
|
'!contains': ':-~',
|
|
80
95
|
'!starts': ':-~^',
|
|
81
96
|
'!ends': ':-~$$'
|
|
82
97
|
})
|
|
83
98
|
for (const part of this.builder.split('+')) {
|
|
84
|
-
let [f, opv] = part.split(':')
|
|
85
|
-
opv = ':' + opv
|
|
99
|
+
let [f, ...opv] = part.split(':')
|
|
100
|
+
opv = ':' + opv.join(':')
|
|
86
101
|
this.selected.push(f)
|
|
87
102
|
let op
|
|
88
103
|
let val
|
|
89
104
|
_.each(tokens, (v, k) => {
|
|
90
105
|
if (opv.slice(0, v.length) === v) {
|
|
91
106
|
op = k
|
|
92
|
-
val = opv.slice(v.length).replaceAll('[', '').replaceAll(']', '').replaceAll('\\'', '')
|
|
107
|
+
val = opv.slice(v.length).replaceAll('[', '').replaceAll('{', '').replaceAll(']', '').replaceAll('}', '').replaceAll('\\'', '')
|
|
93
108
|
}
|
|
94
109
|
})
|
|
110
|
+
console.log(op, val)
|
|
95
111
|
if (_.isEmpty(op)) continue
|
|
96
112
|
this[f + 'Op'] = op
|
|
97
|
-
|
|
113
|
+
if (op === 'between') {
|
|
114
|
+
const vals = val.split(',')
|
|
115
|
+
this[f + 'Val'] = vals[0]
|
|
116
|
+
this[f + 'Val2'] = vals[1]
|
|
117
|
+
} else {
|
|
118
|
+
this[f + 'Val'] = val
|
|
119
|
+
}
|
|
98
120
|
}
|
|
99
121
|
},
|
|
100
122
|
expandArray (val = '') {
|
|
@@ -109,10 +131,14 @@ async function query () {
|
|
|
109
131
|
for (const sel of this.selected) {
|
|
110
132
|
const key = this[sel + 'Op']
|
|
111
133
|
let val = this[sel + 'Val']
|
|
134
|
+
let val2 = this[sel + 'Val2']
|
|
112
135
|
if (_.isEmpty(val)) continue
|
|
136
|
+
if (key === 'between' && _.isEmpty(val2)) continue
|
|
113
137
|
let item
|
|
114
138
|
if (key === 'in') item = this.opsIn(val)
|
|
115
139
|
else if (key === '!in') item = this.opsIn(val, true)
|
|
140
|
+
else if (key === 'between') item = this.opsBetween(val, val2, false)
|
|
141
|
+
else if (key === '!between') item = this.opsBetween(val, val2, true)
|
|
116
142
|
else if (key === 'contains') item = this.opsExt(val)
|
|
117
143
|
else if (key === '!contains') item = this.opsExt(val, true)
|
|
118
144
|
else if (key === 'starts') item = this.opsExt(val, false, '^')
|
|
@@ -137,12 +163,13 @@ async function query () {
|
|
|
137
163
|
instance.hide()
|
|
138
164
|
}
|
|
139
165
|
}" x-init="
|
|
140
|
-
|
|
166
|
+
parse()
|
|
141
167
|
const ops = _.map(fields, f => (f + 'Op'))
|
|
142
168
|
const vals = _.map(fields, f => (f + 'Val'))
|
|
143
|
-
const
|
|
169
|
+
const vals2 = _.map(fields, f => (f + 'Val2'))
|
|
170
|
+
const watcher = ['selected', ...ops, ...vals, ...vals2].join(',')
|
|
144
171
|
$watch(watcher, v => rebuild())
|
|
145
|
-
">
|
|
172
|
+
" ${this.params.attr.modal ? '' : 'style="width:600px;"'}>
|
|
146
173
|
<c:grid-row gutter="2">
|
|
147
174
|
<c:grid-col col="12">
|
|
148
175
|
<c:form-textarea x-model="builder" readonly rows="4"/>
|
|
@@ -17,7 +17,8 @@ async function recsInfo () {
|
|
|
17
17
|
}
|
|
18
18
|
let { count, limit, page, pages } = attrToObject(this.params.attr.options)
|
|
19
19
|
count = count ?? get(this, 'component.locals.list.count', 0)
|
|
20
|
-
|
|
20
|
+
const data = get(this, 'component.locals.list.data', [])
|
|
21
|
+
if (count === 0 || data.length === 0) {
|
|
21
22
|
this.params.noTag = true
|
|
22
23
|
this.params.html = ''
|
|
23
24
|
return
|
|
@@ -61,7 +61,7 @@ async function table () {
|
|
|
61
61
|
for (const prop of schema.properties) {
|
|
62
62
|
if (typeof prop.values === 'string') this.propValues[prop.name] = await callHandler(prop.values)
|
|
63
63
|
}
|
|
64
|
-
if (count === 0) {
|
|
64
|
+
if (count === 0 || data.length === 0) {
|
|
65
65
|
const alert = '<c:alert color="warning" t:content="noRecordFound" margin="top-4"/>'
|
|
66
66
|
this.params.noTag = true
|
|
67
67
|
this.params.html = await this.component.buildSentence(alert)
|
package/lib/crud/edit-handler.js
CHANGED
|
@@ -24,6 +24,9 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
|
|
|
24
24
|
form = defaultsDeep(req.body, old.data)
|
|
25
25
|
if (req.method !== 'GET') {
|
|
26
26
|
form = omit(form, ['_action', '_value'])
|
|
27
|
+
try {
|
|
28
|
+
req.body._value = JSON.parse(req.body._value)
|
|
29
|
+
} catch (err) {}
|
|
27
30
|
if (req.body._action === 'removeatt' && !isEmpty(req.body._value)) {
|
|
28
31
|
const root = `${getPluginDataDir('dobo')}/attachment`
|
|
29
32
|
for (const item of req.body._value) {
|
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-04-02
|
|
4
|
+
|
|
5
|
+
- [2.12.6] Bug fix in ```wdb-query``` widget
|
|
6
|
+
|
|
7
|
+
## 2026-04-01
|
|
8
|
+
|
|
9
|
+
- [2.12.5] Bug fix in ```wdb-btn-column``` widget
|
|
10
|
+
- [2.12.5] Bug fix in ```wdb-pagination``` widget
|
|
11
|
+
- [2.12.5] Bug fix in ```wdb-query``` widget
|
|
12
|
+
- [2.12.5] Bug fix in ```wdb-recs-info``` widget
|
|
13
|
+
- [2.12.5] Bug fix in ```wdb-table``` widget
|
|
14
|
+
- [2.12.5] Bug fix in remove attachment
|
|
15
|
+
|
|
3
16
|
## 2026-03-30
|
|
4
17
|
|
|
5
18
|
- [2.12.3] Bug fix in transaction supports
|