waibu-db 1.2.3 → 1.2.5
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/bajo/intl/en-US.json +3 -0
- package/bajo/intl/id.json +3 -0
- package/bajoTemplate/partial/crud/_details-btns.html +1 -1
- package/bajoTemplate/partial/crud/_edit-btns.html +1 -1
- package/index.js +28 -1
- package/lib/crud/add-handler.js +2 -0
- package/lib/crud/details-handler.js +2 -0
- package/lib/crud/edit-handler.js +2 -0
- package/lib/crud/export-handler.js +17 -4
- package/lib/crud/list-handler.js +2 -0
- package/lib/prep-crud.js +3 -0
- package/package.json +1 -1
- package/plugin-method/format-record.js +6 -12
- package/waibuBootstrap/theme/component/factory/btn-export.js +12 -4
- package/waibuBootstrap/theme/component/factory/query.js +5 -6
- package/waibuBootstrap/theme/component/factory/table.js +20 -9
- package/waibuMpa/sumba/route/export/@action.js +0 -14
package/bajo/intl/en-US.json
CHANGED
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
"checkAll": "Check All",
|
|
33
33
|
"uncheckAll": "Uncheck All",
|
|
34
34
|
"attachment": "Attachment",
|
|
35
|
+
"exportInQueue": "Data export in queue. Please check your download list for progress",
|
|
36
|
+
"tsv": "TSV",
|
|
37
|
+
"ndjson": "NDJSON",
|
|
35
38
|
"op": {
|
|
36
39
|
"equals": "Equals",
|
|
37
40
|
"notEquals": "Not Equals",
|
package/bajo/intl/id.json
CHANGED
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
"checkAll": "Cek Semua",
|
|
33
33
|
"uncheckAll": "Uncheck Semua",
|
|
34
34
|
"attachment": "Attachment",
|
|
35
|
+
"exportInQueue": "Ekspor data sedang dalam antrian. Silahkan cek daftar unduh Anda untuk perkembangan terakhir",
|
|
36
|
+
"tsv": "TSV",
|
|
37
|
+
"ndjson": "NDJSON",
|
|
35
38
|
"op": {
|
|
36
39
|
"equals": "Sama Dengan",
|
|
37
40
|
"notEquals": "Tidak Sama Dengan",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<c:wdb-btn-clone href="<%= schema.view.control.cloneHref ?? 'undefined' %>" />
|
|
17
17
|
<% } %>
|
|
18
18
|
<% if (!schema.view.control.noExportBtn) { %>
|
|
19
|
-
<c:wdb-btn-export selector="#main-form" handler="details" launch-on-end/>
|
|
19
|
+
<c:wdb-btn-export selector="#main-form" handler="details" launch-on-end no-save/>
|
|
20
20
|
<% } %>
|
|
21
21
|
</c:btn-group>
|
|
22
22
|
<% } %>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<% if (!schema.view.control.noCloneBtn) { %>
|
|
11
11
|
<c:wdb-btn-clone href="<%= schema.view.control.cloneHref ?? 'undefined' %>" />
|
|
12
12
|
<% } %>
|
|
13
|
-
<c:wdb-btn-export selector="#main-form" handler="edit" launch-on-end/>
|
|
13
|
+
<c:wdb-btn-export selector="#main-form" handler="edit" launch-on-end no-save />
|
|
14
14
|
</c:btn-group>
|
|
15
15
|
</c:grid-col>
|
|
16
16
|
<c:grid-col col="6-lg" flex="justify-content:end-lg align-items:center">
|
package/index.js
CHANGED
|
@@ -5,7 +5,7 @@ async function factory (pkgName) {
|
|
|
5
5
|
constructor () {
|
|
6
6
|
super(pkgName, me.app)
|
|
7
7
|
this.alias = 'wdb'
|
|
8
|
-
this.dependencies = ['dobo', 'waibu']
|
|
8
|
+
this.dependencies = ['dobo', 'waibu', 'bajo-queue', 'dobo-extra']
|
|
9
9
|
this.config = {
|
|
10
10
|
waibu: {
|
|
11
11
|
prefix: 'db',
|
|
@@ -25,6 +25,33 @@ async function factory (pkgName) {
|
|
|
25
25
|
modelRestApi: false
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
exportData = async (params) => {
|
|
30
|
+
const { getPlugin } = this.app.bajo
|
|
31
|
+
const { get } = this.lib._
|
|
32
|
+
const { fs } = this.lib
|
|
33
|
+
const { recordUpdate } = this.app.dobo
|
|
34
|
+
const { exportTo } = this.app.doboExtra
|
|
35
|
+
const { downloadDir } = getPlugin('sumba')
|
|
36
|
+
const model = get(params, 'payload.data.name')
|
|
37
|
+
const fields = get(params, 'payload.data.opts.fields')
|
|
38
|
+
const { id, file } = get(params, 'payload.data.download', {})
|
|
39
|
+
const dest = `${downloadDir}/${file}`
|
|
40
|
+
const options = {
|
|
41
|
+
filter: get(params, 'payload.data.filter', {}),
|
|
42
|
+
ensureDir: true,
|
|
43
|
+
fields
|
|
44
|
+
}
|
|
45
|
+
const dmodel = 'SumbaDownload'
|
|
46
|
+
try {
|
|
47
|
+
await recordUpdate(dmodel, id, { status: 'PROCESSING' })
|
|
48
|
+
await exportTo(model, dest, options)
|
|
49
|
+
const { size } = fs.statSync(dest)
|
|
50
|
+
await recordUpdate(dmodel, id, { size, status: 'COMPLETE' })
|
|
51
|
+
} catch (err) {
|
|
52
|
+
await recordUpdate(dmodel, id, { status: 'FAIL' })
|
|
53
|
+
}
|
|
54
|
+
}
|
|
28
55
|
}
|
|
29
56
|
}
|
|
30
57
|
|
package/lib/crud/add-handler.js
CHANGED
|
@@ -34,6 +34,8 @@ async function addHandler ({ req, reply, model, params = {}, template, addOnsHan
|
|
|
34
34
|
}
|
|
35
35
|
const addOns = addOnsHandler ? await addOnsHandler.call(this.app[req.ns], { req, reply, params, data: resp, schema, error }) : undefined
|
|
36
36
|
merge(params, { form, schema, error, addOns })
|
|
37
|
+
if (schema.template) template = schema.template
|
|
38
|
+
if (schema.layout) params.page.layout = schema.layout
|
|
37
39
|
return await reply.view(template, params)
|
|
38
40
|
}
|
|
39
41
|
|
|
@@ -16,6 +16,8 @@ async function detailsHandler ({ req, reply, model, params = {}, id, template, a
|
|
|
16
16
|
const addOns = addOnsHandler ? await addOnsHandler.call(this.app[req.ns], { req, reply, params, data: resp, schema }) : undefined
|
|
17
17
|
const attachments = await attachmentHandler.call(this, { schema, id })
|
|
18
18
|
merge(params, { form, schema, addOns, attachments })
|
|
19
|
+
if (schema.template) template = schema.template
|
|
20
|
+
if (schema.layout) params.page.layout = schema.layout
|
|
19
21
|
return await reply.view(template, params)
|
|
20
22
|
}
|
|
21
23
|
|
package/lib/crud/edit-handler.js
CHANGED
|
@@ -45,6 +45,8 @@ async function editHandler ({ req, reply, model, id, params = {}, template, addO
|
|
|
45
45
|
const addOns = addOnsHandler ? await addOnsHandler.call(this.app[req.ns], { req, reply, params, data: resp, schema, error }) : undefined
|
|
46
46
|
const attachments = await attachmentHandler.call(this, { schema, id })
|
|
47
47
|
merge(params, { form, schema, error, addOns, attachments })
|
|
48
|
+
if (schema.template) template = schema.template
|
|
49
|
+
if (schema.layout) params.page.layout = schema.layout
|
|
48
50
|
return await reply.view(template, params)
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -1,14 +1,27 @@
|
|
|
1
|
+
import prepCrud from '../prep-crud.js'
|
|
2
|
+
|
|
1
3
|
async function exportHandler ({ req, reply, model, params = {}, templateDisabled = 'waibuDb.template:/disabled.html' } = {}) {
|
|
4
|
+
const { getPlugin } = this.app.bajo
|
|
5
|
+
const { dayjs } = this.lib
|
|
6
|
+
const { omit, kebabCase, get } = this.lib._
|
|
2
7
|
const { pascalCase } = this.lib.aneka
|
|
3
8
|
const { getSchemaExt } = this.app.waibuDb
|
|
4
9
|
const { buildUrl } = this.app.waibuMpa
|
|
5
|
-
const
|
|
10
|
+
const { pushDownload } = getPlugin('sumba')
|
|
6
11
|
model = model ?? pascalCase(req.params.model)
|
|
7
|
-
const { schema } = await getSchemaExt(model, 'add',
|
|
12
|
+
const { schema } = await getSchemaExt(model, 'add', { params })
|
|
8
13
|
if (schema.disabled.includes('find')) return await reply.view(templateDisabled, { action: 'list' })
|
|
9
|
-
|
|
14
|
+
const data = prepCrud.call(getPlugin('waibuDb'), { model, req, reply, args: ['model'] })
|
|
15
|
+
data.opts = omit(data.opts, ['req', 'reply'])
|
|
16
|
+
const source = `${this.name}:/export-handler`
|
|
17
|
+
const worker = 'waibuDb:exportData'
|
|
18
|
+
const type = get(data, 'input.ftype', 'json')
|
|
19
|
+
const settings = get(data, 'input.options', '').split(',')
|
|
20
|
+
const ext = settings.includes('zip') ? `${type}.gz` : type
|
|
21
|
+
const file = `${kebabCase(model)}_${dayjs().format('YYYYMMDDhhmmss')}.${ext}`
|
|
22
|
+
await pushDownload({ file, type, worker, source, data, req })
|
|
23
|
+
req.flash('notify', req.t('exportInQueue'))
|
|
10
24
|
const url = buildUrl({ url: req.url, base: req.body.handler })
|
|
11
|
-
req.flash('notify', req.t('Data export in queue. You\'ll be notified once completed'))
|
|
12
25
|
return reply.redirectTo(url)
|
|
13
26
|
}
|
|
14
27
|
|
package/lib/crud/list-handler.js
CHANGED
|
@@ -21,6 +21,8 @@ async function listHandler ({ req, reply, model, template, params = {}, addOnsHa
|
|
|
21
21
|
if (!isArray(addOns)) addOns = [addOns]
|
|
22
22
|
}
|
|
23
23
|
merge(params, { list, schema, addOns })
|
|
24
|
+
if (schema.template) template = schema.template
|
|
25
|
+
if (schema.layout) params.page.layout = schema.layout
|
|
24
26
|
return await reply.view(template, params)
|
|
25
27
|
}
|
|
26
28
|
|
package/lib/prep-crud.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
function prepCrud ({ model, body, id, req, reply, options = {}, args }) {
|
|
2
2
|
const { parseFilter } = this.app.waibu
|
|
3
|
+
const { buildQuery, getInfo } = this.app.dobo
|
|
3
4
|
const { pascalCase } = this.lib.aneka
|
|
4
5
|
const { cloneDeep, has } = this.lib._
|
|
5
6
|
const cfgWeb = this.app.waibu.getConfig()
|
|
@@ -20,6 +21,7 @@ function prepCrud ({ model, body, id, req, reply, options = {}, args }) {
|
|
|
20
21
|
|
|
21
22
|
const recId = id ?? params.id ?? req.query.id
|
|
22
23
|
const name = pascalCase(model ?? params.model)
|
|
24
|
+
const { schema } = getInfo(name)
|
|
23
25
|
const input = body ?? params.body
|
|
24
26
|
opts.bboxLatField = req.query[cfgWeb.qsKey.bboxLatField]
|
|
25
27
|
opts.bboxLngField = req.query[cfgWeb.qsKey.bboxLngField]
|
|
@@ -28,6 +30,7 @@ function prepCrud ({ model, body, id, req, reply, options = {}, args }) {
|
|
|
28
30
|
if (options.limit) filter.limit = options.limit
|
|
29
31
|
if (options.sort) filter.sort = options.sort
|
|
30
32
|
if (options.page) filter.page = options.page
|
|
33
|
+
filter.query = buildQuery({ filter, schema })
|
|
31
34
|
return { name, recId, input, opts, filter, attachment, stats, mimeType }
|
|
32
35
|
}
|
|
33
36
|
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
async function formatRow ({ data, req,
|
|
1
|
+
async function formatRow ({ data, req, schema, options = {} }) {
|
|
2
2
|
const { get, find, isFunction, cloneDeep } = this.lib._
|
|
3
3
|
const { format, callHandler } = this.app.bajo
|
|
4
4
|
const fields = get(schema, 'view.fields', Object.keys(schema.properties))
|
|
@@ -19,25 +19,19 @@ async function formatRow ({ data, req, component, schema, options = {} }) {
|
|
|
19
19
|
rec[f] = format(data[f], prop.type, opts)
|
|
20
20
|
const vf = get(schema, `view.valueFormatter.${f}`)
|
|
21
21
|
if (vf) {
|
|
22
|
-
if (isFunction(vf)) rec[f] = await vf.call(
|
|
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])
|
|
22
|
+
if (isFunction(vf)) rec[f] = await vf.call(this, data[f], data)
|
|
23
|
+
else rec[f] = await callHandler(vf, { req, value: data[f], data })
|
|
30
24
|
}
|
|
31
25
|
}
|
|
32
26
|
return rec
|
|
33
27
|
}
|
|
34
28
|
|
|
35
|
-
async function formatRecord ({ data, req, schema,
|
|
29
|
+
async function formatRecord ({ data, req, schema, options = {} }) {
|
|
36
30
|
const { isArray } = this.lib._
|
|
37
|
-
if (!isArray(data)) return await formatRow.call(this, { data, req, schema,
|
|
31
|
+
if (!isArray(data)) return await formatRow.call(this, { data, req, schema, options })
|
|
38
32
|
const items = []
|
|
39
33
|
for (const d of data) {
|
|
40
|
-
const item = await formatRow.call(this, { data: d, req, schema,
|
|
34
|
+
const item = await formatRow.call(this, { data: d, req, schema, options })
|
|
41
35
|
items.push(item)
|
|
42
36
|
}
|
|
43
37
|
return items
|
|
@@ -29,15 +29,22 @@ async function btnExport () {
|
|
|
29
29
|
ftype: 'json',
|
|
30
30
|
toggle (val) {
|
|
31
31
|
if (val === 'clipboard') {
|
|
32
|
+
$refs.fkey.removeAttribute('disabled')
|
|
33
|
+
$refs.fvalue.removeAttribute('disabled')
|
|
32
34
|
$refs.zip.setAttribute('disabled', '')
|
|
33
35
|
$refs.xlsx.setAttribute('disabled', '')
|
|
34
|
-
$refs.
|
|
36
|
+
$refs.tsv.setAttribute('disabled', '')
|
|
37
|
+
$refs.ndjson.setAttribute('disabled', '')
|
|
35
38
|
_.pull(this.options, 'zip')
|
|
36
39
|
if (!['json', 'csv'].includes(this.ftype)) this.ftype = 'json'
|
|
37
40
|
} else {
|
|
41
|
+
$refs.fkey.setAttribute('disabled', '')
|
|
42
|
+
$refs.fvalue.setAttribute('disabled', '')
|
|
38
43
|
$refs.zip.removeAttribute('disabled')
|
|
39
44
|
$refs.xlsx.removeAttribute('disabled')
|
|
40
|
-
$refs.
|
|
45
|
+
$refs.tsv.removeAttribute('disabled')
|
|
46
|
+
$refs.ndjson.removeAttribute('disabled')
|
|
47
|
+
_.pull(this.options, 'fkey', 'fvalue')
|
|
41
48
|
}
|
|
42
49
|
},
|
|
43
50
|
extractForm (selector) {
|
|
@@ -117,8 +124,8 @@ async function btnExport () {
|
|
|
117
124
|
<c:grid-row gutter="2">
|
|
118
125
|
<c:grid-col col="6-md">
|
|
119
126
|
<c:fieldset t:legend="delivery" legend-type="6">
|
|
120
|
-
<c:form-radio x-model="delivery" value="file" t:label="saveAsFile" />
|
|
121
127
|
<c:form-radio x-model="delivery" value="clipboard" t:label="copyClipboard" />
|
|
128
|
+
<c:form-radio x-model="delivery" value="file" t:label="saveAsFile" ${this.params.attr.noSave ? 'disabled' : ''} />
|
|
122
129
|
</c:fieldset>
|
|
123
130
|
<c:fieldset t:legend="options" legend-type="6" margin="top-2">
|
|
124
131
|
<c:form-check x-ref="fkey" x-model="options" value="fkey" t:label="formattedField" />
|
|
@@ -130,8 +137,9 @@ async function btnExport () {
|
|
|
130
137
|
<c:fieldset t:legend="fileType" legend-type="6">
|
|
131
138
|
<c:form-radio x-ref="xlsx" x-model="ftype" value="xlsx" t:label="excelXlsx" />
|
|
132
139
|
<c:form-radio x-ref="csv" x-model="ftype" value="csv" t:label="csv" />
|
|
133
|
-
<c:form-radio x-ref="
|
|
140
|
+
<c:form-radio x-ref="tsv" x-model="ftype" value="tsv" t:label="tsv" />
|
|
134
141
|
<c:form-radio x-ref="json" x-model="ftype" value="json" t:label="json" />
|
|
142
|
+
<c:form-radio x-ref="ndjson" x-model="ftype" value="ndjson" t:label="ndjson" />
|
|
135
143
|
</c:fieldset />
|
|
136
144
|
</c:grid-col>
|
|
137
145
|
</c:grid-row>
|
|
@@ -10,7 +10,6 @@ async function query () {
|
|
|
10
10
|
const { find, get, without, isEmpty, filter, upperFirst } = this.plugin.app.bajo.lib._
|
|
11
11
|
const qsKey = this.plugin.app.waibu.config.qsKey
|
|
12
12
|
const schema = get(this, 'component.locals.schema', {})
|
|
13
|
-
const count = get(this, 'component.locals.list.count', 0)
|
|
14
13
|
if (schema.view.disabled.includes('find')) {
|
|
15
14
|
this.params.html = ''
|
|
16
15
|
return
|
|
@@ -21,7 +20,6 @@ async function query () {
|
|
|
21
20
|
const id = generateId('alpha')
|
|
22
21
|
const columns = []
|
|
23
22
|
const models = []
|
|
24
|
-
const selects = ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'contains', 'starts', 'ends', '!in', '!contains', '!starts', '!ends']
|
|
25
23
|
for (const f of schema.view.fields) {
|
|
26
24
|
if (!fields.includes(f)) continue
|
|
27
25
|
const prop = find(schema.properties, { name: f })
|
|
@@ -29,7 +27,7 @@ async function query () {
|
|
|
29
27
|
if (['float', 'double', 'integer', 'smallint'].includes(prop.type)) ops.push('eq', 'neq', 'gt', 'gte', 'lt', 'lte')
|
|
30
28
|
else if (['datetime', 'date', 'time'].includes(prop.type)) ops.push('eq', 'neq', 'gt', 'gte', 'lt', 'lte')
|
|
31
29
|
else if (['boolean'].includes(prop.type)) ops.push('eq', 'neq')
|
|
32
|
-
else ops.push(
|
|
30
|
+
else ops.push('eq', 'neq', 'in', 'contains', 'starts', 'ends', '!in', '!contains', '!starts', '!ends')
|
|
33
31
|
if (ops.length === 0) continue
|
|
34
32
|
const sels = ops.map(o => `<c:option>${o}</c:option>`)
|
|
35
33
|
models.push(`${f}Op: 'eq'`, `${f}Val: ''`)
|
|
@@ -51,12 +49,12 @@ async function query () {
|
|
|
51
49
|
this.params.noTag = true
|
|
52
50
|
const container = this.params.attr.modal ? 'modal' : 'drawer'
|
|
53
51
|
this.params.html = await this.component.buildSentence(`
|
|
54
|
-
<c:form-input
|
|
52
|
+
<c:form-input type="search" t:placeholder="query" id="${id}" x-data="{ query: '' }" x-init="
|
|
55
53
|
const url = new URL(window.location.href)
|
|
56
54
|
query = url.searchParams.get('${qsKey.query}') ?? ''
|
|
57
55
|
" x-model="query" @on-query.window="query = $event.detail ?? ''" @keyup.enter="$dispatch('on-submit')">
|
|
58
56
|
<c:form-input-addon>
|
|
59
|
-
<c:${container}
|
|
57
|
+
<c:${container} trigger-icon="${this.params.attr.icon ?? 'dotsThree'}" trigger-on-end t:title="queryBuilder" x-ref="query" x-data="{
|
|
60
58
|
fields: ${jsonStringify(fields, true)},
|
|
61
59
|
builder: '',
|
|
62
60
|
selected: [],
|
|
@@ -70,6 +68,7 @@ async function query () {
|
|
|
70
68
|
},
|
|
71
69
|
initBuilder () {
|
|
72
70
|
this.builder = document.getElementById('${id}').value
|
|
71
|
+
if (!this.builder.includes(':')) this.builder = ''
|
|
73
72
|
if (_.isEmpty(this.builder)) return
|
|
74
73
|
const tokens = _.merge({}, this.ops, {
|
|
75
74
|
in: ':[',
|
|
@@ -158,7 +157,7 @@ async function query () {
|
|
|
158
157
|
</c:${container}>
|
|
159
158
|
</c:form-input-addon>
|
|
160
159
|
<c:form-input-addon>
|
|
161
|
-
<c:btn
|
|
160
|
+
<c:btn t:content="submit" x-data="{
|
|
162
161
|
submit () {
|
|
163
162
|
const val = document.getElementById('${id}').value ?? ''
|
|
164
163
|
const url = new URL(window.location.href)
|
|
@@ -19,19 +19,33 @@ async function table () {
|
|
|
19
19
|
return get(schema, 'view.noWrap', []).includes(field)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
_defFormatter = async ({ req, key, value, data, schema }) => {
|
|
23
|
+
const { get, find } = this.plugin.lib._
|
|
24
|
+
const { escape } = this.plugin.app.waibu
|
|
25
|
+
const prop = find(schema.properties, { name: key })
|
|
26
|
+
if (!prop) return value
|
|
27
|
+
if (prop.type === 'boolean') {
|
|
28
|
+
value = (await this.component.buildTag({ tag: 'icon', attr: { name: `circle${data[key] ? 'Check' : ''}` } })) +
|
|
29
|
+
' ' + (req.t(data[key] ? 'Yes' : 'No'))
|
|
30
|
+
} else if (['string', 'text'].includes(prop.type)) {
|
|
31
|
+
if (!get(schema, 'view.noEscape', []).includes(key)) value = escape(value)
|
|
32
|
+
}
|
|
33
|
+
return value
|
|
34
|
+
}
|
|
35
|
+
|
|
22
36
|
build = async () => {
|
|
23
37
|
const { req } = this.component
|
|
24
38
|
const { escape } = this.plugin.app.waibu
|
|
25
39
|
const { formatRecord } = this.plugin.app.waibuDb
|
|
26
40
|
const { attrToArray, groupAttrs } = this.plugin.app.waibuMpa
|
|
27
|
-
const { get, omit, set, find, isEmpty, without, merge } = this.plugin.
|
|
41
|
+
const { get, omit, set, find, isEmpty, without, merge } = this.plugin.lib._
|
|
28
42
|
const group = groupAttrs(this.params.attr, ['body', 'head', 'foot'])
|
|
29
43
|
this.params.attr = group._
|
|
30
44
|
const prettyUrl = this.params.attr.prettyUrl
|
|
31
45
|
|
|
32
46
|
const schema = get(this, 'component.locals.schema', {})
|
|
33
47
|
const data = get(this, 'component.locals.list.data', [])
|
|
34
|
-
const fdata = await formatRecord.call(this.plugin, { data, req, schema
|
|
48
|
+
const fdata = await formatRecord.call(this.plugin, { data, req, schema })
|
|
35
49
|
const filter = get(this, 'component.locals.list.filter', {})
|
|
36
50
|
const count = get(this, 'component.locals.list.count', 0)
|
|
37
51
|
if (count === 0) {
|
|
@@ -136,16 +150,10 @@ async function table () {
|
|
|
136
150
|
if (['array', 'object'].includes(prop.type)) dataValue = escape(JSON.stringify(d[f]))
|
|
137
151
|
}
|
|
138
152
|
let value = fd[f]
|
|
139
|
-
if (prop.type === 'boolean') {
|
|
140
|
-
value = (await this.component.buildTag({ tag: 'icon', attr: { name: `circle${d[f] ? 'Check' : ''}` } })) +
|
|
141
|
-
' ' + (req.t(d[f] ? 'Yes' : 'No'))
|
|
142
|
-
} else {
|
|
143
|
-
if (!get(schema, 'view.noEscape', []).includes(f)) value = escape(value)
|
|
144
|
-
}
|
|
145
153
|
const attr = { dataValue, dataKey: prop.name, dataType: prop.type }
|
|
146
154
|
if (!disableds.includes('get')) attr.style = { cursor: 'pointer' }
|
|
147
155
|
const cellFormatter = get(schema, `view.cellFormatter.${f}`)
|
|
148
|
-
if (cellFormatter) merge(attr, await cellFormatter.call(
|
|
156
|
+
if (cellFormatter) merge(attr, await cellFormatter.call(this, dataValue, d))
|
|
149
157
|
const noWrap = this.isNoWrap(f, schema, group.body.nowrap) ? 'nowrap' : ''
|
|
150
158
|
if (this.isRightAligned(f, schema)) attr.text = `align:end ${noWrap}`
|
|
151
159
|
else attr.text = noWrap
|
|
@@ -154,6 +162,9 @@ async function table () {
|
|
|
154
162
|
const item = find(lookup.values, set({}, lookup.id ?? 'id', d[f]))
|
|
155
163
|
if (item) value = req.t(item[lookup.field ?? 'name'])
|
|
156
164
|
}
|
|
165
|
+
const formatter = get(schema, `view.formatter.${f}`)
|
|
166
|
+
if (formatter) value = await formatter.call(this, value, d)
|
|
167
|
+
else value = await this._defFormatter({ req, key: f, schema, value, data: d })
|
|
157
168
|
const line = await this.component.buildTag({ tag: 'td', attr, html: value })
|
|
158
169
|
lines.push(line)
|
|
159
170
|
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const action = {
|
|
2
|
-
method: ['GET', 'POST'],
|
|
3
|
-
title: 'Database Export',
|
|
4
|
-
handler: async function (req, reply) {
|
|
5
|
-
const { importModule } = this.app.bajo
|
|
6
|
-
const handler = await importModule('waibuDb:/lib/crud/all-handler.js')
|
|
7
|
-
const model = 'SumbaUser'
|
|
8
|
-
const { action } = req.params
|
|
9
|
-
const template = `sumba.template:/crud/${action}.html`
|
|
10
|
-
return handler.call(this, { model, req, reply, action, template })
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default action
|