waibu-db 1.0.1 → 1.0.3

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.
Files changed (28) hide show
  1. package/package.json +1 -1
  2. package/waibuBootstrap/theme/component/factory/btn-add.js +24 -0
  3. package/waibuBootstrap/theme/component/factory/btn-back.js +22 -0
  4. package/waibuBootstrap/theme/component/factory/btn-clone.js +39 -0
  5. package/waibuBootstrap/theme/component/factory/btn-columns.js +55 -0
  6. package/waibuBootstrap/theme/component/factory/btn-delete.js +52 -0
  7. package/waibuBootstrap/theme/component/factory/btn-details.js +41 -0
  8. package/waibuBootstrap/theme/component/factory/btn-edit.js +67 -0
  9. package/waibuBootstrap/theme/component/factory/btn-export.js +138 -0
  10. package/waibuBootstrap/theme/component/factory/echarts.js +67 -0
  11. package/waibuBootstrap/theme/component/factory/pagination.js +69 -0
  12. package/waibuBootstrap/theme/component/factory/query.js +177 -0
  13. package/waibuBootstrap/theme/component/factory/recs-info.js +58 -0
  14. package/waibuBootstrap/theme/component/factory/table.js +168 -0
  15. package/waibuBootstrap/theme/component/wdb-base.js +6 -0
  16. package/waibuBootstrap/theme/component/btn-add.js +0 -15
  17. package/waibuBootstrap/theme/component/btn-back.js +0 -13
  18. package/waibuBootstrap/theme/component/btn-clone.js +0 -30
  19. package/waibuBootstrap/theme/component/btn-columns.js +0 -45
  20. package/waibuBootstrap/theme/component/btn-delete.js +0 -43
  21. package/waibuBootstrap/theme/component/btn-details.js +0 -32
  22. package/waibuBootstrap/theme/component/btn-edit.js +0 -56
  23. package/waibuBootstrap/theme/component/btn-export.js +0 -129
  24. package/waibuBootstrap/theme/component/echarts.js +0 -58
  25. package/waibuBootstrap/theme/component/pagination.js +0 -60
  26. package/waibuBootstrap/theme/component/query.js +0 -137
  27. package/waibuBootstrap/theme/component/recs-info.js +0 -50
  28. package/waibuBootstrap/theme/component/table.js +0 -161
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu-db",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "DB Helper",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,24 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function btnAdd () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbBtnAdd extends WdbBase {
7
+ async build () {
8
+ const { isEmpty, get } = this.plugin.app.bajo.lib._
9
+ const { req } = this.component
10
+ this.params.noTag = true
11
+ const schema = get(this, 'component.locals.schema', {})
12
+ if (schema.view.disabled.includes('create')) {
13
+ this.params.html = ''
14
+ return
15
+ }
16
+ if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('Add')
17
+ this.params.attr.color = this.params.attr.color ?? 'secondary-outline'
18
+ if (!this.params.attr.href) this.params.attr.href = this.component.buildUrl({ base: 'add' })
19
+ this.params.html = await this.component.buildTag({ tag: 'btn', attr: this.params.attr, html: this.params.html })
20
+ }
21
+ }
22
+ }
23
+
24
+ export default btnAdd
@@ -0,0 +1,22 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function btnBack () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbBtnBack extends WdbBase {
7
+ async build () {
8
+ const { isEmpty } = this.plugin.app.bajo.lib._
9
+ const { attrToArray } = this.plugin.app.waibuMpa
10
+ const { req } = this.component
11
+ this.params.noTag = true
12
+ if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('Back')
13
+ if (isEmpty(this.params.attr.icon)) this.params.attr.icon = 'arrowStart'
14
+ this.params.attr.color = this.params.attr.color ?? 'secondary-outline'
15
+ this.params.attr.excludeQs = ['mode', 'id', ...attrToArray(this.params.attr.excludeQs ?? '')]
16
+ if (!this.params.attr.href) this.params.attr.href = this.component.buildUrl({ base: 'list', exclude: this.params.attr.excludeQs })
17
+ this.params.html = await this.component.buildTag({ tag: 'btn', attr: this.params.attr, html: this.params.html })
18
+ }
19
+ }
20
+ }
21
+
22
+ export default btnBack
@@ -0,0 +1,39 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function btnClone () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbBtnClone extends WdbBase {
7
+ async build () {
8
+ const { req } = this.component
9
+ const { isEmpty, get } = this.plugin.app.bajo.lib._
10
+ this.params.noTag = true
11
+ const schema = get(this, 'component.locals.schema', {})
12
+ if (schema.view.disabled.includes('create')) {
13
+ this.params.html = ''
14
+ return
15
+ }
16
+ if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('Clone')
17
+ this.params.attr.color = this.params.attr.color ?? 'secondary-outline'
18
+ if (!this.params.attr.href) this.params.attr.href = this.component.buildUrl({ base: 'add', exclude: ['id'] }) + '&mode=clone'
19
+ if (this.params.attr.onList) {
20
+ this.params.attr['x-ref'] = 'clone'
21
+ this.params.attr.disabled = true
22
+ this.params.attr['x-data'] = `{
23
+ path: '${this.params.attr.href}'
24
+ }`
25
+ this.params.attr['@on-selection.window'] = `
26
+ const recId = $event.detail[0] ?? ''
27
+ if ($event.detail.length === 1) $refs.clone.classList.remove('disabled')
28
+ else $refs.clone.classList.add('disabled')
29
+ $refs.clone.href = path + '&id=' + recId
30
+ `
31
+ } else {
32
+ this.params.attr.href += '&id=' + req.query.id
33
+ }
34
+ this.params.html = await this.component.buildTag({ tag: 'btn', attr: this.params.attr, html: this.params.html })
35
+ }
36
+ }
37
+ }
38
+
39
+ export default btnClone
@@ -0,0 +1,55 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function btnColumns () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbBtnColumns extends WdbBase {
7
+ async build () {
8
+ const { get, isEmpty, without } = this.plugin.app.bajo.lib._
9
+ const { jsonStringify } = this.plugin.app.waibuMpa
10
+ const { req } = this.component
11
+ const qsKey = this.plugin.app.waibu.config.qsKey
12
+ const schema = get(this, 'component.locals.schema', {})
13
+ if (schema.view.disabled.includes('find')) {
14
+ this.params.html = ''
15
+ return
16
+ }
17
+ let fields = without(get(this, `component.locals._meta.query.${qsKey.fields}`, '').split(','), '')
18
+ if (isEmpty(fields)) fields = schema.view.fields
19
+ const items = []
20
+ this.params.attr.color = this.params.attr.color ?? 'secondary-outline'
21
+ if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('Columns')
22
+ for (const f of schema.view.fields) {
23
+ if (f === 'id') {
24
+ items.push(await this.component.buildTag({ tag: 'formCheck', attr: { checked: true, label: req.t('ID'), value: f, disabled: true } }))
25
+ continue
26
+ }
27
+ const attr = { 'x-model': 'selected', label: req.t(`field.${f}`), value: f }
28
+ if (fields.includes(f)) attr.checked = true
29
+ items.push(await this.component.buildTag({ tag: 'formCheck', attr }))
30
+ }
31
+ const href = this.component.buildUrl({ exclude: [qsKey.fields] })
32
+ const html = ['<form class="mt-1 mb-2 mx-3" ']
33
+ html.push(`x-data="{
34
+ selected: ${jsonStringify(fields, true)},
35
+ all: ${jsonStringify(schema.view.fields, true)}
36
+ }"`)
37
+ html.push(`x-init="
38
+ $refs.apply.href = '${href}&${qsKey.fields}=' + selected.join(',')
39
+ $watch('selected', v => {
40
+ $refs.apply.href = '${href}&${qsKey.fields}=' + v.join(',')
41
+ })
42
+ ">`)
43
+ html.push(...items)
44
+ const attr = { size: 'sm', 'x-ref': 'apply', margin: 'top-2', color: this.params.attr.applyColor ?? 'primary', icon: this.params.attr.applyIcon ?? 'arrowsStartEnd', href }
45
+ html.push(await this.component.buildTag({ tag: 'btn', attr, html: req.t('Apply') }))
46
+ html.push('</form>')
47
+ this.params.attr.autoClose = 'outside'
48
+ this.params.attr.triggerColor = this.params.attr.color
49
+ this.params.html = await this.component.buildTag({ tag: 'dropdown', attr: this.params.attr, html: html.join('\n') })
50
+ this.params.noTag = true
51
+ }
52
+ }
53
+ }
54
+
55
+ export default btnColumns
@@ -0,0 +1,52 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function btnDelete () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbBtnDelete extends WdbBase {
7
+ async build () {
8
+ const { req } = this.component
9
+ const { generateId } = this.plugin.app.bajo
10
+ const { isEmpty, get } = this.plugin.app.bajo.lib._
11
+ this.params.noTag = true
12
+ const schema = get(this, 'component.locals.schema', {})
13
+ if (schema.view.disabled.includes('remove')) {
14
+ this.params.html = ''
15
+ return
16
+ }
17
+ if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('Delete')
18
+ this.params.attr.color = this.params.attr.color ?? 'danger-outline'
19
+ this.params.attr.id = generateId('alpha')
20
+ if (this.params.attr.onList) {
21
+ this.params.attr.disabled = true
22
+ this.params.attr['x-data'] = `{
23
+ selected: [],
24
+ remove (modalId, ids) {
25
+ wmpa.postForm({ ids }, '${this.component.buildUrl({ base: 'delete' })}')
26
+ }
27
+ }`
28
+ this.params.attr['@on-selection.window'] = `
29
+ const el = document.getElementById('${this.params.attr.id}')
30
+ selected = $event.detail
31
+ if (selected.length > 0) el.classList.remove('disabled')
32
+ else el.classList.add('disabled')
33
+ `
34
+ } else {
35
+ this.params.attr['x-data'] = `{
36
+ selected: ['${req.query.id}'],
37
+ remove (modalId, ids) {
38
+ wmpa.postForm({ ids }, '${this.component.buildUrl({ base: 'delete', exclude: ['id', 'page'] })}')
39
+ }
40
+ }`
41
+ }
42
+ const msg = 'You\'re about to remove one or more records. Are you really sure to do this?'
43
+ this.params.attr['@click'] = `
44
+ const opts = selected.join(',')
45
+ await wbs.confirmation(\`${req.t(msg)}\`, { ok: '${this.params.attr.id}:remove', close: 'y', opts })
46
+ `
47
+ this.params.html = await this.component.buildTag({ tag: 'btn', attr: this.params.attr, html: this.params.html })
48
+ }
49
+ }
50
+ }
51
+
52
+ export default btnDelete
@@ -0,0 +1,41 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function btnDetails () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbBtnDetails extends WdbBase {
7
+ async build () {
8
+ const { req } = this.component
9
+ const { generateId } = this.plugin.app.bajo
10
+ const { isEmpty, get } = this.plugin.app.bajo.lib._
11
+ this.params.noTag = true
12
+ const schema = get(this, 'component.locals.schema', {})
13
+ if (schema.view.disabled.includes('update')) {
14
+ this.params.html = ''
15
+ return
16
+ }
17
+ if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('Details')
18
+ this.params.attr.color = this.params.attr.color ?? 'secondary-outline'
19
+ this.params.attr.id = generateId('alpha')
20
+ if (!this.params.attr.href) this.params.attr.href = this.component.buildUrl({ base: 'details', exclude: ['id'] })
21
+ if (this.params.attr.onList) {
22
+ this.params.attr.disabled = true
23
+ this.params.attr['x-ref'] = 'details'
24
+ this.params.attr['x-data'] = `{
25
+ path: '${this.params.attr.href}'
26
+ }`
27
+ this.params.attr['@on-selection.window'] = `
28
+ const recId = $event.detail[0] ?? ''
29
+ if ($event.detail.length === 1) $refs.details.classList.remove('disabled')
30
+ else $refs.details.classList.add('disabled')
31
+ $refs.details.href = path + '&id=' + recId
32
+ `
33
+ } else {
34
+ this.params.attr.href += '&id=' + req.query.id
35
+ }
36
+ this.params.html = await this.component.buildTag({ tag: 'btn', attr: this.params.attr, html: this.params.html })
37
+ }
38
+ }
39
+ }
40
+
41
+ export default btnDetails
@@ -0,0 +1,67 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function btnEdit () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbBtnEdit extends WdbBase {
7
+ async build () {
8
+ const { req } = this.component
9
+ const { generateId } = this.plugin.app.bajo
10
+ const { isEmpty, get } = this.plugin.app.bajo.lib._
11
+ this.params.noTag = true
12
+ const schema = get(this, 'component.locals.schema', {})
13
+ if (schema.view.disabled.includes('update')) {
14
+ this.params.html = ''
15
+ return
16
+ }
17
+ if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('Edit')
18
+ this.params.attr.color = this.params.attr.color ?? 'secondary-outline'
19
+ this.params.attr.id = generateId('alpha')
20
+ if (!this.params.attr.href) this.params.attr.href = this.component.buildUrl({ base: 'edit', exclude: ['id'] })
21
+ if (this.params.attr.onList) {
22
+ this.params.attr.split = true
23
+ this.params.attr.triggerDisabled = true
24
+ this.params.attr.triggerId = this.params.attr.id
25
+ this.params.attr['trigger-x-data'] = `{
26
+ path: '${this.params.attr.href}'
27
+ }`
28
+ if (this.params.attr.noClone) {
29
+ this.params.attr['trigger-@on-selection.window'] = `
30
+ const recId = $event.detail[0] ?? ''
31
+ const el = document.getElementById('${this.params.attr.id}')
32
+ if ($event.detail.length === 1) el.classList.remove('disabled')
33
+ else el.classList.add('disabled')
34
+ el.href = path + '&id=' + recId
35
+ `
36
+ this.params.html = await this.component.buildTag({ tag: 'btn', attr: this.params.attr, html: this.params.html })
37
+ } else {
38
+ this.params.attr['trigger-@on-selection.window'] = `
39
+ const recId = $event.detail[0] ?? ''
40
+ const elId = '${this.params.attr.id}'
41
+ for (const id of [elId, elId + '-split']) {
42
+ const el = document.getElementById(id)
43
+ if ($event.detail.length === 1) el.classList.remove('disabled')
44
+ else el.classList.add('disabled')
45
+ const href = path + '&id=' + recId
46
+ if (id.slice(-6) === '-split') {
47
+ const selector = '#' + id.replace('-split', '-menu') + ' a.dropdown-item'
48
+ const item = document.querySelector(selector)
49
+ item.href = href.replace('edit?&id=', 'add?&id=') + '&mode=clone'
50
+ } else el.href = href
51
+ }
52
+ `
53
+ const html = [
54
+ await this.component.buildTag({ tag: 'dropdownItem', attr: { content: req.t('Add as New Clone') } })
55
+ ]
56
+ this.params.attr.triggerColor = this.params.attr.color
57
+ this.params.html = await this.component.buildTag({ tag: 'dropdown', attr: this.params.attr, html: html.join('\n') })
58
+ }
59
+ } else {
60
+ this.params.attr.href += '&id=' + req.query.id
61
+ this.params.html = await this.component.buildTag({ tag: 'btn', attr: this.params.attr, html: this.params.html })
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ export default btnEdit
@@ -0,0 +1,138 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function btnExport () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbBtnExport extends WdbBase {
7
+ async build () {
8
+ const { isEmpty, get } = this.plugin.app.bajo.lib._
9
+ const { req } = this.component
10
+ this.params.noTag = true
11
+ const schema = get(this, 'component.locals.schema', {})
12
+ if (schema.view.disabled.includes('find')) {
13
+ this.params.html = ''
14
+ return
15
+ }
16
+ if (isEmpty(this.params.attr.launch)) this.params.attr.launch = req.t('Export')
17
+ this.params.attr.launchColor = this.params.attr.launchColor ?? 'secondary-outline'
18
+ this.params.attr.title = req.t('Data Export')
19
+ const html = await this.component.buildSentence(`
20
+ <c:div x-data="{
21
+ delivery: 'clipboard',
22
+ options: [],
23
+ ftype: 'json',
24
+ toggle (val) {
25
+ if (val === 'clipboard') {
26
+ $refs.zip.setAttribute('disabled', '')
27
+ $refs.xlsx.setAttribute('disabled', '')
28
+ $refs.xml.setAttribute('disabled', '')
29
+ _.pull(this.options, 'zip')
30
+ if (!['json', 'csv'].includes(this.ftype)) this.ftype = 'json'
31
+ } else {
32
+ $refs.zip.removeAttribute('disabled')
33
+ $refs.xlsx.removeAttribute('disabled')
34
+ $refs.xml.removeAttribute('disabled')
35
+ }
36
+ },
37
+ extractForm (selector) {
38
+ let item = {}
39
+ const els = document.querySelectorAll(selector + ' [data-value]')
40
+ for (const el of els) {
41
+ const value = this.options.includes('fvalue') ? el.getAttribute('value') : wmpa.parseValue(el.dataset.value, el.dataset.type)
42
+ let key = el.getAttribute('name')
43
+ if (this.options.includes('fkey')) {
44
+ try {
45
+ const elLabel = document.querySelector('label[for=' + el.getAttribute('id') + ']')
46
+ key = elLabel.innerText
47
+ } catch (err) {}
48
+ }
49
+ item[key] = value
50
+ }
51
+ return this.ftype === 'csv' ? CSVJSON.json2csv(item) : JSON.stringify(item)
52
+ },
53
+ extractTable (selector) {
54
+ let items = []
55
+ let checker = false
56
+ const keys = []
57
+ const types = []
58
+ let els = document.querySelectorAll(selector + ' thead th')
59
+ for (const el of els) {
60
+ keys.push(this.options.includes('fkey') ? el.innerText : el.dataset.key)
61
+ types.push(el.dataset.type)
62
+ }
63
+ if (_.isEmpty(keys[0])) {
64
+ checker = true
65
+ keys.shift()
66
+ types.shift()
67
+ }
68
+ els = document.querySelectorAll(selector + ' tbody tr')
69
+ for (const el of els) {
70
+ let data = []
71
+ _.each(el.children, (v, i) => {
72
+ if ((i + '') === '0' && checker) return undefined
73
+ data.push(this.options.includes('fvalue') ? v.innerText : wmpa.parseValue(v.dataset.value, types[parseInt(i - 1)]))
74
+ })
75
+ const item = {}
76
+ for (const i in keys) {
77
+ item[keys[i]] = data[i]
78
+ }
79
+ items.push(item)
80
+ }
81
+ return this.ftype === 'csv' ? CSVJSON.json2csv(items) : JSON.stringify(items)
82
+ },
83
+ async submit () {
84
+ const instance = wbs.getInstance('Modal', $refs.export)
85
+ const handler = '${this.params.attr.handler ?? ''}'
86
+ if (this.delivery === 'clipboard') {
87
+ const selector = '${this.params.attr.selector}'
88
+ if (_.isEmpty(selector)) {
89
+ await wbs.notify('Cant get data selector', { type: 'danger' })
90
+ } else {
91
+ const item = handler === 'list' ? this.extractTable(selector) : this.extractForm(selector)
92
+ await wbs.copyToClipboard(item)
93
+ }
94
+ instance.hide()
95
+ return
96
+ }
97
+ wmpa.postForm({ options: this.options.join(','), ftype: this.ftype, handler }, '${this.component.buildUrl({ base: 'export' })}')
98
+ instance.hide()
99
+ }
100
+ }" x-init="
101
+ toggle(delivery)
102
+ $watch('delivery', val => toggle(val))
103
+ ">
104
+ <c:grid-row gutter="2">
105
+ <c:grid-col col="6-md">
106
+ <c:fieldset t:legend="Delivery" legend-type="6">
107
+ <c:form-radio x-model="delivery" value="file" t:label="Save as File" />
108
+ <c:form-radio x-model="delivery" value="clipboard" t:label="Copy to Clipboard" />
109
+ </c:fieldset>
110
+ <c:fieldset t:legend="Options" legend-type="6" margin="top-2">
111
+ <c:form-check x-ref="fkey" x-model="options" value="fkey" t:label="Formatted Field" />
112
+ <c:form-check x-ref="fvalue" x-model="options" value="fvalue" t:label="Formatted Value" />
113
+ <c:form-check x-ref="zip" x-model="options" value="zip" t:label="Zipped" />
114
+ </c:fieldset>
115
+ </c:grid-col>
116
+ <c:grid-col col="6-md">
117
+ <c:fieldset t:legend="File Type" legend-type="6">
118
+ <c:form-radio x-ref="xlsx" x-model="ftype" value="xlsx" t:label="Excel XLSX" />
119
+ <c:form-radio x-ref="csv" x-model="ftype" value="csv" t:label="CSV" />
120
+ <c:form-radio x-ref="xml" x-model="ftype" value="xml" t:label="XML" />
121
+ <c:form-radio x-ref="json" x-model="ftype" value="json" t:label="JSON" />
122
+ </c:fieldset />
123
+ </c:grid-col>
124
+ </c:grid-row>
125
+ <c:div flex="justify-content:end" margin="top-3">
126
+ <c:btn color="secondary" t:content="Close" dismiss />
127
+ <c:btn color="primary" t:content="Submit" margin="start-2" @click="await submit()" />
128
+ </c:div>
129
+ </c:div>
130
+ `)
131
+ this.params.attr['x-data'] = true
132
+ this.params.attr['x-ref'] = 'export'
133
+ this.params.html = await this.component.buildTag({ tag: 'modal', attr: this.params.attr, html })
134
+ }
135
+ }
136
+ }
137
+
138
+ export default btnExport
@@ -0,0 +1,67 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ async function echarts () {
4
+ const WdbBase = await wdbBase.call(this)
5
+
6
+ return class WdbEcharts extends WdbBase {
7
+ static scripts = [...super.scripts,
8
+ '^waibuExtra.virtual:/echarts/echarts.min.js'
9
+ ]
10
+
11
+ constructor (options) {
12
+ super(options)
13
+ this.defOption = {
14
+ grid: {
15
+ top: 8,
16
+ bottom: 20,
17
+ left: 25,
18
+ right: 0
19
+ }
20
+ }
21
+ }
22
+
23
+ async build () {
24
+ const { defaultsDeep, generateId } = this.plugin.app.bajo
25
+ const { base64JsonDecode, jsonStringify } = this.plugin.app.waibuMpa
26
+ const { cloneDeep } = this.plugin.app.bajo.lib._
27
+ this.params.attr.dim = this.params.attr.dim ?? 'width:100 height:100'
28
+ this.params.attr.id = generateId('alpha')
29
+ this.params.attr['x-data'] = `chart${this.params.attr.id}`
30
+ this.params.attr['@resize.window.debounce.500ms'] = `
31
+ if (chart) {
32
+ chart.resize()
33
+ }
34
+ `
35
+ let option = cloneDeep(this.defOption)
36
+ if (this.params.attr.option === true) this.params.attr.option = 'e30='
37
+ if (this.params.attr.option) option = defaultsDeep(base64JsonDecode(this.params.attr.option), this.defOption)
38
+ this.params.attr['x-init'] = `
39
+ $watch('option', val => {
40
+ if (chart) chart.setOption(val)
41
+ })
42
+ `
43
+ this.params.append = `
44
+ <script>
45
+ document.addEventListener('alpine:init', () => {
46
+ Alpine.data('chart${this.params.attr.id}', () => {
47
+ let chart
48
+ return {
49
+ init () {
50
+ const el = document.getElementById('${this.params.attr.id}')
51
+ chart = echarts.init(el, null, { renderer: 'canvas' })
52
+ chart.setOption(this.option)
53
+ },
54
+ get chart () {
55
+ return chart
56
+ },
57
+ option: ${jsonStringify(option, true)}
58
+ }
59
+ })
60
+ })
61
+ </script>
62
+ `
63
+ }
64
+ }
65
+ }
66
+
67
+ export default echarts
@@ -0,0 +1,69 @@
1
+ import wdbBase from '../wdb-base.js'
2
+
3
+ export function getUrlOpts (params = {}) {
4
+ const { get } = this.plugin.app.bajo.lib._
5
+ return {
6
+ params,
7
+ excludes: [
8
+ get(this, 'plugin.app.waibu.config.qsKey.lang', 'lang'),
9
+ get(this, 'plugin.app.waibuMpa.config.darkMode.qsKey', 'dark-mode')
10
+ ]
11
+ }
12
+ }
13
+
14
+ async function pagination () {
15
+ const WdbBase = await wdbBase.call(this)
16
+
17
+ return class WdbPagination extends WdbBase {
18
+ async build () {
19
+ const { req } = this.component
20
+ const { attrToObject, paginationLayout, groupAttrs } = this.plugin.app.waibuMpa
21
+ const { get, isNumber } = this.plugin.app.bajo.lib._
22
+ const schema = get(this, 'component.locals.schema', {})
23
+ if (schema.view.disabled.includes('find')) {
24
+ this.params.html = ''
25
+ return
26
+ }
27
+ let { count, limit, page } = attrToObject(this.params.attr.options)
28
+ count = count ?? get(this, 'component.locals.list.count', 0)
29
+ limit = limit ?? get(this, 'component.locals.list.limit', 25)
30
+ page = page ?? get(this, 'component.locals.list.page', 1)
31
+ const pages = paginationLayout(count, limit, page) ?? []
32
+ this.params.noTag = true
33
+ const group = groupAttrs(this.params.attr, ['pagination'])
34
+ const html = []
35
+ let icon
36
+ let attr
37
+ if (this.params.attr.first) {
38
+ icon = await this.component.buildTag({ tag: 'icon', attr: { name: this.params.attr.firstIcon ?? 'playSkipStart' } })
39
+ attr = { disabled: page <= pages[0], href: this.component.buildUrl(getUrlOpts.call(this, { page: 1 })) }
40
+ html.push(await this.component.buildTag({ tag: 'paginationItem', attr, html: icon }))
41
+ }
42
+ if (this.params.attr.prev) {
43
+ icon = await this.component.buildTag({ tag: 'icon', attr: { name: this.params.attr.prevIcon ?? 'playFastBackward' } })
44
+ attr = { disabled: page <= pages[0], href: this.component.buildUrl(getUrlOpts.call(this, { page: page - 1 })) }
45
+ html.push(await this.component.buildTag({ tag: 'paginationItem', attr, html: icon }))
46
+ }
47
+ if (!this.params.attr.noPages) {
48
+ for (const p of pages) {
49
+ attr = { disabled: p === '...', href: this.component.buildUrl(getUrlOpts.call(this, { page: p })), active: p === page }
50
+ html.push(await this.component.buildTag({ tag: 'paginationItem', attr, html: isNumber(p) ? req.format(p, 'integer') : p }))
51
+ }
52
+ }
53
+ if (this.params.attr.next) {
54
+ icon = await this.component.buildTag({ tag: 'icon', attr: { name: this.params.attr.nextIcon ?? 'playFastForward' } })
55
+ attr = { disabled: page >= pages[pages.length - 1], href: this.component.buildUrl(getUrlOpts.call(this, { page: page + 1 })) }
56
+ html.push(await this.component.buildTag({ tag: 'paginationItem', attr, html: icon }))
57
+ }
58
+ if (this.params.attr.last) {
59
+ icon = await this.component.buildTag({ tag: 'icon', attr: { name: this.params.attr.lastIcon ?? 'playSkipEnd' } })
60
+ attr = { disabled: page >= pages[pages.length - 1], href: this.component.buildUrl(getUrlOpts.call(this, { page: pages[pages.length - 1] })) }
61
+ html.push(await this.component.buildTag({ tag: 'paginationItem', attr, html: icon }))
62
+ }
63
+ this.params.attr = group.pagination
64
+ this.params.html = await this.component.buildTag({ tag: 'pagination', attr: this.params.attr, html: html.join('\n') })
65
+ }
66
+ }
67
+ }
68
+
69
+ export default pagination