@servicetitan/dte-unlayer 0.157.0 → 0.159.0
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/dist/api-core.js +22 -29
- package/dist/api-core.js.map +1 -1
- package/dist/api-custom-tools.js +23 -29
- package/dist/api-custom-tools.js.map +1 -1
- package/dist/business-calendar/BusinessCalendarDrawer.d.ts +19 -0
- package/dist/business-calendar/BusinessCalendarDrawer.d.ts.map +1 -0
- package/dist/business-calendar/BusinessCalendarDrawer.js +41 -0
- package/dist/business-calendar/BusinessCalendarDrawer.js.map +1 -0
- package/dist/business-calendar/business-calendar-requests.d.ts +25 -0
- package/dist/business-calendar/business-calendar-requests.d.ts.map +1 -0
- package/dist/business-calendar/business-calendar-requests.js +46 -0
- package/dist/business-calendar/business-calendar-requests.js.map +1 -0
- package/dist/business-calendar/business-calendar-state.d.ts +22 -0
- package/dist/business-calendar/business-calendar-state.d.ts.map +1 -0
- package/dist/business-calendar/business-calendar-state.js +74 -0
- package/dist/business-calendar/business-calendar-state.js.map +1 -0
- package/dist/business-calendar/useBusinessCalendarRequests.d.ts +15 -0
- package/dist/business-calendar/useBusinessCalendarRequests.d.ts.map +1 -0
- package/dist/business-calendar/useBusinessCalendarRequests.js +30 -0
- package/dist/business-calendar/useBusinessCalendarRequests.js.map +1 -0
- package/dist/display-conditions/ConditionGroup.js +15 -89
- package/dist/display-conditions/ConditionGroup.js.map +1 -1
- package/dist/display-conditions/ConditionGroupsSection.js +2 -70
- package/dist/display-conditions/ConditionGroupsSection.js.map +1 -1
- package/dist/display-conditions/ConditionRow.d.ts.map +1 -1
- package/dist/display-conditions/ConditionRow.js +71 -296
- package/dist/display-conditions/ConditionRow.js.map +1 -1
- package/dist/display-conditions/DisplayConditionModal.js +40 -190
- package/dist/display-conditions/DisplayConditionModal.js.map +1 -1
- package/dist/display-conditions/LookupValueControl.d.ts.map +1 -1
- package/dist/display-conditions/LookupValueControl.js +42 -109
- package/dist/display-conditions/LookupValueControl.js.map +1 -1
- package/dist/display-conditions/SeparatorWithChip.js +1 -10
- package/dist/display-conditions/SeparatorWithChip.js.map +1 -1
- package/dist/display-conditions/constants.js +15 -20
- package/dist/display-conditions/constants.js.map +1 -1
- package/dist/display-conditions/displayConditionController.js +5 -8
- package/dist/display-conditions/displayConditionController.js.map +1 -1
- package/dist/display-conditions/lookupOptionsController.js +16 -16
- package/dist/display-conditions/lookupOptionsController.js.map +1 -1
- package/dist/display-conditions/nunjucks.js +98 -116
- package/dist/display-conditions/nunjucks.js.map +1 -1
- package/dist/display-conditions/schemaDataPoints.js +13 -11
- package/dist/display-conditions/schemaDataPoints.js.map +1 -1
- package/dist/display-conditions/types.js +23 -67
- package/dist/display-conditions/types.js.map +1 -1
- package/dist/display-conditions/useConditionForms.js +38 -56
- package/dist/display-conditions/useConditionForms.js.map +1 -1
- package/dist/display-conditions/useLookupOptions.js +24 -44
- package/dist/display-conditions/useLookupOptions.js.map +1 -1
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.d.ts.map +1 -1
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.js +48 -156
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.js.map +1 -1
- package/dist/e-sign-offset/ESignOffsetRuleRow.d.ts +3 -1
- package/dist/e-sign-offset/ESignOffsetRuleRow.d.ts.map +1 -1
- package/dist/e-sign-offset/ESignOffsetRuleRow.js +12 -71
- package/dist/e-sign-offset/ESignOffsetRuleRow.js.map +1 -1
- package/dist/e-sign-offset/eSignOffsetController.js +5 -8
- package/dist/e-sign-offset/eSignOffsetController.js.map +1 -1
- package/dist/editor-core-source.d.ts +2 -2
- package/dist/editor-core-source.d.ts.map +1 -1
- package/dist/editor-core-source.js +3 -3
- package/dist/editor-core-source.js.map +1 -1
- package/dist/editor-core.js +2 -2
- package/dist/editor-core.js.map +1 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +56 -118
- package/dist/editor.js.map +1 -1
- package/dist/image-upload-error.js +3 -3
- package/dist/image-upload-error.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/loadScript.js +7 -8
- package/dist/loadScript.js.map +1 -1
- package/dist/log.js +2 -3
- package/dist/log.js.map +1 -1
- package/dist/merge-tags.js +18 -17
- package/dist/merge-tags.js.map +1 -1
- package/dist/shared/configs.js +1 -2
- package/dist/shared/configs.js.map +1 -1
- package/dist/shared/const.d.ts +72 -0
- package/dist/shared/const.d.ts.map +1 -1
- package/dist/shared/const.js +13 -4
- package/dist/shared/const.js.map +1 -1
- package/dist/shared/date-calc.d.ts +32 -13
- package/dist/shared/date-calc.d.ts.map +1 -1
- package/dist/shared/date-calc.js +130 -76
- package/dist/shared/date-calc.js.map +1 -1
- package/dist/shared/e-sign-offset.js +46 -63
- package/dist/shared/e-sign-offset.js.map +1 -1
- package/dist/shared/edit-icon.js +0 -1
- package/dist/shared/edit-icon.js.map +1 -1
- package/dist/shared/fonts.js +16 -17
- package/dist/shared/fonts.js.map +1 -1
- package/dist/shared/forms.js +16 -38
- package/dist/shared/forms.js.map +1 -1
- package/dist/shared/instance-id.d.ts +3 -0
- package/dist/shared/instance-id.d.ts.map +1 -1
- package/dist/shared/instance-id.js +10 -7
- package/dist/shared/instance-id.js.map +1 -1
- package/dist/shared/nunjucks-helpers.js +2 -5
- package/dist/shared/nunjucks-helpers.js.map +1 -1
- package/dist/shared/schema.js +52 -96
- package/dist/shared/schema.js.map +1 -1
- package/dist/shared/tools.js +6 -13
- package/dist/shared/tools.js.map +1 -1
- package/dist/store.d.ts +15 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +851 -547
- package/dist/store.js.map +1 -1
- package/dist/tools.js +133 -143
- package/dist/tools.js.map +1 -1
- package/dist/unlayer-interface.d.ts +25 -1
- package/dist/unlayer-interface.d.ts.map +1 -1
- package/dist/unlayer-interface.js +1 -2
- package/dist/unlayer-interface.js.map +1 -1
- package/dist/unlayer.js +86 -113
- package/dist/unlayer.js.map +1 -1
- package/dist/vendor/dte-shared/business-calendar-validation.utils.d.ts +25 -0
- package/dist/vendor/dte-shared/business-calendar-validation.utils.js +80 -0
- package/dist/vendor/dte-shared/components/business-calendar-section.d.ts +15 -0
- package/dist/vendor/dte-shared/components/business-calendar-section.js +14 -0
- package/dist/vendor/dte-shared/components/schedule-drawer.d.ts +18 -0
- package/dist/vendor/dte-shared/components/schedule-drawer.js +119 -0
- package/dist/vendor/dte-shared/components/schedule-picker.d.ts +8 -0
- package/dist/vendor/dte-shared/components/schedule-picker.js +88 -0
- package/dist/vendor/dte-shared/constants.d.ts +31 -0
- package/dist/vendor/dte-shared/constants.js +34 -0
- package/dist/vendor/dte-shared/field-schedule-editor-context.d.ts +31 -0
- package/dist/vendor/dte-shared/field-schedule-editor-context.js +110 -0
- package/dist/vendor/dte-shared/index.d.ts +8 -0
- package/dist/vendor/dte-shared/index.js +7 -0
- package/dist/vendor/dte-shared/schedule-bindings.utils.d.ts +22 -0
- package/dist/vendor/dte-shared/schedule-bindings.utils.js +31 -0
- package/dist/vendor/dte-shared/styles/schedule.css +19 -0
- package/dist/vendor/dte-shared/types.d.ts +129 -0
- package/dist/vendor/dte-shared/types.js +1 -0
- package/package.json +7 -1
- package/src/__tests__/business-calendar-drawer.test.tsx +183 -0
- package/src/__tests__/business-calendar-requests.test.ts +166 -0
- package/src/__tests__/business-calendar-state.test.tsx +142 -0
- package/src/__tests__/condition-row.test.tsx +131 -0
- package/src/__tests__/date-calc.test.ts +145 -0
- package/src/__tests__/e-sign-offset-modal.test.tsx +124 -0
- package/src/__tests__/instance-id.test.ts +49 -0
- package/src/__tests__/store.business-calendar.test.ts +185 -0
- package/src/__tests__/unlayer.e-sign-types.test.ts +30 -0
- package/src/business-calendar/BusinessCalendarDrawer.tsx +76 -0
- package/src/business-calendar/business-calendar-requests.ts +80 -0
- package/src/business-calendar/business-calendar-state.ts +113 -0
- package/src/business-calendar/useBusinessCalendarRequests.ts +49 -0
- package/src/display-conditions/ConditionRow.tsx +102 -175
- package/src/display-conditions/LookupValueControl.tsx +1 -12
- package/src/e-sign-offset/ESignDateSignedOffsetModal.tsx +20 -12
- package/src/e-sign-offset/ESignOffsetRuleRow.tsx +7 -2
- package/src/editor-core-source.ts +2 -2
- package/src/editor.tsx +15 -0
- package/src/index.ts +10 -0
- package/src/shared/const.ts +61 -0
- package/src/shared/date-calc.ts +155 -78
- package/src/shared/instance-id.ts +6 -1
- package/src/store.ts +68 -5
- package/src/unlayer-interface.tsx +25 -1
- package/src/unlayer.tsx +5 -5
package/src/editor.tsx
CHANGED
|
@@ -7,6 +7,9 @@ import {
|
|
|
7
7
|
useRef,
|
|
8
8
|
useState,
|
|
9
9
|
} from 'react';
|
|
10
|
+
import { useBusinessCalendarState } from './business-calendar/business-calendar-state';
|
|
11
|
+
import { BusinessCalendarDrawer } from './business-calendar/BusinessCalendarDrawer';
|
|
12
|
+
import { useBusinessCalendarRequests } from './business-calendar/useBusinessCalendarRequests';
|
|
10
13
|
import { DisplayConditionModal } from './display-conditions/DisplayConditionModal';
|
|
11
14
|
import { ESignDateSignedOffsetModal } from './e-sign-offset/ESignDateSignedOffsetModal';
|
|
12
15
|
import { getErrorMessage } from './log';
|
|
@@ -133,6 +136,9 @@ export const UnlayerEditor = forwardRef<UnlayerRef, UnlayerEditorProps>((props,
|
|
|
133
136
|
return () => store.setOnCalcFieldSelect();
|
|
134
137
|
}, [props.opts.onCalcFieldSelect, store]);
|
|
135
138
|
|
|
139
|
+
const businessCalendar = useBusinessCalendarRequests(store, props.opts);
|
|
140
|
+
useBusinessCalendarState(store, props.opts);
|
|
141
|
+
|
|
136
142
|
const { minHeight = 800, style = {} } = props;
|
|
137
143
|
|
|
138
144
|
return (
|
|
@@ -155,6 +161,15 @@ export const UnlayerEditor = forwardRef<UnlayerRef, UnlayerEditorProps>((props,
|
|
|
155
161
|
onConditionFormSelect={props.opts.onConditionFormSelect}
|
|
156
162
|
/>
|
|
157
163
|
)}
|
|
164
|
+
{businessCalendar.drawer && props.opts.onScheduleBindingsChange && (
|
|
165
|
+
<BusinessCalendarDrawer
|
|
166
|
+
key={businessCalendar.drawer.id}
|
|
167
|
+
request={businessCalendar.drawer}
|
|
168
|
+
host={props.opts}
|
|
169
|
+
portalContainer={props.opts.displayConditionModalPortalContainer}
|
|
170
|
+
onClose={businessCalendar.closeDrawer}
|
|
171
|
+
/>
|
|
172
|
+
)}
|
|
158
173
|
</div>
|
|
159
174
|
);
|
|
160
175
|
});
|
package/src/index.ts
CHANGED
|
@@ -21,3 +21,13 @@ export { versions } from './unlayer';
|
|
|
21
21
|
export * from './shared/date-calc';
|
|
22
22
|
export { emptyArrayIfNull } from './shared/nunjucks-helpers';
|
|
23
23
|
export * from './display-conditions/lookupOptionsController';
|
|
24
|
+
export type {
|
|
25
|
+
BusinessCalendarHostProps,
|
|
26
|
+
BusinessCalendarRules,
|
|
27
|
+
BusinessDaySchedule,
|
|
28
|
+
FieldScheduleBinding,
|
|
29
|
+
HolidayCatalog,
|
|
30
|
+
KnownHoliday,
|
|
31
|
+
SaveScheduleRequest,
|
|
32
|
+
WeekendDay,
|
|
33
|
+
} from '@servicetitan/dte-shared';
|
package/src/shared/const.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { BusinessDaySchedule, HolidayCatalog } from '@servicetitan/dte-shared';
|
|
1
2
|
import type { DisplayConditionState } from '../display-conditions/types';
|
|
3
|
+
import type { BusinessCalendar } from './date-calc';
|
|
2
4
|
import { SchemaObject } from './schema';
|
|
3
5
|
|
|
4
6
|
export const constGenericsEditor = {
|
|
@@ -48,6 +50,62 @@ export interface UnlayerEventESignOffset {
|
|
|
48
50
|
value: ESignDateSignedOffsetSettings;
|
|
49
51
|
}
|
|
50
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Names shown for e-sign field types whose title differs from the type list entry it is derived
|
|
55
|
+
* from (by type value). Only the label changes: the stored value stays, so saved designs and the
|
|
56
|
+
* `esign_<recipient>_<type>` placeholder are unaffected.
|
|
57
|
+
*/
|
|
58
|
+
export const E_SIGN_FIELD_TYPE_LABELS: Readonly<Record<string, string | undefined>> = {
|
|
59
|
+
[E_SIGN_DATE_SIGNED_OFFSET_TYPE]: 'Calculated Signing Date',
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Payload of `--business-calendar-request` (iframe to parent): what a date field's inline schedule
|
|
64
|
+
* settings (a calculated field's or an e-sign "Date Signed Offset" field's) ask the parent window
|
|
65
|
+
* to do. `fieldKey` is the tool's instance id (`values.id`), the key DTE binds the schedule to.
|
|
66
|
+
* - `toggle` / `select`: the exclusion toggle and the schedule picker.
|
|
67
|
+
* - `create` / `edit`: open the schedule drawer, for a new schedule or `scheduleId`.
|
|
68
|
+
* - `delete`: delete the selected schedule; the outcome comes back as `--business-calendar-result`.
|
|
69
|
+
*/
|
|
70
|
+
export type UnlayerEventBusinessCalendarRequest =
|
|
71
|
+
| { action: 'toggle'; fieldKey: string; enabled: boolean }
|
|
72
|
+
| { action: 'select'; fieldKey: string; scheduleId?: number }
|
|
73
|
+
| { action: 'create'; fieldKey: string }
|
|
74
|
+
| { action: 'edit'; fieldKey: string; scheduleId: number }
|
|
75
|
+
| { action: 'delete'; fieldKey: string; scheduleId: number; requestId: string };
|
|
76
|
+
|
|
77
|
+
/** Payload of `--business-calendar-result` (parent to iframe): how a `delete` request ended. */
|
|
78
|
+
export interface UnlayerEventBusinessCalendarResult {
|
|
79
|
+
requestId: string;
|
|
80
|
+
/** Why it failed, shown under the schedule; absent on success. */
|
|
81
|
+
error?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Payload of `--business-calendar-state` (parent to iframe), sent whenever the host's schedule
|
|
86
|
+
* props change: what the property editors show and the calendars the previews use.
|
|
87
|
+
*/
|
|
88
|
+
export interface UnlayerEventBusinessCalendarState {
|
|
89
|
+
/** Whether the host edits schedules (it passes `onScheduleBindingsChange`). */
|
|
90
|
+
enabled: boolean;
|
|
91
|
+
/** The fields whose exclusion toggle is on, by field key, with their schedule (none: default). */
|
|
92
|
+
bindings: Record<string, { scheduleId?: number }>;
|
|
93
|
+
/** The schedules a field can pick, default first, as the host passes them. */
|
|
94
|
+
schedules: BusinessDaySchedule[];
|
|
95
|
+
schedulesLoading?: boolean;
|
|
96
|
+
schedulesError?: string;
|
|
97
|
+
/** The tenant's known holidays, for the schedule preview's names. */
|
|
98
|
+
holidayCatalog?: HolidayCatalog;
|
|
99
|
+
holidayCatalogLoading?: boolean;
|
|
100
|
+
holidayCatalogError?: string;
|
|
101
|
+
/** Whether the host can delete schedules (it passes `onDeleteSchedule`). */
|
|
102
|
+
canDeleteSchedule: boolean;
|
|
103
|
+
/** Calendars of the bound fields, by field key. */
|
|
104
|
+
fieldCalendars: Record<string, BusinessCalendar>;
|
|
105
|
+
/** The default calendar's holidays. */
|
|
106
|
+
holidays?: string[];
|
|
107
|
+
}
|
|
108
|
+
|
|
51
109
|
export interface UnlayerEditorUnit {
|
|
52
110
|
id: string;
|
|
53
111
|
generic: string;
|
|
@@ -69,6 +127,7 @@ export interface UnlayerEventConfig {
|
|
|
69
127
|
isSnapshotMode?: boolean;
|
|
70
128
|
units?: UnlayerEditorUnit[];
|
|
71
129
|
holidays?: string[];
|
|
130
|
+
fieldCalendars?: Record<string, BusinessCalendar>;
|
|
72
131
|
conditionalRulesEnabled?: boolean;
|
|
73
132
|
}
|
|
74
133
|
|
|
@@ -76,6 +135,8 @@ export interface UnlayerEventRegister {
|
|
|
76
135
|
units?: UnlayerEditorUnit[];
|
|
77
136
|
eSignRecipients?: UnlayerEditorESignRecipientInfo[];
|
|
78
137
|
eSignFieldTypes?: string[];
|
|
138
|
+
/** {@link E_SIGN_FIELD_TYPE_LABELS}, for the e-sign tool's canvas label. */
|
|
139
|
+
eSignFieldTypeLabels?: Readonly<Record<string, string | undefined>>;
|
|
79
140
|
customTools?: {
|
|
80
141
|
key: string;
|
|
81
142
|
title?: string;
|
package/src/shared/date-calc.ts
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
export const MAX_DATE_CALC_DAYS = 365;
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* components/scripts/comps/calculated-field.ts).
|
|
4
|
+
* The years DTE knows holidays for (`HolidayCheckService.HolidayYearsWindow`): outside them a
|
|
5
|
+
* default-calendar answer would skip weekends but miss holidays, so it is left blank, as in BYOD.
|
|
7
6
|
*/
|
|
8
|
-
export const
|
|
9
|
-
'2026-01-01T00:00:00.000Z',
|
|
10
|
-
'2026-01-19T00:00:00.000Z',
|
|
11
|
-
'2026-02-16T00:00:00.000Z',
|
|
12
|
-
'2026-05-25T00:00:00.000Z',
|
|
13
|
-
'2026-07-04T00:00:00.000Z',
|
|
14
|
-
'2026-09-07T00:00:00.000Z',
|
|
15
|
-
'2026-11-26T00:00:00.000Z',
|
|
16
|
-
'2026-11-27T00:00:00.000Z',
|
|
17
|
-
'2026-12-25T00:00:00.000Z',
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
export const DATE_RANGE_YEARS = 2;
|
|
7
|
+
export const DATE_RANGE_YEARS = 1;
|
|
21
8
|
|
|
22
9
|
/**
|
|
23
10
|
* Returns true if the date's year falls within [currentYear - DATE_RANGE_YEARS, currentYear + DATE_RANGE_YEARS].
|
|
@@ -36,10 +23,40 @@ export function isDateWithinRange(dateInput: unknown): boolean {
|
|
|
36
23
|
return year >= currentYear - DATE_RANGE_YEARS && year <= currentYear + DATE_RANGE_YEARS;
|
|
37
24
|
}
|
|
38
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Days a date calculation skips, as DTE resolves them (`POST api/holidays/calendar`, and the
|
|
28
|
+
* `calendars` noderenderer receives). Arithmetic outside `firstYear`–`lastYear` is blank; without
|
|
29
|
+
* years no year limit applies.
|
|
30
|
+
*/
|
|
31
|
+
export interface BusinessCalendar {
|
|
32
|
+
/** Excluded weekend days, as `Date.getUTCDay()` numbers them: 0 = Sunday, 6 = Saturday. */
|
|
33
|
+
weekendDays: number[];
|
|
34
|
+
/** Holiday dates, already moved to their observed days, as `YYYY-MM-DD`. */
|
|
35
|
+
holidays: string[];
|
|
36
|
+
firstYear?: number | null;
|
|
37
|
+
lastYear?: number | null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Saturday and Sunday: the default calendar's weekend. */
|
|
41
|
+
export const DEFAULT_WEEKEND_DAYS = [0, 6];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Which calendar a calculation uses. With `calendar` (a field bound to a schedule) only that
|
|
45
|
+
* calendar applies. Without it, the default calendar applies: Saturday and Sunday plus `holidays`,
|
|
46
|
+
* with the start and the result limited to the current year ± DATE_RANGE_YEARS.
|
|
47
|
+
*/
|
|
39
48
|
export interface DateCalcOptions {
|
|
49
|
+
calendar?: BusinessCalendar;
|
|
40
50
|
holidays?: string[];
|
|
41
51
|
}
|
|
42
52
|
|
|
53
|
+
interface PreparedCalendar {
|
|
54
|
+
weekendDays: Set<number>;
|
|
55
|
+
holidays: Set<string>;
|
|
56
|
+
firstYear: number | null;
|
|
57
|
+
lastYear: number | null;
|
|
58
|
+
}
|
|
59
|
+
|
|
43
60
|
function toDateOnly(input: string | Date): Date {
|
|
44
61
|
const d = typeof input === 'string' ? new Date(input) : new Date(input.getTime());
|
|
45
62
|
d.setUTCHours(0, 0, 0, 0);
|
|
@@ -53,96 +70,121 @@ function toDateKey(d: Date): string {
|
|
|
53
70
|
return `${y}-${m}-${day}`;
|
|
54
71
|
}
|
|
55
72
|
|
|
56
|
-
function
|
|
57
|
-
|
|
58
|
-
|
|
73
|
+
function parseDate(input: unknown): Date | null {
|
|
74
|
+
if (typeof input !== 'string' && !(input instanceof Date)) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const d = toDateOnly(input);
|
|
78
|
+
return isFinite(d.getTime()) ? d : null;
|
|
59
79
|
}
|
|
60
80
|
|
|
61
81
|
function buildHolidaySet(holidays?: string[]): Set<string> {
|
|
62
|
-
if (!holidays?.length) {
|
|
63
|
-
return new Set();
|
|
64
|
-
}
|
|
65
82
|
const set = new Set<string>();
|
|
66
|
-
for (const h of holidays) {
|
|
67
|
-
const d =
|
|
68
|
-
if (
|
|
83
|
+
for (const h of holidays ?? []) {
|
|
84
|
+
const d = parseDate(h);
|
|
85
|
+
if (d) {
|
|
69
86
|
set.add(toDateKey(d));
|
|
70
87
|
}
|
|
71
88
|
}
|
|
72
89
|
return set;
|
|
73
90
|
}
|
|
74
91
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
92
|
+
// Calendars are passed once and reused by every calculation, so each is prepared once.
|
|
93
|
+
const preparedCalendars = new WeakMap<BusinessCalendar, PreparedCalendar>();
|
|
94
|
+
|
|
95
|
+
function prepareCalendar(calendar: BusinessCalendar): PreparedCalendar {
|
|
96
|
+
const cached = preparedCalendars.get(calendar);
|
|
97
|
+
if (cached) {
|
|
98
|
+
return cached;
|
|
78
99
|
}
|
|
79
|
-
|
|
80
|
-
|
|
100
|
+
|
|
101
|
+
const prepared: PreparedCalendar = {
|
|
102
|
+
weekendDays: new Set(calendar.weekendDays ?? DEFAULT_WEEKEND_DAYS),
|
|
103
|
+
holidays: buildHolidaySet(calendar.holidays),
|
|
104
|
+
firstYear: calendar.firstYear ?? null,
|
|
105
|
+
lastYear: calendar.lastYear ?? null,
|
|
106
|
+
};
|
|
107
|
+
preparedCalendars.set(calendar, prepared);
|
|
108
|
+
return prepared;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// One calendar per holidays array, so the default calendar is also prepared once.
|
|
112
|
+
const holidayCalendars = new WeakMap<string[], BusinessCalendar>();
|
|
113
|
+
const NO_HOLIDAYS_CALENDAR: BusinessCalendar = { weekendDays: DEFAULT_WEEKEND_DAYS, holidays: [] };
|
|
114
|
+
|
|
115
|
+
function defaultCalendar(holidays?: string[]): BusinessCalendar {
|
|
116
|
+
if (!Array.isArray(holidays)) {
|
|
117
|
+
return NO_HOLIDAYS_CALENDAR;
|
|
81
118
|
}
|
|
82
|
-
|
|
119
|
+
let calendar = holidayCalendars.get(holidays);
|
|
120
|
+
if (!calendar) {
|
|
121
|
+
calendar = { weekendDays: DEFAULT_WEEKEND_DAYS, holidays };
|
|
122
|
+
holidayCalendars.set(holidays, calendar);
|
|
123
|
+
}
|
|
124
|
+
return calendar;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function isBusinessDay(d: Date, calendar: PreparedCalendar): boolean {
|
|
128
|
+
return !calendar.weekendDays.has(d.getUTCDay()) && !calendar.holidays.has(toDateKey(d));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function isWithinYears(d: Date, calendar: PreparedCalendar): boolean {
|
|
132
|
+
const year = d.getUTCFullYear();
|
|
133
|
+
return (
|
|
134
|
+
(calendar.firstYear === null || year >= calendar.firstYear) &&
|
|
135
|
+
(calendar.lastYear === null || year <= calendar.lastYear)
|
|
136
|
+
);
|
|
83
137
|
}
|
|
84
138
|
|
|
85
139
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
140
|
+
* Walks `days` business days from `start` (negative walks back); the start is not counted.
|
|
141
|
+
* Mirrors `BusinessDayCalculator.AddBusinessDays` in DTE: null for more than MAX_DATE_CALC_DAYS,
|
|
142
|
+
* or when the start or the walk leaves the calendar's years.
|
|
88
143
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return result;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const intDays = Math.trunc(days);
|
|
96
|
-
if (intDays === 0) {
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
if (Math.abs(intDays) > MAX_DATE_CALC_DAYS) {
|
|
100
|
-
return new Date(NaN);
|
|
144
|
+
function addBusinessDays(start: Date, days: number, calendar: PreparedCalendar): Date | null {
|
|
145
|
+
if (Math.abs(days) > MAX_DATE_CALC_DAYS || !isWithinYears(start, calendar)) {
|
|
146
|
+
return null;
|
|
101
147
|
}
|
|
102
148
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
149
|
+
const direction = days >= 0 ? 1 : -1;
|
|
150
|
+
let remaining = Math.abs(days);
|
|
151
|
+
const current = new Date(start.getTime());
|
|
106
152
|
|
|
107
153
|
while (remaining > 0) {
|
|
108
|
-
|
|
109
|
-
if (!
|
|
154
|
+
current.setUTCDate(current.getUTCDate() + direction);
|
|
155
|
+
if (!isWithinYears(current, calendar)) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
if (isBusinessDay(current, calendar)) {
|
|
110
159
|
remaining--;
|
|
111
160
|
}
|
|
112
161
|
}
|
|
113
162
|
|
|
114
|
-
return
|
|
163
|
+
return current;
|
|
115
164
|
}
|
|
116
165
|
|
|
117
166
|
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
167
|
+
* Counts the business days from `from` to `to`, negative when `to` is earlier; the start is not
|
|
168
|
+
* counted, the end is. Mirrors `BusinessDayCalculator.CountBusinessDays` in DTE: null for a span
|
|
169
|
+
* over MAX_DATE_CALC_DAYS, or a date outside the calendar's years.
|
|
120
170
|
*/
|
|
121
|
-
|
|
122
|
-
from
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (!isFinite(start.getTime()) || !isFinite(end.getTime())) {
|
|
130
|
-
return 0;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const calendarDiff = Math.abs(end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000);
|
|
134
|
-
if (calendarDiff > MAX_DATE_CALC_DAYS * 2) {
|
|
135
|
-
return NaN;
|
|
171
|
+
function countBusinessDays(from: Date, to: Date, calendar: PreparedCalendar): number | null {
|
|
172
|
+
const span = Math.abs(to.getTime() - from.getTime()) / (24 * 60 * 60 * 1000);
|
|
173
|
+
if (
|
|
174
|
+
span > MAX_DATE_CALC_DAYS ||
|
|
175
|
+
!isWithinYears(from, calendar) ||
|
|
176
|
+
!isWithinYears(to, calendar)
|
|
177
|
+
) {
|
|
178
|
+
return null;
|
|
136
179
|
}
|
|
137
180
|
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
const cursor = new Date(start.getTime());
|
|
181
|
+
const direction = to.getTime() >= from.getTime() ? 1 : -1;
|
|
182
|
+
const cursor = new Date(from.getTime());
|
|
141
183
|
let count = 0;
|
|
142
184
|
|
|
143
|
-
while (toDateKey(cursor) !== toDateKey(
|
|
185
|
+
while (toDateKey(cursor) !== toDateKey(to)) {
|
|
144
186
|
cursor.setUTCDate(cursor.getUTCDate() + direction);
|
|
145
|
-
if (
|
|
187
|
+
if (isBusinessDay(cursor, calendar)) {
|
|
146
188
|
count++;
|
|
147
189
|
}
|
|
148
190
|
}
|
|
@@ -150,12 +192,47 @@ export function dateDiffDays(
|
|
|
150
192
|
return count * direction;
|
|
151
193
|
}
|
|
152
194
|
|
|
153
|
-
/**
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Adds business days to a date, as DTE's noderenderer `dateAddDays` does. Returns the result as
|
|
197
|
+
* `YYYY-MM-DD`, or null (a blank field, as in BYOD) for an invalid date, a fractional offset, or
|
|
198
|
+
* a start or result outside the calendar's years.
|
|
199
|
+
*/
|
|
200
|
+
export function addDays(
|
|
201
|
+
dateInput: unknown,
|
|
202
|
+
daysInput: unknown,
|
|
203
|
+
options?: DateCalcOptions,
|
|
204
|
+
): string | null {
|
|
205
|
+
const isDefault = !options?.calendar;
|
|
206
|
+
const calendar = prepareCalendar(options?.calendar ?? defaultCalendar(options?.holidays));
|
|
207
|
+
const start = parseDate(dateInput);
|
|
208
|
+
const days = Number(daysInput);
|
|
209
|
+
if (!start || !Number.isInteger(days) || (isDefault && !isDateWithinRange(start))) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
const result = addBusinessDays(start, days, calendar);
|
|
213
|
+
if (!result || (isDefault && !isDateWithinRange(result))) {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
return toDateKey(result);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Counts the business days from `from` to `to` (positive when `to` is later), as DTE's
|
|
221
|
+
* noderenderer `dateDiffDays` does. A formula's `D1 - D2` counts from D2 to D1. Null (a blank
|
|
222
|
+
* field) for an invalid or missing date, or a span over MAX_DATE_CALC_DAYS.
|
|
223
|
+
*/
|
|
224
|
+
export function dateDiffDays(
|
|
225
|
+
fromInput: unknown,
|
|
226
|
+
toInput: unknown,
|
|
227
|
+
options?: DateCalcOptions,
|
|
228
|
+
): number | null {
|
|
229
|
+
const calendar = prepareCalendar(options?.calendar ?? defaultCalendar(options?.holidays));
|
|
230
|
+
const from = parseDate(fromInput);
|
|
231
|
+
const to = parseDate(toInput);
|
|
232
|
+
if (!from || !to) {
|
|
233
|
+
return null;
|
|
157
234
|
}
|
|
158
|
-
return
|
|
235
|
+
return countBusinessDays(from, to, calendar);
|
|
159
236
|
}
|
|
160
237
|
|
|
161
238
|
export const DEFAULT_DATE_FORMAT = 'MM/DD/YYYY';
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { E_SIGN_TOOL_SLUG } from './const';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Custom tools whose `values.id` is a per-instance GUID that must stay unique
|
|
3
5
|
* within a design. When such a tool is duplicated (content or row duplicate),
|
|
4
6
|
* Unlayer copies the values as-is, so the host regenerates the id of the copy.
|
|
7
|
+
*
|
|
8
|
+
* `calculated_field` and `e-sign` use it as the field key DTE binds a business-day schedule
|
|
9
|
+
* to, so a copy starts unbound.
|
|
5
10
|
*/
|
|
6
|
-
export const INSTANCE_ID_TOOL_SLUGS = ['embedded-image'];
|
|
11
|
+
export const INSTANCE_ID_TOOL_SLUGS = ['embedded-image', 'calculated_field', E_SIGN_TOOL_SLUG];
|
|
7
12
|
|
|
8
13
|
/**
|
|
9
14
|
* Generates an RFC 4122 v4 GUID (`3fa85f64-5717-4562-b3fc-2c963f66afa6`) with the
|
package/src/store.ts
CHANGED
|
@@ -4,11 +4,15 @@ import { loadScript } from './loadScript';
|
|
|
4
4
|
import { logUnlayerError } from './log';
|
|
5
5
|
import { toUnlayerMergeTags, type UnlayerMergeTagsConfig } from './merge-tags';
|
|
6
6
|
import { defaultImageValidation } from './shared/configs';
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import {
|
|
8
|
+
E_SIGN_FIELD_TYPE_LABELS,
|
|
9
|
+
type UnlayerEditorTwin,
|
|
10
|
+
type UnlayerEventBusinessCalendarRequest,
|
|
11
|
+
type UnlayerEventBusinessCalendarResult,
|
|
12
|
+
type UnlayerEventBusinessCalendarState,
|
|
13
|
+
type UnlayerEventConfig,
|
|
14
|
+
type UnlayerEventESignOffset,
|
|
15
|
+
type UnlayerEventRegister,
|
|
12
16
|
} from './shared/const';
|
|
13
17
|
import { normalizeESignOffsetSettings } from './shared/e-sign-offset';
|
|
14
18
|
import { unlayerSupportedFonts } from './shared/fonts';
|
|
@@ -212,6 +216,9 @@ export class UnlayerStore {
|
|
|
212
216
|
private isEditorReady = false;
|
|
213
217
|
private isMergeTagsApplied = false;
|
|
214
218
|
private mergeTagsConfig?: UnlayerMergeTagsConfig;
|
|
219
|
+
/** Latest `--business-calendar-state` payload, and the last one sent to the iframe. */
|
|
220
|
+
private businessCalendarStateJson?: string;
|
|
221
|
+
private sentBusinessCalendarStateJson?: string;
|
|
215
222
|
|
|
216
223
|
private onMessageCB?: (type: string, data: any) => void;
|
|
217
224
|
private onChangeCB?: (info: UnlayerDesignChangeInfo) => void;
|
|
@@ -222,6 +229,7 @@ export class UnlayerStore {
|
|
|
222
229
|
private onFormSelectCB?: (formId: number) => void;
|
|
223
230
|
private onCalcFieldOpenCB?: (usedFormIds: number[]) => void;
|
|
224
231
|
private onCalcFieldSelectCB?: (fieldKeys: string[]) => void;
|
|
232
|
+
private onBusinessCalendarRequestCB?: (request: UnlayerEventBusinessCalendarRequest) => void;
|
|
225
233
|
|
|
226
234
|
constructor(readonly props: CreateUnlayerEditorProps) {
|
|
227
235
|
const schemaData = this.props.schema ? schemaBuildMap(this.props.schema) : undefined;
|
|
@@ -232,6 +240,7 @@ export class UnlayerStore {
|
|
|
232
240
|
.map(field => field.fullKey),
|
|
233
241
|
);
|
|
234
242
|
|
|
243
|
+
// Each entry's type value is derived from it; the name shown can differ (E_SIGN_FIELD_TYPE_LABELS).
|
|
235
244
|
this.props.eSignFieldTypes = [
|
|
236
245
|
'Signature',
|
|
237
246
|
'Initials',
|
|
@@ -379,6 +388,32 @@ export class UnlayerStore {
|
|
|
379
388
|
this.onCalcFieldSelectCB = onCalcFieldSelect;
|
|
380
389
|
};
|
|
381
390
|
|
|
391
|
+
setOnBusinessCalendarRequest = (
|
|
392
|
+
onBusinessCalendarRequest?: UnlayerStore['onBusinessCalendarRequestCB'],
|
|
393
|
+
) => {
|
|
394
|
+
this.onBusinessCalendarRequestCB = onBusinessCalendarRequest;
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
/** Tells the iframe how a schedule `delete` request ended. */
|
|
398
|
+
sendBusinessCalendarResult = (result: UnlayerEventBusinessCalendarResult) => {
|
|
399
|
+
this.sendMessage('--business-calendar-result', JSON.parse(JSON.stringify(result)));
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Keeps the schedule state for the iframe and sends it once the tools core has loaded (it
|
|
404
|
+
* goes out again right after `--config`). An unchanged state isn't sent again.
|
|
405
|
+
*/
|
|
406
|
+
setBusinessCalendarState = (state: UnlayerEventBusinessCalendarState) => {
|
|
407
|
+
this.businessCalendarStateJson = JSON.stringify(state);
|
|
408
|
+
|
|
409
|
+
if (
|
|
410
|
+
this.hasCoreLoaded &&
|
|
411
|
+
this.businessCalendarStateJson !== this.sentBusinessCalendarStateJson
|
|
412
|
+
) {
|
|
413
|
+
this.sendBusinessCalendarState();
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
|
|
382
417
|
sendFormList = (forms: FormInfo[]) => {
|
|
383
418
|
this.sendMessage('--form-list', { forms });
|
|
384
419
|
};
|
|
@@ -509,17 +544,25 @@ export class UnlayerStore {
|
|
|
509
544
|
genericConfigMode: this.props.genericConfigMode,
|
|
510
545
|
isSnapshotMode: this.props.isSnapshotMode,
|
|
511
546
|
holidays: this.props.holidays,
|
|
547
|
+
fieldCalendars: this.props.fieldCalendars,
|
|
512
548
|
conditionalRulesEnabled:
|
|
513
549
|
!!this.props.displayConditions || !!this.props.onConditionalsOpen,
|
|
514
550
|
};
|
|
515
551
|
|
|
516
552
|
this.sendMessage('--config', JSON.parse(JSON.stringify(configData)));
|
|
553
|
+
// Always: a reloaded tools core starts without it.
|
|
554
|
+
this.sendBusinessCalendarState();
|
|
517
555
|
} else if (type === '--form-select') {
|
|
518
556
|
this.onFormSelectCB?.(data?.formId);
|
|
519
557
|
} else if (type === '--calc-field-open') {
|
|
520
558
|
this.onCalcFieldOpenCB?.(data?.usedFormIds ?? []);
|
|
521
559
|
} else if (type === '--esign-offset-open') {
|
|
522
560
|
this.openESignOffsetRules(data);
|
|
561
|
+
} else if (type === '--business-calendar-request') {
|
|
562
|
+
// It can delete a tenant schedule and replace bindings: only from this editor's iframe.
|
|
563
|
+
if (e.source === this.iframe?.contentWindow) {
|
|
564
|
+
this.routeBusinessCalendarRequest(data);
|
|
565
|
+
}
|
|
523
566
|
} else if (type === '--calc-field-select') {
|
|
524
567
|
if (this.onCalcFieldSelectCB) {
|
|
525
568
|
this.onCalcFieldSelectCB(data?.fieldKeys ?? []);
|
|
@@ -532,6 +575,7 @@ export class UnlayerStore {
|
|
|
532
575
|
toolTwins: this.props.toolTwins,
|
|
533
576
|
eSignRecipients: this.props.eSignRecipients,
|
|
534
577
|
eSignFieldTypes: this.props.eSignFieldTypes,
|
|
578
|
+
eSignFieldTypeLabels: E_SIGN_FIELD_TYPE_LABELS,
|
|
535
579
|
units: this.props.units?.map(unit => ({
|
|
536
580
|
...unit,
|
|
537
581
|
values: {
|
|
@@ -580,6 +624,25 @@ export class UnlayerStore {
|
|
|
580
624
|
});
|
|
581
625
|
};
|
|
582
626
|
|
|
627
|
+
private routeBusinessCalendarRequest = (
|
|
628
|
+
data?: Partial<UnlayerEventBusinessCalendarRequest>,
|
|
629
|
+
) => {
|
|
630
|
+
if (!data?.action || !data.fieldKey) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
this.onBusinessCalendarRequestCB?.(data as UnlayerEventBusinessCalendarRequest);
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
private sendBusinessCalendarState = () => {
|
|
638
|
+
if (!this.businessCalendarStateJson) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
this.sentBusinessCalendarStateJson = this.businessCalendarStateJson;
|
|
643
|
+
this.sendMessage('--business-calendar-state', JSON.parse(this.businessCalendarStateJson));
|
|
644
|
+
};
|
|
645
|
+
|
|
583
646
|
private updateFormFieldSamples = (formId: number, fields: FormFieldInfo[]) => {
|
|
584
647
|
fields.forEach((field, index) => {
|
|
585
648
|
const normalizedFieldId = String(field.id ?? '').replaceAll('-', '');
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { BusinessCalendarHostProps } from '@servicetitan/dte-shared';
|
|
1
2
|
import {
|
|
2
3
|
UnlayerEditorESignRecipientInfo,
|
|
3
4
|
UnlayerEditorTwin,
|
|
4
5
|
UnlayerEditorUnit,
|
|
5
6
|
} from './shared/const';
|
|
7
|
+
import type { BusinessCalendar } from './shared/date-calc';
|
|
6
8
|
import { FormFieldInfo, FormInfo } from './shared/forms';
|
|
7
9
|
import { SchemaObject } from './shared/schema';
|
|
8
10
|
|
|
@@ -72,7 +74,16 @@ export interface UnlayerEditorCustomTool {
|
|
|
72
74
|
groupUrl?: string;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Editor options. The business-day schedule props (`BusinessCalendarHostProps`: `scheduleBindings`,
|
|
79
|
+
* `schedules`, `holidayCatalog`, `onScheduleBindingsChange`, ...) mean the same as `PdfEditor`'s;
|
|
80
|
+
* the field key of a binding is the tool's `values.id` (calculated field or e-sign "Date Signed
|
|
81
|
+
* Offset" field). The schedule UI shows only when `onScheduleBindingsChange` is passed. Changes
|
|
82
|
+
* to them (and to `holidays` / `fieldCalendars`) reach the editor when the host re-renders
|
|
83
|
+
* `UnlayerEditor` with new values: new arrays and objects, as for `PdfEditor`, since one changed
|
|
84
|
+
* in place isn't noticed.
|
|
85
|
+
*/
|
|
86
|
+
export interface CreateUnlayerEditorProps extends BusinessCalendarHostProps {
|
|
76
87
|
tools: UnlayerEditorCustomTool[];
|
|
77
88
|
newSnapshot?: UnlayerEditorTwin;
|
|
78
89
|
toolTwins?: UnlayerEditorTwin[];
|
|
@@ -107,7 +118,20 @@ export interface CreateUnlayerEditorProps {
|
|
|
107
118
|
maxHeight?: number;
|
|
108
119
|
maxFileSize?: number;
|
|
109
120
|
};
|
|
121
|
+
/**
|
|
122
|
+
* Holidays of the default business-day calendar (`YYYY-MM-DD`, observed days), skipped with
|
|
123
|
+
* Saturday and Sunday by date calculated fields whose toggle is off. Without it the previews
|
|
124
|
+
* skip weekends only. Sent to the editor again whenever it changes.
|
|
125
|
+
*/
|
|
110
126
|
holidays?: string[];
|
|
127
|
+
/**
|
|
128
|
+
* Calendars of the date calculated fields bound to a schedule, by field key (the tool's
|
|
129
|
+
* `values.id`), as `POST api/holidays/calendar` resolves them. Fields not listed use the
|
|
130
|
+
* default calendar (`holidays`); while `onScheduleBindingsChange` is passed, so does a field
|
|
131
|
+
* without a binding in `scheduleBindings`. Only the editor previews read it: rendered
|
|
132
|
+
* documents get their calendars from DTE. Sent to the editor again whenever it changes.
|
|
133
|
+
*/
|
|
134
|
+
fieldCalendars?: Record<string, BusinessCalendar>;
|
|
111
135
|
onFormSelect?: (formId: number) => void;
|
|
112
136
|
onCalcFieldOpen?: (usedFormIds: number[]) => void;
|
|
113
137
|
onCalcFieldSelect?: (fieldKeys: string[]) => void;
|
package/src/unlayer.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { emitDisplayCondition } from './display-conditions/displayConditionContr
|
|
|
2
2
|
import { editorCoreScript, editorCoreStyles, editorCoreTools } from './editor-core';
|
|
3
3
|
import { logUnlayerError } from './log';
|
|
4
4
|
import { toUnlayerMergeTags } from './merge-tags';
|
|
5
|
-
import { constGenericsEditor } from './shared/const';
|
|
5
|
+
import { constGenericsEditor, E_SIGN_FIELD_TYPE_LABELS } from './shared/const';
|
|
6
6
|
import { unlayerSupportedFonts } from './shared/fonts';
|
|
7
7
|
import {
|
|
8
8
|
unlayerCustomEmptyToolState,
|
|
@@ -226,10 +226,10 @@ export const createUnlayerEditor = (
|
|
|
226
226
|
|
|
227
227
|
const acv = constGenericsEditor.adminConfigProperty;
|
|
228
228
|
|
|
229
|
-
const eSignTypeMapping = (eSignFieldTypes ?? []).map(key =>
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
})
|
|
229
|
+
const eSignTypeMapping = (eSignFieldTypes ?? []).map(key => {
|
|
230
|
+
const value = key.charAt(0).toLowerCase() + key.replace(/ /g, '').slice(1);
|
|
231
|
+
return { label: E_SIGN_FIELD_TYPE_LABELS[value] ?? key, value };
|
|
232
|
+
});
|
|
233
233
|
|
|
234
234
|
const unitsConfig = (units ?? []).reduce(
|
|
235
235
|
(out, unit) => {
|