@arbidocs/blocks 0.5.112 → 0.5.114

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 (179) hide show
  1. package/dist/{ConnectedCallDock-KUF6RX76.cjs → ConnectedCallDock-2KXEQENS.cjs} +26 -26
  2. package/dist/{ConnectedCallDock-KUF6RX76.cjs.map → ConnectedCallDock-2KXEQENS.cjs.map} +1 -1
  3. package/dist/{ConnectedCallRoom-ZKIYB2JG.cjs → ConnectedCallRoom-MU3NPNXF.cjs} +18 -18
  4. package/dist/{ConnectedCallRoom-ZKIYB2JG.cjs.map → ConnectedCallRoom-MU3NPNXF.cjs.map} +1 -1
  5. package/dist/{ConnectedMailInviteCard-P65MQM6J.cjs → ConnectedMailInviteCard-EINB3THA.cjs} +5 -5
  6. package/dist/{ConnectedMailInviteCard-P65MQM6J.cjs.map → ConnectedMailInviteCard-EINB3THA.cjs.map} +1 -1
  7. package/dist/{ConnectedNativeDocxComparison-S4RKDH2A.cjs → ConnectedNativeDocxComparison-VH3I65H6.cjs} +21 -21
  8. package/dist/{ConnectedNativeDocxComparison-S4RKDH2A.cjs.map → ConnectedNativeDocxComparison-VH3I65H6.cjs.map} +1 -1
  9. package/dist/{ConnectedProductionSetDialog-HX4HTQ3Z.cjs → ConnectedProductionSetDialog-4EAY6KAZ.cjs} +8 -8
  10. package/dist/{ConnectedProductionSetDialog-HX4HTQ3Z.cjs.map → ConnectedProductionSetDialog-4EAY6KAZ.cjs.map} +1 -1
  11. package/dist/{ConnectedStreamedWordArtifact-A2A7Z3TT.cjs → ConnectedStreamedWordArtifact-KQSHCA75.cjs} +21 -21
  12. package/dist/{ConnectedStreamedWordArtifact-A2A7Z3TT.cjs.map → ConnectedStreamedWordArtifact-KQSHCA75.cjs.map} +1 -1
  13. package/dist/{DocumentReviewCard-4A7NF474.cjs → DocumentReviewCard-OCPFVMLD.cjs} +22 -22
  14. package/dist/{DocumentReviewCard-4A7NF474.cjs.map → DocumentReviewCard-OCPFVMLD.cjs.map} +1 -1
  15. package/dist/{FilesViewerDialog-PKCBZXDG.cjs → FilesViewerDialog-BAGOEMXW.cjs} +54 -54
  16. package/dist/{FilesViewerDialog-PKCBZXDG.cjs.map → FilesViewerDialog-BAGOEMXW.cjs.map} +1 -1
  17. package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-IMAZICIZ.cjs} +9 -9
  18. package/dist/{WorkspaceTableView-J3C6VH4T.cjs.map → WorkspaceTableView-IMAZICIZ.cjs.map} +1 -1
  19. package/dist/agents/index.cjs +298 -298
  20. package/dist/{ai-OYTFPMXI.cjs → ai-7U4B4CVF.cjs} +27 -27
  21. package/dist/ai-7U4B4CVF.cjs.map +1 -0
  22. package/dist/calls/index.cjs +147 -147
  23. package/dist/chat/index.cjs +29 -29
  24. package/dist/{chunk-37JPFCCU.cjs → chunk-2W5E62EY.cjs} +6 -6
  25. package/dist/{chunk-37JPFCCU.cjs.map → chunk-2W5E62EY.cjs.map} +1 -1
  26. package/dist/{chunk-N6AZYEYL.cjs → chunk-3ODEWSRO.cjs} +4 -4
  27. package/dist/{chunk-N6AZYEYL.cjs.map → chunk-3ODEWSRO.cjs.map} +1 -1
  28. package/dist/{chunk-VDFYMVMP.cjs → chunk-3R6YHJ3G.cjs} +4 -4
  29. package/dist/{chunk-VDFYMVMP.cjs.map → chunk-3R6YHJ3G.cjs.map} +1 -1
  30. package/dist/{chunk-5RCCZYAE.cjs → chunk-3U36VYMD.cjs} +36 -36
  31. package/dist/{chunk-5RCCZYAE.cjs.map → chunk-3U36VYMD.cjs.map} +1 -1
  32. package/dist/{chunk-A4FGU6YC.cjs → chunk-436I7PQL.cjs} +7 -7
  33. package/dist/{chunk-A4FGU6YC.cjs.map → chunk-436I7PQL.cjs.map} +1 -1
  34. package/dist/{chunk-J2RXQVVF.cjs → chunk-4EK7TAP7.cjs} +5 -5
  35. package/dist/{chunk-J2RXQVVF.cjs.map → chunk-4EK7TAP7.cjs.map} +1 -1
  36. package/dist/{chunk-TP5PGWIO.cjs → chunk-4IOYQLKG.cjs} +3 -3
  37. package/dist/{chunk-TP5PGWIO.cjs.map → chunk-4IOYQLKG.cjs.map} +1 -1
  38. package/dist/{chunk-ZQLRWA3Y.cjs → chunk-4NPCDS2X.cjs} +4 -4
  39. package/dist/{chunk-ZQLRWA3Y.cjs.map → chunk-4NPCDS2X.cjs.map} +1 -1
  40. package/dist/{chunk-ZEQEIFZJ.cjs → chunk-57EE6CMW.cjs} +24 -24
  41. package/dist/{chunk-ZEQEIFZJ.cjs.map → chunk-57EE6CMW.cjs.map} +1 -1
  42. package/dist/{chunk-NMT4UZQM.cjs → chunk-57NHXEU2.cjs} +5 -5
  43. package/dist/{chunk-NMT4UZQM.cjs.map → chunk-57NHXEU2.cjs.map} +1 -1
  44. package/dist/{chunk-4QTQS4LS.cjs → chunk-5QUL5BZO.cjs} +5 -5
  45. package/dist/{chunk-4QTQS4LS.cjs.map → chunk-5QUL5BZO.cjs.map} +1 -1
  46. package/dist/{chunk-MUA5PJGX.cjs → chunk-5SKHK3BG.cjs} +4 -4
  47. package/dist/{chunk-MUA5PJGX.cjs.map → chunk-5SKHK3BG.cjs.map} +1 -1
  48. package/dist/{chunk-AFXDLDPU.cjs → chunk-5UYFLFNR.cjs} +4 -4
  49. package/dist/{chunk-AFXDLDPU.cjs.map → chunk-5UYFLFNR.cjs.map} +1 -1
  50. package/dist/{chunk-FJXJ43JO.cjs → chunk-6DCIZA3X.cjs} +101 -101
  51. package/dist/{chunk-FJXJ43JO.cjs.map → chunk-6DCIZA3X.cjs.map} +1 -1
  52. package/dist/{chunk-G5TRBLKF.cjs → chunk-7TEUGFIL.cjs} +4 -4
  53. package/dist/{chunk-G5TRBLKF.cjs.map → chunk-7TEUGFIL.cjs.map} +1 -1
  54. package/dist/{chunk-ZNZGYSVB.cjs → chunk-7X3FS5HQ.cjs} +39 -39
  55. package/dist/{chunk-ZNZGYSVB.cjs.map → chunk-7X3FS5HQ.cjs.map} +1 -1
  56. package/dist/{chunk-DZDARC3V.cjs → chunk-7XT5B2DZ.cjs} +70 -70
  57. package/dist/{chunk-DZDARC3V.cjs.map → chunk-7XT5B2DZ.cjs.map} +1 -1
  58. package/dist/{chunk-5UMKMUB5.cjs → chunk-AHT6DQNI.cjs} +68 -68
  59. package/dist/{chunk-5UMKMUB5.cjs.map → chunk-AHT6DQNI.cjs.map} +1 -1
  60. package/dist/{chunk-SRET7LYT.cjs → chunk-BW5MF464.cjs} +4 -4
  61. package/dist/{chunk-SRET7LYT.cjs.map → chunk-BW5MF464.cjs.map} +1 -1
  62. package/dist/{chunk-NP4EWPIP.cjs → chunk-CJYWHUZR.cjs} +6 -6
  63. package/dist/{chunk-NP4EWPIP.cjs.map → chunk-CJYWHUZR.cjs.map} +1 -1
  64. package/dist/{chunk-NTD7VSHO.cjs → chunk-CMGNRMPA.cjs} +4 -4
  65. package/dist/{chunk-NTD7VSHO.cjs.map → chunk-CMGNRMPA.cjs.map} +1 -1
  66. package/dist/{chunk-Z3VNKPPH.cjs → chunk-E3Y7RI3J.cjs} +4 -4
  67. package/dist/{chunk-Z3VNKPPH.cjs.map → chunk-E3Y7RI3J.cjs.map} +1 -1
  68. package/dist/{chunk-TDO5UWXF.cjs → chunk-E4BLRF2L.cjs} +5 -5
  69. package/dist/{chunk-TDO5UWXF.cjs.map → chunk-E4BLRF2L.cjs.map} +1 -1
  70. package/dist/{chunk-WT7CCCIN.cjs → chunk-GNX3FBBX.cjs} +4 -4
  71. package/dist/{chunk-WT7CCCIN.cjs.map → chunk-GNX3FBBX.cjs.map} +1 -1
  72. package/dist/{chunk-3NEI27QQ.cjs → chunk-GQXPNIRE.cjs} +14 -14
  73. package/dist/{chunk-3NEI27QQ.cjs.map → chunk-GQXPNIRE.cjs.map} +1 -1
  74. package/dist/{chunk-7OPOPYV6.cjs → chunk-H5OLHP2U.cjs} +3 -3
  75. package/dist/{chunk-7OPOPYV6.cjs.map → chunk-H5OLHP2U.cjs.map} +1 -1
  76. package/dist/{chunk-IIWJQEBC.cjs → chunk-H7PHOTX2.cjs} +10 -10
  77. package/dist/{chunk-IIWJQEBC.cjs.map → chunk-H7PHOTX2.cjs.map} +1 -1
  78. package/dist/{chunk-LQHXUSWZ.cjs → chunk-HQDR43JC.cjs} +6 -6
  79. package/dist/{chunk-LQHXUSWZ.cjs.map → chunk-HQDR43JC.cjs.map} +1 -1
  80. package/dist/{chunk-6LQN4BMX.cjs → chunk-IDCD5TEZ.cjs} +5 -5
  81. package/dist/{chunk-6LQN4BMX.cjs.map → chunk-IDCD5TEZ.cjs.map} +1 -1
  82. package/dist/{chunk-6YOZKXV6.cjs → chunk-JR2YSBD5.cjs} +4 -4
  83. package/dist/{chunk-6YOZKXV6.cjs.map → chunk-JR2YSBD5.cjs.map} +1 -1
  84. package/dist/{chunk-3GYOWDNM.cjs → chunk-JSQQV23D.cjs} +5 -5
  85. package/dist/{chunk-3GYOWDNM.cjs.map → chunk-JSQQV23D.cjs.map} +1 -1
  86. package/dist/{chunk-ZFKWCGA5.cjs → chunk-JV5TVUOU.cjs} +4 -4
  87. package/dist/{chunk-ZFKWCGA5.cjs.map → chunk-JV5TVUOU.cjs.map} +1 -1
  88. package/dist/{chunk-TXFZAA3R.cjs → chunk-LFRNBT2I.cjs} +23 -23
  89. package/dist/{chunk-TXFZAA3R.cjs.map → chunk-LFRNBT2I.cjs.map} +1 -1
  90. package/dist/{chunk-R7CJEIA5.cjs → chunk-LYTIQQQ2.cjs} +3 -3
  91. package/dist/{chunk-R7CJEIA5.cjs.map → chunk-LYTIQQQ2.cjs.map} +1 -1
  92. package/dist/{chunk-6UYTG2YG.cjs → chunk-MC4F2URI.cjs} +28 -28
  93. package/dist/{chunk-6UYTG2YG.cjs.map → chunk-MC4F2URI.cjs.map} +1 -1
  94. package/dist/{chunk-NNG34ONS.cjs → chunk-MGQSLMTC.cjs} +78 -78
  95. package/dist/{chunk-NNG34ONS.cjs.map → chunk-MGQSLMTC.cjs.map} +1 -1
  96. package/dist/{chunk-3Q5L7XVI.cjs → chunk-MZ2KZXNU.cjs} +9 -9
  97. package/dist/{chunk-3Q5L7XVI.cjs.map → chunk-MZ2KZXNU.cjs.map} +1 -1
  98. package/dist/{chunk-PJ762EO2.cjs → chunk-NHHEMBXQ.cjs} +24 -24
  99. package/dist/{chunk-PJ762EO2.cjs.map → chunk-NHHEMBXQ.cjs.map} +1 -1
  100. package/dist/{chunk-ENUZ35NR.cjs → chunk-P5AQYC4D.cjs} +4 -4
  101. package/dist/{chunk-ENUZ35NR.cjs.map → chunk-P5AQYC4D.cjs.map} +1 -1
  102. package/dist/{chunk-5I2VUNZR.cjs → chunk-PGJYD67F.cjs} +6 -6
  103. package/dist/{chunk-5I2VUNZR.cjs.map → chunk-PGJYD67F.cjs.map} +1 -1
  104. package/dist/{chunk-BYN7UMC5.cjs → chunk-PL7HUTM3.cjs} +8 -8
  105. package/dist/{chunk-BYN7UMC5.cjs.map → chunk-PL7HUTM3.cjs.map} +1 -1
  106. package/dist/{chunk-NOYQ23I7.cjs → chunk-Q6DQGGP4.cjs} +6 -6
  107. package/dist/{chunk-NOYQ23I7.cjs.map → chunk-Q6DQGGP4.cjs.map} +1 -1
  108. package/dist/{chunk-T7J352JD.cjs → chunk-QMIHLJMH.cjs} +6 -6
  109. package/dist/{chunk-T7J352JD.cjs.map → chunk-QMIHLJMH.cjs.map} +1 -1
  110. package/dist/{chunk-LTEXVRCH.cjs → chunk-SBWIA4PL.cjs} +21 -21
  111. package/dist/{chunk-LTEXVRCH.cjs.map → chunk-SBWIA4PL.cjs.map} +1 -1
  112. package/dist/{chunk-ZH7LDZJX.cjs → chunk-TDN33HSK.cjs} +14 -14
  113. package/dist/{chunk-ZH7LDZJX.cjs.map → chunk-TDN33HSK.cjs.map} +1 -1
  114. package/dist/{chunk-U5T46QCS.cjs → chunk-TKHCIHE2.cjs} +3 -3
  115. package/dist/chunk-TKHCIHE2.cjs.map +1 -0
  116. package/dist/{chunk-WIAWHETB.cjs → chunk-ULPTSXXO.cjs} +4 -4
  117. package/dist/{chunk-WIAWHETB.cjs.map → chunk-ULPTSXXO.cjs.map} +1 -1
  118. package/dist/{chunk-GTWEWDIZ.cjs → chunk-UNDQYTRF.cjs} +8 -8
  119. package/dist/{chunk-GTWEWDIZ.cjs.map → chunk-UNDQYTRF.cjs.map} +1 -1
  120. package/dist/{chunk-OKHKJ5ML.cjs → chunk-UUENH4BJ.cjs} +11 -11
  121. package/dist/{chunk-OKHKJ5ML.cjs.map → chunk-UUENH4BJ.cjs.map} +1 -1
  122. package/dist/{chunk-K5MYEWD5.cjs → chunk-UZHWXKS6.cjs} +7 -7
  123. package/dist/{chunk-K5MYEWD5.cjs.map → chunk-UZHWXKS6.cjs.map} +1 -1
  124. package/dist/{chunk-QVHP4R7T.cjs → chunk-V5IMYLYK.cjs} +29 -29
  125. package/dist/{chunk-QVHP4R7T.cjs.map → chunk-V5IMYLYK.cjs.map} +1 -1
  126. package/dist/{chunk-XW524KUX.cjs → chunk-VJCSEMXT.cjs} +4 -4
  127. package/dist/{chunk-XW524KUX.cjs.map → chunk-VJCSEMXT.cjs.map} +1 -1
  128. package/dist/{chunk-B5442TKX.cjs → chunk-VRK3IQAP.cjs} +4 -4
  129. package/dist/{chunk-B5442TKX.cjs.map → chunk-VRK3IQAP.cjs.map} +1 -1
  130. package/dist/{chunk-MYRKL3JO.cjs → chunk-VWTOIGX4.cjs} +4 -4
  131. package/dist/{chunk-MYRKL3JO.cjs.map → chunk-VWTOIGX4.cjs.map} +1 -1
  132. package/dist/{chunk-Q7DB5S7N.cjs → chunk-WW6LXQY6.cjs} +12 -12
  133. package/dist/{chunk-Q7DB5S7N.cjs.map → chunk-WW6LXQY6.cjs.map} +1 -1
  134. package/dist/{chunk-NJCK6V6U.cjs → chunk-XKDUPU7B.cjs} +4 -4
  135. package/dist/{chunk-NJCK6V6U.cjs.map → chunk-XKDUPU7B.cjs.map} +1 -1
  136. package/dist/{chunk-YAPXIANR.cjs → chunk-YVCOQHCE.cjs} +5 -5
  137. package/dist/{chunk-YAPXIANR.cjs.map → chunk-YVCOQHCE.cjs.map} +1 -1
  138. package/dist/{chunk-TOM2P3MA.cjs → chunk-ZZA756I4.cjs} +4 -4
  139. package/dist/{chunk-TOM2P3MA.cjs.map → chunk-ZZA756I4.cjs.map} +1 -1
  140. package/dist/citations/index.cjs +8 -8
  141. package/dist/connect/docx.cjs +24 -24
  142. package/dist/connect/index.cjs +1489 -1433
  143. package/dist/connect/index.cjs.map +1 -1
  144. package/dist/connect/viewer.cjs +40 -40
  145. package/dist/connection/ConnectedWorkflowBuilder.d.ts +11 -0
  146. package/dist/connection/ConnectedWorkflowBuilder.js +42 -3
  147. package/dist/connection/ConnectedWorkflowBuilder.js.map +2 -2
  148. package/dist/connection/conversation/ConnectedConversationPage.js +36 -2
  149. package/dist/connection/conversation/ConnectedConversationPage.js.map +2 -2
  150. package/dist/connection/report-problem/ReportProblemDialog.d.ts +2 -2
  151. package/dist/connection/report-problem/ReportProblemDialog.js +51 -19
  152. package/dist/connection/report-problem/ReportProblemDialog.js.map +2 -2
  153. package/dist/connection/workflows/ConnectedWorkflowsPage.js +10 -3
  154. package/dist/connection/workflows/ConnectedWorkflowsPage.js.map +2 -2
  155. package/dist/connection/workflows/useWorkflowsPageState.d.ts +1 -0
  156. package/dist/connection/workflows/useWorkflowsPageState.js.map +2 -2
  157. package/dist/dashboards/index.cjs +23 -23
  158. package/dist/embed/index.cjs +49 -49
  159. package/dist/facts/index.cjs +45 -45
  160. package/dist/files/index.cjs +225 -225
  161. package/dist/home/index.cjs +32 -32
  162. package/dist/index.cjs +1750 -1750
  163. package/dist/provider/environment.d.ts +5 -0
  164. package/dist/provider/environment.js +1 -1
  165. package/dist/provider/environment.js.map +2 -2
  166. package/dist/provider/requests.d.ts +2 -0
  167. package/dist/provider/requests.js.map +2 -2
  168. package/dist/retrieval/index.cjs +4 -4
  169. package/dist/settings/index.cjs +148 -148
  170. package/dist/shell/index.cjs +91 -91
  171. package/dist/site/index.cjs +5 -5
  172. package/dist/studio/index.cjs +43 -43
  173. package/dist/workflow-canvas/index.cjs +114 -72
  174. package/dist/workflow-canvas/index.cjs.map +1 -1
  175. package/dist/workspaces/index.cjs +18 -18
  176. package/node_modules/@arbidocs/coedit/package.json +1 -1
  177. package/package.json +5 -5
  178. package/dist/ai-OYTFPMXI.cjs.map +0 -1
  179. package/dist/chunk-U5T46QCS.cjs.map +0 -1
@@ -37,6 +37,7 @@ function ReportProblemDialog({
37
37
  const [natural, setNatural] = useState(null);
38
38
  const [frameSize, setFrameSize] = useState(null);
39
39
  const [cropArea, setCropArea] = useState(null);
40
+ const [cropping, setCropping] = useState(false);
40
41
  const [busy, setBusy] = useState(false);
41
42
  const [failure, setFailure] = useState(null);
42
43
  const [ticketReference, setTicketReference] = useState(null);
@@ -44,28 +45,33 @@ function ReportProblemDialog({
44
45
  const [submissionId] = useState(() => crypto.randomUUID());
45
46
  const imgRef = useRef(null);
46
47
  const dragStart = useRef(null);
47
- const frameUrl = useMemo(() => frame ? URL.createObjectURL(frame) : null, [frame]);
48
- useEffect(() => () => void (frameUrl && URL.revokeObjectURL(frameUrl)), [frameUrl]);
49
- const imageUrl = useMemo(() => image ? URL.createObjectURL(image) : null, [image]);
48
+ const screenshot = image ?? frame;
49
+ const imageUrl = useMemo(
50
+ () => screenshot ? URL.createObjectURL(screenshot) : null,
51
+ [screenshot]
52
+ );
50
53
  useEffect(() => () => void (imageUrl && URL.revokeObjectURL(imageUrl)), [imageUrl]);
51
54
  useEffect(() => {
52
55
  setFrameSize(null);
53
- if (!frameUrl) return;
56
+ if (!imageUrl) return;
54
57
  const img = new Image();
55
58
  img.onload = () => setFrameSize({ width: img.naturalWidth, height: img.naturalHeight });
56
- img.src = frameUrl;
57
- }, [frameUrl]);
59
+ img.src = imageUrl;
60
+ }, [imageUrl]);
58
61
  useEffect(() => {
59
62
  setMarks([]);
60
63
  setDraft(null);
61
64
  setNatural(null);
62
- }, [image]);
65
+ setCropping(false);
66
+ setCropArea(null);
67
+ }, [screenshot]);
63
68
  const applyCrop = async () => {
64
- if (!frameUrl || !cropArea) return;
69
+ if (!imageUrl || !cropArea) return;
65
70
  setBusy(true);
66
71
  try {
67
- const { blob } = await cropImage(frameUrl, cropArea, { mimeType: "image/png" });
72
+ const { blob } = await cropImage(imageUrl, cropArea, { mimeType: "image/png" });
68
73
  onCropped(blob);
74
+ setCropping(false);
69
75
  } catch {
70
76
  notify("Couldn't crop the screenshot. Please try again.", "error");
71
77
  } finally {
@@ -82,8 +88,8 @@ function ReportProblemDialog({
82
88
  );
83
89
  };
84
90
  const renderImage = async () => {
85
- if (!image || !natural) return null;
86
- const bitmap = await createImageBitmap(image);
91
+ if (!screenshot || !natural) return null;
92
+ const bitmap = await createImageBitmap(screenshot);
87
93
  try {
88
94
  return await renderAnnotatedScreenshot(bitmap, marks, { happened: description, expected: "" });
89
95
  } finally {
@@ -95,8 +101,8 @@ function ReportProblemDialog({
95
101
  setBusy(true);
96
102
  setFailure(null);
97
103
  try {
98
- const rendered = image ? await renderImage() : null;
99
- if (image && !rendered) throw new Error("The screenshot is not ready. Please try again.");
104
+ const rendered = screenshot ? await renderImage() : null;
105
+ if (screenshot && !rendered) throw new Error("The screenshot is not ready. Please try again.");
100
106
  const receipt = await onSubmit({
101
107
  description: description.trim(),
102
108
  image: rendered ?? void 0,
@@ -121,16 +127,15 @@ function ReportProblemDialog({
121
127
  width: `${mark.w / natural.width * 100}%`,
122
128
  height: `${mark.h / natural.height * 100}%`
123
129
  } : void 0;
124
- const cropping = !!frameUrl;
125
130
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => !next && !busy && onClose(), children: /* @__PURE__ */ jsxs(
126
131
  DialogContent,
127
132
  {
128
- className: `flex max-h-[92vh] w-[96vw] flex-col gap-3 p-4 ${ticketId === null && (cropping || image) ? "max-w-[96vw] sm:max-w-[min(96vw,64rem)]" : "max-w-lg sm:max-w-lg"}`,
133
+ className: `flex max-h-[92vh] w-[96vw] flex-col gap-3 p-4 ${ticketId === null && screenshot ? "max-w-[96vw] sm:max-w-[min(96vw,64rem)]" : "max-w-lg sm:max-w-lg"}`,
129
134
  "data-testid": "report-problem-dialog",
130
135
  children: [
131
136
  /* @__PURE__ */ jsxs("div", { className: "pr-8", children: [
132
137
  /* @__PURE__ */ jsx(DialogTitle, { children: ticketId === null ? "Contact support" : "Support request sent" }),
133
- /* @__PURE__ */ jsx(DialogDescription, { children: ticketId !== null ? "We have received your request. Track updates in My requests." : cropping ? "Crop the screenshot to the part that shows the problem. Only the cropped part is kept." : image ? "Black out anything confidential before sending. Blacked-out areas are removed from the image." : "Tell us what you need help with. You can choose to add a screenshot." })
138
+ /* @__PURE__ */ jsx(DialogDescription, { children: ticketId !== null ? "We have received your request. Track updates in My requests." : cropping ? "Crop the screenshot to the part that shows the problem. Only the cropped part is kept." : screenshot ? "Black out anything confidential before sending. Blacked-out areas are removed from the image." : "Tell us what you need help with. You can choose to add a screenshot." })
134
139
  ] }),
135
140
  ticketId !== null && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4 rounded-md border border-border bg-muted p-4", children: [
136
141
  /* @__PURE__ */ jsxs("p", { className: "font-medium", "data-testid": "report-ticket-receipt", children: [
@@ -139,11 +144,11 @@ function ReportProblemDialog({
139
144
  ] }),
140
145
  /* @__PURE__ */ jsx(Button, { onClick: onClose, "data-testid": "report-receipt-close", children: "Close" })
141
146
  ] }),
142
- cropping ? /* @__PURE__ */ jsxs("div", { className: "grid gap-2", hidden: ticketId !== null, children: [
147
+ cropping && imageUrl ? /* @__PURE__ */ jsxs("div", { className: "grid gap-2", hidden: ticketId !== null, children: [
143
148
  /* @__PURE__ */ jsx(
144
149
  ImageCropper,
145
150
  {
146
- image: frameUrl,
151
+ image: imageUrl,
147
152
  aspect: frameSize ? frameSize.width / frameSize.height : window.innerWidth / window.innerHeight,
148
153
  maxZoom: 6,
149
154
  cropAreaClassName: "h-[50vh] min-h-64",
@@ -152,6 +157,15 @@ function ReportProblemDialog({
152
157
  frameSize ? "sized" : "unsized"
153
158
  ),
154
159
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap justify-end gap-2", children: [
160
+ /* @__PURE__ */ jsx(
161
+ Button,
162
+ {
163
+ variant: "ghost",
164
+ onClick: () => setCropping(false),
165
+ "data-testid": "report-cancel-crop",
166
+ children: "Cancel crop"
167
+ }
168
+ ),
155
169
  /* @__PURE__ */ jsxs(
156
170
  Button,
157
171
  {
@@ -240,6 +254,24 @@ function ReportProblemDialog({
240
254
  /* @__PURE__ */ jsx(EyeOff, { className: "size-4" }),
241
255
  " Drag over anything confidential to black it out."
242
256
  ] }),
257
+ /* @__PURE__ */ jsxs(
258
+ Button,
259
+ {
260
+ size: "sm",
261
+ variant: "ghost",
262
+ disabled: !!marks.length,
263
+ title: marks.length ? "Undo blacked-out areas before cropping" : void 0,
264
+ onClick: () => {
265
+ setCropArea(null);
266
+ setCropping(true);
267
+ },
268
+ "data-testid": "report-crop",
269
+ children: [
270
+ /* @__PURE__ */ jsx(Crop, { className: "mr-1 size-4" }),
271
+ " Crop"
272
+ ]
273
+ }
274
+ ),
243
275
  /* @__PURE__ */ jsxs(
244
276
  Button,
245
277
  {
@@ -322,7 +354,7 @@ function ReportProblemDialog({
322
354
  /* @__PURE__ */ jsx(
323
355
  Button,
324
356
  {
325
- disabled: !onSubmit || !description.trim() || busy || cropping || !!image && !natural,
357
+ disabled: !onSubmit || !description.trim() || busy || cropping || !!screenshot && !natural,
326
358
  onClick: () => void submit(),
327
359
  "data-testid": "report-send",
328
360
  children: busy ? "Sending\u2026" : "Send to support"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connection/report-problem/ReportProblemDialog.tsx"],
4
- "sourcesContent": ["/** Support form with optional, explicitly chosen and redacted screenshot evidence. */\nimport React, { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport { Camera, Crop, EyeOff, ImageUp, Trash2, Undo2 } from 'lucide-react'\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n Textarea,\n} from '@arbidocs/react/ui'\nimport { ImageCropper, cropImage, type CropArea } from '@arbidocs/react'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { canCaptureScreen } from './screen-capture'\nimport {\n isMeaningfulRect,\n rectFromDrag,\n renderAnnotatedScreenshot,\n toImagePoint,\n type Mark,\n} from './screenshot-annotations'\n\nexport interface ReportProblemOptions {\n /** @deprecated No image download is created. Retained for source compatibility. */\n fileNamePrefix?: string\n onSubmit?: (report: {\n description: string\n image?: Blob\n idempotencyKey: string\n }) => Promise<{ ticket_id: number; reference?: string }>\n /** A line beside the actions: where reports go (the site's own words). Default: none. */\n footnote?: ReactNode\n}\n\nexport interface ReportProblemDialogProps extends ReportProblemOptions {\n open: boolean\n /** The full captured frame, to crop. Dropped once a crop is chosen. */\n frame: Blob | null\n /** The kept screenshot (the crop, or a picked file). */\n image: Blob | null\n onCropped: (crop: Blob) => void\n onImageChange: (image: Blob | null) => void\n onRetake: () => void\n onClose: () => void\n}\n\nexport function ReportProblemDialog({\n open,\n frame,\n image,\n onCropped,\n onImageChange,\n onRetake,\n onClose,\n onSubmit,\n footnote,\n}: ReportProblemDialogProps): React.ReactElement {\n const { notify } = useBlocksEnvironment()\n const [description, setDescription] = useState('')\n const [marks, setMarks] = useState<Mark[]>([])\n const [draft, setDraft] = useState<Mark | null>(null)\n const [natural, setNatural] = useState<{ width: number; height: number } | null>(null)\n const [frameSize, setFrameSize] = useState<{ width: number; height: number } | null>(null)\n const [cropArea, setCropArea] = useState<CropArea | null>(null)\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | null>(null)\n const [ticketReference, setTicketReference] = useState<string | null>(null)\n const [ticketId, setTicketId] = useState<number | null>(null)\n const [submissionId] = useState(() => crypto.randomUUID())\n const imgRef = useRef<HTMLImageElement>(null)\n const dragStart = useRef<{ x: number; y: number } | null>(null)\n\n const frameUrl = useMemo(() => (frame ? URL.createObjectURL(frame) : null), [frame])\n useEffect(() => () => void (frameUrl && URL.revokeObjectURL(frameUrl)), [frameUrl])\n const imageUrl = useMemo(() => (image ? URL.createObjectURL(image) : null), [image])\n useEffect(() => () => void (imageUrl && URL.revokeObjectURL(imageUrl)), [imageUrl])\n\n // The frame's size picks the \"Screen\" crop shape.\n useEffect(() => {\n setFrameSize(null)\n if (!frameUrl) return\n const img = new Image()\n img.onload = () => setFrameSize({ width: img.naturalWidth, height: img.naturalHeight })\n img.src = frameUrl\n }, [frameUrl])\n\n // A new screenshot starts new marks; closing starts a new report.\n useEffect(() => {\n setMarks([])\n setDraft(null)\n setNatural(null)\n }, [image])\n\n const applyCrop = async () => {\n if (!frameUrl || !cropArea) return\n setBusy(true)\n try {\n const { blob } = await cropImage(frameUrl, cropArea, { mimeType: 'image/png' })\n onCropped(blob)\n } catch {\n notify(\"Couldn't crop the screenshot. Please try again.\", 'error')\n } finally {\n setBusy(false)\n }\n }\n\n const pointFrom = (event: React.PointerEvent) => {\n const img = imgRef.current\n if (!img || !natural) return null\n return toImagePoint(\n { x: event.clientX, y: event.clientY },\n img.getBoundingClientRect(),\n natural\n )\n }\n\n const renderImage = async (): Promise<Blob | null> => {\n if (!image || !natural) return null\n const bitmap = await createImageBitmap(image)\n try {\n return await renderAnnotatedScreenshot(bitmap, marks, { happened: description, expected: '' })\n } finally {\n bitmap.close()\n }\n }\n\n const submit = async () => {\n if (!onSubmit || !description.trim()) return\n setBusy(true)\n setFailure(null)\n try {\n const rendered = image ? await renderImage() : null\n if (image && !rendered) throw new Error('The screenshot is not ready. Please try again.')\n const receipt = await onSubmit({\n description: description.trim(),\n image: rendered ?? undefined,\n idempotencyKey: submissionId,\n })\n setTicketId(receipt.ticket_id)\n setTicketReference(\n receipt.reference &&\n /^[a-z0-9-]+-[0-9]+$/.test(receipt.reference) &&\n receipt.reference.endsWith(`-${receipt.ticket_id}`)\n ? receipt.reference\n : null\n )\n } catch (error) {\n setFailure(\n error instanceof Error ? error.message : 'Could not send your request. Please try again.'\n )\n } finally {\n setBusy(false)\n }\n }\n\n const shown = draft ? [...marks, draft] : marks\n const percent = (mark: Mark) =>\n natural\n ? {\n left: `${(mark.x / natural.width) * 100}%`,\n top: `${(mark.y / natural.height) * 100}%`,\n width: `${(mark.w / natural.width) * 100}%`,\n height: `${(mark.h / natural.height) * 100}%`,\n }\n : undefined\n const cropping = !!frameUrl\n\n return (\n <Dialog open={open} onOpenChange={(next) => !next && !busy && onClose()}>\n <DialogContent\n className={`flex max-h-[92vh] w-[96vw] flex-col gap-3 p-4 ${ticketId === null && (cropping || image) ? 'max-w-[96vw] sm:max-w-[min(96vw,64rem)]' : 'max-w-lg sm:max-w-lg'}`}\n data-testid=\"report-problem-dialog\"\n >\n <div className=\"pr-8\">\n <DialogTitle>\n {ticketId === null ? 'Contact support' : 'Support request sent'}\n </DialogTitle>\n <DialogDescription>\n {ticketId !== null\n ? 'We have received your request. Track updates in My requests.'\n : cropping\n ? 'Crop the screenshot to the part that shows the problem. Only the cropped part is kept.'\n : image\n ? 'Black out anything confidential before sending. Blacked-out areas are removed from the image.'\n : 'Tell us what you need help with. You can choose to add a screenshot.'}\n </DialogDescription>\n </div>\n\n {ticketId !== null && (\n <div className=\"flex items-center justify-between gap-4 rounded-md border border-border bg-muted p-4\">\n <p className=\"font-medium\" data-testid=\"report-ticket-receipt\">\n Ticket number: {ticketReference ?? `#${ticketId}`}\n </p>\n <Button onClick={onClose} data-testid=\"report-receipt-close\">\n Close\n </Button>\n </div>\n )}\n\n {cropping ? (\n <div className=\"grid gap-2\" hidden={ticketId !== null}>\n <ImageCropper\n key={frameSize ? 'sized' : 'unsized'}\n image={frameUrl}\n aspect={\n frameSize\n ? frameSize.width / frameSize.height\n : window.innerWidth / window.innerHeight\n }\n maxZoom={6}\n cropAreaClassName=\"h-[50vh] min-h-64\"\n onCropComplete={(area) => setCropArea(area)}\n />\n <div className=\"flex flex-wrap justify-end gap-2\">\n <Button\n variant=\"ghost\"\n onClick={() => onImageChange(null)}\n data-testid=\"report-remove-screenshot\"\n >\n <Trash2 className=\"mr-1 size-4\" /> Remove screenshot\n </Button>\n <Button variant=\"ghost\" onClick={onRetake} data-testid=\"report-retake\">\n <Camera className=\"mr-1 size-4\" /> Retake\n </Button>\n <Button\n disabled={!cropArea || busy}\n onClick={() => void applyCrop()}\n data-testid=\"report-use-crop\"\n >\n <Crop className=\"mr-1 size-4\" /> Use this crop\n </Button>\n </div>\n </div>\n ) : imageUrl ? (\n <div className=\"grid gap-2\" hidden={ticketId !== null}>\n <div className=\"flex min-h-0 justify-center overflow-hidden rounded-md bg-muted p-2\">\n <div className=\"relative max-w-full\">\n <img\n ref={imgRef}\n src={imageUrl}\n alt=\"Screenshot of the problem\"\n className=\"block max-h-[45vh] max-w-full select-none object-contain\"\n draggable={false}\n onLoad={(event) =>\n setNatural({\n width: event.currentTarget.naturalWidth,\n height: event.currentTarget.naturalHeight,\n })\n }\n data-testid=\"report-screenshot\"\n />\n <div\n className=\"absolute inset-0 cursor-crosshair touch-none\"\n onPointerDown={(event) => {\n const point = pointFrom(event)\n if (!point) return\n event.currentTarget.setPointerCapture?.(event.pointerId)\n dragStart.current = point\n setDraft({ kind: 'redact', ...point, w: 0, h: 0 })\n }}\n onPointerMove={(event) => {\n const point = pointFrom(event)\n if (dragStart.current && point && natural)\n setDraft({\n kind: 'redact',\n ...rectFromDrag(dragStart.current, point, natural),\n })\n }}\n onPointerUp={() => {\n if (draft && isMeaningfulRect(draft)) setMarks((m) => [...m, draft])\n dragStart.current = null\n setDraft(null)\n }}\n data-testid=\"report-draw-surface\"\n >\n {shown.map((mark, i) => (\n <div\n key={i}\n className=\"pointer-events-none absolute bg-black\"\n style={percent(mark)}\n data-testid=\"report-mark-redact\"\n />\n ))}\n </div>\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-end gap-2 text-sm\">\n <span className=\"mr-auto flex items-center gap-1 text-muted-foreground\">\n <EyeOff className=\"size-4\" /> Drag over anything confidential to black it out.\n </span>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={!marks.length}\n onClick={() => setMarks((m) => m.slice(0, -1))}\n data-testid=\"report-undo\"\n >\n <Undo2 className=\"mr-1 size-4\" /> Undo\n </Button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => onImageChange(null)}\n data-testid=\"report-remove-screenshot\"\n >\n <Trash2 className=\"mr-1 size-4\" /> Remove\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={onRetake} data-testid=\"report-retake\">\n <Camera className=\"mr-1 size-4\" /> Retake\n </Button>\n </div>\n </div>\n ) : (\n <div\n className=\"flex flex-wrap items-center gap-3 rounded-md border border-dashed border-border p-3 text-sm\"\n hidden={ticketId !== null}\n >\n <span className=\"text-muted-foreground\">No screenshot attached.</span>\n {canCaptureScreen() ? (\n <Button size=\"sm\" variant=\"outline\" onClick={onRetake} data-testid=\"report-retake\">\n <Camera className=\"mr-1 size-4\" /> Take a screenshot\n </Button>\n ) : (\n <label className=\"inline-flex cursor-pointer items-center gap-1 font-medium text-primary\">\n <ImageUp className=\"size-4\" /> Choose a screenshot\n <input\n type=\"file\"\n accept=\"image/*\"\n className=\"sr-only\"\n onChange={(event) => {\n const file = event.target.files?.[0]\n if (file) onImageChange(file)\n }}\n data-testid=\"report-choose-image\"\n />\n </label>\n )}\n </div>\n )}\n\n <label className=\"grid gap-1 text-sm\" hidden={ticketId !== null}>\n <span className=\"font-medium\">What went wrong?</span>\n <Textarea\n value={description}\n onChange={(event) => setDescription(event.target.value)}\n rows={3}\n placeholder=\"What did you do, and what happened instead?\"\n data-testid=\"report-description\"\n />\n </label>\n\n {failure && (\n <p role=\"alert\" className=\"text-sm text-destructive\" hidden={ticketId !== null}>\n {failure}\n </p>\n )}\n <div className=\"flex flex-wrap items-center justify-end gap-2\" hidden={ticketId !== null}>\n <span className=\"mr-auto text-xs text-muted-foreground\">{footnote}</span>\n <Button variant=\"ghost\" onClick={onClose} disabled={busy}>\n Cancel\n </Button>\n <Button\n disabled={!onSubmit || !description.trim() || busy || cropping || (!!image && !natural)}\n onClick={() => void submit()}\n data-testid=\"report-send\"\n >\n {busy ? 'Sending\u2026' : 'Send to support'}\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/** Support form with optional screenshot evidence and redaction. */\nimport React, { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport { Camera, Crop, EyeOff, ImageUp, Trash2, Undo2 } from 'lucide-react'\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n Textarea,\n} from '@arbidocs/react/ui'\nimport { ImageCropper, cropImage, type CropArea } from '@arbidocs/react'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { canCaptureScreen } from './screen-capture'\nimport {\n isMeaningfulRect,\n rectFromDrag,\n renderAnnotatedScreenshot,\n toImagePoint,\n type Mark,\n} from './screenshot-annotations'\n\nexport interface ReportProblemOptions {\n /** @deprecated No image download is created. Retained for source compatibility. */\n fileNamePrefix?: string\n onSubmit?: (report: {\n description: string\n image?: Blob\n idempotencyKey: string\n }) => Promise<{ ticket_id: number; reference?: string }>\n /** A line beside the actions: where reports go (the site's own words). Default: none. */\n footnote?: ReactNode\n}\n\nexport interface ReportProblemDialogProps extends ReportProblemOptions {\n open: boolean\n /** The captured frame. Dropped once a crop is chosen. */\n frame: Blob | null\n /** The kept screenshot (the crop, or a picked file). */\n image: Blob | null\n onCropped: (crop: Blob) => void\n onImageChange: (image: Blob | null) => void\n onRetake: () => void\n onClose: () => void\n}\n\nexport function ReportProblemDialog({\n open,\n frame,\n image,\n onCropped,\n onImageChange,\n onRetake,\n onClose,\n onSubmit,\n footnote,\n}: ReportProblemDialogProps): React.ReactElement {\n const { notify } = useBlocksEnvironment()\n const [description, setDescription] = useState('')\n const [marks, setMarks] = useState<Mark[]>([])\n const [draft, setDraft] = useState<Mark | null>(null)\n const [natural, setNatural] = useState<{ width: number; height: number } | null>(null)\n const [frameSize, setFrameSize] = useState<{ width: number; height: number } | null>(null)\n const [cropArea, setCropArea] = useState<CropArea | null>(null)\n const [cropping, setCropping] = useState(false)\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | null>(null)\n const [ticketReference, setTicketReference] = useState<string | null>(null)\n const [ticketId, setTicketId] = useState<number | null>(null)\n const [submissionId] = useState(() => crypto.randomUUID())\n const imgRef = useRef<HTMLImageElement>(null)\n const dragStart = useRef<{ x: number; y: number } | null>(null)\n\n const screenshot = image ?? frame\n const imageUrl = useMemo(\n () => (screenshot ? URL.createObjectURL(screenshot) : null),\n [screenshot]\n )\n useEffect(() => () => void (imageUrl && URL.revokeObjectURL(imageUrl)), [imageUrl])\n\n // The frame's size picks the \"Screen\" crop shape.\n useEffect(() => {\n setFrameSize(null)\n if (!imageUrl) return\n const img = new Image()\n img.onload = () => setFrameSize({ width: img.naturalWidth, height: img.naturalHeight })\n img.src = imageUrl\n }, [imageUrl])\n\n // A new screenshot starts new marks; closing starts a new report.\n useEffect(() => {\n setMarks([])\n setDraft(null)\n setNatural(null)\n setCropping(false)\n setCropArea(null)\n }, [screenshot])\n\n const applyCrop = async () => {\n if (!imageUrl || !cropArea) return\n setBusy(true)\n try {\n const { blob } = await cropImage(imageUrl, cropArea, { mimeType: 'image/png' })\n onCropped(blob)\n setCropping(false)\n } catch {\n notify(\"Couldn't crop the screenshot. Please try again.\", 'error')\n } finally {\n setBusy(false)\n }\n }\n\n const pointFrom = (event: React.PointerEvent) => {\n const img = imgRef.current\n if (!img || !natural) return null\n return toImagePoint(\n { x: event.clientX, y: event.clientY },\n img.getBoundingClientRect(),\n natural\n )\n }\n\n const renderImage = async (): Promise<Blob | null> => {\n if (!screenshot || !natural) return null\n const bitmap = await createImageBitmap(screenshot)\n try {\n return await renderAnnotatedScreenshot(bitmap, marks, { happened: description, expected: '' })\n } finally {\n bitmap.close()\n }\n }\n\n const submit = async () => {\n if (!onSubmit || !description.trim()) return\n setBusy(true)\n setFailure(null)\n try {\n const rendered = screenshot ? await renderImage() : null\n if (screenshot && !rendered) throw new Error('The screenshot is not ready. Please try again.')\n const receipt = await onSubmit({\n description: description.trim(),\n image: rendered ?? undefined,\n idempotencyKey: submissionId,\n })\n setTicketId(receipt.ticket_id)\n setTicketReference(\n receipt.reference &&\n /^[a-z0-9-]+-[0-9]+$/.test(receipt.reference) &&\n receipt.reference.endsWith(`-${receipt.ticket_id}`)\n ? receipt.reference\n : null\n )\n } catch (error) {\n setFailure(\n error instanceof Error ? error.message : 'Could not send your request. Please try again.'\n )\n } finally {\n setBusy(false)\n }\n }\n\n const shown = draft ? [...marks, draft] : marks\n const percent = (mark: Mark) =>\n natural\n ? {\n left: `${(mark.x / natural.width) * 100}%`,\n top: `${(mark.y / natural.height) * 100}%`,\n width: `${(mark.w / natural.width) * 100}%`,\n height: `${(mark.h / natural.height) * 100}%`,\n }\n : undefined\n\n return (\n <Dialog open={open} onOpenChange={(next) => !next && !busy && onClose()}>\n <DialogContent\n className={`flex max-h-[92vh] w-[96vw] flex-col gap-3 p-4 ${ticketId === null && screenshot ? 'max-w-[96vw] sm:max-w-[min(96vw,64rem)]' : 'max-w-lg sm:max-w-lg'}`}\n data-testid=\"report-problem-dialog\"\n >\n <div className=\"pr-8\">\n <DialogTitle>\n {ticketId === null ? 'Contact support' : 'Support request sent'}\n </DialogTitle>\n <DialogDescription>\n {ticketId !== null\n ? 'We have received your request. Track updates in My requests.'\n : cropping\n ? 'Crop the screenshot to the part that shows the problem. Only the cropped part is kept.'\n : screenshot\n ? 'Black out anything confidential before sending. Blacked-out areas are removed from the image.'\n : 'Tell us what you need help with. You can choose to add a screenshot.'}\n </DialogDescription>\n </div>\n\n {ticketId !== null && (\n <div className=\"flex items-center justify-between gap-4 rounded-md border border-border bg-muted p-4\">\n <p className=\"font-medium\" data-testid=\"report-ticket-receipt\">\n Ticket number: {ticketReference ?? `#${ticketId}`}\n </p>\n <Button onClick={onClose} data-testid=\"report-receipt-close\">\n Close\n </Button>\n </div>\n )}\n\n {cropping && imageUrl ? (\n <div className=\"grid gap-2\" hidden={ticketId !== null}>\n <ImageCropper\n key={frameSize ? 'sized' : 'unsized'}\n image={imageUrl}\n aspect={\n frameSize\n ? frameSize.width / frameSize.height\n : window.innerWidth / window.innerHeight\n }\n maxZoom={6}\n cropAreaClassName=\"h-[50vh] min-h-64\"\n onCropComplete={(area) => setCropArea(area)}\n />\n <div className=\"flex flex-wrap justify-end gap-2\">\n <Button\n variant=\"ghost\"\n onClick={() => setCropping(false)}\n data-testid=\"report-cancel-crop\"\n >\n Cancel crop\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => onImageChange(null)}\n data-testid=\"report-remove-screenshot\"\n >\n <Trash2 className=\"mr-1 size-4\" /> Remove screenshot\n </Button>\n <Button variant=\"ghost\" onClick={onRetake} data-testid=\"report-retake\">\n <Camera className=\"mr-1 size-4\" /> Retake\n </Button>\n <Button\n disabled={!cropArea || busy}\n onClick={() => void applyCrop()}\n data-testid=\"report-use-crop\"\n >\n <Crop className=\"mr-1 size-4\" /> Use this crop\n </Button>\n </div>\n </div>\n ) : imageUrl ? (\n <div className=\"grid gap-2\" hidden={ticketId !== null}>\n <div className=\"flex min-h-0 justify-center overflow-hidden rounded-md bg-muted p-2\">\n <div className=\"relative max-w-full\">\n <img\n ref={imgRef}\n src={imageUrl}\n alt=\"Screenshot of the problem\"\n className=\"block max-h-[45vh] max-w-full select-none object-contain\"\n draggable={false}\n onLoad={(event) =>\n setNatural({\n width: event.currentTarget.naturalWidth,\n height: event.currentTarget.naturalHeight,\n })\n }\n data-testid=\"report-screenshot\"\n />\n <div\n className=\"absolute inset-0 cursor-crosshair touch-none\"\n onPointerDown={(event) => {\n const point = pointFrom(event)\n if (!point) return\n event.currentTarget.setPointerCapture?.(event.pointerId)\n dragStart.current = point\n setDraft({ kind: 'redact', ...point, w: 0, h: 0 })\n }}\n onPointerMove={(event) => {\n const point = pointFrom(event)\n if (dragStart.current && point && natural)\n setDraft({\n kind: 'redact',\n ...rectFromDrag(dragStart.current, point, natural),\n })\n }}\n onPointerUp={() => {\n if (draft && isMeaningfulRect(draft)) setMarks((m) => [...m, draft])\n dragStart.current = null\n setDraft(null)\n }}\n data-testid=\"report-draw-surface\"\n >\n {shown.map((mark, i) => (\n <div\n key={i}\n className=\"pointer-events-none absolute bg-black\"\n style={percent(mark)}\n data-testid=\"report-mark-redact\"\n />\n ))}\n </div>\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-end gap-2 text-sm\">\n <span className=\"mr-auto flex items-center gap-1 text-muted-foreground\">\n <EyeOff className=\"size-4\" /> Drag over anything confidential to black it out.\n </span>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={!!marks.length}\n title={marks.length ? 'Undo blacked-out areas before cropping' : undefined}\n onClick={() => {\n setCropArea(null)\n setCropping(true)\n }}\n data-testid=\"report-crop\"\n >\n <Crop className=\"mr-1 size-4\" /> Crop\n </Button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={!marks.length}\n onClick={() => setMarks((m) => m.slice(0, -1))}\n data-testid=\"report-undo\"\n >\n <Undo2 className=\"mr-1 size-4\" /> Undo\n </Button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => onImageChange(null)}\n data-testid=\"report-remove-screenshot\"\n >\n <Trash2 className=\"mr-1 size-4\" /> Remove\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={onRetake} data-testid=\"report-retake\">\n <Camera className=\"mr-1 size-4\" /> Retake\n </Button>\n </div>\n </div>\n ) : (\n <div\n className=\"flex flex-wrap items-center gap-3 rounded-md border border-dashed border-border p-3 text-sm\"\n hidden={ticketId !== null}\n >\n <span className=\"text-muted-foreground\">No screenshot attached.</span>\n {canCaptureScreen() ? (\n <Button size=\"sm\" variant=\"outline\" onClick={onRetake} data-testid=\"report-retake\">\n <Camera className=\"mr-1 size-4\" /> Take a screenshot\n </Button>\n ) : (\n <label className=\"inline-flex cursor-pointer items-center gap-1 font-medium text-primary\">\n <ImageUp className=\"size-4\" /> Choose a screenshot\n <input\n type=\"file\"\n accept=\"image/*\"\n className=\"sr-only\"\n onChange={(event) => {\n const file = event.target.files?.[0]\n if (file) onImageChange(file)\n }}\n data-testid=\"report-choose-image\"\n />\n </label>\n )}\n </div>\n )}\n\n <label className=\"grid gap-1 text-sm\" hidden={ticketId !== null}>\n <span className=\"font-medium\">What went wrong?</span>\n <Textarea\n value={description}\n onChange={(event) => setDescription(event.target.value)}\n rows={3}\n placeholder=\"What did you do, and what happened instead?\"\n data-testid=\"report-description\"\n />\n </label>\n\n {failure && (\n <p role=\"alert\" className=\"text-sm text-destructive\" hidden={ticketId !== null}>\n {failure}\n </p>\n )}\n <div className=\"flex flex-wrap items-center justify-end gap-2\" hidden={ticketId !== null}>\n <span className=\"mr-auto text-xs text-muted-foreground\">{footnote}</span>\n <Button variant=\"ghost\" onClick={onClose} disabled={busy}>\n Cancel\n </Button>\n <Button\n disabled={\n !onSubmit || !description.trim() || busy || cropping || (!!screenshot && !natural)\n }\n onClick={() => void submit()}\n data-testid=\"report-send\"\n >\n {busy ? 'Sending\u2026' : 'Send to support'}\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -18,7 +18,8 @@ import { useOpenWorkflow } from "./useOpenWorkflow.js";
18
18
  import { useHost } from "../../provider/host.js";
19
19
  import { useIntentRequest, workflowOpenRequest } from "../../provider/requests.js";
20
20
  import {
21
- ConnectedWorkflowBuilder
21
+ ConnectedWorkflowBuilder,
22
+ scheduledTaskBuilderValue
22
23
  } from "../ConnectedWorkflowBuilder.js";
23
24
  import { ConnectedWorkflowHistory } from "../ConnectedWorkflowHistory.js";
24
25
  import { ConnectedWorkflowsTable } from "../ConnectedWorkflowsTable.js";
@@ -95,7 +96,13 @@ function ConnectedWorkflowsPage({
95
96
  setHostTabId(null);
96
97
  openHistory(workflow);
97
98
  };
98
- useIntentRequest(workflowOpenRequest, ({ workflowId, view }) => {
99
+ useIntentRequest(workflowOpenRequest, ({ workflowId, view, preset }) => {
100
+ if (!workflowId && preset) {
101
+ setRunningId(null);
102
+ setHostTabId(null);
103
+ openBuilder({ kind: "new", preset });
104
+ return;
105
+ }
99
106
  if (view === "run") {
100
107
  if (!workflowId) return;
101
108
  closeBuilder();
@@ -216,7 +223,7 @@ function ConnectedWorkflowsPage({
216
223
  ConnectedWorkflowBuilder,
217
224
  {
218
225
  workflowId: builder.kind === "saved" ? builder.id : void 0,
219
- initial: template ? { workflow: template.workflow, trigger: DEFAULT_WORKFLOW_TRIGGER } : void 0,
226
+ initial: template ? { workflow: template.workflow, trigger: DEFAULT_WORKFLOW_TRIGGER } : builder.kind === "new" && builder.preset === "schedule" ? scheduledTaskBuilderValue() : void 0,
220
227
  workflows: config?.stepWorkflows ?? webWorkflows,
221
228
  renderIcon: config?.renderIcon,
222
229
  onSaved: (id) => builderSaved(id, builderKey),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connection/workflows/ConnectedWorkflowsPage.tsx"],
4
- "sourcesContent": ["/**\n * The Workflows page, connected: one composition of the saved workflows' table\n * (`ConnectedWorkflowsTable`), the visual builder (`ConnectedWorkflowBuilder`) and a workflow's\n * history (`ConnectedWorkflowHistory`), on the shared selection lifecycle\n * (`useWorkflowsPageState`).\n *\n * - The table lists the saved workflows, with the host's catalogue (`workflows.catalogue` in the\n * host configuration), when it has one, above them in the host's categories.\n * - A workflow opens in the builder, which takes the page (Back returns to the list). A document\n * action (annotate or email documents), which runs without a thread, keeps its own editor.\n * - A workflow's history opens as a tab of the table, beside the host's own `tabs`.\n * - `openWorkflow(id, { view })` from anywhere opens the workflow's builder or history here; the\n * host only shows the page. `view: 'run'` on a catalogue entry opens its run page here\n * (`ConnectedWorkflowRunPage`, with the entry's project options).\n *\n * It navigates only through the environment: threads open with `openConversation`, an AI review's\n * result with `openFiles` (offered when the host has it), a catalogue entry runs with\n * `openWorkflow(id, { view: 'run' })`.\n */\n\nimport { useCallback, useMemo, useState, type ReactNode } from 'react'\nimport { ArrowLeft, Pencil, Play, Plus, Workflow as WorkflowIcon } from 'lucide-react'\nimport {\n useInvalidateTagData,\n useRefreshDocuments,\n useTags,\n useWorkflowRuns,\n type WorkflowResponse,\n} from '@arbidocs/react'\nimport { Button, formatFriendlyDate } from '@arbidocs/react/ui'\nimport { PageHeader, type PageHeaderProps } from '../../components/PageHeader'\nimport { describeTrigger } from '../../agents/tasks/taskHelpers'\nimport type { TaskRunsDialogLabels } from '../../agents/tasks/TaskRunsDialog'\nimport type { WorkflowListLabels } from '../../agents/tasks/workflowTableLabels'\nimport { WEB_WORKFLOWS } from '../../agents/workflows/catalogue/registry'\nimport { useNamedWorkflows } from './useNamedWorkflows'\nimport { DEFAULT_WORKFLOW_TRIGGER } from '../../workflow-canvas/trigger'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { useOpenWorkflow } from './useOpenWorkflow'\nimport { useHost } from '../../provider/host'\nimport { useIntentRequest, workflowOpenRequest } from '../../provider/requests'\nimport {\n ConnectedWorkflowBuilder,\n type ConnectedWorkflowBuilderProps,\n} from '../ConnectedWorkflowBuilder'\nimport { ConnectedWorkflowHistory } from '../ConnectedWorkflowHistory'\nimport { ConnectedWorkflowsTable } from '../ConnectedWorkflowsTable'\nimport { ConnectedWorkflowRunPage } from './ConnectedWorkflowRunPage'\nimport { ConnectedTaskComposer } from '../tasks/ConnectedTaskComposer'\nimport { useRenderTaskPerson } from '../tasks/useTaskPeople'\nimport { useAiReviewStore } from '../files/store'\nimport { useWorkflowsPageState } from './useWorkflowsPageState'\nimport {\n DEFAULT_CONNECTED_WORKFLOWS_PAGE_LABELS,\n DEFAULT_WORKFLOWS_PAGE_TABLE_LABELS,\n WORKFLOWS_PAGE_TRIGGER_CHIP_LABELS,\n type ConnectedWorkflowsPageLabels,\n} from './workflowsPageLabels'\n\ntype WorkflowRun = NonNullable<ReturnType<typeof useWorkflowRuns>['data']>[number]\n\n/** A tab of the host's beside the saved workflows (e.g. the agents that run them). */\nexport interface WorkflowsPageTab {\n id: string\n label: string\n icon?: ReactNode\n content: ReactNode\n}\n\n/** The table's own tab (the saved workflows). */\nconst LIST_TAB = 'automations'\n\nexport interface ConnectedWorkflowsPageProps {\n /** A host deep link to a workflow's history (e.g. a `?workflow=` URL), taken once it loads. */\n historyWorkflowId?: string | null\n onHistoryWorkflowConsumed?: () => void\n /** A title block over the table (eyebrow, title, description). Absent: none. */\n pageHeader?: Omit<PageHeaderProps, 'actions' | 'tabs'>\n /** The host's tabs beside the saved workflows, before any open history. */\n tabs?: WorkflowsPageTab[]\n /**\n * One of the host's `tabs` to show instead of the saved workflows (a host deep link such as\n * `?tab=agents`): on mount, and again whenever it changes to another tab. Unknown ids show the\n * saved workflows.\n */\n initialTabId?: string | null\n /** The builder's words and options. */\n builderProps?: Pick<\n ConnectedWorkflowBuilderProps,\n | 'labels'\n | 'canvasLabels'\n | 'inspectorLabels'\n | 'triggerLabels'\n | 'connectedLabels'\n | 'eventKinds'\n | 'compose'\n >\n labels?: Partial<ConnectedWorkflowsPageLabels>\n tableLabels?: Partial<WorkflowListLabels>\n historyLabels?: Partial<TaskRunsDialogLabels>\n testId?: string\n}\n\nexport function ConnectedWorkflowsPage({\n historyWorkflowId,\n onHistoryWorkflowConsumed,\n pageHeader,\n tabs,\n initialTabId,\n builderProps,\n labels,\n tableLabels,\n historyLabels,\n testId = 'workflows-page',\n}: ConnectedWorkflowsPageProps) {\n // The default step catalogue in the host's assistant name.\n const webWorkflows = useNamedWorkflows(WEB_WORKFLOWS)\n const l = { ...DEFAULT_CONNECTED_WORKFLOWS_PAGE_LABELS, ...labels }\n const host = useHost()\n const config = host.workflows\n const { openConversation, openFiles } = useBlocksEnvironment()\n const openWorkflow = useOpenWorkflow()\n const renderPerson = useRenderTaskPerson()\n const refreshDocuments = useRefreshDocuments()\n const invalidateTags = useInvalidateTagData()\n const { data: tags = [] } = useTags()\n const [editing, setEditing] = useState<WorkflowResponse | null>(null)\n const [editorOpen, setEditorOpen] = useState(false)\n const [hostTabId, setHostTabId] = useState<string | null>(initialTabId ?? null)\n // The host's link is applied again when it names another tab (the page stays mounted when the\n // host's address changes), never over the person's own choice of tab otherwise.\n const [appliedTabId, setAppliedTabId] = useState(initialTabId)\n if (initialTabId !== appliedTabId) {\n setAppliedTabId(initialTabId)\n if (initialTabId) setHostTabId(initialTabId)\n }\n // The catalogue entry being run (`openWorkflow(id, { view: 'run' })`).\n const [runningId, setRunningId] = useState<string | null>(null)\n // A workflow `openWorkflow(id, { view: 'runs' })` asked for, until it has loaded.\n const [requestedHistoryId, setRequestedHistoryId] = useState<string | null>(null)\n const consumeHistory = useCallback(() => {\n if (requestedHistoryId) setRequestedHistoryId(null)\n else onHistoryWorkflowConsumed?.()\n }, [requestedHistoryId, onHistoryWorkflowConsumed])\n const {\n workflows,\n builder,\n builderKey,\n openBuilder,\n closeBuilder,\n builderSaved,\n historyFor: runsFor,\n historyTabs,\n activeHistoryId,\n openHistory,\n closeHistoryTab,\n selectHistoryTab,\n } = useWorkflowsPageState({\n historyWorkflowId: requestedHistoryId ?? historyWorkflowId,\n onHistoryWorkflowConsumed: consumeHistory,\n })\n const listLabels = useMemo(\n () => ({ ...DEFAULT_WORKFLOWS_PAGE_TABLE_LABELS, ...tableLabels }),\n [tableLabels]\n )\n const hostTab = tabs?.find((tab) => tab.id === hostTabId)\n const showHistory = (workflow: WorkflowResponse | null) => {\n setHostTabId(null)\n openHistory(workflow)\n }\n\n useIntentRequest(workflowOpenRequest, ({ workflowId, view }) => {\n if (view === 'run') {\n if (!workflowId) return\n closeBuilder()\n setRunningId(workflowId)\n return\n }\n setRunningId(null)\n if (workflowId && view !== 'runs') {\n openBuilder({ kind: 'saved', id: workflowId })\n return\n }\n closeBuilder()\n setHostTabId(null)\n if (workflowId) setRequestedHistoryId(workflowId)\n else selectHistoryTab(null)\n })\n\n const edit = (workflow: WorkflowResponse) => {\n showHistory(workflow)\n // Every workflow opens in the visual builder: stepped ones as their steps, a classic one (a\n // single prompt or skill) as one agent step, a reminder with no steps yet. Only document actions\n // (annotate / email documents), which run without a thread, keep their own editor.\n if (!workflow.action) {\n openBuilder({ kind: 'saved', id: workflow.external_id })\n return\n }\n setEditing(workflow)\n setEditorOpen(true)\n }\n\n // An AI review's result: its documents re-read, Files narrowed to its label, its fields shown.\n const openResult = async (execution: WorkflowRun) => {\n await refreshDocuments(execution.document_ext_ids)\n await invalidateTags()\n const fieldIds =\n (execution.result?.tag_ext_ids as string[] | undefined) ?? runsFor?.action?.tag_ext_ids ?? []\n useAiReviewStore.getState().setRun({\n docIds: execution.document_ext_ids,\n tags: fieldIds.map((fieldId) => ({\n id: fieldId,\n name: tags.find((tag) => tag.external_id === fieldId)?.name ?? 'Review',\n })),\n })\n useAiReviewStore.getState().setOpen(true)\n openFiles(\n execution.label_ext_id ? { filters: { [execution.label_ext_id]: 'include' } } : undefined\n )\n }\n const renderErrorReport = config?.renderErrorReport\n\n const running = runningId\n ? config?.catalogue?.find((entry) => entry.workflow.id === runningId)\n : undefined\n if (running && running.runnable !== false) {\n const stepWorkflows = config?.stepWorkflows ?? webWorkflows\n return (\n // The page in the Workflows page's frame: padded, scrolling.\n <div className=\"h-full min-h-0 w-full overflow-auto p-4 sm:p-6\">\n <ConnectedWorkflowRunPage\n key={running.workflow.id}\n workflow={running.workflow}\n projectFrom={running.projectFrom}\n inputsFromProject={running.inputsFromProject}\n onProjectCreated={running.onProjectCreated}\n options={{ resolveWorkflow: (id) => stepWorkflows.find((w) => w.id === id) }}\n renderIcon={config?.renderIcon}\n onOpenConversation={(id) => openConversation(id)}\n pageHeader={{\n eyebrow: running.category,\n leading: (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setRunningId(null)}\n aria-label={l.back}\n title={l.back}\n data-testid=\"workflow-run-back\"\n >\n <ArrowLeft className=\"size-4\" />\n </Button>\n ),\n }}\n testIdPrefix=\"workflow-run\"\n />\n </div>\n )\n }\n\n if (builder) {\n const template =\n builder.kind === 'template'\n ? config?.catalogue?.find((entry) => entry.workflow.id === builder.id)\n : undefined\n return (\n <div\n className=\"flex h-full min-h-0 flex-col gap-3 overflow-auto p-4\"\n data-testid=\"workflow-builder\"\n >\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={closeBuilder}\n data-testid=\"workflow-builder-back\"\n >\n <ArrowLeft className=\"size-4\" /> {l.back}\n </Button>\n {template && template.runnable !== false && openWorkflow && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => openWorkflow(template.workflow.id, { view: 'run' })}\n data-testid=\"workflow-builder-run\"\n >\n <Play className=\"size-4\" /> {l.runTemplate}\n </Button>\n )}\n </div>\n <ConnectedWorkflowBuilder\n key={builderKey}\n workflowId={builder.kind === 'saved' ? builder.id : undefined}\n initial={\n template\n ? { workflow: template.workflow, trigger: DEFAULT_WORKFLOW_TRIGGER }\n : undefined\n }\n workflows={config?.stepWorkflows ?? webWorkflows}\n renderIcon={config?.renderIcon}\n onSaved={(id) => builderSaved(id, builderKey)}\n testId=\"workflow-builder-canvas\"\n {...builderProps}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\" data-testid={testId}>\n {pageHeader && <PageHeader {...pageHeader} />}\n <ConnectedWorkflowsTable\n onOpenTemplate={(id) => openBuilder({ kind: 'template', id })}\n tabs={[\n ...(tabs ?? []).map(({ id, label, icon }) => ({ id, label, icon })),\n ...historyTabs.map((workflow) => ({\n id: workflow.external_id,\n label: workflow.name,\n icon: <WorkflowIcon className=\"size-3.5\" />,\n onClose: () => {\n closeHistoryTab(workflow.external_id)\n if (activeHistoryId === workflow.external_id) setEditorOpen(false)\n },\n })),\n ]}\n activeTabId={hostTab?.id ?? activeHistoryId ?? LIST_TAB}\n onTabChange={(id) => {\n if (tabs?.some((tab) => tab.id === id)) {\n setHostTabId(id)\n return\n }\n setHostTabId(null)\n selectHistoryTab(id === LIST_TAB ? null : id)\n if (editorOpen) {\n const workflow = workflows.find((item) => item.external_id === id)\n if (workflow) setEditing(workflow)\n else setEditorOpen(false)\n }\n }}\n content={\n hostTab ? (\n hostTab.content\n ) : runsFor ? (\n <ConnectedWorkflowHistory\n inline\n hideHeader\n workflow={runsFor}\n onOpenChange={(open) => !open && openHistory(null)}\n formatDate={formatFriendlyDate}\n labels={historyLabels}\n renderErrorReport={\n renderErrorReport &&\n ((run) =>\n renderErrorReport(\n JSON.stringify(\n {\n workflow_ext_id: runsFor.external_id,\n run_id: run.id,\n status: run.status,\n error: run.error,\n },\n null,\n 2\n )\n ))\n }\n // Offered where the host shows files (its `openFiles`).\n onOpenResult={host.environment?.openFiles ? openResult : undefined}\n />\n ) : undefined\n }\n automationsOnly\n gridId=\"automations-grid-v1\"\n describeTrigger={(workflow) =>\n workflow.on_demand ? l.manualTrigger : describeTrigger(workflow)\n }\n formatDate={formatFriendlyDate}\n renderPerson={renderPerson}\n onViewRuns={showHistory}\n onOpenRow={edit}\n onEdit={edit}\n triggerChipLabels={WORKFLOWS_PAGE_TRIGGER_CHIP_LABELS}\n labels={listLabels}\n // A narrow row (a phone) keeps the actions' icons, so the host's tabs keep their room.\n header={(isCompact) => (\n <>\n {runsFor && !hostTab && (\n <Button\n variant=\"ghost\"\n onClick={() => edit(runsFor)}\n aria-label={l.editAria}\n title={isCompact ? l.edit : undefined}\n >\n <Pencil className={isCompact ? 'size-4' : 'mr-1.5 size-4'} />\n {!isCompact && l.edit}\n </Button>\n )}\n <Button\n onClick={() => openBuilder({ kind: 'new' })}\n aria-label={isCompact ? l.newWorkflow : undefined}\n title={isCompact ? l.newWorkflow : undefined}\n data-testid=\"new-workflow-button\"\n >\n <Plus className={isCompact ? 'size-4' : 'mr-1.5 size-4'} />\n {!isCompact && l.newWorkflow}\n </Button>\n </>\n )}\n />\n <ConnectedTaskComposer\n kind=\"workflow\"\n saveOnly\n startLater\n open={editorOpen}\n onOpenChange={setEditorOpen}\n workflow={editing}\n />\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * The Workflows page, connected: one composition of the saved workflows' table\n * (`ConnectedWorkflowsTable`), the visual builder (`ConnectedWorkflowBuilder`) and a workflow's\n * history (`ConnectedWorkflowHistory`), on the shared selection lifecycle\n * (`useWorkflowsPageState`).\n *\n * - The table lists the saved workflows, with the host's catalogue (`workflows.catalogue` in the\n * host configuration), when it has one, above them in the host's categories.\n * - A workflow opens in the builder, which takes the page (Back returns to the list). A document\n * action (annotate or email documents), which runs without a thread, keeps its own editor.\n * - A workflow's history opens as a tab of the table, beside the host's own `tabs`.\n * - `openWorkflow(id, { view })` from anywhere opens the workflow's builder or history here; the\n * host only shows the page. `view: 'run'` on a catalogue entry opens its run page here\n * (`ConnectedWorkflowRunPage`, with the entry's project options).\n *\n * It navigates only through the environment: threads open with `openConversation`, an AI review's\n * result with `openFiles` (offered when the host has it), a catalogue entry runs with\n * `openWorkflow(id, { view: 'run' })`.\n */\n\nimport { useCallback, useMemo, useState, type ReactNode } from 'react'\nimport { ArrowLeft, Pencil, Play, Plus, Workflow as WorkflowIcon } from 'lucide-react'\nimport {\n useInvalidateTagData,\n useRefreshDocuments,\n useTags,\n useWorkflowRuns,\n type WorkflowResponse,\n} from '@arbidocs/react'\nimport { Button, formatFriendlyDate } from '@arbidocs/react/ui'\nimport { PageHeader, type PageHeaderProps } from '../../components/PageHeader'\nimport { describeTrigger } from '../../agents/tasks/taskHelpers'\nimport type { TaskRunsDialogLabels } from '../../agents/tasks/TaskRunsDialog'\nimport type { WorkflowListLabels } from '../../agents/tasks/workflowTableLabels'\nimport { WEB_WORKFLOWS } from '../../agents/workflows/catalogue/registry'\nimport { useNamedWorkflows } from './useNamedWorkflows'\nimport { DEFAULT_WORKFLOW_TRIGGER } from '../../workflow-canvas/trigger'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { useOpenWorkflow } from './useOpenWorkflow'\nimport { useHost } from '../../provider/host'\nimport { useIntentRequest, workflowOpenRequest } from '../../provider/requests'\nimport {\n ConnectedWorkflowBuilder,\n scheduledTaskBuilderValue,\n type ConnectedWorkflowBuilderProps,\n} from '../ConnectedWorkflowBuilder'\nimport { ConnectedWorkflowHistory } from '../ConnectedWorkflowHistory'\nimport { ConnectedWorkflowsTable } from '../ConnectedWorkflowsTable'\nimport { ConnectedWorkflowRunPage } from './ConnectedWorkflowRunPage'\nimport { ConnectedTaskComposer } from '../tasks/ConnectedTaskComposer'\nimport { useRenderTaskPerson } from '../tasks/useTaskPeople'\nimport { useAiReviewStore } from '../files/store'\nimport { useWorkflowsPageState } from './useWorkflowsPageState'\nimport {\n DEFAULT_CONNECTED_WORKFLOWS_PAGE_LABELS,\n DEFAULT_WORKFLOWS_PAGE_TABLE_LABELS,\n WORKFLOWS_PAGE_TRIGGER_CHIP_LABELS,\n type ConnectedWorkflowsPageLabels,\n} from './workflowsPageLabels'\n\ntype WorkflowRun = NonNullable<ReturnType<typeof useWorkflowRuns>['data']>[number]\n\n/** A tab of the host's beside the saved workflows (e.g. the agents that run them). */\nexport interface WorkflowsPageTab {\n id: string\n label: string\n icon?: ReactNode\n content: ReactNode\n}\n\n/** The table's own tab (the saved workflows). */\nconst LIST_TAB = 'automations'\n\nexport interface ConnectedWorkflowsPageProps {\n /** A host deep link to a workflow's history (e.g. a `?workflow=` URL), taken once it loads. */\n historyWorkflowId?: string | null\n onHistoryWorkflowConsumed?: () => void\n /** A title block over the table (eyebrow, title, description). Absent: none. */\n pageHeader?: Omit<PageHeaderProps, 'actions' | 'tabs'>\n /** The host's tabs beside the saved workflows, before any open history. */\n tabs?: WorkflowsPageTab[]\n /**\n * One of the host's `tabs` to show instead of the saved workflows (a host deep link such as\n * `?tab=agents`): on mount, and again whenever it changes to another tab. Unknown ids show the\n * saved workflows.\n */\n initialTabId?: string | null\n /** The builder's words and options. */\n builderProps?: Pick<\n ConnectedWorkflowBuilderProps,\n | 'labels'\n | 'canvasLabels'\n | 'inspectorLabels'\n | 'triggerLabels'\n | 'connectedLabels'\n | 'eventKinds'\n | 'compose'\n >\n labels?: Partial<ConnectedWorkflowsPageLabels>\n tableLabels?: Partial<WorkflowListLabels>\n historyLabels?: Partial<TaskRunsDialogLabels>\n testId?: string\n}\n\nexport function ConnectedWorkflowsPage({\n historyWorkflowId,\n onHistoryWorkflowConsumed,\n pageHeader,\n tabs,\n initialTabId,\n builderProps,\n labels,\n tableLabels,\n historyLabels,\n testId = 'workflows-page',\n}: ConnectedWorkflowsPageProps) {\n // The default step catalogue in the host's assistant name.\n const webWorkflows = useNamedWorkflows(WEB_WORKFLOWS)\n const l = { ...DEFAULT_CONNECTED_WORKFLOWS_PAGE_LABELS, ...labels }\n const host = useHost()\n const config = host.workflows\n const { openConversation, openFiles } = useBlocksEnvironment()\n const openWorkflow = useOpenWorkflow()\n const renderPerson = useRenderTaskPerson()\n const refreshDocuments = useRefreshDocuments()\n const invalidateTags = useInvalidateTagData()\n const { data: tags = [] } = useTags()\n const [editing, setEditing] = useState<WorkflowResponse | null>(null)\n const [editorOpen, setEditorOpen] = useState(false)\n const [hostTabId, setHostTabId] = useState<string | null>(initialTabId ?? null)\n // The host's link is applied again when it names another tab (the page stays mounted when the\n // host's address changes), never over the person's own choice of tab otherwise.\n const [appliedTabId, setAppliedTabId] = useState(initialTabId)\n if (initialTabId !== appliedTabId) {\n setAppliedTabId(initialTabId)\n if (initialTabId) setHostTabId(initialTabId)\n }\n // The catalogue entry being run (`openWorkflow(id, { view: 'run' })`).\n const [runningId, setRunningId] = useState<string | null>(null)\n // A workflow `openWorkflow(id, { view: 'runs' })` asked for, until it has loaded.\n const [requestedHistoryId, setRequestedHistoryId] = useState<string | null>(null)\n const consumeHistory = useCallback(() => {\n if (requestedHistoryId) setRequestedHistoryId(null)\n else onHistoryWorkflowConsumed?.()\n }, [requestedHistoryId, onHistoryWorkflowConsumed])\n const {\n workflows,\n builder,\n builderKey,\n openBuilder,\n closeBuilder,\n builderSaved,\n historyFor: runsFor,\n historyTabs,\n activeHistoryId,\n openHistory,\n closeHistoryTab,\n selectHistoryTab,\n } = useWorkflowsPageState({\n historyWorkflowId: requestedHistoryId ?? historyWorkflowId,\n onHistoryWorkflowConsumed: consumeHistory,\n })\n const listLabels = useMemo(\n () => ({ ...DEFAULT_WORKFLOWS_PAGE_TABLE_LABELS, ...tableLabels }),\n [tableLabels]\n )\n const hostTab = tabs?.find((tab) => tab.id === hostTabId)\n const showHistory = (workflow: WorkflowResponse | null) => {\n setHostTabId(null)\n openHistory(workflow)\n }\n\n useIntentRequest(workflowOpenRequest, ({ workflowId, view, preset }) => {\n if (!workflowId && preset) {\n setRunningId(null)\n setHostTabId(null)\n openBuilder({ kind: 'new', preset })\n return\n }\n if (view === 'run') {\n if (!workflowId) return\n closeBuilder()\n setRunningId(workflowId)\n return\n }\n setRunningId(null)\n if (workflowId && view !== 'runs') {\n openBuilder({ kind: 'saved', id: workflowId })\n return\n }\n closeBuilder()\n setHostTabId(null)\n if (workflowId) setRequestedHistoryId(workflowId)\n else selectHistoryTab(null)\n })\n\n const edit = (workflow: WorkflowResponse) => {\n showHistory(workflow)\n // Every workflow opens in the visual builder: stepped ones as their steps, a classic one (a\n // single prompt or skill) as one agent step, a reminder with no steps yet. Only document actions\n // (annotate / email documents), which run without a thread, keep their own editor.\n if (!workflow.action) {\n openBuilder({ kind: 'saved', id: workflow.external_id })\n return\n }\n setEditing(workflow)\n setEditorOpen(true)\n }\n\n // An AI review's result: its documents re-read, Files narrowed to its label, its fields shown.\n const openResult = async (execution: WorkflowRun) => {\n await refreshDocuments(execution.document_ext_ids)\n await invalidateTags()\n const fieldIds =\n (execution.result?.tag_ext_ids as string[] | undefined) ?? runsFor?.action?.tag_ext_ids ?? []\n useAiReviewStore.getState().setRun({\n docIds: execution.document_ext_ids,\n tags: fieldIds.map((fieldId) => ({\n id: fieldId,\n name: tags.find((tag) => tag.external_id === fieldId)?.name ?? 'Review',\n })),\n })\n useAiReviewStore.getState().setOpen(true)\n openFiles(\n execution.label_ext_id ? { filters: { [execution.label_ext_id]: 'include' } } : undefined\n )\n }\n const renderErrorReport = config?.renderErrorReport\n\n const running = runningId\n ? config?.catalogue?.find((entry) => entry.workflow.id === runningId)\n : undefined\n if (running && running.runnable !== false) {\n const stepWorkflows = config?.stepWorkflows ?? webWorkflows\n return (\n // The page in the Workflows page's frame: padded, scrolling.\n <div className=\"h-full min-h-0 w-full overflow-auto p-4 sm:p-6\">\n <ConnectedWorkflowRunPage\n key={running.workflow.id}\n workflow={running.workflow}\n projectFrom={running.projectFrom}\n inputsFromProject={running.inputsFromProject}\n onProjectCreated={running.onProjectCreated}\n options={{ resolveWorkflow: (id) => stepWorkflows.find((w) => w.id === id) }}\n renderIcon={config?.renderIcon}\n onOpenConversation={(id) => openConversation(id)}\n pageHeader={{\n eyebrow: running.category,\n leading: (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setRunningId(null)}\n aria-label={l.back}\n title={l.back}\n data-testid=\"workflow-run-back\"\n >\n <ArrowLeft className=\"size-4\" />\n </Button>\n ),\n }}\n testIdPrefix=\"workflow-run\"\n />\n </div>\n )\n }\n\n if (builder) {\n const template =\n builder.kind === 'template'\n ? config?.catalogue?.find((entry) => entry.workflow.id === builder.id)\n : undefined\n return (\n <div\n className=\"flex h-full min-h-0 flex-col gap-3 overflow-auto p-4\"\n data-testid=\"workflow-builder\"\n >\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={closeBuilder}\n data-testid=\"workflow-builder-back\"\n >\n <ArrowLeft className=\"size-4\" /> {l.back}\n </Button>\n {template && template.runnable !== false && openWorkflow && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => openWorkflow(template.workflow.id, { view: 'run' })}\n data-testid=\"workflow-builder-run\"\n >\n <Play className=\"size-4\" /> {l.runTemplate}\n </Button>\n )}\n </div>\n <ConnectedWorkflowBuilder\n key={builderKey}\n workflowId={builder.kind === 'saved' ? builder.id : undefined}\n initial={\n template\n ? { workflow: template.workflow, trigger: DEFAULT_WORKFLOW_TRIGGER }\n : builder.kind === 'new' && builder.preset === 'schedule'\n ? scheduledTaskBuilderValue()\n : undefined\n }\n workflows={config?.stepWorkflows ?? webWorkflows}\n renderIcon={config?.renderIcon}\n onSaved={(id) => builderSaved(id, builderKey)}\n testId=\"workflow-builder-canvas\"\n {...builderProps}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\" data-testid={testId}>\n {pageHeader && <PageHeader {...pageHeader} />}\n <ConnectedWorkflowsTable\n onOpenTemplate={(id) => openBuilder({ kind: 'template', id })}\n tabs={[\n ...(tabs ?? []).map(({ id, label, icon }) => ({ id, label, icon })),\n ...historyTabs.map((workflow) => ({\n id: workflow.external_id,\n label: workflow.name,\n icon: <WorkflowIcon className=\"size-3.5\" />,\n onClose: () => {\n closeHistoryTab(workflow.external_id)\n if (activeHistoryId === workflow.external_id) setEditorOpen(false)\n },\n })),\n ]}\n activeTabId={hostTab?.id ?? activeHistoryId ?? LIST_TAB}\n onTabChange={(id) => {\n if (tabs?.some((tab) => tab.id === id)) {\n setHostTabId(id)\n return\n }\n setHostTabId(null)\n selectHistoryTab(id === LIST_TAB ? null : id)\n if (editorOpen) {\n const workflow = workflows.find((item) => item.external_id === id)\n if (workflow) setEditing(workflow)\n else setEditorOpen(false)\n }\n }}\n content={\n hostTab ? (\n hostTab.content\n ) : runsFor ? (\n <ConnectedWorkflowHistory\n inline\n hideHeader\n workflow={runsFor}\n onOpenChange={(open) => !open && openHistory(null)}\n formatDate={formatFriendlyDate}\n labels={historyLabels}\n renderErrorReport={\n renderErrorReport &&\n ((run) =>\n renderErrorReport(\n JSON.stringify(\n {\n workflow_ext_id: runsFor.external_id,\n run_id: run.id,\n status: run.status,\n error: run.error,\n },\n null,\n 2\n )\n ))\n }\n // Offered where the host shows files (its `openFiles`).\n onOpenResult={host.environment?.openFiles ? openResult : undefined}\n />\n ) : undefined\n }\n automationsOnly\n gridId=\"automations-grid-v1\"\n describeTrigger={(workflow) =>\n workflow.on_demand ? l.manualTrigger : describeTrigger(workflow)\n }\n formatDate={formatFriendlyDate}\n renderPerson={renderPerson}\n onViewRuns={showHistory}\n onOpenRow={edit}\n onEdit={edit}\n triggerChipLabels={WORKFLOWS_PAGE_TRIGGER_CHIP_LABELS}\n labels={listLabels}\n // A narrow row (a phone) keeps the actions' icons, so the host's tabs keep their room.\n header={(isCompact) => (\n <>\n {runsFor && !hostTab && (\n <Button\n variant=\"ghost\"\n onClick={() => edit(runsFor)}\n aria-label={l.editAria}\n title={isCompact ? l.edit : undefined}\n >\n <Pencil className={isCompact ? 'size-4' : 'mr-1.5 size-4'} />\n {!isCompact && l.edit}\n </Button>\n )}\n <Button\n onClick={() => openBuilder({ kind: 'new' })}\n aria-label={isCompact ? l.newWorkflow : undefined}\n title={isCompact ? l.newWorkflow : undefined}\n data-testid=\"new-workflow-button\"\n >\n <Plus className={isCompact ? 'size-4' : 'mr-1.5 size-4'} />\n {!isCompact && l.newWorkflow}\n </Button>\n </>\n )}\n />\n <ConnectedTaskComposer\n kind=\"workflow\"\n saveOnly\n startLater\n open={editorOpen}\n onOpenChange={setEditorOpen}\n workflow={editing}\n />\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -5,6 +5,7 @@ export type WorkflowBuilderSelection = {
5
5
  id: string;
6
6
  } | {
7
7
  kind: 'new';
8
+ preset?: 'schedule';
8
9
  } | {
9
10
  kind: 'template';
10
11
  id: string;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connection/workflows/useWorkflowsPageState.ts"],
4
- "sourcesContent": ["import { useCallback, useEffect, useRef, useState } from 'react'\nimport { useWorkflows, type WorkflowResponse } from '@arbidocs/react'\n\n/** A saved workflow, a new one, or a host catalogue entry opened as a template. */\nexport type WorkflowBuilderSelection =\n { kind: 'saved'; id: string } | { kind: 'new' } | { kind: 'template'; id: string }\n\nexport interface WorkflowsPageStateOptions {\n initialBuilder?: WorkflowBuilderSelection\n /** A host deep link to consume once the saved workflow has loaded. */\n historyWorkflowId?: string | null\n onHistoryWorkflowConsumed?: () => void\n}\n\n/** Shared selection lifecycle for workflow tables, builders and history views. No routing or layout. */\nexport function useWorkflowsPageState({\n initialBuilder,\n historyWorkflowId,\n onHistoryWorkflowConsumed,\n}: WorkflowsPageStateOptions = {}) {\n const { data: workflows = [] } = useWorkflows({ live: true })\n const [builder, setBuilder] = useState<WorkflowBuilderSelection | null>(initialBuilder ?? null)\n const [builderKey, setBuilderKey] = useState(0)\n const [historyIds, setHistoryIds] = useState<string[]>([])\n const [activeHistoryId, setActiveHistoryId] = useState<string | null>(null)\n // Resolve against current query data: renaming/deleting a workflow cannot leave a stale dialog.\n const historyFor = workflows.find((workflow) => workflow.external_id === activeHistoryId) ?? null\n const historyTabs = historyIds.flatMap((id) => {\n const workflow = workflows.find((item) => item.external_id === id)\n return workflow ? [workflow] : []\n })\n\n const openHistory = useCallback((workflow: WorkflowResponse | null) => {\n const id = workflow?.external_id ?? null\n if (id) setHistoryIds((ids) => (ids.includes(id) ? ids : [...ids, id]))\n setActiveHistoryId(id)\n }, [])\n const closeHistoryTab = useCallback((id: string) => {\n setHistoryIds((ids) => ids.filter((item) => item !== id))\n setActiveHistoryId((active) => (active === id ? null : active))\n }, [])\n const builderKeyRef = useRef(builderKey)\n builderKeyRef.current = builderKey\n const openBuilder = useCallback((selection: WorkflowBuilderSelection) => {\n setBuilder(selection)\n // Reopening a template/new/saved selection resets its unsaved canvas; saving does not.\n setBuilderKey((key) => key + 1)\n }, [])\n /**\n * A save finished (it lands once the workflows are re-read): the builder it came from (its\n * `builderKey`, default the current one) now edits the saved workflow. A save the person left\n * meanwhile (Back, or another workflow opened) changes nothing: it never reopens the builder.\n */\n const builderSaved = useCallback((id: string, fromKey?: number) => {\n if (fromKey !== undefined && fromKey !== builderKeyRef.current) return\n setBuilder((open) => (open ? { kind: 'saved', id } : null))\n }, [])\n\n useEffect(() => {\n const workflow = workflows.find((item) => item.external_id === historyWorkflowId)\n if (!workflow) return\n openHistory(workflow)\n onHistoryWorkflowConsumed?.()\n }, [historyWorkflowId, onHistoryWorkflowConsumed, openHistory, workflows])\n\n return {\n workflows,\n builder,\n builderKey,\n openBuilder,\n closeBuilder: () => setBuilder(null),\n builderSaved,\n historyFor,\n historyTabs,\n activeHistoryId,\n openHistory,\n closeHistoryTab,\n selectHistoryTab: setActiveHistoryId,\n }\n}\n"],
5
- "mappings": ";AAAA,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AACzD,SAAS,oBAA2C;AAc7C,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,IAA+B,CAAC,GAAG;AACjC,QAAM,EAAE,MAAM,YAAY,CAAC,EAAE,IAAI,aAAa,EAAE,MAAM,KAAK,CAAC;AAC5D,QAAM,CAAC,SAAS,UAAU,IAAI,SAA0C,kBAAkB,IAAI;AAC9F,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,CAAC;AAC9C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAmB,CAAC,CAAC;AACzD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAwB,IAAI;AAE1E,QAAM,aAAa,UAAU,KAAK,CAAC,aAAa,SAAS,gBAAgB,eAAe,KAAK;AAC7F,QAAM,cAAc,WAAW,QAAQ,CAAC,OAAO;AAC7C,UAAM,WAAW,UAAU,KAAK,CAAC,SAAS,KAAK,gBAAgB,EAAE;AACjE,WAAO,WAAW,CAAC,QAAQ,IAAI,CAAC;AAAA,EAClC,CAAC;AAED,QAAM,cAAc,YAAY,CAAC,aAAsC;AACrE,UAAM,KAAK,UAAU,eAAe;AACpC,QAAI,GAAI,eAAc,CAAC,QAAS,IAAI,SAAS,EAAE,IAAI,MAAM,CAAC,GAAG,KAAK,EAAE,CAAE;AACtE,uBAAmB,EAAE;AAAA,EACvB,GAAG,CAAC,CAAC;AACL,QAAM,kBAAkB,YAAY,CAAC,OAAe;AAClD,kBAAc,CAAC,QAAQ,IAAI,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC;AACxD,uBAAmB,CAAC,WAAY,WAAW,KAAK,OAAO,MAAO;AAAA,EAChE,GAAG,CAAC,CAAC;AACL,QAAM,gBAAgB,OAAO,UAAU;AACvC,gBAAc,UAAU;AACxB,QAAM,cAAc,YAAY,CAAC,cAAwC;AACvE,eAAW,SAAS;AAEpB,kBAAc,CAAC,QAAQ,MAAM,CAAC;AAAA,EAChC,GAAG,CAAC,CAAC;AAML,QAAM,eAAe,YAAY,CAAC,IAAY,YAAqB;AACjE,QAAI,YAAY,UAAa,YAAY,cAAc,QAAS;AAChE,eAAW,CAAC,SAAU,OAAO,EAAE,MAAM,SAAS,GAAG,IAAI,IAAK;AAAA,EAC5D,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,UAAM,WAAW,UAAU,KAAK,CAAC,SAAS,KAAK,gBAAgB,iBAAiB;AAChF,QAAI,CAAC,SAAU;AACf,gBAAY,QAAQ;AACpB,gCAA4B;AAAA,EAC9B,GAAG,CAAC,mBAAmB,2BAA2B,aAAa,SAAS,CAAC;AAEzE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,MAAM,WAAW,IAAI;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EACpB;AACF;",
4
+ "sourcesContent": ["import { useCallback, useEffect, useRef, useState } from 'react'\nimport { useWorkflows, type WorkflowResponse } from '@arbidocs/react'\n\n/** A saved workflow, a new one, or a host catalogue entry opened as a template. */\nexport type WorkflowBuilderSelection =\n | { kind: 'saved'; id: string }\n | { kind: 'new'; preset?: 'schedule' }\n | { kind: 'template'; id: string }\n\nexport interface WorkflowsPageStateOptions {\n initialBuilder?: WorkflowBuilderSelection\n /** A host deep link to consume once the saved workflow has loaded. */\n historyWorkflowId?: string | null\n onHistoryWorkflowConsumed?: () => void\n}\n\n/** Shared selection lifecycle for workflow tables, builders and history views. No routing or layout. */\nexport function useWorkflowsPageState({\n initialBuilder,\n historyWorkflowId,\n onHistoryWorkflowConsumed,\n}: WorkflowsPageStateOptions = {}) {\n const { data: workflows = [] } = useWorkflows({ live: true })\n const [builder, setBuilder] = useState<WorkflowBuilderSelection | null>(initialBuilder ?? null)\n const [builderKey, setBuilderKey] = useState(0)\n const [historyIds, setHistoryIds] = useState<string[]>([])\n const [activeHistoryId, setActiveHistoryId] = useState<string | null>(null)\n // Resolve against current query data: renaming/deleting a workflow cannot leave a stale dialog.\n const historyFor = workflows.find((workflow) => workflow.external_id === activeHistoryId) ?? null\n const historyTabs = historyIds.flatMap((id) => {\n const workflow = workflows.find((item) => item.external_id === id)\n return workflow ? [workflow] : []\n })\n\n const openHistory = useCallback((workflow: WorkflowResponse | null) => {\n const id = workflow?.external_id ?? null\n if (id) setHistoryIds((ids) => (ids.includes(id) ? ids : [...ids, id]))\n setActiveHistoryId(id)\n }, [])\n const closeHistoryTab = useCallback((id: string) => {\n setHistoryIds((ids) => ids.filter((item) => item !== id))\n setActiveHistoryId((active) => (active === id ? null : active))\n }, [])\n const builderKeyRef = useRef(builderKey)\n builderKeyRef.current = builderKey\n const openBuilder = useCallback((selection: WorkflowBuilderSelection) => {\n setBuilder(selection)\n // Reopening a template/new/saved selection resets its unsaved canvas; saving does not.\n setBuilderKey((key) => key + 1)\n }, [])\n /**\n * A save finished (it lands once the workflows are re-read): the builder it came from (its\n * `builderKey`, default the current one) now edits the saved workflow. A save the person left\n * meanwhile (Back, or another workflow opened) changes nothing: it never reopens the builder.\n */\n const builderSaved = useCallback((id: string, fromKey?: number) => {\n if (fromKey !== undefined && fromKey !== builderKeyRef.current) return\n setBuilder((open) => (open ? { kind: 'saved', id } : null))\n }, [])\n\n useEffect(() => {\n const workflow = workflows.find((item) => item.external_id === historyWorkflowId)\n if (!workflow) return\n openHistory(workflow)\n onHistoryWorkflowConsumed?.()\n }, [historyWorkflowId, onHistoryWorkflowConsumed, openHistory, workflows])\n\n return {\n workflows,\n builder,\n builderKey,\n openBuilder,\n closeBuilder: () => setBuilder(null),\n builderSaved,\n historyFor,\n historyTabs,\n activeHistoryId,\n openHistory,\n closeHistoryTab,\n selectHistoryTab: setActiveHistoryId,\n }\n}\n"],
5
+ "mappings": ";AAAA,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AACzD,SAAS,oBAA2C;AAgB7C,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,IAA+B,CAAC,GAAG;AACjC,QAAM,EAAE,MAAM,YAAY,CAAC,EAAE,IAAI,aAAa,EAAE,MAAM,KAAK,CAAC;AAC5D,QAAM,CAAC,SAAS,UAAU,IAAI,SAA0C,kBAAkB,IAAI;AAC9F,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,CAAC;AAC9C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAmB,CAAC,CAAC;AACzD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAwB,IAAI;AAE1E,QAAM,aAAa,UAAU,KAAK,CAAC,aAAa,SAAS,gBAAgB,eAAe,KAAK;AAC7F,QAAM,cAAc,WAAW,QAAQ,CAAC,OAAO;AAC7C,UAAM,WAAW,UAAU,KAAK,CAAC,SAAS,KAAK,gBAAgB,EAAE;AACjE,WAAO,WAAW,CAAC,QAAQ,IAAI,CAAC;AAAA,EAClC,CAAC;AAED,QAAM,cAAc,YAAY,CAAC,aAAsC;AACrE,UAAM,KAAK,UAAU,eAAe;AACpC,QAAI,GAAI,eAAc,CAAC,QAAS,IAAI,SAAS,EAAE,IAAI,MAAM,CAAC,GAAG,KAAK,EAAE,CAAE;AACtE,uBAAmB,EAAE;AAAA,EACvB,GAAG,CAAC,CAAC;AACL,QAAM,kBAAkB,YAAY,CAAC,OAAe;AAClD,kBAAc,CAAC,QAAQ,IAAI,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC;AACxD,uBAAmB,CAAC,WAAY,WAAW,KAAK,OAAO,MAAO;AAAA,EAChE,GAAG,CAAC,CAAC;AACL,QAAM,gBAAgB,OAAO,UAAU;AACvC,gBAAc,UAAU;AACxB,QAAM,cAAc,YAAY,CAAC,cAAwC;AACvE,eAAW,SAAS;AAEpB,kBAAc,CAAC,QAAQ,MAAM,CAAC;AAAA,EAChC,GAAG,CAAC,CAAC;AAML,QAAM,eAAe,YAAY,CAAC,IAAY,YAAqB;AACjE,QAAI,YAAY,UAAa,YAAY,cAAc,QAAS;AAChE,eAAW,CAAC,SAAU,OAAO,EAAE,MAAM,SAAS,GAAG,IAAI,IAAK;AAAA,EAC5D,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,UAAM,WAAW,UAAU,KAAK,CAAC,SAAS,KAAK,gBAAgB,iBAAiB;AAChF,QAAI,CAAC,SAAU;AACf,gBAAY,QAAQ;AACpB,gCAA4B;AAAA,EAC9B,GAAG,CAAC,mBAAmB,2BAA2B,aAAa,SAAS,CAAC;AAEzE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,MAAM,WAAW,IAAI;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EACpB;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,18 +1,18 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkJ2RXQVVF_cjs = require('../chunk-J2RXQVVF.cjs');
4
+ var chunk4EK7TAP7_cjs = require('../chunk-4EK7TAP7.cjs');
5
5
  var chunkLVIQWRC5_cjs = require('../chunk-LVIQWRC5.cjs');
6
- var chunkK5MYEWD5_cjs = require('../chunk-K5MYEWD5.cjs');
6
+ var chunkUZHWXKS6_cjs = require('../chunk-UZHWXKS6.cjs');
7
7
  var chunkPBPO54KZ_cjs = require('../chunk-PBPO54KZ.cjs');
8
- require('../chunk-WIAWHETB.cjs');
8
+ require('../chunk-ULPTSXXO.cjs');
9
9
  require('../chunk-ZU2B2RZK.cjs');
10
10
  var chunkNSD37OF5_cjs = require('../chunk-NSD37OF5.cjs');
11
11
  var chunkOEJQFPWO_cjs = require('../chunk-OEJQFPWO.cjs');
12
- require('../chunk-ZFKWCGA5.cjs');
13
- var chunkZW6FPIFC_cjs = require('../chunk-ZW6FPIFC.cjs');
12
+ require('../chunk-JV5TVUOU.cjs');
14
13
  require('../chunk-IPSHAMO2.cjs');
15
- var chunkU5T46QCS_cjs = require('../chunk-U5T46QCS.cjs');
14
+ var chunkZW6FPIFC_cjs = require('../chunk-ZW6FPIFC.cjs');
15
+ var chunkTKHCIHE2_cjs = require('../chunk-TKHCIHE2.cjs');
16
16
  require('../chunk-JDFBEGQO.cjs');
17
17
  require('../chunk-ULWRNGGE.cjs');
18
18
  require('../chunk-PLIF5CUV.cjs');
@@ -67,8 +67,8 @@ function PanelsGrid({
67
67
  editing,
68
68
  testId
69
69
  }) {
70
- return /* @__PURE__ */ jsxRuntime.jsx(chunkK5MYEWD5_cjs.DashboardGrid, { testId: testId && `${testId}-grid`, children: spec.panels.map((panel, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkK5MYEWD5_cjs.DashboardCell, { width: panel.width, children: /* @__PURE__ */ jsxRuntime.jsx(
71
- chunkK5MYEWD5_cjs.DashboardPanel,
70
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkUZHWXKS6_cjs.DashboardGrid, { testId: testId && `${testId}-grid`, children: spec.panels.map((panel, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkUZHWXKS6_cjs.DashboardCell, { width: panel.width, children: /* @__PURE__ */ jsxRuntime.jsx(
71
+ chunkUZHWXKS6_cjs.DashboardPanel,
72
72
  {
73
73
  panel,
74
74
  labels: panelLabels,
@@ -167,7 +167,7 @@ function ConnectedDashboardsPage({
167
167
  testId = "dashboards"
168
168
  }) {
169
169
  const l = { ...DEFAULT_DASHBOARDS_PAGE_LABELS, ...labels };
170
- const { confirm, notify } = chunkU5T46QCS_cjs.useBlocksEnvironment();
170
+ const { confirm, notify } = chunkTKHCIHE2_cjs.useBlocksEnvironment();
171
171
  const workflowsOn = react.useFeature("workflows");
172
172
  const templates = siteTemplates ?? chunkLVIQWRC5_cjs.templatesFor(chunkLVIQWRC5_cjs.DASHBOARD_TEMPLATES, { workflows: workflowsOn });
173
173
  const store = react.useDashboardStore();
@@ -365,7 +365,7 @@ function ConnectedDashboardsPage({
365
365
  /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: l.editPanelDescription })
366
366
  ] }),
367
367
  editingPanel && /* @__PURE__ */ jsxRuntime.jsx(
368
- chunkJ2RXQVVF_cjs.PanelEditor,
368
+ chunk4EK7TAP7_cjs.PanelEditor,
369
369
  {
370
370
  value: editingPanel.panel,
371
371
  onChange: (panel) => setEditingPanel({ ...editingPanel, panel }),
@@ -527,11 +527,11 @@ function ConnectedDashboardsPage({
527
527
 
528
528
  Object.defineProperty(exports, "DEFAULT_PANEL_EDITOR_LABELS", {
529
529
  enumerable: true,
530
- get: function () { return chunkJ2RXQVVF_cjs.DEFAULT_PANEL_EDITOR_LABELS; }
530
+ get: function () { return chunk4EK7TAP7_cjs.DEFAULT_PANEL_EDITOR_LABELS; }
531
531
  });
532
532
  Object.defineProperty(exports, "PanelEditor", {
533
533
  enumerable: true,
534
- get: function () { return chunkJ2RXQVVF_cjs.PanelEditor; }
534
+ get: function () { return chunk4EK7TAP7_cjs.PanelEditor; }
535
535
  });
536
536
  Object.defineProperty(exports, "DASHBOARD_TEMPLATES", {
537
537
  enumerable: true,
@@ -555,47 +555,47 @@ Object.defineProperty(exports, "usagePanels", {
555
555
  });
556
556
  Object.defineProperty(exports, "ChartRenderer", {
557
557
  enumerable: true,
558
- get: function () { return chunkK5MYEWD5_cjs.ChartRenderer; }
558
+ get: function () { return chunkUZHWXKS6_cjs.ChartRenderer; }
559
559
  });
560
560
  Object.defineProperty(exports, "ChartTable", {
561
561
  enumerable: true,
562
- get: function () { return chunkK5MYEWD5_cjs.ChartTable; }
562
+ get: function () { return chunkUZHWXKS6_cjs.ChartTable; }
563
563
  });
564
564
  Object.defineProperty(exports, "DEFAULT_CHART_RENDERER_LABELS", {
565
565
  enumerable: true,
566
- get: function () { return chunkK5MYEWD5_cjs.DEFAULT_CHART_RENDERER_LABELS; }
566
+ get: function () { return chunkUZHWXKS6_cjs.DEFAULT_CHART_RENDERER_LABELS; }
567
567
  });
568
568
  Object.defineProperty(exports, "DEFAULT_DASHBOARD_PANEL_LABELS", {
569
569
  enumerable: true,
570
- get: function () { return chunkK5MYEWD5_cjs.DEFAULT_DASHBOARD_PANEL_LABELS; }
570
+ get: function () { return chunkUZHWXKS6_cjs.DEFAULT_DASHBOARD_PANEL_LABELS; }
571
571
  });
572
572
  Object.defineProperty(exports, "DEFAULT_PANEL_VIEW_LABELS", {
573
573
  enumerable: true,
574
- get: function () { return chunkK5MYEWD5_cjs.DEFAULT_PANEL_VIEW_LABELS; }
574
+ get: function () { return chunkUZHWXKS6_cjs.DEFAULT_PANEL_VIEW_LABELS; }
575
575
  });
576
576
  Object.defineProperty(exports, "DashboardCell", {
577
577
  enumerable: true,
578
- get: function () { return chunkK5MYEWD5_cjs.DashboardCell; }
578
+ get: function () { return chunkUZHWXKS6_cjs.DashboardCell; }
579
579
  });
580
580
  Object.defineProperty(exports, "DashboardGrid", {
581
581
  enumerable: true,
582
- get: function () { return chunkK5MYEWD5_cjs.DashboardGrid; }
582
+ get: function () { return chunkUZHWXKS6_cjs.DashboardGrid; }
583
583
  });
584
584
  Object.defineProperty(exports, "DashboardPanel", {
585
585
  enumerable: true,
586
- get: function () { return chunkK5MYEWD5_cjs.DashboardPanel; }
586
+ get: function () { return chunkUZHWXKS6_cjs.DashboardPanel; }
587
587
  });
588
588
  Object.defineProperty(exports, "PANEL_FORMATTERS", {
589
589
  enumerable: true,
590
- get: function () { return chunkK5MYEWD5_cjs.PANEL_FORMATTERS; }
590
+ get: function () { return chunkUZHWXKS6_cjs.PANEL_FORMATTERS; }
591
591
  });
592
592
  Object.defineProperty(exports, "PanelView", {
593
593
  enumerable: true,
594
- get: function () { return chunkK5MYEWD5_cjs.PanelView; }
594
+ get: function () { return chunkUZHWXKS6_cjs.PanelView; }
595
595
  });
596
596
  Object.defineProperty(exports, "clampPanelWidth", {
597
597
  enumerable: true,
598
- get: function () { return chunkK5MYEWD5_cjs.clampPanelWidth; }
598
+ get: function () { return chunkUZHWXKS6_cjs.clampPanelWidth; }
599
599
  });
600
600
  Object.defineProperty(exports, "DEFAULT_UNIT_FORMATTERS", {
601
601
  enumerable: true,