import { signedGet, signedPost, isSuccess } from '@/api/client'; import { normalizeDataDesigner } from '@/components/form/DataDesignerField'; import { dropdownMap, fetchUserAttributes } from '@/api/dropdowns'; import { splitHash } from '@/helpers/metric'; const STATUS = { active: 'Active', disabled: 'Disabled' }; function asArray(value) { if (Array.isArray(value)) return value.filter((part) => part !== null && part !== undefined && part !== ''); return splitHash(value); } function normalizeEmailRules(raw) { let rules = raw; if (typeof raw === 'string' && raw.trim()) { try { rules = JSON.parse(raw); } catch { rules = []; } } if (!Array.isArray(rules)) return []; return rules.map((rule) => { const row = rule && typeof rule === 'object' ? rule : {}; return { enabled: row.enabled === 'no' ? 'no' : 'yes', manager_levels: asArray(row.manager_levels), role_ids: asArray(row.role_ids), selected_users: asArray(row.selected_users), condition: typeof row.condition === 'string' ? row.condition : row.condition ? JSON.stringify(row.condition) : '', subject: row.subject || '', body: row.body || '', }; }); } const formentitys = { service: 'form', module: 'formentity', title: 'Form', subtitle: 'Data Gathering', baseUrl: '/formentity', listPath: '/formentitys', listFields: [ { key: 'actions', title: 'Actions', buttons: [ 'edit', 'delete', { name: 'questions', to: (row) => `/formquestions?id=${row.id}`, title: 'Questions' }, { name: 'personalizations', to: (row) => `/formpersonalizations?id=${row.id}`, title: 'Personalizations' }, ], }, { key: 'title', title: 'Title', type: 'text' }, { key: 'workflow', title: 'Workflow', type: 'text' }, { key: 'status', title: 'Status', type: 'select' }, ], formFields: async () => { const [usersRes, roles, contactRes, userAttrItems, workflowRes] = await Promise.all([ signedGet('ums', 'users/dropdown'), dropdownMap('ums', 'roles', (item) => item.name), signedGet('contact', 'contactattribute/get_all'), fetchUserAttributes(), signedGet('workflow', 'workflow_definition/get_all'), ]); const approvers = { l1manager: 'L1 Manager', l2manager: 'L2 Manager', l3manager: 'L3 Manager', l4manager: 'L4 Manager', }; const notifyUsers = {}; const userItems = isSuccess(usersRes) ? usersRes.data?.items || [] : []; userItems.forEach((user) => { if (!user?.id) return; const label = `${user.firstname || ''} ${user.lastname || ''} (${user.employee_code || ''})`.trim(); approvers[user.id] = label; notifyUsers[user.id] = label; }); const contactAttributes = {}; const contactItems = isSuccess(contactRes) ? contactRes.data?.items || [] : []; contactItems.forEach((attr) => { if (attr?.code) contactAttributes[attr.code] = attr.attribute || attr.code; }); const userAttributes = {}; userAttrItems.forEach((attr) => { if (!attr?.code || attr.status === 'disabled') return; userAttributes[attr.code] = attr.attribute || attr.code; }); const workflowDefinitions = { '': 'None' }; const workflowItems = isSuccess(workflowRes) ? workflowRes.data?.items || [] : []; workflowItems.forEach((definition) => { if (!definition?.id || !definition.published_version) return; if (definition.entity && definition.entity !== 'form_submission' && definition.entity !== 'manual') return; workflowDefinitions[definition.id] = `${definition.name} (v${definition.published_version})`; }); return [ { key: 'title', title: 'Title', type: 'text', required: true }, { key: 'status', title: 'Status', type: 'select', required: true, values: STATUS }, { key: 'metric_submission', title: 'Metric Submission', type: 'yesno', required: true }, { key: 'metric_authkey', title: 'Auth Key', type: 'text', required: true }, { key: 'manager_de_roles', title: 'Manager Data Entry Roles', type: 'multiselect', values: roles }, { key: 'manager_data_child_type', title: 'Manager Data Child Type', type: 'multiselect', values: { Territory: 'Territory', Area: 'Area', Region: 'Region', Zone: 'Zone', Country: 'Country' }, }, { key: 'export_manager_levels', title: 'Export Manager Levels', type: 'multiselect', required: true, values: { l1manager: 'L1 Manager', l2manager: 'L2 Manager', l3manager: 'L3Manager', l4manager: 'L4 Manager' }, }, { key: 'contact_attributes', title: 'Include Doctor Attributes in Export', type: 'multiselect', values: contactAttributes }, { key: 'show_user_attributes', title: 'Show User Attributes', type: 'yesno', required: true, default: 'no' }, { key: 'user_attributes', title: 'Include User Attributes in Export', type: 'multiselect', values: userAttributes, default: [], }, { key: 'form_type', title: 'Enter From Type', type: 'select', values: { plan_vs_execution: 'Plan vs Execution', enrollment_form: 'Enrollment Form' }, }, { key: 'enrollment_form_attributes', title: 'Enter Attributes for Enrollment Form', type: 'multiselect', values: contactAttributes, showIf: { form_type: 'enrollment_form' }, }, { key: 'self_notification', title: 'Self Email Notification', type: 'yesno', required: true, fullwidth: true }, { key: 'manager1_email_notification', title: '1st Level Manager Email Notification', type: 'yesno', required: true }, { key: 'manager1_push_notification', title: '1st Level Manager Mobile Notification', type: 'yesno', required: true }, { key: 'manager2_email_notification', title: '2nd Level Manager Email Notification', type: 'yesno', required: true }, { key: 'manager2_push_notification', title: '2nd Level Manager Mobile Notification', type: 'yesno', required: true }, { key: 'roles_email_notification', title: 'Email Notification to Roles', type: 'multiselect', values: roles }, { key: 'roles_push_notification', title: 'Push Notification to Roles', type: 'multiselect', values: roles }, { key: 'show_positions', title: 'Show Positions on Submitted Data', type: 'yesno', required: true, default: 'no' }, { key: 'show_positions_type', title: 'Show Positions Type', type: 'select', required: true, values: { all: 'All', loggedin: 'Logged In' }, default: 'all', }, { key: 'show_manager_details', title: 'Show Managers details on Submitted Data', type: 'yesno', required: true, default: 'no' }, { key: 'roles_info', title: 'Roles Info', type: 'yesno', required: true, default: 'no' }, { key: 'allow_non_hierarchy_submission', title: 'Allow Non Hierarchy Submission', type: 'yesno', required: true }, { key: 'workflow', title: 'Enable Workflow', type: 'yesno', required: true }, { key: 'workflow_definition_id', title: 'Workflow definition', type: 'select', values: workflowDefinitions, showIf: { workflow: 'yes' }, }, { key: 'workflow_type', title: 'Workflow type', type: 'select', required: true, values: { single: 'Single Persoon', multiple: 'Multiple person', sequencial: 'Sequencial' }, }, { key: 'retain_status_on_resubmit', title: 'Retain workflow status on resubmit', type: 'yesno', required: true }, { key: 'approver_can_edit', title: 'Approver can edit entry', type: 'yesno', required: true }, { key: 'send_email_workflow_notification', title: 'Send Email Workflow Notification', type: 'yesno', required: true }, { key: 'send_approval_to_manager_if_approver_vacant', title: 'Send Approval Notification to Manager if Approver is Vacant', type: 'yesno', required: true, }, { key: 'is_personalized', title: 'Is Personalization Needed', type: 'yesno', required: true }, { key: 'allow_delete_by_user', title: 'Allow Submission Delete by User', type: 'yesno', required: true }, { key: 'auto_approve', title: 'Want To Auto Approve', type: 'yesno', required: true }, { key: 'auto_approve_condition', title: 'Auto Approve Condition If Any', type: 'textarea', fullwidth: true }, { key: 'export_fields', title: 'Export Fields', type: 'textarea', fullwidth: true }, { key: 'workflow_approvers', title: 'Metric', type: 'mapping', approvers, fullwidth: true }, { key: 'email_notification', title: 'Email Notification', type: 'yesno', required: true, default: 'no', fullwidth: true }, { key: 'email_notification_rules', title: 'Email Notification Rules', type: 'email_notifications', fullwidth: true, hide_label: true, showIf: { email_notification: 'yes' }, manager_levels: { l1manager: 'L1 Manager', l2manager: 'L2 Manager', l3manager: 'L3 Manager', l4manager: 'L4 Manager', }, roles, users: notifyUsers, }, { key: 'data_designer', type: 'data_designer', fullwidth: true, hide_label: true, userAttributes, }, ]; }, beforeForm: (item) => { const next = { ...item }; const yesno = (value, fallback = 'no') => (value ? String(value).toLowerCase() : fallback); next.self_notification = yesno(next.self_notification); next.manager1_email_notification = yesno(next.manager1_email_notification); next.manager1_push_notification = yesno(next.manager1_push_notification); next.manager2_email_notification = yesno(next.manager2_email_notification); next.manager2_push_notification = yesno(next.manager2_push_notification); next.send_approval_to_manager_if_approver_vacant = yesno(next.send_approval_to_manager_if_approver_vacant); next.export_fields = next.export_fields || ''; next.email_notification_rules = normalizeEmailRules(next.email_notification_rules); next.email_notification = next.email_notification || (next.email_notification_rules.length ? 'yes' : 'no'); next.form_type = next.form_type || ''; next.enrollment_form_attributes = asArray(next.enrollment_form_attributes); next.auto_approve = yesno(next.auto_approve); next.auto_approve_condition = next.auto_approve_condition || ''; next.roles_info = yesno(next.roles_info); if (!next.show_positions) next.show_positions = next.show_position || 'no'; next.show_positions = String(next.show_positions).toLowerCase(); if (!next.show_positions_type) next.show_positions_type = next.show_position_type || 'all'; next.show_positions_type = String(next.show_positions_type).toLowerCase(); if (!['all', 'loggedin'].includes(next.show_positions_type)) next.show_positions_type = 'all'; next.show_manager_details = yesno(next.show_manager_details); next.manager_de_roles = asArray(next.manager_de_roles); next.manager_data_child_type = asArray(next.manager_data_child_type); next.export_manager_levels = asArray(next.export_manager_levels); next.contact_attributes = asArray(next.contact_attributes); next.show_user_attributes = yesno(next.show_user_attributes, 'no'); next.user_attributes = asArray(next.user_attributes); if (next.user_attributes.length) next.show_user_attributes = 'yes'; next.roles_email_notification = asArray(next.roles_email_notification); next.roles_push_notification = asArray(next.roles_push_notification); next.workflow_approvers = Array.isArray(next.workflow_approvers) && next.workflow_approvers.length ? next.workflow_approvers : ['l1manager']; next.workflow_definition_id = next.workflow_definition_id || ''; next.data_designer = normalizeDataDesigner(next.data_designer); return next; }, beforeSave: async (data, mode) => { const payload = { ...data }; payload.manager_data_child_type = asArray(payload.manager_data_child_type); payload.export_manager_levels = asArray(payload.export_manager_levels); payload.manager_de_roles = asArray(payload.manager_de_roles); payload.contact_attributes = asArray(payload.contact_attributes); payload.data_designer = normalizeDataDesigner(payload.data_designer); payload.show_user_attributes = payload.show_user_attributes === 'yes' ? 'yes' : 'no'; payload.user_attributes = asArray(payload.user_attributes); if (payload.user_attributes.length) payload.show_user_attributes = 'yes'; payload.enrollment_form_attributes = asArray(payload.enrollment_form_attributes); payload.roles_email_notification = asArray(payload.roles_email_notification); payload.roles_push_notification = asArray(payload.roles_push_notification); payload.workflow_approvers = Array.isArray(payload.workflow_approvers) ? payload.workflow_approvers.filter(Boolean) : []; payload.workflow_definition_id = payload.workflow_definition_id || ''; if (mode === 'new' && payload.workflow === 'yes' && !payload.workflow_definition_id) { throw new Error('New forms with workflow must use a published workflow definition'); } if (payload.workflow_definition_id) { payload.workflow_approvers = []; } else if (payload.workflow === 'yes' && !payload.workflow_approvers.length) { payload.workflow_approvers = ['l1manager']; } payload.email_notification = payload.email_notification === 'yes' ? 'yes' : 'no'; payload.roles_info = payload.roles_info === 'yes' ? 'yes' : 'no'; if (payload.email_notification === 'no') { payload.email_notification_rules = []; } else { payload.email_notification_rules = normalizeEmailRules(payload.email_notification_rules); } if (mode === 'new') { const mapping = await signedPost('metric', 'injestion_mapping/create', { name: payload.title, status: 'active', }); if (isSuccess(mapping) && mapping.data?.item?.id) { payload.map_auth_key = mapping.data.item.id; } payload.metric_submission = 'yes'; } return payload; }, }; export default formentitys;