@easyteam/auto-scheduler-modal-ui 0.1.3 → 0.1.5
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/index.cjs +1105 -370
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +202 -7
- package/dist/index.d.ts +202 -7
- package/dist/index.js +1098 -368
- package/dist/index.js.map +1 -1
- package/package.json +27 -25
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
2
3
|
import { ThemeOverride } from '@chakra-ui/react';
|
|
3
4
|
|
|
4
5
|
declare class RequestError extends Error {
|
|
@@ -131,8 +132,17 @@ type EmployeeProperties = {
|
|
|
131
132
|
worker_type: string;
|
|
132
133
|
costToRevenueRatio?: number;
|
|
133
134
|
avgSalesAmount?: number;
|
|
135
|
+
/** Integer basis points (e.g. 1234 = 12.34%). Omit when unknown. */
|
|
136
|
+
conversionRate?: number;
|
|
134
137
|
[key: string]: object | string | number | boolean | undefined;
|
|
135
138
|
};
|
|
139
|
+
/** One hourly traffic cell for the solver TrafficForecast fact (location-local). */
|
|
140
|
+
type TrafficForecastEntry = {
|
|
141
|
+
locationId: string;
|
|
142
|
+
date: string;
|
|
143
|
+
hour: number;
|
|
144
|
+
visits: number;
|
|
145
|
+
};
|
|
136
146
|
type Employee = {
|
|
137
147
|
id: string;
|
|
138
148
|
name: string;
|
|
@@ -250,10 +260,88 @@ type AutoSchedulerModalTheme = (ThemeOverride & {
|
|
|
250
260
|
}) | (EasyTeamThemeOverrides & {
|
|
251
261
|
autoSchedulerModal?: AutoSchedulerModalStyleOverrides;
|
|
252
262
|
});
|
|
263
|
+
type SubLocationOption = {
|
|
264
|
+
id: string;
|
|
265
|
+
name: string;
|
|
266
|
+
parentId: string;
|
|
267
|
+
};
|
|
268
|
+
type TeamOption = {
|
|
269
|
+
id: string;
|
|
270
|
+
name: string;
|
|
271
|
+
resources: {
|
|
272
|
+
id: string;
|
|
273
|
+
externalEmployeeId?: string;
|
|
274
|
+
type?: string;
|
|
275
|
+
properties?: {
|
|
276
|
+
name?: string;
|
|
277
|
+
} & Record<string, unknown>;
|
|
278
|
+
[key: string]: unknown;
|
|
279
|
+
}[];
|
|
280
|
+
};
|
|
281
|
+
type HardConstraintOption = {
|
|
282
|
+
id: string;
|
|
283
|
+
name: string;
|
|
284
|
+
/** Shows this option as selected without requiring user interaction. */
|
|
285
|
+
defaultSelected?: boolean;
|
|
286
|
+
/** Prevents changing an implicitly selected option in the scheduler drawer. */
|
|
287
|
+
readOnly?: boolean;
|
|
288
|
+
/** When present, the modal shows a numeric input on selection. */
|
|
289
|
+
defaultValue?: string;
|
|
290
|
+
/** Label next to the input, e.g. 'hours' or 'days'. Defaults to 'hours'. */
|
|
291
|
+
suffix?: string;
|
|
292
|
+
min?: number;
|
|
293
|
+
max?: number;
|
|
294
|
+
/** Used as violation message detail when the solver reports this constraint as violated. */
|
|
295
|
+
description?: string;
|
|
296
|
+
};
|
|
297
|
+
type SoftConstraintOption = {
|
|
298
|
+
id: string;
|
|
299
|
+
title: string;
|
|
300
|
+
/** Shows this option as selected without requiring user interaction. */
|
|
301
|
+
defaultSelected?: boolean;
|
|
302
|
+
/** Prevents changing an implicitly selected option in the scheduler drawer. */
|
|
303
|
+
readOnly?: boolean;
|
|
304
|
+
/** Shown below the title in the picker. Also used as violation message detail. */
|
|
305
|
+
subtitle?: string;
|
|
306
|
+
};
|
|
307
|
+
type SoftConstraintGroup = {
|
|
308
|
+
id: string;
|
|
309
|
+
name: string;
|
|
310
|
+
options: SoftConstraintOption[];
|
|
311
|
+
};
|
|
312
|
+
type BuiltinConstraintOption = {
|
|
313
|
+
id: string;
|
|
314
|
+
title: string;
|
|
315
|
+
subtitle?: string;
|
|
316
|
+
category?: string;
|
|
317
|
+
defaultSelected?: boolean;
|
|
318
|
+
};
|
|
319
|
+
type GenerateScheduleConfig = {
|
|
320
|
+
selectedLocationIds: string[];
|
|
321
|
+
selectedSubLocationIds: string[];
|
|
322
|
+
selectedTeamIds: string[];
|
|
323
|
+
/** IANA timezone resolved from the selected drawer location. */
|
|
324
|
+
schedulerTimezone?: string;
|
|
325
|
+
/** Calendar dates YYYY-MM-DD within the viewed week to include in workflow evaluation and solver optimization */
|
|
326
|
+
selectedScheduleDates: string[];
|
|
327
|
+
selectedConstraintIds: string[];
|
|
328
|
+
constraintValues: Record<string, string>;
|
|
329
|
+
selectedOptimizationIds: string[];
|
|
330
|
+
optimizationValues: Record<string, string>;
|
|
331
|
+
/** Opt-in built-in Timefold constraint slugs (not org visual-rule UUIDs). */
|
|
332
|
+
selectedBuiltinIds?: string[];
|
|
333
|
+
};
|
|
253
334
|
type AutoSchedulerModalProps = {
|
|
254
|
-
|
|
335
|
+
/** Controls whether the component renders as a modal or a right-side drawer */
|
|
336
|
+
displayMode?: 'modal' | 'drawer';
|
|
337
|
+
/** Width of the drawer when displayMode="drawer". "sm"=448px, "md"=578px, "lg"=600px. Defaults to "lg". */
|
|
338
|
+
drawerSize?: 'sm' | 'md' | 'lg';
|
|
339
|
+
/** When true, the drawer fills 100% viewport height. Defaults to false. */
|
|
340
|
+
drawerFullHeight?: boolean;
|
|
341
|
+
baseURL?: string;
|
|
255
342
|
isOpen: boolean;
|
|
256
343
|
title?: string;
|
|
344
|
+
bannerTitle?: string;
|
|
257
345
|
bannerText?: string;
|
|
258
346
|
jurisdictions: JurisdictionGroup[];
|
|
259
347
|
employees: Employee[];
|
|
@@ -270,23 +358,94 @@ type AutoSchedulerModalProps = {
|
|
|
270
358
|
};
|
|
271
359
|
theme?: AutoSchedulerModalTheme;
|
|
272
360
|
cssVarsRoot?: string;
|
|
273
|
-
generateRecommendationsURLAndHeaders
|
|
361
|
+
generateRecommendationsURLAndHeaders?: {
|
|
274
362
|
url: string;
|
|
275
363
|
headers?: Record<string, string>;
|
|
276
364
|
};
|
|
277
|
-
getTokenURLAndHeaders
|
|
365
|
+
getTokenURLAndHeaders?: {
|
|
278
366
|
url: string;
|
|
279
367
|
headers?: Record<string, string>;
|
|
280
368
|
};
|
|
281
|
-
onSolution
|
|
369
|
+
onSolution?: (solution: ScheduleSolution) => Promise<void>;
|
|
282
370
|
/** When provided, fetches stored config for a location set to prefill the form */
|
|
283
371
|
getStoredConfigForLocations?: (locationIds: string[]) => AutoSchedulerModalConfig | null;
|
|
284
372
|
/** When provided, persists config after successful schedule creation */
|
|
285
373
|
persistConfigForLocations?: (locationIds: string[], config: AutoSchedulerModalConfig) => void;
|
|
286
374
|
errorToast?: (msg: string) => void;
|
|
375
|
+
/** Organization id — required when sending visual rule ids */
|
|
376
|
+
organizationId?: string;
|
|
377
|
+
/** Visual rule ids attached to this solve (production path) */
|
|
378
|
+
constraintDefinitionIds?: string[];
|
|
379
|
+
/** Inline visual rule definitions (sandbox/test path; for unsaved rules) */
|
|
380
|
+
constraintDefinitions?: unknown[];
|
|
381
|
+
/** Replaces the built-in hard constraint list shown in "Required rules". */
|
|
382
|
+
hardConstraintOptions?: HardConstraintOption[];
|
|
383
|
+
/** Replaces the built-in optimization groups shown in "Optimization". */
|
|
384
|
+
softConstraintGroups?: SoftConstraintGroup[];
|
|
385
|
+
/** Optional footer under Optimization (e.g. host-owned Avia attribution). Prefer a render fn when showing in multiple places. */
|
|
386
|
+
optimizationFooter?: ReactNode | (() => ReactNode);
|
|
387
|
+
/**
|
|
388
|
+
* Hourly traffic forecast for the solve week (location-local).
|
|
389
|
+
* When Maximize Sales is selected and this is non-empty, the modal injects
|
|
390
|
+
* traffic-forecast-incentive and serializes this field on the solve payload.
|
|
391
|
+
*/
|
|
392
|
+
trafficForecast?: TrafficForecastEntry[];
|
|
393
|
+
/** Opt-in built-in Timefold constraints (solver catalog slugs). */
|
|
394
|
+
builtinConstraintOptions?: BuiltinConstraintOption[];
|
|
395
|
+
/** All sub-locations (with parentId). The component filters them internally based on selected location IDs. */
|
|
396
|
+
subLocations?: SubLocationOption[];
|
|
397
|
+
/** When true, renders the sub-locations multiselect (filtered by selected locations). Defaults to false. */
|
|
398
|
+
showSubLocations?: boolean;
|
|
399
|
+
/** Teams list. The caller should update this reactively in response to onSelectionChange. */
|
|
400
|
+
teams?: TeamOption[];
|
|
401
|
+
/** When true, renders the teams multiselect. Defaults to false. */
|
|
402
|
+
showTeams?: boolean;
|
|
403
|
+
/**
|
|
404
|
+
* Called when the user changes location or sub-location selection.
|
|
405
|
+
* Use this to re-fetch teams filtered by the new selection.
|
|
406
|
+
*/
|
|
407
|
+
onSelectionChange?: (locationIds: string[], subLocationIds: string[]) => void;
|
|
408
|
+
/**
|
|
409
|
+
* When provided, replaces the Java solver flow entirely.
|
|
410
|
+
* The component shows the progress animation and calls this function at step 1.
|
|
411
|
+
* Resolving means success (the resolved value is forwarded to onGenerateSolution);
|
|
412
|
+
* throwing means failure (shown in the failed screen).
|
|
413
|
+
*/
|
|
414
|
+
onGenerate?: (config: GenerateScheduleConfig) => Promise<unknown>;
|
|
415
|
+
/**
|
|
416
|
+
* Called after onGenerate resolves successfully, just before the drawer/modal closes.
|
|
417
|
+
* Receives the value returned by onGenerate.
|
|
418
|
+
*/
|
|
419
|
+
onGenerateSolution?: (result: unknown) => void;
|
|
420
|
+
/**
|
|
421
|
+
* Calendar week-start date YYYY-MM-DD (matches ops weekly schedule / evaluate-range window).
|
|
422
|
+
* When `onGenerate` is used, pass the week currently shown on the schedule grid.
|
|
423
|
+
*/
|
|
424
|
+
scheduleWeekStartYmd?: string;
|
|
425
|
+
/**
|
|
426
|
+
* Today's civil date YYYY-MM-DD in `evaluationTimezone`, used to leave past week days unselected by default.
|
|
427
|
+
*/
|
|
428
|
+
todayCalendarYmd?: string;
|
|
429
|
+
/**
|
|
430
|
+
* IANA timezone for interpreting today + backend evaluate-range date filtering (defaults to UTC).
|
|
431
|
+
*/
|
|
432
|
+
evaluationTimezone?: string;
|
|
433
|
+
/**
|
|
434
|
+
* Live status of the underlying solve job. When set to "QUEUED" while the
|
|
435
|
+
* progress UI is visible, step 2's caption is replaced with "Waiting in queue…".
|
|
436
|
+
* Any other value (or null/undefined) leaves the step copy unchanged.
|
|
437
|
+
*/
|
|
438
|
+
solveStatus?: SolveJobStatus | null;
|
|
287
439
|
};
|
|
288
440
|
type Screen = "configure" | "creating" | "failed";
|
|
289
441
|
type StepStatus = "pending" | "active" | "done";
|
|
442
|
+
/**
|
|
443
|
+
* Status of an async solve job, as reported by the scheduler service.
|
|
444
|
+
* QUEUED → waiting for a solver slot
|
|
445
|
+
* SOLVING_ACTIVE → solver is running
|
|
446
|
+
* NOT_SOLVING / TERMINATED_EARLY → terminal
|
|
447
|
+
*/
|
|
448
|
+
type SolveJobStatus = "QUEUED" | "SOLVING_ACTIVE" | "NOT_SOLVING" | "TERMINATED_EARLY";
|
|
290
449
|
type RuleOverrideEntry = {
|
|
291
450
|
ruleId: string;
|
|
292
451
|
parameters?: Record<string, unknown>;
|
|
@@ -323,10 +482,16 @@ type SchedulePayload = {
|
|
|
323
482
|
timezone?: string;
|
|
324
483
|
jurisdiction?: string;
|
|
325
484
|
tags?: string[];
|
|
485
|
+
properties?: Record<string, unknown>;
|
|
326
486
|
}>;
|
|
327
487
|
timeOffs?: TimeOff[];
|
|
328
488
|
ruleIds?: string[];
|
|
329
489
|
ruleOverrides?: RuleOverrideEntry[];
|
|
490
|
+
/** Hourly traffic forecast problem fact (omit when unused). */
|
|
491
|
+
trafficForecast?: TrafficForecastEntry[];
|
|
492
|
+
constraintDefinitionIds?: string[];
|
|
493
|
+
constraintDefinitions?: unknown[];
|
|
494
|
+
organizationId?: string;
|
|
330
495
|
};
|
|
331
496
|
type AutoSchedulerModalConfig = {
|
|
332
497
|
selectedLocationIds: string[];
|
|
@@ -334,6 +499,7 @@ type AutoSchedulerModalConfig = {
|
|
|
334
499
|
constraintValues: Record<string, string>;
|
|
335
500
|
selectedOptimizationIds: string[];
|
|
336
501
|
optimizationValues: Record<string, string>;
|
|
502
|
+
selectedBuiltinIds?: string[];
|
|
337
503
|
};
|
|
338
504
|
type SolveApiExplanation = SolveApiResponse["explanation"];
|
|
339
505
|
/** Full POST body for the getRecommendationURL API (context, locations, employees, shifts, etc.) */
|
|
@@ -404,8 +570,12 @@ type ScheduleRecommendation = {
|
|
|
404
570
|
recommendation: string;
|
|
405
571
|
why_this_resolves_it: string;
|
|
406
572
|
};
|
|
573
|
+
declare class InfeasibleScheduleError extends Error {
|
|
574
|
+
readonly failure: ViolatedConstraintsResult;
|
|
575
|
+
constructor(failure: ViolatedConstraintsResult);
|
|
576
|
+
}
|
|
407
577
|
|
|
408
|
-
declare function AutoSchedulerModal({ baseURL, isOpen, title, bannerText, jurisdictions, openShifts, employees, timeOffs, locationPlaceholder, onClose, cancelLabel, primaryActionLabel, onPrimaryAction: _onPrimaryAction, onFixManually, initialConfig, theme, cssVarsRoot, generateRecommendationsURLAndHeaders, getTokenURLAndHeaders, onSolution, getStoredConfigForLocations, persistConfigForLocations, errorToast, }: AutoSchedulerModalProps): react_jsx_runtime.JSX.Element;
|
|
578
|
+
declare function AutoSchedulerModal({ displayMode, drawerSize, baseURL, isOpen, title, bannerTitle, bannerText, jurisdictions, openShifts, employees, timeOffs, locationPlaceholder, onClose, cancelLabel, primaryActionLabel, onPrimaryAction: _onPrimaryAction, onFixManually, initialConfig, theme, cssVarsRoot, generateRecommendationsURLAndHeaders, getTokenURLAndHeaders, onSolution, getStoredConfigForLocations, persistConfigForLocations, errorToast, organizationId, constraintDefinitionIds, constraintDefinitions, hardConstraintOptions, softConstraintGroups, optimizationFooter, trafficForecast, builtinConstraintOptions, subLocations, showSubLocations, teams, showTeams, onSelectionChange, onGenerate, onGenerateSolution, solveStatus, scheduleWeekStartYmd, todayCalendarYmd, evaluationTimezone, }: AutoSchedulerModalProps): react_jsx_runtime.JSX.Element;
|
|
409
579
|
|
|
410
580
|
/**
|
|
411
581
|
* Self-contained AutoSchedulerModal that wraps itself in ChakraProvider.
|
|
@@ -418,7 +588,21 @@ declare function ViolatedConstraintsPanel({ violatedConstraints, title, subtitle
|
|
|
418
588
|
|
|
419
589
|
declare function ViolatedConstraintsPanelWithProvider(props: ViolatedConstraintsPanelProps): react_jsx_runtime.JSX.Element;
|
|
420
590
|
|
|
421
|
-
|
|
591
|
+
/** Soft companion for conversion rate — silent inject under Maximize Sales / Cost-to-sales. */
|
|
592
|
+
declare const MAXIMIZE_CONVERSION_RATE_RULE_ID = "maximize-conversion-rate";
|
|
593
|
+
/** Soft companion for traffic × sales — silent inject under Maximize Sales only. */
|
|
594
|
+
declare const TRAFFIC_FORECAST_INCENTIVE_RULE_ID = "traffic-forecast-incentive";
|
|
595
|
+
type SiblingRuleOptions = {
|
|
596
|
+
/** Inject maximize-conversion-rate when sales opts are selected. */
|
|
597
|
+
includeConversionRate?: boolean;
|
|
598
|
+
/** Inject traffic-forecast-incentive when Maximize Sales is selected. */
|
|
599
|
+
includeTrafficIncentive?: boolean;
|
|
600
|
+
};
|
|
601
|
+
/**
|
|
602
|
+
* Build ruleIds / ruleOverrides. Sibling Avia-agnostic rules are appended into
|
|
603
|
+
* whichever structure is returned (Maximize Sales forces the overrides path).
|
|
604
|
+
*/
|
|
605
|
+
declare function buildRulesPayload(selectedConstraintIds: string[], constraintValues: Record<string, string>, selectedOptimizationIds: string[], optimizationValues: Record<string, string>, siblings?: SiblingRuleOptions): {
|
|
422
606
|
ruleIds?: string[];
|
|
423
607
|
ruleOverrides?: RuleOverrideEntry[];
|
|
424
608
|
};
|
|
@@ -432,6 +616,10 @@ type BuildSchedulePayloadInput = {
|
|
|
432
616
|
constraintValues: Record<string, string>;
|
|
433
617
|
selectedOptimizationIds: string[];
|
|
434
618
|
optimizationValues: Record<string, string>;
|
|
619
|
+
trafficForecast?: TrafficForecastEntry[];
|
|
620
|
+
constraintDefinitionIds?: string[];
|
|
621
|
+
constraintDefinitions?: unknown[];
|
|
622
|
+
organizationId?: string;
|
|
435
623
|
};
|
|
436
624
|
declare function buildSchedulePayload(input: BuildSchedulePayloadInput): SchedulePayload;
|
|
437
625
|
|
|
@@ -441,4 +629,11 @@ declare function buildSchedulePayload(input: BuildSchedulePayloadInput): Schedul
|
|
|
441
629
|
*/
|
|
442
630
|
declare function getFriendlyRuleName(ruleIdOrConstraintName: string): string;
|
|
443
631
|
|
|
444
|
-
|
|
632
|
+
/** Seven consecutive calendar days starting at `weekStartYmd` (already aligned to org week start). */
|
|
633
|
+
declare function getSequentialWeekDatesFromWeekStart(weekStartYmd: string): string[];
|
|
634
|
+
/** Calendar-day weekday chip Su … Sa following JS getDay() order (0 = Sun). */
|
|
635
|
+
declare function weekdayTwoLetterFromYmd(ymd: string): string;
|
|
636
|
+
/** Defaults to all week dates strictly on or after `todayYmd` (ISO date string compare). */
|
|
637
|
+
declare function defaultSelectedScheduleDates(orderedWeekYmds: string[], todayYmd: string): string[];
|
|
638
|
+
|
|
639
|
+
export { AutoSchedulerModal, type AutoSchedulerModalConfig, type AutoSchedulerModalProps, type AutoSchedulerModalStyleOverrides, type AutoSchedulerModalTheme, AutoSchedulerModalWithProvider, type BuildSchedulePayloadInput, type BuiltinConstraintOption, type EasyTeamThemeOverrides, type Employee, type EmployeeProperties, type GenerateScheduleConfig, type HardConstraintOption, InfeasibleScheduleError, type JurisdictionGroup, type LocationOption, MAXIMIZE_CONVERSION_RATE_RULE_ID, type OpenShift, type RecommendationPayload, RequestError, type RuleOverrideEntry, type SchedulePayload, type ScheduleRecommendation, type ScheduleSolution, type ScheduleSolutionAvailability, type ScheduleSolutionEmployee, type ScheduleSolutionLocation, type ScheduleSolutionRuleMetadata, type ScheduleSolutionRuleOverride, type ScheduleSolutionShift, type ScheduleSolutionShiftAssignment, type ScheduleSolutionTimeOff, type ScheduleSolutionWaiver, type Screen, type ShiftAssignmentJustification, type SiblingRuleOptions, type SoftConstraintGroup, type SoftConstraintOption, type SolveApiExplanation, type SolveApiResponse, type SolveJobStatus, type StepStatus, type SubLocationOption, TRAFFIC_FORECAST_INCENTIVE_RULE_ID, type TeamOption, type TimeOff, type TrafficForecastEntry, ViolatedConstraintsPanel, type ViolatedConstraintsPanelProps, type ViolatedConstraintsPanelStyleOverrides, ViolatedConstraintsPanelWithProvider, type ViolatedConstraintsResult, buildRulesPayload, buildSchedulePayload, defaultSelectedScheduleDates, getFriendlyRuleName, getSequentialWeekDatesFromWeekStart, weekdayTwoLetterFromYmd };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
2
3
|
import { ThemeOverride } from '@chakra-ui/react';
|
|
3
4
|
|
|
4
5
|
declare class RequestError extends Error {
|
|
@@ -131,8 +132,17 @@ type EmployeeProperties = {
|
|
|
131
132
|
worker_type: string;
|
|
132
133
|
costToRevenueRatio?: number;
|
|
133
134
|
avgSalesAmount?: number;
|
|
135
|
+
/** Integer basis points (e.g. 1234 = 12.34%). Omit when unknown. */
|
|
136
|
+
conversionRate?: number;
|
|
134
137
|
[key: string]: object | string | number | boolean | undefined;
|
|
135
138
|
};
|
|
139
|
+
/** One hourly traffic cell for the solver TrafficForecast fact (location-local). */
|
|
140
|
+
type TrafficForecastEntry = {
|
|
141
|
+
locationId: string;
|
|
142
|
+
date: string;
|
|
143
|
+
hour: number;
|
|
144
|
+
visits: number;
|
|
145
|
+
};
|
|
136
146
|
type Employee = {
|
|
137
147
|
id: string;
|
|
138
148
|
name: string;
|
|
@@ -250,10 +260,88 @@ type AutoSchedulerModalTheme = (ThemeOverride & {
|
|
|
250
260
|
}) | (EasyTeamThemeOverrides & {
|
|
251
261
|
autoSchedulerModal?: AutoSchedulerModalStyleOverrides;
|
|
252
262
|
});
|
|
263
|
+
type SubLocationOption = {
|
|
264
|
+
id: string;
|
|
265
|
+
name: string;
|
|
266
|
+
parentId: string;
|
|
267
|
+
};
|
|
268
|
+
type TeamOption = {
|
|
269
|
+
id: string;
|
|
270
|
+
name: string;
|
|
271
|
+
resources: {
|
|
272
|
+
id: string;
|
|
273
|
+
externalEmployeeId?: string;
|
|
274
|
+
type?: string;
|
|
275
|
+
properties?: {
|
|
276
|
+
name?: string;
|
|
277
|
+
} & Record<string, unknown>;
|
|
278
|
+
[key: string]: unknown;
|
|
279
|
+
}[];
|
|
280
|
+
};
|
|
281
|
+
type HardConstraintOption = {
|
|
282
|
+
id: string;
|
|
283
|
+
name: string;
|
|
284
|
+
/** Shows this option as selected without requiring user interaction. */
|
|
285
|
+
defaultSelected?: boolean;
|
|
286
|
+
/** Prevents changing an implicitly selected option in the scheduler drawer. */
|
|
287
|
+
readOnly?: boolean;
|
|
288
|
+
/** When present, the modal shows a numeric input on selection. */
|
|
289
|
+
defaultValue?: string;
|
|
290
|
+
/** Label next to the input, e.g. 'hours' or 'days'. Defaults to 'hours'. */
|
|
291
|
+
suffix?: string;
|
|
292
|
+
min?: number;
|
|
293
|
+
max?: number;
|
|
294
|
+
/** Used as violation message detail when the solver reports this constraint as violated. */
|
|
295
|
+
description?: string;
|
|
296
|
+
};
|
|
297
|
+
type SoftConstraintOption = {
|
|
298
|
+
id: string;
|
|
299
|
+
title: string;
|
|
300
|
+
/** Shows this option as selected without requiring user interaction. */
|
|
301
|
+
defaultSelected?: boolean;
|
|
302
|
+
/** Prevents changing an implicitly selected option in the scheduler drawer. */
|
|
303
|
+
readOnly?: boolean;
|
|
304
|
+
/** Shown below the title in the picker. Also used as violation message detail. */
|
|
305
|
+
subtitle?: string;
|
|
306
|
+
};
|
|
307
|
+
type SoftConstraintGroup = {
|
|
308
|
+
id: string;
|
|
309
|
+
name: string;
|
|
310
|
+
options: SoftConstraintOption[];
|
|
311
|
+
};
|
|
312
|
+
type BuiltinConstraintOption = {
|
|
313
|
+
id: string;
|
|
314
|
+
title: string;
|
|
315
|
+
subtitle?: string;
|
|
316
|
+
category?: string;
|
|
317
|
+
defaultSelected?: boolean;
|
|
318
|
+
};
|
|
319
|
+
type GenerateScheduleConfig = {
|
|
320
|
+
selectedLocationIds: string[];
|
|
321
|
+
selectedSubLocationIds: string[];
|
|
322
|
+
selectedTeamIds: string[];
|
|
323
|
+
/** IANA timezone resolved from the selected drawer location. */
|
|
324
|
+
schedulerTimezone?: string;
|
|
325
|
+
/** Calendar dates YYYY-MM-DD within the viewed week to include in workflow evaluation and solver optimization */
|
|
326
|
+
selectedScheduleDates: string[];
|
|
327
|
+
selectedConstraintIds: string[];
|
|
328
|
+
constraintValues: Record<string, string>;
|
|
329
|
+
selectedOptimizationIds: string[];
|
|
330
|
+
optimizationValues: Record<string, string>;
|
|
331
|
+
/** Opt-in built-in Timefold constraint slugs (not org visual-rule UUIDs). */
|
|
332
|
+
selectedBuiltinIds?: string[];
|
|
333
|
+
};
|
|
253
334
|
type AutoSchedulerModalProps = {
|
|
254
|
-
|
|
335
|
+
/** Controls whether the component renders as a modal or a right-side drawer */
|
|
336
|
+
displayMode?: 'modal' | 'drawer';
|
|
337
|
+
/** Width of the drawer when displayMode="drawer". "sm"=448px, "md"=578px, "lg"=600px. Defaults to "lg". */
|
|
338
|
+
drawerSize?: 'sm' | 'md' | 'lg';
|
|
339
|
+
/** When true, the drawer fills 100% viewport height. Defaults to false. */
|
|
340
|
+
drawerFullHeight?: boolean;
|
|
341
|
+
baseURL?: string;
|
|
255
342
|
isOpen: boolean;
|
|
256
343
|
title?: string;
|
|
344
|
+
bannerTitle?: string;
|
|
257
345
|
bannerText?: string;
|
|
258
346
|
jurisdictions: JurisdictionGroup[];
|
|
259
347
|
employees: Employee[];
|
|
@@ -270,23 +358,94 @@ type AutoSchedulerModalProps = {
|
|
|
270
358
|
};
|
|
271
359
|
theme?: AutoSchedulerModalTheme;
|
|
272
360
|
cssVarsRoot?: string;
|
|
273
|
-
generateRecommendationsURLAndHeaders
|
|
361
|
+
generateRecommendationsURLAndHeaders?: {
|
|
274
362
|
url: string;
|
|
275
363
|
headers?: Record<string, string>;
|
|
276
364
|
};
|
|
277
|
-
getTokenURLAndHeaders
|
|
365
|
+
getTokenURLAndHeaders?: {
|
|
278
366
|
url: string;
|
|
279
367
|
headers?: Record<string, string>;
|
|
280
368
|
};
|
|
281
|
-
onSolution
|
|
369
|
+
onSolution?: (solution: ScheduleSolution) => Promise<void>;
|
|
282
370
|
/** When provided, fetches stored config for a location set to prefill the form */
|
|
283
371
|
getStoredConfigForLocations?: (locationIds: string[]) => AutoSchedulerModalConfig | null;
|
|
284
372
|
/** When provided, persists config after successful schedule creation */
|
|
285
373
|
persistConfigForLocations?: (locationIds: string[], config: AutoSchedulerModalConfig) => void;
|
|
286
374
|
errorToast?: (msg: string) => void;
|
|
375
|
+
/** Organization id — required when sending visual rule ids */
|
|
376
|
+
organizationId?: string;
|
|
377
|
+
/** Visual rule ids attached to this solve (production path) */
|
|
378
|
+
constraintDefinitionIds?: string[];
|
|
379
|
+
/** Inline visual rule definitions (sandbox/test path; for unsaved rules) */
|
|
380
|
+
constraintDefinitions?: unknown[];
|
|
381
|
+
/** Replaces the built-in hard constraint list shown in "Required rules". */
|
|
382
|
+
hardConstraintOptions?: HardConstraintOption[];
|
|
383
|
+
/** Replaces the built-in optimization groups shown in "Optimization". */
|
|
384
|
+
softConstraintGroups?: SoftConstraintGroup[];
|
|
385
|
+
/** Optional footer under Optimization (e.g. host-owned Avia attribution). Prefer a render fn when showing in multiple places. */
|
|
386
|
+
optimizationFooter?: ReactNode | (() => ReactNode);
|
|
387
|
+
/**
|
|
388
|
+
* Hourly traffic forecast for the solve week (location-local).
|
|
389
|
+
* When Maximize Sales is selected and this is non-empty, the modal injects
|
|
390
|
+
* traffic-forecast-incentive and serializes this field on the solve payload.
|
|
391
|
+
*/
|
|
392
|
+
trafficForecast?: TrafficForecastEntry[];
|
|
393
|
+
/** Opt-in built-in Timefold constraints (solver catalog slugs). */
|
|
394
|
+
builtinConstraintOptions?: BuiltinConstraintOption[];
|
|
395
|
+
/** All sub-locations (with parentId). The component filters them internally based on selected location IDs. */
|
|
396
|
+
subLocations?: SubLocationOption[];
|
|
397
|
+
/** When true, renders the sub-locations multiselect (filtered by selected locations). Defaults to false. */
|
|
398
|
+
showSubLocations?: boolean;
|
|
399
|
+
/** Teams list. The caller should update this reactively in response to onSelectionChange. */
|
|
400
|
+
teams?: TeamOption[];
|
|
401
|
+
/** When true, renders the teams multiselect. Defaults to false. */
|
|
402
|
+
showTeams?: boolean;
|
|
403
|
+
/**
|
|
404
|
+
* Called when the user changes location or sub-location selection.
|
|
405
|
+
* Use this to re-fetch teams filtered by the new selection.
|
|
406
|
+
*/
|
|
407
|
+
onSelectionChange?: (locationIds: string[], subLocationIds: string[]) => void;
|
|
408
|
+
/**
|
|
409
|
+
* When provided, replaces the Java solver flow entirely.
|
|
410
|
+
* The component shows the progress animation and calls this function at step 1.
|
|
411
|
+
* Resolving means success (the resolved value is forwarded to onGenerateSolution);
|
|
412
|
+
* throwing means failure (shown in the failed screen).
|
|
413
|
+
*/
|
|
414
|
+
onGenerate?: (config: GenerateScheduleConfig) => Promise<unknown>;
|
|
415
|
+
/**
|
|
416
|
+
* Called after onGenerate resolves successfully, just before the drawer/modal closes.
|
|
417
|
+
* Receives the value returned by onGenerate.
|
|
418
|
+
*/
|
|
419
|
+
onGenerateSolution?: (result: unknown) => void;
|
|
420
|
+
/**
|
|
421
|
+
* Calendar week-start date YYYY-MM-DD (matches ops weekly schedule / evaluate-range window).
|
|
422
|
+
* When `onGenerate` is used, pass the week currently shown on the schedule grid.
|
|
423
|
+
*/
|
|
424
|
+
scheduleWeekStartYmd?: string;
|
|
425
|
+
/**
|
|
426
|
+
* Today's civil date YYYY-MM-DD in `evaluationTimezone`, used to leave past week days unselected by default.
|
|
427
|
+
*/
|
|
428
|
+
todayCalendarYmd?: string;
|
|
429
|
+
/**
|
|
430
|
+
* IANA timezone for interpreting today + backend evaluate-range date filtering (defaults to UTC).
|
|
431
|
+
*/
|
|
432
|
+
evaluationTimezone?: string;
|
|
433
|
+
/**
|
|
434
|
+
* Live status of the underlying solve job. When set to "QUEUED" while the
|
|
435
|
+
* progress UI is visible, step 2's caption is replaced with "Waiting in queue…".
|
|
436
|
+
* Any other value (or null/undefined) leaves the step copy unchanged.
|
|
437
|
+
*/
|
|
438
|
+
solveStatus?: SolveJobStatus | null;
|
|
287
439
|
};
|
|
288
440
|
type Screen = "configure" | "creating" | "failed";
|
|
289
441
|
type StepStatus = "pending" | "active" | "done";
|
|
442
|
+
/**
|
|
443
|
+
* Status of an async solve job, as reported by the scheduler service.
|
|
444
|
+
* QUEUED → waiting for a solver slot
|
|
445
|
+
* SOLVING_ACTIVE → solver is running
|
|
446
|
+
* NOT_SOLVING / TERMINATED_EARLY → terminal
|
|
447
|
+
*/
|
|
448
|
+
type SolveJobStatus = "QUEUED" | "SOLVING_ACTIVE" | "NOT_SOLVING" | "TERMINATED_EARLY";
|
|
290
449
|
type RuleOverrideEntry = {
|
|
291
450
|
ruleId: string;
|
|
292
451
|
parameters?: Record<string, unknown>;
|
|
@@ -323,10 +482,16 @@ type SchedulePayload = {
|
|
|
323
482
|
timezone?: string;
|
|
324
483
|
jurisdiction?: string;
|
|
325
484
|
tags?: string[];
|
|
485
|
+
properties?: Record<string, unknown>;
|
|
326
486
|
}>;
|
|
327
487
|
timeOffs?: TimeOff[];
|
|
328
488
|
ruleIds?: string[];
|
|
329
489
|
ruleOverrides?: RuleOverrideEntry[];
|
|
490
|
+
/** Hourly traffic forecast problem fact (omit when unused). */
|
|
491
|
+
trafficForecast?: TrafficForecastEntry[];
|
|
492
|
+
constraintDefinitionIds?: string[];
|
|
493
|
+
constraintDefinitions?: unknown[];
|
|
494
|
+
organizationId?: string;
|
|
330
495
|
};
|
|
331
496
|
type AutoSchedulerModalConfig = {
|
|
332
497
|
selectedLocationIds: string[];
|
|
@@ -334,6 +499,7 @@ type AutoSchedulerModalConfig = {
|
|
|
334
499
|
constraintValues: Record<string, string>;
|
|
335
500
|
selectedOptimizationIds: string[];
|
|
336
501
|
optimizationValues: Record<string, string>;
|
|
502
|
+
selectedBuiltinIds?: string[];
|
|
337
503
|
};
|
|
338
504
|
type SolveApiExplanation = SolveApiResponse["explanation"];
|
|
339
505
|
/** Full POST body for the getRecommendationURL API (context, locations, employees, shifts, etc.) */
|
|
@@ -404,8 +570,12 @@ type ScheduleRecommendation = {
|
|
|
404
570
|
recommendation: string;
|
|
405
571
|
why_this_resolves_it: string;
|
|
406
572
|
};
|
|
573
|
+
declare class InfeasibleScheduleError extends Error {
|
|
574
|
+
readonly failure: ViolatedConstraintsResult;
|
|
575
|
+
constructor(failure: ViolatedConstraintsResult);
|
|
576
|
+
}
|
|
407
577
|
|
|
408
|
-
declare function AutoSchedulerModal({ baseURL, isOpen, title, bannerText, jurisdictions, openShifts, employees, timeOffs, locationPlaceholder, onClose, cancelLabel, primaryActionLabel, onPrimaryAction: _onPrimaryAction, onFixManually, initialConfig, theme, cssVarsRoot, generateRecommendationsURLAndHeaders, getTokenURLAndHeaders, onSolution, getStoredConfigForLocations, persistConfigForLocations, errorToast, }: AutoSchedulerModalProps): react_jsx_runtime.JSX.Element;
|
|
578
|
+
declare function AutoSchedulerModal({ displayMode, drawerSize, baseURL, isOpen, title, bannerTitle, bannerText, jurisdictions, openShifts, employees, timeOffs, locationPlaceholder, onClose, cancelLabel, primaryActionLabel, onPrimaryAction: _onPrimaryAction, onFixManually, initialConfig, theme, cssVarsRoot, generateRecommendationsURLAndHeaders, getTokenURLAndHeaders, onSolution, getStoredConfigForLocations, persistConfigForLocations, errorToast, organizationId, constraintDefinitionIds, constraintDefinitions, hardConstraintOptions, softConstraintGroups, optimizationFooter, trafficForecast, builtinConstraintOptions, subLocations, showSubLocations, teams, showTeams, onSelectionChange, onGenerate, onGenerateSolution, solveStatus, scheduleWeekStartYmd, todayCalendarYmd, evaluationTimezone, }: AutoSchedulerModalProps): react_jsx_runtime.JSX.Element;
|
|
409
579
|
|
|
410
580
|
/**
|
|
411
581
|
* Self-contained AutoSchedulerModal that wraps itself in ChakraProvider.
|
|
@@ -418,7 +588,21 @@ declare function ViolatedConstraintsPanel({ violatedConstraints, title, subtitle
|
|
|
418
588
|
|
|
419
589
|
declare function ViolatedConstraintsPanelWithProvider(props: ViolatedConstraintsPanelProps): react_jsx_runtime.JSX.Element;
|
|
420
590
|
|
|
421
|
-
|
|
591
|
+
/** Soft companion for conversion rate — silent inject under Maximize Sales / Cost-to-sales. */
|
|
592
|
+
declare const MAXIMIZE_CONVERSION_RATE_RULE_ID = "maximize-conversion-rate";
|
|
593
|
+
/** Soft companion for traffic × sales — silent inject under Maximize Sales only. */
|
|
594
|
+
declare const TRAFFIC_FORECAST_INCENTIVE_RULE_ID = "traffic-forecast-incentive";
|
|
595
|
+
type SiblingRuleOptions = {
|
|
596
|
+
/** Inject maximize-conversion-rate when sales opts are selected. */
|
|
597
|
+
includeConversionRate?: boolean;
|
|
598
|
+
/** Inject traffic-forecast-incentive when Maximize Sales is selected. */
|
|
599
|
+
includeTrafficIncentive?: boolean;
|
|
600
|
+
};
|
|
601
|
+
/**
|
|
602
|
+
* Build ruleIds / ruleOverrides. Sibling Avia-agnostic rules are appended into
|
|
603
|
+
* whichever structure is returned (Maximize Sales forces the overrides path).
|
|
604
|
+
*/
|
|
605
|
+
declare function buildRulesPayload(selectedConstraintIds: string[], constraintValues: Record<string, string>, selectedOptimizationIds: string[], optimizationValues: Record<string, string>, siblings?: SiblingRuleOptions): {
|
|
422
606
|
ruleIds?: string[];
|
|
423
607
|
ruleOverrides?: RuleOverrideEntry[];
|
|
424
608
|
};
|
|
@@ -432,6 +616,10 @@ type BuildSchedulePayloadInput = {
|
|
|
432
616
|
constraintValues: Record<string, string>;
|
|
433
617
|
selectedOptimizationIds: string[];
|
|
434
618
|
optimizationValues: Record<string, string>;
|
|
619
|
+
trafficForecast?: TrafficForecastEntry[];
|
|
620
|
+
constraintDefinitionIds?: string[];
|
|
621
|
+
constraintDefinitions?: unknown[];
|
|
622
|
+
organizationId?: string;
|
|
435
623
|
};
|
|
436
624
|
declare function buildSchedulePayload(input: BuildSchedulePayloadInput): SchedulePayload;
|
|
437
625
|
|
|
@@ -441,4 +629,11 @@ declare function buildSchedulePayload(input: BuildSchedulePayloadInput): Schedul
|
|
|
441
629
|
*/
|
|
442
630
|
declare function getFriendlyRuleName(ruleIdOrConstraintName: string): string;
|
|
443
631
|
|
|
444
|
-
|
|
632
|
+
/** Seven consecutive calendar days starting at `weekStartYmd` (already aligned to org week start). */
|
|
633
|
+
declare function getSequentialWeekDatesFromWeekStart(weekStartYmd: string): string[];
|
|
634
|
+
/** Calendar-day weekday chip Su … Sa following JS getDay() order (0 = Sun). */
|
|
635
|
+
declare function weekdayTwoLetterFromYmd(ymd: string): string;
|
|
636
|
+
/** Defaults to all week dates strictly on or after `todayYmd` (ISO date string compare). */
|
|
637
|
+
declare function defaultSelectedScheduleDates(orderedWeekYmds: string[], todayYmd: string): string[];
|
|
638
|
+
|
|
639
|
+
export { AutoSchedulerModal, type AutoSchedulerModalConfig, type AutoSchedulerModalProps, type AutoSchedulerModalStyleOverrides, type AutoSchedulerModalTheme, AutoSchedulerModalWithProvider, type BuildSchedulePayloadInput, type BuiltinConstraintOption, type EasyTeamThemeOverrides, type Employee, type EmployeeProperties, type GenerateScheduleConfig, type HardConstraintOption, InfeasibleScheduleError, type JurisdictionGroup, type LocationOption, MAXIMIZE_CONVERSION_RATE_RULE_ID, type OpenShift, type RecommendationPayload, RequestError, type RuleOverrideEntry, type SchedulePayload, type ScheduleRecommendation, type ScheduleSolution, type ScheduleSolutionAvailability, type ScheduleSolutionEmployee, type ScheduleSolutionLocation, type ScheduleSolutionRuleMetadata, type ScheduleSolutionRuleOverride, type ScheduleSolutionShift, type ScheduleSolutionShiftAssignment, type ScheduleSolutionTimeOff, type ScheduleSolutionWaiver, type Screen, type ShiftAssignmentJustification, type SiblingRuleOptions, type SoftConstraintGroup, type SoftConstraintOption, type SolveApiExplanation, type SolveApiResponse, type SolveJobStatus, type StepStatus, type SubLocationOption, TRAFFIC_FORECAST_INCENTIVE_RULE_ID, type TeamOption, type TimeOff, type TrafficForecastEntry, ViolatedConstraintsPanel, type ViolatedConstraintsPanelProps, type ViolatedConstraintsPanelStyleOverrides, ViolatedConstraintsPanelWithProvider, type ViolatedConstraintsResult, buildRulesPayload, buildSchedulePayload, defaultSelectedScheduleDates, getFriendlyRuleName, getSequentialWeekDatesFromWeekStart, weekdayTwoLetterFromYmd };
|