@operato/data-grist 10.29.14 → 10.29.18
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/CHANGELOG.md +18 -0
- package/coverage/lcov-report/index.html +161 -161
- package/coverage/lcov-report/webpack/bootstrap.html +1 -1
- package/coverage/lcov-report/webpack/index.html +1 -1
- package/coverage/lcov-report/webpack/runtime/define property getters.html +1 -1
- package/coverage/lcov-report/webpack/runtime/global.html +1 -1
- package/coverage/lcov-report/webpack/runtime/hasOwnProperty shorthand.html +1 -1
- package/coverage/lcov-report/webpack/runtime/index.html +1 -1
- package/coverage/lcov-report/webpack/runtime/make namespace object.html +1 -1
- package/coverage/lcov.info +37856 -37153
- package/dist/src/filters/filters-form.js +33 -47
- package/dist/src/filters/filters-form.js.map +1 -1
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.d.ts +1 -1
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +23 -1
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -1
- package/dist/test/filter-labels.test.d.ts +2 -0
- package/dist/test/filter-labels.test.js +60 -0
- package/dist/test/filter-labels.test.js.map +1 -0
- package/dist/test/record-view-popup-editor.test.d.ts +1 -0
- package/dist/test/record-view-popup-editor.test.js +58 -0
- package/dist/test/record-view-popup-editor.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/test/filter-labels.test.ts +68 -0
- package/test/record-view-popup-editor.test.ts +68 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@operato/data-grist",
|
|
3
|
-
"version": "10.29.
|
|
3
|
+
"version": "10.29.18",
|
|
4
4
|
"description": "User interface for grid (desktop) and list (mobile)",
|
|
5
5
|
"author": "heartyoh",
|
|
6
6
|
"type": "module",
|
|
@@ -70,12 +70,12 @@
|
|
|
70
70
|
"@material/web": "^2.0.0",
|
|
71
71
|
"@operato/headroom": "^10.29.1",
|
|
72
72
|
"@operato/i18n": "^10.29.1",
|
|
73
|
-
"@operato/input": "^10.29.
|
|
73
|
+
"@operato/input": "^10.29.17",
|
|
74
74
|
"@operato/list-state": "^10.29.1",
|
|
75
|
-
"@operato/p13n": "^10.29.
|
|
76
|
-
"@operato/popup": "^10.29.
|
|
75
|
+
"@operato/p13n": "^10.29.17",
|
|
76
|
+
"@operato/popup": "^10.29.17",
|
|
77
77
|
"@operato/pull-to-refresh": "^10.29.1",
|
|
78
|
-
"@operato/styles": "^10.29.
|
|
78
|
+
"@operato/styles": "^10.29.17",
|
|
79
79
|
"@operato/time-calculator": "^10.29.1",
|
|
80
80
|
"@operato/utils": "^10.29.1",
|
|
81
81
|
"i18next": "^24.2.1",
|
|
@@ -116,5 +116,5 @@
|
|
|
116
116
|
"prettier --write"
|
|
117
117
|
]
|
|
118
118
|
},
|
|
119
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "f3adef5197cdb03b1efbdb123dc935a80b6ddc00"
|
|
120
120
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/* Elements are compared by presence, not by value: a failing element comparison makes chai render the DOM and hang the runner. */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing'
|
|
3
|
+
import { html } from 'lit'
|
|
4
|
+
|
|
5
|
+
import '../src/data-grist.js'
|
|
6
|
+
import '../src/filters/filters-form.js'
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Every filter in the form says what it filters, beside its chooser. A select once carried its name only as a
|
|
10
|
+
* placeholder, which a chosen value replaces - the bar then showed 「진행 중」 with nothing saying it was the status.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const columns = [
|
|
14
|
+
{ type: 'string', name: 'name', header: 'name', filter: 'i_like' },
|
|
15
|
+
{ type: 'select', name: 'status', header: 'status', record: { options: ['', 'OPEN', 'CLOSED'] }, filter: 'in' },
|
|
16
|
+
{ type: 'select', name: 'kind', header: 'kind', record: { options: ['', 'A', 'B'] }, filter: true },
|
|
17
|
+
{ type: 'date', name: 'day', header: 'day', filter: 'between' }
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
const settle = (ms = 150) => new Promise(resolve => setTimeout(resolve, ms))
|
|
21
|
+
|
|
22
|
+
describe('필터 라벨', () => {
|
|
23
|
+
const ignoreResizeLoop = (e: ErrorEvent) => {
|
|
24
|
+
if (String(e.message).includes('ResizeObserver loop')) {
|
|
25
|
+
e.stopImmediatePropagation()
|
|
26
|
+
e.preventDefault()
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
let previousOnError: OnErrorEventHandler = null
|
|
30
|
+
|
|
31
|
+
before(() => {
|
|
32
|
+
window.addEventListener('error', ignoreResizeLoop, true)
|
|
33
|
+
previousOnError = window.onerror
|
|
34
|
+
window.onerror = (message, ...rest) =>
|
|
35
|
+
String(message).includes('ResizeObserver loop') ? true : previousOnError?.call(window, message, ...rest)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
after(() => {
|
|
39
|
+
window.removeEventListener('error', ignoreResizeLoop, true)
|
|
40
|
+
window.onerror = previousOnError
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('every filter, a select too, sits in a label that names it', async () => {
|
|
44
|
+
const el = (await fixture(html`
|
|
45
|
+
<ox-grist
|
|
46
|
+
style="height: 300px"
|
|
47
|
+
mode="GRID"
|
|
48
|
+
.config=${{ columns, pagination: { pages: [20] } }}
|
|
49
|
+
.fetchHandler=${async () => ({ page: 1, limit: 20, total: 0, records: [] })}
|
|
50
|
+
>
|
|
51
|
+
<div slot="headroom"><ox-filters-form without-search></ox-filters-form></div>
|
|
52
|
+
</ox-grist>
|
|
53
|
+
`)) as any
|
|
54
|
+
await settle()
|
|
55
|
+
|
|
56
|
+
const form = el.querySelector('ox-filters-form') as any
|
|
57
|
+
await form.updateComplete
|
|
58
|
+
const root = form.renderRoot as ShadowRoot
|
|
59
|
+
const named = (name: string) => root.querySelector(`[name="${name}"]`)
|
|
60
|
+
for (const name of ['name', 'status', 'kind', 'day']) {
|
|
61
|
+
const chooser = named(name)
|
|
62
|
+
expect(!!chooser, `${name} is rendered`).to.equal(true)
|
|
63
|
+
const label = chooser!.closest('label[filter-title]')
|
|
64
|
+
expect(!!label, `${name} sits in a label`).to.equal(true)
|
|
65
|
+
expect(label!.querySelector('span')?.textContent?.trim()).to.equal(name)
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
})
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/* Elements are compared by presence, not by value: a failing element comparison makes chai render the DOM and hang the runner. */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing'
|
|
3
|
+
import { html } from 'lit'
|
|
4
|
+
|
|
5
|
+
import '../src/record-view/record-view.js'
|
|
6
|
+
import { buildColumn } from '../src/configure/column-builder.js'
|
|
7
|
+
import { OxGristEditor } from '../src/editors/ox-grist-editor.js'
|
|
8
|
+
import { registerEditor } from '../src/editors/registry.js'
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* In a form (ox-record-view - the 「만들기」 dialog of a grid) a field is pressed to be edited. A field whose editor
|
|
12
|
+
* opens a popup used to become 「editing」 on the first press but open nothing until its editor was pressed again,
|
|
13
|
+
* so what was typed after the first press went nowhere (pdf template 「만들기」, body HTML, 2026-10-10).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
let opened = 0
|
|
17
|
+
|
|
18
|
+
class ProbePopupEditor extends OxGristEditor {
|
|
19
|
+
static opensPopup = true
|
|
20
|
+
|
|
21
|
+
_onclick(e: Event): void {
|
|
22
|
+
e.stopPropagation()
|
|
23
|
+
opened++
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
customElements.define('probe-popup-editor', ProbePopupEditor)
|
|
27
|
+
registerEditor('probe-popup', ProbePopupEditor)
|
|
28
|
+
|
|
29
|
+
const settle = (ms = 100) => new Promise(resolve => setTimeout(resolve, ms))
|
|
30
|
+
|
|
31
|
+
describe('a popup field in a form', () => {
|
|
32
|
+
it('opens its popup on the first press', async () => {
|
|
33
|
+
opened = 0
|
|
34
|
+
const columns = [
|
|
35
|
+
buildColumn({ type: 'string', name: 'name', header: 'name', record: { editable: true } } as any),
|
|
36
|
+
buildColumn({ type: 'probe-popup', name: 'body', header: 'body', record: { editable: true } } as any)
|
|
37
|
+
]
|
|
38
|
+
const view = (await fixture(html`<ox-record-view .columns=${columns} .record=${{}}></ox-record-view>`)) as any
|
|
39
|
+
await view.updateComplete
|
|
40
|
+
await settle()
|
|
41
|
+
|
|
42
|
+
const body = view.renderRoot.querySelector('ox-record-view-body') as any
|
|
43
|
+
await body.updateComplete
|
|
44
|
+
const field = Array.from(body.renderRoot.querySelectorAll('ox-grid-field') as NodeListOf<any>).find(one => one.column?.name === 'body')
|
|
45
|
+
expect(!!field, 'the body field is drawn').to.equal(true)
|
|
46
|
+
|
|
47
|
+
field.click()
|
|
48
|
+
await settle(200)
|
|
49
|
+
|
|
50
|
+
expect(field.getAttribute('editing'), 'the field is being edited').to.equal('true')
|
|
51
|
+
expect(opened, 'the popup editor was opened once').to.equal(1)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('leaves a field edited in place as it was - nothing extra is pressed', async () => {
|
|
55
|
+
opened = 0
|
|
56
|
+
const columns = [buildColumn({ type: 'string', name: 'name', header: 'name', record: { editable: true } } as any)]
|
|
57
|
+
const view = (await fixture(html`<ox-record-view .columns=${columns} .record=${{}}></ox-record-view>`)) as any
|
|
58
|
+
await view.updateComplete
|
|
59
|
+
await settle()
|
|
60
|
+
const body = view.renderRoot.querySelector('ox-record-view-body') as any
|
|
61
|
+
await body.updateComplete
|
|
62
|
+
const field = body.renderRoot.querySelector('ox-grid-field') as any
|
|
63
|
+
field.click()
|
|
64
|
+
await settle(200)
|
|
65
|
+
expect(field.getAttribute('editing')).to.equal('true')
|
|
66
|
+
expect(opened).to.equal(0)
|
|
67
|
+
})
|
|
68
|
+
})
|