298 lines
14 KiB
JavaScript
298 lines
14 KiB
JavaScript
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;
|