@simai-studio/view 0.0.0-stage → 1.1.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.
Files changed (127) hide show
  1. package/LICENSE.md +183 -0
  2. package/README.md +75 -2
  3. package/dist/package-receipt.json +972 -0
  4. package/dist/set.json +141 -0
  5. package/dist/smart/rule.js +278 -0
  6. package/dist/smart/rule.js.gz +0 -0
  7. package/dist/smart/view/aliases.json +129 -0
  8. package/dist/smart/view/aliases.json.gz +0 -0
  9. package/dist/smart/view/component.json +1628 -0
  10. package/dist/smart/view/component.json.gz +0 -0
  11. package/dist/smart/view/css/view.css +208 -0
  12. package/dist/smart/view/css/view.css.gz +0 -0
  13. package/dist/smart/view/css/view.min.css +2 -0
  14. package/dist/smart/view/css/view.min.css.gz +0 -0
  15. package/dist/smart/view/examples.json +668 -0
  16. package/dist/smart/view/examples.json.gz +0 -0
  17. package/dist/smart/view/js/view.js +3955 -0
  18. package/dist/smart/view/js/view.js.gz +0 -0
  19. package/dist/smart/view/js/view.min.js +1 -0
  20. package/dist/smart/view/js/view.min.js.gz +0 -0
  21. package/dist/smart/view/lang/en.json +61 -0
  22. package/dist/smart/view/lang/en.json.gz +0 -0
  23. package/dist/smart/view/lang/ru.json +61 -0
  24. package/dist/smart/view/lang/ru.json.gz +0 -0
  25. package/dist/smart/view/probe.json +165 -0
  26. package/dist/smart/view/probe.json.gz +0 -0
  27. package/dist/smart/view/smart.manifest.json +1577 -0
  28. package/dist/smart/view/smart.manifest.json.gz +0 -0
  29. package/dist/smart/view/static/default/embedded.html +96 -0
  30. package/dist/smart/view/static/default/embedded.html.gz +0 -0
  31. package/dist/smart/view/static/default/open-record.html +242 -0
  32. package/dist/smart/view/static/default/open-record.html.gz +0 -0
  33. package/dist/smart/view/static/default/reference.html +242 -0
  34. package/dist/smart/view/static/default/reference.html.gz +0 -0
  35. package/dist/smart/view/static/sheets.json +282 -0
  36. package/dist/smart/view/static/sheets.json.gz +0 -0
  37. package/dist/smart/view-properties/aliases.json +174 -0
  38. package/dist/smart/view-properties/aliases.json.gz +0 -0
  39. package/dist/smart/view-properties/component.json +1906 -0
  40. package/dist/smart/view-properties/component.json.gz +0 -0
  41. package/dist/smart/view-properties/css/view-properties.css +1158 -0
  42. package/dist/smart/view-properties/css/view-properties.css.gz +0 -0
  43. package/dist/smart/view-properties/css/view-properties.min.css +2 -0
  44. package/dist/smart/view-properties/css/view-properties.min.css.gz +0 -0
  45. package/dist/smart/view-properties/examples.json +841 -0
  46. package/dist/smart/view-properties/examples.json.gz +0 -0
  47. package/dist/smart/view-properties/js/view-properties.js +10551 -0
  48. package/dist/smart/view-properties/js/view-properties.js.gz +0 -0
  49. package/dist/smart/view-properties/js/view-properties.min.js +1392 -0
  50. package/dist/smart/view-properties/js/view-properties.min.js.gz +0 -0
  51. package/dist/smart/view-properties/lang/en.json +89 -0
  52. package/dist/smart/view-properties/lang/en.json.gz +0 -0
  53. package/dist/smart/view-properties/lang/ru.json +89 -0
  54. package/dist/smart/view-properties/lang/ru.json.gz +0 -0
  55. package/dist/smart/view-properties/probe.json +188 -0
  56. package/dist/smart/view-properties/probe.json.gz +0 -0
  57. package/dist/smart/view-properties/skeleton.html +13 -0
  58. package/dist/smart/view-properties/skeleton.html.gz +0 -0
  59. package/dist/smart/view-properties/smart.manifest.json +1593 -0
  60. package/dist/smart/view-properties/smart.manifest.json.gz +0 -0
  61. package/dist/smart/view-properties/static/default/full.html +2 -0
  62. package/dist/smart/view-properties/static/default/full.html.gz +0 -0
  63. package/dist/smart/view-properties/static/default/panel-closed.html +4 -0
  64. package/dist/smart/view-properties/static/default/panel-closed.html.gz +0 -0
  65. package/dist/smart/view-properties/static/default/panel.html +4 -0
  66. package/dist/smart/view-properties/static/default/panel.html.gz +0 -0
  67. package/dist/smart/view-properties/static/default/reference.html +2 -0
  68. package/dist/smart/view-properties/static/default/reference.html.gz +0 -0
  69. package/dist/smart/view-properties/static/sheets.json +426 -0
  70. package/dist/smart/view-properties/static/sheets.json.gz +0 -0
  71. package/dist/smart/view-properties/template/default.css +992 -0
  72. package/dist/smart/view-properties/template/default.css.gz +0 -0
  73. package/dist/smart/view-properties/template/default.js +1658 -0
  74. package/dist/smart/view-properties/template/default.js.gz +0 -0
  75. package/dist/smart/view-table/aliases.json +448 -0
  76. package/dist/smart/view-table/aliases.json.gz +0 -0
  77. package/dist/smart/view-table/component.json +2746 -0
  78. package/dist/smart/view-table/component.json.gz +0 -0
  79. package/dist/smart/view-table/css/view-table.css +3658 -0
  80. package/dist/smart/view-table/css/view-table.css.gz +0 -0
  81. package/dist/smart/view-table/css/view-table.min.css +2 -0
  82. package/dist/smart/view-table/css/view-table.min.css.gz +0 -0
  83. package/dist/smart/view-table/examples.json +499 -0
  84. package/dist/smart/view-table/examples.json.gz +0 -0
  85. package/dist/smart/view-table/js/view-table.js +14166 -0
  86. package/dist/smart/view-table/js/view-table.js.gz +0 -0
  87. package/dist/smart/view-table/js/view-table.min.js +1440 -0
  88. package/dist/smart/view-table/js/view-table.min.js.gz +0 -0
  89. package/dist/smart/view-table/lang/en.json +132 -0
  90. package/dist/smart/view-table/lang/en.json.gz +0 -0
  91. package/dist/smart/view-table/lang/ru.json +132 -0
  92. package/dist/smart/view-table/lang/ru.json.gz +0 -0
  93. package/dist/smart/view-table/probe.json +275 -0
  94. package/dist/smart/view-table/probe.json.gz +0 -0
  95. package/dist/smart/view-table/smart.manifest.json +2531 -0
  96. package/dist/smart/view-table/smart.manifest.json.gz +0 -0
  97. package/dist/smart/view-table/static/default/current.html +141 -0
  98. package/dist/smart/view-table/static/default/current.html.gz +0 -0
  99. package/dist/smart/view-table/static/default/current.skeleton.html +141 -0
  100. package/dist/smart/view-table/static/default/current.skeleton.html.gz +0 -0
  101. package/dist/smart/view-table/static/default/empty.html +149 -0
  102. package/dist/smart/view-table/static/default/empty.html.gz +0 -0
  103. package/dist/smart/view-table/static/default/loading.html +180 -0
  104. package/dist/smart/view-table/static/default/loading.html.gz +0 -0
  105. package/dist/smart/view-table/static/default/many.html +180 -0
  106. package/dist/smart/view-table/static/default/many.html.gz +0 -0
  107. package/dist/smart/view-table/static/default/reference.html +136 -0
  108. package/dist/smart/view-table/static/default/reference.html.gz +0 -0
  109. package/dist/smart/view-table/static/default/reference.skeleton.html +136 -0
  110. package/dist/smart/view-table/static/default/reference.skeleton.html.gz +0 -0
  111. package/dist/smart/view-table/static/default/typed-cells.html +229 -0
  112. package/dist/smart/view-table/static/default/typed-cells.html.gz +0 -0
  113. package/dist/smart/view-table/static/default/typed-cells.skeleton.html +229 -0
  114. package/dist/smart/view-table/static/default/typed-cells.skeleton.html.gz +0 -0
  115. package/dist/smart/view-table/static/sheets.json +480 -0
  116. package/dist/smart/view-table/static/sheets.json.gz +0 -0
  117. package/dist/smart/view-table/studio.fixture.json +17 -0
  118. package/dist/smart/view-table/studio.fixture.json.gz +0 -0
  119. package/dist/smart/view-table/studio.scenario.json +30 -0
  120. package/dist/smart/view-table/studio.scenario.json.gz +0 -0
  121. package/dist/smart/view-table/template/default.css +1301 -0
  122. package/dist/smart/view-table/template/default.css.gz +0 -0
  123. package/dist/smart/view-table/template/default.js +1215 -0
  124. package/dist/smart/view-table/template/default.js.gz +0 -0
  125. package/dist/smart/view-table/template/link-cell-contract.js +48 -0
  126. package/dist/smart/view-table/template/link-cell-contract.js.gz +0 -0
  127. package/package.json +29 -4
@@ -0,0 +1,668 @@
1
+ {
2
+ "examples": [
3
+ {
4
+ "name": "reference",
5
+ "title": "Решения",
6
+ "settings": {
7
+ "aria-label": "Решения",
8
+ "collection": "workbench.solutions"
9
+ },
10
+ "children": "<sf-view-table slot=\"content\" aria-label=\"Решения\"></sf-view-table><sf-pagination slot=\"pagination\"></sf-pagination>",
11
+ "first-paint": {
12
+ "max-bytes": 20480,
13
+ "why": "The view's skeleton (the toolbar, the head and a page of rows, the compact list for a phone, the page row) beside the table and the page row the page gives it as documented, each printed in its own resting markup and held out of view until the host's first answer."
14
+ },
15
+ "expect": {
16
+ "name": "Решения",
17
+ "values": {
18
+ "state": "ready"
19
+ }
20
+ },
21
+ "x-port": "the reference host of ui-admin (src/ports/polygon-host.mjs)",
22
+ "port": {
23
+ "capabilities": [
24
+ "row-actions"
25
+ ],
26
+ "answers": {
27
+ "query.change": {
28
+ "answer": "applied",
29
+ "data": {
30
+ "records": [
31
+ {
32
+ "id": "r-001",
33
+ "revision": "r1",
34
+ "actions": [
35
+ "view"
36
+ ],
37
+ "title": "Портал клиента",
38
+ "owner": "Анна Захарова, продажи",
39
+ "status": "Опубликовано на сайте",
40
+ "updated": "27 октября 2026, 14:05"
41
+ },
42
+ {
43
+ "id": "r-002",
44
+ "revision": "r1",
45
+ "actions": [
46
+ "view"
47
+ ],
48
+ "title": "Каталог товаров",
49
+ "owner": "Илья Петров, закупки",
50
+ "status": "Черновик на согласовании",
51
+ "updated": "26 октября 2026, 09:40"
52
+ },
53
+ {
54
+ "id": "r-003",
55
+ "revision": "r1",
56
+ "actions": [
57
+ "view"
58
+ ],
59
+ "title": "Личный кабинет",
60
+ "owner": "Мария Соколова, поддержка",
61
+ "status": "Опубликовано на сайте",
62
+ "updated": "24 октября 2026, 18:12"
63
+ },
64
+ {
65
+ "id": "r-004",
66
+ "revision": "r1",
67
+ "actions": [
68
+ "view"
69
+ ],
70
+ "title": "Склад",
71
+ "owner": "Олег Иванов, склад",
72
+ "status": "Снято с публикации",
73
+ "updated": "21 октября 2026, 11:30"
74
+ },
75
+ {
76
+ "id": "r-005",
77
+ "revision": "r1",
78
+ "actions": [
79
+ "view"
80
+ ],
81
+ "title": "Сайт",
82
+ "owner": "Ирина Белова, маркетинг",
83
+ "status": "Черновик на согласовании",
84
+ "updated": "19 октября 2026, 16:55"
85
+ },
86
+ {
87
+ "id": "r-006",
88
+ "revision": "r1",
89
+ "actions": [
90
+ "view"
91
+ ],
92
+ "title": "Портал клиента",
93
+ "owner": "Анна Захарова, продажи",
94
+ "status": "Опубликовано на сайте",
95
+ "updated": "27 октября 2026, 14:05"
96
+ },
97
+ {
98
+ "id": "r-007",
99
+ "revision": "r1",
100
+ "actions": [
101
+ "view"
102
+ ],
103
+ "title": "Каталог товаров",
104
+ "owner": "Илья Петров, закупки",
105
+ "status": "Черновик на согласовании",
106
+ "updated": "26 октября 2026, 09:40"
107
+ },
108
+ {
109
+ "id": "r-008",
110
+ "revision": "r1",
111
+ "actions": [
112
+ "view"
113
+ ],
114
+ "title": "Личный кабинет",
115
+ "owner": "Мария Соколова, поддержка",
116
+ "status": "Опубликовано на сайте",
117
+ "updated": "24 октября 2026, 18:12"
118
+ },
119
+ {
120
+ "id": "r-009",
121
+ "revision": "r1",
122
+ "actions": [
123
+ "view"
124
+ ],
125
+ "title": "Склад",
126
+ "owner": "Олег Иванов, склад",
127
+ "status": "Снято с публикации",
128
+ "updated": "21 октября 2026, 11:30"
129
+ },
130
+ {
131
+ "id": "r-010",
132
+ "revision": "r1",
133
+ "actions": [
134
+ "view"
135
+ ],
136
+ "title": "Сайт",
137
+ "owner": "Ирина Белова, маркетинг",
138
+ "status": "Черновик на согласовании",
139
+ "updated": "19 октября 2026, 16:55"
140
+ }
141
+ ],
142
+ "columns": [
143
+ {
144
+ "key": "title",
145
+ "label": "Название",
146
+ "property_type": "string",
147
+ "role": "title"
148
+ },
149
+ {
150
+ "key": "owner",
151
+ "label": "Ответственный",
152
+ "property_type": "string"
153
+ },
154
+ {
155
+ "key": "status",
156
+ "label": "Статус",
157
+ "property_type": "string"
158
+ },
159
+ {
160
+ "key": "updated",
161
+ "label": "Изменено",
162
+ "property_type": "string"
163
+ }
164
+ ],
165
+ "total": 10,
166
+ "echo": {
167
+ "filters_chosen": {},
168
+ "filters": {},
169
+ "filters_rejected": [],
170
+ "search": "",
171
+ "sort": [],
172
+ "page": 1,
173
+ "per_page": 25
174
+ },
175
+ "column_settings": {
176
+ "layers": {
177
+ "personal": {
178
+ "revision": "p1",
179
+ "columns": {}
180
+ }
181
+ },
182
+ "target": {
183
+ "kind": "personal",
184
+ "revision": "p1"
185
+ }
186
+ }
187
+ }
188
+ },
189
+ "*": {
190
+ "answer": "applied"
191
+ }
192
+ },
193
+ "$comment": "A fake host (ui-source first-paint-lib.mjs portOf): gate 24 hands it over as phase 3. It answers the shape the skeleton stands for: as many rows (row-cap, else a page of 10) and as many columns (expected-columns, 4) as it draws, each field long enough to take its own line in the compact list."
194
+ }
195
+ },
196
+ {
197
+ "name": "embedded",
198
+ "title": "Связанный список в записи",
199
+ "settings": {
200
+ "aria-label": "Связанные",
201
+ "chrome": "",
202
+ "row-cap": 5,
203
+ "expected-columns": 2
204
+ },
205
+ "children": "<sf-view-table slot=\"content\" aria-label=\"Связанные\" toolbar=\"false\"></sf-view-table>",
206
+ "expect": {
207
+ "name": "Связанные"
208
+ },
209
+ "port": {
210
+ "capabilities": [
211
+ "row-actions"
212
+ ],
213
+ "answers": {
214
+ "query.change": {
215
+ "answer": "applied",
216
+ "data": {
217
+ "records": [
218
+ {
219
+ "id": "r-001",
220
+ "revision": "r1",
221
+ "actions": [
222
+ "view"
223
+ ],
224
+ "title": "Портал клиента",
225
+ "status": "Опубликовано"
226
+ },
227
+ {
228
+ "id": "r-002",
229
+ "revision": "r1",
230
+ "actions": [
231
+ "view"
232
+ ],
233
+ "title": "Каталог товаров",
234
+ "status": "Черновик"
235
+ },
236
+ {
237
+ "id": "r-003",
238
+ "revision": "r1",
239
+ "actions": [
240
+ "view"
241
+ ],
242
+ "title": "Личный кабинет",
243
+ "status": "Опубликовано"
244
+ },
245
+ {
246
+ "id": "r-004",
247
+ "revision": "r1",
248
+ "actions": [
249
+ "view"
250
+ ],
251
+ "title": "Склад",
252
+ "status": "Снято"
253
+ },
254
+ {
255
+ "id": "r-005",
256
+ "revision": "r1",
257
+ "actions": [
258
+ "view"
259
+ ],
260
+ "title": "Сайт",
261
+ "status": "Черновик"
262
+ }
263
+ ],
264
+ "columns": [
265
+ {
266
+ "key": "title",
267
+ "label": "Название",
268
+ "property_type": "string",
269
+ "role": "title"
270
+ },
271
+ {
272
+ "key": "status",
273
+ "label": "Статус",
274
+ "property_type": "string"
275
+ }
276
+ ],
277
+ "total": 5,
278
+ "echo": {
279
+ "filters_chosen": {},
280
+ "filters": {},
281
+ "filters_rejected": [],
282
+ "search": "",
283
+ "sort": [],
284
+ "page": 1,
285
+ "per_page": 25
286
+ },
287
+ "column_settings": {
288
+ "layers": {
289
+ "personal": {
290
+ "revision": "p1",
291
+ "columns": {}
292
+ }
293
+ },
294
+ "target": {
295
+ "kind": "personal",
296
+ "revision": "p1"
297
+ }
298
+ }
299
+ }
300
+ },
301
+ "*": {
302
+ "answer": "applied"
303
+ }
304
+ },
305
+ "$comment": "A fake host (ui-source first-paint-lib.mjs portOf): gate 24 hands it over as phase 3. It answers the shape the skeleton stands for: row-cap rows and the expected-columns (2) a related list in a record shows, each value one line; on a phone the two columns fit, so no sideways rail comes with the data."
306
+ }
307
+ },
308
+ {
309
+ "name": "open-record",
310
+ "title": "Открытая запись",
311
+ "settings": {
312
+ "aria-label": "Решения",
313
+ "current": "r-005"
314
+ },
315
+ "children": "<sf-view-table slot=\"content\" aria-label=\"Решения\"></sf-view-table><sf-pagination slot=\"pagination\"></sf-pagination>",
316
+ "first-paint": {
317
+ "max-bytes": 20480,
318
+ "why": "The view's skeleton (the toolbar, the head and a page of rows, the compact list for a phone, the page row) beside the table and the page row the page gives it as documented, each printed in its own resting markup and held out of view until the host's first answer."
319
+ },
320
+ "expect": {
321
+ "name": "Решения",
322
+ "values": {
323
+ "selected": "r-005"
324
+ }
325
+ },
326
+ "port": {
327
+ "capabilities": [
328
+ "row-actions"
329
+ ],
330
+ "answers": {
331
+ "query.change": {
332
+ "answer": "applied",
333
+ "data": {
334
+ "records": [
335
+ {
336
+ "id": "r-001",
337
+ "revision": "r1",
338
+ "actions": [
339
+ "view"
340
+ ],
341
+ "title": "Портал клиента",
342
+ "owner": "Анна Захарова, продажи",
343
+ "status": "Опубликовано на сайте",
344
+ "updated": "27 октября 2026, 14:05"
345
+ },
346
+ {
347
+ "id": "r-002",
348
+ "revision": "r1",
349
+ "actions": [
350
+ "view"
351
+ ],
352
+ "title": "Каталог товаров",
353
+ "owner": "Илья Петров, закупки",
354
+ "status": "Черновик на согласовании",
355
+ "updated": "26 октября 2026, 09:40"
356
+ },
357
+ {
358
+ "id": "r-003",
359
+ "revision": "r1",
360
+ "actions": [
361
+ "view"
362
+ ],
363
+ "title": "Личный кабинет",
364
+ "owner": "Мария Соколова, поддержка",
365
+ "status": "Опубликовано на сайте",
366
+ "updated": "24 октября 2026, 18:12"
367
+ },
368
+ {
369
+ "id": "r-004",
370
+ "revision": "r1",
371
+ "actions": [
372
+ "view"
373
+ ],
374
+ "title": "Склад",
375
+ "owner": "Олег Иванов, склад",
376
+ "status": "Снято с публикации",
377
+ "updated": "21 октября 2026, 11:30"
378
+ },
379
+ {
380
+ "id": "r-005",
381
+ "revision": "r1",
382
+ "actions": [
383
+ "view"
384
+ ],
385
+ "title": "Сайт",
386
+ "owner": "Ирина Белова, маркетинг",
387
+ "status": "Черновик на согласовании",
388
+ "updated": "19 октября 2026, 16:55"
389
+ },
390
+ {
391
+ "id": "r-006",
392
+ "revision": "r1",
393
+ "actions": [
394
+ "view"
395
+ ],
396
+ "title": "Портал клиента",
397
+ "owner": "Анна Захарова, продажи",
398
+ "status": "Опубликовано на сайте",
399
+ "updated": "27 октября 2026, 14:05"
400
+ },
401
+ {
402
+ "id": "r-007",
403
+ "revision": "r1",
404
+ "actions": [
405
+ "view"
406
+ ],
407
+ "title": "Каталог товаров",
408
+ "owner": "Илья Петров, закупки",
409
+ "status": "Черновик на согласовании",
410
+ "updated": "26 октября 2026, 09:40"
411
+ },
412
+ {
413
+ "id": "r-008",
414
+ "revision": "r1",
415
+ "actions": [
416
+ "view"
417
+ ],
418
+ "title": "Личный кабинет",
419
+ "owner": "Мария Соколова, поддержка",
420
+ "status": "Опубликовано на сайте",
421
+ "updated": "24 октября 2026, 18:12"
422
+ },
423
+ {
424
+ "id": "r-009",
425
+ "revision": "r1",
426
+ "actions": [
427
+ "view"
428
+ ],
429
+ "title": "Склад",
430
+ "owner": "Олег Иванов, склад",
431
+ "status": "Снято с публикации",
432
+ "updated": "21 октября 2026, 11:30"
433
+ },
434
+ {
435
+ "id": "r-010",
436
+ "revision": "r1",
437
+ "actions": [
438
+ "view"
439
+ ],
440
+ "title": "Сайт",
441
+ "owner": "Ирина Белова, маркетинг",
442
+ "status": "Черновик на согласовании",
443
+ "updated": "19 октября 2026, 16:55"
444
+ }
445
+ ],
446
+ "columns": [
447
+ {
448
+ "key": "title",
449
+ "label": "Название",
450
+ "property_type": "string",
451
+ "role": "title"
452
+ },
453
+ {
454
+ "key": "owner",
455
+ "label": "Ответственный",
456
+ "property_type": "string"
457
+ },
458
+ {
459
+ "key": "status",
460
+ "label": "Статус",
461
+ "property_type": "string"
462
+ },
463
+ {
464
+ "key": "updated",
465
+ "label": "Изменено",
466
+ "property_type": "string"
467
+ }
468
+ ],
469
+ "total": 10,
470
+ "echo": {
471
+ "filters_chosen": {},
472
+ "filters": {},
473
+ "filters_rejected": [],
474
+ "search": "",
475
+ "sort": [],
476
+ "page": 1,
477
+ "per_page": 25
478
+ },
479
+ "column_settings": {
480
+ "layers": {
481
+ "personal": {
482
+ "revision": "p1",
483
+ "columns": {}
484
+ }
485
+ },
486
+ "target": {
487
+ "kind": "personal",
488
+ "revision": "p1"
489
+ }
490
+ }
491
+ }
492
+ },
493
+ "*": {
494
+ "answer": "applied"
495
+ }
496
+ },
497
+ "$comment": "A fake host (ui-source first-paint-lib.mjs portOf): gate 24 hands it over as phase 3. It answers the shape the skeleton stands for: as many rows (row-cap, else a page of 10) and as many columns (expected-columns, 4) as it draws, each field long enough to take its own line in the compact list."
498
+ }
499
+ }
500
+ ],
501
+ "pages": [
502
+ {
503
+ "name": "conformance",
504
+ "title": "sf-data-view against component.json (standard simai.smart-component 1.3.8 §12, gate 20)",
505
+ "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",
506
+ "page": {
507
+ "lang": "ru",
508
+ "body": [
509
+ "<main style=\"width: 1100px\">",
510
+ " <sf-view id=\"v\" aria-label=\"Решения\" collection=\"workbench.solutions\"></sf-view>",
511
+ "</main>"
512
+ ]
513
+ },
514
+ "checks": [
515
+ {
516
+ "id": "p1-values",
517
+ "title": "after the host's answer: state ready, total 3, three rows",
518
+ "covers": "values.state, values.total, port answers",
519
+ "steps": [
520
+ {
521
+ "script": "(() => { window.__calls = []; const records = [{id: '1', revision: '1', actions: ['view', 'delete'], title: 'Портал клиента'}, {id: '2', revision: '1', actions: ['view', 'delete'], title: 'Каталог товаров'}, {id: '3', revision: '1', actions: ['view'], title: 'Склад'}]; const port = {id: 'simai.dataview-port', version: '1.12.0', capabilities: ['row-actions'], raise: async (intent, payload) => { window.__calls.push(intent); if (intent === 'query.change') return {answer: 'applied', sequence: payload.sequence, data: {records: records.map((one) => ({...one})), columns: [{key: 'title', label: 'Название', role: 'title'}], total: records.length, has_next: false, echo: {page: 1, per_page: 25}}}; if (intent === 'record.open') return {answer: 'applied', record_id: payload.record_ids?.[0]}; if (intent === 'record.mutate') { const at = records.findIndex((one) => one.id === payload.record_ids[0]); if (at >= 0) records.splice(at, 1); return {answer: 'applied'}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.getElementById('v').setHostPort(port); return true; })()",
522
+ "wait": 1200,
523
+ "expect": {
524
+ "values": {
525
+ "#v.state": "ready",
526
+ "#v.total": 3
527
+ }
528
+ },
529
+ "check": "document.getElementById('v').table.querySelectorAll('tbody tr[data-row-id]').length === 3 && window.__calls[0] === 'query.change'"
530
+ }
531
+ ]
532
+ },
533
+ {
534
+ "id": "p2-open",
535
+ "title": "a record's title asks to open it: sf-data-view-open {id} once, then the host's record.open",
536
+ "covers": "events.open (vocabulary §5 open)",
537
+ "steps": [
538
+ {
539
+ "script": "(() => { window.__calls = []; const records = [{id: '1', revision: '1', actions: ['view', 'delete'], title: 'Портал клиента'}, {id: '2', revision: '1', actions: ['view', 'delete'], title: 'Каталог товаров'}, {id: '3', revision: '1', actions: ['view'], title: 'Склад'}]; const port = {id: 'simai.dataview-port', version: '1.12.0', capabilities: ['row-actions'], raise: async (intent, payload) => { window.__calls.push(intent); if (intent === 'query.change') return {answer: 'applied', sequence: payload.sequence, data: {records: records.map((one) => ({...one})), columns: [{key: 'title', label: 'Название', role: 'title'}], total: records.length, has_next: false, echo: {page: 1, per_page: 25}}}; if (intent === 'record.open') return {answer: 'applied', record_id: payload.record_ids?.[0]}; if (intent === 'record.mutate') { const at = records.findIndex((one) => one.id === payload.record_ids[0]); if (at >= 0) records.splice(at, 1); return {answer: 'applied'}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.getElementById('v').setHostPort(port); return true; })()",
540
+ "wait": 1200
541
+ },
542
+ {
543
+ "wait": 500,
544
+ "expect": {
545
+ "events": [
546
+ {
547
+ "name": "sf-view-open",
548
+ "count": 1,
549
+ "detail": {
550
+ "id": "2"
551
+ }
552
+ }
553
+ ]
554
+ },
555
+ "check": "window.__calls.includes('record.open')",
556
+ "script": "(document.getElementById('v').table.querySelector('tbody tr[data-row-id=\"2\"] a.sf-table-title-link').click(), true)"
557
+ }
558
+ ]
559
+ },
560
+ {
561
+ "id": "p3-open-refused",
562
+ "title": "a listener that refuses sf-data-view-open keeps the host out of it",
563
+ "covers": "events.open cancelable (§8)",
564
+ "steps": [
565
+ {
566
+ "script": "(() => { window.__calls = []; const records = [{id: '1', revision: '1', actions: ['view', 'delete'], title: 'Портал клиента'}, {id: '2', revision: '1', actions: ['view', 'delete'], title: 'Каталог товаров'}, {id: '3', revision: '1', actions: ['view'], title: 'Склад'}]; const port = {id: 'simai.dataview-port', version: '1.12.0', capabilities: ['row-actions'], raise: async (intent, payload) => { window.__calls.push(intent); if (intent === 'query.change') return {answer: 'applied', sequence: payload.sequence, data: {records: records.map((one) => ({...one})), columns: [{key: 'title', label: 'Название', role: 'title'}], total: records.length, has_next: false, echo: {page: 1, per_page: 25}}}; if (intent === 'record.open') return {answer: 'applied', record_id: payload.record_ids?.[0]}; if (intent === 'record.mutate') { const at = records.findIndex((one) => one.id === payload.record_ids[0]); if (at >= 0) records.splice(at, 1); return {answer: 'applied'}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.getElementById('v').setHostPort(port); return true; })()",
567
+ "wait": 1200
568
+ },
569
+ {
570
+ "script": "(document.getElementById('v').addEventListener('sf-view-open', (event) => event.preventDefault()), true)",
571
+ "wait": 50
572
+ },
573
+ {
574
+ "wait": 500,
575
+ "expect": {
576
+ "events": [
577
+ {
578
+ "name": "sf-view-open",
579
+ "count": 1,
580
+ "detail": {
581
+ "id": "1"
582
+ }
583
+ }
584
+ ]
585
+ },
586
+ "check": "!window.__calls.includes('record.open')",
587
+ "script": "(document.getElementById('v').table.querySelector('tbody tr[data-row-id=\"1\"] a.sf-table-title-link').click(), true)"
588
+ }
589
+ ]
590
+ },
591
+ {
592
+ "id": "p4-deleted",
593
+ "title": "an applied delete is the fact sf-data-view-deleted {ids}",
594
+ "covers": "events.deleted",
595
+ "steps": [
596
+ {
597
+ "script": "(() => { window.__calls = []; const records = [{id: '1', revision: '1', actions: ['view', 'delete'], title: 'Портал клиента'}, {id: '2', revision: '1', actions: ['view', 'delete'], title: 'Каталог товаров'}, {id: '3', revision: '1', actions: ['view'], title: 'Склад'}]; const port = {id: 'simai.dataview-port', version: '1.12.0', capabilities: ['row-actions'], raise: async (intent, payload) => { window.__calls.push(intent); if (intent === 'query.change') return {answer: 'applied', sequence: payload.sequence, data: {records: records.map((one) => ({...one})), columns: [{key: 'title', label: 'Название', role: 'title'}], total: records.length, has_next: false, echo: {page: 1, per_page: 25}}}; if (intent === 'record.open') return {answer: 'applied', record_id: payload.record_ids?.[0]}; if (intent === 'record.mutate') { const at = records.findIndex((one) => one.id === payload.record_ids[0]); if (at >= 0) records.splice(at, 1); return {answer: 'applied'}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.getElementById('v').setHostPort(port); return true; })()",
598
+ "wait": 1200
599
+ },
600
+ {
601
+ "script": "(document.getElementById('v').table.requestActionIntent('delete', ['1']), true)",
602
+ "wait": 900,
603
+ "expect": {
604
+ "events": [
605
+ {
606
+ "name": "sf-view-deleted",
607
+ "count": 1,
608
+ "detail": {
609
+ "ids": [
610
+ "1"
611
+ ]
612
+ }
613
+ }
614
+ ]
615
+ },
616
+ "check": "window.__calls.includes('record.mutate')"
617
+ }
618
+ ]
619
+ },
620
+ {
621
+ "id": "p5-current",
622
+ "title": "current marks the open record's row, and selected reads it",
623
+ "covers": "settings.current, values.selected",
624
+ "steps": [
625
+ {
626
+ "script": "(() => { window.__calls = []; const records = [{id: '1', revision: '1', actions: ['view', 'delete'], title: 'Портал клиента'}, {id: '2', revision: '1', actions: ['view', 'delete'], title: 'Каталог товаров'}, {id: '3', revision: '1', actions: ['view'], title: 'Склад'}]; const port = {id: 'simai.dataview-port', version: '1.12.0', capabilities: ['row-actions'], raise: async (intent, payload) => { window.__calls.push(intent); if (intent === 'query.change') return {answer: 'applied', sequence: payload.sequence, data: {records: records.map((one) => ({...one})), columns: [{key: 'title', label: 'Название', role: 'title'}], total: records.length, has_next: false, echo: {page: 1, per_page: 25}}}; if (intent === 'record.open') return {answer: 'applied', record_id: payload.record_ids?.[0]}; if (intent === 'record.mutate') { const at = records.findIndex((one) => one.id === payload.record_ids[0]); if (at >= 0) records.splice(at, 1); return {answer: 'applied'}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.getElementById('v').setHostPort(port); return true; })()",
627
+ "wait": 1200
628
+ },
629
+ {
630
+ "script": "(document.getElementById('v').current = '3', true)",
631
+ "wait": 400,
632
+ "expect": {
633
+ "values": {
634
+ "#v.selected": "3"
635
+ }
636
+ },
637
+ "check": "document.getElementById('v').table.querySelector('tbody tr[data-row-id=\"3\"]').getAttribute('aria-current') === 'true'"
638
+ }
639
+ ]
640
+ },
641
+ {
642
+ "id": "p6-refresh",
643
+ "title": "refresh answers an outcome and reads the list again",
644
+ "covers": "actions.refresh (§4.4)",
645
+ "steps": [
646
+ {
647
+ "script": "(() => { window.__calls = []; const records = [{id: '1', revision: '1', actions: ['view', 'delete'], title: 'Портал клиента'}, {id: '2', revision: '1', actions: ['view', 'delete'], title: 'Каталог товаров'}, {id: '3', revision: '1', actions: ['view'], title: 'Склад'}]; const port = {id: 'simai.dataview-port', version: '1.12.0', capabilities: ['row-actions'], raise: async (intent, payload) => { window.__calls.push(intent); if (intent === 'query.change') return {answer: 'applied', sequence: payload.sequence, data: {records: records.map((one) => ({...one})), columns: [{key: 'title', label: 'Название', role: 'title'}], total: records.length, has_next: false, echo: {page: 1, per_page: 25}}}; if (intent === 'record.open') return {answer: 'applied', record_id: payload.record_ids?.[0]}; if (intent === 'record.mutate') { const at = records.findIndex((one) => one.id === payload.record_ids[0]); if (at >= 0) records.splice(at, 1); return {answer: 'applied'}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.getElementById('v').setHostPort(port); return true; })()",
648
+ "wait": 1200
649
+ },
650
+ {
651
+ "action": {
652
+ "name": "refresh"
653
+ },
654
+ "target": "#v",
655
+ "wait": 600,
656
+ "expect": {
657
+ "returns": {
658
+ "outcome": "applied"
659
+ }
660
+ },
661
+ "check": "window.__calls.filter((one) => one === 'query.change').length === 2"
662
+ }
663
+ ]
664
+ }
665
+ ]
666
+ }
667
+ ]
668
+ }
Binary file