@feedmepos/mf-hrm-portal 2.2.5-dev.9 → 2.3.0-dev
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/{ApprovalCodeList-D5l9vIsE.js → ApprovalCodeList-cG0zmQVJ.js} +5 -5
- package/dist/{AuditLogList-ByTa5UJY.js → AuditLogList-BTifJhO1.js} +4 -4
- package/dist/{ConditionBuilderForm.vue_vue_type_script_setup_true_lang-mNdn1TYV.js → ConditionBuilderForm.vue_vue_type_script_setup_true_lang-qr5TwLTK.js} +2 -2
- package/dist/{EmployeeList-Bv6ANk-P.js → EmployeeList-DzcMtxJ3.js} +6 -6
- package/dist/{GrantUserList-Bt8w3p4j.js → GrantUserList-D5b7tJ8Y.js} +6 -6
- package/dist/{Main-DqiGpT4v.js → Main-B2r59IOW.js} +5 -5
- package/dist/{Main-DHJcgePj.js → Main-DFwdAWqn.js} +8 -8
- package/dist/{Main-DkP8dWgn.js → Main-DkLBemi7.js} +11 -11
- package/dist/{PermissionSetList-BIGv1u67.js → PermissionSetList-B80hrfMW.js} +7 -7
- package/dist/PortalPermissionEditor.vue_vue_type_script_setup_true_lang-DjNcJQM9.js +4167 -0
- package/dist/{PortalUserSearcher.vue_vue_type_style_index_0_scoped_827dfd60_lang-XHuHin8t.js → PortalUserSearcher.vue_vue_type_style_index_0_scoped_827dfd60_lang-fe-Rdwn4.js} +1 -1
- package/dist/{RoleList-CH6NDKPU.js → RoleList-DHO4JRKF.js} +9 -9
- package/dist/ScheduleAddPositionModal.vue_vue_type_script_setup_true_lang-B-XtB64L.js +452 -0
- package/dist/ScheduleGeneralPage-WlBM8bxV.js +629 -0
- package/dist/SchedulePage-Nm0krGVU.js +17056 -0
- package/dist/SchedulePositionPage-C0hrO11d.js +263 -0
- package/dist/ScheduleSelect.vue_vue_type_script_setup_true_lang-DTDXir_7.js +1150 -0
- package/dist/{TeamMemberList-BwfG3go2.js → TeamMemberList-CgFWLRBM.js} +10 -10
- package/dist/{TimesheetList-DcoqzbLO.js → TimesheetList-Dp40G-0I.js} +7 -7
- package/dist/{TimesheetList.vue_vue_type_style_index_0_scoped_63294af2_lang-RyhiKTSd.js → TimesheetList.vue_vue_type_style_index_0_scoped_63294af2_lang-BFjrMhUG.js} +3 -3
- package/dist/{app-BcZ6C8M8.js → app-CmBSTvaI.js} +851 -739
- package/dist/app.js +1 -1
- package/dist/{approval-code-jIjkeVEb.js → approval-code-C9DmR4Md.js} +1 -1
- package/dist/{dayjs.min-Ch0iysTG.js → dayjs.min-CfL2DQ3d.js} +1 -1
- package/dist/{employee-DwYHFacQ.js → employee-DQcHjoij.js} +4 -4
- package/dist/{grant-user-SNiDV22U.js → grant-user-Bv-pJ9Wt.js} +1 -1
- package/dist/{iteration-D1uWLp0V.js → iteration-BlavheWG.js} +1 -1
- package/dist/{lodash-DErxm7xf.js → lodash-QerqayrJ.js} +1 -1
- package/dist/{restaurant-BTpBmfBV.js → restaurant-D7PEQjPY.js} +257 -251
- package/dist/{role-B9VanAny.js → role-RM2YLO7n.js} +2 -2
- package/dist/{rule-C4f_Ilzr.js → rule-DjlvYIuP.js} +3 -3
- package/dist/src/api/restaurant/index.d.ts +2 -0
- package/dist/src/api/schedule/index.d.ts +12 -2
- package/dist/src/composables/useMessage.d.ts +8 -2
- package/dist/src/types/schedule.d.ts +10 -218
- package/dist/src/views/scheduling/components/ScheduleAddEmployeeModal.vue.d.ts +2 -0
- package/dist/src/views/scheduling/components/ScheduleAreaRows.vue.d.ts +11 -0
- package/dist/src/views/scheduling/components/ScheduleAutoScheduleDetailsModal.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleCloneOutletModal.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/{ScheduleLegendBar.vue.d.ts → ScheduleCoach.vue.d.ts} +2 -2
- package/dist/src/views/scheduling/components/ScheduleConfirmModal.vue.d.ts +9 -1
- package/dist/src/views/scheduling/components/ScheduleCostRailEmptyArt.vue.d.ts +2 -0
- package/dist/src/views/scheduling/components/ScheduleExportDoneDialog.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleLeaveEditModal.vue.d.ts +0 -2
- package/dist/src/views/scheduling/components/ScheduleOnboardingComplete.vue.d.ts +10 -0
- package/dist/src/views/scheduling/components/ScheduleOnboardingDoneArt.vue.d.ts +2 -0
- package/dist/src/views/scheduling/components/ScheduleOnboardingWelcome.vue.d.ts +1 -2
- package/dist/src/views/scheduling/components/ScheduleShiftCardMenu.vue.d.ts +2 -2
- package/dist/src/views/scheduling/components/ScheduleShiftCell.vue.d.ts +6 -6
- package/dist/src/views/scheduling/components/ScheduleShiftMoreOptions.vue.d.ts +2 -0
- package/dist/src/views/scheduling/components/ScheduleStaffRail.vue.d.ts +0 -2
- package/dist/src/views/scheduling/components/ScheduleStaffRows.vue.d.ts +6 -6
- package/dist/src/views/scheduling/components/ScheduleTourAllSet.vue.d.ts +6 -0
- package/dist/src/views/scheduling/composables/auto-schedule-mapping.d.ts +33 -0
- package/dist/src/views/scheduling/composables/onboarding-constants.d.ts +5 -0
- package/dist/src/views/scheduling/composables/onboarding-hours.d.ts +7 -0
- package/dist/src/views/scheduling/composables/onboarding-types.d.ts +50 -0
- package/dist/src/views/scheduling/composables/schedule-add-employee-form.d.ts +8 -2
- package/dist/src/views/scheduling/composables/schedule-board-helpers.d.ts +22 -1
- package/dist/src/views/scheduling/composables/schedule-breaks.d.ts +3 -0
- package/dist/src/views/scheduling/composables/schedule-day-meta.d.ts +2 -8
- package/dist/src/views/scheduling/composables/schedule-shift-time.d.ts +12 -0
- package/dist/src/views/scheduling/composables/useScheduleAddEmployee.d.ts +11 -8
- package/dist/src/views/scheduling/composables/useScheduleAddPick.d.ts +10 -2
- package/dist/src/views/scheduling/composables/useScheduleAreaBoard.d.ts +13 -0
- package/dist/src/views/scheduling/composables/useScheduleAutoSchedule.d.ts +158 -12
- package/dist/src/views/scheduling/composables/useScheduleBoard.d.ts +110 -13
- package/dist/src/views/scheduling/composables/useScheduleClashDetection.d.ts +11 -1
- package/dist/src/views/scheduling/composables/useScheduleCloneOutletModal.d.ts +19 -0
- package/dist/src/views/scheduling/composables/useScheduleCoach.d.ts +80 -0
- package/dist/src/views/scheduling/composables/useScheduleDayNote.d.ts +0 -3
- package/dist/src/views/scheduling/composables/useScheduleDayTimeline.d.ts +24 -1
- package/dist/src/views/scheduling/composables/useScheduleDemandRow.d.ts +4 -2
- package/dist/src/views/scheduling/composables/useScheduleDragDrop.d.ts +33 -1
- package/dist/src/views/scheduling/composables/useScheduleExport.d.ts +17 -0
- package/dist/src/views/scheduling/composables/useScheduleGapPopover.d.ts +1 -3
- package/dist/src/views/scheduling/composables/useScheduleLeave.d.ts +20 -31
- package/dist/src/views/scheduling/composables/useScheduleOnboardingFlow.d.ts +9 -0
- package/dist/src/views/scheduling/composables/useScheduleOnboardingPersistence.d.ts +13 -0
- package/dist/src/views/scheduling/composables/useScheduleOnboardingWizard.d.ts +327 -75
- package/dist/src/views/scheduling/composables/useScheduleOutlet.d.ts +5 -3
- package/dist/src/views/scheduling/composables/useSchedulePageBootstrap.d.ts +9 -0
- package/dist/src/views/scheduling/composables/useSchedulePageClearActions.d.ts +20 -0
- package/dist/src/views/scheduling/composables/useSchedulePageOverlays.d.ts +18 -0
- package/dist/src/views/scheduling/composables/useSchedulePositionModal.d.ts +2 -0
- package/dist/src/views/scheduling/composables/useSchedulePositions.d.ts +0 -5
- package/dist/src/views/scheduling/composables/useSchedulePublish.d.ts +25 -0
- package/dist/src/views/scheduling/composables/useScheduleRoster.d.ts +53 -1
- package/dist/src/views/scheduling/composables/useScheduleSettings.d.ts +7 -4
- package/dist/src/views/scheduling/composables/useScheduleSetupBanner.d.ts +8 -9
- package/dist/src/views/scheduling/composables/useScheduleShiftActions.d.ts +63 -92
- package/dist/src/views/scheduling/composables/useScheduleShiftPopover.d.ts +30 -2
- package/dist/src/views/scheduling/composables/useScheduleStaffRail.d.ts +5 -11
- package/dist/src/views/scheduling/composables/useScheduleStatsRow.d.ts +0 -1
- package/dist/src/views/scheduling/composables/useScheduleTopbar.d.ts +4 -4
- package/dist/src/views/scheduling/composables/useScheduleTour.d.ts +93 -0
- package/dist/src/views/scheduling/data.d.ts +6 -19
- package/dist/src/views/scheduling/locales/index.d.ts +116 -4
- package/dist/src/views/scheduling/schedule-state.d.ts +679 -0
- package/dist/src/views/scheduling/schedule-store.d.ts +16 -60
- package/dist/src/views/scheduling/types.d.ts +29 -2
- package/dist/style.css +1 -1
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/dist/{useAppStore-DCwd8GWN.js → useAppStore-d_nHyK5u.js} +1 -1
- package/dist/{useLoading-CXzTpIVv.js → useLoading-JFoghhRz.js} +1 -1
- package/dist/{useReportPermissions-CTr56kBo.js → useReportPermissions-Bl6Br79r.js} +3 -3
- package/package.json +3 -2
- package/dist/PortalPermissionEditor.vue_vue_type_script_setup_true_lang-niywl_DX.js +0 -4167
- package/dist/ScheduleAddPositionModal.vue_vue_type_script_setup_true_lang-T1ACkX_6.js +0 -426
- package/dist/ScheduleButton.vue_vue_type_script_setup_true_lang-BzQuLLf5.js +0 -690
- package/dist/ScheduleGeneralPage-DJPENJZ2.js +0 -320
- package/dist/SchedulePage-C1egcbIC.js +0 -14421
- package/dist/SchedulePositionPage-OhL_hsqG.js +0 -293
- package/dist/ScheduleSelect.vue_vue_type_script_setup_true_lang-B8W4sTsA.js +0 -242
- package/dist/src/views/scheduling/composables/scheduleAutoSolver.d.ts +0 -21
- package/dist/src/views/scheduling/composables/useScheduleLegendBar.d.ts +0 -35
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ScheduleOnboardingStep } from './onboarding-types';
|
|
2
|
+
export declare const ONBOARDING_STEPS: ScheduleOnboardingStep[];
|
|
3
|
+
export declare const SKIPPABLE_ONBOARDING_STEPS: ScheduleOnboardingStep[];
|
|
4
|
+
export declare const COMMON_POSITION_SUGGESTIONS: string[];
|
|
5
|
+
export declare const ANY_POSITION_KEY = "__any__";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ScheduleRules } from '../types';
|
|
2
|
+
import type { ScheduleOnboardingDayHours } from './onboarding-types';
|
|
3
|
+
import type { FdtoScheduleDayOperatingHours } from '@feedmepos/hrm-schedule-contract';
|
|
4
|
+
/** Converts persisted outlet hours into the wizard's editable draft shape. */
|
|
5
|
+
export declare function onboardingHoursFromRules(rules: ScheduleRules): ScheduleOnboardingDayHours[];
|
|
6
|
+
/** Converts the grid's Monday-first draft back to the restaurant profile's Sunday-first wire shape. */
|
|
7
|
+
export declare function onboardingHoursToProfile(hours: ScheduleOnboardingDayHours[]): FdtoScheduleDayOperatingHours[];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type ScheduleOnboardingStep = 'hours' | 'staffing' | 'positions' | 'team' | 'availability' | 'review';
|
|
2
|
+
export interface ScheduleOnboardingSession {
|
|
3
|
+
from: string;
|
|
4
|
+
to: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ScheduleOnboardingDayHours {
|
|
7
|
+
open: boolean;
|
|
8
|
+
sessions: ScheduleOnboardingSession[];
|
|
9
|
+
}
|
|
10
|
+
export interface ScheduleOnboardingRange {
|
|
11
|
+
from: string;
|
|
12
|
+
to: string;
|
|
13
|
+
/** Blank until typed: an unset range asks for nobody. */
|
|
14
|
+
n: number | null;
|
|
15
|
+
roles: Array<{
|
|
16
|
+
position: string;
|
|
17
|
+
n: number | null;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
export type TeamEmployment = 'full' | 'part';
|
|
21
|
+
export type TeamBasis = 'monthly' | 'hourly';
|
|
22
|
+
export interface TeamRow {
|
|
23
|
+
picked: boolean;
|
|
24
|
+
/** '' means "Any position" — a person with none. */
|
|
25
|
+
position: string;
|
|
26
|
+
second: string;
|
|
27
|
+
employment: TeamEmployment;
|
|
28
|
+
maxHours: string;
|
|
29
|
+
rate: string;
|
|
30
|
+
basis: TeamBasis;
|
|
31
|
+
}
|
|
32
|
+
export interface AvailDay {
|
|
33
|
+
on: boolean;
|
|
34
|
+
from: string;
|
|
35
|
+
to: string;
|
|
36
|
+
}
|
|
37
|
+
export interface AvailRow {
|
|
38
|
+
offDays: boolean[];
|
|
39
|
+
days: AvailDay[];
|
|
40
|
+
}
|
|
41
|
+
export interface ReviewRow {
|
|
42
|
+
step: ScheduleOnboardingStep;
|
|
43
|
+
title: string;
|
|
44
|
+
text: string;
|
|
45
|
+
sub?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface IntroRecapRow {
|
|
48
|
+
label: string;
|
|
49
|
+
value: string;
|
|
50
|
+
}
|
|
@@ -12,6 +12,9 @@ export interface ScheduleAddEmployeeForm {
|
|
|
12
12
|
payAmount: string;
|
|
13
13
|
maxHours: string;
|
|
14
14
|
minHours: string;
|
|
15
|
+
/** Overtime is opt-in: off is "no rule", not "zero overtime" — a 0 sitting in the fields
|
|
16
|
+
* below by default would read as "every hour is overtime", the opposite of unset. */
|
|
17
|
+
otEnabled: boolean;
|
|
15
18
|
otAfterDaily: string;
|
|
16
19
|
maxOtHours: string;
|
|
17
20
|
/** For a part-timer: days they CAN work. For a full-timer: days they're OFF — the
|
|
@@ -24,10 +27,13 @@ export interface ScheduleAddEmployeeForm {
|
|
|
24
27
|
seniority: '' | 'senior' | 'junior';
|
|
25
28
|
passcode: string[];
|
|
26
29
|
masterUser: boolean;
|
|
27
|
-
/** POS role for a brand-new user (applied at every outlet in `locations`). */
|
|
28
|
-
roleId: string;
|
|
29
30
|
/** Required by the POS for a master user. */
|
|
30
31
|
masterCode: string;
|
|
32
|
+
/** Gates the fields below it — someone can be fully scheduled with this off. */
|
|
33
|
+
posAccessEnabled: boolean;
|
|
34
|
+
/** WHAT the passcode opens the till as, at this outlet — the one this person is being added
|
|
35
|
+
* to. The outlet itself isn't a choice here: this wizard is already scoped to it. */
|
|
36
|
+
posRoleId: string;
|
|
31
37
|
}
|
|
32
38
|
/** A salaried month, for converting a monthly figure into the hourly one the cost rail
|
|
33
39
|
* actually reads. Ported verbatim from the mockup's MONTH_HOURS. */
|
|
@@ -6,7 +6,16 @@ export declare function isoDateKey(d: Date): string;
|
|
|
6
6
|
export declare function isWorkSlot(slot: DaySlot): slot is WorkSlot;
|
|
7
7
|
export declare function isLeaveSlot(slot: DaySlot): slot is LeaveSlot;
|
|
8
8
|
export declare function workSlotsOf(day: DaySlot): WorkSlot[];
|
|
9
|
-
/**
|
|
9
|
+
/** The inverse of `workSlotsOf` — bare slot for one, the array for two or more, so a day
|
|
10
|
+
* that's back down to its last period reads as a normal single shift again rather than a
|
|
11
|
+
* one-element array everything else has to unwrap. */
|
|
12
|
+
export declare function collapseSlots(slots: WorkSlot[]): WorkSlot | WorkSlot[] | null;
|
|
13
|
+
/** Whether a day's periods are genuinely one shift split across a gap — same `splitGroupId`,
|
|
14
|
+
* set only by the popover's "+ Split" — versus two or more independent shifts that happen to
|
|
15
|
+
* land on the same day (a swap override, say). The card/popover both branch on this: a
|
|
16
|
+
* genuine split draws and edits as one shift; anything else stays separate, card per shift. */
|
|
17
|
+
export declare function isGenuineSplitGroup(slots: WorkSlot[]): boolean;
|
|
18
|
+
/** A WorkSlot, in the shape ScheduleShiftAssignments actually stores. `pending` is the only status
|
|
10
19
|
* this board's own writers ever set on a fresh slot (see commitShift's callers) — `ot` is
|
|
11
20
|
* derived at cost-rail time, never authored, so it has nowhere sensible to map but PUBLISHED. */
|
|
12
21
|
export declare function toAssignmentReq(employeeId: string, date: string, slot: WorkSlot): FdtoScheduleSaveAssignmentReq;
|
|
@@ -33,6 +42,18 @@ export declare function contractCapFor(emp: Employee): number;
|
|
|
33
42
|
* exceeded, so it is treated as no limit and the question is answered false. */
|
|
34
43
|
export declare function overContract(emp: Employee, hours: number): boolean;
|
|
35
44
|
export declare function isPartTime(emp: Employee): boolean;
|
|
45
|
+
/** Colour keys off the POSITION's rank in the alphabetical position list, looped every six —
|
|
46
|
+
* position 7 repeats position 1's colour, which is expected once a page holds more than six.
|
|
47
|
+
* Unset ("Any position") isn't a real position at all, so it skips the rotation entirely and is
|
|
48
|
+
* always stone, the one of the seven neutral enough to read as "no position". A role no longer in
|
|
49
|
+
* the list (e.g. since deleted) falls back to the first band rather than erroring.
|
|
50
|
+
*
|
|
51
|
+
* Rotation by name, not a keyword lookup — a position is whatever the outlet typed into the
|
|
52
|
+
* Positions page, so there's no fixed vocabulary ("cashier", "kitchen", ...) to match against.
|
|
53
|
+
*
|
|
54
|
+
* Shared by the employee view's own card and the area view's position-row header + card, so the
|
|
55
|
+
* same position never disagrees on its colour anywhere on the board. */
|
|
56
|
+
export declare function positionColorClass(role: string): string;
|
|
36
57
|
/** Which weekday (0 = Mon) is today, relative to no particular week — used to seed
|
|
37
58
|
* focusDayIdx whenever "today" needs a weekday index rather than a date. */
|
|
38
59
|
export declare function todayWeekdayIdx(): number;
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Employee, ScheduleDayNote } from '../types';
|
|
1
|
+
import type { ScheduleDayNote } from '../types';
|
|
3
2
|
/** Everything a manager authors about a DATE rather than about a shift — the note on its
|
|
4
3
|
* card, whether the venue opens, whether it bills at the holiday rate. Keyed by ISO date
|
|
5
4
|
* (via the board's `dateKey`), not by weekday index: the mockup's flat single-week horizon
|
|
6
5
|
* could use the weekday index directly, but the board pages through weeks, and a note put on
|
|
7
6
|
* this Monday must not reappear on every other Monday. */
|
|
8
|
-
export declare function useScheduleDayMeta(
|
|
7
|
+
export declare function useScheduleDayMeta(dateKey: (dayIdx: number) => string | null, handlers?: {
|
|
9
8
|
onPersistError?: (message: string) => void;
|
|
10
9
|
}): {
|
|
11
10
|
dayNote: (dayIdx: number) => ScheduleDayNote | null;
|
|
12
11
|
setDayNote: (dayIdx: number, title: string, desc: string) => void;
|
|
13
12
|
clearDayNote: (dayIdx: number) => void;
|
|
14
|
-
toggleClosed: (dayIdx: number) => {
|
|
15
|
-
closed: boolean;
|
|
16
|
-
rostered: number;
|
|
17
|
-
};
|
|
18
|
-
isManuallyClosed: (dayIdx: number) => boolean;
|
|
19
13
|
isStandingClosedWeekday: (dayIdx: number) => boolean;
|
|
20
14
|
holidayName: (dayIdx: number) => string | null;
|
|
21
15
|
holidayIsAuto: (dayIdx: number) => boolean;
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
import type { WorkSlot } from '../types';
|
|
1
2
|
export type ScheduleBreakChoice = 0 | 30 | 60 | 90 | 120 | 'custom';
|
|
2
3
|
export interface ScheduleShiftSegment {
|
|
3
4
|
start: string;
|
|
4
5
|
end: string;
|
|
5
6
|
}
|
|
7
|
+
/** The one break shape that names a clock window rather than just a duration — when present,
|
|
8
|
+
* the card reads as two periods around it, each on its own line, instead of one span that
|
|
9
|
+
* quietly got shorter. Shared by the employee view's own card and the area view's position-row
|
|
10
|
+
* card, so a TIME_RANGE break draws the same split face wherever a shift is shown. */
|
|
11
|
+
export declare function timeRangeBreakOf(sl: WorkSlot): {
|
|
12
|
+
startTime: string;
|
|
13
|
+
endTime: string;
|
|
14
|
+
} | null;
|
|
15
|
+
/** Same face as `t12`, but never drops the minutes — two ranges stacked on a split card need
|
|
16
|
+
* to line up at a glance, and "10am" next to "10:30am" reads as two different units. */
|
|
17
|
+
export declare function t12Full(hhmm: string): string;
|
|
6
18
|
/** A break length that doesn't match one of the presets becomes 'custom', carrying its own
|
|
7
19
|
* minutes/unit back out for the caller to seed its custom-break fields from. */
|
|
8
20
|
export declare function normalizeBreak(mins: number | undefined): {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Role } from '@/types/role';
|
|
1
2
|
import type { Employee } from '../types';
|
|
2
3
|
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
3
4
|
import { type ScheduleAddEmployeeMode, type ScheduleAddEmployeeStep } from './schedule-add-employee-form';
|
|
@@ -20,6 +21,7 @@ export declare function useScheduleAddEmployee(board: ScheduleBoardApi): {
|
|
|
20
21
|
payAmount: string;
|
|
21
22
|
maxHours: string;
|
|
22
23
|
minHours: string;
|
|
24
|
+
otEnabled: boolean;
|
|
23
25
|
otAfterDaily: string;
|
|
24
26
|
maxOtHours: string;
|
|
25
27
|
availDays: boolean[];
|
|
@@ -33,11 +35,13 @@ export declare function useScheduleAddEmployee(board: ScheduleBoardApi): {
|
|
|
33
35
|
seniority: "" | "senior" | "junior";
|
|
34
36
|
passcode: string[];
|
|
35
37
|
masterUser: boolean;
|
|
36
|
-
roleId: string;
|
|
37
38
|
masterCode: string;
|
|
39
|
+
posAccessEnabled: boolean;
|
|
40
|
+
posRoleId: string;
|
|
38
41
|
};
|
|
39
42
|
sectionId: import("vue").Ref<string, string>;
|
|
40
43
|
isEditing: import("vue").ComputedRef<boolean>;
|
|
44
|
+
editingEmployeeId: import("vue").Ref<number | null, number | null>;
|
|
41
45
|
locOpen: import("vue").Ref<boolean, boolean>;
|
|
42
46
|
secOpen: import("vue").Ref<boolean, boolean>;
|
|
43
47
|
secondaryOptions: import("vue").ComputedRef<string[]>;
|
|
@@ -47,19 +51,15 @@ export declare function useScheduleAddEmployee(board: ScheduleBoardApi): {
|
|
|
47
51
|
avAllLabel: import("vue").ComputedRef<"Clear all" | "Select all" | "No days off" | "Every day off">;
|
|
48
52
|
maxHoursPlaceholder: import("vue").ComputedRef<"Hours per week" | "No cap">;
|
|
49
53
|
otAfterDailyPlaceholder: import("vue").ComputedRef<string>;
|
|
54
|
+
toggleOt: () => void;
|
|
50
55
|
payUnit: import("vue").ComputedRef<"/month" | "/hour">;
|
|
51
56
|
effectiveRate: import("vue").ComputedRef<number>;
|
|
52
57
|
passcodeValue: import("vue").ComputedRef<string>;
|
|
53
58
|
passcodeOk: import("vue").ComputedRef<boolean>;
|
|
54
59
|
currentLocationLabel: import("vue").ComputedRef<string>;
|
|
55
|
-
|
|
56
|
-
value: string;
|
|
57
|
-
label: string;
|
|
58
|
-
}[]>;
|
|
59
|
-
roleError: import("vue").ComputedRef<boolean>;
|
|
60
|
+
locationOptions: import("vue").Reactive<string[]>;
|
|
60
61
|
masterCodeError: import("vue").ComputedRef<boolean>;
|
|
61
62
|
isNewUser: import("vue").ComputedRef<boolean>;
|
|
62
|
-
needsRole: import("vue").ComputedRef<boolean>;
|
|
63
63
|
footerHint: import("vue").ComputedRef<"Pick who — this outlet's own pay, position and hours are still set here." | "One short form. Rest days are set on their profile afterwards.">;
|
|
64
64
|
primaryRoleLabel: import("vue").ComputedRef<string>;
|
|
65
65
|
locationsSummary: import("vue").ComputedRef<string>;
|
|
@@ -77,7 +77,7 @@ export declare function useScheduleAddEmployee(board: ScheduleBoardApi): {
|
|
|
77
77
|
setMode: (m: ScheduleAddEmployeeMode) => void;
|
|
78
78
|
openSelectExisting: () => void;
|
|
79
79
|
closeSelectExisting: () => void;
|
|
80
|
-
pickExisting: (employeeId: string) => void
|
|
80
|
+
pickExisting: (employeeId: string) => Promise<void>;
|
|
81
81
|
next: () => void;
|
|
82
82
|
back: () => void;
|
|
83
83
|
toggleMulti: (which: "loc" | "sec") => void;
|
|
@@ -93,6 +93,9 @@ export declare function useScheduleAddEmployee(board: ScheduleBoardApi): {
|
|
|
93
93
|
copyAvailHourDown: (i: number) => void;
|
|
94
94
|
setPasscodeDigit: (i: number, value: string) => void;
|
|
95
95
|
generatePasscode: () => void;
|
|
96
|
+
togglePosAccess: () => void;
|
|
97
|
+
setPosRole: (roleId: string) => void;
|
|
98
|
+
posRoleOptions: import("vue").ComputedRef<Role[]>;
|
|
96
99
|
create: () => Promise<boolean>;
|
|
97
100
|
};
|
|
98
101
|
export type ScheduleAddEmployeeApi = ReturnType<typeof useScheduleAddEmployee>;
|
|
@@ -35,7 +35,7 @@ export interface ScheduleAddPickSuggestion {
|
|
|
35
35
|
* left out — it needs split-shift/group-joining machinery this board doesn't model. */
|
|
36
36
|
export declare function useScheduleAddPick(board: ScheduleBoardApi, demand: ScheduleDemandApi, handlers: {
|
|
37
37
|
onCommitted: (message: string) => void;
|
|
38
|
-
onOpenFullEditor: (empId: number, dayIdx: number) => void;
|
|
38
|
+
onOpenFullEditor: (empId: number, dayIdx: number, slotIndex: number) => void;
|
|
39
39
|
/** The leave editor, on this cell. `reason` is the row's own type, or null for the plain "Leave" row. */
|
|
40
40
|
onOpenLeave: (empId: number, dayIdx: number, reason: string | null) => void;
|
|
41
41
|
}): {
|
|
@@ -58,7 +58,15 @@ export declare function useScheduleAddPick(board: ScheduleBoardApi, demand: Sche
|
|
|
58
58
|
end: string;
|
|
59
59
|
} | null>;
|
|
60
60
|
suggested: import("vue").ComputedRef<ScheduleAddPickSuggestion | null>;
|
|
61
|
-
filteredPatterns: import("vue").ComputedRef<
|
|
61
|
+
filteredPatterns: import("vue").ComputedRef<{
|
|
62
|
+
key: string;
|
|
63
|
+
label: string;
|
|
64
|
+
start: string;
|
|
65
|
+
end: string;
|
|
66
|
+
color: string;
|
|
67
|
+
active: boolean;
|
|
68
|
+
breakMins: number;
|
|
69
|
+
}[]>;
|
|
62
70
|
filteredLeaves: import("vue").ComputedRef<ScheduleAddPickLeaveOption[]>;
|
|
63
71
|
hasResults: import("vue").ComputedRef<boolean>;
|
|
64
72
|
openFor: (empId: number, dayIdx: number, anchor: HTMLElement) => void;
|
|
@@ -3,6 +3,9 @@ import type { Employee, WorkSlot } from '../types';
|
|
|
3
3
|
export interface ScheduleAssignedSlot {
|
|
4
4
|
emp: Employee;
|
|
5
5
|
slot: WorkSlot;
|
|
6
|
+
/** This slot's position within the employee's day — what a drag of this card has to hand
|
|
7
|
+
* `board.moveShift`/`swapShifts` to pick the right period out of a day holding more than one. */
|
|
8
|
+
slotIndex: number;
|
|
6
9
|
}
|
|
7
10
|
export interface SchedulePositionCellMeta {
|
|
8
11
|
required: number;
|
|
@@ -12,6 +15,16 @@ export interface SchedulePositionCellMeta {
|
|
|
12
15
|
}
|
|
13
16
|
/** Shared by the week and day area views, so a position's colour never disagrees between them. */
|
|
14
17
|
export declare function positionSwatchClass(position: string): string;
|
|
18
|
+
/** Where shifts and employees go that name no station at all — either because the outlet
|
|
19
|
+
* hasn't named its positions yet, or because a shift deliberately names none. Rostering
|
|
20
|
+
* shouldn't be blocked on the Positions page being filled in first, so this row exists
|
|
21
|
+
* whenever there's anyone or anything to put in it (see `positionRows`). */
|
|
22
|
+
export declare const ANY_POSITION_ROW = "Any position";
|
|
23
|
+
/** Every other row is named after the position its shifts carry, so the row name and the
|
|
24
|
+
* position key are the same string. This one differs: it collects records that name nothing,
|
|
25
|
+
* so anything that queries BY position — qualifiedFor, assignedOn, a new shift's role — has to
|
|
26
|
+
* ask for '' instead, or the row would answer "nobody holds Any position". */
|
|
27
|
+
export declare function rowAsk(row: string): string;
|
|
15
28
|
/** Whether this employee can be put on `position` — ported from the mockup's qualifiedFor().
|
|
16
29
|
* Nobody having a named position yet reads as "any station", the same way an unspecialised
|
|
17
30
|
* new-account roster does in the reference: rostering shouldn't be blocked on the Positions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FdtoScheduleAutoScheduleObjective,
|
|
1
|
+
import type { FdtoScheduleAutoScheduleObjective, FdtoScheduleAutoSchedulePlanner } from '@/types/schedule';
|
|
2
2
|
import type { Proposal } from '../types';
|
|
3
3
|
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
4
4
|
import type { ScheduleDemandApi } from './useScheduleDemand';
|
|
@@ -6,6 +6,7 @@ export type ScheduleAutoScheduleStep = 'options' | 'summary';
|
|
|
6
6
|
export interface ScheduleAutoScheduleOptions {
|
|
7
7
|
fillGaps: boolean;
|
|
8
8
|
objective: FdtoScheduleAutoScheduleObjective;
|
|
9
|
+
planner: FdtoScheduleAutoSchedulePlanner;
|
|
9
10
|
allowOvertime: boolean;
|
|
10
11
|
/** Shown as preferences in the dialog but not sent: the generator takes no input for them yet
|
|
11
12
|
* (availability and time off are always respected; patterns and cost ride on the objective). */
|
|
@@ -13,30 +14,54 @@ export interface ScheduleAutoScheduleOptions {
|
|
|
13
14
|
followPatterns: boolean;
|
|
14
15
|
costEfficient: boolean;
|
|
15
16
|
}
|
|
16
|
-
/** Backend-powered draft generation and local proposal review
|
|
17
|
-
*
|
|
17
|
+
/** Backend-powered draft generation and local proposal review — the engine lives in hr-backend;
|
|
18
|
+
* this composable only maps its result onto the board and lets a manager review it. Generation
|
|
19
|
+
* never writes; accepted proposals use the board's existing assignment persistence path. */
|
|
18
20
|
export declare function useScheduleAutoSchedule(board: ScheduleBoardApi, demand: ScheduleDemandApi): {
|
|
19
21
|
wizardOpen: import("vue").Ref<boolean, boolean>;
|
|
20
22
|
step: import("vue").Ref<ScheduleAutoScheduleStep, ScheduleAutoScheduleStep>;
|
|
21
23
|
options: {
|
|
22
24
|
fillGaps: boolean;
|
|
23
25
|
objective: FdtoScheduleAutoScheduleObjective;
|
|
26
|
+
planner: FdtoScheduleAutoSchedulePlanner;
|
|
24
27
|
allowOvertime: boolean;
|
|
25
28
|
respectAvailability: boolean;
|
|
26
29
|
followPatterns: boolean;
|
|
27
30
|
costEfficient: boolean;
|
|
28
31
|
};
|
|
32
|
+
planners: import("vue").Ref<("GREEDY" | "LLM")[], ("GREEDY" | "LLM")[]>;
|
|
33
|
+
plannerChoice: import("vue").ComputedRef<boolean>;
|
|
29
34
|
generating: import("vue").Ref<boolean, boolean>;
|
|
30
35
|
generateError: import("vue").Ref<string | null, string | null>;
|
|
31
36
|
result: import("vue").Ref<{
|
|
37
|
+
objective: "BALANCED" | "SERVICE" | "LOWER_COST" | "STABLE_HOURS";
|
|
38
|
+
allowOvertime: boolean;
|
|
32
39
|
proposals: {
|
|
33
|
-
employeeId: string;
|
|
34
40
|
date: string;
|
|
35
41
|
startTime: string;
|
|
36
42
|
endTime: string;
|
|
43
|
+
positionId: string | null;
|
|
44
|
+
employeeId: string;
|
|
45
|
+
employeeName: string;
|
|
37
46
|
position: string;
|
|
47
|
+
reason: string;
|
|
38
48
|
}[];
|
|
39
49
|
unfilledCount: number;
|
|
50
|
+
unfilledNeeds: {
|
|
51
|
+
date: string;
|
|
52
|
+
startTime: string;
|
|
53
|
+
endTime: string;
|
|
54
|
+
position: string | null;
|
|
55
|
+
short: number;
|
|
56
|
+
excluded: {
|
|
57
|
+
occupied: number;
|
|
58
|
+
notQualified: number;
|
|
59
|
+
weeklyCap: number;
|
|
60
|
+
rest: number;
|
|
61
|
+
dayOff: number;
|
|
62
|
+
dayCap: number;
|
|
63
|
+
};
|
|
64
|
+
}[];
|
|
40
65
|
metrics: {
|
|
41
66
|
minimumCoveragePercent: number;
|
|
42
67
|
recommendedCoveragePercent: number;
|
|
@@ -52,27 +77,55 @@ export declare function useScheduleAutoSchedule(board: ScheduleBoardApi, demand:
|
|
|
52
77
|
capabilities: string[];
|
|
53
78
|
issues: {
|
|
54
79
|
code: string;
|
|
55
|
-
severity: "BLOCKER" | "WARNING" | "INFO";
|
|
56
80
|
message: string;
|
|
81
|
+
severity: "BLOCKER" | "WARNING" | "INFO";
|
|
57
82
|
}[];
|
|
58
83
|
coverage: {
|
|
59
|
-
position: number;
|
|
60
|
-
availability: number;
|
|
61
84
|
wage: number;
|
|
85
|
+
availability: number;
|
|
86
|
+
position: number;
|
|
62
87
|
targetHours: number;
|
|
63
88
|
};
|
|
64
89
|
};
|
|
65
90
|
explanations: string[];
|
|
66
91
|
solver: string;
|
|
67
|
-
|
|
92
|
+
week: {
|
|
93
|
+
from: string;
|
|
94
|
+
to: string;
|
|
95
|
+
};
|
|
96
|
+
timing: {
|
|
97
|
+
totalMs: number;
|
|
98
|
+
modelMs: number | null;
|
|
99
|
+
};
|
|
100
|
+
} | null, {
|
|
101
|
+
objective: "BALANCED" | "SERVICE" | "LOWER_COST" | "STABLE_HOURS";
|
|
102
|
+
allowOvertime: boolean;
|
|
68
103
|
proposals: {
|
|
69
|
-
employeeId: string;
|
|
70
104
|
date: string;
|
|
71
105
|
startTime: string;
|
|
72
106
|
endTime: string;
|
|
107
|
+
positionId: string | null;
|
|
108
|
+
employeeId: string;
|
|
109
|
+
employeeName: string;
|
|
73
110
|
position: string;
|
|
111
|
+
reason: string;
|
|
74
112
|
}[];
|
|
75
113
|
unfilledCount: number;
|
|
114
|
+
unfilledNeeds: {
|
|
115
|
+
date: string;
|
|
116
|
+
startTime: string;
|
|
117
|
+
endTime: string;
|
|
118
|
+
position: string | null;
|
|
119
|
+
short: number;
|
|
120
|
+
excluded: {
|
|
121
|
+
occupied: number;
|
|
122
|
+
notQualified: number;
|
|
123
|
+
weeklyCap: number;
|
|
124
|
+
rest: number;
|
|
125
|
+
dayOff: number;
|
|
126
|
+
dayCap: number;
|
|
127
|
+
};
|
|
128
|
+
}[];
|
|
76
129
|
metrics: {
|
|
77
130
|
minimumCoveragePercent: number;
|
|
78
131
|
recommendedCoveragePercent: number;
|
|
@@ -88,18 +141,90 @@ export declare function useScheduleAutoSchedule(board: ScheduleBoardApi, demand:
|
|
|
88
141
|
capabilities: string[];
|
|
89
142
|
issues: {
|
|
90
143
|
code: string;
|
|
91
|
-
severity: "BLOCKER" | "WARNING" | "INFO";
|
|
92
144
|
message: string;
|
|
145
|
+
severity: "BLOCKER" | "WARNING" | "INFO";
|
|
93
146
|
}[];
|
|
94
147
|
coverage: {
|
|
95
|
-
|
|
148
|
+
wage: number;
|
|
96
149
|
availability: number;
|
|
150
|
+
position: number;
|
|
151
|
+
targetHours: number;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
explanations: string[];
|
|
155
|
+
solver: string;
|
|
156
|
+
week: {
|
|
157
|
+
from: string;
|
|
158
|
+
to: string;
|
|
159
|
+
};
|
|
160
|
+
timing: {
|
|
161
|
+
totalMs: number;
|
|
162
|
+
modelMs: number | null;
|
|
163
|
+
};
|
|
164
|
+
} | {
|
|
165
|
+
objective: "BALANCED" | "SERVICE" | "LOWER_COST" | "STABLE_HOURS";
|
|
166
|
+
allowOvertime: boolean;
|
|
167
|
+
proposals: {
|
|
168
|
+
date: string;
|
|
169
|
+
startTime: string;
|
|
170
|
+
endTime: string;
|
|
171
|
+
positionId: string | null;
|
|
172
|
+
employeeId: string;
|
|
173
|
+
employeeName: string;
|
|
174
|
+
position: string;
|
|
175
|
+
reason: string;
|
|
176
|
+
}[];
|
|
177
|
+
unfilledCount: number;
|
|
178
|
+
unfilledNeeds: {
|
|
179
|
+
date: string;
|
|
180
|
+
startTime: string;
|
|
181
|
+
endTime: string;
|
|
182
|
+
position: string | null;
|
|
183
|
+
short: number;
|
|
184
|
+
excluded: {
|
|
185
|
+
occupied: number;
|
|
186
|
+
notQualified: number;
|
|
187
|
+
weeklyCap: number;
|
|
188
|
+
rest: number;
|
|
189
|
+
dayOff: number;
|
|
190
|
+
dayCap: number;
|
|
191
|
+
};
|
|
192
|
+
}[];
|
|
193
|
+
metrics: {
|
|
194
|
+
minimumCoveragePercent: number;
|
|
195
|
+
recommendedCoveragePercent: number;
|
|
196
|
+
totalHours: number;
|
|
197
|
+
estimatedLabourCost: number | null;
|
|
198
|
+
costCoveragePercent: number;
|
|
199
|
+
overtimeHours: number;
|
|
200
|
+
targetHoursVariance: number;
|
|
201
|
+
unfilledIntervals: number;
|
|
202
|
+
};
|
|
203
|
+
readiness: {
|
|
204
|
+
ready: boolean;
|
|
205
|
+
capabilities: string[];
|
|
206
|
+
issues: {
|
|
207
|
+
code: string;
|
|
208
|
+
message: string;
|
|
209
|
+
severity: "BLOCKER" | "WARNING" | "INFO";
|
|
210
|
+
}[];
|
|
211
|
+
coverage: {
|
|
97
212
|
wage: number;
|
|
213
|
+
availability: number;
|
|
214
|
+
position: number;
|
|
98
215
|
targetHours: number;
|
|
99
216
|
};
|
|
100
217
|
};
|
|
101
218
|
explanations: string[];
|
|
102
219
|
solver: string;
|
|
220
|
+
week: {
|
|
221
|
+
from: string;
|
|
222
|
+
to: string;
|
|
223
|
+
};
|
|
224
|
+
timing: {
|
|
225
|
+
totalMs: number;
|
|
226
|
+
modelMs: number | null;
|
|
227
|
+
};
|
|
103
228
|
} | null>;
|
|
104
229
|
gapCount: import("vue").ComputedRef<number>;
|
|
105
230
|
hasDemand: import("vue").ComputedRef<boolean>;
|
|
@@ -118,6 +243,7 @@ export declare function useScheduleAutoSchedule(board: ScheduleBoardApi, demand:
|
|
|
118
243
|
start: string;
|
|
119
244
|
end: string;
|
|
120
245
|
role: string;
|
|
246
|
+
positionId?: string | null | undefined;
|
|
121
247
|
openId?: number | undefined;
|
|
122
248
|
status: "pending" | "rejected";
|
|
123
249
|
weekKey?: string | undefined;
|
|
@@ -138,6 +264,26 @@ export declare function useScheduleAutoSchedule(board: ScheduleBoardApi, demand:
|
|
|
138
264
|
toggleReject: (id: number) => void;
|
|
139
265
|
rejectAll: () => void;
|
|
140
266
|
exitReview: () => void;
|
|
141
|
-
apply: () => number
|
|
267
|
+
apply: () => Promise<number | null>;
|
|
268
|
+
applying: import("vue").Ref<boolean, boolean>;
|
|
269
|
+
applyRejections: import("vue").Ref<{
|
|
270
|
+
employeeName: string;
|
|
271
|
+
day: string;
|
|
272
|
+
time: string;
|
|
273
|
+
message: string;
|
|
274
|
+
}[], {
|
|
275
|
+
employeeName: string;
|
|
276
|
+
day: string;
|
|
277
|
+
time: string;
|
|
278
|
+
message: string;
|
|
279
|
+
}[] | {
|
|
280
|
+
employeeName: string;
|
|
281
|
+
day: string;
|
|
282
|
+
time: string;
|
|
283
|
+
message: string;
|
|
284
|
+
}[]>;
|
|
285
|
+
applyError: import("vue").Ref<string | null, string | null>;
|
|
286
|
+
detailsOpen: import("vue").Ref<boolean, boolean>;
|
|
287
|
+
toggleDetails: () => void;
|
|
142
288
|
};
|
|
143
289
|
export type ScheduleAutoScheduleApi = ReturnType<typeof useScheduleAutoSchedule>;
|