@simai-studio/view 0.0.0-stage → 1.0.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.
- package/LICENSE.md +183 -0
- package/README.md +75 -2
- package/dist/package-receipt.json +971 -0
- package/dist/set.json +141 -0
- package/dist/smart/rule.js +278 -0
- package/dist/smart/rule.js.gz +0 -0
- package/dist/smart/view/aliases.json +129 -0
- package/dist/smart/view/aliases.json.gz +0 -0
- package/dist/smart/view/component.json +1620 -0
- package/dist/smart/view/component.json.gz +0 -0
- package/dist/smart/view/css/view.css +208 -0
- package/dist/smart/view/css/view.css.gz +0 -0
- package/dist/smart/view/css/view.min.css +2 -0
- package/dist/smart/view/css/view.min.css.gz +0 -0
- package/dist/smart/view/examples.json +668 -0
- package/dist/smart/view/examples.json.gz +0 -0
- package/dist/smart/view/js/view.js +3938 -0
- package/dist/smart/view/js/view.js.gz +0 -0
- package/dist/smart/view/js/view.min.js +1 -0
- package/dist/smart/view/js/view.min.js.gz +0 -0
- package/dist/smart/view/lang/en.json +61 -0
- package/dist/smart/view/lang/en.json.gz +0 -0
- package/dist/smart/view/lang/ru.json +61 -0
- package/dist/smart/view/lang/ru.json.gz +0 -0
- package/dist/smart/view/probe.json +165 -0
- package/dist/smart/view/probe.json.gz +0 -0
- package/dist/smart/view/smart.manifest.json +1570 -0
- package/dist/smart/view/smart.manifest.json.gz +0 -0
- package/dist/smart/view/static/default/embedded.html +96 -0
- package/dist/smart/view/static/default/embedded.html.gz +0 -0
- package/dist/smart/view/static/default/open-record.html +247 -0
- package/dist/smart/view/static/default/open-record.html.gz +0 -0
- package/dist/smart/view/static/default/reference.html +247 -0
- package/dist/smart/view/static/default/reference.html.gz +0 -0
- package/dist/smart/view/static/sheets.json +282 -0
- package/dist/smart/view/static/sheets.json.gz +0 -0
- package/dist/smart/view-properties/aliases.json +174 -0
- package/dist/smart/view-properties/aliases.json.gz +0 -0
- package/dist/smart/view-properties/component.json +1898 -0
- package/dist/smart/view-properties/component.json.gz +0 -0
- package/dist/smart/view-properties/css/view-properties.css +1153 -0
- package/dist/smart/view-properties/css/view-properties.css.gz +0 -0
- package/dist/smart/view-properties/css/view-properties.min.css +2 -0
- package/dist/smart/view-properties/css/view-properties.min.css.gz +0 -0
- package/dist/smart/view-properties/examples.json +841 -0
- package/dist/smart/view-properties/examples.json.gz +0 -0
- package/dist/smart/view-properties/js/view-properties.js +10416 -0
- package/dist/smart/view-properties/js/view-properties.js.gz +0 -0
- package/dist/smart/view-properties/js/view-properties.min.js +1421 -0
- package/dist/smart/view-properties/js/view-properties.min.js.gz +0 -0
- package/dist/smart/view-properties/lang/en.json +96 -0
- package/dist/smart/view-properties/lang/en.json.gz +0 -0
- package/dist/smart/view-properties/lang/ru.json +96 -0
- package/dist/smart/view-properties/lang/ru.json.gz +0 -0
- package/dist/smart/view-properties/probe.json +188 -0
- package/dist/smart/view-properties/probe.json.gz +0 -0
- package/dist/smart/view-properties/skeleton.html +13 -0
- package/dist/smart/view-properties/skeleton.html.gz +0 -0
- package/dist/smart/view-properties/smart.manifest.json +1590 -0
- package/dist/smart/view-properties/smart.manifest.json.gz +0 -0
- package/dist/smart/view-properties/static/default/full.html +2 -0
- package/dist/smart/view-properties/static/default/full.html.gz +0 -0
- package/dist/smart/view-properties/static/default/panel-closed.html +4 -0
- package/dist/smart/view-properties/static/default/panel-closed.html.gz +0 -0
- package/dist/smart/view-properties/static/default/panel.html +4 -0
- package/dist/smart/view-properties/static/default/panel.html.gz +0 -0
- package/dist/smart/view-properties/static/default/reference.html +2 -0
- package/dist/smart/view-properties/static/default/reference.html.gz +0 -0
- package/dist/smart/view-properties/static/sheets.json +426 -0
- package/dist/smart/view-properties/static/sheets.json.gz +0 -0
- package/dist/smart/view-properties/template/default.css +989 -0
- package/dist/smart/view-properties/template/default.css.gz +0 -0
- package/dist/smart/view-properties/template/default.js +1660 -0
- package/dist/smart/view-properties/template/default.js.gz +0 -0
- package/dist/smart/view-table/aliases.json +448 -0
- package/dist/smart/view-table/aliases.json.gz +0 -0
- package/dist/smart/view-table/component.json +2738 -0
- package/dist/smart/view-table/component.json.gz +0 -0
- package/dist/smart/view-table/css/view-table.css +3658 -0
- package/dist/smart/view-table/css/view-table.css.gz +0 -0
- package/dist/smart/view-table/css/view-table.min.css +2 -0
- package/dist/smart/view-table/css/view-table.min.css.gz +0 -0
- package/dist/smart/view-table/examples.json +499 -0
- package/dist/smart/view-table/examples.json.gz +0 -0
- package/dist/smart/view-table/js/view-table.js +13879 -0
- package/dist/smart/view-table/js/view-table.js.gz +0 -0
- package/dist/smart/view-table/js/view-table.min.js +1440 -0
- package/dist/smart/view-table/js/view-table.min.js.gz +0 -0
- package/dist/smart/view-table/lang/en.json +132 -0
- package/dist/smart/view-table/lang/en.json.gz +0 -0
- package/dist/smart/view-table/lang/ru.json +132 -0
- package/dist/smart/view-table/lang/ru.json.gz +0 -0
- package/dist/smart/view-table/probe.json +275 -0
- package/dist/smart/view-table/probe.json.gz +0 -0
- package/dist/smart/view-table/smart.manifest.json +2524 -0
- package/dist/smart/view-table/smart.manifest.json.gz +0 -0
- package/dist/smart/view-table/static/default/current.html +141 -0
- package/dist/smart/view-table/static/default/current.html.gz +0 -0
- package/dist/smart/view-table/static/default/current.skeleton.html +141 -0
- package/dist/smart/view-table/static/default/current.skeleton.html.gz +0 -0
- package/dist/smart/view-table/static/default/empty.html +149 -0
- package/dist/smart/view-table/static/default/empty.html.gz +0 -0
- package/dist/smart/view-table/static/default/loading.html +180 -0
- package/dist/smart/view-table/static/default/loading.html.gz +0 -0
- package/dist/smart/view-table/static/default/many.html +180 -0
- package/dist/smart/view-table/static/default/many.html.gz +0 -0
- package/dist/smart/view-table/static/default/reference.html +136 -0
- package/dist/smart/view-table/static/default/reference.html.gz +0 -0
- package/dist/smart/view-table/static/default/reference.skeleton.html +136 -0
- package/dist/smart/view-table/static/default/reference.skeleton.html.gz +0 -0
- package/dist/smart/view-table/static/default/typed-cells.html +229 -0
- package/dist/smart/view-table/static/default/typed-cells.html.gz +0 -0
- package/dist/smart/view-table/static/default/typed-cells.skeleton.html +229 -0
- package/dist/smart/view-table/static/default/typed-cells.skeleton.html.gz +0 -0
- package/dist/smart/view-table/static/sheets.json +480 -0
- package/dist/smart/view-table/static/sheets.json.gz +0 -0
- package/dist/smart/view-table/studio.fixture.json +17 -0
- package/dist/smart/view-table/studio.fixture.json.gz +0 -0
- package/dist/smart/view-table/studio.scenario.json +30 -0
- package/dist/smart/view-table/studio.scenario.json.gz +0 -0
- package/dist/smart/view-table/template/default.css +1301 -0
- package/dist/smart/view-table/template/default.css.gz +0 -0
- package/dist/smart/view-table/template/default.js +1215 -0
- package/dist/smart/view-table/template/default.js.gz +0 -0
- package/dist/smart/view-table/template/link-cell-contract.js +48 -0
- package/dist/smart/view-table/template/link-cell-contract.js.gz +0 -0
- package/package.json +29 -4
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
{
|
|
2
|
+
"examples": [
|
|
3
|
+
{
|
|
4
|
+
"name": "reference",
|
|
5
|
+
"title": "Записи",
|
|
6
|
+
"settings": {
|
|
7
|
+
"aria-label": "Записи",
|
|
8
|
+
"table-settings-key": "docs.records",
|
|
9
|
+
"columns": [
|
|
10
|
+
{
|
|
11
|
+
"key": "title",
|
|
12
|
+
"label": "Название",
|
|
13
|
+
"sortable": true
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"key": "status",
|
|
17
|
+
"label": "Статус"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"rows": [
|
|
21
|
+
{
|
|
22
|
+
"id": "1",
|
|
23
|
+
"title": "Портал клиента",
|
|
24
|
+
"status": "Опубликовано",
|
|
25
|
+
"revision": "r1"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "2",
|
|
29
|
+
"title": "Каталог товаров",
|
|
30
|
+
"status": "Черновик",
|
|
31
|
+
"revision": "r1"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"expect": {
|
|
36
|
+
"name": "Записи",
|
|
37
|
+
"values": {
|
|
38
|
+
"selection": []
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"from": "studio.fixture.json",
|
|
42
|
+
"first-paint": {
|
|
43
|
+
"max-bytes": 16384,
|
|
44
|
+
"why": "A data table at rest: its toolbar (search, settings, export), the selection column and the rows, every control a printed Smart element with its own markup. Nothing closed is printed; the table itself is the first paint."
|
|
45
|
+
},
|
|
46
|
+
"studio": {
|
|
47
|
+
"title": "Data View reference",
|
|
48
|
+
"props": {
|
|
49
|
+
"aria-label": "Записи",
|
|
50
|
+
"table-settings-key": "studio.records",
|
|
51
|
+
"pagin": true,
|
|
52
|
+
"pagination-total": 3,
|
|
53
|
+
"pagination-page-size": 10
|
|
54
|
+
},
|
|
55
|
+
"scenario": {
|
|
56
|
+
"steps": [
|
|
57
|
+
{
|
|
58
|
+
"invoke": "setDataState",
|
|
59
|
+
"with": [
|
|
60
|
+
"empty"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "loading",
|
|
69
|
+
"title": "Первая загрузка",
|
|
70
|
+
"settings": {
|
|
71
|
+
"aria-label": "Записи",
|
|
72
|
+
"data-state": "loading"
|
|
73
|
+
},
|
|
74
|
+
"expect": {
|
|
75
|
+
"name": "Записи"
|
|
76
|
+
},
|
|
77
|
+
"first-paint": {
|
|
78
|
+
"max-bytes": 16384,
|
|
79
|
+
"why": "A data table at rest: its toolbar (search, settings, export), the selection column and the rows, every control a printed Smart element with its own markup. Nothing closed is printed; the table itself is the first paint."
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "empty",
|
|
84
|
+
"title": "Пусто",
|
|
85
|
+
"settings": {
|
|
86
|
+
"aria-label": "Записи",
|
|
87
|
+
"data-state": "empty",
|
|
88
|
+
"columns": [
|
|
89
|
+
{
|
|
90
|
+
"key": "title",
|
|
91
|
+
"label": "Название"
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"expect": {
|
|
96
|
+
"name": "Записи"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "current",
|
|
101
|
+
"title": "Открытая запись",
|
|
102
|
+
"settings": {
|
|
103
|
+
"aria-label": "Записи",
|
|
104
|
+
"current": "2",
|
|
105
|
+
"columns": [
|
|
106
|
+
{
|
|
107
|
+
"key": "title",
|
|
108
|
+
"label": "Название"
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
"rows": [
|
|
112
|
+
{
|
|
113
|
+
"id": "1",
|
|
114
|
+
"title": "Первая"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "2",
|
|
118
|
+
"title": "Вторая"
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
"expect": {
|
|
123
|
+
"name": "Записи",
|
|
124
|
+
"values": {
|
|
125
|
+
"selected": "2"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"first-paint": {
|
|
129
|
+
"max-bytes": 16384,
|
|
130
|
+
"why": "A data table at rest: its toolbar (search, settings, export), the selection column and the rows, every control a printed Smart element with its own markup. Nothing closed is printed; the table itself is the first paint."
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"name": "many",
|
|
135
|
+
"title": "Тысяча записей (окно)",
|
|
136
|
+
"settings": {
|
|
137
|
+
"aria-label": "Записи",
|
|
138
|
+
"x-rows": "1 000 generated rows, as probe.json p1 makes them"
|
|
139
|
+
},
|
|
140
|
+
"expect": {
|
|
141
|
+
"name": "Записи"
|
|
142
|
+
},
|
|
143
|
+
"x-note": "§18.4: the window draws the rows in view; gate 17 runs on this shape (probe.json p1, p4, p7)",
|
|
144
|
+
"first-paint": {
|
|
145
|
+
"max-bytes": 16384,
|
|
146
|
+
"why": "A data table at rest: its toolbar (search, settings, export), the selection column and the rows, every control a printed Smart element with its own markup. Nothing closed is printed; the table itself is the first paint."
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"name": "typed-cells",
|
|
151
|
+
"title": "Ссылка, файл и цвет в ячейках",
|
|
152
|
+
"settings": {
|
|
153
|
+
"aria-label": "Решения",
|
|
154
|
+
"columns": [
|
|
155
|
+
{
|
|
156
|
+
"key": "title",
|
|
157
|
+
"label": "Название"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"key": "owner",
|
|
161
|
+
"label": "Ответственный",
|
|
162
|
+
"propertyType": "record"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"key": "attachment",
|
|
166
|
+
"label": "Файл",
|
|
167
|
+
"propertyType": "file"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"key": "accent",
|
|
171
|
+
"label": "Цвет",
|
|
172
|
+
"propertyType": "color"
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
"rows": [
|
|
176
|
+
{
|
|
177
|
+
"id": "1",
|
|
178
|
+
"revision": "r1",
|
|
179
|
+
"title": "Портал клиента",
|
|
180
|
+
"owner": {
|
|
181
|
+
"value": "u-1",
|
|
182
|
+
"label": "Анна Захарова",
|
|
183
|
+
"href": "#u-1"
|
|
184
|
+
},
|
|
185
|
+
"attachment": {
|
|
186
|
+
"value": "f-1",
|
|
187
|
+
"label": "договор.pdf",
|
|
188
|
+
"mime": "application/pdf",
|
|
189
|
+
"href": "#f-1"
|
|
190
|
+
},
|
|
191
|
+
"accent": "#2f6feb"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"id": "2",
|
|
195
|
+
"revision": "r1",
|
|
196
|
+
"title": "Каталог товаров",
|
|
197
|
+
"owner": {
|
|
198
|
+
"value": "u-2",
|
|
199
|
+
"label": "Илья Петров",
|
|
200
|
+
"href": "#u-2"
|
|
201
|
+
},
|
|
202
|
+
"attachment": {
|
|
203
|
+
"value": "f-2",
|
|
204
|
+
"label": "схема.png",
|
|
205
|
+
"mime": "image/png",
|
|
206
|
+
"href": "#f-2"
|
|
207
|
+
},
|
|
208
|
+
"accent": "#1a7f37"
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
"expect": {
|
|
213
|
+
"name": "Решения"
|
|
214
|
+
},
|
|
215
|
+
"x-first-paint": "The cells sf-table draws with other Smart elements (sf-reference-link, sf-file-preview, sf-input-color): their code comes with the table's, so the rows do not move when they arrive (stand 24: CLS 0.0145 at 1280).",
|
|
216
|
+
"first-paint": {
|
|
217
|
+
"max-bytes": 16384,
|
|
218
|
+
"why": "A data table at rest with its toolbar (search, settings, export), a selection column and two rows whose cells are three printed Smart elements each (sf-reference-link, sf-file-preview, sf-input-color)."
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
],
|
|
222
|
+
"pages": [
|
|
223
|
+
{
|
|
224
|
+
"name": "conformance",
|
|
225
|
+
"title": "sf-table against component.json (standard simai.smart-component 1.3.8 §12, gate 20; §18.4 many entries)",
|
|
226
|
+
"format": "stands/15-scenarios (A4 modal: a page, probes in steps); the runner is the SIMAI Framework's tests/browser/manifest-probes.browser.mjs through tests/browser/package-manifest-probes.browser.mjs",
|
|
227
|
+
"page": {
|
|
228
|
+
"lang": "ru",
|
|
229
|
+
"body": [
|
|
230
|
+
"<main style=\"width: 1100px\">",
|
|
231
|
+
" <sf-view-table id=\"t\" aria-label=\"Записи\" table-settings-key=\"probe.table\"></sf-view-table>",
|
|
232
|
+
"</main>"
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
"checks": [
|
|
236
|
+
{
|
|
237
|
+
"id": "p1-window",
|
|
238
|
+
"title": "1 000 rows: only the rows in view and a margin are drawn, at most thirty nodes a row; a scroll moves the window and sf-table-window reports it",
|
|
239
|
+
"covers": "§18.4 window, gate 17 nodes per entry, events.window",
|
|
240
|
+
"steps": [
|
|
241
|
+
{
|
|
242
|
+
"script": "(() => { const t = document.getElementById('t'); t.setColumns([{key: 'title', label: 'Название', sortable: true}, {key: 'status', label: 'Статус'}, {key: 'amount', label: 'Сумма', type: 'number'}]); t.setRows(Array.from({length: 1000}, (_, i) => ({id: String(i + 1), title: 'Запись ' + (i + 1), status: ['active', 'done'][i % 2], amount: i * 3, revision: 'r1', actions: ['view', 'publish']}))); return true; })()",
|
|
243
|
+
"wait": 900,
|
|
244
|
+
"check": "(() => { const t = document.getElementById('t'); const drawn = t.querySelectorAll('tbody tr[data-row-id]').length; const body = t.querySelector('tbody'); let nodes = 0; const w = document.createTreeWalker(body, NodeFilter.SHOW_ALL); while (w.nextNode()) nodes++; return drawn > 10 && drawn <= 100 && t.querySelector('table').getAttribute('aria-rowcount') === '1001' && nodes / drawn <= 30; })()"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"script": "(() => { const t = document.getElementById('t'); window.__windows = []; t.addEventListener('sf-view-table-window', (event) => window.__windows.push(event.detail)); const row = t.querySelector('tbody tr[data-row-id]').getBoundingClientRect().height; window.scrollTo({top: t.querySelector('tbody').getBoundingClientRect().top + window.scrollY + row * 500, behavior: 'instant'}); return true; })()",
|
|
248
|
+
"wait": 800,
|
|
249
|
+
"check": "(() => { const t = document.getElementById('t'); const seen = [...t.querySelectorAll('tbody tr[data-row-id]')].map((row) => Number(row.dataset.rowId)); const last = window.__windows.at(-1); return window.__windows.length >= 1 && last.first > 300 && !seen.includes(1) && seen.length <= 100 && seen.every((id) => id - 1 >= last.first && id - 1 <= last.last); })()"
|
|
250
|
+
}
|
|
251
|
+
]
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"id": "p2-select",
|
|
255
|
+
"title": "a row's box: sf-table-select {ids} once, the composition port's sf-port-output once after it with its old detail, noted with its dates",
|
|
256
|
+
"covers": "events.select, values.selection, aliases sf-port-output, §18.4 a box is class markup",
|
|
257
|
+
"steps": [
|
|
258
|
+
{
|
|
259
|
+
"script": "(() => { const t = document.getElementById('t'); t.setColumns([{key: 'title', label: 'Название', sortable: true}, {key: 'status', label: 'Статус'}, {key: 'amount', label: 'Сумма', type: 'number'}]); t.setRows(Array.from({length: 3}, (_, i) => ({id: String(i + 1), title: 'Запись ' + (i + 1), status: ['active', 'done'][i % 2], amount: i * 3, revision: 'r1', actions: ['view', 'publish']}))); return true; })()",
|
|
260
|
+
"wait": 700,
|
|
261
|
+
"check": "!document.querySelector('#t tbody sf-checkbox') && Boolean(document.querySelector('#t tbody tr[data-row-id=\"2\"] input[data-sf-row-box]'))"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"user": "click:#t tbody tr[data-row-id=\"2\"] input[data-sf-row-box]",
|
|
265
|
+
"expect": {
|
|
266
|
+
"events": [
|
|
267
|
+
{
|
|
268
|
+
"name": "sf-view-table-select",
|
|
269
|
+
"count": 1,
|
|
270
|
+
"detail": {
|
|
271
|
+
"ids": [
|
|
272
|
+
"2"
|
|
273
|
+
]
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"name": "sf-port-output",
|
|
278
|
+
"count": 1,
|
|
279
|
+
"detail": {
|
|
280
|
+
"port": "selection",
|
|
281
|
+
"value": [
|
|
282
|
+
"2"
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
],
|
|
287
|
+
"values": {
|
|
288
|
+
"#t.selection": [
|
|
289
|
+
"2"
|
|
290
|
+
]
|
|
291
|
+
},
|
|
292
|
+
"journal": [
|
|
293
|
+
{
|
|
294
|
+
"from": "sf-port-output",
|
|
295
|
+
"to": "sf-table-select",
|
|
296
|
+
"since": "2026-10-27",
|
|
297
|
+
"remove_after": "2026-12-01"
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
},
|
|
301
|
+
"check": "document.querySelector('#t tbody tr[data-row-id=\"2\"]').hasAttribute('data-selected')"
|
|
302
|
+
}
|
|
303
|
+
]
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"id": "p3-apply",
|
|
307
|
+
"title": "request-action-intent answers applied and sends sf-table-apply {action, scope: entry, ids, revisions}; sf-table-action-intent follows with {action_id, record_ids}",
|
|
308
|
+
"covers": "actions.request-action-intent emits apply, aliases sf-table-action-intent",
|
|
309
|
+
"steps": [
|
|
310
|
+
{
|
|
311
|
+
"script": "(() => { const t = document.getElementById('t'); t.setColumns([{key: 'title', label: 'Название', sortable: true}, {key: 'status', label: 'Статус'}, {key: 'amount', label: 'Сумма', type: 'number'}]); t.setRows(Array.from({length: 3}, (_, i) => ({id: String(i + 1), title: 'Запись ' + (i + 1), status: ['active', 'done'][i % 2], amount: i * 3, revision: 'r1', actions: ['view', 'publish']}))); return true; })()",
|
|
312
|
+
"wait": 700
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"action": {
|
|
316
|
+
"name": "request-action-intent",
|
|
317
|
+
"with": {
|
|
318
|
+
"action-id": "publish",
|
|
319
|
+
"record-ids": [
|
|
320
|
+
"3"
|
|
321
|
+
]
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
"target": "#t",
|
|
325
|
+
"expect": {
|
|
326
|
+
"returns": {
|
|
327
|
+
"outcome": "applied"
|
|
328
|
+
},
|
|
329
|
+
"events": [
|
|
330
|
+
{
|
|
331
|
+
"name": "sf-view-table-apply",
|
|
332
|
+
"count": 1,
|
|
333
|
+
"detail": {
|
|
334
|
+
"action": "publish",
|
|
335
|
+
"scope": "entry",
|
|
336
|
+
"ids": [
|
|
337
|
+
"3"
|
|
338
|
+
],
|
|
339
|
+
"revisions": {
|
|
340
|
+
"3": "r1"
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"name": "sf-table-action-intent",
|
|
346
|
+
"count": 1,
|
|
347
|
+
"detail": {
|
|
348
|
+
"action_id": "publish",
|
|
349
|
+
"record_ids": [
|
|
350
|
+
"3"
|
|
351
|
+
]
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
],
|
|
355
|
+
"journal": [
|
|
356
|
+
{
|
|
357
|
+
"from": "sf-table-action-intent",
|
|
358
|
+
"to": "sf-table-apply"
|
|
359
|
+
}
|
|
360
|
+
]
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
]
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
"id": "p4-keys",
|
|
367
|
+
"title": "the arrows, Home and End move between rows; End reaches the last of 1 000 rows, which is drawn first",
|
|
368
|
+
"covers": "keyboard.row ArrowDown focus:next, ArrowUp focus:prev, Home focus:first, End focus:last",
|
|
369
|
+
"steps": [
|
|
370
|
+
{
|
|
371
|
+
"script": "(() => { const t = document.getElementById('t'); t.setColumns([{key: 'title', label: 'Название', sortable: true}, {key: 'status', label: 'Статус'}, {key: 'amount', label: 'Сумма', type: 'number'}]); t.setRows(Array.from({length: 1000}, (_, i) => ({id: String(i + 1), title: 'Запись ' + (i + 1), status: ['active', 'done'][i % 2], amount: i * 3, revision: 'r1', actions: ['view', 'publish']}))); return true; })()",
|
|
372
|
+
"wait": 900
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"script": "(document.querySelector('#t tbody tr[data-row-id=\"1\"]').focus(), true)",
|
|
376
|
+
"wait": 100
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"user": "keyboard:ArrowDown",
|
|
380
|
+
"wait": 200,
|
|
381
|
+
"check": "document.activeElement?.dataset?.rowId === '2'"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"user": "keyboard:ArrowUp",
|
|
385
|
+
"wait": 200,
|
|
386
|
+
"check": "document.activeElement?.dataset?.rowId === '1'"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"user": "keyboard:End",
|
|
390
|
+
"wait": 900,
|
|
391
|
+
"check": "document.activeElement?.dataset?.rowId === '1000' && document.activeElement.getAttribute('aria-rowindex') === '1001'"
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
"user": "keyboard:Home",
|
|
395
|
+
"wait": 900,
|
|
396
|
+
"check": "document.activeElement?.dataset?.rowId === '1'"
|
|
397
|
+
}
|
|
398
|
+
]
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"id": "p5-search",
|
|
402
|
+
"title": "a cleared search is sf-table-search-change {search}; onSearchEnd follows once with the text as its detail, noted",
|
|
403
|
+
"covers": "events.search-change, aliases onSearchEnd (simai/ui-pro#1)",
|
|
404
|
+
"steps": [
|
|
405
|
+
{
|
|
406
|
+
"script": "(() => { const t = document.getElementById('t'); t.setColumns([{key: 'title', label: 'Название', sortable: true}, {key: 'status', label: 'Статус'}, {key: 'amount', label: 'Сумма', type: 'number'}]); t.setRows(Array.from({length: 3}, (_, i) => ({id: String(i + 1), title: 'Запись ' + (i + 1), status: ['active', 'done'][i % 2], amount: i * 3, revision: 'r1', actions: ['view', 'publish']}))); return true; })()",
|
|
407
|
+
"wait": 700
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"script": "(document.getElementById('t').resetQuery('search'), true)",
|
|
411
|
+
"expect": {
|
|
412
|
+
"events": [
|
|
413
|
+
{
|
|
414
|
+
"name": "sf-view-table-search-change",
|
|
415
|
+
"count": 1,
|
|
416
|
+
"detail": {
|
|
417
|
+
"search": ""
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"name": "onSearchEnd",
|
|
422
|
+
"count": 1
|
|
423
|
+
}
|
|
424
|
+
],
|
|
425
|
+
"journal": [
|
|
426
|
+
{
|
|
427
|
+
"from": "onSearchEnd",
|
|
428
|
+
"to": "sf-table-search-change"
|
|
429
|
+
}
|
|
430
|
+
]
|
|
431
|
+
},
|
|
432
|
+
"check": "window.__heard.find((one) => one.name === 'onSearchEnd')?.detail === ''"
|
|
433
|
+
}
|
|
434
|
+
]
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
"id": "p6-current",
|
|
438
|
+
"title": "current marks the open row with aria-current, sends nothing and moves no focus",
|
|
439
|
+
"covers": "settings.current",
|
|
440
|
+
"steps": [
|
|
441
|
+
{
|
|
442
|
+
"script": "(() => { const t = document.getElementById('t'); t.setColumns([{key: 'title', label: 'Название', sortable: true}, {key: 'status', label: 'Статус'}, {key: 'amount', label: 'Сумма', type: 'number'}]); t.setRows(Array.from({length: 3}, (_, i) => ({id: String(i + 1), title: 'Запись ' + (i + 1), status: ['active', 'done'][i % 2], amount: i * 3, revision: 'r1', actions: ['view', 'publish']}))); return true; })()",
|
|
443
|
+
"wait": 700
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
"script": "(document.getElementById('t').current = '2', true)",
|
|
447
|
+
"wait": 300,
|
|
448
|
+
"expect": {
|
|
449
|
+
"events": [
|
|
450
|
+
{
|
|
451
|
+
"name": "sf-view-table-select",
|
|
452
|
+
"count": 0
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
"name": "sf-view-table-apply",
|
|
456
|
+
"count": 0
|
|
457
|
+
}
|
|
458
|
+
]
|
|
459
|
+
},
|
|
460
|
+
"check": "document.querySelector('#t tbody tr[data-row-id=\"2\"]').getAttribute('aria-current') === 'true' && document.getElementById('t').getAttribute('current') === '2' && !document.querySelector('#t tbody tr[data-row-id=\"1\"]').hasAttribute('aria-current')"
|
|
461
|
+
}
|
|
462
|
+
]
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
"id": "p7-one-row",
|
|
466
|
+
"title": "one row changed is drawn again in place: the same element, the new text",
|
|
467
|
+
"covers": "§18.4 one entry redrawn in place, gate 17",
|
|
468
|
+
"steps": [
|
|
469
|
+
{
|
|
470
|
+
"script": "(() => { const t = document.getElementById('t'); t.setColumns([{key: 'title', label: 'Название', sortable: true}, {key: 'status', label: 'Статус'}, {key: 'amount', label: 'Сумма', type: 'number'}]); t.setRows(Array.from({length: 1000}, (_, i) => ({id: String(i + 1), title: 'Запись ' + (i + 1), status: ['active', 'done'][i % 2], amount: i * 3, revision: 'r1', actions: ['view', 'publish']}))); return true; })()",
|
|
471
|
+
"wait": 900
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
"script": "(() => { window.__row = document.querySelector('#t tbody tr[data-row-id=\"3\"]'); document.getElementById('t').updateRowByKey('id', '3', {title: 'Изменено', revision: 'r2'}); return true; })()",
|
|
475
|
+
"wait": 300,
|
|
476
|
+
"check": "document.querySelector('#t tbody tr[data-row-id=\"3\"]') === window.__row && window.__row.textContent.includes('Изменено')"
|
|
477
|
+
}
|
|
478
|
+
]
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
"id": "p8-template-name",
|
|
482
|
+
"title": "the filter window's template row says its name: sf-radio is fetched when the window opens, so the row is not a handle and a menu with nothing between them",
|
|
483
|
+
"covers": "relations cl-radio (lazy), §18.4 portal",
|
|
484
|
+
"steps": [
|
|
485
|
+
{
|
|
486
|
+
"script": "(() => { const t = document.getElementById('t'); t.setColumns([{key: 'title', label: 'Название', filter: {enabled: true}}, {key: 'status', label: 'Статус'}]); t.setRows(Array.from({length: 12}, (_, i) => ({id: String(i + 1), title: 'Запись ' + (i + 1), status: 'active'}))); t.templates = [{key: 'default', label: 'Все записи', default: true}]; return true; })()",
|
|
487
|
+
"wait": 700
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
"script": "(() => { const t = document.getElementById('t'); const anchor = t.querySelector('button, [role=\"button\"]') || t; t.openContextMenu({currentTarget: anchor, target: anchor, composedPath: () => [anchor], preventDefault() {}, stopPropagation() {}}, {menu: 'filter-settings'}); return true; })()",
|
|
491
|
+
"wait": 1500,
|
|
492
|
+
"check": "(() => { const row = document.querySelector('[data-filter-template-key]'); if (!row) return false; const radio = row.querySelector('sf-radio'); if (!radio || !customElements.get('sf-radio')) return false; const drawn = radio.querySelector('.sf-radio-button, label'); const box = drawn?.getBoundingClientRect(); return Boolean(box) && box.width > 24 && box.height > 8 && row.textContent.includes('Все записи'); })()"
|
|
493
|
+
}
|
|
494
|
+
]
|
|
495
|
+
}
|
|
496
|
+
]
|
|
497
|
+
}
|
|
498
|
+
]
|
|
499
|
+
}
|
|
Binary file
|