@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,89 @@
1
+ {
2
+ "title": "Property view",
3
+ "events": {
4
+ "state": {
5
+ "label": "Record state"
6
+ },
7
+ "address-copy": {
8
+ "label": "Address copied"
9
+ },
10
+ "favourite": {
11
+ "label": "Favourite"
12
+ }
13
+ },
14
+ "runtime": {
15
+ "add-field-text": "Add a field",
16
+ "add-group-text": "Add an area",
17
+ "add-section-text": "Add a section",
18
+ "add-view-text": "Add a view",
19
+ "back-label": "Back",
20
+ "cancel-configuring-text": "Cancel",
21
+ "cancel-name-text": "Leave the name",
22
+ "cancel-text": "Cancel",
23
+ "changed-text": "Fields changed",
24
+ "close-label": "Close",
25
+ "configure-hint-narrow-text": "Drag fields between groups. Applied at once.",
26
+ "configure-hint-text": "Drag fields between groups and onto a section on the left. Applied at once.",
27
+ "configure-text": "Arrange the view",
28
+ "confirm-save-text": "Confirm and save",
29
+ "conflict-text": "The record changed; read it again",
30
+ "copy-link-label": "Copy link",
31
+ "create-text": "Create",
32
+ "delete-text": "Delete",
33
+ "delete-view-text": "Remove the view",
34
+ "done-configuring-text": "Done",
35
+ "edit-text": "edit",
36
+ "empty-record-text": "This record has nothing to show",
37
+ "empty-text": "not filled in",
38
+ "errors-text": "Errors",
39
+ "favourite-label": "Favourite",
40
+ "field-label-text": "Name",
41
+ "field-settings-text": "Field settings",
42
+ "hidden-text": "Hide",
43
+ "hide-rare-text": "Hide rare fields",
44
+ "hint-text": "Hint",
45
+ "in-this-group-text": "In this area",
46
+ "inherited-text": "by default",
47
+ "keep-editing-text": "Keep editing",
48
+ "last-shared-view-text": "The only view everyone has",
49
+ "link-copied-label": "Link copied",
50
+ "menu-label": "More",
51
+ "move-down-text": "Move down",
52
+ "move-up-text": "Move up",
53
+ "new-group-title": "New area",
54
+ "new-section-title": "New section",
55
+ "new-view-text": "New view",
56
+ "no-match-text": "Nothing matches",
57
+ "open-full-label": "Open as a page",
58
+ "personal-layer-text": "Personal",
59
+ "rare-text": "rare",
60
+ "read-only-text": "You can only view this record",
61
+ "remove-field-text": "Remove from this area",
62
+ "remove-group-text": "Remove this area",
63
+ "remove-section-text": "Remove this section",
64
+ "rename-text": "Rename",
65
+ "reset-view-ask-text": "Reset the whole view?",
66
+ "reset-view-text": "Reset",
67
+ "save-failed-text": "The save failed",
68
+ "save-name-text": "Save the name",
69
+ "save-text": "Save",
70
+ "section-icon-text": "Section glyph",
71
+ "sections-label": "Sections",
72
+ "shared-layer-text": "Everyone's",
73
+ "show-rare-text": "Show rare fields",
74
+ "shown-text": "Shown",
75
+ "state-load-failed": "The record could not be read",
76
+ "state-loading": "Reading the record",
77
+ "state-port-not-connected": "The record port is not connected",
78
+ "state-unavailable": "The record is unavailable",
79
+ "unplaced-hint-text": "Fields this view does not show. Drag one into a group to place it, or drag a field here to take it out.",
80
+ "unplaced-title": "Not placed",
81
+ "variant-text": "Template",
82
+ "view-conflict-text": "The view changed and was read again",
83
+ "view-denied-text": "You may not change this layer",
84
+ "view-profile-label": "View",
85
+ "view-reset-failed-text": "The view could not be reset",
86
+ "view-save-failed-text": "The view could not be saved",
87
+ "width-text": "Full width"
88
+ }
89
+ }
@@ -0,0 +1,89 @@
1
+ {
2
+ "title": "Запись",
3
+ "events": {
4
+ "state": {
5
+ "label": "Состояние записи"
6
+ },
7
+ "address-copy": {
8
+ "label": "Адрес скопирован"
9
+ },
10
+ "favourite": {
11
+ "label": "Избранное"
12
+ }
13
+ },
14
+ "runtime": {
15
+ "add-field-text": "Добавить поле",
16
+ "add-group-text": "Добавить область",
17
+ "add-section-text": "Добавить раздел",
18
+ "add-view-text": "Добавить вид",
19
+ "back-label": "Назад",
20
+ "cancel-configuring-text": "Отменить",
21
+ "cancel-name-text": "Оставить название",
22
+ "cancel-text": "Отменить",
23
+ "changed-text": "Изменено полей",
24
+ "close-label": "Закрыть",
25
+ "configure-hint-narrow-text": "Перетаскивайте поля между группами. Применяется сразу.",
26
+ "configure-hint-text": "Перетаскивайте поля между группами и на разделы слева. Применяется сразу.",
27
+ "configure-text": "Настроить вид",
28
+ "confirm-save-text": "Подтвердить и сохранить",
29
+ "conflict-text": "Запись изменилась, обновите её",
30
+ "copy-link-label": "Копировать ссылку",
31
+ "create-text": "Создать",
32
+ "delete-text": "Удалить",
33
+ "delete-view-text": "Удалить вид",
34
+ "done-configuring-text": "Готово",
35
+ "edit-text": "изменить",
36
+ "empty-record-text": "В этой записи нечего показать",
37
+ "empty-text": "не заполнено",
38
+ "errors-text": "Ошибок",
39
+ "favourite-label": "В избранное",
40
+ "field-label-text": "Название",
41
+ "field-settings-text": "Настройки поля",
42
+ "hidden-text": "Скрыть",
43
+ "hide-rare-text": "Скрыть редкие поля",
44
+ "hint-text": "Подсказка",
45
+ "in-this-group-text": "В этой области",
46
+ "inherited-text": "по умолчанию",
47
+ "keep-editing-text": "Вернуться к правке",
48
+ "last-shared-view-text": "Единственный общий вид",
49
+ "link-copied-label": "Ссылка скопирована",
50
+ "menu-label": "Ещё",
51
+ "move-down-text": "Ниже",
52
+ "move-up-text": "Выше",
53
+ "new-group-title": "Новая область",
54
+ "new-section-title": "Новый раздел",
55
+ "new-view-text": "Новый вид",
56
+ "no-match-text": "Ничего не найдено",
57
+ "open-full-label": "Открыть на всю страницу",
58
+ "personal-layer-text": "Персональный",
59
+ "rare-text": "редкое",
60
+ "read-only-text": "Эту запись можно только смотреть",
61
+ "remove-field-text": "Убрать из области",
62
+ "remove-group-text": "Удалить область",
63
+ "remove-section-text": "Удалить раздел",
64
+ "rename-text": "Переименовать",
65
+ "reset-view-ask-text": "Сбросить весь вид?",
66
+ "reset-view-text": "Сбросить",
67
+ "save-failed-text": "Не удалось сохранить",
68
+ "save-name-text": "Сохранить название",
69
+ "save-text": "Сохранить",
70
+ "section-icon-text": "Значок раздела",
71
+ "sections-label": "Разделы",
72
+ "shared-layer-text": "Для всех",
73
+ "show-rare-text": "Показать редкие поля",
74
+ "shown-text": "Показывать",
75
+ "state-load-failed": "Не удалось загрузить запись",
76
+ "state-loading": "Загрузка записи",
77
+ "state-port-not-connected": "Порт записи не подключён",
78
+ "state-unavailable": "Запись недоступна",
79
+ "unplaced-hint-text": "Поля, которых нет в этом виде. Перетащите поле в группу, чтобы разместить, или сюда, чтобы убрать.",
80
+ "unplaced-title": "Не размещённые",
81
+ "variant-text": "Вид",
82
+ "view-conflict-text": "Вид изменился, он перезагружен",
83
+ "view-denied-text": "Нет права менять этот слой",
84
+ "view-profile-label": "Вид",
85
+ "view-reset-failed-text": "Не удалось сбросить вид",
86
+ "view-save-failed-text": "Не удалось сохранить вид",
87
+ "width-text": "На всю ширину"
88
+ }
89
+ }
@@ -0,0 +1,188 @@
1
+ {
2
+ "component": "sf-view-properties",
3
+ "probe": "sf-property-view against component.json (standard simai.smart-component 1.3.8 §12, gate 20; simai/ui-pro#3, #4)",
4
+ "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",
5
+ "page": {
6
+ "lang": "ru",
7
+ "body": [
8
+ "<main style=\"width: 1100px\">",
9
+ " <sf-view-properties id=\"p\" record-id=\"r1\" collection=\"workbench.solutions\" sections-as=\"tabs\" aria-label=\"Запись\"></sf-view-properties>",
10
+ " <sf-view-properties id=\"missing\" record-id=\"r-999\" aria-label=\"Запись\"></sf-view-properties>",
11
+ " <sf-view-properties id=\"panel\" panel record-id=\"r1\" panel-label=\"Запись\"></sf-view-properties>",
12
+ "</main>"
13
+ ]
14
+ },
15
+ "probes": [
16
+ {
17
+ "id": "p1-saved",
18
+ "title": "an applied group save is the fact sf-property-view-saved {id, revision}, once",
19
+ "covers": "events.saved (simai/ui-pro#4 item 1), actions.edit-group, actions.save-group, values.revision",
20
+ "steps": [
21
+ {
22
+ "script": "(() => { window.__calls = []; let revision = 1; const record = (id) => ({record_id: id, collection: 'workbench.solutions', revision: String(revision), label: 'Портал клиента', editable: true, actions: ['record.edit'], address: '/admin/r1', sections: [{key: 'main', label: 'Основное', groups: [{key: 'g', label: 'Главное', columns: 1, fields: [{key: 'title', label: 'Название', propertyType: 'string', width: 'full', value: 'Портал клиента'}]}]}, {key: 'links', label: 'Связи', groups: [{key: 'l', label: 'Ссылки', columns: 1, fields: [{key: 'site', label: 'Сайт', propertyType: 'string', width: 'full', value: 'simai.io'}]}]}]}); const port = {id: 'simai.property-view-port', version: '1.14.0', capabilities: [], raise: async (intent, payload) => { window.__calls.push(intent); if (window.__never) return new Promise(() => {}); if (intent === 'record.load') return payload.record_id === 'r1' ? {answer: 'applied', record: record('r1')} : {answer: 'refused', reason: 'record-unknown', message: 'Запись не найдена'}; if (intent === 'group.save') { revision += 1; return {answer: 'applied', revision: String(revision), record: record('r1')}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.querySelectorAll('sf-view-properties').forEach((one) => one.setHostPort(port)); return true; })()",
23
+ "wait": 900,
24
+ "expect": {
25
+ "values": {
26
+ "#p.revision": "1",
27
+ "#p.section": "main"
28
+ }
29
+ }
30
+ },
31
+ {
32
+ "action": {
33
+ "name": "edit-group",
34
+ "with": {
35
+ "section": "main",
36
+ "group": "g"
37
+ }
38
+ },
39
+ "target": "#p",
40
+ "wait": 300
41
+ },
42
+ {
43
+ "script": "(() => { const el = document.getElementById('p'); const field = el.sections[0].groups[0].fields[0]; el.changeField(field, 'Портал клиента 2'); return true; })()",
44
+ "wait": 200
45
+ },
46
+ {
47
+ "action": {
48
+ "name": "save-group"
49
+ },
50
+ "target": "#p",
51
+ "wait": 600,
52
+ "expect": {
53
+ "returns": {
54
+ "outcome": "applied"
55
+ },
56
+ "events": [
57
+ {
58
+ "name": "sf-view-properties-saved",
59
+ "count": 1,
60
+ "detail": {
61
+ "id": "r1",
62
+ "revision": "2"
63
+ }
64
+ }
65
+ ],
66
+ "values": {
67
+ "#p.revision": "2"
68
+ }
69
+ }
70
+ }
71
+ ]
72
+ },
73
+ {
74
+ "id": "p2-failed",
75
+ "title": "a record the host does not know is the fact sf-property-view-failed {reason: record-unknown}",
76
+ "covers": "events.failed",
77
+ "steps": [
78
+ {
79
+ "script": "(() => { window.__failed = []; document.getElementById('missing').addEventListener('sf-view-properties-failed', (event) => window.__failed.push(event.detail)); return true; })()",
80
+ "wait": 10
81
+ },
82
+ {
83
+ "script": "(() => { window.__calls = []; let revision = 1; const record = (id) => ({record_id: id, collection: 'workbench.solutions', revision: String(revision), label: 'Портал клиента', editable: true, actions: ['record.edit'], address: '/admin/r1', sections: [{key: 'main', label: 'Основное', groups: [{key: 'g', label: 'Главное', columns: 1, fields: [{key: 'title', label: 'Название', propertyType: 'string', width: 'full', value: 'Портал клиента'}]}]}, {key: 'links', label: 'Связи', groups: [{key: 'l', label: 'Ссылки', columns: 1, fields: [{key: 'site', label: 'Сайт', propertyType: 'string', width: 'full', value: 'simai.io'}]}]}]}); const port = {id: 'simai.property-view-port', version: '1.14.0', capabilities: [], raise: async (intent, payload) => { window.__calls.push(intent); if (window.__never) return new Promise(() => {}); if (intent === 'record.load') return payload.record_id === 'r1' ? {answer: 'applied', record: record('r1')} : {answer: 'refused', reason: 'record-unknown', message: 'Запись не найдена'}; if (intent === 'group.save') { revision += 1; return {answer: 'applied', revision: String(revision), record: record('r1')}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.querySelectorAll('sf-view-properties').forEach((one) => one.setHostPort(port)); return true; })()",
84
+ "wait": 900,
85
+ "check": "window.__failed.length === 1 && window.__failed[0].reason === 'record-unknown' && window.__failed[0].message === 'Запись не найдена'"
86
+ }
87
+ ]
88
+ },
89
+ {
90
+ "id": "p3-panel-hidden",
91
+ "title": "a panel shows while it is not hidden: hidden closes its drawer, removing hidden opens it again (one element)",
92
+ "covers": "settings.open, hidden (simai/ui-pro#4 item 2, §7.2.2)",
93
+ "steps": [
94
+ {
95
+ "script": "(() => { window.__calls = []; let revision = 1; const record = (id) => ({record_id: id, collection: 'workbench.solutions', revision: String(revision), label: 'Портал клиента', editable: true, actions: ['record.edit'], address: '/admin/r1', sections: [{key: 'main', label: 'Основное', groups: [{key: 'g', label: 'Главное', columns: 1, fields: [{key: 'title', label: 'Название', propertyType: 'string', width: 'full', value: 'Портал клиента'}]}]}, {key: 'links', label: 'Связи', groups: [{key: 'l', label: 'Ссылки', columns: 1, fields: [{key: 'site', label: 'Сайт', propertyType: 'string', width: 'full', value: 'simai.io'}]}]}]}); const port = {id: 'simai.property-view-port', version: '1.14.0', capabilities: [], raise: async (intent, payload) => { window.__calls.push(intent); if (window.__never) return new Promise(() => {}); if (intent === 'record.load') return payload.record_id === 'r1' ? {answer: 'applied', record: record('r1')} : {answer: 'refused', reason: 'record-unknown', message: 'Запись не найдена'}; if (intent === 'group.save') { revision += 1; return {answer: 'applied', revision: String(revision), record: record('r1')}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.querySelectorAll('sf-view-properties').forEach((one) => one.setHostPort(port)); return true; })()",
96
+ "wait": 1000,
97
+ "check": "document.querySelector('#panel sf-drawer')?.hasAttribute('open') === true"
98
+ },
99
+ {
100
+ "script": "(document.getElementById('panel').hidden = true, true)",
101
+ "wait": 600,
102
+ "check": "document.querySelector('#panel sf-drawer')?.hasAttribute('open') === false"
103
+ },
104
+ {
105
+ "script": "(document.getElementById('panel').hidden = false, true)",
106
+ "wait": 600,
107
+ "check": "document.querySelector('#panel sf-drawer')?.hasAttribute('open') === true"
108
+ },
109
+ {
110
+ "script": "(document.getElementById('panel').setAttribute('open', 'false'), true)",
111
+ "wait": 600,
112
+ "check": "document.querySelector('#panel sf-drawer')?.hasAttribute('open') === false"
113
+ }
114
+ ]
115
+ },
116
+ {
117
+ "id": "p4-close-refused",
118
+ "title": "close is a cancelable request: a listener refuses it and close-panel answers refused",
119
+ "covers": "events.close cancelable (vocabulary §5 close, §19.3), actions.close-panel",
120
+ "steps": [
121
+ {
122
+ "script": "(() => { window.__calls = []; let revision = 1; const record = (id) => ({record_id: id, collection: 'workbench.solutions', revision: String(revision), label: 'Портал клиента', editable: true, actions: ['record.edit'], address: '/admin/r1', sections: [{key: 'main', label: 'Основное', groups: [{key: 'g', label: 'Главное', columns: 1, fields: [{key: 'title', label: 'Название', propertyType: 'string', width: 'full', value: 'Портал клиента'}]}]}, {key: 'links', label: 'Связи', groups: [{key: 'l', label: 'Ссылки', columns: 1, fields: [{key: 'site', label: 'Сайт', propertyType: 'string', width: 'full', value: 'simai.io'}]}]}]}); const port = {id: 'simai.property-view-port', version: '1.14.0', capabilities: [], raise: async (intent, payload) => { window.__calls.push(intent); if (window.__never) return new Promise(() => {}); if (intent === 'record.load') return payload.record_id === 'r1' ? {answer: 'applied', record: record('r1')} : {answer: 'refused', reason: 'record-unknown', message: 'Запись не найдена'}; if (intent === 'group.save') { revision += 1; return {answer: 'applied', revision: String(revision), record: record('r1')}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.querySelectorAll('sf-view-properties').forEach((one) => one.setHostPort(port)); return true; })()",
123
+ "wait": 900
124
+ },
125
+ {
126
+ "script": "(document.getElementById('p').addEventListener('sf-view-properties-close', (event) => event.preventDefault()), true)",
127
+ "wait": 10
128
+ },
129
+ {
130
+ "action": {
131
+ "name": "close-panel",
132
+ "with": {
133
+ "reason": "close"
134
+ }
135
+ },
136
+ "target": "#p",
137
+ "wait": 200,
138
+ "expect": {
139
+ "returns": {
140
+ "outcome": "refused"
141
+ },
142
+ "events": [
143
+ {
144
+ "name": "sf-view-properties-close",
145
+ "count": 1,
146
+ "detail": {
147
+ "reason": "close"
148
+ }
149
+ }
150
+ ]
151
+ }
152
+ }
153
+ ]
154
+ },
155
+ {
156
+ "id": "p5-skeleton-tabs",
157
+ "title": "while the record is on its way the section tabs' strip is drawn with the skeleton",
158
+ "covers": "simai/ui-pro#3 items 2-3, presentation.skeleton",
159
+ "steps": [
160
+ {
161
+ "script": "(() => { window.__never = true; return true; })()",
162
+ "wait": 10
163
+ },
164
+ {
165
+ "script": "(() => { window.__calls = []; let revision = 1; const record = (id) => ({record_id: id, collection: 'workbench.solutions', revision: String(revision), label: 'Портал клиента', editable: true, actions: ['record.edit'], address: '/admin/r1', sections: [{key: 'main', label: 'Основное', groups: [{key: 'g', label: 'Главное', columns: 1, fields: [{key: 'title', label: 'Название', propertyType: 'string', width: 'full', value: 'Портал клиента'}]}]}, {key: 'links', label: 'Связи', groups: [{key: 'l', label: 'Ссылки', columns: 1, fields: [{key: 'site', label: 'Сайт', propertyType: 'string', width: 'full', value: 'simai.io'}]}]}]}); const port = {id: 'simai.property-view-port', version: '1.14.0', capabilities: [], raise: async (intent, payload) => { window.__calls.push(intent); if (window.__never) return new Promise(() => {}); if (intent === 'record.load') return payload.record_id === 'r1' ? {answer: 'applied', record: record('r1')} : {answer: 'refused', reason: 'record-unknown', message: 'Запись не найдена'}; if (intent === 'group.save') { revision += 1; return {answer: 'applied', revision: String(revision), record: record('r1')}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.querySelectorAll('sf-view-properties').forEach((one) => one.setHostPort(port)); return true; })()",
166
+ "wait": 600,
167
+ "check": "Boolean(document.querySelector('#p [data-sf-skeleton=\"tabs\"]')) && document.getElementById('p').getAttribute('data-state') === 'loading'"
168
+ }
169
+ ]
170
+ },
171
+ {
172
+ "id": "p6-full",
173
+ "title": "full draws a panel in place: no drawer while full",
174
+ "covers": "settings.full",
175
+ "steps": [
176
+ {
177
+ "script": "(() => { window.__calls = []; let revision = 1; const record = (id) => ({record_id: id, collection: 'workbench.solutions', revision: String(revision), label: 'Портал клиента', editable: true, actions: ['record.edit'], address: '/admin/r1', sections: [{key: 'main', label: 'Основное', groups: [{key: 'g', label: 'Главное', columns: 1, fields: [{key: 'title', label: 'Название', propertyType: 'string', width: 'full', value: 'Портал клиента'}]}]}, {key: 'links', label: 'Связи', groups: [{key: 'l', label: 'Ссылки', columns: 1, fields: [{key: 'site', label: 'Сайт', propertyType: 'string', width: 'full', value: 'simai.io'}]}]}]}); const port = {id: 'simai.property-view-port', version: '1.14.0', capabilities: [], raise: async (intent, payload) => { window.__calls.push(intent); if (window.__never) return new Promise(() => {}); if (intent === 'record.load') return payload.record_id === 'r1' ? {answer: 'applied', record: record('r1')} : {answer: 'refused', reason: 'record-unknown', message: 'Запись не найдена'}; if (intent === 'group.save') { revision += 1; return {answer: 'applied', revision: String(revision), record: record('r1')}; } return {answer: 'unavailable', reason: 'capability-not-provided'}; } }; document.querySelectorAll('sf-view-properties').forEach((one) => one.setHostPort(port)); return true; })()",
178
+ "wait": 1000
179
+ },
180
+ {
181
+ "script": "(document.getElementById('panel').full = true, true)",
182
+ "wait": 600,
183
+ "check": "!document.querySelector('#panel sf-drawer[open]') && Boolean(document.querySelector('#panel .sf-property-view-layout'))"
184
+ }
185
+ ]
186
+ }
187
+ ]
188
+ }
@@ -0,0 +1,13 @@
1
+ <!-- sf-view-properties skeleton (standard simai.smart-component 1.3.8 §5.4, item 25; simai/ui-pro#3):
2
+ settings only, no data and no script. It is the element's own loading render
3
+ (js/templates/default.js renderLoading) as a server prints it: the strip of
4
+ section tabs, drawn by the stylesheet only for sections-as tabs in the wide
5
+ arrangement, and three group cards in the shape a group read by itself takes
6
+ until its fields come (port 1.15.0 group-load): a title bar and a line per
7
+ field. The element keeps it until the record comes (sfAwaitingData). -->
8
+ <div class="sf-property-view-tabs sf-property-view-tabs--skeleton flex items-cross-center gap-2" aria-hidden="true" data-sf-skeleton="tabs" data-sections-as="{{sections-as}}" data-sf-static><div class="flex-none" style="inline-size: 6rem"><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-3/4"></div></div></div><div class="flex-none" style="inline-size: 6rem"><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-2/5"></div></div></div><div class="flex-none" style="inline-size: 6rem"><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-1/3"></div></div></div></div>
9
+ <div class="sf-property-view-loading flex flex-col gap-4" data-state="loading" data-sf-static>
10
+ <section class="sf-property-view-group bg-surface-0 flex flex-col gap-2" aria-busy="true"><header class="sf-property-view-group-header flex items-cross-center content-main-between gap-2"><div class="flex-1"><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-1/3"></div></div></div></header><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-2/3"></div></div><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-1/2"></div></div><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-3/4"></div></div></section>
11
+ <section class="sf-property-view-group bg-surface-0 flex flex-col gap-2" aria-busy="true"><header class="sf-property-view-group-header flex items-cross-center content-main-between gap-2"><div class="flex-1"><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-2/3"></div></div></div></header><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-1/2"></div></div><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-3/4"></div></div><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-2/5"></div></div></section>
12
+ <section class="sf-property-view-group bg-surface-0 flex flex-col gap-2" aria-busy="true"><header class="sf-property-view-group-header flex items-cross-center content-main-between gap-2"><div class="flex-1"><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-1/2"></div></div></div></header><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-3/4"></div></div><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-2/5"></div></div><div class="sf-skeleton sf-skeleton--animation-pulse" aria-hidden="true"><div class="sf-skeleton-text sf-skeleton-text--size-1 w-1/3"></div></div></section>
13
+ <span class="sr-only" role="status"></span></div>