Changes done in several Modules
## Metric Views:
- Added missing fields in the Metric view (edit or create) as Team Leaderboard Widget Roles, Include User Attributes
- Added one field called stateheadwise_leaderboard:{ type: String, default: 'no' }, Radio button: Yes/No
## Metric Campaigns:
- Added missing fields Show Units Export, Show Normal Metrics, Show Combined Metrics, Manager Details, Total Units Name in Add / Edit Campaign management.
## Recognition - Milestones:
- Added missing fields Show Units Export, Show Normal Metrics, Show Combined Metrics, Manager Details, Total Units Name in Add / Edit Milestone View after Show Positions Type.
- Days checkboxes are inline.
- Added more missing fields like Report Subject, Report Body which are after Show Overall Average.
## Data Gathering - Forms:
- Added missing User Attributes in Export field in Add/Edit form
- In Add / Edit Form Questions, Add Option control should only visible for Question Type Dropdown, Checkbox, Radio, RadioMetrix and Multi Text Boxes
- In Add / Edit Form Personalization, added missing major fields like Template and Positions and others.
## Form data export:
- Resolved error while opening Form Data Export.
- In Add / Edit Form Exports, Select Date Field must have options whose type is date for the selected form. Also Select Date Field should have Default Date (Recommended) option.
## Reminders:
- In Add / Edit Form Reminder, added Notification Type field.
## Leaderboard:
- In Add / Edit Leaderboard, updated the form fields same as Laravel.
- Added missing fields like Show Units Export, Show Normal Metrics, Show Combined Metrics, Total Units Name.
This commit is contained in:
parent
212cf0091d
commit
16c0ef827c
|
|
@ -18,6 +18,7 @@ import RankRolesField from '@/components/form/RankRolesField';
|
||||||
import ReminderRowsField from '@/components/form/ReminderRowsField';
|
import ReminderRowsField from '@/components/form/ReminderRowsField';
|
||||||
import DependentSelectField from '@/components/form/DependentSelectField';
|
import DependentSelectField from '@/components/form/DependentSelectField';
|
||||||
import BigMultiSelectField from '@/components/form/BigMultiSelectField';
|
import BigMultiSelectField from '@/components/form/BigMultiSelectField';
|
||||||
|
import TemplatePositionsField from '@/components/form/TemplatePositionsField';
|
||||||
import S3FileField from '@/components/S3FileField';
|
import S3FileField from '@/components/S3FileField';
|
||||||
import { parseCombinedMetrics } from '@/helpers/metric';
|
import { parseCombinedMetrics } from '@/helpers/metric';
|
||||||
|
|
||||||
|
|
@ -30,7 +31,7 @@ function defaultValue(field, item) {
|
||||||
const raw = fromItem !== undefined && fromItem !== null ? fromItem : field.default;
|
const raw = fromItem !== undefined && fromItem !== null ? fromItem : field.default;
|
||||||
if (raw === undefined || raw === null) {
|
if (raw === undefined || raw === null) {
|
||||||
if (field.type === 'multiselect' || field.type === 'bigmultiselect' || field.type === 'checkbox') return [];
|
if (field.type === 'multiselect' || field.type === 'bigmultiselect' || field.type === 'checkbox') return [];
|
||||||
if (field.type === 'mapping' || field.type === 'color_ranges' || field.type === 'ranking_attributes' || field.type === 'combined_metrics' || field.type === 'milestonemapping' || field.type === 'email_notifications' || field.type === 'rank_roles' || field.type === 'reminders') {
|
if (field.type === 'mapping' || field.type === 'color_ranges' || field.type === 'ranking_attributes' || field.type === 'combined_metrics' || field.type === 'milestonemapping' || field.type === 'email_notifications' || field.type === 'rank_roles' || field.type === 'reminders' || field.type === 'template_positions') {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (field.type === 'approverlist') return ['l1manager'];
|
if (field.type === 'approverlist') return ['l1manager'];
|
||||||
|
|
@ -49,7 +50,7 @@ function defaultValue(field, item) {
|
||||||
}
|
}
|
||||||
return Array.isArray(raw) ? raw : [];
|
return Array.isArray(raw) ? raw : [];
|
||||||
}
|
}
|
||||||
if ((field.type === 'mapping' || field.type === 'color_ranges' || field.type === 'ranking_attributes' || field.type === 'milestonemapping' || field.type === 'rank_roles' || field.type === 'reminders') && !Array.isArray(raw)) {
|
if ((field.type === 'mapping' || field.type === 'color_ranges' || field.type === 'ranking_attributes' || field.type === 'milestonemapping' || field.type === 'rank_roles' || field.type === 'reminders' || field.type === 'template_positions') && !Array.isArray(raw)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (field.type === 'multiselect' || field.type === 'bigmultiselect') {
|
if (field.type === 'multiselect' || field.type === 'bigmultiselect') {
|
||||||
|
|
@ -94,12 +95,28 @@ function defaultValue(field, item) {
|
||||||
return raw === undefined || raw === null ? '' : String(raw);
|
return raw === undefined || raw === null ? '' : String(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toColorPickerValue(value, fallback = '#ffffff') {
|
||||||
|
const raw = String(value || '').trim();
|
||||||
|
if (/^#[0-9A-Fa-f]{6}$/.test(raw)) return raw;
|
||||||
|
if (/^#[0-9A-Fa-f]{3}$/.test(raw)) {
|
||||||
|
return `#${raw[1]}${raw[1]}${raw[2]}${raw[2]}${raw[3]}${raw[3]}`;
|
||||||
|
}
|
||||||
|
if (/^[0-9A-Fa-f]{6}$/.test(raw)) return `#${raw}`;
|
||||||
|
const fallbackRaw = String(fallback || '').trim();
|
||||||
|
if (/^#[0-9A-Fa-f]{6}$/.test(fallbackRaw)) return fallbackRaw;
|
||||||
|
return '#ffffff';
|
||||||
|
}
|
||||||
|
|
||||||
function isFieldVisible(field, values) {
|
function isFieldVisible(field, values) {
|
||||||
if (field.workflowOnly && values?.workflow !== 'yes') return false;
|
if (field.workflowOnly && values?.workflow !== 'yes') return false;
|
||||||
if (!field.showIf) return true;
|
if (!field.showIf) return true;
|
||||||
return Object.entries(field.showIf).every(([key, expected]) => {
|
return Object.entries(field.showIf).every(([key, expected]) => {
|
||||||
const actual = values?.[key];
|
const actual = values?.[key];
|
||||||
if (Array.isArray(expected)) return expected.includes(actual);
|
if (Array.isArray(expected)) {
|
||||||
|
if (Array.isArray(actual)) return expected.some((value) => actual.map(String).includes(String(value)));
|
||||||
|
return expected.map(String).includes(String(actual));
|
||||||
|
}
|
||||||
|
if (Array.isArray(actual)) return actual.map(String).includes(String(expected));
|
||||||
return actual === expected;
|
return actual === expected;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +131,7 @@ function applyExclusive(next, previous, exclusiveValue) {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
function FieldControl({ field, control, register, moduleName, onUploadingChange }) {
|
function FieldControl({ field, control, register, watch, moduleName, onUploadingChange }) {
|
||||||
const common = { className: 'form-control', id: `field-${field.key}` };
|
const common = { className: 'form-control', id: `field-${field.key}` };
|
||||||
if (field.type === 'hidden') {
|
if (field.type === 'hidden') {
|
||||||
return <input type="hidden" {...register(field.key)} />;
|
return <input type="hidden" {...register(field.key)} />;
|
||||||
|
|
@ -224,9 +241,10 @@ function FieldControl({ field, control, register, moduleName, onUploadingChange
|
||||||
<div className="d-flex gap-2 align-items-center">
|
<div className="d-flex gap-2 align-items-center">
|
||||||
<Form.Control
|
<Form.Control
|
||||||
type="color"
|
type="color"
|
||||||
value={rhf.value || '#000000'}
|
className="form-control-color"
|
||||||
|
value={toColorPickerValue(rhf.value, field.pickerDefault || '#ffffff')}
|
||||||
onChange={(e) => rhf.onChange(e.target.value)}
|
onChange={(e) => rhf.onChange(e.target.value)}
|
||||||
style={{ width: 50, padding: 2 }}
|
style={{ width: 50, height: 38, padding: 2, colorScheme: 'light' }}
|
||||||
/>
|
/>
|
||||||
<Form.Control
|
<Form.Control
|
||||||
value={rhf.value || ''}
|
value={rhf.value || ''}
|
||||||
|
|
@ -240,10 +258,35 @@ function FieldControl({ field, control, register, moduleName, onUploadingChange
|
||||||
}
|
}
|
||||||
if (field.type === 'yesno') {
|
if (field.type === 'yesno') {
|
||||||
return (
|
return (
|
||||||
<div>
|
<Controller
|
||||||
<Form.Check inline type="radio" label="Yes" value="yes" {...register(field.key, { required: field.required })} />
|
name={field.key}
|
||||||
<Form.Check inline type="radio" label="No" value="no" {...register(field.key, { required: field.required })} />
|
control={control}
|
||||||
</div>
|
rules={{ required: field.required }}
|
||||||
|
render={({ field: rhf }) => (
|
||||||
|
<div>
|
||||||
|
<Form.Check
|
||||||
|
inline
|
||||||
|
type="radio"
|
||||||
|
id={`field-${field.key}-yes`}
|
||||||
|
name={field.key}
|
||||||
|
label="Yes"
|
||||||
|
value="yes"
|
||||||
|
checked={rhf.value === 'yes'}
|
||||||
|
onChange={() => rhf.onChange('yes')}
|
||||||
|
/>
|
||||||
|
<Form.Check
|
||||||
|
inline
|
||||||
|
type="radio"
|
||||||
|
id={`field-${field.key}-no`}
|
||||||
|
name={field.key}
|
||||||
|
label="No"
|
||||||
|
value="no"
|
||||||
|
checked={rhf.value === 'no'}
|
||||||
|
onChange={() => rhf.onChange('no')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (field.type === 'radio') {
|
if (field.type === 'radio') {
|
||||||
|
|
@ -264,11 +307,33 @@ function FieldControl({ field, control, register, moduleName, onUploadingChange
|
||||||
}
|
}
|
||||||
if (field.type === 'checkbox') {
|
if (field.type === 'checkbox') {
|
||||||
return (
|
return (
|
||||||
<div>
|
<Controller
|
||||||
{Object.entries(field.values || {}).map(([value, label]) => (
|
name={field.key}
|
||||||
<Form.Check key={value} type="checkbox" label={label} value={value} {...register(field.key)} />
|
control={control}
|
||||||
))}
|
render={({ field: rhf }) => {
|
||||||
</div>
|
const selected = Array.isArray(rhf.value) ? rhf.value.map(String) : [];
|
||||||
|
return (
|
||||||
|
<div className="d-flex flex-wrap align-items-center gap-3">
|
||||||
|
{Object.entries(field.values || {}).map(([value, label]) => (
|
||||||
|
<Form.Check
|
||||||
|
key={value}
|
||||||
|
inline
|
||||||
|
type="checkbox"
|
||||||
|
id={`field-${field.key}-${value}`}
|
||||||
|
label={label}
|
||||||
|
checked={selected.includes(String(value))}
|
||||||
|
onChange={(event) => {
|
||||||
|
const next = event.target.checked
|
||||||
|
? [...selected, value]
|
||||||
|
: selected.filter((item) => item !== String(value));
|
||||||
|
rhf.onChange(next);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (field.type === 'bigmultiselect') {
|
if (field.type === 'bigmultiselect') {
|
||||||
|
|
@ -411,6 +476,16 @@ function FieldControl({ field, control, register, moduleName, onUploadingChange
|
||||||
if (field.type === 'reminders') {
|
if (field.type === 'reminders') {
|
||||||
return <ReminderRowsField field={field} control={control} />;
|
return <ReminderRowsField field={field} control={control} />;
|
||||||
}
|
}
|
||||||
|
if (field.type === 'template_positions') {
|
||||||
|
return (
|
||||||
|
<TemplatePositionsField
|
||||||
|
field={field}
|
||||||
|
control={control}
|
||||||
|
moduleName={moduleName}
|
||||||
|
onUploadingChange={onUploadingChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
if (field.type === 'dependent_select') {
|
if (field.type === 'dependent_select') {
|
||||||
return <DependentSelectField field={field} control={control} watch={watch} />;
|
return <DependentSelectField field={field} control={control} watch={watch} />;
|
||||||
}
|
}
|
||||||
|
|
@ -581,7 +656,7 @@ export default function EntityForm({ module: config }) {
|
||||||
{fields.map((field) => {
|
{fields.map((field) => {
|
||||||
if (!isFieldVisible(field, watched)) return null;
|
if (!isFieldVisible(field, watched)) return null;
|
||||||
return field.type === 'hidden' ? (
|
return field.type === 'hidden' ? (
|
||||||
<FieldControl key={field.key} field={field} control={control} register={register} moduleName={config.module} onUploadingChange={onUploadingChange} />
|
<FieldControl key={field.key} field={field} control={control} register={register} watch={watch} moduleName={config.module} onUploadingChange={onUploadingChange} />
|
||||||
) : (
|
) : (
|
||||||
<Col md={field.fullwidth ? 12 : 6} className="mb-3 min-w-0" key={field.key}>
|
<Col md={field.fullwidth ? 12 : 6} className="mb-3 min-w-0" key={field.key}>
|
||||||
{field.hide_label ? null : (
|
{field.hide_label ? null : (
|
||||||
|
|
@ -589,7 +664,7 @@ export default function EntityForm({ module: config }) {
|
||||||
{field.title} {field.required ? <span className="text-danger">*</span> : null}
|
{field.title} {field.required ? <span className="text-danger">*</span> : null}
|
||||||
</Form.Label>
|
</Form.Label>
|
||||||
)}
|
)}
|
||||||
<FieldControl field={field} control={control} register={register} moduleName={config.module} onUploadingChange={onUploadingChange} />
|
<FieldControl field={field} control={control} register={register} watch={watch} moduleName={config.module} onUploadingChange={onUploadingChange} />
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,44 @@
|
||||||
import { Controller } from 'react-hook-form';
|
import { useEffect } from 'react';
|
||||||
|
import { useController } from 'react-hook-form';
|
||||||
import { Form } from 'react-bootstrap';
|
import { Form } from 'react-bootstrap';
|
||||||
|
|
||||||
export default function DependentSelectField({ field, control, watch }) {
|
export default function DependentSelectField({ field, control, watch }) {
|
||||||
const parentValue = watch(field.dependsOn);
|
const parentValue = watch(field.dependsOn);
|
||||||
const staticOptions = field.staticOptions || {};
|
const staticOptions = Object.entries(field.staticOptions || {}).map(([value, label]) => ({ value, label }));
|
||||||
const questions = (field.questions || []).filter((question) => question.entity_id === parentValue);
|
const allowedTypes = field.questionTypes || (field.questionType ? [field.questionType] : null);
|
||||||
const options = { ...staticOptions };
|
const questions = (field.questions || []).filter((question) => {
|
||||||
questions.forEach((question) => {
|
const questionFormId = question.entity_id ?? question.form_id;
|
||||||
if (question.code) options[question.code] = `${question.question || question.code} (Only Experts)`;
|
if (String(questionFormId ?? '') !== String(parentValue || '')) return false;
|
||||||
|
if (!allowedTypes) return true;
|
||||||
|
return allowedTypes.includes(String(question.type || '').toLowerCase());
|
||||||
});
|
});
|
||||||
|
const options = [
|
||||||
|
...staticOptions,
|
||||||
|
...questions
|
||||||
|
.filter((question) => question.code)
|
||||||
|
.map((question) => ({
|
||||||
|
value: question.code,
|
||||||
|
label: `${question.question || question.code} (Only Experts)`,
|
||||||
|
})),
|
||||||
|
];
|
||||||
|
const optionValues = new Set(options.map((option) => String(option.value)));
|
||||||
|
const fallback = staticOptions[0]?.value || '';
|
||||||
|
const { field: rhf } = useController({ name: field.key, control });
|
||||||
|
const selected = optionValues.has(String(rhf.value || '')) ? rhf.value : fallback;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (String(rhf.value || '') === String(selected || '')) return;
|
||||||
|
rhf.onChange(selected);
|
||||||
|
}, [parentValue, selected, rhf.value, rhf.onChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Controller
|
<Form.Select required={field.required} value={selected || ''} onChange={(e) => rhf.onChange(e.target.value)}>
|
||||||
name={field.key}
|
{staticOptions.length ? null : <option value=""> -- Select {field.title} -- </option>}
|
||||||
control={control}
|
{options.map((option, index) => (
|
||||||
render={({ field: rhf }) => (
|
<option key={`${option.value}-${index}`} value={option.value}>
|
||||||
<Form.Select
|
{option.label}
|
||||||
required={field.required}
|
</option>
|
||||||
value={rhf.value || ''}
|
))}
|
||||||
onChange={(e) => rhf.onChange(e.target.value)}
|
</Form.Select>
|
||||||
>
|
|
||||||
<option value=""> -- Select {field.title} -- </option>
|
|
||||||
{Object.entries(options).map(([value, label]) => (
|
|
||||||
<option key={value} value={value}>
|
|
||||||
{label}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</Form.Select>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ function emptyRow() {
|
||||||
checksubmission_days: '',
|
checksubmission_days: '',
|
||||||
message: '',
|
message: '',
|
||||||
plan_date_field: '',
|
plan_date_field: '',
|
||||||
|
notification_type: 'normal',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,6 +166,17 @@ export default function ReminderRowsField({ field, control }) {
|
||||||
onChange={(e) => rhf.onChange(patchRow(rows, index, { plan_date_field: e.target.value }))}
|
onChange={(e) => rhf.onChange(patchRow(rows, index, { plan_date_field: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col md={2}>
|
||||||
|
<Form.Label>Notification Type</Form.Label>
|
||||||
|
<Form.Select
|
||||||
|
required
|
||||||
|
value={row.notification_type || 'normal'}
|
||||||
|
onChange={(e) => rhf.onChange(patchRow(rows, index, { notification_type: e.target.value }))}
|
||||||
|
>
|
||||||
|
<option value="normal">Normal</option>
|
||||||
|
<option value="overlay_custom">Overlay Custom</option>
|
||||||
|
</Form.Select>
|
||||||
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
import { Button, Col, Form, Row } from 'react-bootstrap';
|
||||||
|
import { Controller } from 'react-hook-form';
|
||||||
|
import S3FileField from '@/components/S3FileField';
|
||||||
|
|
||||||
|
const YES_NO = [
|
||||||
|
{ value: 'no', label: 'No' },
|
||||||
|
{ value: 'yes', label: 'Yes' },
|
||||||
|
];
|
||||||
|
|
||||||
|
function emptyRow() {
|
||||||
|
return {
|
||||||
|
template: '',
|
||||||
|
createpdf: 'no',
|
||||||
|
addlink: 'no',
|
||||||
|
linkfield: '',
|
||||||
|
positions: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function patchRow(rows, index, patch) {
|
||||||
|
return rows.map((row, i) => (i === index ? { ...row, ...patch } : row));
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TemplatePositionsField({ field, control, moduleName, onUploadingChange }) {
|
||||||
|
const linkFields = field.values || field.linkFields || {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Controller
|
||||||
|
name={field.key}
|
||||||
|
control={control}
|
||||||
|
render={({ field: rhf }) => {
|
||||||
|
const rows = Array.isArray(rhf.value) ? rhf.value : [];
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="d-flex justify-content-end mb-2">
|
||||||
|
<Button
|
||||||
|
variant="info"
|
||||||
|
size="sm"
|
||||||
|
type="button"
|
||||||
|
onClick={() => rhf.onChange([...rows, emptyRow()])}
|
||||||
|
>
|
||||||
|
Add New Template
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{rows.length === 0 ? <div className="text-muted fs-12">No templates</div> : null}
|
||||||
|
{rows.map((row, index) => (
|
||||||
|
<div key={index} className="border rounded p-3 mb-3">
|
||||||
|
<Row className="g-3">
|
||||||
|
<Col md={8}>
|
||||||
|
<S3FileField
|
||||||
|
field={{ type: 'image', allowedExtensions: ['png', 'jpg', 'jpeg'], uploadModule: 'personalization' }}
|
||||||
|
value={row.template || ''}
|
||||||
|
onChange={(url) => rhf.onChange(patchRow(rows, index, { template: url }))}
|
||||||
|
moduleName={moduleName}
|
||||||
|
onUploadingChange={onUploadingChange}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col md={3}>
|
||||||
|
<Form.Label>Include in PDF</Form.Label>
|
||||||
|
<Form.Select
|
||||||
|
className="mb-2"
|
||||||
|
value={row.createpdf || 'no'}
|
||||||
|
onChange={(e) => rhf.onChange(patchRow(rows, index, { createpdf: e.target.value }))}
|
||||||
|
>
|
||||||
|
{YES_NO.map((option) => (
|
||||||
|
<option key={option.value} value={option.value}>
|
||||||
|
{option.label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Form.Select>
|
||||||
|
<Form.Label>Add Link to PDF</Form.Label>
|
||||||
|
<Form.Select
|
||||||
|
className="mb-2"
|
||||||
|
value={row.addlink || 'no'}
|
||||||
|
onChange={(e) => rhf.onChange(patchRow(rows, index, { addlink: e.target.value }))}
|
||||||
|
>
|
||||||
|
{YES_NO.map((option) => (
|
||||||
|
<option key={option.value} value={option.value}>
|
||||||
|
{option.label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Form.Select>
|
||||||
|
<Form.Label>Link Field</Form.Label>
|
||||||
|
<Form.Select
|
||||||
|
value={row.linkfield || ''}
|
||||||
|
onChange={(e) => rhf.onChange(patchRow(rows, index, { linkfield: e.target.value }))}
|
||||||
|
>
|
||||||
|
<option value=""> -- Select Link Field -- </option>
|
||||||
|
{Object.entries(linkFields).map(([value, label]) => (
|
||||||
|
<option key={value} value={value}>
|
||||||
|
{label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Form.Select>
|
||||||
|
</Col>
|
||||||
|
<Col md={1} className="d-flex align-items-start pt-1">
|
||||||
|
<Button
|
||||||
|
variant="danger"
|
||||||
|
size="sm"
|
||||||
|
type="button"
|
||||||
|
onClick={() => rhf.onChange(rows.filter((_, i) => i !== index))}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
<Col md={12}>
|
||||||
|
<Form.Control
|
||||||
|
as="textarea"
|
||||||
|
rows={4}
|
||||||
|
placeholder="Enter Position"
|
||||||
|
value={row.positions || ''}
|
||||||
|
onChange={(e) => rhf.onChange(patchRow(rows, index, { positions: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -122,7 +122,6 @@ const formentitys = {
|
||||||
type: 'multiselect',
|
type: 'multiselect',
|
||||||
values: userAttributes,
|
values: userAttributes,
|
||||||
default: [],
|
default: [],
|
||||||
showIf: { show_user_attributes: 'yes' },
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'form_type',
|
key: 'form_type',
|
||||||
|
|
@ -234,6 +233,7 @@ const formentitys = {
|
||||||
next.contact_attributes = asArray(next.contact_attributes);
|
next.contact_attributes = asArray(next.contact_attributes);
|
||||||
next.show_user_attributes = yesno(next.show_user_attributes, 'no');
|
next.show_user_attributes = yesno(next.show_user_attributes, 'no');
|
||||||
next.user_attributes = asArray(next.user_attributes);
|
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_email_notification = asArray(next.roles_email_notification);
|
||||||
next.roles_push_notification = asArray(next.roles_push_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_approvers = Array.isArray(next.workflow_approvers) && next.workflow_approvers.length ? next.workflow_approvers : ['l1manager'];
|
||||||
|
|
@ -248,6 +248,7 @@ const formentitys = {
|
||||||
payload.contact_attributes = asArray(payload.contact_attributes);
|
payload.contact_attributes = asArray(payload.contact_attributes);
|
||||||
payload.show_user_attributes = payload.show_user_attributes === 'yes' ? 'yes' : 'no';
|
payload.show_user_attributes = payload.show_user_attributes === 'yes' ? 'yes' : 'no';
|
||||||
payload.user_attributes = asArray(payload.user_attributes);
|
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.enrollment_form_attributes = asArray(payload.enrollment_form_attributes);
|
||||||
payload.roles_email_notification = asArray(payload.roles_email_notification);
|
payload.roles_email_notification = asArray(payload.roles_email_notification);
|
||||||
payload.roles_push_notification = asArray(payload.roles_push_notification);
|
payload.roles_push_notification = asArray(payload.roles_push_notification);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ const formexports = {
|
||||||
required: true,
|
required: true,
|
||||||
dependsOn: 'form_id',
|
dependsOn: 'form_id',
|
||||||
questions,
|
questions,
|
||||||
|
questionType: 'date',
|
||||||
|
default: 'record_date',
|
||||||
staticOptions: { record_date: 'Default Date (Recommended)' },
|
staticOptions: { record_date: 'Default Date (Recommended)' },
|
||||||
},
|
},
|
||||||
{ key: 'start_date', title: 'Start Date', type: 'date', required: true },
|
{ key: 'start_date', title: 'Start Date', type: 'date', required: true },
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,43 @@ import { splitHash } from '@/helpers/metric';
|
||||||
|
|
||||||
const STATUS = { active: 'Active', disabled: 'Disabled' };
|
const STATUS = { active: 'Active', disabled: 'Disabled' };
|
||||||
|
|
||||||
|
function asList(value) {
|
||||||
|
if (value == null || value === '') return [];
|
||||||
|
if (Array.isArray(value)) return value;
|
||||||
|
if (typeof value === 'object') return Object.values(value);
|
||||||
|
return [value];
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringifyPositions(value) {
|
||||||
|
if (value == null || value === '') return '';
|
||||||
|
if (typeof value === 'string') return value;
|
||||||
|
try {
|
||||||
|
return JSON.stringify(value, null, 2);
|
||||||
|
} catch {
|
||||||
|
return String(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function flattenMappings(item) {
|
||||||
|
const templates = asList(item?.templates);
|
||||||
|
const positions = asList(item?.positions);
|
||||||
|
const createpdf = asList(item?.createpdf);
|
||||||
|
const addlink = asList(item?.addlink);
|
||||||
|
const linkfield = asList(item?.linkfield);
|
||||||
|
const length = Math.max(templates.length, positions.length, createpdf.length, addlink.length, linkfield.length);
|
||||||
|
const rows = [];
|
||||||
|
for (let index = 0; index < length; index += 1) {
|
||||||
|
rows.push({
|
||||||
|
template: templates[index] || '',
|
||||||
|
createpdf: createpdf[index] === 'yes' ? 'yes' : 'no',
|
||||||
|
addlink: addlink[index] === 'yes' ? 'yes' : 'no',
|
||||||
|
linkfield: linkfield[index] || '',
|
||||||
|
positions: stringifyPositions(positions[index]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
const formpersonalizations = {
|
const formpersonalizations = {
|
||||||
service: 'form',
|
service: 'form',
|
||||||
module: 'personalization',
|
module: 'personalization',
|
||||||
|
|
@ -26,24 +63,55 @@ const formpersonalizations = {
|
||||||
formFields: async ({ item } = {}) => {
|
formFields: async ({ item } = {}) => {
|
||||||
const entityId = item?.entity_id || '';
|
const entityId = item?.entity_id || '';
|
||||||
const questions = {};
|
const questions = {};
|
||||||
|
const linkFields = {};
|
||||||
if (entityId) {
|
if (entityId) {
|
||||||
const response = await signedGet('form', 'formquestion/get_all', { entity_id: entityId });
|
const response = await signedGet('form', 'formquestion/get_all', { entity_id: entityId });
|
||||||
(isSuccess(response) ? response.data?.items || [] : []).forEach((q) => {
|
(isSuccess(response) ? response.data?.items || [] : []).forEach((question) => {
|
||||||
if (q?.id) questions[q.id] = q.question || q.title || q.id;
|
if (question?.id) questions[question.id] = question.question || question.title || question.id;
|
||||||
|
if (question?.code) linkFields[question.code] = question.question || question.title || question.code;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
{ key: 'title', title: 'Title', type: 'text', required: true, fullwidth: true },
|
{ key: 'title', title: 'Title', type: 'text', required: true, fullwidth: true },
|
||||||
{ key: 'questions', title: 'Select 1 or Multiple questions (to be included in this personalization)', type: 'checkbox', values: questions, required: true },
|
{
|
||||||
|
key: 'questions',
|
||||||
|
title: 'Select 1 or Multiple questions (to be included in this personalization)',
|
||||||
|
type: 'checkbox',
|
||||||
|
values: questions,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
{ key: 'status', title: 'Status', type: 'select', required: true, values: STATUS },
|
{ key: 'status', title: 'Status', type: 'select', required: true, values: STATUS },
|
||||||
{ key: 'icon', title: 'Icon', type: 'image', required: true },
|
{ key: 'icon', title: 'Icon', type: 'image', required: true },
|
||||||
|
{
|
||||||
|
key: 'mappings',
|
||||||
|
title: 'Template and Positions',
|
||||||
|
type: 'template_positions',
|
||||||
|
fullwidth: true,
|
||||||
|
values: linkFields,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
beforeForm: (item, _mode, ctx) => ({
|
beforeForm: (item, _mode, ctx) => {
|
||||||
...item,
|
const next = {
|
||||||
entity_id: item.entity_id || ctx?.searchParams?.get('id') || '',
|
...item,
|
||||||
questions: splitHash(item.questions),
|
entity_id: item.entity_id || ctx?.searchParams?.get('id') || '',
|
||||||
}),
|
questions: splitHash(item.questions),
|
||||||
|
};
|
||||||
|
next.mappings = flattenMappings(next);
|
||||||
|
return next;
|
||||||
|
},
|
||||||
|
beforeSave: (data) => {
|
||||||
|
const mappings = Array.isArray(data.mappings) ? data.mappings : [];
|
||||||
|
const payload = { ...data };
|
||||||
|
payload.questions = Array.isArray(payload.questions) ? payload.questions.filter(Boolean) : [];
|
||||||
|
payload.templates = mappings.map((row) => row.template || '');
|
||||||
|
payload.positions = mappings.map((row) => row.positions || '');
|
||||||
|
payload.createpdf = mappings.map((row) => (row.createpdf === 'yes' ? 'yes' : 'no'));
|
||||||
|
payload.addlink = mappings.map((row) => (row.addlink === 'yes' ? 'yes' : 'no'));
|
||||||
|
payload.linkfield = mappings.map((row) => row.linkfield || '');
|
||||||
|
delete payload.mappings;
|
||||||
|
return payload;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default formpersonalizations;
|
export default formpersonalizations;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ const FORM_QUESTION_TYPES = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const STATUS = { active: 'Active', disabled: 'Disabled' };
|
const STATUS = { active: 'Active', disabled: 'Disabled' };
|
||||||
|
const OPTION_TYPES = ['dropdown', 'checkbox', 'radio', 'radiometrix', 'multitextbox'];
|
||||||
|
|
||||||
const formquestions = {
|
const formquestions = {
|
||||||
service: 'form',
|
service: 'form',
|
||||||
|
|
@ -49,7 +50,7 @@ const formquestions = {
|
||||||
{ key: 'required', title: 'Is Required', type: 'yesno', required: true },
|
{ key: 'required', title: 'Is Required', type: 'yesno', required: true },
|
||||||
{ key: 'sort_order', title: 'Sort Order', type: 'number' },
|
{ key: 'sort_order', title: 'Sort Order', type: 'number' },
|
||||||
{ key: 'status', title: 'Status', type: 'select', required: true, values: STATUS },
|
{ key: 'status', title: 'Status', type: 'select', required: true, values: STATUS },
|
||||||
{ key: 'options', title: 'Options', type: 'mapping', variant: 'question_options', fullwidth: true },
|
{ key: 'options', title: 'Options', type: 'mapping', variant: 'question_options', fullwidth: true, showIf: { type: OPTION_TYPES } },
|
||||||
],
|
],
|
||||||
beforeForm: (item) => ({
|
beforeForm: (item) => ({
|
||||||
...item,
|
...item,
|
||||||
|
|
@ -59,7 +60,7 @@ const formquestions = {
|
||||||
beforeSave: (data) => ({
|
beforeSave: (data) => ({
|
||||||
...data,
|
...data,
|
||||||
sort_order: data.sort_order === '' || data.sort_order == null ? 0 : Number(data.sort_order),
|
sort_order: data.sort_order === '' || data.sort_order == null ? 0 : Number(data.sort_order),
|
||||||
options: Array.isArray(data.options) ? data.options : [],
|
options: OPTION_TYPES.includes(data.type) && Array.isArray(data.options) ? data.options : [],
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,73 @@
|
||||||
|
import { signedGet, isSuccess } from '@/api/client';
|
||||||
import { dropdownMap } from '@/api/dropdowns';
|
import { dropdownMap } from '@/api/dropdowns';
|
||||||
import {
|
import {
|
||||||
DEFAULT_INTERVAL_VALUES,
|
|
||||||
INTERVAL_VALUES,
|
INTERVAL_VALUES,
|
||||||
metricOptions,
|
metricOptions,
|
||||||
parseCombinedMetrics,
|
parseCombinedMetrics,
|
||||||
splitHash,
|
splitHash,
|
||||||
|
stringifyCombinedMetrics,
|
||||||
toDateInput,
|
toDateInput,
|
||||||
} from '@/helpers/metric';
|
} from '@/helpers/metric';
|
||||||
|
|
||||||
const STATUS = { active: 'Active', disabled: 'Disabled' };
|
const STATUS = { active: 'Active', disabled: 'Disabled' };
|
||||||
const YES_NO = { yes: 'Yes', no: 'No' };
|
const YES_NO = { yes: 'Yes', no: 'No' };
|
||||||
|
const MANAGER_LEVELS = {
|
||||||
|
l1manager: 'L1 Manager',
|
||||||
|
l2manager: 'L2 Manager',
|
||||||
|
l3manager: 'L3 Manager',
|
||||||
|
l4manager: 'L4 Manager',
|
||||||
|
};
|
||||||
|
const DEFAULT_INTERVAL_VALUES = {
|
||||||
|
'': 'Overall / All',
|
||||||
|
all: 'Overall',
|
||||||
|
'month-0': 'This Month',
|
||||||
|
'month-1': 'Last Month',
|
||||||
|
'month-3': 'Last 3 Months',
|
||||||
|
'month-6': 'Last 6 Months',
|
||||||
|
'month-12': 'Last 12 Months',
|
||||||
|
'day-0': 'Today',
|
||||||
|
'day-1': 'Yesterday',
|
||||||
|
'day-7': 'Last 7 Days',
|
||||||
|
'day-30': 'Last 30 Days',
|
||||||
|
'week-0': 'This week',
|
||||||
|
'week-1': 'Last week',
|
||||||
|
'yearfy-0': 'This Financial Year',
|
||||||
|
'yearfy-1': 'Last Financial Year',
|
||||||
|
'yearcy-0': 'This Calender Year',
|
||||||
|
'yearcy-1': 'Last Calender Year',
|
||||||
|
};
|
||||||
|
|
||||||
function asArray(value) {
|
function asArray(value) {
|
||||||
if (Array.isArray(value)) return value.filter((part) => part !== null && part !== undefined && part !== '');
|
if (Array.isArray(value)) return value.filter((part) => part !== null && part !== undefined && part !== '');
|
||||||
return splitHash(value);
|
return splitHash(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bySortOrder(left, right) {
|
||||||
|
return (Number(left?.sort_order) || 0) - (Number(right?.sort_order) || 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itemsToMap(items) {
|
||||||
|
const values = {};
|
||||||
|
(items || []).forEach((item) => {
|
||||||
|
const id = item?.id;
|
||||||
|
if (id === undefined || id === null || id === '') return;
|
||||||
|
values[id] = item.name || item.title || id;
|
||||||
|
});
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function teamOptions() {
|
||||||
|
const fromDropdown = await dropdownMap('detailing', 'team', (item) => item.name);
|
||||||
|
if (Object.keys(fromDropdown).length) return fromDropdown;
|
||||||
|
for (const path of ['team/get_all', 'team/list']) {
|
||||||
|
const response = await signedGet('detailing', path);
|
||||||
|
const items = isSuccess(response) ? response.data?.items || response.data || [] : [];
|
||||||
|
const values = itemsToMap(Array.isArray(items) ? items : []);
|
||||||
|
if (Object.keys(values).length) return values;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const leaderboards = {
|
const leaderboards = {
|
||||||
service: 'reports',
|
service: 'reports',
|
||||||
module: 'roles_leaderboard',
|
module: 'roles_leaderboard',
|
||||||
|
|
@ -26,6 +78,7 @@ const leaderboards = {
|
||||||
listFields: [
|
listFields: [
|
||||||
{ key: 'actions', title: 'Actions', buttons: ['edit', 'delete', { name: 'report', to: (row) => `/leaderboard/dashboard?id=${row.id}`, title: 'Dashboard' }] },
|
{ key: 'actions', title: 'Actions', buttons: ['edit', 'delete', { name: 'report', to: (row) => `/leaderboard/dashboard?id=${row.id}`, title: 'Dashboard' }] },
|
||||||
{ key: 'name', title: 'Name', type: 'text' },
|
{ key: 'name', title: 'Name', type: 'text' },
|
||||||
|
{ key: 'leaderboard_roles_type_label', title: 'Type', type: 'text' },
|
||||||
{ key: 'sort_order', title: 'Sort Order', type: 'number' },
|
{ key: 'sort_order', title: 'Sort Order', type: 'number' },
|
||||||
{ key: 'visible_roles_label', title: 'Visible Roles', type: 'text' },
|
{ key: 'visible_roles_label', title: 'Visible Roles', type: 'text' },
|
||||||
{ key: 'validity_start', title: 'Validity start', type: 'text' },
|
{ key: 'validity_start', title: 'Validity start', type: 'text' },
|
||||||
|
|
@ -36,18 +89,47 @@ const leaderboards = {
|
||||||
(items || []).map((item) => ({
|
(items || []).map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
visible_roles_label: asArray(item.visible_roles).join(', '),
|
visible_roles_label: asArray(item.visible_roles).join(', '),
|
||||||
|
leaderboard_roles_type_label: item.leaderboard_roles_type === 'team' ? 'Team' : 'Roles',
|
||||||
sort_order: item.sort_order ?? 0,
|
sort_order: item.sort_order ?? 0,
|
||||||
})),
|
})),
|
||||||
formFields: async () => {
|
formFields: async () => {
|
||||||
const [metrics, roles] = await Promise.all([metricOptions(), dropdownMap('ums', 'roles', (item) => item.name)]);
|
const [metrics, roles, teams] = await Promise.all([
|
||||||
|
metricOptions(),
|
||||||
|
dropdownMap('ums', 'roles', (item) => item.name),
|
||||||
|
teamOptions(),
|
||||||
|
]);
|
||||||
return [
|
return [
|
||||||
{ key: 'name', title: 'Name', type: 'text', required: true },
|
{ key: 'name', title: 'Name', type: 'text', required: true },
|
||||||
{ key: 'sort_order', title: 'Sort Order', type: 'number', required: true },
|
{ key: 'sort_order', title: 'Sort Order', type: 'number', required: true },
|
||||||
{ key: 'validity_start', title: 'Validity start', type: 'date', required: true },
|
{ key: 'validity_start', title: 'Validity start', type: 'date', required: true },
|
||||||
{ key: 'validity_end', title: 'Validity end', type: 'date', required: true },
|
{ key: 'validity_end', title: 'Validity end', type: 'date', required: true },
|
||||||
|
{
|
||||||
|
key: 'leaderboard_roles_type',
|
||||||
|
title: 'Leaderboard Type',
|
||||||
|
type: 'select',
|
||||||
|
required: true,
|
||||||
|
values: { roles: 'Roles', team: 'Team' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'leaderboard_team_ids',
|
||||||
|
title: 'Teams',
|
||||||
|
type: 'multiselect',
|
||||||
|
values: teams,
|
||||||
|
fullwidth: true,
|
||||||
|
required: true,
|
||||||
|
showIf: { leaderboard_roles_type: 'team' },
|
||||||
|
},
|
||||||
{ key: 'visible_roles', title: 'Visible Roles', type: 'multiselect', values: roles, required: true },
|
{ key: 'visible_roles', title: 'Visible Roles', type: 'multiselect', values: roles, required: true },
|
||||||
{ key: 'reporting_roles', title: 'Reporting Roles', type: 'multiselect', values: roles, required: true },
|
{ key: 'reporting_roles', title: 'Reporting Roles', type: 'multiselect', values: roles, required: true },
|
||||||
{ key: 'rank_roles', title: 'Rank Roles', type: 'rank_roles', roles, required: true, fullwidth: true },
|
{
|
||||||
|
key: 'rank_roles',
|
||||||
|
title: 'Rank Roles',
|
||||||
|
type: 'rank_roles',
|
||||||
|
roles,
|
||||||
|
required: true,
|
||||||
|
fullwidth: true,
|
||||||
|
showIf: { leaderboard_roles_type: 'roles' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'metrics',
|
key: 'metrics',
|
||||||
title: 'Choose Metric',
|
title: 'Choose Metric',
|
||||||
|
|
@ -59,7 +141,7 @@ const leaderboards = {
|
||||||
},
|
},
|
||||||
{ key: 'combined_metrics', title: 'Combined Metrics (if any)', type: 'combined_metrics', fullwidth: true },
|
{ key: 'combined_metrics', title: 'Combined Metrics (if any)', type: 'combined_metrics', fullwidth: true },
|
||||||
{ key: 'intervals', title: 'Intervals', type: 'multiselect', required: true, values: INTERVAL_VALUES },
|
{ key: 'intervals', title: 'Intervals', type: 'multiselect', required: true, values: INTERVAL_VALUES },
|
||||||
{ key: 'default_interval', title: 'Default Interval', type: 'select', values: { '': 'Overall / All', all: 'Overall', ...DEFAULT_INTERVAL_VALUES } },
|
{ key: 'default_interval', title: 'Default Interval', type: 'select', values: DEFAULT_INTERVAL_VALUES },
|
||||||
{ key: 'show_positions', title: 'Show Positions', type: 'select', required: true, values: YES_NO },
|
{ key: 'show_positions', title: 'Show Positions', type: 'select', required: true, values: YES_NO },
|
||||||
{
|
{
|
||||||
key: 'show_positions_type',
|
key: 'show_positions_type',
|
||||||
|
|
@ -68,40 +150,70 @@ const leaderboards = {
|
||||||
required: true,
|
required: true,
|
||||||
values: { all: 'All', loggedin: 'Logged In' },
|
values: { all: 'All', loggedin: 'Logged In' },
|
||||||
},
|
},
|
||||||
|
{ key: 'show_units_export', title: 'Show Units Export', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'show_normal_metrics', title: 'Show Normal Metrics', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'show_combined_metrics', title: 'Show Combined Metrics', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'manager_details', title: 'Manager Details', type: 'multiselect', values: MANAGER_LEVELS },
|
||||||
|
{ key: 'total_units_name', title: 'Total Units Name', type: 'text', placeholder: 'Total Units' },
|
||||||
|
{ key: 'bg_color', title: 'Background Color', type: 'color' },
|
||||||
|
{ key: 'bg_image', title: 'Background Image', type: 'image', uploadModule: 'leaderboard' },
|
||||||
|
{ key: 'icon', title: 'Icon', type: 'image', uploadModule: 'leaderboard' },
|
||||||
{ key: 'status', title: 'Status', type: 'select', required: true, values: STATUS },
|
{ key: 'status', title: 'Status', type: 'select', required: true, values: STATUS },
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
beforeForm: (item) => {
|
beforeForm: (item) => {
|
||||||
const next = { ...item };
|
const next = { ...item };
|
||||||
next.sort_order = next.sort_order ?? 0;
|
next.sort_order = next.sort_order ?? 0;
|
||||||
next.show_positions = next.show_positions || 'no';
|
next.show_positions = String(next.show_positions || 'no').toLowerCase();
|
||||||
next.show_positions_type = next.show_positions_type || 'all';
|
next.show_positions_type = next.show_positions_type || 'all';
|
||||||
|
next.show_units_export = next.show_units_export === 'no' ? 'no' : 'yes';
|
||||||
|
next.show_normal_metrics = next.show_normal_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
next.show_combined_metrics = next.show_combined_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
next.total_units_name = next.total_units_name || '';
|
||||||
next.status = next.status || 'active';
|
next.status = next.status || 'active';
|
||||||
next.default_interval = next.default_interval ?? '';
|
next.default_interval = next.default_interval ?? '';
|
||||||
|
next.leaderboard_roles_type = next.leaderboard_roles_type === 'team' ? 'team' : 'roles';
|
||||||
|
next.bg_color = next.bg_color || '';
|
||||||
|
next.bg_image = next.bg_image || '';
|
||||||
|
next.icon = next.icon || '';
|
||||||
next.validity_start = toDateInput(next.validity_start);
|
next.validity_start = toDateInput(next.validity_start);
|
||||||
next.validity_end = toDateInput(next.validity_end);
|
next.validity_end = toDateInput(next.validity_end);
|
||||||
next.visible_roles = asArray(next.visible_roles);
|
next.visible_roles = asArray(next.visible_roles);
|
||||||
next.reporting_roles = asArray(next.reporting_roles);
|
next.reporting_roles = asArray(next.reporting_roles);
|
||||||
next.intervals = asArray(next.intervals);
|
next.intervals = asArray(next.intervals);
|
||||||
next.rank_roles = Array.isArray(next.rank_roles) ? next.rank_roles : [];
|
next.leaderboard_team_ids = asArray(next.leaderboard_team_ids);
|
||||||
next.metrics = Array.isArray(next.metrics)
|
next.manager_details = asArray(next.manager_details);
|
||||||
? next.metrics.map((row) => ({
|
if (!next.manager_details.length) next.manager_details = ['l1manager'];
|
||||||
metric: row.metric || '',
|
next.rank_roles = (Array.isArray(next.rank_roles) ? next.rank_roles : []).slice().sort(bySortOrder);
|
||||||
display: row.display || '',
|
next.metrics = (Array.isArray(next.metrics) ? next.metrics : [])
|
||||||
sort_order: row.sort_order ?? 0,
|
.map((row) => ({
|
||||||
weight: row.weight ?? 1,
|
metric: row.metric || '',
|
||||||
list_view: row.list_view || 'yes',
|
display: row.display || '',
|
||||||
}))
|
sort_order: row.sort_order ?? 0,
|
||||||
: [];
|
weight: row.weight ?? 1,
|
||||||
|
list_view: row.list_view || 'yes',
|
||||||
|
}))
|
||||||
|
.sort(bySortOrder);
|
||||||
next.combined_metrics = parseCombinedMetrics(next.combined_metrics);
|
next.combined_metrics = parseCombinedMetrics(next.combined_metrics);
|
||||||
return next;
|
return next;
|
||||||
},
|
},
|
||||||
beforeSave: (data) => {
|
beforeSave: (data) => {
|
||||||
const payload = { ...data };
|
const payload = { ...data };
|
||||||
|
const leaderboardType = payload.leaderboard_roles_type === 'team' ? 'team' : 'roles';
|
||||||
|
payload.leaderboard_roles_type = leaderboardType;
|
||||||
payload.sort_order = payload.sort_order === '' || payload.sort_order == null ? 0 : Number(payload.sort_order);
|
payload.sort_order = payload.sort_order === '' || payload.sort_order == null ? 0 : Number(payload.sort_order);
|
||||||
payload.visible_roles = asArray(payload.visible_roles);
|
payload.visible_roles = asArray(payload.visible_roles);
|
||||||
payload.reporting_roles = asArray(payload.reporting_roles);
|
payload.reporting_roles = asArray(payload.reporting_roles);
|
||||||
payload.intervals = asArray(payload.intervals);
|
payload.intervals = asArray(payload.intervals);
|
||||||
|
payload.leaderboard_team_ids = leaderboardType === 'team' ? asArray(payload.leaderboard_team_ids) : [];
|
||||||
|
payload.show_units_export = payload.show_units_export === 'no' ? 'no' : 'yes';
|
||||||
|
payload.show_normal_metrics = payload.show_normal_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
payload.show_combined_metrics = payload.show_combined_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
payload.total_units_name = payload.total_units_name || '';
|
||||||
|
payload.manager_details = asArray(payload.manager_details);
|
||||||
|
if (!payload.manager_details.length) payload.manager_details = ['l1manager'];
|
||||||
|
payload.bg_color = Array.isArray(payload.bg_color) ? '' : payload.bg_color || '';
|
||||||
|
payload.default_interval = payload.default_interval ?? '';
|
||||||
payload.rank_roles = (Array.isArray(payload.rank_roles) ? payload.rank_roles : [])
|
payload.rank_roles = (Array.isArray(payload.rank_roles) ? payload.rank_roles : [])
|
||||||
.filter((row) => row.title || row.role)
|
.filter((row) => row.title || row.role)
|
||||||
.map((row) => ({
|
.map((row) => ({
|
||||||
|
|
@ -118,7 +230,11 @@ const leaderboards = {
|
||||||
sort_order: row.sort_order === '' || row.sort_order == null ? 0 : Number(row.sort_order),
|
sort_order: row.sort_order === '' || row.sort_order == null ? 0 : Number(row.sort_order),
|
||||||
weight: row.weight === '' || row.weight == null ? '1' : String(row.weight),
|
weight: row.weight === '' || row.weight == null ? '1' : String(row.weight),
|
||||||
}));
|
}));
|
||||||
payload.combined_metrics = Array.isArray(payload.combined_metrics) ? payload.combined_metrics : [];
|
payload.combined_metrics = stringifyCombinedMetrics(
|
||||||
|
(Array.isArray(payload.combined_metrics) ? payload.combined_metrics : []).filter((row) => row?.type),
|
||||||
|
);
|
||||||
|
if (!payload.bg_image) delete payload.bg_image;
|
||||||
|
if (!payload.icon) delete payload.icon;
|
||||||
return payload;
|
return payload;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,12 @@ function normalizeCombined(row) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const YES_NO = { yes: 'Yes', no: 'No' };
|
const YES_NO = { yes: 'Yes', no: 'No' };
|
||||||
|
const MANAGER_LEVELS = {
|
||||||
|
l1manager: 'L1 Manager',
|
||||||
|
l2manager: 'L2 Manager',
|
||||||
|
l3manager: 'L3 Manager',
|
||||||
|
l4manager: 'L4 Manager',
|
||||||
|
};
|
||||||
|
|
||||||
const metriccampaigns = {
|
const metriccampaigns = {
|
||||||
service: 'metric',
|
service: 'metric',
|
||||||
|
|
@ -171,6 +177,11 @@ const metriccampaigns = {
|
||||||
required: true,
|
required: true,
|
||||||
values: { all: 'All', loggedin: 'Logged In' },
|
values: { all: 'All', loggedin: 'Logged In' },
|
||||||
},
|
},
|
||||||
|
{ key: 'show_units_export', title: 'Show Units Export', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'show_normal_metrics', title: 'Show Normal Metrics', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'show_combined_metrics', title: 'Show Combined Metrics', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'manager_details', title: 'Manager Details', type: 'multiselect', values: MANAGER_LEVELS },
|
||||||
|
{ key: 'total_units_name', title: 'Total Units Name', type: 'text', placeholder: 'Total Units' },
|
||||||
{ key: 'highlight_top', title: 'Highlight Top', type: 'text', placeholder: 'e.g. 10, 20, 30' },
|
{ key: 'highlight_top', title: 'Highlight Top', type: 'text', placeholder: 'e.g. 10, 20, 30' },
|
||||||
{ key: 'highlight_color', title: 'Highlight Color', type: 'text', placeholder: 'R-G-B-A or CSS color' },
|
{ key: 'highlight_color', title: 'Highlight Color', type: 'text', placeholder: 'R-G-B-A or CSS color' },
|
||||||
{
|
{
|
||||||
|
|
@ -202,11 +213,22 @@ const metriccampaigns = {
|
||||||
showManagerTeamRank: 'yes',
|
showManagerTeamRank: 'yes',
|
||||||
highlight_top: '',
|
highlight_top: '',
|
||||||
highlight_color: '',
|
highlight_color: '',
|
||||||
|
show_units_export: 'yes',
|
||||||
|
show_normal_metrics: 'yes',
|
||||||
|
show_combined_metrics: 'yes',
|
||||||
|
manager_details: ['l1manager'],
|
||||||
|
total_units_name: '',
|
||||||
...item,
|
...item,
|
||||||
};
|
};
|
||||||
next.campaign_visible_roles = asArray(next.campaign_visible_roles);
|
next.campaign_visible_roles = asArray(next.campaign_visible_roles);
|
||||||
next.reporting_roles = asArray(next.reporting_roles);
|
next.reporting_roles = asArray(next.reporting_roles);
|
||||||
next.intervals = asArray(next.intervals);
|
next.intervals = asArray(next.intervals);
|
||||||
|
next.manager_details = asArray(next.manager_details);
|
||||||
|
if (!next.manager_details.length) next.manager_details = ['l1manager'];
|
||||||
|
next.show_units_export = next.show_units_export === 'no' ? 'no' : 'yes';
|
||||||
|
next.show_normal_metrics = next.show_normal_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
next.show_combined_metrics = next.show_combined_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
next.total_units_name = next.total_units_name || '';
|
||||||
next.metrics = (Array.isArray(next.metrics) ? next.metrics : []).map(normalizeCampaignMetric);
|
next.metrics = (Array.isArray(next.metrics) ? next.metrics : []).map(normalizeCampaignMetric);
|
||||||
next.combined_metrics = parseCombinedMetrics(next.combined_metrics).map(normalizeCombined);
|
next.combined_metrics = parseCombinedMetrics(next.combined_metrics).map(normalizeCombined);
|
||||||
next.ranking_attributes = normalizeRankingAttributes(next.ranking_attributes);
|
next.ranking_attributes = normalizeRankingAttributes(next.ranking_attributes);
|
||||||
|
|
@ -253,6 +275,11 @@ const metriccampaigns = {
|
||||||
campaign_visible_roles: asArray(data.campaign_visible_roles),
|
campaign_visible_roles: asArray(data.campaign_visible_roles),
|
||||||
reporting_roles: asArray(data.reporting_roles),
|
reporting_roles: asArray(data.reporting_roles),
|
||||||
intervals: asArray(data.intervals),
|
intervals: asArray(data.intervals),
|
||||||
|
manager_details: asArray(data.manager_details).length ? asArray(data.manager_details) : ['l1manager'],
|
||||||
|
show_units_export: data.show_units_export === 'no' ? 'no' : 'yes',
|
||||||
|
show_normal_metrics: data.show_normal_metrics === 'no' ? 'no' : 'yes',
|
||||||
|
show_combined_metrics: data.show_combined_metrics === 'no' ? 'no' : 'yes',
|
||||||
|
total_units_name: data.total_units_name || '',
|
||||||
sort_order: Number.parseInt(data.sort_order, 10) || 0,
|
sort_order: Number.parseInt(data.sort_order, 10) || 0,
|
||||||
validity_start: toApiDate(data.validity_start),
|
validity_start: toApiDate(data.validity_start),
|
||||||
validity_end: toApiDate(data.validity_end),
|
validity_end: toApiDate(data.validity_end),
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,12 @@ const metricviews = {
|
||||||
values: { all: 'All', loggedin: 'Logged In' },
|
values: { all: 'All', loggedin: 'Logged In' },
|
||||||
},
|
},
|
||||||
{ key: 'contact_attributes', title: 'Include Doctor Attributes', type: 'multiselect', values: contactAttributes },
|
{ key: 'contact_attributes', title: 'Include Doctor Attributes', type: 'multiselect', values: contactAttributes },
|
||||||
|
{
|
||||||
|
key: 'team_leaderboard_widget_roles',
|
||||||
|
title: 'Team Leaderboard Widget Roles',
|
||||||
|
type: 'multiselect',
|
||||||
|
values: roles,
|
||||||
|
},
|
||||||
{ key: 'show_user_attributes', title: 'Show User Attributes', type: 'yesno', required: true, default: 'no' },
|
{ key: 'show_user_attributes', title: 'Show User Attributes', type: 'yesno', required: true, default: 'no' },
|
||||||
{
|
{
|
||||||
key: 'user_attributes',
|
key: 'user_attributes',
|
||||||
|
|
@ -206,7 +212,13 @@ const metricviews = {
|
||||||
type: 'multiselect',
|
type: 'multiselect',
|
||||||
values: userAttributes,
|
values: userAttributes,
|
||||||
default: [],
|
default: [],
|
||||||
showIf: { show_user_attributes: 'yes' },
|
},
|
||||||
|
{
|
||||||
|
key: 'stateheadwise_leaderboard',
|
||||||
|
title: 'Stateheadwise Leaderboard',
|
||||||
|
type: 'yesno',
|
||||||
|
required: true,
|
||||||
|
default: 'no',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
@ -219,9 +231,11 @@ const metricviews = {
|
||||||
show_positions_type: 'all',
|
show_positions_type: 'all',
|
||||||
show_user_attributes: 'no',
|
show_user_attributes: 'no',
|
||||||
user_attributes: [],
|
user_attributes: [],
|
||||||
|
stateheadwise_leaderboard: 'no',
|
||||||
list_chart_type: 'progressbar',
|
list_chart_type: 'progressbar',
|
||||||
value_views: ['value'],
|
value_views: ['value'],
|
||||||
default_tab: '',
|
default_tab: '',
|
||||||
|
team_leaderboard_widget_roles: [],
|
||||||
...item,
|
...item,
|
||||||
};
|
};
|
||||||
next.designations = asArray(next.designations);
|
next.designations = asArray(next.designations);
|
||||||
|
|
@ -240,8 +254,15 @@ const metricviews = {
|
||||||
next.default_tab = next.default_tab || '';
|
next.default_tab = next.default_tab || '';
|
||||||
next.intervals = asArray(next.intervals);
|
next.intervals = asArray(next.intervals);
|
||||||
next.contact_attributes = asArray(next.contact_attributes);
|
next.contact_attributes = asArray(next.contact_attributes);
|
||||||
next.show_user_attributes = next.show_user_attributes === 'yes' ? 'yes' : 'no';
|
next.team_leaderboard_widget_roles = asArray(
|
||||||
|
next.team_leaderboard_widget_roles || next.leaderboard_widget_roles || next.widget_roles,
|
||||||
|
);
|
||||||
|
next.show_user_attributes = ['yes', '1', 'true', true, 1].includes(next.show_user_attributes) ? 'yes' : 'no';
|
||||||
next.user_attributes = asArray(next.user_attributes);
|
next.user_attributes = asArray(next.user_attributes);
|
||||||
|
if (next.user_attributes.length && next.show_user_attributes !== 'yes') {
|
||||||
|
next.show_user_attributes = 'yes';
|
||||||
|
}
|
||||||
|
next.stateheadwise_leaderboard = next.stateheadwise_leaderboard === 'yes' ? 'yes' : 'no';
|
||||||
next.combined_metrics = parseCombinedMetrics(next.combined_metrics);
|
next.combined_metrics = parseCombinedMetrics(next.combined_metrics);
|
||||||
next.validity_start = toDateInput(next.validity_start);
|
next.validity_start = toDateInput(next.validity_start);
|
||||||
next.validity_end = toDateInput(next.validity_end);
|
next.validity_end = toDateInput(next.validity_end);
|
||||||
|
|
@ -309,8 +330,10 @@ const metricviews = {
|
||||||
default_tab: data.default_tab || '',
|
default_tab: data.default_tab || '',
|
||||||
intervals: asArray(data.intervals),
|
intervals: asArray(data.intervals),
|
||||||
contact_attributes: asArray(data.contact_attributes),
|
contact_attributes: asArray(data.contact_attributes),
|
||||||
|
team_leaderboard_widget_roles: asArray(data.team_leaderboard_widget_roles),
|
||||||
show_user_attributes: data.show_user_attributes === 'yes' ? 'yes' : 'no',
|
show_user_attributes: data.show_user_attributes === 'yes' ? 'yes' : 'no',
|
||||||
user_attributes: asArray(data.user_attributes),
|
user_attributes: asArray(data.user_attributes),
|
||||||
|
stateheadwise_leaderboard: data.stateheadwise_leaderboard === 'yes' ? 'yes' : 'no',
|
||||||
combined_metrics: stringifyCombinedMetrics(
|
combined_metrics: stringifyCombinedMetrics(
|
||||||
(data.combined_metrics || [])
|
(data.combined_metrics || [])
|
||||||
.filter((row) => row.type)
|
.filter((row) => row.type)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,12 @@ import { metricOptions, toDateInput } from '@/helpers/metric';
|
||||||
|
|
||||||
const STATUS = { active: 'Active', disabled: 'Disabled' };
|
const STATUS = { active: 'Active', disabled: 'Disabled' };
|
||||||
const YES_NO = { yes: 'Yes', no: 'No' };
|
const YES_NO = { yes: 'Yes', no: 'No' };
|
||||||
|
const MANAGER_LEVELS = {
|
||||||
|
l1manager: 'L1 Manager',
|
||||||
|
l2manager: 'L2 Manager',
|
||||||
|
l3manager: 'L3 Manager',
|
||||||
|
l4manager: 'L4 Manager',
|
||||||
|
};
|
||||||
const DAYS = {
|
const DAYS = {
|
||||||
MON: 'Monday',
|
MON: 'Monday',
|
||||||
TUE: 'Tuesday',
|
TUE: 'Tuesday',
|
||||||
|
|
@ -195,6 +201,11 @@ const milestones = {
|
||||||
required: true,
|
required: true,
|
||||||
values: { all: 'All', loggedin: 'Logged In' },
|
values: { all: 'All', loggedin: 'Logged In' },
|
||||||
},
|
},
|
||||||
|
{ key: 'show_units_export', title: 'Show Units Export', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'show_normal_metrics', title: 'Show Normal Metrics', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'show_combined_metrics', title: 'Show Combined Metrics', type: 'select', values: YES_NO },
|
||||||
|
{ key: 'manager_details', title: 'Manager Details', type: 'multiselect', values: MANAGER_LEVELS },
|
||||||
|
{ key: 'total_units_name', title: 'Total Units Name', type: 'text', placeholder: 'Total Units' },
|
||||||
{ key: 'send_report', title: 'Send Report', type: 'select', required: true, values: YES_NO },
|
{ key: 'send_report', title: 'Send Report', type: 'select', required: true, values: YES_NO },
|
||||||
{
|
{
|
||||||
key: 'performance_period',
|
key: 'performance_period',
|
||||||
|
|
@ -276,6 +287,18 @@ const milestones = {
|
||||||
values: YES_NO,
|
values: YES_NO,
|
||||||
showIf: { send_report: 'yes' },
|
showIf: { send_report: 'yes' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'subject',
|
||||||
|
title: 'Report Subject',
|
||||||
|
type: 'text',
|
||||||
|
showIf: { send_report: 'yes' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'body',
|
||||||
|
title: 'Report Body',
|
||||||
|
type: 'textarea',
|
||||||
|
showIf: { send_report: 'yes' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'metrics',
|
key: 'metrics',
|
||||||
title: 'Metric Mapping',
|
title: 'Metric Mapping',
|
||||||
|
|
@ -326,7 +349,15 @@ const milestones = {
|
||||||
next.send_pending_users = fromBool(reportConfig.send_pending_users ?? false);
|
next.send_pending_users = fromBool(reportConfig.send_pending_users ?? false);
|
||||||
next.show_target_average = fromBool(reportConfig.show_target_average ?? false);
|
next.show_target_average = fromBool(reportConfig.show_target_average ?? false);
|
||||||
next.show_overall_average = fromBool(reportConfig.show_overall_average ?? false);
|
next.show_overall_average = fromBool(reportConfig.show_overall_average ?? false);
|
||||||
|
next.subject = reportConfig.subject || '';
|
||||||
|
next.body = reportConfig.body || '';
|
||||||
next.send_report = fromBool(next.send_report ?? false);
|
next.send_report = fromBool(next.send_report ?? false);
|
||||||
|
next.show_units_export = next.show_units_export === 'no' ? 'no' : 'yes';
|
||||||
|
next.show_normal_metrics = next.show_normal_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
next.show_combined_metrics = next.show_combined_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
next.manager_details = toStringList(next.manager_details);
|
||||||
|
if (!next.manager_details.length) next.manager_details = ['l1manager'];
|
||||||
|
next.total_units_name = next.total_units_name || '';
|
||||||
return next;
|
return next;
|
||||||
},
|
},
|
||||||
beforeSave: (data) => {
|
beforeSave: (data) => {
|
||||||
|
|
@ -354,7 +385,16 @@ const milestones = {
|
||||||
send_pending_users: toBool(payload.send_pending_users ?? 'no'),
|
send_pending_users: toBool(payload.send_pending_users ?? 'no'),
|
||||||
show_target_average: toBool(payload.show_target_average ?? 'no'),
|
show_target_average: toBool(payload.show_target_average ?? 'no'),
|
||||||
show_overall_average: toBool(payload.show_overall_average ?? 'no'),
|
show_overall_average: toBool(payload.show_overall_average ?? 'no'),
|
||||||
|
subject: (payload.subject || '').trim(),
|
||||||
|
body: (payload.body || '').trim(),
|
||||||
};
|
};
|
||||||
|
payload.show_units_export = payload.show_units_export === 'no' ? 'no' : 'yes';
|
||||||
|
payload.show_normal_metrics = payload.show_normal_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
payload.show_combined_metrics = payload.show_combined_metrics === 'no' ? 'no' : 'yes';
|
||||||
|
payload.manager_details = toStringList(payload.manager_details).length
|
||||||
|
? toStringList(payload.manager_details)
|
||||||
|
: ['l1manager'];
|
||||||
|
payload.total_units_name = payload.total_units_name || '';
|
||||||
|
|
||||||
delete payload.interval_start_date;
|
delete payload.interval_start_date;
|
||||||
delete payload.interval_end_date;
|
delete payload.interval_end_date;
|
||||||
|
|
@ -370,6 +410,8 @@ const milestones = {
|
||||||
delete payload.send_pending_users;
|
delete payload.send_pending_users;
|
||||||
delete payload.show_target_average;
|
delete payload.show_target_average;
|
||||||
delete payload.show_overall_average;
|
delete payload.show_overall_average;
|
||||||
|
delete payload.subject;
|
||||||
|
delete payload.body;
|
||||||
return payload;
|
return payload;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,9 @@ function flattenReminders(rows) {
|
||||||
checksubmission_days: item.checksubmission_days || '',
|
checksubmission_days: item.checksubmission_days || '',
|
||||||
message: item.message || '',
|
message: item.message || '',
|
||||||
plan_date_field: item.plan_date_field || '',
|
plan_date_field: item.plan_date_field || '',
|
||||||
|
notification_type: ['normal', 'overlay_custom'].includes(item.notification_type)
|
||||||
|
? item.notification_type
|
||||||
|
: 'normal',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -108,6 +111,7 @@ const reminders = {
|
||||||
checksubmission_days: row.checksubmission === 'yes' ? row.checksubmission_days || '' : '',
|
checksubmission_days: row.checksubmission === 'yes' ? row.checksubmission_days || '' : '',
|
||||||
message: row.message || '',
|
message: row.message || '',
|
||||||
plan_date_field: row.plan_date_field || '',
|
plan_date_field: row.plan_date_field || '',
|
||||||
|
notification_type: row.notification_type === 'overlay_custom' ? 'overlay_custom' : 'normal',
|
||||||
}));
|
}));
|
||||||
return payload;
|
return payload;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue