@feedmepos/mf-hrm-portal 2.2.5-dev → 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-DgcWZ3SZ.js → ApprovalCodeList-BsDMMSIz.js} +4 -4
- package/dist/{AuditLogList-vWKMMGvd.js → AuditLogList-CGNZdtmn.js} +18 -17
- package/dist/{ConditionBuilderForm.vue_vue_type_script_setup_true_lang-DuhXogXK.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-BAW0C1bA.js → GrantUserList-Bd0lXmFo.js} +5 -5
- package/dist/{Main-NzpdRNB3.js → Main-B66lSeOv.js} +5 -5
- package/dist/{Main-Wr6cTqfM.js → Main-CzHSNHsH.js} +2 -2
- package/dist/{Main-B7Nn8CLQ.js → Main-njRQ1tFk.js} +9 -9
- package/dist/PasscodePinField.vue_vue_type_script_setup_true_lang-CqG0v0Sz.js +243 -0
- package/dist/{PermissionSetList-D6AFOleD.js → PermissionSetList-GTI6Cwj5.js} +18 -18
- package/dist/{PortalPermissionEditor.vue_vue_type_script_setup_true_lang-Bzq2_BMn.js → PortalPermissionEditor.vue_vue_type_script_setup_true_lang-C-QEQ-js.js} +1052 -1052
- package/dist/{RoleList-BuqpmXn_.js → RoleList-CmHgtM0m.js} +7 -7
- 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-B5FyVyCz.js → TimesheetList-Dv0-W--W.js} +54 -53
- package/dist/{TimesheetList.vue_vue_type_style_index_0_scoped_63294af2_lang-C99Jr6Ax.js → TimesheetList.vue_vue_type_style_index_0_scoped_63294af2_lang-DIo6h5-a.js} +2 -2
- package/dist/_plugin-vue_export-helper-CHgC5LLL.js +9 -0
- package/dist/{app-8samJY5z.js → app-SCXGJ95F.js} +3146 -2553
- package/dist/app.js +1 -1
- package/dist/{dayjs.min-Ba4X_9nY.js → dayjs.min-DqMLPYv-.js} +1 -1
- package/dist/{employee-BcFgm8Rt.js → employee-DT_xYQkz.js} +3 -3
- package/dist/{iteration-Dhdew1jW.js → iteration-B5dB9ecy.js} +1 -1
- package/dist/{lodash-CJ3mHku0.js → lodash-CRHFapxI.js} +1 -1
- package/dist/{role-BViYS7RK.js → role-CJm8pXaw.js} +1 -1
- package/dist/{rule-Dxt1ZSQS.js → rule-AJm-eVzJ.js} +276 -272
- package/dist/src/api/schedule/index.d.ts +41 -0
- package/dist/src/components/form/OutletRoleAssignment.vue.d.ts +16 -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/router/shared.d.ts +4 -1
- package/dist/src/types/schedule.d.ts +232 -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/member/TeamMemberMasterUser.vue.d.ts +12 -3
- package/dist/style.css +1 -1
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/dist/{useReportPermissions-BiyAfGvZ.js → useReportPermissions-Cg3lV70m.js} +3 -3
- package/package.json +1 -1
- package/dist/EmployeeList-Cu4RxVQX.js +0 -889
- package/dist/PasscodePinField.vue_vue_type_script_setup_true_lang-BUI0Xsgc.js +0 -85
- package/dist/SelectFilter-ATOm0hdn.js +0 -269
- package/dist/TeamMemberList-M6HA9BWu.js +0 -1248
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
/** Column facts shared by the day header and every `.shift-cell` under it.
|
|
3
|
+
*
|
|
4
|
+
* The mockup builds these inline in its cell loop (`cell.className = 'shift-cell' + …`) and
|
|
5
|
+
* again in its header loop, which is exactly how the two drifted: closing a day painted the
|
|
6
|
+
* header and left the cells beneath it clean. One helper, both consumers.
|
|
7
|
+
*
|
|
8
|
+
* Two of the mockup's cell states are deliberately absent here:
|
|
9
|
+
* - `wk-off` — this board has no standing weekly-off pattern to read (same reason
|
|
10
|
+
* `otRateOn()` drops the mockup's rest-day case).
|
|
11
|
+
* - `peek` / `week-start` — the mockup renders a multi-week horizon, so it has columns
|
|
12
|
+
* outside the selected range and interior week boundaries. This board's visible range
|
|
13
|
+
* is exactly one week, so neither can ever fire.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isPastDate(date: Date): boolean;
|
|
16
|
+
export declare function isWeekendDate(date: Date): boolean;
|
|
17
|
+
/** Month-edge compares neighbours in the VISIBLE column order, not raw weekday
|
|
18
|
+
* index — a lone Daily-view column has no on-screen neighbour to differ from. */
|
|
19
|
+
export declare function isMonthEdgeAt(board: ScheduleBoardApi, colIndex: number): boolean;
|
|
20
|
+
export interface ScheduleCellState {
|
|
21
|
+
locked: boolean;
|
|
22
|
+
'closed-day': boolean;
|
|
23
|
+
'month-edge': boolean;
|
|
24
|
+
past: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** The class object for one grid cell in column `colIndex` (its weekday is `dayIdx`). */
|
|
27
|
+
export declare function cellStateClasses(board: ScheduleBoardApi, dayIdx: number, colIndex: number): ScheduleCellState;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ScheduleClashState {
|
|
2
|
+
open: boolean;
|
|
3
|
+
message: string;
|
|
4
|
+
onConfirm: (() => void) | null;
|
|
5
|
+
}
|
|
6
|
+
/** Generic Yes/No conflict-confirmation primitive — the mockup's `askClash`/clashModal,
|
|
7
|
+
* reused across several flows (leave clashes, overlapping shifts, etc). */
|
|
8
|
+
export declare function useScheduleClashDetection(): {
|
|
9
|
+
state: {
|
|
10
|
+
open: boolean;
|
|
11
|
+
message: string;
|
|
12
|
+
onConfirm: (() => void) | null;
|
|
13
|
+
};
|
|
14
|
+
ask: (message: string, onConfirm: () => void) => void;
|
|
15
|
+
confirm: () => void;
|
|
16
|
+
close: () => void;
|
|
17
|
+
};
|
|
18
|
+
export type ScheduleClashDetectionApi = ReturnType<typeof useScheduleClashDetection>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
export interface ScheduleCopySkipReport {
|
|
3
|
+
leave: number;
|
|
4
|
+
already: number;
|
|
5
|
+
hours: number;
|
|
6
|
+
full: number;
|
|
7
|
+
closed: number;
|
|
8
|
+
}
|
|
9
|
+
/** The mockup's Copy schedule feature (copyLastWeek/copyThisWeekForward), ported against this
|
|
10
|
+
* board's per-week-offset bucket cache instead of the mockup's absolute 91-day horizon. Split
|
|
11
|
+
* shifts (copyUnitsOf in the mockup) aren't ported — WorkSlot has no splitId concept in this
|
|
12
|
+
* data model, so each slot is copied as its own unit. */
|
|
13
|
+
export declare function useScheduleCopyWeek(board: ScheduleBoardApi, handlers?: {
|
|
14
|
+
onDemandChanged?: () => void;
|
|
15
|
+
}): {
|
|
16
|
+
copyLastWeek: (mode: "staffed" | "open") => Promise<void>;
|
|
17
|
+
copyThisWeekForward: (mode: "staffed" | "open") => Promise<void>;
|
|
18
|
+
};
|
|
19
|
+
export type ScheduleCopyWeekApi = ReturnType<typeof useScheduleCopyWeek>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
export declare function slotHours(start: string, end: string): number;
|
|
3
|
+
export interface ScheduleDayCost {
|
|
4
|
+
hours: number;
|
|
5
|
+
otHours: number;
|
|
6
|
+
base: number;
|
|
7
|
+
ot: number;
|
|
8
|
+
total: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SchedulePositionCost {
|
|
11
|
+
position: string;
|
|
12
|
+
base: number;
|
|
13
|
+
ot: number;
|
|
14
|
+
total: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ScheduleSectionCost {
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
base: number;
|
|
20
|
+
ot: number;
|
|
21
|
+
total: number;
|
|
22
|
+
rows: SchedulePositionCost[];
|
|
23
|
+
}
|
|
24
|
+
export interface ScheduleOtRisk {
|
|
25
|
+
empId: number;
|
|
26
|
+
name: string;
|
|
27
|
+
hours: number;
|
|
28
|
+
contract: number;
|
|
29
|
+
}
|
|
30
|
+
/** Weekly labour cost + monthly OT gauge for the collapsible cost rail, built off one
|
|
31
|
+
* per-day breakdown so the rail's totals and the stats row's per-day figures can never
|
|
32
|
+
* disagree about what a day cost. */
|
|
33
|
+
export declare function useScheduleCostRail(board: ScheduleBoardApi): {
|
|
34
|
+
collapsed: import("vue").Ref<boolean, boolean>;
|
|
35
|
+
byDay: import("vue").ComputedRef<ScheduleDayCost[]>;
|
|
36
|
+
weeklyCost: import("vue").ComputedRef<number>;
|
|
37
|
+
otHours: import("vue").ComputedRef<number>;
|
|
38
|
+
monthlyOtUsed: import("vue").ComputedRef<number>;
|
|
39
|
+
monthlyOtCapHours: number;
|
|
40
|
+
bySection: import("vue").ComputedRef<ScheduleSectionCost[]>;
|
|
41
|
+
otRisk: import("vue").ComputedRef<ScheduleOtRisk[]>;
|
|
42
|
+
};
|
|
43
|
+
export type ScheduleCostRailApi = ReturnType<typeof useScheduleCostRail>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
export interface ScheduleDayNoteState {
|
|
3
|
+
open: boolean;
|
|
4
|
+
dayIdx: number | null;
|
|
5
|
+
left: number;
|
|
6
|
+
top: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ScheduleDayNoteOptions {
|
|
9
|
+
/** Toasts for the writes that happen on the spot — closing a day, repricing it, saving. */
|
|
10
|
+
onToast?: (message: string) => void;
|
|
11
|
+
}
|
|
12
|
+
/** One decimal, always: "2×" reads as a count, and 1.5 beside a bare 2 in one sentence looks
|
|
13
|
+
* like two different kinds of number. Ported from the mockup's fmtRate(). */
|
|
14
|
+
export declare function fmtRate(rate: number): string;
|
|
15
|
+
/** The date card editor — opened by clicking a day card or its pencil. Everything on it is a
|
|
16
|
+
* fact about the DATE, applying to the whole column: a titled note, whether the venue opens,
|
|
17
|
+
* and whether the day bills at the holiday rate. Ported from the mockup's openDayNote() /
|
|
18
|
+
* saveDayNote() / dnToggleClosed() / dnToggleHoliday().
|
|
19
|
+
*
|
|
20
|
+
* The mockup re-renders the grid on the two toggles and rebuilds the popover from a stashed
|
|
21
|
+
* draft so half-typed text survives; Vue re-renders in place, so the draft just stays in the
|
|
22
|
+
* refs and there is nothing to stash. */
|
|
23
|
+
export declare function useScheduleDayNote(board: ScheduleBoardApi, opts?: ScheduleDayNoteOptions): {
|
|
24
|
+
state: {
|
|
25
|
+
open: boolean;
|
|
26
|
+
dayIdx: number | null;
|
|
27
|
+
left: number;
|
|
28
|
+
top: number;
|
|
29
|
+
};
|
|
30
|
+
dayIdx: import("vue").ComputedRef<number | null>;
|
|
31
|
+
title: import("vue").Ref<string, string>;
|
|
32
|
+
desc: import("vue").Ref<string, string>;
|
|
33
|
+
savedNote: import("vue").ComputedRef<import("../types").ScheduleDayNote | null>;
|
|
34
|
+
hasSaved: import("vue").ComputedRef<boolean>;
|
|
35
|
+
whenLabel: import("vue").ComputedRef<string>;
|
|
36
|
+
isClosed: import("vue").ComputedRef<boolean>;
|
|
37
|
+
isAuto: import("vue").ComputedRef<boolean>;
|
|
38
|
+
rateApplies: import("vue").ComputedRef<boolean>;
|
|
39
|
+
closedHint: import("vue").ComputedRef<"Nothing is required or rostered on this date." | "The venue does not open — this date only.">;
|
|
40
|
+
holidayHint: import("vue").ComputedRef<string>;
|
|
41
|
+
openFor: (dayIdx: number, anchor: HTMLElement) => void;
|
|
42
|
+
close: () => void;
|
|
43
|
+
toggleClosed: () => void;
|
|
44
|
+
toggleHoliday: () => void;
|
|
45
|
+
save: () => void;
|
|
46
|
+
remove: () => void;
|
|
47
|
+
};
|
|
48
|
+
export type ScheduleDayNoteApi = ReturnType<typeof useScheduleDayNote>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ScheduleBoardApi } from './useScheduleBoard';
|
|
2
|
+
import type { ScheduleRosterApi } from './useScheduleRoster';
|
|
3
|
+
import type { ScheduleAreaBoardApi } from './useScheduleAreaBoard';
|
|
4
|
+
declare function minToHHMM(m: number): string;
|
|
5
|
+
export interface ScheduleTimelineBar {
|
|
6
|
+
key: string;
|
|
7
|
+
left: number;
|
|
8
|
+
width: number;
|
|
9
|
+
cls: string;
|
|
10
|
+
label: string;
|
|
11
|
+
sub?: string;
|
|
12
|
+
title: string;
|
|
13
|
+
brk?: {
|
|
14
|
+
left: number;
|
|
15
|
+
width: number;
|
|
16
|
+
};
|
|
17
|
+
laneTop?: number;
|
|
18
|
+
laneHeight?: number;
|
|
19
|
+
onClick?: () => void;
|
|
20
|
+
}
|
|
21
|
+
export interface ScheduleTimelineRow {
|
|
22
|
+
key: string;
|
|
23
|
+
kind: 'open' | 'employee' | 'position';
|
|
24
|
+
swatchColor?: string;
|
|
25
|
+
swatchClass?: string;
|
|
26
|
+
avatarInitials?: string;
|
|
27
|
+
avatarColor?: string;
|
|
28
|
+
name: string;
|
|
29
|
+
sub: string;
|
|
30
|
+
bars: ScheduleTimelineBar[];
|
|
31
|
+
minHeight?: number;
|
|
32
|
+
emptyText?: string;
|
|
33
|
+
onTrackClick?: () => void;
|
|
34
|
+
}
|
|
35
|
+
export interface ScheduleHourCell {
|
|
36
|
+
m: number;
|
|
37
|
+
clock: string;
|
|
38
|
+
open: boolean;
|
|
39
|
+
state: '' | 'short' | 'met' | 'over';
|
|
40
|
+
barHeightPct: number;
|
|
41
|
+
title: string;
|
|
42
|
+
n: number;
|
|
43
|
+
}
|
|
44
|
+
export declare function useScheduleDayTimeline(board: ScheduleBoardApi, roster: ScheduleRosterApi, areaBoard: ScheduleAreaBoardApi, handlers: {
|
|
45
|
+
onAddShift: (empId: number, dayIdx: number) => void;
|
|
46
|
+
onEditShift: (empId: number, dayIdx: number) => void;
|
|
47
|
+
onEditLeave: (empId: number, dayIdx: number) => void;
|
|
48
|
+
onOpenAssign: (openId: number) => void;
|
|
49
|
+
onAddAreaShift: (dayIdx: number, position: string) => void;
|
|
50
|
+
}): {
|
|
51
|
+
dayIdx: import("vue").ComputedRef<number>;
|
|
52
|
+
axis: import("vue").ComputedRef<{
|
|
53
|
+
from: number;
|
|
54
|
+
to: number;
|
|
55
|
+
span: number;
|
|
56
|
+
}>;
|
|
57
|
+
hours: import("vue").ComputedRef<{
|
|
58
|
+
m: number;
|
|
59
|
+
clock: string;
|
|
60
|
+
}[]>;
|
|
61
|
+
isOpenHour: (m: number) => boolean;
|
|
62
|
+
openShiftsRow: import("vue").ComputedRef<ScheduleTimelineRow | null>;
|
|
63
|
+
employeeRows: import("vue").ComputedRef<ScheduleTimelineRow[]>;
|
|
64
|
+
positionTimelineRows: import("vue").ComputedRef<ScheduleTimelineRow[]>;
|
|
65
|
+
footer: import("vue").ComputedRef<{
|
|
66
|
+
cells: ScheduleHourCell[];
|
|
67
|
+
staffCount: number;
|
|
68
|
+
totalHours: number;
|
|
69
|
+
totalWages: number;
|
|
70
|
+
peakN: number;
|
|
71
|
+
lowN: number;
|
|
72
|
+
peakAt: number | undefined;
|
|
73
|
+
}>;
|
|
74
|
+
minToHHMM: typeof minToHHMM;
|
|
75
|
+
};
|
|
76
|
+
export type ScheduleDayTimelineApi = ReturnType<typeof useScheduleDayTimeline>;
|
|
77
|
+
export {};
|
|
@@ -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>;
|