hazo_collab_forms 3.0.14 → 3.0.18

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 (203) hide show
  1. package/CHANGE_LOG.md +65 -0
  2. package/README.md +5 -38
  3. package/dist/components/clarification/clarification_card.d.ts +2 -0
  4. package/dist/components/clarification/clarification_card.d.ts.map +1 -1
  5. package/dist/components/clarification/clarification_card.js +13 -4
  6. package/dist/components/clarification/clarification_card.js.map +1 -1
  7. package/dist/components/clarification/clarification_doc_reference.js +1 -1
  8. package/dist/components/clarification/clarification_doc_reference.js.map +1 -1
  9. package/dist/components/clarification/clarification_group_card.d.ts +2 -0
  10. package/dist/components/clarification/clarification_group_card.d.ts.map +1 -1
  11. package/dist/components/clarification/clarification_group_card.js +2 -2
  12. package/dist/components/clarification/clarification_group_card.js.map +1 -1
  13. package/dist/components/clarification/clarification_item_body.d.ts +2 -0
  14. package/dist/components/clarification/clarification_item_body.d.ts.map +1 -1
  15. package/dist/components/clarification/clarification_item_body.js +7 -2
  16. package/dist/components/clarification/clarification_item_body.js.map +1 -1
  17. package/dist/components/clarification/clarification_response_form.d.ts +2 -0
  18. package/dist/components/clarification/clarification_response_form.d.ts.map +1 -1
  19. package/dist/components/clarification/clarification_response_form.js +2 -2
  20. package/dist/components/clarification/clarification_response_form.js.map +1 -1
  21. package/dist/components/clarification/clarification_section.d.ts +2 -0
  22. package/dist/components/clarification/clarification_section.d.ts.map +1 -1
  23. package/dist/components/clarification/clarification_section.js +2 -2
  24. package/dist/components/clarification/clarification_section.js.map +1 -1
  25. package/dist/components/clarification/clarification_thread.d.ts +19 -0
  26. package/dist/components/clarification/clarification_thread.d.ts.map +1 -0
  27. package/dist/components/clarification/clarification_thread.js +94 -0
  28. package/dist/components/clarification/clarification_thread.js.map +1 -0
  29. package/dist/components/collab_form_file_upload.js +1 -2
  30. package/dist/components/collab_form_file_upload.js.map +1 -1
  31. package/dist/components/data_ok_multi_state.d.ts.map +1 -1
  32. package/dist/components/data_ok_multi_state.js +1 -2
  33. package/dist/components/data_ok_multi_state.js.map +1 -1
  34. package/dist/components/hazo_collab_form_base.d.ts.map +1 -1
  35. package/dist/components/hazo_collab_form_base.js +6 -8
  36. package/dist/components/hazo_collab_form_base.js.map +1 -1
  37. package/dist/components/hazo_collab_form_combo.d.ts.map +1 -1
  38. package/dist/components/hazo_collab_form_combo.js +8 -10
  39. package/dist/components/hazo_collab_form_combo.js.map +1 -1
  40. package/dist/components/hazo_collab_form_data_table.d.ts.map +1 -1
  41. package/dist/components/hazo_collab_form_data_table.js +7 -4
  42. package/dist/components/hazo_collab_form_data_table.js.map +1 -1
  43. package/dist/components/hazo_collab_form_date.d.ts.map +1 -1
  44. package/dist/components/hazo_collab_form_date.js +3 -6
  45. package/dist/components/hazo_collab_form_date.js.map +1 -1
  46. package/dist/components/hazo_collab_form_file_textbox/validation_dialog.d.ts.map +1 -1
  47. package/dist/components/hazo_collab_form_file_textbox/validation_dialog.js +1 -1
  48. package/dist/components/hazo_collab_form_file_textbox/validation_dialog.js.map +1 -1
  49. package/dist/components/hazo_fb_form/components/draft_clarification_card.d.ts.map +1 -1
  50. package/dist/components/hazo_fb_form/components/draft_clarification_card.js +19 -11
  51. package/dist/components/hazo_fb_form/components/draft_clarification_card.js.map +1 -1
  52. package/dist/components/hazo_fb_form/components/reject_clarification_dialog.d.ts +15 -0
  53. package/dist/components/hazo_fb_form/components/reject_clarification_dialog.d.ts.map +1 -0
  54. package/dist/components/hazo_fb_form/components/reject_clarification_dialog.js +26 -0
  55. package/dist/components/hazo_fb_form/components/reject_clarification_dialog.js.map +1 -0
  56. package/dist/components/hazo_fb_form/components/run_details_dialog.d.ts.map +1 -1
  57. package/dist/components/hazo_fb_form/components/run_details_dialog.js +4 -4
  58. package/dist/components/hazo_fb_form/components/run_details_dialog.js.map +1 -1
  59. package/dist/components/hazo_fb_form/components/sent_clarification_group.d.ts +2 -1
  60. package/dist/components/hazo_fb_form/components/sent_clarification_group.d.ts.map +1 -1
  61. package/dist/components/hazo_fb_form/components/sent_clarification_group.js +2 -2
  62. package/dist/components/hazo_fb_form/components/sent_clarification_group.js.map +1 -1
  63. package/dist/components/hazo_fb_form/context.d.ts +39 -2
  64. package/dist/components/hazo_fb_form/context.d.ts.map +1 -1
  65. package/dist/components/hazo_fb_form/context.js.map +1 -1
  66. package/dist/components/hazo_fb_form/hazo_fb_form.d.ts.map +1 -1
  67. package/dist/components/hazo_fb_form/hazo_fb_form.js +331 -65
  68. package/dist/components/hazo_fb_form/hazo_fb_form.js.map +1 -1
  69. package/dist/components/hazo_fb_form/hooks/use_fb_form_state.d.ts +14 -3
  70. package/dist/components/hazo_fb_form/hooks/use_fb_form_state.d.ts.map +1 -1
  71. package/dist/components/hazo_fb_form/hooks/use_fb_form_state.js +311 -5
  72. package/dist/components/hazo_fb_form/hooks/use_fb_form_state.js.map +1 -1
  73. package/dist/components/hazo_fb_form/hooks/use_llm_run.d.ts.map +1 -1
  74. package/dist/components/hazo_fb_form/hooks/use_llm_run.js +252 -50
  75. package/dist/components/hazo_fb_form/hooks/use_llm_run.js.map +1 -1
  76. package/dist/components/hazo_fb_form/index.d.ts +5 -0
  77. package/dist/components/hazo_fb_form/index.d.ts.map +1 -1
  78. package/dist/components/hazo_fb_form/index.js +3 -0
  79. package/dist/components/hazo_fb_form/index.js.map +1 -1
  80. package/dist/components/hazo_fb_form/shared/agent_stepper.d.ts +9 -0
  81. package/dist/components/hazo_fb_form/shared/agent_stepper.d.ts.map +1 -0
  82. package/dist/components/hazo_fb_form/shared/agent_stepper.js +17 -0
  83. package/dist/components/hazo_fb_form/shared/agent_stepper.js.map +1 -0
  84. package/dist/components/hazo_fb_form/shared/format.d.ts +3 -0
  85. package/dist/components/hazo_fb_form/shared/format.d.ts.map +1 -1
  86. package/dist/components/hazo_fb_form/shared/format.js +16 -0
  87. package/dist/components/hazo_fb_form/shared/format.js.map +1 -1
  88. package/dist/components/hazo_fb_form/shared/group_debug_icon.d.ts +15 -0
  89. package/dist/components/hazo_fb_form/shared/group_debug_icon.d.ts.map +1 -0
  90. package/dist/components/hazo_fb_form/shared/group_debug_icon.js +48 -0
  91. package/dist/components/hazo_fb_form/shared/group_debug_icon.js.map +1 -0
  92. package/dist/components/hazo_fb_form/shared/pdf_side_panel.js +1 -1
  93. package/dist/components/hazo_fb_form/shared/pdf_side_panel.js.map +1 -1
  94. package/dist/components/hazo_fb_form/shared/send_back_item_card.d.ts +31 -0
  95. package/dist/components/hazo_fb_form/shared/send_back_item_card.d.ts.map +1 -0
  96. package/dist/components/hazo_fb_form/shared/send_back_item_card.js +41 -0
  97. package/dist/components/hazo_fb_form/shared/send_back_item_card.js.map +1 -0
  98. package/dist/components/hazo_fb_form/types.d.ts +47 -4
  99. package/dist/components/hazo_fb_form/types.d.ts.map +1 -1
  100. package/dist/components/hazo_fb_form/views/back_office_view.d.ts.map +1 -1
  101. package/dist/components/hazo_fb_form/views/back_office_view.js +69 -18
  102. package/dist/components/hazo_fb_form/views/back_office_view.js.map +1 -1
  103. package/dist/components/hazo_fb_form/views/clarifications_view.d.ts.map +1 -1
  104. package/dist/components/hazo_fb_form/views/clarifications_view.js +18 -7
  105. package/dist/components/hazo_fb_form/views/clarifications_view.js.map +1 -1
  106. package/dist/components/hazo_fb_form/views/client_data_view.d.ts.map +1 -1
  107. package/dist/components/hazo_fb_form/views/client_data_view.js +5 -2
  108. package/dist/components/hazo_fb_form/views/client_data_view.js.map +1 -1
  109. package/dist/components/hazo_fb_form/views/front_office_view.d.ts.map +1 -1
  110. package/dist/components/hazo_fb_form/views/front_office_view.js +121 -41
  111. package/dist/components/hazo_fb_form/views/front_office_view.js.map +1 -1
  112. package/dist/components/hazo_fb_form/views/interim_view.d.ts.map +1 -1
  113. package/dist/components/hazo_fb_form/views/interim_view.js +174 -55
  114. package/dist/components/hazo_fb_form/views/interim_view.js.map +1 -1
  115. package/dist/components/hazo_fb_form/views/review_queue_view.d.ts +14 -0
  116. package/dist/components/hazo_fb_form/views/review_queue_view.d.ts.map +1 -0
  117. package/dist/components/hazo_fb_form/views/review_queue_view.js +162 -0
  118. package/dist/components/hazo_fb_form/views/review_queue_view.js.map +1 -0
  119. package/dist/components/hazo_fb_form/views/send_back_view.d.ts +13 -0
  120. package/dist/components/hazo_fb_form/views/send_back_view.d.ts.map +1 -0
  121. package/dist/components/hazo_fb_form/views/send_back_view.js +203 -0
  122. package/dist/components/hazo_fb_form/views/send_back_view.js.map +1 -0
  123. package/dist/components/hazo_fb_form/views/summary_review_view.d.ts +3 -1
  124. package/dist/components/hazo_fb_form/views/summary_review_view.d.ts.map +1 -1
  125. package/dist/components/hazo_fb_form/views/summary_review_view.js +75 -14
  126. package/dist/components/hazo_fb_form/views/summary_review_view.js.map +1 -1
  127. package/dist/components/hazo_field_selector_dialog/components/field_autocomplete.d.ts.map +1 -1
  128. package/dist/components/hazo_field_selector_dialog/components/field_autocomplete.js +7 -8
  129. package/dist/components/hazo_field_selector_dialog/components/field_autocomplete.js.map +1 -1
  130. package/dist/components/hazo_field_selector_dialog/components/sortable_field_item.d.ts.map +1 -1
  131. package/dist/components/hazo_field_selector_dialog/components/sortable_field_item.js +1 -2
  132. package/dist/components/hazo_field_selector_dialog/components/sortable_field_item.js.map +1 -1
  133. package/dist/components/hazo_template_generator/types.d.ts.map +1 -1
  134. package/dist/components/hazo_template_generator/types.js +1 -0
  135. package/dist/components/hazo_template_generator/types.js.map +1 -1
  136. package/dist/components/hazo_validation_rule_editor/components/rule_editor.js +1 -1
  137. package/dist/components/hazo_validation_rule_editor/components/rule_editor.js.map +1 -1
  138. package/dist/components/index.d.ts +2 -2
  139. package/dist/components/index.d.ts.map +1 -1
  140. package/dist/components/index.js +1 -1
  141. package/dist/components/index.js.map +1 -1
  142. package/dist/components/multi_state_radio.d.ts.map +1 -1
  143. package/dist/components/multi_state_radio.js +1 -2
  144. package/dist/components/multi_state_radio.js.map +1 -1
  145. package/dist/components/shared/field_tooltip/field_tooltip.d.ts.map +1 -1
  146. package/dist/components/shared/field_tooltip/field_tooltip.js +1 -2
  147. package/dist/components/shared/field_tooltip/field_tooltip.js.map +1 -1
  148. package/dist/components/shared/file_bar/file_bar.d.ts +12 -2
  149. package/dist/components/shared/file_bar/file_bar.d.ts.map +1 -1
  150. package/dist/components/shared/file_bar/file_bar.js +8 -9
  151. package/dist/components/shared/file_bar/file_bar.js.map +1 -1
  152. package/dist/components/shared/file_bar/file_bar_validation.d.ts +1 -1
  153. package/dist/components/shared/file_bar/file_bar_validation.d.ts.map +1 -1
  154. package/dist/components/shared/file_bar/file_bar_validation.js +9 -0
  155. package/dist/components/shared/file_bar/file_bar_validation.js.map +1 -1
  156. package/dist/components/shared/file_bar/file_bar_validation_dialog.d.ts +16 -1
  157. package/dist/components/shared/file_bar/file_bar_validation_dialog.d.ts.map +1 -1
  158. package/dist/components/shared/file_bar/file_bar_validation_dialog.js +31 -26
  159. package/dist/components/shared/file_bar/file_bar_validation_dialog.js.map +1 -1
  160. package/dist/components/shared/file_bar/file_validation_issues_dialog.d.ts +3 -1
  161. package/dist/components/shared/file_bar/file_validation_issues_dialog.d.ts.map +1 -1
  162. package/dist/components/shared/file_bar/file_validation_issues_dialog.js +2 -2
  163. package/dist/components/shared/file_bar/file_validation_issues_dialog.js.map +1 -1
  164. package/dist/components/shared/role_utils/role_utils.d.ts +1 -0
  165. package/dist/components/shared/role_utils/role_utils.d.ts.map +1 -1
  166. package/dist/components/shared/role_utils/role_utils.js +3 -0
  167. package/dist/components/shared/role_utils/role_utils.js.map +1 -1
  168. package/dist/components/shared/rule_result_card.d.ts +31 -0
  169. package/dist/components/shared/rule_result_card.d.ts.map +1 -0
  170. package/dist/components/shared/rule_result_card.js +72 -0
  171. package/dist/components/shared/rule_result_card.js.map +1 -0
  172. package/dist/components/shared/unified_field_controls/constants.d.ts.map +1 -1
  173. package/dist/components/shared/unified_field_controls/constants.js +1 -0
  174. package/dist/components/shared/unified_field_controls/constants.js.map +1 -1
  175. package/dist/components/shared/unified_field_controls/resolve_field_controls.d.ts +2 -0
  176. package/dist/components/shared/unified_field_controls/resolve_field_controls.d.ts.map +1 -1
  177. package/dist/components/shared/unified_field_controls/resolve_field_controls.js +4 -0
  178. package/dist/components/shared/unified_field_controls/resolve_field_controls.js.map +1 -1
  179. package/dist/components/shared/unified_field_controls/types.d.ts +5 -0
  180. package/dist/components/shared/unified_field_controls/types.d.ts.map +1 -1
  181. package/dist/components/shared/unified_field_controls/unified_field_controls.d.ts.map +1 -1
  182. package/dist/components/shared/unified_field_controls/unified_field_controls.js +13 -2
  183. package/dist/components/shared/unified_field_controls/unified_field_controls.js.map +1 -1
  184. package/dist/components/shared/use_base_form_field.d.ts +2 -0
  185. package/dist/components/shared/use_base_form_field.d.ts.map +1 -1
  186. package/dist/components/shared/use_base_form_field.js +4 -0
  187. package/dist/components/shared/use_base_form_field.js.map +1 -1
  188. package/dist/lib/autofill_handler.d.ts +5 -0
  189. package/dist/lib/autofill_handler.d.ts.map +1 -1
  190. package/dist/lib/autofill_handler.js +27 -10
  191. package/dist/lib/autofill_handler.js.map +1 -1
  192. package/dist/lib/fb_form_handler.d.ts.map +1 -1
  193. package/dist/lib/fb_form_handler.js +45 -0
  194. package/dist/lib/fb_form_handler.js.map +1 -1
  195. package/dist/types/clarification.d.ts +22 -1
  196. package/dist/types/clarification.d.ts.map +1 -1
  197. package/dist/types/icons_behaviour.d.ts +1 -1
  198. package/dist/types/icons_behaviour.d.ts.map +1 -1
  199. package/dist/types/icons_behaviour.js +3 -1
  200. package/dist/types/icons_behaviour.js.map +1 -1
  201. package/dist/types/validation.d.ts +6 -0
  202. package/dist/types/validation.d.ts.map +1 -1
  203. package/package.json +4 -8
@@ -21,6 +21,9 @@ import { RunDetailsDialog } from './components/run_details_dialog.js';
21
21
  import { BackofficeRunButton } from './components/backoffice_run_button.js';
22
22
  import { InstanceSidebar } from './components/instance_sidebar.js';
23
23
  import { register_ihelp_icon } from '../shared/ihelp_icon.js';
24
+ import { AgentStepper } from './shared/agent_stepper.js';
25
+ import { ReviewQueueView } from './views/review_queue_view.js';
26
+ import { SendBackView } from './views/send_back_view.js';
24
27
  export const VIRTUAL_INSTANCE_ID = '__single__';
25
28
  export function HazoFbForm(props) {
26
29
  const logger = use_logger();
@@ -58,31 +61,9 @@ export function HazoFbForm(props) {
58
61
  classification_results: active_instance.classification_results ?? props.classification_results,
59
62
  };
60
63
  }, [props, is_multi_instance, active_instance]);
61
- const state = use_fb_form_state(effective_props, active_instance_id, active_instance);
62
- // Log mount and key prop changes
63
- useEffect(() => {
64
- logger.info('[HazoFbForm] mounted', {
65
- is_multi_instance,
66
- instance_count: instances.length,
67
- active_instance_id,
68
- user_role: props.user_role,
69
- has_llm_endpoint: !!props.llm_api_endpoint,
70
- has_validation_endpoint: !!props.validation_api_endpoint,
71
- has_file_manager: !!props.file_manager,
72
- front_section_count: props.front_sections?.length ?? 0,
73
- back_section_count: props.back_sections?.length ?? 0,
74
- });
75
- }, []);
76
- useEffect(() => {
77
- if (is_multi_instance) {
78
- logger.info('[HazoFbForm] instance_switched', {
79
- active_instance_id,
80
- instance_status: active_instance?.status,
81
- });
82
- }
83
- }, [active_instance_id]);
84
- // Pending clarification responses — declared before use_llm_run so it can read them via ref
64
+ // Pending clarification responses — declared before use_fb_form_state and use_llm_run so both can access them
85
65
  const [pending_clarification_responses, set_pending_clarification_responses] = useState(new Map());
66
+ const state = use_fb_form_state(effective_props, active_instance_id, active_instance, pending_clarification_responses);
86
67
  const { trigger_run, trigger_complete, trigger_classify_file, trigger_assign_file, route_skipped_files, trigger_backoffice_run } = use_llm_run({
87
68
  props: effective_props,
88
69
  update_progress: state.update_progress,
@@ -189,10 +170,24 @@ export function HazoFbForm(props) {
189
170
  }, [props, is_multi_instance, active_instance, active_instance_id]);
190
171
  const update_clarification_status = useCallback((id, updates) => {
191
172
  logger.debug('[HazoFbForm] update_clarification_status', { id, status: updates.status, instance_id: active_instance_id });
173
+ const now = new Date().toISOString();
192
174
  if (is_multi_instance && active_instance) {
193
175
  // Per-instance: update within active instance's sent_clarifications
194
176
  const existing = active_instance.sent_clarifications ?? [];
195
- const updated = existing.map((item) => item.id === id ? { ...item, ...updates, updated_at: new Date().toISOString() } : item);
177
+ let found = false;
178
+ const updated = existing.map((item) => {
179
+ if (item.id === id) {
180
+ found = true;
181
+ return { ...item, ...updates, updated_at: now };
182
+ }
183
+ return item;
184
+ });
185
+ // Upsert: if item wasn't in sent_clarifications (e.g. validation draft), add it
186
+ if (!found) {
187
+ const draft = state.draft_clarifications.find((d) => d.id === id);
188
+ if (draft)
189
+ updated.push({ ...draft, ...updates, updated_at: now });
190
+ }
196
191
  props.on_instance_update?.(active_instance_id, { sent_clarifications: updated });
197
192
  }
198
193
  else {
@@ -200,60 +195,109 @@ export function HazoFbForm(props) {
200
195
  const existing = Array.isArray(props.back_form_data?.['__clarifications'])
201
196
  ? props.back_form_data['__clarifications']
202
197
  : [];
203
- const updated = existing.map((item) => item.id === id ? { ...item, ...updates, updated_at: new Date().toISOString() } : item);
198
+ let found = false;
199
+ const updated = existing.map((item) => {
200
+ if (item.id === id) {
201
+ found = true;
202
+ return { ...item, ...updates, updated_at: now };
203
+ }
204
+ return item;
205
+ });
206
+ if (!found) {
207
+ const draft = state.draft_clarifications.find((d) => d.id === id);
208
+ if (draft)
209
+ updated.push({ ...draft, ...updates, updated_at: now });
210
+ }
204
211
  props.on_back_change?.('__clarifications', updated);
205
212
  }
206
- }, [props, is_multi_instance, active_instance, active_instance_id]);
213
+ }, [props, is_multi_instance, active_instance, active_instance_id, state.draft_clarifications]);
207
214
  const update_clarification_response = useCallback((id, response) => {
208
- update_clarification_status(id, {
215
+ // If the clarification has a thread (resent item), append the client's new response to it
216
+ const all_items = [
217
+ ...(is_multi_instance ? (active_instance?.sent_clarifications ?? []) : []),
218
+ ...(Array.isArray(props.back_form_data?.['__clarifications'])
219
+ ? props.back_form_data['__clarifications']
220
+ : []),
221
+ ];
222
+ const existing_item = all_items.find(c => c.id === id);
223
+ const has_thread = existing_item?.thread && existing_item.thread.length > 0;
224
+ const updates = {
209
225
  status: 'responded',
210
226
  response_choice: response.response_choice,
211
227
  user_comment: response.user_comment,
212
228
  response_files: response.response_files ?? [],
213
- });
214
- }, [update_clarification_status]);
229
+ };
230
+ // Append client response to thread history
231
+ if (has_thread && response.response_choice) {
232
+ const now = new Date().toISOString();
233
+ updates.thread = [
234
+ ...(existing_item.thread ?? []),
235
+ {
236
+ role: 'client',
237
+ action: 'responded',
238
+ response_choice: response.response_choice,
239
+ message: response.user_comment || undefined,
240
+ timestamp: now,
241
+ },
242
+ ];
243
+ }
244
+ update_clarification_status(id, updates);
245
+ }, [update_clarification_status, is_multi_instance, active_instance, props.back_form_data]);
215
246
  /** Batch-update multiple responses in a single write to avoid stale-state overwrites */
216
247
  const batch_update_clarification_responses = useCallback((responses) => {
217
248
  if (responses.size === 0)
218
249
  return;
219
250
  const now = new Date().toISOString();
251
+ const apply_response = (item, response) => ({
252
+ ...item,
253
+ status: 'responded',
254
+ response_choice: response.response_choice,
255
+ user_comment: response.user_comment,
256
+ response_files: response.response_files ?? [],
257
+ updated_at: now,
258
+ });
220
259
  if (is_multi_instance && active_instance) {
221
260
  const existing = active_instance.sent_clarifications ?? [];
261
+ const matched_ids = new Set();
222
262
  const updated = existing.map((item) => {
223
263
  const response = responses.get(item.id);
224
264
  if (!response)
225
265
  return item;
226
- return {
227
- ...item,
228
- status: 'responded',
229
- response_choice: response.response_choice,
230
- user_comment: response.user_comment,
231
- response_files: response.response_files ?? [],
232
- updated_at: now,
233
- };
266
+ matched_ids.add(item.id);
267
+ return apply_response(item, response);
234
268
  });
269
+ // Upsert: append draft items that weren't in sent_clarifications
270
+ for (const [id, response] of responses) {
271
+ if (matched_ids.has(id))
272
+ continue;
273
+ const draft = state.draft_clarifications.find((d) => d.id === id);
274
+ if (draft)
275
+ updated.push(apply_response(draft, response));
276
+ }
235
277
  props.on_instance_update?.(active_instance_id, { sent_clarifications: updated });
236
278
  }
237
279
  else {
238
280
  const existing = Array.isArray(props.back_form_data?.['__clarifications'])
239
281
  ? props.back_form_data['__clarifications']
240
282
  : [];
283
+ const matched_ids = new Set();
241
284
  const updated = existing.map((item) => {
242
285
  const response = responses.get(item.id);
243
286
  if (!response)
244
287
  return item;
245
- return {
246
- ...item,
247
- status: 'responded',
248
- response_choice: response.response_choice,
249
- user_comment: response.user_comment,
250
- response_files: response.response_files ?? [],
251
- updated_at: now,
252
- };
288
+ matched_ids.add(item.id);
289
+ return apply_response(item, response);
253
290
  });
291
+ for (const [id, response] of responses) {
292
+ if (matched_ids.has(id))
293
+ continue;
294
+ const draft = state.draft_clarifications.find((d) => d.id === id);
295
+ if (draft)
296
+ updated.push(apply_response(draft, response));
297
+ }
254
298
  props.on_back_change?.('__clarifications', updated);
255
299
  }
256
- }, [props, is_multi_instance, active_instance, active_instance_id]);
300
+ }, [props, is_multi_instance, active_instance, active_instance_id, state.draft_clarifications]);
257
301
  const resolve_clarification = useCallback((id) => {
258
302
  update_clarification_status(id, { status: 'resolved' });
259
303
  }, [update_clarification_status]);
@@ -287,7 +331,7 @@ export function HazoFbForm(props) {
287
331
  return new_instance;
288
332
  }, [props.on_instance_create, set_active_instance]);
289
333
  // ── Prepare for client: move clarifications to target instance ──
290
- const prepare_for_client = useCallback(async (clarification_ids) => {
334
+ const prepare_for_client = useCallback(async (clarification_ids, sent_items) => {
291
335
  logger.info('[HazoFbForm] prepare_for_client', { clarification_count: clarification_ids.length, source_instance: active_instance_id });
292
336
  if (clarification_ids.length === 0)
293
337
  return;
@@ -307,15 +351,180 @@ export function HazoFbForm(props) {
307
351
  }
308
352
  }
309
353
  if (target_id) {
310
- props.on_prepare_for_client?.(clarification_ids, target_id);
311
- // Mark source instance as completed (read-only) after preparing clarifications
312
354
  if (is_multi_instance) {
313
- props.on_instance_update?.(active_instance_id, { status: 'completed' });
355
+ const existing = active_instance?.sent_clarifications ?? [];
356
+ // Merge: start with existing, replacing any items that appear in sent_items (which have cleared response data)
357
+ const sent_items_map = new Map((sent_items ?? []).map(item => [item.id, item]));
358
+ const merged = existing.map(e => sent_items_map.get(e.id) ?? e);
359
+ // Add any new sent_items not already in existing
360
+ if (sent_items) {
361
+ for (const item of sent_items) {
362
+ if (!merged.find(e => e.id === item.id))
363
+ merged.push(item);
364
+ }
365
+ }
366
+ // Step 1: Write items with status: 'pending' so consuming app can read them for forwarding
367
+ props.on_instance_update?.(active_instance_id, { sent_clarifications: merged });
368
+ // Step 2: Forward cleared items directly to the target instance
369
+ // Pass sent_items (which have response_choice/user_comment cleared) so consuming app
370
+ // doesn't need to read from state (avoids stale data from React state batching)
371
+ props.on_prepare_for_client?.(clarification_ids, target_id, sent_items);
372
+ // Step 3: Clear pending_clarification_responses for forwarded IDs
373
+ // This prevents stale responses from Instance 1 polluting Instance 2's view
374
+ set_pending_clarification_responses(prev => {
375
+ const next = new Map(prev);
376
+ for (const id of clarification_ids)
377
+ next.delete(id);
378
+ return next.size === prev.size ? prev : next;
379
+ });
380
+ // Step 4: Mark forwarded items as resolved on source and complete the instance
381
+ const forwarded_set = new Set(clarification_ids);
382
+ const now = new Date().toISOString();
383
+ const resolved = merged.map((item) => forwarded_set.has(item.id) ? { ...item, status: 'resolved', updated_at: now } : item);
384
+ props.on_instance_update?.(active_instance_id, { sent_clarifications: resolved, status: 'completed' });
385
+ }
386
+ else {
387
+ props.on_prepare_for_client?.(clarification_ids, target_id);
314
388
  }
315
389
  }
316
390
  // Remove sent items from drafts
317
391
  state.set_draft_clarifications((prev) => prev.filter((d) => !clarification_ids.includes(d.id)));
318
- }, [is_multi_instance, instances, active_instance_id, props, state.set_draft_clarifications]);
392
+ }, [is_multi_instance, instances, active_instance, active_instance_id, props, state.set_draft_clarifications]);
393
+ // ── Reject & send back ──
394
+ const reject_clarification = useCallback((id, reason) => {
395
+ logger.info('[HazoFbForm] reject_clarification', { id, reason, instance_id: active_instance_id });
396
+ // Find the clarification item from sent or draft clarifications
397
+ const all_items = [
398
+ ...(is_multi_instance ? (active_instance?.sent_clarifications ?? []) : []),
399
+ ...(Array.isArray(props.back_form_data?.['__clarifications'])
400
+ ? props.back_form_data['__clarifications']
401
+ : []),
402
+ ...state.draft_clarifications,
403
+ ];
404
+ const item = all_items.find((c) => c.id === id);
405
+ if (!item) {
406
+ logger.warn('[HazoFbForm] reject_clarification: item not found', { id });
407
+ return;
408
+ }
409
+ // Build thread from existing data if not present
410
+ const now = new Date().toISOString();
411
+ const existing_thread = item.thread ?? [
412
+ { role: 'system', action: 'created', message: item.issue_description, timestamp: item.created_at },
413
+ ...(item.response_choice ? [{
414
+ role: 'client',
415
+ action: 'responded',
416
+ response_choice: item.response_choice,
417
+ message: item.user_comment,
418
+ files: item.response_files?.length ? item.response_files : undefined,
419
+ timestamp: item.updated_at ?? now,
420
+ }] : []),
421
+ ];
422
+ // Append author rejection entry
423
+ const thread = [
424
+ ...existing_thread,
425
+ {
426
+ role: 'author',
427
+ action: 'rejected',
428
+ message: reason,
429
+ timestamp: now,
430
+ actor_name: props.current_user?.name,
431
+ },
432
+ ];
433
+ // Update the clarification: reset response, set pending, attach thread
434
+ const updates = {
435
+ status: 'pending',
436
+ response_choice: undefined,
437
+ user_comment: undefined,
438
+ response_files: [],
439
+ thread,
440
+ updated_at: now,
441
+ };
442
+ // Write updated item back
443
+ if (is_multi_instance && active_instance) {
444
+ const existing = active_instance.sent_clarifications ?? [];
445
+ const updated = existing.map((c) => c.id === id ? { ...c, ...updates } : c);
446
+ props.on_instance_update?.(active_instance_id, { sent_clarifications: updated });
447
+ }
448
+ else {
449
+ const existing = Array.isArray(props.back_form_data?.['__clarifications'])
450
+ ? props.back_form_data['__clarifications']
451
+ : [];
452
+ const updated = existing.map((c) => c.id === id ? { ...c, ...updates } : c);
453
+ props.on_back_change?.('__clarifications', updated);
454
+ }
455
+ // Forward to new instance via prepare_for_client
456
+ const updated_item = { ...item, ...updates };
457
+ prepare_for_client([id], [updated_item]);
458
+ }, [props, is_multi_instance, active_instance, active_instance_id, prepare_for_client, state.draft_clarifications]);
459
+ // ── Override resolved validation — create draft clarification (pre-approved) ──
460
+ const create_validation_clarification = useCallback((rule, file, message) => {
461
+ logger.info('[HazoFbForm] create_validation_clarification', { rule_id: rule.rule_id, file_id: file.file_id });
462
+ const now = new Date().toISOString();
463
+ const id = `clr_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
464
+ const new_item = {
465
+ id,
466
+ type: 'validation_override',
467
+ status: 'pending',
468
+ target_field_id: '',
469
+ target_label: '',
470
+ rule_id: rule.rule_id,
471
+ rule_name: rule.rule_name,
472
+ issue_description: message,
473
+ validation_details: rule.issue_description ?? rule.raw_response ?? '',
474
+ doc_references: [{
475
+ file_id: file.file_id,
476
+ file_name: file.file_name,
477
+ mime_type: 'application/pdf',
478
+ comment: file.classification,
479
+ }],
480
+ response_options: [
481
+ { value: 'upload_corrected', label: 'Upload corrected document', shows_file_upload: true },
482
+ { value: 'provide_comment', label: 'Provide comment', shows_additional_input: true },
483
+ ],
484
+ response_files: [],
485
+ created_at: now,
486
+ created_by: props.current_user?.id ?? props.current_user?.name,
487
+ };
488
+ // Add as draft clarification (not sent yet)
489
+ state.set_draft_clarifications((prev) => [...prev, new_item]);
490
+ // Pre-set review decision to 'approve'
491
+ state.set_review_decisions((prev) => {
492
+ const next = new Map(prev);
493
+ next.set(id, 'approve');
494
+ return next;
495
+ });
496
+ // Mark the rule as sent_back in validation results (prevents re-sending + changes badge)
497
+ const vr_copy = { ...state.file_validation_results };
498
+ const file_vr = vr_copy[file.file_id];
499
+ if (file_vr?.rule_results) {
500
+ const updated_rules = file_vr.rule_results.map((rr) => rr.rule_id === rule.rule_id ? { ...rr, sent_back: true, sent_back_message: message } : rr);
501
+ vr_copy[file.file_id] = { ...file_vr, rule_results: updated_rules };
502
+ state.set_file_validation_results(vr_copy);
503
+ }
504
+ }, [props, state.set_draft_clarifications, state.set_review_decisions, state.file_validation_results, state.set_file_validation_results]);
505
+ // ── Accept resolved validation rule ──
506
+ const accept_validation_rule = useCallback((rule, file_id) => {
507
+ logger.info('[HazoFbForm] accept_validation_rule', { rule_id: rule.rule_id, file_id });
508
+ const vr_copy = { ...state.file_validation_results };
509
+ const file_vr = vr_copy[file_id];
510
+ if (file_vr?.rule_results) {
511
+ const updated_rules = file_vr.rule_results.map((rr) => rr.rule_id === rule.rule_id ? { ...rr, accepted: true } : rr);
512
+ vr_copy[file_id] = { ...file_vr, rule_results: updated_rules };
513
+ state.set_file_validation_results(vr_copy);
514
+ }
515
+ }, [state.file_validation_results, state.set_file_validation_results]);
516
+ // ── Accept all unreviewed resolved rules on a file ──
517
+ const accept_all_validation_rules = useCallback((rules, file_id) => {
518
+ logger.info('[HazoFbForm] accept_all_validation_rules', { rule_ids: rules.map(r => r.rule_id), file_id });
519
+ const rule_ids = new Set(rules.map(r => r.rule_id));
520
+ const vr_copy = { ...state.file_validation_results };
521
+ const file_vr = vr_copy[file_id];
522
+ if (file_vr?.rule_results) {
523
+ const updated_rules = file_vr.rule_results.map((rr) => rule_ids.has(rr.rule_id) ? { ...rr, accepted: true } : rr);
524
+ vr_copy[file_id] = { ...file_vr, rule_results: updated_rules };
525
+ state.set_file_validation_results(vr_copy);
526
+ }
527
+ }, [state.file_validation_results, state.set_file_validation_results]);
319
528
  // Badge: reviewed/total for draft clarifications (excluding those with pending responses)
320
529
  const clarification_badge = useMemo(() => {
321
530
  const active_drafts = state.draft_clarifications.filter((d) => !pending_clarification_responses.get(d.id)?.response_choice);
@@ -337,6 +546,31 @@ export function HazoFbForm(props) {
337
546
  state.set_active_tab('front');
338
547
  }
339
548
  }, [is_responder, state.active_tab]);
549
+ // Agent stepper redirect: when enabled, redirect legacy back-office tabs to stepper
550
+ useEffect(() => {
551
+ if (props.agent_stepper && show_back_office && ['client_data', 'back', 'clarifications'].includes(state.active_tab)) {
552
+ state.set_active_tab('agent_stepper');
553
+ }
554
+ }, [props.agent_stepper, show_back_office, state.active_tab]);
555
+ // ── Front office stepper state (persists across tab switches) ──
556
+ const [active_front_step, set_active_front_step] = useState(0);
557
+ // ── Submit state (lifted from SummaryReviewView so it persists across tab switches) ──
558
+ // Re-derive when active instance changes so each instance has its own submitted status
559
+ const [submitted_at, set_submitted_at] = useState(null);
560
+ useEffect(() => {
561
+ if (active_instance) {
562
+ const s = active_instance.status;
563
+ if (s === 'client_submitted' || s === 'client_submitted_auto_review' || s === 'completed') {
564
+ set_submitted_at(active_instance.updated_at ? new Date(active_instance.updated_at) : new Date());
565
+ }
566
+ else {
567
+ set_submitted_at(null);
568
+ }
569
+ }
570
+ else {
571
+ set_submitted_at(null);
572
+ }
573
+ }, [active_instance_id]);
340
574
  // Status dialog for run details
341
575
  const [details_open, set_details_open] = useState(false);
342
576
  const is_running = state.run_progress.status === 'classifying' || state.run_progress.status === 'validating' || state.run_progress.status === 'routing';
@@ -429,24 +663,56 @@ export function HazoFbForm(props) {
429
663
  // Back-office group collapse
430
664
  back_group_collapsed: state.back_group_collapsed,
431
665
  set_back_group_collapsed: state.set_back_group_collapsed,
666
+ // Front office stepper
667
+ active_front_step,
668
+ set_active_front_step,
669
+ // Submit state
670
+ submitted_at,
671
+ set_submitted_at,
672
+ // Agent stepper state
673
+ active_step: state.active_step,
674
+ set_active_step: state.set_active_step,
675
+ step_configs: state.step_configs,
676
+ review_queue_items: state.review_queue_items,
677
+ review_queue_decisions: state.review_queue_decisions,
678
+ set_review_queue_decisions: state.set_review_queue_decisions,
679
+ review_complete: state.review_complete,
680
+ send_back_items: state.send_back_items,
681
+ send_back_comments: state.send_back_comments,
682
+ set_send_back_comments: state.set_send_back_comments,
683
+ confirm_review_decisions: state.confirm_review_decisions,
684
+ // Reject & send back
685
+ reject_clarification,
686
+ // Override resolved validation
687
+ create_validation_clarification,
688
+ // Accept validation rules
689
+ accept_validation_rule,
690
+ accept_all_validation_rules,
432
691
  // Debug
433
692
  show_debug_dialogs,
434
693
  };
435
- return (_jsx(FbFormContext.Provider, { value: ctx, children: _jsxs("div", { className: cn('cls_fb_form flex w-full', is_multi_instance ? 'h-full' : 'flex-col', props.className), children: [is_multi_instance && (_jsx(InstanceSidebar, { instances: instances, active_instance_id: active_instance_id, on_instance_change: set_active_instance, on_create: props.on_instance_create ? create_instance : undefined, user_role: props.user_role, instance_badge_render: props.instance_badge_render, className: props.sidebar_class_name })), _jsxs("div", { className: cn('flex-1 flex flex-col min-w-0 overflow-hidden', is_multi_instance && 'h-full'), children: [_jsxs("div", { className: cn('flex items-center justify-between border-b border-border/60 px-2 mb-4 flex-shrink-0', props.tab_bar_class_name), children: [_jsxs("div", { className: "flex gap-1", children: [_jsxs("button", { type: "button", onClick: () => state.set_active_tab('front'), className: cn('px-3 py-2 text-sm font-medium border-b-2 transition-colors', state.active_tab === 'front'
436
- ? cn('border-foreground text-foreground', props.active_tab_class_name)
437
- : 'border-transparent text-muted-foreground hover:text-foreground', props.tab_class_name), children: [props.front_tab_label ?? 'Client View', props.front_tab_badge && _jsx("span", { className: "ml-2", children: props.front_tab_badge })] }), show_back_office && (_jsx("button", { type: "button", onClick: () => state.set_active_tab('client_data'), className: cn('px-3 py-2 text-sm font-medium border-b-2 transition-colors', state.active_tab === 'client_data'
438
- ? cn('border-foreground text-foreground', props.active_tab_class_name)
439
- : 'border-transparent text-muted-foreground hover:text-foreground', props.tab_class_name), children: props.client_data_tab_label ?? 'Client Data' })), show_back_office && (_jsx("button", { type: "button", onClick: () => state.set_active_tab('back'), className: cn('px-3 py-2 text-sm font-medium border-b-2 transition-colors', state.active_tab === 'back'
440
- ? cn('border-foreground text-foreground', props.active_tab_class_name)
441
- : 'border-transparent text-muted-foreground hover:text-foreground', props.tab_class_name), children: props.back_tab_label ?? 'Back Office' })), show_back_office && (_jsxs("button", { type: "button", onClick: () => state.set_active_tab('clarifications'), className: cn('px-3 py-2 text-sm font-medium border-b-2 transition-colors relative', state.active_tab === 'clarifications'
694
+ return (_jsx(FbFormContext.Provider, { value: ctx, children: _jsxs("div", { className: cn('cls_fb_form flex w-full', is_multi_instance ? 'h-full' : 'flex-col', props.className), children: [is_multi_instance && (_jsx(InstanceSidebar, { instances: instances, active_instance_id: active_instance_id, on_instance_change: set_active_instance, on_create: props.on_instance_create ? create_instance : undefined, user_role: props.user_role, instance_badge_render: props.instance_badge_render, className: props.sidebar_class_name })), _jsxs("div", { className: cn('flex-1 flex flex-col min-w-0 overflow-hidden', is_multi_instance && 'h-full'), children: [_jsxs("div", { className: cn('flex items-center justify-between border-b border-border/60 px-2 mb-4 flex-shrink-0', props.tab_bar_class_name), children: [_jsxs("div", { className: "flex gap-1 items-center", children: [_jsxs("button", { type: "button", onClick: () => state.set_active_tab('front'), className: cn('px-3 py-2 text-sm font-medium border-b-2 transition-colors', state.active_tab === 'front'
442
695
  ? cn('border-foreground text-foreground', props.active_tab_class_name)
443
- : 'border-transparent text-muted-foreground hover:text-foreground', props.tab_class_name), children: [props.clarifications_tab_label ?? 'Send Back to Client', clarification_badge.total > 0 && (_jsx("span", { className: cn('ml-1.5 inline-flex items-center justify-center h-4 min-w-[16px] px-1 rounded text-[10px] font-semibold', clarification_badge.all_reviewed
444
- ? 'bg-green-100 text-green-700'
445
- : 'bg-amber-100 text-amber-700'), title: `Reviewed ${clarification_badge.reviewed} of ${clarification_badge.total} clarifications`, children: clarification_badge.total > 0
446
- ? `${clarification_badge.reviewed} / ${clarification_badge.total}`
447
- : clarification_badge.total }))] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [can_send_to_client && state.active_tab === 'front' && (_jsx("button", { type: "button", onClick: () => props.on_send_to_client(active_instance_id), disabled: !has_front_data, className: cn('inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md transition-colors', has_front_data
696
+ : 'border-transparent text-muted-foreground hover:text-foreground', props.tab_class_name), children: [props.front_tab_label ?? 'Client View', props.front_tab_badge && _jsx("span", { className: "ml-2", children: props.front_tab_badge })] }), props.agent_stepper && show_back_office ? (_jsx(AgentStepper, { steps: state.step_configs, active_step: state.active_step, on_step_click: (step) => {
697
+ // Confirm review decisions when navigating away from review step
698
+ if (state.active_step === 'review' && step !== 'review' && state.review_complete) {
699
+ state.confirm_review_decisions();
700
+ }
701
+ state.set_active_tab('agent_stepper');
702
+ state.set_active_step(step);
703
+ } })) : (_jsxs(_Fragment, { children: [show_back_office && (_jsx("button", { type: "button", onClick: () => state.set_active_tab('client_data'), className: cn('px-3 py-2 text-sm font-medium border-b-2 transition-colors', state.active_tab === 'client_data'
704
+ ? cn('border-foreground text-foreground', props.active_tab_class_name)
705
+ : 'border-transparent text-muted-foreground hover:text-foreground', props.tab_class_name), children: props.client_data_tab_label ?? 'Client Data' })), show_back_office && (_jsx("button", { type: "button", onClick: () => state.set_active_tab('back'), className: cn('px-3 py-2 text-sm font-medium border-b-2 transition-colors', state.active_tab === 'back'
706
+ ? cn('border-foreground text-foreground', props.active_tab_class_name)
707
+ : 'border-transparent text-muted-foreground hover:text-foreground', props.tab_class_name), children: props.back_tab_label ?? 'Back Office' })), show_back_office && (_jsxs("button", { type: "button", onClick: () => state.set_active_tab('clarifications'), className: cn('px-3 py-2 text-sm font-medium border-b-2 transition-colors relative', state.active_tab === 'clarifications'
708
+ ? cn('border-foreground text-foreground', props.active_tab_class_name)
709
+ : 'border-transparent text-muted-foreground hover:text-foreground', props.tab_class_name), children: [props.clarifications_tab_label ?? 'Send Back to Client', clarification_badge.total > 0 && (_jsx("span", { className: cn('ml-1.5 inline-flex items-center justify-center h-4 min-w-[16px] px-1 rounded text-[10px] font-semibold', clarification_badge.all_reviewed
710
+ ? 'bg-green-100 text-green-700'
711
+ : 'bg-amber-100 text-amber-700'), title: `Reviewed ${clarification_badge.reviewed} of ${clarification_badge.total} clarifications`, children: clarification_badge.total > 0
712
+ ? `${clarification_badge.reviewed} / ${clarification_badge.total}`
713
+ : clarification_badge.total }))] }))] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [can_send_to_client && state.active_tab === 'front' && (_jsx("button", { type: "button", onClick: () => props.on_send_to_client(active_instance_id), disabled: !has_front_data, className: cn('inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md transition-colors', has_front_data
448
714
  ? 'bg-primary text-primary-foreground hover:bg-primary/90'
449
- : 'bg-muted text-muted-foreground cursor-not-allowed opacity-50'), children: "Send to Client" })), is_past_instance && (_jsx("span", { className: "text-xs text-muted-foreground bg-muted px-2 py-1 rounded", children: "Read-only" }))] })] }), _jsxs("div", { className: cn('flex-1 overflow-y-auto px-4'), children: [state.active_tab === 'front' && _jsx(FrontOfficeView, {}), state.active_tab === 'client_data' && show_back_office && (_jsxs(_Fragment, { children: [show_backoffice_run_button && !is_past_instance && (_jsx("div", { className: "flex justify-end pt-2 mb-4", children: _jsx(BackofficeRunButton, { progress: state.run_progress, on_run: trigger_backoffice_run, disabled: !has_front_data, className: props.run_button_class_name, run_button_label: props.run_button_label, classification_results: state.classification_results, unassigned_files: state.unassigned_files, group_autofill_log: state.group_autofill_log }) })), _jsx(ClientDataView, {})] })), state.active_tab === 'back' && show_back_office && (_jsxs(_Fragment, { children: [show_backoffice_run_button && !is_past_instance && (_jsx("div", { className: "flex justify-end pt-2 mb-4", children: _jsx(BackofficeRunButton, { progress: state.run_progress, on_run: trigger_backoffice_run, disabled: !has_front_data, className: props.run_button_class_name, run_button_label: props.run_button_label, classification_results: state.classification_results, unassigned_files: state.unassigned_files, group_autofill_log: state.group_autofill_log }) })), _jsx(BackOfficeView, {})] })), state.active_tab === 'clarifications' && show_back_office && _jsx(ClarificationsView, {})] })] }), _jsx(RunDetailsDialog, { open: details_open, on_open_change: set_details_open, progress: state.run_progress, classification_results: state.classification_results, unassigned_files: state.unassigned_files, group_autofill_log: state.group_autofill_log, show_run_log: show_debug_dialogs })] }) }));
715
+ : 'bg-muted text-muted-foreground cursor-not-allowed opacity-50'), children: "Send to Client" })), is_past_instance && (_jsx("span", { className: "text-xs text-muted-foreground bg-muted px-2 py-1 rounded", children: "Read-only" }))] })] }), _jsxs("div", { className: cn('flex-1 overflow-y-auto px-4'), children: [_jsx("div", { style: { display: state.active_tab === 'front' ? undefined : 'none' }, children: _jsx(FrontOfficeView, {}) }), state.active_tab === 'client_data' && show_back_office && (_jsxs(_Fragment, { children: [show_backoffice_run_button && !is_past_instance && (_jsx("div", { className: "flex justify-end pt-2 mb-4", children: _jsx(BackofficeRunButton, { progress: state.run_progress, on_run: trigger_backoffice_run, disabled: !has_front_data, className: props.run_button_class_name, run_button_label: props.run_button_label, classification_results: state.classification_results, unassigned_files: state.unassigned_files, group_autofill_log: state.group_autofill_log }) })), _jsx(ClientDataView, {})] })), state.active_tab === 'back' && show_back_office && (_jsxs(_Fragment, { children: [show_backoffice_run_button && !is_past_instance && (_jsx("div", { className: "flex justify-end pt-2 mb-4", children: _jsx(BackofficeRunButton, { progress: state.run_progress, on_run: trigger_backoffice_run, disabled: !has_front_data, className: props.run_button_class_name, run_button_label: props.run_button_label, classification_results: state.classification_results, unassigned_files: state.unassigned_files, group_autofill_log: state.group_autofill_log }) })), _jsx(BackOfficeView, {})] })), state.active_tab === 'clarifications' && show_back_office && _jsx(ClarificationsView, {}), state.active_tab === 'agent_stepper' && show_back_office && (_jsxs(_Fragment, { children: [state.active_step === 'review' && _jsx(ReviewQueueView, {}), state.active_step === 'tax_data' && (_jsxs(_Fragment, { children: [show_backoffice_run_button && !is_past_instance && (_jsx("div", { className: "flex justify-end pt-2 mb-4", children: _jsx(BackofficeRunButton, { progress: state.run_progress, on_run: trigger_backoffice_run, disabled: !has_front_data, className: props.run_button_class_name, run_button_label: props.run_button_label, classification_results: state.classification_results, unassigned_files: state.unassigned_files, group_autofill_log: state.group_autofill_log }) })), _jsx(BackOfficeView, {}), _jsxs("div", { className: "flex items-center justify-between border-t border-border/60 pt-4 mt-6 pb-4", children: [state.step_configs.find(s => s.id === 'review')?.enabled && (_jsx("button", { type: "button", onClick: () => state.set_active_step('review'), className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors", children: "\u2190 Back to Review" })), state.send_back_items.length > 0 ? (_jsxs("button", { type: "button", onClick: () => state.set_active_step('send_back'), className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium bg-primary text-primary-foreground hover:bg-primary/90 rounded-md transition-colors", children: ["Next: Send Back (", state.send_back_items.length, ") \u2192"] })) : (_jsx("span", { className: "text-sm text-green-600 font-medium", children: "✓ All resolved" }))] })] })), state.active_step === 'send_back' && _jsx(SendBackView, {})] }))] })] }), _jsx(RunDetailsDialog, { open: details_open, on_open_change: set_details_open, progress: state.run_progress, classification_results: state.classification_results, unassigned_files: state.unassigned_files, group_autofill_log: state.group_autofill_log, show_run_log: show_debug_dialogs })] }) }));
450
716
  }
451
717
  HazoFbForm.displayName = 'HazoFbForm';
452
718
  //# sourceMappingURL=hazo_fb_form.js.map