@yadsh/dsh-qa-surface 0.17.0 → 0.19.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 (213) hide show
  1. package/README.md +35 -25
  2. package/compatibility.json +1 -1
  3. package/lib/account-remotes.js +4 -0
  4. package/lib/account-remotes.js.map +1 -1
  5. package/lib/accounts/database.js +86 -1
  6. package/lib/accounts/database.js.map +1 -1
  7. package/lib/accounts/file.js.map +1 -1
  8. package/lib/accounts/store.js +111 -5
  9. package/lib/accounts/store.js.map +1 -1
  10. package/lib/accounts/token.js +8 -2
  11. package/lib/accounts/token.js.map +1 -1
  12. package/lib/admin/metrics.js +15 -2
  13. package/lib/admin/metrics.js.map +1 -1
  14. package/lib/admin/read-budget.js +28 -0
  15. package/lib/admin/read-budget.js.map +1 -0
  16. package/lib/admin/service.js +135 -40
  17. package/lib/admin/service.js.map +1 -1
  18. package/lib/admin/session-log.js +63 -4
  19. package/lib/admin/session-log.js.map +1 -1
  20. package/lib/attachment-access.js +147 -0
  21. package/lib/attachment-access.js.map +1 -0
  22. package/lib/chat-sharing/native-fence.js +20 -0
  23. package/lib/chat-sharing/native-fence.js.map +1 -1
  24. package/lib/chat-sharing/search.js +89 -0
  25. package/lib/chat-sharing/search.js.map +1 -0
  26. package/lib/chat-sharing/transport.js +10 -9
  27. package/lib/chat-sharing/transport.js.map +1 -1
  28. package/lib/chat-sharing/uploads.js +79 -6
  29. package/lib/chat-sharing/uploads.js.map +1 -1
  30. package/lib/cli.js +13 -0
  31. package/lib/cli.js.map +1 -1
  32. package/lib/client/QaAccountsController.js +61 -0
  33. package/lib/client/QaAccountsController.js.map +1 -1
  34. package/lib/client/QaRouteController.js +3 -1
  35. package/lib/client/QaRouteController.js.map +1 -1
  36. package/lib/client/QaSessionController.js +141 -35
  37. package/lib/client/QaSessionController.js.map +1 -1
  38. package/lib/client/QaSurface.js +43 -13
  39. package/lib/client/QaSurface.js.map +1 -1
  40. package/lib/client/account-sessions.js +74 -8
  41. package/lib/client/account-sessions.js.map +1 -1
  42. package/lib/client/admin/CapabilityPicker.js +50 -0
  43. package/lib/client/admin/CapabilityPicker.js.map +1 -0
  44. package/lib/client/admin/CoverageNotice.js +9 -0
  45. package/lib/client/admin/CoverageNotice.js.map +1 -0
  46. package/lib/client/admin/QaAdmin.js +3 -150
  47. package/lib/client/admin/QaAdmin.js.map +1 -1
  48. package/lib/client/admin/RoleEditor.js +46 -0
  49. package/lib/client/admin/RoleEditor.js.map +1 -0
  50. package/lib/client/admin/capability-selection.js +63 -0
  51. package/lib/client/admin/capability-selection.js.map +1 -0
  52. package/lib/client/admin/pages/Conversations.js +35 -17
  53. package/lib/client/admin/pages/Conversations.js.map +1 -1
  54. package/lib/client/admin/pages/Overview.js +3 -2
  55. package/lib/client/admin/pages/Overview.js.map +1 -1
  56. package/lib/client/admin/pages/Quality.js +77 -20
  57. package/lib/client/admin/pages/Quality.js.map +1 -1
  58. package/lib/client/admin/pages/SkillFiles.js +14 -3
  59. package/lib/client/admin/pages/SkillFiles.js.map +1 -1
  60. package/lib/client/admin/shared.js +68 -3
  61. package/lib/client/admin/shared.js.map +1 -1
  62. package/lib/client/components/QaAuthGate.js +31 -28
  63. package/lib/client/components/QaAuthGate.js.map +1 -1
  64. package/lib/client/components/QaChangelog.js +71 -0
  65. package/lib/client/components/QaChangelog.js.map +1 -1
  66. package/lib/client/components/QaComposer.js +27 -4
  67. package/lib/client/components/QaComposer.js.map +1 -1
  68. package/lib/client/components/QaFormItem.js +63 -0
  69. package/lib/client/components/QaFormItem.js.map +1 -0
  70. package/lib/client/components/QaInputForm.js +281 -0
  71. package/lib/client/components/QaInputForm.js.map +1 -0
  72. package/lib/client/components/QaModal.js +17 -4
  73. package/lib/client/components/QaModal.js.map +1 -1
  74. package/lib/client/components/QaRequestWait.js +15 -0
  75. package/lib/client/components/QaRequestWait.js.map +1 -0
  76. package/lib/client/forms-styles.js +14 -0
  77. package/lib/client/forms-styles.js.map +1 -0
  78. package/lib/client/forms.js +40 -0
  79. package/lib/client/forms.js.map +1 -0
  80. package/lib/client/index.js +18 -2
  81. package/lib/client/index.js.map +1 -1
  82. package/lib/client/oidc-browser.js +39 -0
  83. package/lib/client/oidc-browser.js.map +1 -0
  84. package/lib/client/panels/PanelHost.js +23 -1
  85. package/lib/client/panels/PanelHost.js.map +1 -1
  86. package/lib/client/project-session-state.js.map +1 -1
  87. package/lib/client/request-wait-styles.js +7 -0
  88. package/lib/client/request-wait-styles.js.map +1 -0
  89. package/lib/client/settings/sections/interface.js +2 -1
  90. package/lib/client/settings/sections/interface.js.map +1 -1
  91. package/lib/client/settings/sections/status.js +3 -1
  92. package/lib/client/settings/sections/status.js.map +1 -1
  93. package/lib/client/styles.js +5 -3
  94. package/lib/client/styles.js.map +1 -1
  95. package/lib/client/types.js.map +1 -1
  96. package/lib/client.js +471 -72918
  97. package/lib/client.js.map +1 -1
  98. package/lib/config-resolvers/accounts.js +5 -4
  99. package/lib/config-resolvers/accounts.js.map +1 -1
  100. package/lib/config-resolvers/defaults.js +16 -0
  101. package/lib/config-resolvers/defaults.js.map +1 -1
  102. package/lib/config-resolvers/oidc.js +53 -0
  103. package/lib/config-resolvers/oidc.js.map +1 -0
  104. package/lib/config.js +71 -0
  105. package/lib/config.js.map +1 -1
  106. package/lib/filesystem-intent.js +39 -0
  107. package/lib/filesystem-intent.js.map +1 -0
  108. package/lib/forms/attachments.js +230 -0
  109. package/lib/forms/attachments.js.map +1 -0
  110. package/lib/forms/errors.js +37 -0
  111. package/lib/forms/errors.js.map +1 -0
  112. package/lib/forms/fingerprint.js +21 -0
  113. package/lib/forms/fingerprint.js.map +1 -0
  114. package/lib/forms/gate.js +125 -0
  115. package/lib/forms/gate.js.map +1 -0
  116. package/lib/forms/schema.js +182 -0
  117. package/lib/forms/schema.js.map +1 -0
  118. package/lib/forms/service.js +220 -0
  119. package/lib/forms/service.js.map +1 -0
  120. package/lib/forms/store.js +194 -0
  121. package/lib/forms/store.js.map +1 -0
  122. package/lib/forms/types.js +2 -0
  123. package/lib/forms/types.js.map +1 -0
  124. package/lib/forms/validation.js +113 -0
  125. package/lib/forms/validation.js.map +1 -0
  126. package/lib/index.js +271 -81
  127. package/lib/index.js.map +1 -1
  128. package/lib/oidc/http.js +30 -0
  129. package/lib/oidc/http.js.map +1 -0
  130. package/lib/oidc/service.js +250 -0
  131. package/lib/oidc/service.js.map +1 -0
  132. package/lib/qa-tools/activation-manager.js +24 -2
  133. package/lib/qa-tools/activation-manager.js.map +1 -1
  134. package/lib/qa-tools/catalog.js +11 -1
  135. package/lib/qa-tools/catalog.js.map +1 -1
  136. package/lib/qa-tools/index.js +27 -0
  137. package/lib/qa-tools/index.js.map +1 -1
  138. package/lib/qa-tools/request-user-form.js +121 -0
  139. package/lib/qa-tools/request-user-form.js.map +1 -0
  140. package/lib/request-scheduler.js +235 -0
  141. package/lib/request-scheduler.js.map +1 -0
  142. package/lib/resolve-config.js +2 -0
  143. package/lib/resolve-config.js.map +1 -1
  144. package/lib/secure-session.js +60 -60
  145. package/lib/secure-session.js.map +1 -1
  146. package/lib/session-create.js +125 -0
  147. package/lib/session-create.js.map +1 -0
  148. package/lib/typert.host.js +4636 -1103
  149. package/lib/typert.remote-client.d.ts +135 -5
  150. package/lib/typert.remote-client.js +4502 -1095
  151. package/lib/types/accounts/database.d.ts +8 -0
  152. package/lib/types/accounts/file.d.ts +2 -0
  153. package/lib/types/accounts/store.d.ts +17 -0
  154. package/lib/types/accounts/token.d.ts +3 -1
  155. package/lib/types/admin/metrics.d.ts +5 -1
  156. package/lib/types/admin/read-budget.d.ts +8 -0
  157. package/lib/types/admin/service.d.ts +17 -0
  158. package/lib/types/admin/session-log.d.ts +30 -1
  159. package/lib/types/attachment-access.d.ts +29 -0
  160. package/lib/types/chat-sharing/search.d.ts +5 -0
  161. package/lib/types/chat-sharing/uploads.d.ts +2 -1
  162. package/lib/types/client/QaAccountsController.d.ts +4 -0
  163. package/lib/types/client/QaRouteController.d.ts +1 -0
  164. package/lib/types/client/QaSessionController.d.ts +24 -12
  165. package/lib/types/client/QaSurface.d.ts +2 -0
  166. package/lib/types/client/admin/CapabilityPicker.d.ts +14 -0
  167. package/lib/types/client/admin/CoverageNotice.d.ts +6 -0
  168. package/lib/types/client/admin/RoleEditor.d.ts +15 -0
  169. package/lib/types/client/admin/capability-selection.d.ts +27 -0
  170. package/lib/types/client/admin/shared.d.ts +39 -1
  171. package/lib/types/client/components/QaAuthGate.d.ts +2 -0
  172. package/lib/types/client/components/QaFormItem.d.ts +20 -0
  173. package/lib/types/client/components/QaInputForm.d.ts +18 -0
  174. package/lib/types/client/components/QaRequestWait.d.ts +6 -0
  175. package/lib/types/client/forms-styles.d.ts +2 -0
  176. package/lib/types/client/forms.d.ts +23 -0
  177. package/lib/types/client/oidc-browser.d.ts +12 -0
  178. package/lib/types/client/project-session-state.d.ts +2 -4
  179. package/lib/types/client/request-wait-styles.d.ts +2 -0
  180. package/lib/types/client/types.d.ts +10 -4
  181. package/lib/types/config-resolvers/oidc.d.ts +3 -0
  182. package/lib/types/filesystem-intent.d.ts +12 -0
  183. package/lib/types/forms/attachments.d.ts +51 -0
  184. package/lib/types/forms/errors.d.ts +11 -0
  185. package/lib/types/forms/fingerprint.d.ts +9 -0
  186. package/lib/types/forms/gate.d.ts +33 -0
  187. package/lib/types/forms/schema.d.ts +72 -0
  188. package/lib/types/forms/service.d.ts +15 -0
  189. package/lib/types/forms/store.d.ts +25 -0
  190. package/lib/types/forms/types.d.ts +215 -0
  191. package/lib/types/forms/validation.d.ts +20 -0
  192. package/lib/types/index.d.ts +33 -12
  193. package/lib/types/oidc/http.d.ts +5 -0
  194. package/lib/types/oidc/service.d.ts +30 -0
  195. package/lib/types/oidc.js +2 -0
  196. package/lib/types/oidc.js.map +1 -0
  197. package/lib/types/qa-tools/activation-manager.d.ts +5 -0
  198. package/lib/types/qa-tools/catalog.d.ts +4 -1
  199. package/lib/types/qa-tools/index.d.ts +5 -1
  200. package/lib/types/qa-tools/request-user-form.d.ts +5 -0
  201. package/lib/types/request-scheduler.d.ts +28 -0
  202. package/lib/types/secure-session.d.ts +13 -26
  203. package/lib/types/session-create.d.ts +29 -0
  204. package/lib/types/types/accounts.d.ts +2 -0
  205. package/lib/types/types/admin.d.ts +6 -0
  206. package/lib/types/types/config.d.ts +6 -0
  207. package/lib/types/types/oidc.d.ts +36 -0
  208. package/lib/types/types/session.d.ts +8 -0
  209. package/lib/types/types.d.ts +2 -0
  210. package/lib/types/user-workspace.d.ts +4 -6
  211. package/lib/user-workspace.js +13 -67
  212. package/lib/user-workspace.js.map +1 -1
  213. package/package.json +66 -62
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /** Input requirements are separate from file requirements, including in the labels. */
3
+ export function QaFormItem(props) {
4
+ const { item, answer, disabled } = props, a = item.answer;
5
+ const required = a?.required || item.files.requirement === "required";
6
+ const choice = a && "options" in a ? a : undefined;
7
+ const selected = answer && "selected" in answer ? answer.selected : [];
8
+ const other = answer && "other_text" in answer ? (answer.other_text ?? "") : "";
9
+ const inputId = `qa-form-answer-${item.id}`;
10
+ return (_jsxs("fieldset", { className: "dsh-qa-form__item", disabled: disabled, children: [_jsxs("legend", { children: [item.title, " ", _jsx("small", { children: required ? "Обязательно" : "Необязательно — можно оставить пустым" })] }), item.description && _jsx("p", { children: item.description }), a && (_jsxs("p", { className: "dsh-qa-form__hint", children: [a.required ? "Ответ обязателен." : "Ответ можно оставить пустым.", " ", "min_length" in a && a.min_length
11
+ ? `Минимум ${a.min_length} символов.`
12
+ : ""] })), a && (a.type === "text" || a.type === "textarea") && (_jsxs("label", { htmlFor: inputId, children: [_jsx("span", { className: "dsh-qa-form__hint", children: "\u0412\u0430\u0448 \u043E\u0442\u0432\u0435\u0442" }), a.type === "textarea" ? (_jsx("textarea", { id: inputId, rows: 3, placeholder: a.placeholder, value: answer && "text" in answer ? answer.text : "", onChange: (e) => props.onAnswer({ type: a.type, text: e.target.value }) })) : (_jsx("input", { id: inputId, type: "text", placeholder: a.placeholder, value: answer && "text" in answer ? answer.text : "", onChange: (e) => props.onAnswer({ type: a.type, text: e.target.value }) }))] })), choice && (_jsxs("div", { className: "dsh-qa-form__choices", children: [choice.options.map((o) => (_jsxs("label", { children: [_jsx("input", { type: choice.type === "single_select" ? "radio" : "checkbox", name: inputId, checked: selected.includes(o.value), onChange: (e) => props.onAnswer({
13
+ type: choice.type,
14
+ selected: choice.type === "single_select"
15
+ ? [o.value]
16
+ : e.target.checked
17
+ ? [...selected, o.value]
18
+ : selected.filter((v) => v !== o.value),
19
+ ...(choice.type === "multi_select" && other
20
+ ? { other_text: other }
21
+ : {}),
22
+ }) }), _jsxs("span", { children: [o.label, o.recommended ? " · Рекомендуется" : "", o.description && _jsx("small", { children: o.description })] })] }, o.value))), choice.allow_other && (_jsxs("label", { children: ["\u0421\u0432\u043E\u0439 \u0432\u0430\u0440\u0438\u0430\u043D\u0442", _jsx("input", { type: "text", value: other, onChange: (e) => props.onAnswer({
23
+ type: choice.type,
24
+ selected: choice.type === "single_select" && e.target.value
25
+ ? []
26
+ : selected,
27
+ other_text: e.target.value,
28
+ }) })] })), !choice.required && (_jsx("button", { type: "button", onClick: () => props.onAnswer(null), children: "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u043E\u0442\u0432\u0435\u0442" }))] })), item.files.requirement !== "none" && (_jsxs("div", { className: "dsh-qa-form__files", onDragOver: (e) => e.preventDefault(), onDrop: (e) => {
29
+ e.preventDefault();
30
+ if (!disabled)
31
+ for (const f of Array.from(e.dataTransfer.files))
32
+ props.onUpload(f);
33
+ }, children: [_jsxs("p", { children: [item.files.requirement === "required"
34
+ ? `Приложите ${item.files.min_count}–${item.files.max_count} файлов.`
35
+ : `Файлы необязательны, до ${item.files.max_count}.`, " ", item.files.accept.join(", "), " \u00B7 \u0434\u043E", " ", Math.floor(item.files.max_file_size_bytes / 1048576), " \u041C\u0438\u0411"] }), _jsxs("label", { children: ["\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0444\u0430\u0439\u043B\u044B \u0438\u043B\u0438 \u043F\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u044C \u0441\u044E\u0434\u0430", _jsx("input", { type: "file", multiple: true, accept: item.files.accept.join(","), onChange: (e) => {
36
+ for (const f of Array.from(e.target.files ?? []))
37
+ props.onUpload(f);
38
+ e.target.value = "";
39
+ } })] }), _jsx("ul", { children: props.files.map((f) => (_jsxs("li", { children: [_jsxs("span", { children: [f.name, " \u00B7 ", f.size_bytes, " \u0411 \u00B7 \u0432\u0435\u0440\u0441\u0438\u044F ", f.version, " \u00B7 \u0413\u043E\u0442\u043E\u0432"] }), _jsx("button", { type: "button", onClick: () => props.onOpen(f), children: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C" }), _jsxs("label", { children: ["\u0417\u0430\u043C\u0435\u043D\u0438\u0442\u044C", _jsx("input", { type: "file", "aria-label": `Заменить ${f.name}`, accept: item.files.requirement === "none"
40
+ ? ""
41
+ : item.files.accept.join(","), onChange: (e) => {
42
+ const next = e.target.files?.[0];
43
+ if (next)
44
+ props.onUpload(next, {
45
+ attachment_id: f.attachment_id,
46
+ version: f.version,
47
+ });
48
+ e.target.value = "";
49
+ } })] }), _jsx("button", { type: "button", onClick: () => props.onRemove(f), children: "\u0423\u0431\u0440\u0430\u0442\u044C \u0438\u0437 \u043F\u0443\u043D\u043A\u0442\u0430" })] }, f.attachment_id))) }), props.uploads
50
+ .filter((u) => !["ready", "cancelled"].includes(u.state))
51
+ .map((u) => (_jsxs("div", { role: "status", children: [_jsxs("span", { children: [u.name, " \u00B7", " ", u.state === "failed"
52
+ ? "Ошибка загрузки"
53
+ : "Передача и проверка…"] }), u.state === "failed" && (_jsxs("label", { children: ["\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C: \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043B", _jsx("input", { type: "file", "aria-label": `Повторить загрузку ${u.name}`, onChange: (e) => {
54
+ const f = e.target.files?.[0];
55
+ if (f) {
56
+ props.onCancel(u);
57
+ props.onUpload(f, u.target);
58
+ }
59
+ } })] })), _jsx("button", { type: "button", onClick: () => props.onCancel(u), children: u.state === "failed"
60
+ ? "Убрать загрузку"
61
+ : "Отменить загрузку" })] }, u.id)))] }))] }));
62
+ }
63
+ //# sourceMappingURL=QaFormItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QaFormItem.js","sourceRoot":"","sources":["../../../src/client/components/QaFormItem.tsx"],"names":[],"mappings":";AAsBA,uFAAuF;AACvF,MAAM,UAAU,UAAU,CAAC,KAAY;IACrC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,EACtC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IAClB,MAAM,QAAQ,GAAG,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC;IACtE,MAAM,MAAM,GAAG,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,UAAU,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,MAAM,KAAK,GACT,MAAM,IAAI,YAAY,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,MAAM,OAAO,GAAG,kBAAkB,IAAI,CAAC,EAAE,EAAE,CAAC;IAC5C,OAAO,CACL,oBAAU,SAAS,EAAC,mBAAmB,EAAC,QAAQ,EAAE,QAAQ,aACxD,6BACG,IAAI,CAAC,KAAK,EAAE,GAAG,EAChB,0BACG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,uCAAuC,GAC7D,IACD,EACR,IAAI,CAAC,WAAW,IAAI,sBAAI,IAAI,CAAC,WAAW,GAAK,EAC7C,CAAC,IAAI,CACJ,aAAG,SAAS,EAAC,mBAAmB,aAC7B,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,8BAA8B,EAAE,GAAG,EACtE,YAAY,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU;wBAChC,CAAC,CAAC,WAAW,CAAC,CAAC,UAAU,YAAY;wBACrC,CAAC,CAAC,EAAE,IACJ,CACL,EACA,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CACpD,iBAAO,OAAO,EAAE,OAAO,aACrB,eAAM,SAAS,EAAC,mBAAmB,kEAAiB,EACnD,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,CACvB,mBACE,EAAE,EAAE,OAAO,EACX,IAAI,EAAE,CAAC,EACP,WAAW,EAAE,CAAC,CAAC,WAAW,EAC1B,KAAK,EAAE,MAAM,IAAI,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EACpD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAExD,CACH,CAAC,CAAC,CAAC,CACF,gBACE,EAAE,EAAE,OAAO,EACX,IAAI,EAAC,MAAM,EACX,WAAW,EAAE,CAAC,CAAC,WAAW,EAC1B,KAAK,EAAE,MAAM,IAAI,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EACpD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAExD,CACH,IACK,CACT,EACA,MAAM,IAAI,CACT,eAAK,SAAS,EAAC,sBAAsB,aAClC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACzB,4BACE,gBACE,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAC5D,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EACnC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,KAAK,CAAC,QAAQ,CAAC;oCACb,IAAI,EAAE,MAAM,CAAC,IAAI;oCACjB,QAAQ,EACN,MAAM,CAAC,IAAI,KAAK,eAAe;wCAC7B,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;wCACX,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO;4CAChB,CAAC,CAAC,CAAC,GAAG,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;4CACxB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;oCAC7C,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK;wCACzC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE;wCACvB,CAAC,CAAC,EAAE,CAAC;iCACR,CAAC,GAEJ,EACF,2BACG,CAAC,CAAC,KAAK,EACP,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EACvC,CAAC,CAAC,WAAW,IAAI,0BAAQ,CAAC,CAAC,WAAW,GAAS,IAC3C,KAxBG,CAAC,CAAC,KAAK,CAyBX,CACT,CAAC,EACD,MAAM,CAAC,WAAW,IAAI,CACrB,mGAEE,gBACE,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,KAAK,CAAC,QAAQ,CAAC;oCACb,IAAI,EAAE,MAAM,CAAC,IAAI;oCACjB,QAAQ,EACN,MAAM,CAAC,IAAI,KAAK,eAAe,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK;wCAC/C,CAAC,CAAC,EAAE;wCACJ,CAAC,CAAC,QAAQ;oCACd,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK;iCAC3B,CAAC,GAEJ,IACI,CACT,EACA,CAAC,MAAM,CAAC,QAAQ,IAAI,CACnB,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,gGAEhD,CACV,IACG,CACP,EACA,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,MAAM,IAAI,CACpC,eACE,SAAS,EAAC,oBAAoB,EAC9B,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,EACrC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;oBACZ,CAAC,CAAC,cAAc,EAAE,CAAC;oBACnB,IAAI,CAAC,QAAQ;wBACX,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC;4BAC9C,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACxB,CAAC,aAED,wBACG,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,UAAU;gCACpC,CAAC,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,UAAU;gCACrE,CAAC,CAAC,2BAA2B,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,GAAG,EAC1D,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,0BAAO,GAAG,EACtC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,OAAO,CAAC,2BACnD,EACJ,wNAEE,gBACE,IAAI,EAAC,MAAM,EACX,QAAQ,QACR,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EACnC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;oCACd,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;wCAC9C,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oCACpB,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC;gCACtB,CAAC,GACD,IACI,EACR,uBACG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACtB,yBACE,2BACG,CAAC,CAAC,IAAI,cAAK,CAAC,CAAC,UAAU,0DAAc,CAAC,CAAC,OAAO,8CAC1C,EACP,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,2DAE3C,EACT,gFAEE,gBACE,IAAI,EAAC,MAAM,gBACC,YAAY,CAAC,CAAC,IAAI,EAAE,EAChC,MAAM,EACJ,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,MAAM;gDAC/B,CAAC,CAAC,EAAE;gDACJ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAEjC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;gDACd,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;gDACjC,IAAI,IAAI;oDACN,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE;wDACnB,aAAa,EAAE,CAAC,CAAC,aAAa;wDAC9B,OAAO,EAAE,CAAC,CAAC,OAAO;qDACnB,CAAC,CAAC;gDACL,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC;4CACtB,CAAC,GACD,IACI,EACR,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,uGAE7C,KA9BF,CAAC,CAAC,aAAa,CA+BnB,CACN,CAAC,GACC,EACJ,KAAK,CAAC,OAAO;yBACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;yBACxD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACV,eAAgB,IAAI,EAAC,QAAQ,aAC3B,2BACG,CAAC,CAAC,IAAI,aAAI,GAAG,EACb,CAAC,CAAC,KAAK,KAAK,QAAQ;wCACnB,CAAC,CAAC,iBAAiB;wCACnB,CAAC,CAAC,sBAAsB,IACrB,EACN,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CACvB,iKAEE,gBACE,IAAI,EAAC,MAAM,gBACC,sBAAsB,CAAC,CAAC,IAAI,EAAE,EAC1C,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;4CACd,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;4CAC9B,IAAI,CAAC,EAAE,CAAC;gDACN,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gDAClB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;4CAC9B,CAAC;wCACH,CAAC,GACD,IACI,CACT,EACD,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YACnD,CAAC,CAAC,KAAK,KAAK,QAAQ;oCACnB,CAAC,CAAC,iBAAiB;oCACnB,CAAC,CAAC,mBAAmB,GAChB,KA3BD,CAAC,CAAC,EAAE,CA4BR,CACP,CAAC,IACA,CACP,IACQ,CACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,281 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { DEFAULT_FORM_POLICY } from "../../forms/schema.js";
4
+ import { validateForm } from "../../forms/validation.js";
5
+ import { QaFormClientError, unwrapForm } from "../forms.js";
6
+ import { QaFormItem } from "./QaFormItem.js";
7
+ export function QaInputForm(props) {
8
+ const [record, setRecord] = useState(props.form), current = useRef(props.form);
9
+ const [answers, setAnswers] = useState(props.form.answers);
10
+ const local = useRef(answers), dirty = useRef(false), conflict = useRef(false);
11
+ const [error, setError] = useState(""), [saving, setSaving] = useState(false), [collapsed, setCollapsed] = useState(!props.form.waiting);
12
+ const queue = useRef(Promise.resolve()), alive = useRef(true);
13
+ const transfers = useRef(new Map());
14
+ const previousWaiting = useRef(props.form.waiting);
15
+ const [download, setDownload] = useState();
16
+ const update = useCallback((r) => {
17
+ if (!alive.current)
18
+ return;
19
+ current.current = r;
20
+ setRecord(r);
21
+ if (!dirty.current) {
22
+ local.current = r.answers;
23
+ setAnswers(r.answers);
24
+ }
25
+ }, []);
26
+ useEffect(() => {
27
+ if (record.waiting && !previousWaiting.current)
28
+ setCollapsed(false);
29
+ previousWaiting.current = record.waiting;
30
+ }, [record.waiting]);
31
+ useEffect(() => {
32
+ alive.current = true;
33
+ const active = transfers.current;
34
+ return () => {
35
+ alive.current = false;
36
+ for (const a of active.values())
37
+ a.abort();
38
+ };
39
+ }, []);
40
+ useEffect(() => () => {
41
+ if (download)
42
+ URL.revokeObjectURL(download.url);
43
+ }, [download]);
44
+ useEffect(() => {
45
+ props.onTakeover(record.status === "draft" && !collapsed);
46
+ return () => props.onTakeover(false);
47
+ }, [record.status, collapsed, props.onTakeover]);
48
+ const report = useCallback((e) => {
49
+ if (!alive.current)
50
+ return;
51
+ if (e instanceof QaFormClientError && e.code === "REVISION_CONFLICT")
52
+ conflict.current = true;
53
+ setError(e instanceof Error ? e.message : "Операция не подтверждена сервером.");
54
+ }, []);
55
+ const mutate = useCallback((op) => {
56
+ const work = queue.current
57
+ .catch(() => undefined)
58
+ .then(async () => {
59
+ if (conflict.current)
60
+ throw new QaFormClientError("REVISION_CONFLICT", "Форма изменилась в другом окне. Загрузите актуальное состояние перед повторным применением своих ответов.");
61
+ const command = {
62
+ ...op,
63
+ form_id: current.current.id,
64
+ expected_revision: current.current.revision,
65
+ mutation_id: crypto.randomUUID(),
66
+ };
67
+ const r = unwrapForm(await props.api.mutate(props.token, props.session, command));
68
+ update(r);
69
+ return r;
70
+ });
71
+ queue.current = work;
72
+ return work;
73
+ }, [props.api, props.token, props.session, update]);
74
+ const save = useCallback(async (step = current.current.step) => {
75
+ if (!dirty.current && step === current.current.step)
76
+ return current.current;
77
+ const snapshot = local.current;
78
+ setSaving(true);
79
+ try {
80
+ const r = await mutate({ action: "save", answers: snapshot, step });
81
+ if (local.current === snapshot)
82
+ dirty.current = false;
83
+ if (alive.current)
84
+ setError("");
85
+ return r;
86
+ }
87
+ finally {
88
+ if (alive.current)
89
+ setSaving(false);
90
+ }
91
+ }, [mutate]);
92
+ useEffect(() => {
93
+ if (!dirty.current || record.status !== "draft")
94
+ return;
95
+ const timer = setTimeout(() => {
96
+ void save().catch(report);
97
+ }, 650);
98
+ return () => clearTimeout(timer);
99
+ }, [answers, record.status, save, report]);
100
+ useEffect(() => {
101
+ let stopped = false;
102
+ const refresh = async () => {
103
+ try {
104
+ const r = unwrapForm(await props.api.get(props.token, props.session, props.form.id));
105
+ if (!stopped && !saving && r.revision >= current.current.revision) {
106
+ if (dirty.current &&
107
+ r.revision > current.current.revision &&
108
+ transfers.current.size === 0) {
109
+ conflict.current = true;
110
+ setError("Форма изменилась в другом окне. Ваши несохранённые ответы сохранены в этом окне для повторного применения.");
111
+ }
112
+ update(r);
113
+ }
114
+ }
115
+ catch (e) {
116
+ if (!stopped)
117
+ report(e);
118
+ }
119
+ };
120
+ const timer = setInterval(() => {
121
+ void refresh();
122
+ }, 1500);
123
+ return () => {
124
+ stopped = true;
125
+ clearInterval(timer);
126
+ };
127
+ }, [
128
+ props.api,
129
+ props.token,
130
+ props.session,
131
+ props.form.id,
132
+ saving,
133
+ update,
134
+ report,
135
+ ]);
136
+ const action = (work) => {
137
+ void work().catch(report);
138
+ };
139
+ const open = (file) => action(async () => {
140
+ const value = unwrapForm(await props.api.file(props.token, props.session, record.id, file.resource_id));
141
+ if (!alive.current)
142
+ return;
143
+ const bytes = Uint8Array.from(atob(value.data), (c) => c.charCodeAt(0));
144
+ setDownload({
145
+ url: URL.createObjectURL(new Blob([bytes], { type: value.media_type })),
146
+ name: value.name,
147
+ });
148
+ });
149
+ const upload = async (item, file, target) => {
150
+ const r = await mutate({
151
+ action: "begin_upload",
152
+ item_id: item,
153
+ name: file.name,
154
+ size_bytes: file.size,
155
+ ...(target ? { target } : {}),
156
+ });
157
+ const intent = r.uploads.at(-1);
158
+ const abort = new AbortController();
159
+ transfers.current.set(intent.id, abort);
160
+ let failure;
161
+ try {
162
+ await props.api.upload(props.token, props.session, intent.id, file, abort.signal);
163
+ }
164
+ catch (e) {
165
+ failure = e;
166
+ }
167
+ finally {
168
+ transfers.current.delete(intent.id);
169
+ }
170
+ if (!alive.current)
171
+ return;
172
+ const saved = unwrapForm(await props.api.get(props.token, props.session, r.id));
173
+ update(saved);
174
+ if (saved.uploads.find((u) => u.id === intent.id)?.state === "ready") {
175
+ setError("");
176
+ return;
177
+ }
178
+ if (failure !== undefined)
179
+ throw failure;
180
+ throw new QaFormClientError("UPLOAD_FAILED", "Загрузка не подтверждена сервером. Повторите её или уберите файл.");
181
+ };
182
+ const step = record.schema.steps[record.step], review = step === undefined;
183
+ const required = record.schema.steps
184
+ .flatMap((s) => s.items)
185
+ .filter((i) => i.answer?.required || i.files.requirement === "required");
186
+ const fieldErrors = validateForm({ ...record, answers }, props.policy ?? DEFAULT_FORM_POLICY);
187
+ const incomplete = new Set(fieldErrors.map((e) => e.item_id));
188
+ const blocked = fieldErrors.some((e) => review || e.step_id === step?.id);
189
+ const stop = () => {
190
+ for (const a of transfers.current.values())
191
+ a.abort();
192
+ void props.onStop().catch(report);
193
+ };
194
+ if (record.status === "submitted")
195
+ return (_jsxs("section", { className: "dsh-qa-form", "aria-label": record.schema.title, children: [_jsx("strong", { children: record.schema.title }), _jsxs("p", { children: ["\u0414\u0430\u043D\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u043D\u044B \u00B7 ", record.submission?.submitted_at] }), !record.waiting && (_jsx("button", { type: "button", onClick: () => props.onResume(record.id), children: "\u041F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C \u043F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043A\u0443" }))] }));
196
+ if (collapsed)
197
+ return (_jsxs("section", { className: "dsh-qa-form", children: [_jsx("strong", { children: record.schema.title }), _jsx("p", { children: "\u0427\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D. \u0421\u0431\u043E\u0440 \u0434\u0430\u043D\u043D\u044B\u0445 \u043D\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043D." }), _jsx("button", { type: "button", onClick: () => setCollapsed(false), children: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0444\u043E\u0440\u043C\u0443" }), !record.waiting && (_jsx("button", { type: "button", onClick: () => props.onResume(record.id), children: "\u041F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C \u0441 \u0430\u0433\u0435\u043D\u0442\u043E\u043C" }))] }));
198
+ return (_jsxs("section", { className: "dsh-qa-form", "aria-label": record.schema.title, children: [_jsxs("header", { children: [_jsx("strong", { children: record.schema.title }), _jsx("span", { children: review
199
+ ? "Проверка перед отправкой"
200
+ : `Шаг ${record.step + 1} из ${record.schema.steps.length}` })] }), _jsxs("div", { className: "dsh-qa-form__content", children: [record.schema.description && _jsx("p", { children: record.schema.description }), _jsxs("p", { role: "status", children: ["\u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u043F\u0443\u043D\u043A\u0442\u044B:", " ", required.filter((i) => !incomplete.has(i.id)).length, " \u0438\u0437", " ", required.length, ".", " ", saving
201
+ ? "Сохранение…"
202
+ : dirty.current
203
+ ? "Есть несохранённые изменения"
204
+ : "Черновик сохранён", " ", "\u00B7", " ", record.waiting
205
+ ? "Агент ожидает данные"
206
+ : "Агент не ожидает — сохранённый черновик"] }), _jsx("nav", { "aria-label": "\u0428\u0430\u0433\u0438 \u0444\u043E\u0440\u043C\u044B", children: record.schema.steps.map((s, index) => (_jsxs("button", { type: "button", "aria-current": index === record.step ? "step" : undefined, onClick: () => action(() => save(index)), children: [index + 1, ". ", s.title] }, s.id))) }), error && (_jsxs("div", { role: "alert", children: [_jsx("p", { children: error }), conflict.current && (_jsx("button", { type: "button", onClick: () => action(async () => {
207
+ await queue.current.catch(() => undefined);
208
+ const r = unwrapForm(await props.api.get(props.token, props.session, record.id));
209
+ update(r);
210
+ conflict.current = false;
211
+ await save();
212
+ }), children: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0430\u043A\u0442\u0443\u0430\u043B\u044C\u043D\u043E\u0435 \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C \u043C\u043E\u0438 \u043E\u0442\u0432\u0435\u0442\u044B" }))] })), download && (_jsxs("p", { children: [_jsxs("a", { href: download.url, download: download.name, children: ["\u0421\u043A\u0430\u0447\u0430\u0442\u044C ", download.name] }), " ", _jsx("a", { href: download.url, target: "_blank", rel: "noopener noreferrer", children: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0444\u0430\u0439\u043B" })] })), review ? (_jsxs("div", { className: "dsh-qa-form__review", children: [_jsx("h3", { children: "\u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u0434\u0430\u043D\u043D\u044B\u0435" }), record.schema.steps.map((s) => (_jsxs("div", { children: [_jsx("h4", { children: s.title }), s.items.map((i) => {
213
+ const a = answers[i.id];
214
+ return (_jsxs("div", { children: [_jsx("strong", { children: i.title }), _jsx("p", { children: a
215
+ ? "text" in a
216
+ ? a.text
217
+ : [
218
+ ...a.selected.map((v) => i.answer && "options" in i.answer
219
+ ? (i.answer.options.find((o) => o.value === v)?.label ?? v)
220
+ : v),
221
+ a.other_text,
222
+ ]
223
+ .filter(Boolean)
224
+ .join(", ")
225
+ : "Ответ не указан" }), (record.attachments[i.id] ?? []).map((f) => (_jsxs("p", { children: [f.name, " \u00B7 \u0432\u0435\u0440\u0441\u0438\u044F ", f.version, " \u00B7 ", f.size_bytes, " \u0411"] }, f.resource_id))), !a && !record.attachments[i.id]?.length && (_jsx("p", { children: "\u041D\u0435\u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0439 \u043F\u0443\u043D\u043A\u0442 \u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D \u043F\u0443\u0441\u0442\u044B\u043C" }))] }, i.id));
226
+ })] }, s.id)))] })) : (_jsxs("div", { children: [_jsx("h3", { children: step.title }), step.description && _jsx("p", { children: step.description }), step.items.map((item) => (_jsx(QaFormItem, { item: item, answer: answers[item.id] ?? null, files: record.attachments[item.id] ?? [], uploads: record.uploads.filter((u) => u.item_id === item.id), disabled: false, onAnswer: (answer) => {
227
+ dirty.current = true;
228
+ local.current = { ...local.current, [item.id]: answer };
229
+ setAnswers(local.current);
230
+ }, onUpload: (file, target) => action(() => upload(item.id, file, target)), onCancel: (u) => {
231
+ transfers.current.get(u.id)?.abort();
232
+ action(() => mutate({ action: "cancel_upload", upload_id: u.id }));
233
+ }, onRemove: (f) => action(() => mutate({
234
+ action: "remove",
235
+ item_id: item.id,
236
+ attachment_id: f.attachment_id,
237
+ version: f.version,
238
+ })), onOpen: open }, item.id)))] })), fieldErrors
239
+ .filter((e) => review || e.step_id === step?.id)
240
+ .map((e) => (_jsx("p", { className: "dsh-qa-form__hint", children: e.message }, `${e.item_id}:${e.code}`)))] }), _jsxs("footer", { children: [_jsx("button", { type: "button", disabled: record.step === 0 || saving, onClick: () => action(() => save(record.step - 1)), children: "\u041D\u0430\u0437\u0430\u0434" }), _jsx("button", { type: "button", disabled: saving || blocked, onClick: () => action(async () => {
241
+ await save();
242
+ if (review) {
243
+ await mutate({ action: "submit" });
244
+ }
245
+ else {
246
+ await save(record.step + 1);
247
+ }
248
+ }), children: review ? (record.schema.submit_label ?? "Передать данные") : "Далее" }), _jsx("button", { type: "button", onClick: () => action(async () => {
249
+ await save();
250
+ await mutate({ action: "pause" });
251
+ setCollapsed(true);
252
+ }), children: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u0438 \u0432\u044B\u0439\u0442\u0438" }), props.canStop && (_jsx("button", { type: "button", onClick: stop, children: "\u041E\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C" }))] })] }));
253
+ }
254
+ /** Session/identity-keyed parent discards account-local state and aborts transfers on switch. */
255
+ export function QaInputForms(props) {
256
+ const [forms, setForms] = useState([]);
257
+ useEffect(() => {
258
+ let active = true;
259
+ const refresh = async () => {
260
+ try {
261
+ const list = unwrapForm(await props.api.list(props.token, props.session));
262
+ if (active)
263
+ setForms(list);
264
+ }
265
+ catch {
266
+ /* Existing cards keep their explicit error/retry state. */
267
+ }
268
+ };
269
+ void refresh();
270
+ const timer = setInterval(() => {
271
+ void refresh();
272
+ }, 1500);
273
+ return () => {
274
+ active = false;
275
+ clearInterval(timer);
276
+ };
277
+ }, [props.api, props.token, props.session]);
278
+ const form = forms.find((r) => r.status === "draft") ?? forms[0];
279
+ return form ? _jsx(QaInputForm, { ...props, form: form }, form.id) : null;
280
+ }
281
+ //# sourceMappingURL=QaInputForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QaInputForm.js","sourceRoot":"","sources":["../../../src/client/components/QaInputForm.tsx"],"names":[],"mappings":"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"}
@@ -40,6 +40,10 @@ export function joinQaDialogStack() {
40
40
  */
41
41
  export function QaModal(props) {
42
42
  const closeButton = useRef(null);
43
+ const onClose = useRef(props.onClose);
44
+ useEffect(() => {
45
+ onClose.current = props.onClose;
46
+ }, [props.onClose]);
43
47
  useEffect(() => {
44
48
  if (!props.open)
45
49
  return;
@@ -51,16 +55,25 @@ export function QaModal(props) {
51
55
  return;
52
56
  if (openDialogs.at(-1) !== token)
53
57
  return;
54
- props.onClose();
58
+ const target = event.target;
59
+ if (target instanceof Element &&
60
+ target.closest('[role="menu"], [role="listbox"], [role="combobox"][aria-expanded="true"]'))
61
+ return;
62
+ event.preventDefault();
63
+ event.stopPropagation();
64
+ onClose.current();
55
65
  };
56
- window.addEventListener("keydown", onKey);
66
+ // Host tooltips can consume Escape during document capture. The top QA
67
+ // dialog owns it before that handler, including when its close button
68
+ // currently carries a Host tooltip.
69
+ window.addEventListener("keydown", onKey, true);
57
70
  return () => {
58
- window.removeEventListener("keydown", onKey);
71
+ window.removeEventListener("keydown", onKey, true);
59
72
  const index = openDialogs.indexOf(token);
60
73
  if (index >= 0)
61
74
  openDialogs.splice(index, 1);
62
75
  };
63
- }, [props.open, props.onClose]);
76
+ }, [props.open]);
64
77
  if (!props.open)
65
78
  return null;
66
79
  return (_jsx("div", { className: "dsh-qa-modal", "data-testid": "qa-surface-modal", role: "dialog", "aria-modal": "true", "aria-label": props.title, onClick: (event) => {
@@ -1 +1 @@
1
- {"version":3,"file":"QaModal.js","sourceRoot":"","sources":["../../../src/client/components/QaModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,GAAa,EAAE,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAI/B,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;IACrC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO;QACL,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK;QAC7C,KAAK,EAAE,GAAG,EAAE;YACV,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,KAAK,IAAI,CAAC;gBAAE,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC;AAsBD;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,KAAmB;IACzC,MAAM,WAAW,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IACpD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,CAAC,IAAI;YAAE,OAAO;QACxB,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;QACrC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,MAAM,KAAK,GAAG,CAAC,KAAoB,EAAE,EAAE;YACrC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ;gBAAE,OAAO;YACnC,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK;gBAAE,OAAO;YACzC,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAC7C,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,KAAK,IAAI,CAAC;gBAAE,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,CACL,cACE,SAAS,EAAC,cAAc,iBACZ,kBAAkB,EAC9B,IAAI,EAAC,QAAQ,gBACF,MAAM,gBACL,KAAK,CAAC,KAAK,EACvB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa;gBAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAC5D,CAAC,YAED,eACE,SAAS,EAAE,sBAAsB,aAAa,CAAC,KAAK,CAAC,EAAE,iBAC3C,wBAAwB,aAEpC,kBACE,SAAS,EAAC,oBAAoB,iBAClB,uBAAuB,aAEnC,aACE,SAAS,EAAC,qBAAqB,iBACnB,wBAAwB,YAEnC,KAAK,CAAC,KAAK,GACT,EACL,iBACE,GAAG,EAAE,WAAW,EAChB,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,qBAAqB,iBACnB,wBAAwB,gBACxB,KAAK,CAAC,UAAU,EAC5B,OAAO,EAAE,KAAK,CAAC,OAAO,YAEtB,cAAK,OAAO,EAAC,WAAW,iBAAa,MAAM,YACzC,eAAM,CAAC,EAAC,sBAAsB,GAAG,GAC7B,GACC,IACF,EACT,cAAK,SAAS,EAAC,oBAAoB,iBAAa,uBAAuB,YACpE,KAAK,CAAC,QAAQ,GACX,EACL,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACnC,iBACE,SAAS,EAAC,sBAAsB,iBACpB,yBAAyB,YAEpC,KAAK,CAAC,MAAM,GACN,CACV,IACG,GACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAmB;IACxC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACtE,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,yBAAyB,IAAI,EAAE,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"QaModal.js","sourceRoot":"","sources":["../../../src/client/components/QaModal.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /** A queued turn belongs to the Host and starts without resending the question. */
3
+ export function QaRequestWait({ status, }) {
4
+ if (status?.managed !== true || status.waiting !== true)
5
+ return null;
6
+ const estimate = status.estimatedWaitMs;
7
+ return (_jsxs("div", { className: "dsh-qa-request-wait", "data-testid": "qa-request-wait", role: "status", "aria-live": "polite", children: [_jsx("span", { className: "dsh-qa-request-wait__spinner", "aria-hidden": "true" }), _jsxs("span", { children: ["\u0417\u0430\u043F\u0440\u043E\u0441 \u0432 \u043E\u0447\u0435\u0440\u0435\u0434\u0438", status.position == null
8
+ ? ""
9
+ : ` · Место в очереди: ${String(status.position)}`, estimate == null
10
+ ? ""
11
+ : estimate < 60000
12
+ ? " · Примерное ожидание — меньше минуты"
13
+ : ` · Примерное ожидание — ${String(Math.ceil(estimate / 60000))} мин`] })] }));
14
+ }
15
+ //# sourceMappingURL=QaRequestWait.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QaRequestWait.js","sourceRoot":"","sources":["../../../src/client/components/QaRequestWait.tsx"],"names":[],"mappings":";AAEA,mFAAmF;AACnF,MAAM,UAAU,aAAa,CAAC,EAC5B,MAAM,GAGP;IACC,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrE,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,CAAC;IACxC,OAAO,CACL,eACE,SAAS,EAAC,qBAAqB,iBACnB,iBAAiB,EAC7B,IAAI,EAAC,QAAQ,eACH,QAAQ,aAElB,eAAM,SAAS,EAAC,8BAA8B,iBAAa,MAAM,GAAG,EACpE,qHAEG,MAAM,CAAC,QAAQ,IAAI,IAAI;wBACtB,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,uBAAuB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EACnD,QAAQ,IAAI,IAAI;wBACf,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,QAAQ,GAAG,KAAK;4BAChB,CAAC,CAAC,uCAAuC;4BACzC,CAAC,CAAC,2BAA2B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,IACrE,IACH,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ export const QA_FORM_STYLES = `
2
+ .dsh-qa-form{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;padding:16px;max-height:75vh;overflow:hidden;overflow-wrap:anywhere;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column}
3
+ .dsh-qa-form__content{overflow:auto;min-height:0;padding:0 2px}.dsh-qa-form>header,.dsh-qa-form>footer,.dsh-qa-form>nav,.dsh-qa-form>p{flex-shrink:0}.dsh-qa-form>footer{border-top:1px solid var(--dsw-alias-border-l2);padding-top:12px;margin-top:8px}
4
+ .dsh-qa-form>header{max-height:96px;overflow:auto}
5
+ .dsh-qa-form header,.dsh-qa-form footer,.dsh-qa-form nav{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
6
+ .dsh-qa-form header{justify-content:space-between}.dsh-qa-form nav{margin:12px 0}.dsh-qa-form h3{margin:12px 0}
7
+ .dsh-qa-form button{font:inherit;color:inherit;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px 12px;cursor:pointer}
8
+ .dsh-qa-form button:disabled{opacity:.55;cursor:default}.dsh-qa-form button:focus-visible,.dsh-qa-form input:focus-visible,.dsh-qa-form textarea:focus-visible{outline:var(--dsw-focus-ring-width,2px) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:2px}
9
+ .dsh-qa-form__item{min-width:0;border:0;border-bottom:1px solid var(--dsw-alias-border-l2);padding:12px 0;margin:0 0 12px}.dsh-qa-form legend{font-weight:600}.dsh-qa-form small{font-weight:400;display:block;color:var(--dsw-alias-label-tertiary)}
10
+ .dsh-qa-form__hint{font-size:13px;color:var(--dsw-alias-label-secondary)}.dsh-qa-form label{display:block}.dsh-qa-form input[type=text],.dsh-qa-form textarea{display:block;box-sizing:border-box;width:100%;font:inherit;color:inherit;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;margin:6px 0}
11
+ .dsh-qa-form__choices>label{display:flex;gap:8px;align-items:baseline;margin:8px 0}.dsh-qa-form__files{border:1px dashed var(--dsw-alias-border-l2);border-radius:8px;padding:12px;margin-top:12px}.dsh-qa-form input[type=file]{max-width:100%;display:block;margin:8px 0}.dsh-qa-form__files ul{padding-left:18px}.dsh-qa-form__files li{margin:10px 0}.dsh-qa-form__files button{margin:4px}.dsh-qa-form__review>div{border-bottom:1px solid var(--dsw-alias-border-l2);margin-bottom:12px}.dsh-qa-form [role=alert]{color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l2);padding:10px;border-radius:8px}
12
+ @media(max-width:600px){.dsh-qa-form{padding:12px;max-height:80vh}.dsh-qa-form footer button{flex:1 1 auto}.dsh-qa-form nav button{font-size:12px}}
13
+ `;
14
+ //# sourceMappingURL=forms-styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms-styles.js","sourceRoot":"","sources":["../../src/client/forms-styles.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;CAY7B,CAAC"}
@@ -0,0 +1,40 @@
1
+ export class QaFormClientError extends Error {
2
+ code;
3
+ constructor(code, message) {
4
+ super(message);
5
+ this.code = code;
6
+ }
7
+ }
8
+ export function unwrapForm(result) {
9
+ if (!result.ok)
10
+ throw new QaFormClientError("TRANSPORT_UNAVAILABLE", "Связь с сервером прервана. Изменения ещё не подтверждены.");
11
+ if (!result.value.ok)
12
+ throw new QaFormClientError(result.value.error.code, result.value.error.message);
13
+ return result.value.value;
14
+ }
15
+ /** Same protected carrier and route as ordinary QA uploads; no fabricated percentage. */
16
+ export async function uploadQaFormFile(carrier, token, session, uploadId, file, signal) {
17
+ if (!carrier || !token)
18
+ throw new QaFormClientError("INTERACTION_UNAVAILABLE", "Загрузка файлов недоступна.");
19
+ const query = new URLSearchParams({
20
+ sessionId: session,
21
+ formUploadId: uploadId,
22
+ });
23
+ const response = await carrier.post({
24
+ path: `api/qa-chat-upload?${query}`,
25
+ body: file,
26
+ headers: {
27
+ authorization: `Bearer ${token}`,
28
+ "content-type": "application/octet-stream",
29
+ },
30
+ signal,
31
+ });
32
+ const result = JSON.parse(response.body);
33
+ if (response.status !== 200 ||
34
+ typeof result !== "object" ||
35
+ result === null ||
36
+ !("ok" in result) ||
37
+ result.ok !== true)
38
+ throw new QaFormClientError("UPLOAD_FAILED", "Не удалось загрузить файл. Проверьте сохранённое состояние, повторите или уберите загрузку.");
39
+ }
40
+ //# sourceMappingURL=forms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.js","sourceRoot":"","sources":["../../src/client/forms.ts"],"names":[],"mappings":"AA0CA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAE/B,IAAI;IADf,YACW,IAAY,EACrB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;oBAHN,IAAI;IAIf,CAAC;CACF;AACD,MAAM,UAAU,UAAU,CAAI,MAAqC;IACjE,IAAI,CAAC,MAAM,CAAC,EAAE;QACZ,MAAM,IAAI,iBAAiB,CACzB,uBAAuB,EACvB,2DAA2D,CAC5D,CAAC;IACJ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QAClB,MAAM,IAAI,iBAAiB,CACzB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EACvB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAC3B,CAAC;IACJ,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;AAC5B,CAAC;AACD,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAoC,EACpC,KAAa,EACb,OAAe,EACf,QAAgB,EAChB,IAAU,EACV,MAAmB;IAEnB,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK;QACpB,MAAM,IAAI,iBAAiB,CACzB,yBAAyB,EACzB,6BAA6B,CAC9B,CAAC;IACJ,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC;QAChC,SAAS,EAAE,OAAO;QAClB,YAAY,EAAE,QAAQ;KACvB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;QAClC,IAAI,EAAE,sBAAsB,KAAK,EAAE;QACnC,IAAI,EAAE,IAAI;QACV,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,cAAc,EAAE,0BAA0B;SAC3C;QACD,MAAM;KACP,CAAC,CAAC;IACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClD,IACE,QAAQ,CAAC,MAAM,KAAK,GAAG;QACvB,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,KAAK,IAAI;QACf,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,KAAK,IAAI;QAElB,MAAM,IAAI,iBAAiB,CACzB,eAAe,EACf,6FAA6F,CAC9F,CAAC;AACN,CAAC"}
@@ -5,6 +5,7 @@ import { QaNativeAnswerReviewStatus, QA_REVIEW_STYLES, } from "./components/QaAn
5
5
  import { QaConfigController } from "./QaConfigController.js";
6
6
  import { matchesQaRoute, QaRouteController } from "./QaRouteController.js";
7
7
  import { QaAccountsController } from "./QaAccountsController.js";
8
+ import { createQaOidcBrowser } from "./oidc-browser.js";
8
9
  import { createQaAccountSessions } from "./account-sessions.js";
9
10
  import { createQaAccountUpload } from "./account-upload.js";
10
11
  import { createQaAccountConversation } from "./account-conversation.js";
@@ -15,6 +16,8 @@ import { isDelegatedSession } from "./lineage.js";
15
16
  import { QaSurfaceGuard } from "./QaSurfaceGuard.js";
16
17
  import { QaWelcomeNoticeStep } from "./components/QaWelcomeNotice.js";
17
18
  import { QA_OVERLAY_STYLES, QA_ROOT_STYLES } from "./styles.js";
19
+ import { QA_FORM_STYLES } from "./forms-styles.js";
20
+ import { uploadQaFormFile } from "./forms.js";
18
21
  import { qaKioskBasePath, qaKioskMode } from "./kiosk.js";
19
22
  import { QaAuditController } from "./audit/controller.js";
20
23
  import { createQaAuditApi } from "./audit/types.js";
@@ -121,7 +124,9 @@ export async function apply(ctx) {
121
124
  const secureSession = (token, sessionId) => policyRemote.secureSession(token, sessionId);
122
125
  // The stand's live load, asked once per send. Only the Host can say it:
123
126
  // a browser sees its own chats and never the HTTP API's questions.
124
- const queueStatus = () => policyRemote.queueStatus();
127
+ const queueStatus = (token, sessionId) => sessionId === undefined
128
+ ? policyRemote.queueStatus()
129
+ : policyRemote.queueStatus(token ?? "", sessionId);
125
130
  const qaApi = {
126
131
  selectModel: (request) => config.getSnapshot().config?.accounts.enabled
127
132
  ? policyRemote.chatSelectModel(accounts.token() ?? "", request)
@@ -191,6 +196,13 @@ export async function apply(ctx) {
191
196
  answerQuestion: (token, sessionId, requestId, answers) => policyRemote.answerQuestion(token, sessionId, requestId, answers),
192
197
  cancelQuestion: (token, sessionId, requestId) => policyRemote.cancelQuestion(token, sessionId, requestId),
193
198
  };
199
+ const formApi = {
200
+ list: (token, id) => policyRemote.listForms(token, id),
201
+ get: (token, id, form) => policyRemote.getForm(token, id, form),
202
+ mutate: (token, id, command) => policyRemote.mutateForm(token, id, command),
203
+ file: (token, id, form, resource) => policyRemote.readFormAttachment(token, id, form, resource),
204
+ upload: (token, id, upload, file, signal) => uploadQaFormFile(ctx.get("fileUpload"), token, id, upload, file, signal),
205
+ };
194
206
  // Personal skills: the token rides every call, and the Host answers with
195
207
  // the caller's own storage. The section simply does not exist on a page
196
208
  // whose deployment cannot host one.
@@ -215,6 +227,7 @@ export async function apply(ctx) {
215
227
  // "not authenticated" and the browser shows the login card.
216
228
  const accounts = new QaAccountsController({
217
229
  remote: policyRemote,
230
+ oidcBrowser: createQaOidcBrowser(window, () => config.getSnapshot().config),
218
231
  storage: window.localStorage,
219
232
  config: () => config.getSnapshot().config,
220
233
  legacyChatIds: () => {
@@ -401,7 +414,9 @@ export async function apply(ctx) {
401
414
  // The kiosk sheet carries no host-hiding rules: nothing native mounts
402
415
  // beneath the surface in that composition, so there is nothing to hide.
403
416
  style.textContent =
404
- (kiosk ? QA_ROOT_STYLES : QA_OVERLAY_STYLES) + QA_SHARING_STYLES;
417
+ (kiosk ? QA_ROOT_STYLES : QA_OVERLAY_STYLES) +
418
+ QA_SHARING_STYLES +
419
+ QA_FORM_STYLES;
405
420
  document.head.append(style);
406
421
  return () => style.remove();
407
422
  }, "dsh-qa-surface: styles");
@@ -449,6 +464,7 @@ export async function apply(ctx) {
449
464
  skillApi,
450
465
  approvalApi,
451
466
  questionApi,
467
+ formApi,
452
468
  slashApi,
453
469
  accounts,
454
470
  panels,