ud-components 0.5.21 → 0.5.23
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OnDestroy, TemplateRef } from '@angular/core';
|
|
2
|
-
import { CalendarMode, CalendarSlot, CalendarUser, CalendarView } from './calendar.interface';
|
|
2
|
+
import { CalendarMode, CalendarSlot, CalendarUser, CalendarView, RescheduleContext } from './calendar.interface';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export declare class CalendarComponent implements OnDestroy {
|
|
5
5
|
slots: import("@angular/core").InputSignal<CalendarSlot[]>;
|
|
@@ -20,10 +20,44 @@ export declare class CalendarComponent implements OnDestroy {
|
|
|
20
20
|
* free-text input.
|
|
21
21
|
*/
|
|
22
22
|
bookableUsers: import("@angular/core").InputSignal<CalendarUser[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Optional cutoff: any cell whose start is strictly before this Date is
|
|
25
|
+
* visually disabled (grey, no hover, no cursor) and click-blocked. The
|
|
26
|
+
* "Add slot" toolbar button pre-fills the modal with this timestamp
|
|
27
|
+
* (rounded up to the next `slotDuration` increment) instead of `new Date()`.
|
|
28
|
+
* The modal's save handler also refuses to emit if a hand-edited time
|
|
29
|
+
* lands before the cutoff. Applies to both admin and student modes.
|
|
30
|
+
*/
|
|
31
|
+
minSlotStart: import("@angular/core").InputSignal<Date | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Optional initial calendar position. Overrides the internal `navDate`
|
|
34
|
+
* which otherwise defaults to "today / now". Useful for reschedule flows
|
|
35
|
+
* or deep links that should land on a specific day.
|
|
36
|
+
*/
|
|
37
|
+
defaultDate: import("@angular/core").InputSignal<Date | null>;
|
|
38
|
+
/**
|
|
39
|
+
* When set, the "Add slot" modal flips into reschedule mode:
|
|
40
|
+
* • title becomes "Move appointment"
|
|
41
|
+
* • a lede shows the original time being moved away from
|
|
42
|
+
* • the user picker auto-selects the lone bookable user (or `userId` if
|
|
43
|
+
* provided) so the admin doesn't have to choose from a list of one
|
|
44
|
+
* • Booked defaults to true (a reschedule keeps a booking, not a fresh slot)
|
|
45
|
+
* • the confirm button reads "Reschedule" instead of "Save"
|
|
46
|
+
*
|
|
47
|
+
* The wire-level event is still `slotAdded` — consumers route it to their
|
|
48
|
+
* reschedule API based on their own context (no extra output needed).
|
|
49
|
+
*/
|
|
50
|
+
rescheduleContext: import("@angular/core").InputSignal<RescheduleContext | null>;
|
|
23
51
|
slotAdded: import("@angular/core").OutputEmitterRef<CalendarSlot>;
|
|
24
52
|
slotUpdated: import("@angular/core").OutputEmitterRef<CalendarSlot>;
|
|
25
53
|
slotRemoved: import("@angular/core").OutputEmitterRef<string>;
|
|
26
54
|
slotBooked: import("@angular/core").OutputEmitterRef<CalendarSlot>;
|
|
55
|
+
/** Fired when a user attempts to interact with a cell before `minSlotStart`. */
|
|
56
|
+
slotBlocked: import("@angular/core").OutputEmitterRef<{
|
|
57
|
+
start: Date;
|
|
58
|
+
end: Date;
|
|
59
|
+
reason: "before-min";
|
|
60
|
+
}>;
|
|
27
61
|
activeView: import("@angular/core").WritableSignal<CalendarView>;
|
|
28
62
|
navDate: import("@angular/core").WritableSignal<Date>;
|
|
29
63
|
readonly viewOptions: {
|
|
@@ -87,11 +121,26 @@ export declare class CalendarComponent implements OnDestroy {
|
|
|
87
121
|
slotTextColor(slot: CalendarSlot): string;
|
|
88
122
|
slotBorderColor(slot: CalendarSlot): string;
|
|
89
123
|
formatSlotTime(slot: CalendarSlot): string;
|
|
124
|
+
/**
|
|
125
|
+
* Pretty range like "Mon Jun 8 · 2:00 – 2:30 PM". Used by reschedule-mode's
|
|
126
|
+
* "Moving from …" lede so the admin sees where the appointment is coming
|
|
127
|
+
* from while picking the new time.
|
|
128
|
+
*/
|
|
129
|
+
private formatMomentRange;
|
|
90
130
|
isToday(day: Date): boolean;
|
|
91
131
|
isCurrentMonth(day: Date): boolean;
|
|
92
132
|
dayLabel(day: Date): string;
|
|
93
133
|
dayNum(day: Date): number;
|
|
94
134
|
onCellClick(day: Date, hour: number, minute: number): void;
|
|
135
|
+
/**
|
|
136
|
+
* True when the cell at (day, hour, minute) starts before `minSlotStart`.
|
|
137
|
+
* Templates bind a CSS class on this to grey out past cells; the click
|
|
138
|
+
* handler also bails so consumers don't see invalid `slotAdded` events.
|
|
139
|
+
*/
|
|
140
|
+
isCellDisabled(day: Date, hour: number, minute: number): boolean;
|
|
141
|
+
/** True when `day` is fully before `minSlotStart` (used by month view). */
|
|
142
|
+
isDayDisabled(day: Date): boolean;
|
|
143
|
+
private combineDayTime;
|
|
95
144
|
onSlotMouseDown(e: MouseEvent, slot: CalendarSlot): void;
|
|
96
145
|
onDocMouseMove(e: MouseEvent): void;
|
|
97
146
|
onDocMouseUp(e: MouseEvent): void;
|
|
@@ -102,6 +151,8 @@ export declare class CalendarComponent implements OnDestroy {
|
|
|
102
151
|
previewHeight(): number;
|
|
103
152
|
private getGridTarget;
|
|
104
153
|
openAddModal(day?: Date, hour?: number, minute?: number): void;
|
|
154
|
+
/** Round a Date up to the next `slotDuration` increment (minute-aligned). */
|
|
155
|
+
private roundUpToSlot;
|
|
105
156
|
openEditModal(slot: CalendarSlot): void;
|
|
106
157
|
private get slotFormErrors();
|
|
107
158
|
private slotTimeValidator;
|
|
@@ -116,5 +167,5 @@ export declare class CalendarComponent implements OnDestroy {
|
|
|
116
167
|
private formatTime;
|
|
117
168
|
private hexToRgba;
|
|
118
169
|
static ɵfac: i0.ɵɵFactoryDeclaration<CalendarComponent, never>;
|
|
119
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<CalendarComponent, "ud-calendar", never, { "slots": { "alias": "slots"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "defaultView": { "alias": "defaultView"; "required": false; "isSignal": true; }; "slotDuration": { "alias": "slotDuration"; "required": false; "isSignal": true; }; "minHour": { "alias": "minHour"; "required": false; "isSignal": true; }; "maxHour": { "alias": "maxHour"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "bookableUsers": { "alias": "bookableUsers"; "required": false; "isSignal": true; }; }, { "slotAdded": "slotAdded"; "slotUpdated": "slotUpdated"; "slotRemoved": "slotRemoved"; "slotBooked": "slotBooked"; }, never, never, true, never>;
|
|
170
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<CalendarComponent, "ud-calendar", never, { "slots": { "alias": "slots"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "defaultView": { "alias": "defaultView"; "required": false; "isSignal": true; }; "slotDuration": { "alias": "slotDuration"; "required": false; "isSignal": true; }; "minHour": { "alias": "minHour"; "required": false; "isSignal": true; }; "maxHour": { "alias": "maxHour"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "bookableUsers": { "alias": "bookableUsers"; "required": false; "isSignal": true; }; "minSlotStart": { "alias": "minSlotStart"; "required": false; "isSignal": true; }; "defaultDate": { "alias": "defaultDate"; "required": false; "isSignal": true; }; "rescheduleContext": { "alias": "rescheduleContext"; "required": false; "isSignal": true; }; }, { "slotAdded": "slotAdded"; "slotUpdated": "slotUpdated"; "slotRemoved": "slotRemoved"; "slotBooked": "slotBooked"; "slotBlocked": "slotBlocked"; }, never, never, true, never>;
|
|
120
171
|
}
|
|
@@ -19,6 +19,28 @@ export interface CalendarUser {
|
|
|
19
19
|
}
|
|
20
20
|
export type CalendarView = 'week' | 'month' | 'day';
|
|
21
21
|
export type CalendarMode = 'admin' | 'student' | 'readonly';
|
|
22
|
+
/**
|
|
23
|
+
* Context the host supplies when the calendar should be used to *move* an
|
|
24
|
+
* existing booking instead of creating a new one. When set on
|
|
25
|
+
* `<ud-calendar [rescheduleContext]>`, the add-slot modal flips into
|
|
26
|
+
* "move appointment" mode (title, lede, save label, defaults).
|
|
27
|
+
*
|
|
28
|
+
* The component does not call any reschedule API itself — it still emits
|
|
29
|
+
* `slotAdded` with the picked slot and the host decides whether to POST a
|
|
30
|
+
* new booking or PUT a reschedule.
|
|
31
|
+
*/
|
|
32
|
+
export interface RescheduleContext {
|
|
33
|
+
/** The current appointment's start, used in the modal's "Moving from …" lede. */
|
|
34
|
+
originalStart: Date;
|
|
35
|
+
/** The current appointment's end — paired with `originalStart` for the label. */
|
|
36
|
+
originalEnd: Date;
|
|
37
|
+
/**
|
|
38
|
+
* Optional id of the user the appointment belongs to. When provided, the
|
|
39
|
+
* add-slot modal pre-selects this user in the `bookableUsers` picker so the
|
|
40
|
+
* admin doesn't have to choose from a list of one.
|
|
41
|
+
*/
|
|
42
|
+
userId?: string;
|
|
43
|
+
}
|
|
22
44
|
/**
|
|
23
45
|
* Curated slot colours. Assign one to `CalendarSlot.color` for a consistent,
|
|
24
46
|
* on-brand palette instead of hand-picking hex values — the calendar tints these
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ud-components",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.23",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/cdk": ">=19",
|
|
6
6
|
"@angular/common": ">=19",
|
|
@@ -21,30 +21,6 @@
|
|
|
21
21
|
".": {
|
|
22
22
|
"types": "./index.d.ts",
|
|
23
23
|
"default": "./fesm2022/ud-components.mjs"
|
|
24
|
-
},
|
|
25
|
-
"./enums/role.enum": {
|
|
26
|
-
"types": "./enums/role.enum.d.ts",
|
|
27
|
-
"default": "./enums/role.enum.js"
|
|
28
|
-
},
|
|
29
|
-
"./lib/kpi/kpi.enum": {
|
|
30
|
-
"types": "./lib/kpi/kpi.enum.d.ts",
|
|
31
|
-
"default": "./lib/kpi/kpi.enum.js"
|
|
32
|
-
},
|
|
33
|
-
"./lib/edit-view/edit-view-section.directive": {
|
|
34
|
-
"types": "./lib/edit-view/edit-view-section.directive.d.ts",
|
|
35
|
-
"default": "./lib/edit-view/edit-view-section.directive.js"
|
|
36
|
-
},
|
|
37
|
-
"./interfaces/page-request.interface": {
|
|
38
|
-
"types": "./interfaces/page-request.interface.d.ts",
|
|
39
|
-
"default": "./interfaces/page-request.interface.js"
|
|
40
|
-
},
|
|
41
|
-
"./interfaces/table.interface": {
|
|
42
|
-
"types": "./interfaces/table.interface.d.ts",
|
|
43
|
-
"default": "./interfaces/table.interface.js"
|
|
44
|
-
},
|
|
45
|
-
"./interfaces/table-display-column.interface": {
|
|
46
|
-
"types": "./interfaces/table-display-column.interface.d.ts",
|
|
47
|
-
"default": "./interfaces/table-display-column.interface.js"
|
|
48
24
|
}
|
|
49
25
|
}
|
|
50
|
-
}
|
|
26
|
+
}
|