@servicetitan/dte-pdf-editor 1.96.0 → 1.96.2
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/README.md +19 -7
- package/dist/components/field-config-panel/advanced-settings.d.ts +1 -1
- package/dist/components/field-config-panel/advanced-settings.js +1 -1
- package/dist/components/field-config-panel/e-sign-options-modal.d.ts +1 -1
- package/dist/components/field-config-panel/e-sign-options-modal.js +1 -1
- package/dist/components/field-config-panel/field-config-panel-overlay.d.ts.map +1 -1
- package/dist/components/field-config-panel/field-config-panel-overlay.js +23 -15
- package/dist/components/field-config-panel/field-config-panel-overlay.js.map +1 -1
- package/dist/components/field-config-panel/field-config-panel.d.ts +1 -1
- package/dist/components/field-config-panel/formula-generator.d.ts +1 -1
- package/dist/components/field-config-panel/formula-modal.d.ts +1 -1
- package/dist/components/field-config-panel/formula-workspace.d.ts +1 -1
- package/dist/components/pdf-editor/pdf-editor.d.ts +6 -1
- package/dist/components/pdf-editor/pdf-editor.d.ts.map +1 -1
- package/dist/components/pdf-editor/pdf-editor.js.map +1 -1
- package/dist/interface/types.d.ts +1 -1
- package/dist/vendor/dte-shared/business-calendar-validation.utils.d.ts +22 -0
- package/dist/vendor/dte-shared/business-calendar-validation.utils.js +76 -0
- package/dist/vendor/dte-shared/components/business-calendar-section.d.ts +15 -0
- package/dist/vendor/dte-shared/components/business-calendar-section.js +13 -0
- package/dist/vendor/dte-shared/components/schedule-drawer.d.ts +16 -0
- package/dist/vendor/dte-shared/components/schedule-drawer.js +112 -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 +10 -0
- package/dist/vendor/dte-shared/constants.js +10 -0
- package/dist/vendor/dte-shared/index.d.ts +6 -0
- package/dist/vendor/dte-shared/index.js +5 -0
- package/dist/vendor/dte-shared/styles/schedule.css +19 -0
- package/dist/vendor/dte-shared/types.d.ts +67 -0
- package/dist/vendor/dte-shared/types.js +1 -0
- package/package.json +5 -3
- package/src/components/field-config-panel/__tests__/field-config-panel-overlay.test.tsx +184 -0
- package/src/components/field-config-panel/__tests__/schedule-switch-visibility.test.tsx +206 -0
- package/src/components/field-config-panel/field-config-panel-overlay.tsx +25 -16
- package/src/components/pdf-editor/pdf-editor.tsx +6 -1
package/README.md
CHANGED
|
@@ -31,6 +31,12 @@ formulas.
|
|
|
31
31
|
|
|
32
32
|
### Recent changes
|
|
33
33
|
|
|
34
|
+
- **fix/hide-sceduler** (schedule UI) — the schedule switch, picker and the e-sign schedule are shown only when
|
|
35
|
+
`onScheduleBindingsChange` is passed. See [RELEASE_NOTES.md](./RELEASE_NOTES.md) and
|
|
36
|
+
[Business-day calendars](#business-day-calendars).
|
|
37
|
+
- **fix/shared-incloud-on-BYOD-build** (installable package) — the package no longer depends on the unpublished
|
|
38
|
+
`@servicetitan/dte-shared`; its code is bundled in, so `npm install` works. See
|
|
39
|
+
[RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
|
34
40
|
- **feat/DTE-4695/custom-weekend-holiday-exclusion** (business-day calendars) — a per-field "Exclude weekends &
|
|
35
41
|
holidays" toggle, schedule picker and "Create New Schedule" drawer in the Formula Builder (`scheduleBindings`,
|
|
36
42
|
`holidayCatalog`, `schedules`, `onScheduleBindingsChange`, `onCreateSchedule`); date calculated fields take a
|
|
@@ -135,16 +141,16 @@ The main component for editing PDF documents and placing fields.
|
|
|
135
141
|
| `holidays` | `string[]` | No | Holidays of the default business-day calendar, for the formula builder preview; as on `PdfView` |
|
|
136
142
|
| `fieldCalendars` | `Record<string, BusinessCalendar>` | No | Calendars of date calculated fields bound to a schedule, by field id; as on `PdfView` |
|
|
137
143
|
| `scheduleBindings` | `FieldScheduleBinding[]` | No | Date fields whose exclusion toggle is on, and the schedule each uses; as on `PdfView` — see [Business-day calendars](#business-day-calendars) |
|
|
138
|
-
| `onScheduleBindingsChange` | `(bindings: FieldScheduleBinding[]) => void` | No | Called with the complete desired `scheduleBindings` when the toggle or picker changes the selected field's binding
|
|
139
|
-
| `holidayCatalog` | `HolidayCatalog` | No | The tenant's known holidays, for the schedule editor's checklist
|
|
144
|
+
| `onScheduleBindingsChange` | `(bindings: FieldScheduleBinding[]) => void` | No | Called with the complete desired `scheduleBindings` when the toggle or picker changes the selected field's binding. Passing it turns the schedule UI on; without it the switch, picker and e-sign schedule are not shown. It is not called for the e-sign schedule, which is stored in the field's `data` |
|
|
145
|
+
| `holidayCatalog` | `HolidayCatalog` | No | The tenant's known holidays, for the schedule editor's checklist (the schedule UI needs `onScheduleBindingsChange`) |
|
|
140
146
|
| `holidayCatalogLoading`| `boolean` | No | Whether `holidayCatalog` is still loading |
|
|
141
147
|
| `holidayCatalogError` | `string` | No | Error message shown in the schedule editor if the catalog failed to load |
|
|
142
|
-
| `schedules` | `BusinessDaySchedule[]` | No | The schedules the tenant can pick from the Formula Builder's schedule picker, default schedule first
|
|
148
|
+
| `schedules` | `BusinessDaySchedule[]` | No | The schedules the tenant can pick from the Formula Builder's schedule picker, default schedule first (the schedule UI needs `onScheduleBindingsChange`) |
|
|
143
149
|
| `schedulesLoading` | `boolean` | No | Whether `schedules` is still loading |
|
|
144
150
|
| `schedulesError` | `string` | No | Error message shown in the picker if the schedule list failed to load |
|
|
145
|
-
| `onCreateSchedule` | `(request: SaveScheduleRequest) => Promise<BusinessDaySchedule>` | No | Creates a tenant schedule from the "Create New Schedule" drawer; a rejected promise's `message` is shown as its error
|
|
146
|
-
| `onUpdateSchedule` | `(id: number, request: SaveScheduleRequest) => Promise<BusinessDaySchedule>` | No | Replaces a tenant schedule in place from the picker's "Edit" action; same error handling as `onCreateSchedule`
|
|
147
|
-
| `onDeleteSchedule` | `(id: number) => Promise<void>` | No | Permanently deletes a tenant schedule from the picker's delete action
|
|
151
|
+
| `onCreateSchedule` | `(request: SaveScheduleRequest) => Promise<BusinessDaySchedule>` | No | Creates a tenant schedule from the "Create New Schedule" drawer; a rejected promise's `message` is shown as its error (the schedule UI needs `onScheduleBindingsChange`) |
|
|
152
|
+
| `onUpdateSchedule` | `(id: number, request: SaveScheduleRequest) => Promise<BusinessDaySchedule>` | No | Replaces a tenant schedule in place from the picker's "Edit" action; same error handling as `onCreateSchedule` (the schedule UI needs `onScheduleBindingsChange`) |
|
|
153
|
+
| `onDeleteSchedule` | `(id: number) => Promise<void>` | No | Permanently deletes a tenant schedule from the picker's delete action (the schedule UI needs `onScheduleBindingsChange`) |
|
|
148
154
|
|
|
149
155
|
#### Example
|
|
150
156
|
|
|
@@ -337,7 +343,9 @@ Types of e-signature fields:
|
|
|
337
343
|
backend, at signing time.
|
|
338
344
|
- **`businessCalendarEnabled`** / **`scheduleId`**: the same business-day exclusion toggle and schedule choice as a
|
|
339
345
|
calculated field's (see **Business-day calendars** below), stored here instead of in `scheduleBindings` because,
|
|
340
|
-
like `rules`, it applies to every `dateSignedOffset` field in the document at once, not one field at a time.
|
|
346
|
+
like `rules`, it applies to every `dateSignedOffset` field in the document at once, not one field at a time. The
|
|
347
|
+
e-sign schedule is shown only when `onScheduleBindingsChange` is passed to `PdfEditor`; the callback is not called
|
|
348
|
+
for it.
|
|
341
349
|
|
|
342
350
|
All `dateSignedOffset` fields in a document share one `data` object — editing any one of them (days, rules, or the
|
|
343
351
|
business-calendar toggle) updates every sibling via `onMatchingFieldsConfigChange`, and a newly dropped
|
|
@@ -404,6 +412,10 @@ shown inline in its own config panel (see **ESignDateSignedOffsetSettings** abov
|
|
|
404
412
|
schedules (`holidayCatalog`, `schedules`, `onCreateSchedule`/`onUpdateSchedule`/`onDeleteSchedule`) but storing the
|
|
405
413
|
choice on the field's `data` instead of in `scheduleBindings`.
|
|
406
414
|
|
|
415
|
+
- **Showing and hiding the UI**: the switch, the picker and the e-sign schedule are offered only when
|
|
416
|
+
`onScheduleBindingsChange` is passed. A host that cannot save bindings (for example one without a tenant, or whose
|
|
417
|
+
schedules failed to load) leaves it out, and the editor then shows none of them. The formula preview still follows
|
|
418
|
+
`scheduleBindings`, `fieldCalendars` and `holidays`.
|
|
407
419
|
- **`scheduleBindings`** (`FieldScheduleBinding[]`, `{ fieldKey, scheduleId? }`, `fieldKey` = `PdfField.id`) is the
|
|
408
420
|
source of truth for which fields have the toggle on, and which schedule each uses (`scheduleId` undefined = the
|
|
409
421
|
default schedule). A field with no entry here is unaffected by `holidays` / `fieldCalendars`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ScheduleEditorContext } from '
|
|
1
|
+
import { type ScheduleEditorContext } from '../../vendor/dte-shared/index';
|
|
2
2
|
import { Dispatch, FC, SetStateAction } from 'react';
|
|
3
3
|
import { type CalculatedFieldFormat } from '../../interface/types';
|
|
4
4
|
interface AdvancedSettingsProps {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Flex, SegmentedControl, Switch, Text } from '@servicetitan/anvil2';
|
|
3
|
-
import { BusinessCalendarSection } from '
|
|
3
|
+
import { BusinessCalendarSection } from '../../vendor/dte-shared/index';
|
|
4
4
|
import { DEFAULT_DATE_FORMAT, ROUNDING_OPTIONS } from '../../constants';
|
|
5
5
|
const DateFormatSettings = ({ businessCalendar, format, setFormat }) => {
|
|
6
6
|
var _a;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ScheduleEditorContext } from '
|
|
1
|
+
import { type ScheduleEditorContext } from '../../vendor/dte-shared/index';
|
|
2
2
|
import { FC } from 'react';
|
|
3
3
|
import { ESignDateSignedOffsetSettings, FormFieldsByFormIdI, FormInfo, PdfField, SchemaObject } from '../../interface/types';
|
|
4
4
|
interface ESignOptionsModalProps {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button, Flex, NumberField } from '@servicetitan/anvil2';
|
|
3
3
|
import AddIcon from '@servicetitan/anvil2/assets/icons/material/round/add_circle.svg';
|
|
4
|
-
import { BusinessCalendarSection } from '
|
|
4
|
+
import { BusinessCalendarSection } from '../../vendor/dte-shared/index';
|
|
5
5
|
import { Fragment, useState } from 'react';
|
|
6
6
|
import { createClearedESignOffsetSettings } from '../../utils';
|
|
7
7
|
import { ESignDateRulesSummary } from './e-sign-date-rules-summary';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-config-panel-overlay.d.ts","sourceRoot":"","sources":["../../../src/components/field-config-panel/field-config-panel-overlay.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,EAAE,EAAwB,MAAM,OAAO,CAAC;AACjD,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACpB,MAAM,uBAAuB,CAAC;AAI/B,UAAU,4BAA4B;IAClC,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC5B,kBAAkB,EAAE,mBAAmB,CAAC;IACxC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,aAAa,EAAE,QAAQ,CAAC;IACxB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAClD,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC1C,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB,CAAC,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;IAClE,gBAAgB,CAAC,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9E,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC1F,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACtD,4BAA4B,CAAC,CACzB,SAAS,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,EACvC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,GACtE,IAAI,CAAC;IACR,aAAa,IAAI,IAAI,CAAC;IACtB,eAAe,CAAC,IAAI,IAAI,CAAC;IACzB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,4BAA4B,
|
|
1
|
+
{"version":3,"file":"field-config-panel-overlay.d.ts","sourceRoot":"","sources":["../../../src/components/field-config-panel/field-config-panel-overlay.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,EAAE,EAAwB,MAAM,OAAO,CAAC;AACjD,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACpB,MAAM,uBAAuB,CAAC;AAI/B,UAAU,4BAA4B;IAClC,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC5B,kBAAkB,EAAE,mBAAmB,CAAC;IACxC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,aAAa,EAAE,QAAQ,CAAC;IACxB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAClD,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC1C,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB,CAAC,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;IAClE,gBAAgB,CAAC,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9E,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC1F,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACtD,4BAA4B,CAAC,CACzB,SAAS,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,EACvC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,GACtE,IAAI,CAAC;IACR,aAAa,IAAI,IAAI,CAAC;IACtB,eAAe,CAAC,IAAI,IAAI,CAAC;IACzB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,4BAA4B,CAwIpE,CAAC"}
|
|
@@ -14,21 +14,29 @@ export const FieldConfigPanelOverlay = ({ dataModel, documentFields = [], fieldC
|
|
|
14
14
|
const handleSelectSchedule = useCallback((scheduleId) => {
|
|
15
15
|
onScheduleBindingsChange === null || onScheduleBindingsChange === void 0 ? void 0 : onScheduleBindingsChange(setFieldSchedule(scheduleBindings !== null && scheduleBindings !== void 0 ? scheduleBindings : [], selectedFieldId, scheduleId));
|
|
16
16
|
}, [scheduleBindings, selectedFieldId, onScheduleBindingsChange]);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
/*
|
|
18
|
+
* The schedule UI (the Formula Builder's switch and the e-sign day offset's schedule) is offered
|
|
19
|
+
* only to a host that passes `onScheduleBindingsChange`. Without it there is no context, and
|
|
20
|
+
* everything that renders the schedule UI checks for one.
|
|
21
|
+
*/
|
|
22
|
+
const businessCalendar = useMemo(() => onScheduleBindingsChange
|
|
23
|
+
? {
|
|
24
|
+
enabled: !!selectedBinding,
|
|
25
|
+
selectedScheduleId: selectedBinding === null || selectedBinding === void 0 ? void 0 : selectedBinding.scheduleId,
|
|
26
|
+
onToggle: handleToggle,
|
|
27
|
+
onSelectSchedule: handleSelectSchedule,
|
|
28
|
+
holidayCatalog,
|
|
29
|
+
holidayCatalogLoading,
|
|
30
|
+
holidayCatalogError,
|
|
31
|
+
schedules,
|
|
32
|
+
schedulesLoading,
|
|
33
|
+
schedulesError,
|
|
34
|
+
onCreateSchedule,
|
|
35
|
+
onUpdateSchedule,
|
|
36
|
+
onDeleteSchedule,
|
|
37
|
+
}
|
|
38
|
+
: undefined, [
|
|
39
|
+
onScheduleBindingsChange,
|
|
32
40
|
selectedBinding,
|
|
33
41
|
handleToggle,
|
|
34
42
|
handleSelectSchedule,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-config-panel-overlay.js","sourceRoot":"","sources":["../../../src/components/field-config-panel/field-config-panel-overlay.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,SAAS,MAAM,4DAA4D,CAAC;AAEnF,OAAO,EAAM,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAajD,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAkCxD,MAAM,CAAC,MAAM,uBAAuB,GAAqC,CAAC,EACtE,SAAS,EACT,cAAc,GAAG,EAAE,EACnB,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,4BAA4B,EAC5B,mBAAmB,EACnB,wBAAwB,EACxB,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,aAAa,GAChB,EAAE,EAAE;IACD,MAAM,eAAe,GAAG,OAAO,CAC3B,GAAG,EAAE,CAAC,uBAAuB,CAAC,aAAa,CAAC,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,CAAC,EAC3F,CAAC,aAAa,CAAC,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,CAAC,CACjE,CAAC;IAEF,MAAM,eAAe,GAAG,aAAa,CAAC,EAAE,CAAC;IACzC,MAAM,eAAe,GAAG,OAAO,CAC3B,GAAG,EAAE,CAAC,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,eAAe,CAAC,EACjE,CAAC,gBAAgB,EAAE,eAAe,CAAC,CACtC,CAAC;IAEF,MAAM,YAAY,GAAG,WAAW,CAC5B,CAAC,OAAgB,EAAE,EAAE;QACjB,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CACpB,uBAAuB,CAAC,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,CAC5E,CAAC;IACN,CAAC,EACD,CAAC,gBAAgB,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAChE,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CACpC,CAAC,UAA8B,EAAE,EAAE;QAC/B,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CACpB,gBAAgB,CAAC,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,EAAE,EAAE,eAAe,EAAE,UAAU,CAAC,CACxE,CAAC;IACN,CAAC,EACD,CAAC,gBAAgB,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAChE,CAAC;IAEF,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"field-config-panel-overlay.js","sourceRoot":"","sources":["../../../src/components/field-config-panel/field-config-panel-overlay.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,SAAS,MAAM,4DAA4D,CAAC;AAEnF,OAAO,EAAM,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAajD,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAkCxD,MAAM,CAAC,MAAM,uBAAuB,GAAqC,CAAC,EACtE,SAAS,EACT,cAAc,GAAG,EAAE,EACnB,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,4BAA4B,EAC5B,mBAAmB,EACnB,wBAAwB,EACxB,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,aAAa,GAChB,EAAE,EAAE;IACD,MAAM,eAAe,GAAG,OAAO,CAC3B,GAAG,EAAE,CAAC,uBAAuB,CAAC,aAAa,CAAC,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,CAAC,EAC3F,CAAC,aAAa,CAAC,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,CAAC,CACjE,CAAC;IAEF,MAAM,eAAe,GAAG,aAAa,CAAC,EAAE,CAAC;IACzC,MAAM,eAAe,GAAG,OAAO,CAC3B,GAAG,EAAE,CAAC,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,eAAe,CAAC,EACjE,CAAC,gBAAgB,EAAE,eAAe,CAAC,CACtC,CAAC;IAEF,MAAM,YAAY,GAAG,WAAW,CAC5B,CAAC,OAAgB,EAAE,EAAE;QACjB,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CACpB,uBAAuB,CAAC,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,CAC5E,CAAC;IACN,CAAC,EACD,CAAC,gBAAgB,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAChE,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CACpC,CAAC,UAA8B,EAAE,EAAE;QAC/B,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CACpB,gBAAgB,CAAC,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,EAAE,EAAE,eAAe,EAAE,UAAU,CAAC,CACxE,CAAC;IACN,CAAC,EACD,CAAC,gBAAgB,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAChE,CAAC;IAEF;;;;OAIG;IACH,MAAM,gBAAgB,GAAsC,OAAO,CAC/D,GAAG,EAAE,CACD,wBAAwB;QACpB,CAAC,CAAC;YACI,OAAO,EAAE,CAAC,CAAC,eAAe;YAC1B,kBAAkB,EAAE,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,UAAU;YAC/C,QAAQ,EAAE,YAAY;YACtB,gBAAgB,EAAE,oBAAoB;YACtC,cAAc;YACd,qBAAqB;YACrB,mBAAmB;YACnB,SAAS;YACT,gBAAgB;YAChB,cAAc;YACd,gBAAgB;YAChB,gBAAgB;YAChB,gBAAgB;SACnB;QACH,CAAC,CAAC,SAAS,EACnB;QACI,wBAAwB;QACxB,eAAe;QACf,YAAY;QACZ,oBAAoB;QACpB,cAAc;QACd,qBAAqB;QACrB,mBAAmB;QACnB,SAAS;QACT,gBAAgB;QAChB,cAAc;QACd,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;KACnB,CACJ,CAAC;IAEF,OAAO,CACH,MAAC,IAAI,IAAC,SAAS,EAAC,gCAAgC,EAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,aAC9E,MAAC,IAAI,IACD,SAAS,EAAC,+BAA+B,EACzC,UAAU,EAAC,QAAQ,EACnB,cAAc,EAAC,eAAe,aAE9B,KAAC,IAAI,IAAC,OAAO,EAAC,UAAU,EAAC,EAAE,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,oCAEtC,EACP,KAAC,MAAM,IACH,UAAU,EAAC,OAAO,EAClB,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,eAAe,gBACb,OAAO,EAClB,IAAI,EAAE,SAAS,GACjB,IACC,EACP,cAAK,SAAS,EAAC,gCAAgC,YAC3C,KAAC,gBAAgB,IACb,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,EAC9B,KAAK,EAAE,aAAa,EACpB,kBAAkB,EAAE,kBAAkB,EACtC,KAAK,EAAE,KAAK,EACZ,oBAAoB,EAAE,oBAAoB,EAC1C,UAAU,EAAE,UAAU,EACtB,mBAAmB,EAAE,mBAAmB,EACxC,4BAA4B,EAAE,4BAA4B,EAC1D,aAAa,EAAE,aAAa,EAC5B,oBAAoB,EAAE,oBAAoB,EAC1C,eAAe,EAAE,eAAe,EAChC,gBAAgB,EAAE,gBAAgB,EAClC,mBAAmB,EAAE,mBAAmB,GAC1C,GACA,IACH,CACV,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ScheduleEditorContext } from '
|
|
1
|
+
import { type ScheduleEditorContext } from '../../vendor/dte-shared/index';
|
|
2
2
|
import { FC } from 'react';
|
|
3
3
|
import { type FormFieldsByFormIdI, type FormInfo, type PdfField, type RecipientInfo, type SchemaObject } from '../../interface/types';
|
|
4
4
|
import { type DateCalcOptions } from '../../utils';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ScheduleEditorContext } from '
|
|
1
|
+
import { type ScheduleEditorContext } from '../../vendor/dte-shared/index';
|
|
2
2
|
import { FC } from 'react';
|
|
3
3
|
import { type CalculatedFieldFormat, type FormFieldsByFormIdI, type FormInfo, type PdfField, type SchemaObject, type StructuredFormula } from '../../interface/types';
|
|
4
4
|
import { type DateCalcOptions } from '../../utils';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ScheduleEditorContext } from '
|
|
1
|
+
import { type ScheduleEditorContext } from '../../vendor/dte-shared/index';
|
|
2
2
|
import { FC } from 'react';
|
|
3
3
|
import { type CalculatedFieldFormat, type DataModelFieldGroup, type FieldTypeOption, type FormFieldsByFormIdI, type FormInfo, type StructuredFormula } from '../../interface/types';
|
|
4
4
|
import { type DateCalcOptions } from '../../utils';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ScheduleEditorContext } from '
|
|
1
|
+
import { type ScheduleEditorContext } from '../../vendor/dte-shared/index';
|
|
2
2
|
import { Dispatch, FC, KeyboardEvent, MouseEvent, ReactNode, RefObject, SetStateAction } from 'react';
|
|
3
3
|
import { type CalculatedFieldFormat } from '../../interface/types';
|
|
4
4
|
interface FormulaWorkspaceProps {
|
|
@@ -27,7 +27,7 @@ export interface PdfEditorProps {
|
|
|
27
27
|
/**
|
|
28
28
|
* Date calculated fields whose custom business-day exclusion toggle is on, and the schedule
|
|
29
29
|
* each uses (`PdfField.id` as `fieldKey`), as `PdfView`'s. Also drives the Formula Builder's
|
|
30
|
-
* toggle/picker for the selected field
|
|
30
|
+
* toggle/picker for the selected field, which are shown only with `onScheduleBindingsChange`.
|
|
31
31
|
*/
|
|
32
32
|
scheduleBindings?: FieldScheduleBinding[];
|
|
33
33
|
/** The tenant's known holidays, for the schedule editor's checklist. */
|
|
@@ -45,6 +45,11 @@ export interface PdfEditorProps {
|
|
|
45
45
|
* `PUT api/holidays/templates/{id}/bindings`). `PdfEditor` does not persist this itself —
|
|
46
46
|
* the host is expected to save it (and the bindings are typically saved separately from the
|
|
47
47
|
* template's own fields).
|
|
48
|
+
*
|
|
49
|
+
* Passing it also turns the schedule UI on: without it the Formula Builder has no "Exclude
|
|
50
|
+
* weekends & holidays" switch and the e-sign day offset has no schedule. A host that cannot save
|
|
51
|
+
* bindings (for example one without a tenant) leaves it out. It is not called for the e-sign
|
|
52
|
+
* schedule, which is stored in the field's `data`.
|
|
48
53
|
*/
|
|
49
54
|
onScheduleBindingsChange?(bindings: FieldScheduleBinding[]): void;
|
|
50
55
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-editor.d.ts","sourceRoot":"","sources":["../../../src/components/pdf-editor/pdf-editor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,SAAS,EAAgC,MAAM,OAAO,CAAC;AAEpE,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACpB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAa,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,wBAAwB,CAAC;AAEhC,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,kBAAkB,CAAC,EAAE,SAAS,CAAC;IAC/B,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAClD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC1C,wEAAwE;IACxE,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,CACX,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,CAAC,kBAAkB,EAAE,mBAAmB,KAAK,IAAI,KAChE,IAAI,CAAC;IACV
|
|
1
|
+
{"version":3,"file":"pdf-editor.d.ts","sourceRoot":"","sources":["../../../src/components/pdf-editor/pdf-editor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,SAAS,EAAgC,MAAM,OAAO,CAAC;AAEpE,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACpB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAa,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,wBAAwB,CAAC;AAEhC,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,kBAAkB,CAAC,EAAE,SAAS,CAAC;IAC/B,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAClD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC1C,wEAAwE;IACxE,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,CACX,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,CAAC,kBAAkB,EAAE,mBAAmB,KAAK,IAAI,KAChE,IAAI,CAAC;IACV;;;;;;;;;;;OAWG;IACH,wBAAwB,CAAC,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;IAClE;;;;;OAKG;IACH,gBAAgB,CAAC,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9E;;;;OAIG;IACH,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC1F;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,aAAa,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;CAC5C;AAED,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CA0IxC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-editor.js","sourceRoot":"","sources":["../../../src/components/pdf-editor/pdf-editor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAiB,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAclF,OAAO,EAAE,iCAAiC,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAkB,MAAM,0BAA0B,CAAC;AAErE,OAAO,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"pdf-editor.js","sourceRoot":"","sources":["../../../src/components/pdf-editor/pdf-editor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -255,7 +255,7 @@ export interface BusinessCalendar {
|
|
|
255
255
|
* working: the schedule editor UI (`ScheduleDrawer`/`SchedulePicker`) is shared with
|
|
256
256
|
* `@servicetitan/dte-unlayer` and lives there now, these types are its domain model.
|
|
257
257
|
*/
|
|
258
|
-
export type { BusinessCalendarRules, BusinessDaySchedule, HolidayCatalog, KnownHoliday, SaveScheduleRequest, WeekendDay, } from '
|
|
258
|
+
export type { BusinessCalendarRules, BusinessDaySchedule, HolidayCatalog, KnownHoliday, SaveScheduleRequest, WeekendDay, } from '../vendor/dte-shared/index';
|
|
259
259
|
/**
|
|
260
260
|
* A date calculated field whose custom business-day exclusion toggle is on, and the schedule it
|
|
261
261
|
* uses (DTE's bindings, full-replace via `PUT api/holidays/templates/{id}/bindings`). A field with
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Whether `value` is a valid `MM-DD` custom date (`02-29` included, as a recurring rule). */
|
|
2
|
+
export declare function isValidCustomDate(value: string): boolean;
|
|
3
|
+
/** A month/day pair as `DateFieldYearless` represents it (either part `null` while incomplete). */
|
|
4
|
+
export interface YearlessDateValue {
|
|
5
|
+
month: number | null;
|
|
6
|
+
day: number | null;
|
|
7
|
+
}
|
|
8
|
+
/** Converts a complete `{ month, day }` to `MM-DD`, or null while the field is incomplete/invalid. */
|
|
9
|
+
export declare function yearlessDateToCustomDate(value: YearlessDateValue | null): string | null;
|
|
10
|
+
/** Converts a stored `MM-DD` custom date back to `DateFieldYearless`'s `{ month, day }` value. */
|
|
11
|
+
export declare function customDateToYearlessDate(value: string): YearlessDateValue | null;
|
|
12
|
+
/** Formats a stored `MM-DD` custom date for display, e.g. `03-03` → `Mar - 03`. */
|
|
13
|
+
export declare function formatCustomDateLabel(value: string): string;
|
|
14
|
+
/** Whether `name` is the reserved default-schedule name, ignoring case and surrounding whitespace. */
|
|
15
|
+
export declare function isReservedScheduleName(name: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Client-side schedule name checks mirroring DTE's `SaveDateScheduleRequest.Name` contract: a
|
|
18
|
+
* required, non-reserved name up to 255 characters, unique per tenant ignoring case. `existingNames`
|
|
19
|
+
* should exclude the schedule being edited, if any. The server is still authoritative — a duplicate
|
|
20
|
+
* it rejects despite passing this check is a 409, not a bug here.
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateScheduleName(name: string, existingNames: string[]): string | undefined;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { CUSTOM_DATE_MONTH_LENGTHS, CUSTOM_DATE_PATTERN, MAX_SCHEDULE_NAME_LENGTH, RESERVED_SCHEDULE_NAME, } from './constants';
|
|
2
|
+
/** Whether `value` is a valid `MM-DD` custom date (`02-29` included, as a recurring rule). */
|
|
3
|
+
export function isValidCustomDate(value) {
|
|
4
|
+
const match = CUSTOM_DATE_PATTERN.exec(value);
|
|
5
|
+
if (!match) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const month = Number(match[1]);
|
|
9
|
+
const day = Number(match[2]);
|
|
10
|
+
return day <= CUSTOM_DATE_MONTH_LENGTHS[month - 1];
|
|
11
|
+
}
|
|
12
|
+
/** Converts a complete `{ month, day }` to `MM-DD`, or null while the field is incomplete/invalid. */
|
|
13
|
+
export function yearlessDateToCustomDate(value) {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
const month = (_a = value === null || value === void 0 ? void 0 : value.month) !== null && _a !== void 0 ? _a : null;
|
|
16
|
+
const day = (_b = value === null || value === void 0 ? void 0 : value.day) !== null && _b !== void 0 ? _b : null;
|
|
17
|
+
if (month === null || day === null) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const candidate = `${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
|
21
|
+
return isValidCustomDate(candidate) ? candidate : null;
|
|
22
|
+
}
|
|
23
|
+
/** Converts a stored `MM-DD` custom date back to `DateFieldYearless`'s `{ month, day }` value. */
|
|
24
|
+
export function customDateToYearlessDate(value) {
|
|
25
|
+
const match = CUSTOM_DATE_PATTERN.exec(value);
|
|
26
|
+
return match ? { month: Number(match[1]), day: Number(match[2]) } : null;
|
|
27
|
+
}
|
|
28
|
+
const CUSTOM_DATE_MONTH_ABBREVIATIONS = [
|
|
29
|
+
'Jan',
|
|
30
|
+
'Feb',
|
|
31
|
+
'Mar',
|
|
32
|
+
'Apr',
|
|
33
|
+
'May',
|
|
34
|
+
'Jun',
|
|
35
|
+
'Jul',
|
|
36
|
+
'Aug',
|
|
37
|
+
'Sep',
|
|
38
|
+
'Oct',
|
|
39
|
+
'Nov',
|
|
40
|
+
'Dec',
|
|
41
|
+
];
|
|
42
|
+
/** Formats a stored `MM-DD` custom date for display, e.g. `03-03` → `Mar - 03`. */
|
|
43
|
+
export function formatCustomDateLabel(value) {
|
|
44
|
+
const match = CUSTOM_DATE_PATTERN.exec(value);
|
|
45
|
+
if (!match) {
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
const [, month, day] = match;
|
|
49
|
+
return `${CUSTOM_DATE_MONTH_ABBREVIATIONS[Number(month) - 1]} - ${day}`;
|
|
50
|
+
}
|
|
51
|
+
/** Whether `name` is the reserved default-schedule name, ignoring case and surrounding whitespace. */
|
|
52
|
+
export function isReservedScheduleName(name) {
|
|
53
|
+
return name.trim().toLowerCase() === RESERVED_SCHEDULE_NAME.toLowerCase();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Client-side schedule name checks mirroring DTE's `SaveDateScheduleRequest.Name` contract: a
|
|
57
|
+
* required, non-reserved name up to 255 characters, unique per tenant ignoring case. `existingNames`
|
|
58
|
+
* should exclude the schedule being edited, if any. The server is still authoritative — a duplicate
|
|
59
|
+
* it rejects despite passing this check is a 409, not a bug here.
|
|
60
|
+
*/
|
|
61
|
+
export function validateScheduleName(name, existingNames) {
|
|
62
|
+
const trimmed = name.trim();
|
|
63
|
+
if (!trimmed) {
|
|
64
|
+
return 'Schedule name is required';
|
|
65
|
+
}
|
|
66
|
+
if (trimmed.length > MAX_SCHEDULE_NAME_LENGTH) {
|
|
67
|
+
return `Schedule name must be ${MAX_SCHEDULE_NAME_LENGTH} characters or fewer`;
|
|
68
|
+
}
|
|
69
|
+
if (isReservedScheduleName(trimmed)) {
|
|
70
|
+
return `"${RESERVED_SCHEDULE_NAME}" is reserved for the default schedule`;
|
|
71
|
+
}
|
|
72
|
+
if (existingNames.some(existing => existing.trim().toLowerCase() === trimmed.toLowerCase())) {
|
|
73
|
+
return 'A schedule with this name already exists';
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import '../styles/schedule.css';
|
|
3
|
+
import { type ScheduleEditorContext } from '../types';
|
|
4
|
+
interface BusinessCalendarSectionProps {
|
|
5
|
+
businessCalendar: ScheduleEditorContext;
|
|
6
|
+
/** @default "Exclude weekends & holidays from the calculation" */
|
|
7
|
+
label?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A business-day exclusion toggle, shown for a date calculated field (Formula Builder's Advanced
|
|
11
|
+
* Settings, date result type only) and an e-sign `dateSignedOffset` field's day-offset settings.
|
|
12
|
+
* Off is plain calendar-day arithmetic; on reveals the schedule picker.
|
|
13
|
+
*/
|
|
14
|
+
export declare const BusinessCalendarSection: FC<BusinessCalendarSectionProps>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Flex, Switch } from '@servicetitan/anvil2';
|
|
3
|
+
import '../styles/schedule.css';
|
|
4
|
+
import { SchedulePicker } from './schedule-picker';
|
|
5
|
+
/**
|
|
6
|
+
* A business-day exclusion toggle, shown for a date calculated field (Formula Builder's Advanced
|
|
7
|
+
* Settings, date result type only) and an e-sign `dateSignedOffset` field's day-offset settings.
|
|
8
|
+
* Off is plain calendar-day arithmetic; on reveals the schedule picker.
|
|
9
|
+
*/
|
|
10
|
+
export const BusinessCalendarSection = ({ businessCalendar, label = 'Exclude weekends & holidays from the calculation', }) => {
|
|
11
|
+
const { enabled, onToggle } = businessCalendar;
|
|
12
|
+
return (_jsx("div", { className: "dte-business-calendar-section", children: _jsxs(Flex, { direction: "column", gap: "4", children: [_jsx(Switch, { checked: enabled, onChange: (_e, state) => onToggle(state.checked), label: label, value: "business-calendar-exclusion" }), enabled && _jsx(SchedulePicker, { businessCalendar: businessCalendar })] }) }));
|
|
13
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { type BusinessDaySchedule, type ScheduleEditorContext } from '../types';
|
|
3
|
+
interface ScheduleDrawerProps {
|
|
4
|
+
businessCalendar: ScheduleEditorContext;
|
|
5
|
+
/** When set, edits this schedule in place (PUT) instead of creating a new one (POST). */
|
|
6
|
+
editingSchedule?: BusinessDaySchedule;
|
|
7
|
+
onClose(): void;
|
|
8
|
+
onSaved(schedule: BusinessDaySchedule): void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* "Create New Schedule" / "Edit Schedule" drawer. Creating starts from the default schedule's
|
|
12
|
+
* rules (DEFAULT_SCHEDULE_WEEKEND_DAYS, every catalog holiday); editing starts from
|
|
13
|
+
* `editingSchedule`'s own rules and replaces it in place on save.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ScheduleDrawer: FC<ScheduleDrawerProps>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Alert, Button, ButtonToggle, DateFieldYearless, Drawer, Flex, MultiSelectFieldSync, Text, TextField, } from '@servicetitan/anvil2';
|
|
3
|
+
import IconAddCircle from '@servicetitan/anvil2/assets/icons/material/round/add_circle.svg';
|
|
4
|
+
import DeleteIcon from '@servicetitan/anvil2/assets/icons/material/round/delete.svg';
|
|
5
|
+
import { useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { customDateToYearlessDate, validateScheduleName, yearlessDateToCustomDate, } from '../business-calendar-validation.utils';
|
|
7
|
+
import { DEFAULT_SCHEDULE_WEEKEND_DAYS } from '../constants';
|
|
8
|
+
const EMPTY_DATE = { month: null, day: null };
|
|
9
|
+
const isEmptyDate = (value) => value.month === null && value.day === null;
|
|
10
|
+
/**
|
|
11
|
+
* "Create New Schedule" / "Edit Schedule" drawer. Creating starts from the default schedule's
|
|
12
|
+
* rules (DEFAULT_SCHEDULE_WEEKEND_DAYS, every catalog holiday); editing starts from
|
|
13
|
+
* `editingSchedule`'s own rules and replaces it in place on save.
|
|
14
|
+
*/
|
|
15
|
+
export const ScheduleDrawer = ({ businessCalendar, editingSchedule, onClose, onSaved, }) => {
|
|
16
|
+
var _a;
|
|
17
|
+
const { holidayCatalog, holidayCatalogError, holidayCatalogLoading, onCreateSchedule, onUpdateSchedule, schedules, } = businessCalendar;
|
|
18
|
+
const [name, setName] = useState((_a = editingSchedule === null || editingSchedule === void 0 ? void 0 : editingSchedule.name) !== null && _a !== void 0 ? _a : '');
|
|
19
|
+
const [weekendDays, setWeekendDays] = useState(() => { var _a; return new Set((_a = editingSchedule === null || editingSchedule === void 0 ? void 0 : editingSchedule.calendar.weekendDays) !== null && _a !== void 0 ? _a : DEFAULT_SCHEDULE_WEEKEND_DAYS); });
|
|
20
|
+
const [knownHolidays, setKnownHolidays] = useState(() => {
|
|
21
|
+
var _a, _b;
|
|
22
|
+
return new Set((_b = (_a = editingSchedule === null || editingSchedule === void 0 ? void 0 : editingSchedule.calendar.knownHolidays) !== null && _a !== void 0 ? _a : holidayCatalog === null || holidayCatalog === void 0 ? void 0 : holidayCatalog.holidays.map(h => h.code)) !== null && _b !== void 0 ? _b : []);
|
|
23
|
+
});
|
|
24
|
+
const [customDates, setCustomDates] = useState(() => {
|
|
25
|
+
var _a;
|
|
26
|
+
return ((_a = editingSchedule === null || editingSchedule === void 0 ? void 0 : editingSchedule.calendar.customDates) !== null && _a !== void 0 ? _a : []).map((date, index) => {
|
|
27
|
+
var _a;
|
|
28
|
+
return ({
|
|
29
|
+
id: index,
|
|
30
|
+
value: (_a = customDateToYearlessDate(date)) !== null && _a !== void 0 ? _a : EMPTY_DATE,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
const nextRowId = useRef(customDates.length);
|
|
35
|
+
const [nameTouched, setNameTouched] = useState(false);
|
|
36
|
+
const [submitError, setSubmitError] = useState();
|
|
37
|
+
const [submitting, setSubmitting] = useState(false);
|
|
38
|
+
const holidayOptions = useMemo(() => {
|
|
39
|
+
var _a;
|
|
40
|
+
return ((_a = holidayCatalog === null || holidayCatalog === void 0 ? void 0 : holidayCatalog.holidays) !== null && _a !== void 0 ? _a : []).map(h => ({
|
|
41
|
+
id: h.code,
|
|
42
|
+
label: `${h.displayName} · ${h.rule}`,
|
|
43
|
+
}));
|
|
44
|
+
}, [holidayCatalog]);
|
|
45
|
+
const selectedHolidayOptions = useMemo(() => holidayOptions.filter(o => knownHolidays.has(String(o.id))), [holidayOptions, knownHolidays]);
|
|
46
|
+
const existingNames = useMemo(() => (schedules !== null && schedules !== void 0 ? schedules : [])
|
|
47
|
+
.filter(s => !s.isDefault && s.id !== (editingSchedule === null || editingSchedule === void 0 ? void 0 : editingSchedule.id))
|
|
48
|
+
.map(s => s.name), [schedules, editingSchedule]);
|
|
49
|
+
const nameError = validateScheduleName(name, existingNames);
|
|
50
|
+
const toggleWeekendDay = (day) => {
|
|
51
|
+
setWeekendDays(prev => {
|
|
52
|
+
const next = new Set(prev);
|
|
53
|
+
if (next.has(day)) {
|
|
54
|
+
next.delete(day);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
next.add(day);
|
|
58
|
+
}
|
|
59
|
+
return next;
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const handleAddDate = () => setCustomDates(prev => [...prev, { id: nextRowId.current++, value: EMPTY_DATE }]);
|
|
63
|
+
const handleRemoveDate = (id) => setCustomDates(prev => prev.filter(row => row.id !== id));
|
|
64
|
+
const handleCustomDateChange = (id, value) => setCustomDates(prev => prev.map(row => (row.id === id ? { ...row, value: value !== null && value !== void 0 ? value : EMPTY_DATE } : row)));
|
|
65
|
+
/** Resolved `MM-DD` per non-empty row, or `null` for an incomplete/invalid one (blocks submit). */
|
|
66
|
+
const resolvedCustomDates = customDates.map(row => isEmptyDate(row.value) ? '' : yearlessDateToCustomDate(row.value));
|
|
67
|
+
const hasInvalidCustomDate = resolvedCustomDates.some((d, i) => d === null && !isEmptyDate(customDates[i].value));
|
|
68
|
+
/*
|
|
69
|
+
* Editing is only offered for a saved tenant schedule, which always has an id (only the
|
|
70
|
+
* read-only default schedule — never editable — lacks one).
|
|
71
|
+
*/
|
|
72
|
+
const editingId = editingSchedule === null || editingSchedule === void 0 ? void 0 : editingSchedule.id;
|
|
73
|
+
const isEditing = editingId !== undefined;
|
|
74
|
+
const canSave = isEditing ? !!onUpdateSchedule : !!onCreateSchedule;
|
|
75
|
+
const canSubmit = !nameError && !hasInvalidCustomDate && !submitting && canSave;
|
|
76
|
+
const handleSubmit = async () => {
|
|
77
|
+
setNameTouched(true);
|
|
78
|
+
if (nameError || hasInvalidCustomDate || !canSave) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const request = {
|
|
82
|
+
name: name.trim(),
|
|
83
|
+
weekendDays: Array.from(weekendDays),
|
|
84
|
+
knownHolidays: Array.from(knownHolidays),
|
|
85
|
+
customDates: Array.from(new Set(resolvedCustomDates.filter((d) => !!d))),
|
|
86
|
+
};
|
|
87
|
+
setSubmitting(true);
|
|
88
|
+
setSubmitError(undefined);
|
|
89
|
+
try {
|
|
90
|
+
if (isEditing && onUpdateSchedule) {
|
|
91
|
+
onSaved(await onUpdateSchedule(editingId, request));
|
|
92
|
+
}
|
|
93
|
+
else if (!isEditing && onCreateSchedule) {
|
|
94
|
+
onSaved(await onCreateSchedule(request));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
setSubmitError(e instanceof Error
|
|
99
|
+
? e.message
|
|
100
|
+
: `Failed to ${isEditing ? 'save' : 'create'} schedule`);
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
setSubmitting(false);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
return (_jsxs(Drawer, { open: true, onClose: onClose, size: "medium", children: [_jsx(Drawer.Header, { children: isEditing ? 'Edit Schedule' : 'Create New Schedule' }), _jsx(Drawer.Content, { children: _jsxs(Flex, { direction: "column", gap: "4", children: [_jsx(TextField, { required: true, label: "Schedule Name", value: name, onChange: e => setName(e.target.value), onBlur: () => setNameTouched(true), error: nameTouched ? nameError : undefined }), _jsxs(Flex, { direction: "column", gap: "2", children: [_jsx(Text, { variant: "eyebrow", size: "small", children: "Exclude Weekends" }), _jsxs(Flex, { gap: "3", children: [_jsx(ButtonToggle, { checked: weekendDays.has(6), onClick: () => toggleWeekendDay(6), children: "Saturday" }), _jsx(ButtonToggle, { checked: weekendDays.has(0), onClick: () => toggleWeekendDay(0), children: "Sunday" })] })] }), _jsxs(Flex, { direction: "column", gap: "2", children: [_jsx(Text, { variant: "eyebrow", size: "small", children: "Exclude Holidays" }), holidayCatalogLoading && _jsx(Text, { variant: "body", children: "Loading holidays\u2026" }), holidayCatalogError && (_jsx(Alert, { status: "danger", title: holidayCatalogError })), _jsx(MultiSelectFieldSync, { label: holidayCatalog
|
|
107
|
+
? `${holidayCatalog.jurisdiction} Holidays`
|
|
108
|
+
: 'Holidays', disabled: holidayCatalogLoading, options: holidayOptions, value: selectedHolidayOptions, onSelectedOptionsChange: options => setKnownHolidays(new Set(options.map(o => String(o.id)))), description: "Select the holidays you want to exclude", filter: { keys: ['label'] } })] }), _jsxs(Flex, { direction: "column", gap: "2", children: [_jsx(Text, { variant: "eyebrow", size: "small", children: "Custom Dates" }), customDates.map((row, index) => {
|
|
109
|
+
const invalid = resolvedCustomDates[index] === null && !isEmptyDate(row.value);
|
|
110
|
+
return (_jsxs(Flex, { gap: "2", children: [_jsx(DateFieldYearless, { label: `Custom date ${index + 1}`, hideLabel: true, value: row.value, error: invalid ? 'Enter a valid date' : undefined, onChange: change => handleCustomDateChange(row.id, change.value), flex: 1 }), _jsx(Button, { icon: DeleteIcon, appearance: "ghost", "aria-label": "Remove date", onClick: () => handleRemoveDate(row.id) })] }, row.id));
|
|
111
|
+
}), _jsx(Button, { appearance: "ghost", icon: IconAddCircle, onClick: handleAddDate, children: "Add Date" })] }), submitError && _jsx(Alert, { status: "danger", title: submitError })] }) }), _jsxs(Drawer.Footer, { sticky: true, children: [_jsx(Drawer.CancelButton, { appearance: "secondary", children: "Cancel" }), _jsx(Button, { appearance: "primary", onClick: handleSubmit, loading: submitting, disabled: !canSubmit, children: isEditing ? 'Save' : 'Create' })] })] }));
|
|
112
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { type ScheduleEditorContext } from '../types';
|
|
3
|
+
interface SchedulePickerProps {
|
|
4
|
+
businessCalendar: ScheduleEditorContext;
|
|
5
|
+
}
|
|
6
|
+
/** "Select Schedule or create new" picker plus a collapsible preview of the selected schedule's rules. */
|
|
7
|
+
export declare const SchedulePicker: FC<SchedulePickerProps>;
|
|
8
|
+
export {};
|