@feedmepos/mf-hrm-portal 2.2.4 → 2.2.5-dev.10
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-ChGQwko6.js → ApprovalCodeList-BsDMMSIz.js} +7 -7
- package/dist/{AuditLogList-Cpj8O5qS.js → AuditLogList-CGNZdtmn.js} +244 -241
- package/dist/{ConditionBuilderForm.vue_vue_type_script_setup_true_lang-CNmbZlVZ.js → ConditionBuilderForm.vue_vue_type_script_setup_true_lang-C6MoToqi.js} +2 -2
- package/dist/EmployeeList-B_OuDWWQ.js +787 -0
- package/dist/{FormItem.vue_vue_type_script_setup_true_lang-DPT2FoIc.js → FormItem.vue_vue_type_script_setup_true_lang-CUnlKsxk.js} +1 -1
- package/dist/{GrantUserList-CAXJmQ4i.js → GrantUserList-Bd0lXmFo.js} +8 -8
- package/dist/{Main-Ada9K_jO.js → Main-B66lSeOv.js} +8 -8
- package/dist/{Main-T9-30vq8.js → Main-CzHSNHsH.js} +5 -5
- package/dist/{Main-7yT_w5vt.js → Main-njRQ1tFk.js} +11 -11
- package/dist/PasscodePinField.vue_vue_type_script_setup_true_lang-CqG0v0Sz.js +243 -0
- package/dist/{PermissionSetList-CkWYPmT2.js → PermissionSetList-GTI6Cwj5.js} +20 -20
- package/dist/{PortalPermissionEditor.vue_vue_type_script_setup_true_lang-CCLLrSyq.js → PortalPermissionEditor.vue_vue_type_script_setup_true_lang-C-QEQ-js.js} +937 -944
- package/dist/{PortalUserSearcher.vue_vue_type_style_index_0_scoped_827dfd60_lang-Z-DH7ouY.js → PortalUserSearcher.vue_vue_type_style_index_0_scoped_827dfd60_lang-XHuHin8t.js} +1 -1
- package/dist/{RoleList-Do36AmlU.js → RoleList-CmHgtM0m.js} +9 -9
- package/dist/ScheduleAddPositionModal.vue_vue_type_script_setup_true_lang-SFqxftRx.js +426 -0
- package/dist/ScheduleButton.vue_vue_type_script_setup_true_lang-CrWfo-zF.js +690 -0
- package/dist/ScheduleGeneralPage-DxFxJN5j.js +320 -0
- package/dist/SchedulePage-cJDI3-E7.js +14647 -0
- package/dist/SchedulePositionPage-n1wUShIM.js +293 -0
- package/dist/ScheduleSelect.vue_vue_type_script_setup_true_lang-B8W4sTsA.js +242 -0
- package/dist/SelectFilter-CG13h83-.js +264 -0
- package/dist/TeamMemberList-ByZt3VqN.js +1154 -0
- package/dist/{TimesheetList-DboJ2_89.js → TimesheetList-Dv0-W--W.js} +71 -68
- package/dist/{TimesheetList.vue_vue_type_style_index_0_scoped_2c7a177a_lang-C4g8wRjv.js → TimesheetList.vue_vue_type_style_index_0_scoped_63294af2_lang-DIo6h5-a.js} +3 -3
- package/dist/_plugin-vue_export-helper-CHgC5LLL.js +9 -0
- package/dist/{app-CcCcPbyB.js → app-SCXGJ95F.js} +3182 -2565
- package/dist/app.js +1 -1
- package/dist/{approval-code-BRClD2HN.js → approval-code-jIjkeVEb.js} +1 -1
- package/dist/{dayjs.min-lvkj1Rwa.js → dayjs.min-DqMLPYv-.js} +1 -1
- package/dist/employee-DT_xYQkz.js +204 -0
- package/dist/{grant-user-Dhi3ilC_.js → grant-user-SNiDV22U.js} +1 -1
- package/dist/{iteration-LZbo-knt.js → iteration-B5dB9ecy.js} +1 -1
- package/dist/{lodash-CKzaMa7f.js → lodash-CRHFapxI.js} +1 -1
- package/dist/{restaurant-DiYb0pCm.js → restaurant-BTpBmfBV.js} +2 -2
- package/dist/{role-BZr8zzeq.js → role-CJm8pXaw.js} +2 -2
- package/dist/{rule-DNaqlUUB.js → rule-AJm-eVzJ.js} +291 -279
- package/dist/src/api/employee/index.d.ts +5 -1
- package/dist/src/api/schedule/index.d.ts +41 -0
- package/dist/src/api/team/index.d.ts +3 -0
- package/dist/src/components/form/OutletRoleAssignment.vue.d.ts +16 -0
- package/dist/src/components/form/PasscodeGenerateButton.vue.d.ts +15 -0
- package/dist/src/components/form/PasscodePinField.vue.d.ts +18 -0
- package/dist/src/components/layout/AppSidebar.vue.d.ts +2 -0
- package/dist/src/components/layout/PortalShell.vue.d.ts +12 -0
- package/dist/src/components/layout/withShell.d.ts +14 -0
- package/dist/src/helpers/outlet-role-assignment.d.ts +40 -0
- package/dist/src/helpers/rule.d.ts +15 -0
- package/dist/src/helpers/string.d.ts +2 -1
- package/dist/src/router/shared.d.ts +4 -1
- package/dist/src/types/schedule.d.ts +232 -0
- package/dist/src/views/audit-log/locales/index.d.ts +4 -0
- package/dist/src/views/hr/locales/index.d.ts +8 -0
- package/dist/src/views/scheduling/ScheduleGeneralPage.vue.d.ts +3 -0
- package/dist/src/views/scheduling/SchedulePage.vue.d.ts +3 -0
- package/dist/src/views/scheduling/SchedulePositionPage.vue.d.ts +3 -0
- package/dist/src/views/scheduling/components/ScheduleAddEmployeeIdentitySection.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleAddEmployeeModal.vue.d.ts +10 -0
- package/dist/src/views/scheduling/components/ScheduleAddEmployeeModeStep.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleAddEmployeePosAccessSection.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleAddEmployeePositionsSection.vue.d.ts +10 -0
- package/dist/src/views/scheduling/components/ScheduleAddEmployeeSchedulingSection.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleAddPickPopover.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleAddPositionModal.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleAllShiftsRow.vue.d.ts +22 -0
- package/dist/src/views/scheduling/components/ScheduleAreaRows.vue.d.ts +34 -0
- package/dist/src/views/scheduling/components/ScheduleAssignEmployeePopover.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleAutoScheduleModal.vue.d.ts +10 -0
- package/dist/src/views/scheduling/components/ScheduleButton.vue.d.ts +23 -0
- package/dist/src/views/scheduling/components/ScheduleChangeEmployeeModal.vue.d.ts +8 -0
- package/dist/src/views/scheduling/components/ScheduleConfirmModal.vue.d.ts +24 -0
- package/dist/src/views/scheduling/components/ScheduleCostRail.vue.d.ts +8 -0
- package/dist/src/views/scheduling/components/ScheduleDateRangePopover.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleDayNotePopover.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleDayTimeline.vue.d.ts +12 -0
- package/dist/src/views/scheduling/components/ScheduleDemandRow.vue.d.ts +23 -0
- package/dist/src/views/scheduling/components/ScheduleDemandSheet.vue.d.ts +10 -0
- package/dist/src/views/scheduling/components/ScheduleDotsIcon.vue.d.ts +2 -0
- package/dist/src/views/scheduling/components/ScheduleEmployeeDetailPanel.vue.d.ts +12 -0
- package/dist/src/views/scheduling/components/ScheduleEmployeeIdentity.vue.d.ts +17 -0
- package/dist/src/views/scheduling/components/ScheduleEmployeeMenu.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleFilterBar.vue.d.ts +18 -0
- package/dist/src/views/scheduling/components/ScheduleGapPopover.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleGridHeader.vue.d.ts +18 -0
- package/dist/src/views/scheduling/components/ScheduleGridSkeleton.vue.d.ts +2 -0
- package/dist/src/views/scheduling/components/ScheduleLeaveEditModal.vue.d.ts +8 -0
- package/dist/src/views/scheduling/components/ScheduleLegendBar.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleOnboardingWelcome.vue.d.ts +12 -0
- package/dist/src/views/scheduling/components/ScheduleOnboardingWizard.vue.d.ts +9 -0
- package/dist/src/views/scheduling/components/ScheduleOpenShiftCardMenu.vue.d.ts +14 -0
- package/dist/src/views/scheduling/components/SchedulePdfPreview.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/SchedulePublishModal.vue.d.ts +8 -0
- package/dist/src/views/scheduling/components/ScheduleReviewBar.vue.d.ts +12 -0
- package/dist/src/views/scheduling/components/ScheduleSelect.vue.d.ts +54 -0
- package/dist/src/views/scheduling/components/ScheduleSelectExistingEmployeeModal.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleShiftCardMenu.vue.d.ts +12 -0
- package/dist/src/views/scheduling/components/ScheduleShiftCell.vue.d.ts +35 -0
- package/dist/src/views/scheduling/components/ScheduleShiftHeadcountEditor.vue.d.ts +10 -0
- package/dist/src/views/scheduling/components/ScheduleShiftImpact.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleShiftMoreOptions.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleShiftPopover.vue.d.ts +16 -0
- package/dist/src/views/scheduling/components/ScheduleShiftRepeatDaysRow.vue.d.ts +8 -0
- package/dist/src/views/scheduling/components/ScheduleShiftSegmentsEditor.vue.d.ts +8 -0
- package/dist/src/views/scheduling/components/ScheduleShiftWhoPicker.vue.d.ts +25 -0
- package/dist/src/views/scheduling/components/ScheduleStackPopover.vue.d.ts +14 -0
- package/dist/src/views/scheduling/components/ScheduleStaffRail.vue.d.ts +18 -0
- package/dist/src/views/scheduling/components/ScheduleStaffRows.vue.d.ts +60 -0
- package/dist/src/views/scheduling/components/ScheduleStatsRow.vue.d.ts +12 -0
- package/dist/src/views/scheduling/components/ScheduleSwapShiftsModal.vue.d.ts +8 -0
- package/dist/src/views/scheduling/components/ScheduleTimePickerPopover.vue.d.ts +6 -0
- package/dist/src/views/scheduling/components/ScheduleTopbar.vue.d.ts +20 -0
- package/dist/src/views/scheduling/composables/schedule-add-employee-form.d.ts +72 -0
- package/dist/src/views/scheduling/composables/schedule-board-helpers.d.ts +38 -0
- package/dist/src/views/scheduling/composables/schedule-day-meta.d.ts +29 -0
- package/dist/src/views/scheduling/composables/schedule-employee-profile.d.ts +7 -0
- package/dist/src/views/scheduling/composables/schedule-popover-position.d.ts +16 -0
- package/dist/src/views/scheduling/composables/schedule-shift-time.d.ts +14 -0
- package/dist/src/views/scheduling/composables/schedule-week-cache.d.ts +10 -0
- package/dist/src/views/scheduling/composables/scheduleAutoSolver.d.ts +21 -0
- package/dist/src/views/scheduling/composables/useCollapsedList.d.ts +9 -0
- package/dist/src/views/scheduling/composables/useScheduleAddEmployee.d.ts +98 -0
- package/dist/src/views/scheduling/composables/useScheduleAddPick.d.ts +73 -0
- package/dist/src/views/scheduling/composables/useScheduleAllShiftsRow.d.ts +77 -0
- package/dist/src/views/scheduling/composables/useScheduleAreaBoard.d.ts +50 -0
- package/dist/src/views/scheduling/composables/useScheduleAreaDragDrop.d.ts +18 -0
- package/dist/src/views/scheduling/composables/useScheduleAssign.d.ts +122 -0
- package/dist/src/views/scheduling/composables/useScheduleAutoSchedule.d.ts +143 -0
- package/dist/src/views/scheduling/composables/useScheduleBoard.d.ts +426 -0
- package/dist/src/views/scheduling/composables/useScheduleCellState.d.ts +27 -0
- package/dist/src/views/scheduling/composables/useScheduleClashDetection.d.ts +18 -0
- package/dist/src/views/scheduling/composables/useScheduleCopyWeek.d.ts +19 -0
- package/dist/src/views/scheduling/composables/useScheduleCostRail.d.ts +43 -0
- package/dist/src/views/scheduling/composables/useScheduleDayNote.d.ts +48 -0
- package/dist/src/views/scheduling/composables/useScheduleDayTimeline.d.ts +77 -0
- package/dist/src/views/scheduling/composables/useScheduleDemand.d.ts +76 -0
- package/dist/src/views/scheduling/composables/useScheduleDemandRow.d.ts +45 -0
- package/dist/src/views/scheduling/composables/useScheduleDemandSheet.d.ts +145 -0
- package/dist/src/views/scheduling/composables/useScheduleDragDrop.d.ts +22 -0
- package/dist/src/views/scheduling/composables/useScheduleEmployeeIdentity.d.ts +41 -0
- package/dist/src/views/scheduling/composables/useScheduleEmployeeMenu.d.ts +35 -0
- package/dist/src/views/scheduling/composables/useScheduleEmployeeProfile.d.ts +16 -0
- package/dist/src/views/scheduling/composables/useScheduleExport.d.ts +26 -0
- package/dist/src/views/scheduling/composables/useScheduleFilterBar.d.ts +14 -0
- package/dist/src/views/scheduling/composables/useScheduleGapPopover.d.ts +82 -0
- package/dist/src/views/scheduling/composables/useScheduleLeave.d.ts +70 -0
- package/dist/src/views/scheduling/composables/useScheduleLegend.d.ts +15 -0
- package/dist/src/views/scheduling/composables/useScheduleLegendBar.d.ts +35 -0
- package/dist/src/views/scheduling/composables/useScheduleOnboardingWizard.d.ts +1316 -0
- package/dist/src/views/scheduling/composables/useScheduleOpenShiftCard.d.ts +23 -0
- package/dist/src/views/scheduling/composables/useScheduleOutlet.d.ts +20 -0
- package/dist/src/views/scheduling/composables/useSchedulePositionModal.d.ts +50 -0
- package/dist/src/views/scheduling/composables/useSchedulePositions.d.ts +32 -0
- package/dist/src/views/scheduling/composables/useSchedulePublish.d.ts +93 -0
- package/dist/src/views/scheduling/composables/useScheduleRangeCalendar.d.ts +27 -0
- package/dist/src/views/scheduling/composables/useScheduleRoster.d.ts +189 -0
- package/dist/src/views/scheduling/composables/useScheduleSettings.d.ts +54 -0
- package/dist/src/views/scheduling/composables/useScheduleSetupBanner.d.ts +18 -0
- package/dist/src/views/scheduling/composables/useScheduleShiftActions.d.ts +163 -0
- package/dist/src/views/scheduling/composables/useScheduleShiftPopover.d.ts +181 -0
- package/dist/src/views/scheduling/composables/useScheduleStaffRail.d.ts +23 -0
- package/dist/src/views/scheduling/composables/useScheduleStatsRow.d.ts +25 -0
- package/dist/src/views/scheduling/composables/useScheduleTimePicker.d.ts +49 -0
- package/dist/src/views/scheduling/composables/useScheduleTopbar.d.ts +10 -0
- package/dist/src/views/scheduling/composables/useScheduleViewportFit.d.ts +9 -0
- package/dist/src/views/scheduling/data.d.ts +110 -0
- package/dist/src/views/scheduling/locales/index.d.ts +496 -0
- package/dist/src/views/scheduling/schedule-store.d.ts +151 -0
- package/dist/src/views/scheduling/types.d.ts +324 -0
- package/dist/src/views/team/components/PortalConditionForm.vue.d.ts +2 -2
- package/dist/src/views/team/condition-builders/ConditionBuilderForm.vue.d.ts +2 -2
- package/dist/src/views/team/locales/index.d.ts +12 -0
- package/dist/src/views/team/member/AddMemberForm.vue.d.ts +1 -0
- package/dist/src/views/team/member/TeamMemberMasterUser.vue.d.ts +21 -3
- package/dist/string-VNuQNweN.js +15 -0
- package/dist/style.css +1 -1
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/dist/{useAppStore-BGhlB1_1.js → useAppStore-DCwd8GWN.js} +1 -1
- package/dist/{useLoading-CvgqVDbF.js → useLoading-CXzTpIVv.js} +1 -1
- package/dist/{useReportPermissions-Buzv6pkY.js → useReportPermissions-Cg3lV70m.js} +3 -3
- package/package.json +1 -1
- package/dist/EmployeeList-PdGzSCP-.js +0 -887
- package/dist/SelectFilter-ATOm0hdn.js +0 -269
- package/dist/Skeleton.vue_vue_type_script_setup_true_lang-B4PxNMwq.js +0 -16
- package/dist/TeamMemberList-CVVNnz0R.js +0 -1216
- package/dist/employee-CLgrXpmZ.js +0 -201
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { CoverageSegment, DaySlot, DemandPeriod, Employee, Proposal } from '../types';
|
|
2
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
3
|
+
export declare function toMin(t: string): number;
|
|
4
|
+
export declare function minToHHMM(m: number): string;
|
|
5
|
+
/** Minutes from midnight for a start/end pair, with the end pushed past 1440 when it wraps —
|
|
6
|
+
* so an overnight stretch stays one interval rather than two that cross zero. */
|
|
7
|
+
export declare function spanOf(start: string, end: string): [number, number];
|
|
8
|
+
/** 12-hour clock for prose — the sheet and the popovers read as sentences, and "16:00" in the
|
|
9
|
+
* middle of one does not. */
|
|
10
|
+
export declare function t12(hhmm: string): string;
|
|
11
|
+
/** The timeline's two end labels — "8am", "10:30pm", meridiem spelled out. */
|
|
12
|
+
export declare function minToShort(m: number): string;
|
|
13
|
+
export declare function rangeText(from: number, to: number): string;
|
|
14
|
+
export declare function roleTotalOf(p: DemandPeriod): number;
|
|
15
|
+
/** The unnamed part of a period's headcount. Derived, never typed — so it cannot disagree with
|
|
16
|
+
* the total above it. Negative means the breakdown has overrun that total. */
|
|
17
|
+
export declare function anyLeftOf(p: DemandPeriod): number;
|
|
18
|
+
export interface ScheduleCoverageAxis {
|
|
19
|
+
from: number;
|
|
20
|
+
to: number;
|
|
21
|
+
}
|
|
22
|
+
/** Staffing demand, and coverage read against it.
|
|
23
|
+
*
|
|
24
|
+
* Storage follows this board's dayNotes rather than the mockup's flat `di` index: the mockup
|
|
25
|
+
* renders one long horizon so a day index identifies a date, but this board pages through
|
|
26
|
+
* weeks, and demand put on this Monday must not reappear on every other Monday. So a date's
|
|
27
|
+
* own demand is keyed by ISO date, and a standing weekday rule is keyed by weekday index.
|
|
28
|
+
*
|
|
29
|
+
* A date's own demand wins over the weekday rule it would otherwise inherit — "every Tuesday
|
|
30
|
+
* needs eight" is a standing statement, and "this Tuesday is different" has to be able to
|
|
31
|
+
* override it without rewriting the rule. */
|
|
32
|
+
export declare function useScheduleDemand(board: ScheduleBoardApi): {
|
|
33
|
+
byDate: Record<string, DemandPeriod[]>;
|
|
34
|
+
byWeekday: Record<number, DemandPeriod[]>;
|
|
35
|
+
demandFor: (dayIdx: number) => DemandPeriod[];
|
|
36
|
+
hasDemandOn: (dayIdx: number) => boolean;
|
|
37
|
+
demandIsOwn: (dayIdx: number) => boolean;
|
|
38
|
+
setDateDemand: (dayIdx: number, periods: DemandPeriod[]) => void;
|
|
39
|
+
clearDateDemand: (dayIdx: number) => void;
|
|
40
|
+
setWeekdayDemand: (weekday: number, periods: DemandPeriod[]) => void;
|
|
41
|
+
coverageAxis: (dayIdx: number) => ScheduleCoverageAxis;
|
|
42
|
+
coverageSegments: (dayIdx: number) => CoverageSegment[];
|
|
43
|
+
setPreview: (items: Proposal[]) => void;
|
|
44
|
+
segmentsWith: (dayIdx: number, employees: Employee[]) => CoverageSegment[];
|
|
45
|
+
dayHeadcount: (dayIdx: number) => {
|
|
46
|
+
crew: number;
|
|
47
|
+
peak: number;
|
|
48
|
+
};
|
|
49
|
+
coverageImpact: (dayIdx: number, empId: number | null, slot: DaySlot) => {
|
|
50
|
+
when: string;
|
|
51
|
+
pctBefore: number;
|
|
52
|
+
pctAfter: number;
|
|
53
|
+
stillShort: number;
|
|
54
|
+
before: {
|
|
55
|
+
required: number;
|
|
56
|
+
scheduled: number;
|
|
57
|
+
};
|
|
58
|
+
after: {
|
|
59
|
+
required: number;
|
|
60
|
+
scheduled: number;
|
|
61
|
+
};
|
|
62
|
+
beforeSegs: CoverageSegment[];
|
|
63
|
+
afterSegs: CoverageSegment[];
|
|
64
|
+
axis: ScheduleCoverageAxis;
|
|
65
|
+
} | null;
|
|
66
|
+
coveragePct: (dayIdx: number) => number | null;
|
|
67
|
+
shortSegs: (dayIdx: number) => CoverageSegment[];
|
|
68
|
+
shortInRange: (dayIdx: number, start: string, end: string) => number;
|
|
69
|
+
biggestGap: (dayIdx: number) => CoverageSegment | null;
|
|
70
|
+
rangeSummary: import("vue").ComputedRef<{
|
|
71
|
+
live: number;
|
|
72
|
+
set: number;
|
|
73
|
+
shortDays: number;
|
|
74
|
+
}>;
|
|
75
|
+
};
|
|
76
|
+
export type ScheduleDemandApi = ReturnType<typeof useScheduleDemand>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
import type { ScheduleDemandApi } from './useScheduleDemand';
|
|
3
|
+
export type ScheduleSegState = 'met' | 'short' | 'over' | 'nodem';
|
|
4
|
+
export interface ScheduleDemandSeg {
|
|
5
|
+
key: string;
|
|
6
|
+
from: number;
|
|
7
|
+
to: number;
|
|
8
|
+
state: ScheduleSegState;
|
|
9
|
+
/** Percentage of the day's axis this segment occupies — width means duration. */
|
|
10
|
+
width: string;
|
|
11
|
+
label: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ScheduleDemandCell {
|
|
14
|
+
dayIdx: number;
|
|
15
|
+
closed: boolean;
|
|
16
|
+
/** No demand stated on this day — the cell carries its own "+ Set demand" instead. */
|
|
17
|
+
blank: boolean;
|
|
18
|
+
pct: number;
|
|
19
|
+
tone: '' | 'part' | 'short';
|
|
20
|
+
segs: ScheduleDemandSeg[];
|
|
21
|
+
hoursFrom: string;
|
|
22
|
+
hoursTo: string;
|
|
23
|
+
pctTitle: string;
|
|
24
|
+
title: string;
|
|
25
|
+
}
|
|
26
|
+
/** What the coverage band draws, one cell per visible day.
|
|
27
|
+
*
|
|
28
|
+
* The percentage is the headline and the strip is the reason — a day can be 81% covered with
|
|
29
|
+
* the missing fifth spread thinly or concentrated at six o'clock, and only one of those is a
|
|
30
|
+
* problem you act on tonight. */
|
|
31
|
+
export declare function useScheduleDemandRow(board: ScheduleBoardApi, demand: ScheduleDemandApi): {
|
|
32
|
+
cellFor: (dayIdx: number) => ScheduleDemandCell;
|
|
33
|
+
cells: import("vue").ComputedRef<{
|
|
34
|
+
dayIdx: number;
|
|
35
|
+
colIndex: number;
|
|
36
|
+
cell: ScheduleDemandCell;
|
|
37
|
+
}[]>;
|
|
38
|
+
lead: import("vue").ComputedRef<{
|
|
39
|
+
blank: boolean;
|
|
40
|
+
name: string;
|
|
41
|
+
meta: string;
|
|
42
|
+
}>;
|
|
43
|
+
dayTitle: (dayIdx: number) => string;
|
|
44
|
+
};
|
|
45
|
+
export type ScheduleDemandRowApi = ReturnType<typeof useScheduleDemandRow>;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { DemandApplyMode, DemandPeriod } from '../types';
|
|
2
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
3
|
+
import type { ScheduleDemandApi } from './useScheduleDemand';
|
|
4
|
+
export interface ScheduleDemandSuggestion {
|
|
5
|
+
why: string;
|
|
6
|
+
periods: DemandPeriod[];
|
|
7
|
+
}
|
|
8
|
+
export interface ScheduleDemandSheetOptions {
|
|
9
|
+
onToast?: (message: string) => void;
|
|
10
|
+
/** Positions the breakdown can name — the same list the shift editor offers. */
|
|
11
|
+
positionOptions: () => string[];
|
|
12
|
+
/** Called instead of a toast when "+ Position breakdown" is pressed and there is no position
|
|
13
|
+
* to name yet — the page opens its Add Position popup for that period. */
|
|
14
|
+
onNeedPosition?: (periodIdx: number, roleIdx: number) => void;
|
|
15
|
+
}
|
|
16
|
+
/** The demand sheet — editing happens on a DRAFT, so Save is a real commit and closing is a
|
|
17
|
+
* real cancel. The sheet also carries the recurrence choice, because "every Tuesday" is a
|
|
18
|
+
* property of the statement being made rather than a second screen. */
|
|
19
|
+
export declare function useScheduleDemandSheet(board: ScheduleBoardApi, demand: ScheduleDemandApi, opts: ScheduleDemandSheetOptions): {
|
|
20
|
+
open: import("vue").Ref<boolean, boolean>;
|
|
21
|
+
dayIdx: import("vue").Ref<number | null, number | null>;
|
|
22
|
+
periods: import("vue").Ref<{
|
|
23
|
+
from: string;
|
|
24
|
+
to: string;
|
|
25
|
+
n: number;
|
|
26
|
+
roles?: {
|
|
27
|
+
position: string;
|
|
28
|
+
n: number;
|
|
29
|
+
}[] | undefined;
|
|
30
|
+
}[], DemandPeriod[] | {
|
|
31
|
+
from: string;
|
|
32
|
+
to: string;
|
|
33
|
+
n: number;
|
|
34
|
+
roles?: {
|
|
35
|
+
position: string;
|
|
36
|
+
n: number;
|
|
37
|
+
}[] | undefined;
|
|
38
|
+
}[]>;
|
|
39
|
+
apply: import("vue").Ref<DemandApplyMode, DemandApplyMode>;
|
|
40
|
+
applyOptions: import("vue").ComputedRef<({
|
|
41
|
+
on: boolean;
|
|
42
|
+
key: "day";
|
|
43
|
+
label: string;
|
|
44
|
+
sub: string;
|
|
45
|
+
} | {
|
|
46
|
+
on: boolean;
|
|
47
|
+
key: "every";
|
|
48
|
+
label: string;
|
|
49
|
+
sub: string;
|
|
50
|
+
} | {
|
|
51
|
+
on: boolean;
|
|
52
|
+
key: "weekdays";
|
|
53
|
+
label: string;
|
|
54
|
+
sub: string;
|
|
55
|
+
} | {
|
|
56
|
+
on: boolean;
|
|
57
|
+
key: "custom";
|
|
58
|
+
label: string;
|
|
59
|
+
sub: string;
|
|
60
|
+
})[]>;
|
|
61
|
+
weekdayButtons: import("vue").ComputedRef<{
|
|
62
|
+
i: number;
|
|
63
|
+
label: string;
|
|
64
|
+
on: boolean;
|
|
65
|
+
}[]>;
|
|
66
|
+
toggleCustomDay: (i: number) => void;
|
|
67
|
+
applyNote: import("vue").ComputedRef<string>;
|
|
68
|
+
overlapWarning: import("vue").ComputedRef<string>;
|
|
69
|
+
whenLabel: import("vue").ComputedRef<string>;
|
|
70
|
+
openFor: (idx: number) => void;
|
|
71
|
+
close: () => void;
|
|
72
|
+
addPeriod: () => void;
|
|
73
|
+
removePeriod: (i: number) => void;
|
|
74
|
+
setHeads: (i: number, value: number | string) => void;
|
|
75
|
+
addRole: (i: number) => void;
|
|
76
|
+
addRoleNamed: (i: number, position: string) => void;
|
|
77
|
+
requestNewPosition: (i: number, k: number) => void;
|
|
78
|
+
removeRole: (i: number, k: number) => void;
|
|
79
|
+
setRoleCount: (i: number, k: number, value: number | string) => void;
|
|
80
|
+
setRolePosition: (i: number, k: number, position: string) => void;
|
|
81
|
+
anyLeft: (p: DemandPeriod) => number;
|
|
82
|
+
coverageRows: import("vue").ComputedRef<{
|
|
83
|
+
when: string;
|
|
84
|
+
required: number;
|
|
85
|
+
scheduled: number;
|
|
86
|
+
varies: boolean;
|
|
87
|
+
pct: number;
|
|
88
|
+
tone: "short" | "part" | "met" | "over";
|
|
89
|
+
note: string;
|
|
90
|
+
}[]>;
|
|
91
|
+
coverageTotal: import("vue").ComputedRef<{
|
|
92
|
+
required: number;
|
|
93
|
+
scheduled: number;
|
|
94
|
+
pct: number;
|
|
95
|
+
tone: "short" | "part" | "met" | "over";
|
|
96
|
+
note: string;
|
|
97
|
+
}>;
|
|
98
|
+
saving: import("vue").Ref<boolean, boolean>;
|
|
99
|
+
save: () => Promise<void>;
|
|
100
|
+
suggestion: import("vue").Ref<{
|
|
101
|
+
why: string;
|
|
102
|
+
periods: {
|
|
103
|
+
from: string;
|
|
104
|
+
to: string;
|
|
105
|
+
n: number;
|
|
106
|
+
roles?: {
|
|
107
|
+
position: string;
|
|
108
|
+
n: number;
|
|
109
|
+
}[] | undefined;
|
|
110
|
+
}[];
|
|
111
|
+
} | null, ScheduleDemandSuggestion | {
|
|
112
|
+
why: string;
|
|
113
|
+
periods: {
|
|
114
|
+
from: string;
|
|
115
|
+
to: string;
|
|
116
|
+
n: number;
|
|
117
|
+
roles?: {
|
|
118
|
+
position: string;
|
|
119
|
+
n: number;
|
|
120
|
+
}[] | undefined;
|
|
121
|
+
}[];
|
|
122
|
+
} | null>;
|
|
123
|
+
suggestionRows: import("vue").ComputedRef<{
|
|
124
|
+
when: string;
|
|
125
|
+
n: number;
|
|
126
|
+
word: string;
|
|
127
|
+
}[]>;
|
|
128
|
+
suggest: () => void;
|
|
129
|
+
acceptSuggestion: () => void;
|
|
130
|
+
dismissSuggestion: () => void;
|
|
131
|
+
canCopy: import("vue").ComputedRef<boolean>;
|
|
132
|
+
copyOpen: import("vue").Ref<boolean, boolean>;
|
|
133
|
+
copyPicks: Record<number, boolean>;
|
|
134
|
+
copyRows: import("vue").ComputedRef<{
|
|
135
|
+
dayIdx: number;
|
|
136
|
+
label: string;
|
|
137
|
+
sub: string;
|
|
138
|
+
}[]>;
|
|
139
|
+
copySub: import("vue").ComputedRef<string>;
|
|
140
|
+
openCopy: () => void;
|
|
141
|
+
closeCopy: () => void;
|
|
142
|
+
confirmCopy: () => Promise<void>;
|
|
143
|
+
setApply: (k: DemandApplyMode) => DemandApplyMode;
|
|
144
|
+
};
|
|
145
|
+
export type ScheduleDemandSheetApi = ReturnType<typeof useScheduleDemandSheet>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
export interface ScheduleDragPayload {
|
|
3
|
+
empId: number;
|
|
4
|
+
dayIdx: number;
|
|
5
|
+
}
|
|
6
|
+
/** Native HTML5 drag & drop for moving an existing shift card between employee/day cells.
|
|
7
|
+
* The mockup's other drag source — a staff-rail row dragged onto an open shift — is an
|
|
8
|
+
* area-view feature (`r.draggable = viewMode === 'area'` there); this board is employee-view
|
|
9
|
+
* only, so that gesture doesn't exist here — filling an open shift goes through the Assign
|
|
10
|
+
* popover (click) instead. */
|
|
11
|
+
export declare function useScheduleDragDrop(board: ScheduleBoardApi): {
|
|
12
|
+
dragging: import("vue").Ref<{
|
|
13
|
+
empId: number;
|
|
14
|
+
dayIdx: number;
|
|
15
|
+
} | null, ScheduleDragPayload | {
|
|
16
|
+
empId: number;
|
|
17
|
+
dayIdx: number;
|
|
18
|
+
} | null>;
|
|
19
|
+
startShiftDrag: (empId: number, dayIdx: number, ev: DragEvent) => void;
|
|
20
|
+
endDrag: () => void;
|
|
21
|
+
dropOnCell: (targetEmpId: number, targetDayIdx: number) => void;
|
|
22
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Employee, Proposal } from '../types';
|
|
2
|
+
/** The one form every SMALL avatar wears — `.sc-av`, `.ch-av`, `.ap-av`, `.tl-av`, and the
|
|
3
|
+
* shift editor's `.sp2-who-av`. A tint of the person's colour behind their own colour, never a
|
|
4
|
+
* solid fill with white text: at 17–30px the initials are the only identifier, and knocking
|
|
5
|
+
* them out to white on a saturated disc costs the contrast that makes them legible.
|
|
6
|
+
*
|
|
7
|
+
* None of those classes declare a background of their own, so they REQUIRE this — a bare
|
|
8
|
+
* `<span class="sc-av">` renders as an invisible disc.
|
|
9
|
+
*
|
|
10
|
+
* The big identity avatars are the opposite case and take no inline style at all: `.emp-avatar`,
|
|
11
|
+
* `.dp-emp-av` and `.pub-change-av` are neutral in CSS, because a name sits right beside them
|
|
12
|
+
* and a filled disc would out-shout it. */
|
|
13
|
+
export declare function avatarTint(color?: string | null): Record<string, string>;
|
|
14
|
+
export interface ScheduleEmployeeLoad {
|
|
15
|
+
emp: Employee;
|
|
16
|
+
hours: number;
|
|
17
|
+
cost: number;
|
|
18
|
+
contract: number;
|
|
19
|
+
partTime: boolean;
|
|
20
|
+
/** Hours as a fraction of contract, capped at 1 — the load bar's width. */
|
|
21
|
+
pct: number;
|
|
22
|
+
barColor: string;
|
|
23
|
+
otHours: number;
|
|
24
|
+
/** Of `hours`, how many are auto-schedule suggestions not yet on the board. */
|
|
25
|
+
proposedHours: number;
|
|
26
|
+
/** The board's own hours as a fraction of contract: where the fill ends and the suggested part starts. */
|
|
27
|
+
boardPct: number;
|
|
28
|
+
/** The suggested part's width on the bar, as a fraction of contract. With no contract to measure
|
|
29
|
+
* against it fills the track, so suggested hours still show. */
|
|
30
|
+
proposedPct: number;
|
|
31
|
+
}
|
|
32
|
+
/** This person's live (not rejected) suggestions in the week on screen. */
|
|
33
|
+
export declare function proposedSlotsOf(emp: Employee, proposalAt?: (empId: number, dayIdx: number) => Proposal | undefined): Pick<Proposal, 'start' | 'end'>[];
|
|
34
|
+
/** One person's load against their contract, derived from the shifts actually on the board
|
|
35
|
+
* rather than from the stored `weekHours` field, so the bar can never disagree with the row
|
|
36
|
+
* of cards beside it.
|
|
37
|
+
*
|
|
38
|
+
* The staff rail (area view) and the grid's name column (employee view) are the same list of
|
|
39
|
+
* the same people; they used to be two pieces of markup reading two different numbers. This
|
|
40
|
+
* is the single one — the mockup's own note on empIdentityHTML(). */
|
|
41
|
+
export declare function employeeLoadOf(emp: Employee, proposed?: Pick<Proposal, 'start' | 'end'>[]): ScheduleEmployeeLoad;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
import type { ScheduleAnchorRect } from './schedule-popover-position';
|
|
3
|
+
export type ScheduleEmployeeMenuAction = 'profile' | 'edit' | 'hl' | 'remove';
|
|
4
|
+
export interface ScheduleEmployeeMenuState {
|
|
5
|
+
open: boolean;
|
|
6
|
+
empId: number | null;
|
|
7
|
+
anchor: ScheduleAnchorRect | null;
|
|
8
|
+
left: number;
|
|
9
|
+
top: number;
|
|
10
|
+
}
|
|
11
|
+
/** The ⋯ menu on a team member's row — V6.2's #empMenu: profile, update, highlight, remove. The actions that need a page-level surface (profile panel,
|
|
12
|
+
* edit wizard, confirm dialog) come in as handlers; highlight lives here. */
|
|
13
|
+
export declare function useScheduleEmployeeMenu(board: ScheduleBoardApi, handlers: {
|
|
14
|
+
onProfile: (empId: number) => void;
|
|
15
|
+
onEdit: (empId: number) => void;
|
|
16
|
+
onRemove: (empId: number) => void;
|
|
17
|
+
}): {
|
|
18
|
+
state: {
|
|
19
|
+
open: boolean;
|
|
20
|
+
empId: number | null;
|
|
21
|
+
anchor: {
|
|
22
|
+
left: number;
|
|
23
|
+
right: number;
|
|
24
|
+
top: number;
|
|
25
|
+
bottom: number;
|
|
26
|
+
} | null;
|
|
27
|
+
left: number;
|
|
28
|
+
top: number;
|
|
29
|
+
};
|
|
30
|
+
employee: import("vue").ComputedRef<import("../types").Employee | undefined>;
|
|
31
|
+
openFor: (empId: number, anchor: HTMLElement) => void;
|
|
32
|
+
close: () => void;
|
|
33
|
+
go: (action: ScheduleEmployeeMenuAction) => void;
|
|
34
|
+
};
|
|
35
|
+
export type ScheduleEmployeeMenuApi = ReturnType<typeof useScheduleEmployeeMenu>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
export interface ScheduleEmployeeProfileState {
|
|
3
|
+
open: boolean;
|
|
4
|
+
empId: number | null;
|
|
5
|
+
}
|
|
6
|
+
/** Employee profile side sheet — opened from the staff-rail row menu or by clicking
|
|
7
|
+
* an employee's identity block. */
|
|
8
|
+
export declare function useScheduleEmployeeProfile(board: ScheduleBoardApi): {
|
|
9
|
+
state: {
|
|
10
|
+
open: boolean;
|
|
11
|
+
empId: number | null;
|
|
12
|
+
};
|
|
13
|
+
employee: import("vue").ComputedRef<import("../types").Employee | null>;
|
|
14
|
+
openFor: (empId: number) => void;
|
|
15
|
+
close: () => void;
|
|
16
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
export interface ExportShiftCell {
|
|
3
|
+
note: string;
|
|
4
|
+
shifts: {
|
|
5
|
+
when: string;
|
|
6
|
+
pos: string;
|
|
7
|
+
}[];
|
|
8
|
+
}
|
|
9
|
+
export interface ExportMatrix {
|
|
10
|
+
head: string[];
|
|
11
|
+
body: (string | ExportShiftCell)[][];
|
|
12
|
+
foot: string[];
|
|
13
|
+
}
|
|
14
|
+
/** The mockup's Share/export feature (buildExportMatrix/exportPDF/exportJPG) — no external
|
|
15
|
+
* PDF/canvas library anywhere in the mockup; PDF is an HTML preview handed to window.print(),
|
|
16
|
+
* JPG is a hand-drawn Canvas 2D table converted with toBlob. */
|
|
17
|
+
export declare function useScheduleExport(board: ScheduleBoardApi): {
|
|
18
|
+
buildExportMatrix: () => ExportMatrix;
|
|
19
|
+
pdfPreviewOpen: import("vue").Ref<boolean, boolean>;
|
|
20
|
+
pdfHtml: import("vue").ComputedRef<string>;
|
|
21
|
+
openPdfPreview: () => void;
|
|
22
|
+
closePdfPreview: () => void;
|
|
23
|
+
printNow: () => void;
|
|
24
|
+
exportJpg: () => void;
|
|
25
|
+
};
|
|
26
|
+
export type ScheduleExportApi = ReturnType<typeof useScheduleExport>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
export type ScheduleViewMode = 'area' | 'employee';
|
|
3
|
+
export type ScheduleGranularity = 'day' | 'week';
|
|
4
|
+
/** State for the filter-bar's mode/granularity selects. Granularity delegates straight to
|
|
5
|
+
* the board, which owns the day/week grid state — both area and employee grouping combine
|
|
6
|
+
* with either granularity. Outlet switching isn't modeled at all yet, so that control has
|
|
7
|
+
* no state here; it's a static label in the component. */
|
|
8
|
+
export declare function useScheduleFilterBar(board: ScheduleBoardApi): {
|
|
9
|
+
mode: import("vue").Ref<ScheduleViewMode, ScheduleViewMode>;
|
|
10
|
+
granularity: import("vue").Ref<import("./useScheduleBoard").ScheduleGranularity, import("./useScheduleBoard").ScheduleGranularity>;
|
|
11
|
+
setMode: (value: ScheduleViewMode) => boolean;
|
|
12
|
+
setGranularity: (value: ScheduleGranularity) => boolean;
|
|
13
|
+
};
|
|
14
|
+
export type ScheduleFilterBarApi = ReturnType<typeof useScheduleFilterBar>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { CoverageSegment } from '../types';
|
|
2
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
3
|
+
import type { ScheduleDemandApi } from './useScheduleDemand';
|
|
4
|
+
import type { ScheduleAssignApi } from './useScheduleAssign';
|
|
5
|
+
export interface ScheduleGapActions {
|
|
6
|
+
/** Open the shift editor on a brand new shift for this day and these hours. */
|
|
7
|
+
addShift: (dayIdx: number, position: string, start: string, end: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function useScheduleGapPopover(board: ScheduleBoardApi, demand: ScheduleDemandApi, assign: ScheduleAssignApi, actions: ScheduleGapActions): {
|
|
10
|
+
state: {
|
|
11
|
+
open: boolean;
|
|
12
|
+
pinned: boolean;
|
|
13
|
+
peek: boolean;
|
|
14
|
+
wide: boolean;
|
|
15
|
+
left: number;
|
|
16
|
+
top: number;
|
|
17
|
+
};
|
|
18
|
+
ctx: import("vue").Ref<{
|
|
19
|
+
from: number;
|
|
20
|
+
to: number;
|
|
21
|
+
required: number;
|
|
22
|
+
scheduled: number;
|
|
23
|
+
short: number;
|
|
24
|
+
over: number;
|
|
25
|
+
roles: {
|
|
26
|
+
position: string;
|
|
27
|
+
n: number;
|
|
28
|
+
required: number;
|
|
29
|
+
got: number;
|
|
30
|
+
short: number;
|
|
31
|
+
}[];
|
|
32
|
+
anyReq: number;
|
|
33
|
+
anyGot: number;
|
|
34
|
+
none: boolean;
|
|
35
|
+
dayIdx: number;
|
|
36
|
+
} | null, (CoverageSegment & {
|
|
37
|
+
dayIdx: number;
|
|
38
|
+
}) | {
|
|
39
|
+
from: number;
|
|
40
|
+
to: number;
|
|
41
|
+
required: number;
|
|
42
|
+
scheduled: number;
|
|
43
|
+
short: number;
|
|
44
|
+
over: number;
|
|
45
|
+
roles: {
|
|
46
|
+
position: string;
|
|
47
|
+
n: number;
|
|
48
|
+
required: number;
|
|
49
|
+
got: number;
|
|
50
|
+
short: number;
|
|
51
|
+
}[];
|
|
52
|
+
anyReq: number;
|
|
53
|
+
anyGot: number;
|
|
54
|
+
none: boolean;
|
|
55
|
+
dayIdx: number;
|
|
56
|
+
} | null>;
|
|
57
|
+
view: import("vue").ComputedRef<{
|
|
58
|
+
crew: number;
|
|
59
|
+
peak: number;
|
|
60
|
+
when: string;
|
|
61
|
+
day: string;
|
|
62
|
+
none: boolean;
|
|
63
|
+
required: number;
|
|
64
|
+
scheduled: number;
|
|
65
|
+
short: number;
|
|
66
|
+
over: number;
|
|
67
|
+
missing: {
|
|
68
|
+
short: number;
|
|
69
|
+
position: string;
|
|
70
|
+
}[];
|
|
71
|
+
missingNote: string;
|
|
72
|
+
} | null>;
|
|
73
|
+
segEnter: (dayIdx: number, from: number, to: number, anchor: HTMLElement) => void;
|
|
74
|
+
segLeave: () => void;
|
|
75
|
+
hold: () => void;
|
|
76
|
+
segClick: (dayIdx: number, from: number, to: number, anchor: HTMLElement) => void;
|
|
77
|
+
segFocus: (dayIdx: number, from: number, to: number, anchor: HTMLElement) => void;
|
|
78
|
+
addShift: () => void;
|
|
79
|
+
suggestStaffing: () => void;
|
|
80
|
+
close: () => void;
|
|
81
|
+
};
|
|
82
|
+
export type ScheduleGapPopoverApi = ReturnType<typeof useScheduleGapPopover>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { LeaveSlot } from '../types';
|
|
2
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
3
|
+
/** What a day off can be booked as. "Rest Day" leads: it is the most-used reason a day is not
|
|
4
|
+
* worked. */
|
|
5
|
+
export declare const LEAVE_REASONS: string[];
|
|
6
|
+
/** The type the menu's plain "Leave" row books. */
|
|
7
|
+
export declare const DEFAULT_LEAVE_REASON = "Annual Leave";
|
|
8
|
+
export type ScheduleLeaveMode = 'all' | 'am' | 'pm' | 'custom';
|
|
9
|
+
export interface ScheduleLeaveState {
|
|
10
|
+
open: boolean;
|
|
11
|
+
empId: number | null;
|
|
12
|
+
dayIdx: number | null;
|
|
13
|
+
/** Booking a new record, rather than editing one that is already on the day. */
|
|
14
|
+
isNew: boolean;
|
|
15
|
+
reason: string;
|
|
16
|
+
mode: ScheduleLeaveMode;
|
|
17
|
+
/** The hours when mode is 'custom'. */
|
|
18
|
+
from: string;
|
|
19
|
+
to: string;
|
|
20
|
+
}
|
|
21
|
+
/** The leave editor — V6.2's "Book leave" dialog: a reason, how much of the day it covers, and
|
|
22
|
+
* what that does to the person's availability. Opened from the add popup's Rest Day / Leave rows
|
|
23
|
+
* (booking) and from an existing leave card (editing, or approving a pending request). */
|
|
24
|
+
export declare function useScheduleLeave(board: ScheduleBoardApi): {
|
|
25
|
+
state: {
|
|
26
|
+
open: boolean;
|
|
27
|
+
empId: number | null;
|
|
28
|
+
dayIdx: number | null;
|
|
29
|
+
isNew: boolean;
|
|
30
|
+
reason: string;
|
|
31
|
+
mode: ScheduleLeaveMode;
|
|
32
|
+
from: string;
|
|
33
|
+
to: string;
|
|
34
|
+
};
|
|
35
|
+
employee: import("vue").ComputedRef<import("../types").Employee | undefined>;
|
|
36
|
+
activeSlot: import("vue").ComputedRef<LeaveSlot | null>;
|
|
37
|
+
options: import("vue").ComputedRef<({
|
|
38
|
+
hrs: string;
|
|
39
|
+
mode: "custom";
|
|
40
|
+
name: "Specific hours";
|
|
41
|
+
} | {
|
|
42
|
+
hrs: string;
|
|
43
|
+
mode: "all";
|
|
44
|
+
name: "All day";
|
|
45
|
+
} | {
|
|
46
|
+
hrs: string;
|
|
47
|
+
mode: "am";
|
|
48
|
+
name: "Morning";
|
|
49
|
+
} | {
|
|
50
|
+
hrs: string;
|
|
51
|
+
mode: "pm";
|
|
52
|
+
name: "Afternoon";
|
|
53
|
+
})[]>;
|
|
54
|
+
span: import("vue").ComputedRef<{
|
|
55
|
+
from: string;
|
|
56
|
+
to: string;
|
|
57
|
+
hours: number;
|
|
58
|
+
}>;
|
|
59
|
+
valid: import("vue").ComputedRef<boolean>;
|
|
60
|
+
dayLabel: import("vue").ComputedRef<string>;
|
|
61
|
+
hoursText: import("vue").ComputedRef<string>;
|
|
62
|
+
coverText: import("vue").ComputedRef<string>;
|
|
63
|
+
openFor: (empId: number, dayIdx: number, reason?: string | null) => void;
|
|
64
|
+
close: () => void;
|
|
65
|
+
save: () => void;
|
|
66
|
+
approve: () => void;
|
|
67
|
+
reject: () => void;
|
|
68
|
+
remove: () => void;
|
|
69
|
+
};
|
|
70
|
+
export type ScheduleLeaveApi = ReturnType<typeof useScheduleLeave>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
export interface ScheduleCoverageBadge {
|
|
3
|
+
position: string;
|
|
4
|
+
required: number;
|
|
5
|
+
scheduled: number;
|
|
6
|
+
short: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Coverage badges for a day's header card — required vs. scheduled headcount per
|
|
9
|
+
* position, from the single active shift template's coverage matrix. */
|
|
10
|
+
export declare function useScheduleLegend(board: ScheduleBoardApi): {
|
|
11
|
+
coveragePositions: import("vue").ComputedRef<string[]>;
|
|
12
|
+
coverageForDay: (dayIdx: number) => ScheduleCoverageBadge[];
|
|
13
|
+
dayIsShort: (dayIdx: number) => boolean;
|
|
14
|
+
dayCardTitle: (dayIdx: number) => string;
|
|
15
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
import type { ScheduleAreaBoardApi } from './useScheduleAreaBoard';
|
|
3
|
+
export type ScheduleLegendKey = 'empty' | 'draft' | 'pub' | 'open' | 'warn' | 'ot' | 'leave';
|
|
4
|
+
export interface ScheduleLegendItem {
|
|
5
|
+
key: ScheduleLegendKey;
|
|
6
|
+
count: number;
|
|
7
|
+
label: string;
|
|
8
|
+
/** The warnings figure is the one worth acting on, so it renders as a control that
|
|
9
|
+
* cycles the grid through each conflict — see jumpToConflict(). */
|
|
10
|
+
action: boolean;
|
|
11
|
+
title?: string;
|
|
12
|
+
}
|
|
13
|
+
interface ScheduleConflictRef {
|
|
14
|
+
empId: number;
|
|
15
|
+
dayIdx: number;
|
|
16
|
+
name: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ScheduleLegendBarOptions {
|
|
19
|
+
/** Toast for the conflict cycle — "Conflict 2 of 5 · Nadia, Wed". */
|
|
20
|
+
onJump?: (message: string) => void;
|
|
21
|
+
}
|
|
22
|
+
/** The footer legend under the scheduler: every state a card can be in, counted off the
|
|
23
|
+
* same records the grid renders. Ported from the mockup's renderLegend(). Every figure is
|
|
24
|
+
* scoped to the days currently on screen, except warnings — which counts the whole week, so
|
|
25
|
+
* the number stays stable while jumpToConflict() pages through days one at a time (the
|
|
26
|
+
* mockup's conflictCount() is likewise whole-data rather than span-scoped).
|
|
27
|
+
*
|
|
28
|
+
* Distinct from useScheduleLegend, which is the day header's coverage badges. */
|
|
29
|
+
export declare function useScheduleLegendBar(board: ScheduleBoardApi, areaBoard: ScheduleAreaBoardApi, opts?: ScheduleLegendBarOptions): {
|
|
30
|
+
items: import("vue").ComputedRef<ScheduleLegendItem[]>;
|
|
31
|
+
conflicts: import("vue").ComputedRef<ScheduleConflictRef[]>;
|
|
32
|
+
jumpToConflict: () => void;
|
|
33
|
+
};
|
|
34
|
+
export type ScheduleLegendBarApi = ReturnType<typeof useScheduleLegendBar>;
|
|
35
|
+
export {};
|