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.
- package/CHANGE_LOG.md +65 -0
- package/README.md +5 -38
- package/dist/components/clarification/clarification_card.d.ts +2 -0
- package/dist/components/clarification/clarification_card.d.ts.map +1 -1
- package/dist/components/clarification/clarification_card.js +13 -4
- package/dist/components/clarification/clarification_card.js.map +1 -1
- package/dist/components/clarification/clarification_doc_reference.js +1 -1
- package/dist/components/clarification/clarification_doc_reference.js.map +1 -1
- package/dist/components/clarification/clarification_group_card.d.ts +2 -0
- package/dist/components/clarification/clarification_group_card.d.ts.map +1 -1
- package/dist/components/clarification/clarification_group_card.js +2 -2
- package/dist/components/clarification/clarification_group_card.js.map +1 -1
- package/dist/components/clarification/clarification_item_body.d.ts +2 -0
- package/dist/components/clarification/clarification_item_body.d.ts.map +1 -1
- package/dist/components/clarification/clarification_item_body.js +7 -2
- package/dist/components/clarification/clarification_item_body.js.map +1 -1
- package/dist/components/clarification/clarification_response_form.d.ts +2 -0
- package/dist/components/clarification/clarification_response_form.d.ts.map +1 -1
- package/dist/components/clarification/clarification_response_form.js +2 -2
- package/dist/components/clarification/clarification_response_form.js.map +1 -1
- package/dist/components/clarification/clarification_section.d.ts +2 -0
- package/dist/components/clarification/clarification_section.d.ts.map +1 -1
- package/dist/components/clarification/clarification_section.js +2 -2
- package/dist/components/clarification/clarification_section.js.map +1 -1
- package/dist/components/clarification/clarification_thread.d.ts +19 -0
- package/dist/components/clarification/clarification_thread.d.ts.map +1 -0
- package/dist/components/clarification/clarification_thread.js +94 -0
- package/dist/components/clarification/clarification_thread.js.map +1 -0
- package/dist/components/collab_form_file_upload.js +1 -2
- package/dist/components/collab_form_file_upload.js.map +1 -1
- package/dist/components/data_ok_multi_state.d.ts.map +1 -1
- package/dist/components/data_ok_multi_state.js +1 -2
- package/dist/components/data_ok_multi_state.js.map +1 -1
- package/dist/components/hazo_collab_form_base.d.ts.map +1 -1
- package/dist/components/hazo_collab_form_base.js +6 -8
- package/dist/components/hazo_collab_form_base.js.map +1 -1
- package/dist/components/hazo_collab_form_combo.d.ts.map +1 -1
- package/dist/components/hazo_collab_form_combo.js +8 -10
- package/dist/components/hazo_collab_form_combo.js.map +1 -1
- package/dist/components/hazo_collab_form_data_table.d.ts.map +1 -1
- package/dist/components/hazo_collab_form_data_table.js +7 -4
- package/dist/components/hazo_collab_form_data_table.js.map +1 -1
- package/dist/components/hazo_collab_form_date.d.ts.map +1 -1
- package/dist/components/hazo_collab_form_date.js +3 -6
- package/dist/components/hazo_collab_form_date.js.map +1 -1
- package/dist/components/hazo_collab_form_file_textbox/validation_dialog.d.ts.map +1 -1
- package/dist/components/hazo_collab_form_file_textbox/validation_dialog.js +1 -1
- package/dist/components/hazo_collab_form_file_textbox/validation_dialog.js.map +1 -1
- package/dist/components/hazo_fb_form/components/draft_clarification_card.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/components/draft_clarification_card.js +19 -11
- package/dist/components/hazo_fb_form/components/draft_clarification_card.js.map +1 -1
- package/dist/components/hazo_fb_form/components/reject_clarification_dialog.d.ts +15 -0
- package/dist/components/hazo_fb_form/components/reject_clarification_dialog.d.ts.map +1 -0
- package/dist/components/hazo_fb_form/components/reject_clarification_dialog.js +26 -0
- package/dist/components/hazo_fb_form/components/reject_clarification_dialog.js.map +1 -0
- package/dist/components/hazo_fb_form/components/run_details_dialog.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/components/run_details_dialog.js +4 -4
- package/dist/components/hazo_fb_form/components/run_details_dialog.js.map +1 -1
- package/dist/components/hazo_fb_form/components/sent_clarification_group.d.ts +2 -1
- package/dist/components/hazo_fb_form/components/sent_clarification_group.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/components/sent_clarification_group.js +2 -2
- package/dist/components/hazo_fb_form/components/sent_clarification_group.js.map +1 -1
- package/dist/components/hazo_fb_form/context.d.ts +39 -2
- package/dist/components/hazo_fb_form/context.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/context.js.map +1 -1
- package/dist/components/hazo_fb_form/hazo_fb_form.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/hazo_fb_form.js +331 -65
- package/dist/components/hazo_fb_form/hazo_fb_form.js.map +1 -1
- package/dist/components/hazo_fb_form/hooks/use_fb_form_state.d.ts +14 -3
- package/dist/components/hazo_fb_form/hooks/use_fb_form_state.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/hooks/use_fb_form_state.js +311 -5
- package/dist/components/hazo_fb_form/hooks/use_fb_form_state.js.map +1 -1
- package/dist/components/hazo_fb_form/hooks/use_llm_run.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/hooks/use_llm_run.js +252 -50
- package/dist/components/hazo_fb_form/hooks/use_llm_run.js.map +1 -1
- package/dist/components/hazo_fb_form/index.d.ts +5 -0
- package/dist/components/hazo_fb_form/index.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/index.js +3 -0
- package/dist/components/hazo_fb_form/index.js.map +1 -1
- package/dist/components/hazo_fb_form/shared/agent_stepper.d.ts +9 -0
- package/dist/components/hazo_fb_form/shared/agent_stepper.d.ts.map +1 -0
- package/dist/components/hazo_fb_form/shared/agent_stepper.js +17 -0
- package/dist/components/hazo_fb_form/shared/agent_stepper.js.map +1 -0
- package/dist/components/hazo_fb_form/shared/format.d.ts +3 -0
- package/dist/components/hazo_fb_form/shared/format.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/shared/format.js +16 -0
- package/dist/components/hazo_fb_form/shared/format.js.map +1 -1
- package/dist/components/hazo_fb_form/shared/group_debug_icon.d.ts +15 -0
- package/dist/components/hazo_fb_form/shared/group_debug_icon.d.ts.map +1 -0
- package/dist/components/hazo_fb_form/shared/group_debug_icon.js +48 -0
- package/dist/components/hazo_fb_form/shared/group_debug_icon.js.map +1 -0
- package/dist/components/hazo_fb_form/shared/pdf_side_panel.js +1 -1
- package/dist/components/hazo_fb_form/shared/pdf_side_panel.js.map +1 -1
- package/dist/components/hazo_fb_form/shared/send_back_item_card.d.ts +31 -0
- package/dist/components/hazo_fb_form/shared/send_back_item_card.d.ts.map +1 -0
- package/dist/components/hazo_fb_form/shared/send_back_item_card.js +41 -0
- package/dist/components/hazo_fb_form/shared/send_back_item_card.js.map +1 -0
- package/dist/components/hazo_fb_form/types.d.ts +47 -4
- package/dist/components/hazo_fb_form/types.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/views/back_office_view.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/views/back_office_view.js +69 -18
- package/dist/components/hazo_fb_form/views/back_office_view.js.map +1 -1
- package/dist/components/hazo_fb_form/views/clarifications_view.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/views/clarifications_view.js +18 -7
- package/dist/components/hazo_fb_form/views/clarifications_view.js.map +1 -1
- package/dist/components/hazo_fb_form/views/client_data_view.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/views/client_data_view.js +5 -2
- package/dist/components/hazo_fb_form/views/client_data_view.js.map +1 -1
- package/dist/components/hazo_fb_form/views/front_office_view.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/views/front_office_view.js +121 -41
- package/dist/components/hazo_fb_form/views/front_office_view.js.map +1 -1
- package/dist/components/hazo_fb_form/views/interim_view.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/views/interim_view.js +174 -55
- package/dist/components/hazo_fb_form/views/interim_view.js.map +1 -1
- package/dist/components/hazo_fb_form/views/review_queue_view.d.ts +14 -0
- package/dist/components/hazo_fb_form/views/review_queue_view.d.ts.map +1 -0
- package/dist/components/hazo_fb_form/views/review_queue_view.js +162 -0
- package/dist/components/hazo_fb_form/views/review_queue_view.js.map +1 -0
- package/dist/components/hazo_fb_form/views/send_back_view.d.ts +13 -0
- package/dist/components/hazo_fb_form/views/send_back_view.d.ts.map +1 -0
- package/dist/components/hazo_fb_form/views/send_back_view.js +203 -0
- package/dist/components/hazo_fb_form/views/send_back_view.js.map +1 -0
- package/dist/components/hazo_fb_form/views/summary_review_view.d.ts +3 -1
- package/dist/components/hazo_fb_form/views/summary_review_view.d.ts.map +1 -1
- package/dist/components/hazo_fb_form/views/summary_review_view.js +75 -14
- package/dist/components/hazo_fb_form/views/summary_review_view.js.map +1 -1
- package/dist/components/hazo_field_selector_dialog/components/field_autocomplete.d.ts.map +1 -1
- package/dist/components/hazo_field_selector_dialog/components/field_autocomplete.js +7 -8
- package/dist/components/hazo_field_selector_dialog/components/field_autocomplete.js.map +1 -1
- package/dist/components/hazo_field_selector_dialog/components/sortable_field_item.d.ts.map +1 -1
- package/dist/components/hazo_field_selector_dialog/components/sortable_field_item.js +1 -2
- package/dist/components/hazo_field_selector_dialog/components/sortable_field_item.js.map +1 -1
- package/dist/components/hazo_template_generator/types.d.ts.map +1 -1
- package/dist/components/hazo_template_generator/types.js +1 -0
- package/dist/components/hazo_template_generator/types.js.map +1 -1
- package/dist/components/hazo_validation_rule_editor/components/rule_editor.js +1 -1
- package/dist/components/hazo_validation_rule_editor/components/rule_editor.js.map +1 -1
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/multi_state_radio.d.ts.map +1 -1
- package/dist/components/multi_state_radio.js +1 -2
- package/dist/components/multi_state_radio.js.map +1 -1
- package/dist/components/shared/field_tooltip/field_tooltip.d.ts.map +1 -1
- package/dist/components/shared/field_tooltip/field_tooltip.js +1 -2
- package/dist/components/shared/field_tooltip/field_tooltip.js.map +1 -1
- package/dist/components/shared/file_bar/file_bar.d.ts +12 -2
- package/dist/components/shared/file_bar/file_bar.d.ts.map +1 -1
- package/dist/components/shared/file_bar/file_bar.js +8 -9
- package/dist/components/shared/file_bar/file_bar.js.map +1 -1
- package/dist/components/shared/file_bar/file_bar_validation.d.ts +1 -1
- package/dist/components/shared/file_bar/file_bar_validation.d.ts.map +1 -1
- package/dist/components/shared/file_bar/file_bar_validation.js +9 -0
- package/dist/components/shared/file_bar/file_bar_validation.js.map +1 -1
- package/dist/components/shared/file_bar/file_bar_validation_dialog.d.ts +16 -1
- package/dist/components/shared/file_bar/file_bar_validation_dialog.d.ts.map +1 -1
- package/dist/components/shared/file_bar/file_bar_validation_dialog.js +31 -26
- package/dist/components/shared/file_bar/file_bar_validation_dialog.js.map +1 -1
- package/dist/components/shared/file_bar/file_validation_issues_dialog.d.ts +3 -1
- package/dist/components/shared/file_bar/file_validation_issues_dialog.d.ts.map +1 -1
- package/dist/components/shared/file_bar/file_validation_issues_dialog.js +2 -2
- package/dist/components/shared/file_bar/file_validation_issues_dialog.js.map +1 -1
- package/dist/components/shared/role_utils/role_utils.d.ts +1 -0
- package/dist/components/shared/role_utils/role_utils.d.ts.map +1 -1
- package/dist/components/shared/role_utils/role_utils.js +3 -0
- package/dist/components/shared/role_utils/role_utils.js.map +1 -1
- package/dist/components/shared/rule_result_card.d.ts +31 -0
- package/dist/components/shared/rule_result_card.d.ts.map +1 -0
- package/dist/components/shared/rule_result_card.js +72 -0
- package/dist/components/shared/rule_result_card.js.map +1 -0
- package/dist/components/shared/unified_field_controls/constants.d.ts.map +1 -1
- package/dist/components/shared/unified_field_controls/constants.js +1 -0
- package/dist/components/shared/unified_field_controls/constants.js.map +1 -1
- package/dist/components/shared/unified_field_controls/resolve_field_controls.d.ts +2 -0
- package/dist/components/shared/unified_field_controls/resolve_field_controls.d.ts.map +1 -1
- package/dist/components/shared/unified_field_controls/resolve_field_controls.js +4 -0
- package/dist/components/shared/unified_field_controls/resolve_field_controls.js.map +1 -1
- package/dist/components/shared/unified_field_controls/types.d.ts +5 -0
- package/dist/components/shared/unified_field_controls/types.d.ts.map +1 -1
- package/dist/components/shared/unified_field_controls/unified_field_controls.d.ts.map +1 -1
- package/dist/components/shared/unified_field_controls/unified_field_controls.js +13 -2
- package/dist/components/shared/unified_field_controls/unified_field_controls.js.map +1 -1
- package/dist/components/shared/use_base_form_field.d.ts +2 -0
- package/dist/components/shared/use_base_form_field.d.ts.map +1 -1
- package/dist/components/shared/use_base_form_field.js +4 -0
- package/dist/components/shared/use_base_form_field.js.map +1 -1
- package/dist/lib/autofill_handler.d.ts +5 -0
- package/dist/lib/autofill_handler.d.ts.map +1 -1
- package/dist/lib/autofill_handler.js +27 -10
- package/dist/lib/autofill_handler.js.map +1 -1
- package/dist/lib/fb_form_handler.d.ts.map +1 -1
- package/dist/lib/fb_form_handler.js +45 -0
- package/dist/lib/fb_form_handler.js.map +1 -1
- package/dist/types/clarification.d.ts +22 -1
- package/dist/types/clarification.d.ts.map +1 -1
- package/dist/types/icons_behaviour.d.ts +1 -1
- package/dist/types/icons_behaviour.d.ts.map +1 -1
- package/dist/types/icons_behaviour.js +3 -1
- package/dist/types/icons_behaviour.js.map +1 -1
- package/dist/types/validation.d.ts +6 -0
- package/dist/types/validation.d.ts.map +1 -1
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
227
|
-
|
|
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
|
-
|
|
246
|
-
|
|
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
|
-
|
|
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.
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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'
|
|
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
|