@simai-studio/view 1.1.0 → 1.3.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 (74) hide show
  1. package/README.md +5 -5
  2. package/dist/package-receipt.json +322 -81
  3. package/dist/set.json +35 -2
  4. package/dist/smart/rule.js +94 -0
  5. package/dist/smart/rule.js.gz +0 -0
  6. package/dist/smart/view/component.json +1 -1
  7. package/dist/smart/view/component.json.gz +0 -0
  8. package/dist/smart/view/js/view.js +1 -1
  9. package/dist/smart/view/js/view.js.gz +0 -0
  10. package/dist/smart/view/js/view.min.js +1 -1
  11. package/dist/smart/view/js/view.min.js.gz +0 -0
  12. package/dist/smart/view/smart.manifest.json +1 -1
  13. package/dist/smart/view/smart.manifest.json.gz +0 -0
  14. package/dist/smart/view/static/default/open-record.html +1 -1
  15. package/dist/smart/view/static/default/open-record.html.gz +0 -0
  16. package/dist/smart/view/static/default/reference.html +1 -1
  17. package/dist/smart/view/static/default/reference.html.gz +0 -0
  18. package/dist/smart/view-flow/component.json +620 -0
  19. package/dist/smart/view-flow/component.json.gz +0 -0
  20. package/dist/smart/view-flow/css/view-flow.css +570 -0
  21. package/dist/smart/view-flow/css/view-flow.css.gz +0 -0
  22. package/dist/smart/view-flow/css/view-flow.min.css +3 -0
  23. package/dist/smart/view-flow/css/view-flow.min.css.gz +0 -0
  24. package/dist/smart/view-flow/examples.json +452 -0
  25. package/dist/smart/view-flow/examples.json.gz +0 -0
  26. package/dist/smart/view-flow/js/view-flow.js +7406 -0
  27. package/dist/smart/view-flow/js/view-flow.js.gz +0 -0
  28. package/dist/smart/view-flow/js/view-flow.min.js +749 -0
  29. package/dist/smart/view-flow/js/view-flow.min.js.gz +0 -0
  30. package/dist/smart/view-flow/lang/en.json +24 -0
  31. package/dist/smart/view-flow/lang/en.json.gz +0 -0
  32. package/dist/smart/view-flow/lang/ru.json +24 -0
  33. package/dist/smart/view-flow/lang/ru.json.gz +0 -0
  34. package/dist/smart/view-flow/probe.json +149 -0
  35. package/dist/smart/view-flow/probe.json.gz +0 -0
  36. package/dist/smart/view-flow/smart.manifest.json +486 -0
  37. package/dist/smart/view-flow/smart.manifest.json.gz +0 -0
  38. package/dist/smart/view-flow/static/default/answered.html +57 -0
  39. package/dist/smart/view-flow/static/default/answered.html.gz +0 -0
  40. package/dist/smart/view-flow/static/default/ask.html +146 -0
  41. package/dist/smart/view-flow/static/default/ask.html.gz +0 -0
  42. package/dist/smart/view-flow/static/default/expired.html +16 -0
  43. package/dist/smart/view-flow/static/default/expired.html.gz +0 -0
  44. package/dist/smart/view-flow/static/default/groups.html +44 -0
  45. package/dist/smart/view-flow/static/default/groups.html.gz +0 -0
  46. package/dist/smart/view-flow/static/default/reference.html +72 -0
  47. package/dist/smart/view-flow/static/default/reference.html.gz +0 -0
  48. package/dist/smart/view-flow/static/default/untitled.html +41 -0
  49. package/dist/smart/view-flow/static/default/untitled.html.gz +0 -0
  50. package/dist/smart/view-flow/static/sheets.json +443 -0
  51. package/dist/smart/view-flow/static/sheets.json.gz +0 -0
  52. package/dist/smart/view-flow/template/default.css +180 -0
  53. package/dist/smart/view-flow/template/default.css.gz +0 -0
  54. package/dist/smart/view-flow/template/default.js +136 -0
  55. package/dist/smart/view-flow/template/default.js.gz +0 -0
  56. package/dist/smart/view-properties/component.json +8 -1
  57. package/dist/smart/view-properties/component.json.gz +0 -0
  58. package/dist/smart/view-properties/css/view-properties.css +367 -0
  59. package/dist/smart/view-properties/css/view-properties.css.gz +0 -0
  60. package/dist/smart/view-properties/css/view-properties.min.css +1 -0
  61. package/dist/smart/view-properties/css/view-properties.min.css.gz +0 -0
  62. package/dist/smart/view-properties/js/view-properties.js +1755 -169
  63. package/dist/smart/view-properties/js/view-properties.js.gz +0 -0
  64. package/dist/smart/view-properties/js/view-properties.min.js +491 -378
  65. package/dist/smart/view-properties/js/view-properties.min.js.gz +0 -0
  66. package/dist/smart/view-properties/smart.manifest.json +38 -3
  67. package/dist/smart/view-properties/smart.manifest.json.gz +0 -0
  68. package/dist/smart/view-properties/template/default.js +1 -77
  69. package/dist/smart/view-properties/template/default.js.gz +0 -0
  70. package/dist/smart/view-table/js/view-table.js +2 -0
  71. package/dist/smart/view-table/js/view-table.js.gz +0 -0
  72. package/dist/smart/view-table/js/view-table.min.js +2 -0
  73. package/dist/smart/view-table/js/view-table.min.js.gz +0 -0
  74. package/package.json +1 -1
@@ -0,0 +1,452 @@
1
+ {
2
+ "examples": [
3
+ {
4
+ "name": "reference",
5
+ "title": "Данные записи",
6
+ "settings": {
7
+ "heading": "Заявка на отпуск № 17",
8
+ "fields": [
9
+ {
10
+ "key": "employee",
11
+ "label": "Сотрудник",
12
+ "propertyType": "string",
13
+ "width": "full",
14
+ "value": "Ирина Волкова"
15
+ },
16
+ {
17
+ "key": "from",
18
+ "label": "С",
19
+ "propertyType": "date",
20
+ "width": "half",
21
+ "value": "2026-12-21"
22
+ },
23
+ {
24
+ "key": "to",
25
+ "label": "По",
26
+ "propertyType": "date",
27
+ "width": "half",
28
+ "value": "2027-01-08"
29
+ },
30
+ {
31
+ "key": "days",
32
+ "label": "Дней",
33
+ "propertyType": "integer",
34
+ "width": "half",
35
+ "value": 19
36
+ },
37
+ {
38
+ "key": "status",
39
+ "label": "Статус",
40
+ "propertyType": "choice",
41
+ "width": "half",
42
+ "value": "approved",
43
+ "options": [
44
+ {
45
+ "value": "approved",
46
+ "label": "Согласована",
47
+ "scheme": "success"
48
+ }
49
+ ]
50
+ }
51
+ ]
52
+ },
53
+ "expect": {
54
+ "name": "Заявка на отпуск № 17"
55
+ },
56
+ "parent": "<div style=\"inline-size: 32rem; max-inline-size: 100%\"></div>",
57
+ "x-first-paint": "A message's width: the block is as wide as its flow."
58
+ },
59
+ {
60
+ "name": "ask",
61
+ "title": "Заполнить и отправить",
62
+ "settings": {
63
+ "mode": "edit",
64
+ "heading": "Новая командировка",
65
+ "block-id": "b1",
66
+ "fields": [
67
+ {
68
+ "key": "city",
69
+ "label": "Город",
70
+ "propertyType": "string",
71
+ "width": "half",
72
+ "required": true,
73
+ "placeholder": "Куда",
74
+ "value": null
75
+ },
76
+ {
77
+ "key": "from",
78
+ "label": "Выезд",
79
+ "propertyType": "date",
80
+ "width": "half",
81
+ "required": true,
82
+ "value": null
83
+ },
84
+ {
85
+ "key": "nights",
86
+ "label": "Ночей",
87
+ "propertyType": "integer",
88
+ "width": "half",
89
+ "value": 2
90
+ },
91
+ {
92
+ "key": "goal",
93
+ "label": "Цель поездки",
94
+ "propertyType": "text",
95
+ "width": "full",
96
+ "placeholder": "Например, встреча с заказчиком",
97
+ "value": null
98
+ }
99
+ ]
100
+ },
101
+ "expect": {
102
+ "name": "Новая командировка",
103
+ "host": {
104
+ "state": "open"
105
+ }
106
+ },
107
+ "parent": "<div style=\"inline-size: 32rem; max-inline-size: 100%\"></div>"
108
+ },
109
+ {
110
+ "name": "answered",
111
+ "title": "Ответ отправлен",
112
+ "settings": {
113
+ "mode": "edit",
114
+ "state": "accepted",
115
+ "heading": "Новая командировка",
116
+ "block-id": "b1",
117
+ "fields": [
118
+ {
119
+ "key": "city",
120
+ "label": "Город",
121
+ "propertyType": "string",
122
+ "width": "half",
123
+ "required": true,
124
+ "placeholder": "Куда",
125
+ "value": "Казань"
126
+ },
127
+ {
128
+ "key": "from",
129
+ "label": "Выезд",
130
+ "propertyType": "date",
131
+ "width": "half",
132
+ "required": true,
133
+ "value": "2026-11-20"
134
+ },
135
+ {
136
+ "key": "nights",
137
+ "label": "Ночей",
138
+ "propertyType": "integer",
139
+ "width": "half",
140
+ "value": 3
141
+ },
142
+ {
143
+ "key": "goal",
144
+ "label": "Цель поездки",
145
+ "propertyType": "text",
146
+ "width": "full",
147
+ "placeholder": "Например, встреча с заказчиком",
148
+ "value": "Встреча с заказчиком"
149
+ }
150
+ ]
151
+ },
152
+ "expect": {
153
+ "name": "Новая командировка",
154
+ "texts": {
155
+ ".sf-view-flow__status span": "Отправлено"
156
+ }
157
+ },
158
+ "parent": "<div style=\"inline-size: 32rem; max-inline-size: 100%\"></div>"
159
+ },
160
+ {
161
+ "name": "groups",
162
+ "title": "Группы",
163
+ "settings": {
164
+ "heading": "Заказ № 10458",
165
+ "groups": [
166
+ {
167
+ "key": "order",
168
+ "label": "Заказ",
169
+ "fields": [
170
+ {
171
+ "key": "buyer",
172
+ "label": "Покупатель",
173
+ "propertyType": "string",
174
+ "width": "half",
175
+ "value": "Анна Белова"
176
+ },
177
+ {
178
+ "key": "amount",
179
+ "label": "Сумма",
180
+ "propertyType": "number",
181
+ "unit": "₽",
182
+ "width": "half",
183
+ "value": 12490
184
+ }
185
+ ]
186
+ },
187
+ {
188
+ "key": "delivery",
189
+ "label": "Доставка",
190
+ "collapsible": true,
191
+ "collapsed": true,
192
+ "fields": [
193
+ {
194
+ "key": "city",
195
+ "label": "Город",
196
+ "propertyType": "string",
197
+ "width": "half",
198
+ "value": "Казань"
199
+ },
200
+ {
201
+ "key": "way",
202
+ "label": "Способ",
203
+ "propertyType": "string",
204
+ "width": "half",
205
+ "value": "Курьер"
206
+ }
207
+ ]
208
+ }
209
+ ]
210
+ },
211
+ "expect": {
212
+ "name": "Заказ № 10458"
213
+ },
214
+ "parent": "<div style=\"inline-size: 32rem; max-inline-size: 100%\"></div>"
215
+ },
216
+ {
217
+ "name": "expired",
218
+ "title": "Время ответа истекло",
219
+ "settings": {
220
+ "mode": "edit",
221
+ "heading": "Новая командировка",
222
+ "block-id": "b2",
223
+ "expires-at": "2020-01-01T00:00:00Z",
224
+ "fields": [
225
+ {
226
+ "key": "city",
227
+ "label": "Город",
228
+ "propertyType": "string",
229
+ "width": "half",
230
+ "required": true,
231
+ "placeholder": "Куда",
232
+ "value": null
233
+ },
234
+ {
235
+ "key": "from",
236
+ "label": "Выезд",
237
+ "propertyType": "date",
238
+ "width": "half",
239
+ "required": true,
240
+ "value": null
241
+ },
242
+ {
243
+ "key": "nights",
244
+ "label": "Ночей",
245
+ "propertyType": "integer",
246
+ "width": "half",
247
+ "value": 2
248
+ },
249
+ {
250
+ "key": "goal",
251
+ "label": "Цель поездки",
252
+ "propertyType": "text",
253
+ "width": "full",
254
+ "placeholder": "Например, встреча с заказчиком",
255
+ "value": null
256
+ }
257
+ ]
258
+ },
259
+ "expect": {
260
+ "name": "Новая командировка",
261
+ "events": [
262
+ "expired"
263
+ ]
264
+ },
265
+ "parent": "<div style=\"inline-size: 32rem; max-inline-size: 100%\"></div>"
266
+ },
267
+ {
268
+ "name": "untitled",
269
+ "title": "Без заголовка",
270
+ "settings": {
271
+ "fields": [
272
+ {
273
+ "key": "employee",
274
+ "label": "Сотрудник",
275
+ "propertyType": "string",
276
+ "width": "full",
277
+ "value": "Ирина Волкова"
278
+ },
279
+ {
280
+ "key": "from",
281
+ "label": "С",
282
+ "propertyType": "date",
283
+ "width": "half",
284
+ "value": "2026-12-21"
285
+ },
286
+ {
287
+ "key": "to",
288
+ "label": "По",
289
+ "propertyType": "date",
290
+ "width": "half",
291
+ "value": "2027-01-08"
292
+ }
293
+ ]
294
+ },
295
+ "expect": {
296
+ "name": "Данные"
297
+ },
298
+ "parent": "<div style=\"inline-size: 32rem; max-inline-size: 100%\"></div>"
299
+ }
300
+ ],
301
+ "pages": [
302
+ {
303
+ "name": "conformance",
304
+ "title": "sf-view-flow against component.json (standard simai.smart-component 1.4 §12, gate 20)",
305
+ "format": "stands/15-scenarios (A4 modal: a page, probes in steps); the runner is ui-source tests/browser/manifest-probes.browser.mjs, run for the package by scripts/run-manifest-probes.mjs",
306
+ "page": {
307
+ "lang": "ru",
308
+ "body": [
309
+ "<main>",
310
+ " <sf-view-flow id=\"b\" mode=\"edit\" heading=\"Новая командировка\" block-id=\"b1\" fields='[{\"key\": \"city\", \"label\": \"Город\", \"propertyType\": \"string\", \"width\": \"half\", \"required\": true, \"placeholder\": \"Куда\", \"value\": null}, {\"key\": \"from\", \"label\": \"Выезд\", \"propertyType\": \"date\", \"width\": \"half\", \"required\": true, \"value\": null}, {\"key\": \"nights\", \"label\": \"Ночей\", \"propertyType\": \"integer\", \"width\": \"half\", \"value\": 2}, {\"key\": \"goal\", \"label\": \"Цель поездки\", \"propertyType\": \"text\", \"width\": \"full\", \"placeholder\": \"Например, встреча с заказчиком\", \"value\": null}]'></sf-view-flow>",
311
+ " <sf-view-flow id=\"c\" mode=\"edit\" block-id=\"b2\" cancelable=\"false\" fields='[{\"key\": \"nights\", \"label\": \"Ночей\", \"propertyType\": \"integer\", \"width\": \"half\", \"value\": 2}]'></sf-view-flow>",
312
+ " <button id=\"page-send\" type=\"button\" data-sf-action=\"c.confirm\">Отправить</button>",
313
+ "</main>"
314
+ ]
315
+ },
316
+ "checks": [
317
+ {
318
+ "id": "p1-required-stops-send",
319
+ "title": "Send with the required fields empty sends nothing: each says «Заполните поле», the status line «Заполните отмеченные поля», and the block stays open",
320
+ "covers": "actions.confirm refused invalid, required, accessibility.name heading",
321
+ "steps": [
322
+ {
323
+ "script": "(document.activeElement?.blur?.(), true)",
324
+ "wait": 60,
325
+ "check": "document.querySelector('#b section').getAttribute('aria-labelledby') === document.querySelector('#b [role=heading]').id"
326
+ },
327
+ {
328
+ "action": {
329
+ "name": "confirm"
330
+ },
331
+ "target": "#b",
332
+ "wait": 120,
333
+ "expect": {
334
+ "returns": {
335
+ "outcome": "refused",
336
+ "reason": "invalid"
337
+ },
338
+ "events": [
339
+ {
340
+ "name": "sf-view-flow-answer",
341
+ "count": 0
342
+ }
343
+ ]
344
+ },
345
+ "check": "document.querySelector('#b').state === 'open' && document.querySelectorAll('#b .sf-view-flow__error').length === 2 && document.querySelector('#b .sf-view-flow__status span').textContent.trim() === 'Заполните отмеченные поля'"
346
+ }
347
+ ]
348
+ },
349
+ {
350
+ "id": "p2-cancel",
351
+ "title": "Cancel answers {id, accepted: false}; the block is pending, then declined when the host settles it, and shows only «Отменено»",
352
+ "covers": "actions.cancel, events.answer, actions.settle",
353
+ "steps": [
354
+ {
355
+ "action": {
356
+ "name": "cancel"
357
+ },
358
+ "target": "#b",
359
+ "expect": {
360
+ "returns": {
361
+ "outcome": "applied"
362
+ },
363
+ "events": [
364
+ {
365
+ "name": "sf-view-flow-answer",
366
+ "count": 1,
367
+ "detail": {
368
+ "id": "b1",
369
+ "accepted": false
370
+ }
371
+ }
372
+ ]
373
+ },
374
+ "check": "document.querySelector('#b').state === 'pending'"
375
+ },
376
+ {
377
+ "action": {
378
+ "name": "settle",
379
+ "with": {
380
+ "result": {
381
+ "answer": "applied"
382
+ }
383
+ }
384
+ },
385
+ "target": "#b",
386
+ "wait": 120,
387
+ "expect": {
388
+ "returns": {
389
+ "outcome": "applied"
390
+ }
391
+ },
392
+ "check": "document.querySelector('#b').state === 'declined' && !document.querySelector('#b .sf-view-flow__groups') && document.querySelector('#b .sf-view-flow__status span').textContent.trim() === 'Отменено'"
393
+ }
394
+ ]
395
+ },
396
+ {
397
+ "id": "p3-page-trigger-send",
398
+ "title": "a page button data-sf-action=\"c.confirm\" sends the untitled block with its values; without Cancel there is one answer; the block is named «Данные»",
399
+ "covers": "actions.confirm (§8 page trigger), cancelable false, accessibility.name runtime.block-label",
400
+ "steps": [
401
+ {
402
+ "script": "(document.activeElement?.blur?.(), true)",
403
+ "wait": 60,
404
+ "check": "document.querySelectorAll('#c sf-button').length === 1 && document.querySelector('#c section').getAttribute('aria-label') === 'Данные'"
405
+ },
406
+ {
407
+ "user": "click:#page-send",
408
+ "expect": {
409
+ "events": [
410
+ {
411
+ "name": "sf-view-flow-answer",
412
+ "count": 1,
413
+ "detail": {
414
+ "id": "b2",
415
+ "accepted": true,
416
+ "values": {
417
+ "nights": 2
418
+ }
419
+ }
420
+ }
421
+ ]
422
+ },
423
+ "check": "document.querySelector('#c').state === 'pending'"
424
+ }
425
+ ]
426
+ },
427
+ {
428
+ "id": "p4-expired",
429
+ "title": "an open block past expires-at reads as expired, says sf-view-flow-expired once and offers no answer",
430
+ "covers": "events.expired (own verb)",
431
+ "steps": [
432
+ {
433
+ "script": "(document.querySelector('#c').state = 'open', document.querySelector('#c').setAttribute('expires-at', '2020-01-01T00:00:00Z'), true)",
434
+ "expect": {
435
+ "events": [
436
+ {
437
+ "name": "sf-view-flow-expired",
438
+ "count": 1,
439
+ "detail": {
440
+ "id": "b2"
441
+ }
442
+ }
443
+ ]
444
+ },
445
+ "check": "document.querySelector('#c').shownState === 'expired' && document.querySelector('#c .sf-view-flow__actions').hidden"
446
+ }
447
+ ]
448
+ }
449
+ ]
450
+ }
451
+ ]
452
+ }