courthive-components 2.0.0 → 3.0.0

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.
Files changed (31) hide show
  1. package/dist/components/{temporal-grid/controller/temporalGridControl.d.ts → availability-grid/controller/availabilityGridControl.d.ts} +21 -7
  2. package/dist/components/{temporal-grid → availability-grid}/engine/viewState.d.ts +1 -1
  3. package/dist/components/{temporal-grid → availability-grid}/index.d.ts +6 -6
  4. package/dist/components/{temporal-grid/ui/temporalGrid.d.ts → availability-grid/ui/availabilityGrid.d.ts} +11 -11
  5. package/dist/components/{temporal-grid → availability-grid}/ui/blockPopover.d.ts +15 -0
  6. package/dist/components/modal/mockParticipants.d.ts +1 -1
  7. package/dist/components/renderStructure/renderStructureMinimap.d.ts +7 -0
  8. package/dist/components/schedule-page/domain/activeStrip.d.ts +1 -1
  9. package/dist/components/schedule-page/index.d.ts +1 -1
  10. package/dist/components/schedule-page/types.d.ts +14 -0
  11. package/dist/components/schedule-page/ui/activeStrip.d.ts +23 -0
  12. package/dist/components/scheduling-profile/domain/validateProfile.d.ts +4 -3
  13. package/dist/components/scheduling-profile/index.d.ts +1 -1
  14. package/dist/components/scheduling-profile/types.d.ts +3 -3
  15. package/dist/courthive-components.css +1 -1
  16. package/dist/courthive-components.es.js +4789 -4669
  17. package/dist/courthive-components.umd.js +38 -38
  18. package/dist/index.d.ts +6 -4
  19. package/package.json +9 -9
  20. /package/dist/components/{temporal-grid → availability-grid}/controller/viewProjections.d.ts +0 -0
  21. /package/dist/components/{temporal-grid → availability-grid}/timeline/CourtTimeline.d.ts +0 -0
  22. /package/dist/components/{temporal-grid → availability-grid}/timeline/InteractionManager.d.ts +0 -0
  23. /package/dist/components/{temporal-grid → availability-grid}/timeline/ItemRenderer.d.ts +0 -0
  24. /package/dist/components/{temporal-grid → availability-grid}/timeline/RowLayout.d.ts +0 -0
  25. /package/dist/components/{temporal-grid → availability-grid}/timeline/TimeAxis.d.ts +0 -0
  26. /package/dist/components/{temporal-grid → availability-grid}/timeline/TimeScale.d.ts +0 -0
  27. /package/dist/components/{temporal-grid → availability-grid}/timeline/types.d.ts +0 -0
  28. /package/dist/components/{temporal-grid → availability-grid}/ui/courtAvailabilityModal.d.ts +0 -0
  29. /package/dist/components/{temporal-grid → availability-grid}/ui/modernTimePicker.d.ts +0 -0
  30. /package/dist/components/{temporal-grid → availability-grid}/ui/statsBar.d.ts +0 -0
  31. /package/dist/components/{temporal-grid → availability-grid}/ui/viewToolbar.d.ts +0 -0
@@ -1,12 +1,12 @@
1
1
  import { availability, AvailabilityEngine } from 'tods-competition-factory';
2
- import { TemporalViewState } from '../engine/viewState';
2
+ import { AvailabilityViewState } from '../engine/viewState';
3
3
  import { DEFAULT_COLOR_SCHEME, ResourceGroupingMode } from './viewProjections';
4
4
  import { BlockPopoverManager } from '../ui/blockPopover';
5
5
  import { CourtTimeline } from '../timeline/CourtTimeline';
6
6
  type BlockType = availability.BlockType;
7
7
  type CourtRef = availability.CourtRef;
8
8
  type DayId = availability.DayId;
9
- export interface TemporalGridControlConfig {
9
+ export interface AvailabilityGridControlConfig {
10
10
  /** Container element for the timeline */
11
11
  container: HTMLElement;
12
12
  /** Initial selected day */
@@ -43,8 +43,22 @@ export interface TemporalGridControlConfig {
43
43
  * native browser alert).
44
44
  */
45
45
  onConflict?: (conflicts: any[]) => void;
46
+ /**
47
+ * Optional callback rendered as a "Manage Registrations" menu item on
48
+ * the block popover for PRACTICE blocks. The argument carries the
49
+ * resolved block descriptor — consumers use it to open their practice-
50
+ * registration management surface (e.g. a cModal in TMX).
51
+ */
52
+ onManageRegistrations?: (args: {
53
+ blockId: string;
54
+ courtId: string;
55
+ venueId: string;
56
+ date: string;
57
+ startTime: string;
58
+ endTime: string;
59
+ }) => void;
46
60
  }
47
- export declare class TemporalGridControl {
61
+ export declare class AvailabilityGridControl {
48
62
  private readonly engine;
49
63
  private timeline;
50
64
  private readonly config;
@@ -57,7 +71,7 @@ export declare class TemporalGridControl {
57
71
  private currentView;
58
72
  private selectedCourts;
59
73
  private visibleCourts;
60
- constructor(engine: AvailabilityEngine, config: TemporalGridControlConfig);
74
+ constructor(engine: AvailabilityEngine, config: AvailabilityGridControlConfig);
61
75
  private initialize;
62
76
  /**
63
77
  * Ensure timeline exists. Defers creation to the next macro-task so the
@@ -143,8 +157,8 @@ export declare class TemporalGridControl {
143
157
  /** Get engine instance */
144
158
  getEngine(): AvailabilityEngine;
145
159
  /** Get view state (for external consumers to subscribe to view changes) */
146
- getViewState(): TemporalViewState;
160
+ getViewState(): AvailabilityViewState;
147
161
  }
148
- /** Create a temporal grid controller */
149
- export declare function createTemporalGridControl(engine: AvailabilityEngine, config: TemporalGridControlConfig): TemporalGridControl;
162
+ /** Create a availability grid controller */
163
+ export declare function createAvailabilityGridControl(engine: AvailabilityEngine, config: AvailabilityGridControlConfig): AvailabilityGridControl;
150
164
  export {};
@@ -12,7 +12,7 @@ export interface ViewChangeEvent {
12
12
  payload: Partial<ViewStateSnapshot>;
13
13
  }
14
14
  export type ViewChangeListener = (event: ViewChangeEvent) => void;
15
- export declare class TemporalViewState {
15
+ export declare class AvailabilityViewState {
16
16
  private selectedDay;
17
17
  private selectedVenue;
18
18
  private selectedCourt;
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Temporal Grid - Main Entry Point
2
+ * Availability Grid - Main Entry Point
3
3
  *
4
- * Engine modules re-exported from tods-competition-factory via `temporal` namespace.
4
+ * Engine modules re-exported from tods-competition-factory via `availability` namespace.
5
5
  * Controller, UI, and view state are local to courthive-components.
6
6
  */
7
- export { AvailabilityEngine, AvailabilityEngine as TemporalGridEngine, availability } from 'tods-competition-factory';
8
- export { TemporalViewState, type ViewChangeEvent, type ViewChangeListener, type ViewStateSnapshot } from './engine/viewState';
9
- export { createTemporalGridControl, TemporalGridControl, type TemporalGridControlConfig } from './controller/temporalGridControl';
7
+ export { AvailabilityEngine, AvailabilityEngine as AvailabilityGridEngine, availability } from 'tods-competition-factory';
8
+ export { AvailabilityViewState, type ViewChangeEvent, type ViewChangeListener, type ViewStateSnapshot } from './engine/viewState';
9
+ export { createAvailabilityGridControl, AvailabilityGridControl, type AvailabilityGridControlConfig } from './controller/availabilityGridControl';
10
10
  export { buildBlockEvents, buildCapacityVisualization, buildConflictEvents, buildEventsFromTimelines, buildVenueGroups, buildHiddenDates, buildResourcesFromTimelines, buildTimeSlotConfig, buildTimelineWindowConfig, DEFAULT_COLOR_SCHEME, filterEventsByTimeRange, filterResourcesByVenue, generateBlockPatternCSS, isBlockEvent, isConflictEvent, isSegmentEvent, parseBlockEventId, parseResourceId, sortResources, type BlockColorScheme, type CalendarEvent, type CalendarResource, type TimelineGroup, type TimelineItem, type ProjectionConfig, type ResourceGroupingMode } from './controller/viewProjections';
11
- export { createTemporalGrid, TemporalGrid, type TemporalGridCallbacks, type TemporalGridConfig, type TemporalGridLabels } from './ui/temporalGrid';
11
+ export { createAvailabilityGrid, AvailabilityGrid, type AvailabilityGridCallbacks, type AvailabilityGridConfig, type AvailabilityGridLabels } from './ui/availabilityGrid';
12
12
  export { ModernTimePicker, showModernTimePicker, type TimePickerConfig } from './ui/modernTimePicker';
13
13
  export { createBlockPopoverManager, type BlockPopoverManager, type BlockPopoverOptions, type EngineBlockPopoverOptions } from './ui/blockPopover';
14
14
  export { buildStatsBar, type StatsBarUpdate } from './ui/statsBar';
@@ -1,11 +1,11 @@
1
1
  import { AvailabilityEngine, availability } from 'tods-competition-factory';
2
- import { TemporalGridControl, TemporalGridControlConfig } from '../controller/temporalGridControl';
2
+ import { AvailabilityGridControl, AvailabilityGridControlConfig } from '../controller/availabilityGridControl';
3
3
  type DayId = availability.DayId;
4
4
  /**
5
- * i18n labels for the temporal grid component.
5
+ * i18n labels for the availability grid component.
6
6
  * All fields are optional — English defaults are used when omitted.
7
7
  */
8
- export interface TemporalGridLabels {
8
+ export interface AvailabilityGridLabels {
9
9
  view?: string;
10
10
  day1?: string;
11
11
  days3?: string;
@@ -19,13 +19,13 @@ export interface TemporalGridLabels {
19
19
  setDefaultAvailability?: string;
20
20
  saveToTournament?: string;
21
21
  }
22
- export interface TemporalGridCallbacks {
22
+ export interface AvailabilityGridCallbacks {
23
23
  /**
24
24
  * Called when dirty state changes (blocks/availability modified vs initial)
25
25
  */
26
26
  onDirtyChange?: (isDirty: boolean) => void;
27
27
  }
28
- export interface TemporalGridConfig extends Partial<TemporalGridControlConfig>, TemporalGridCallbacks {
28
+ export interface AvailabilityGridConfig extends Partial<AvailabilityGridControlConfig>, AvailabilityGridCallbacks {
29
29
  /**
30
30
  * Tournament record (TODS format)
31
31
  */
@@ -57,7 +57,7 @@ export interface TemporalGridConfig extends Partial<TemporalGridControlConfig>,
57
57
  /**
58
58
  * i18n labels
59
59
  */
60
- labels?: TemporalGridLabels;
60
+ labels?: AvailabilityGridLabels;
61
61
  /**
62
62
  * Language code for datepicker localization (e.g. 'en', 'fr', 'de')
63
63
  */
@@ -75,7 +75,7 @@ export interface TemporalGridConfig extends Partial<TemporalGridControlConfig>,
75
75
  */
76
76
  onMutationsApplied?: (mutations: any[]) => void;
77
77
  }
78
- export declare class TemporalGrid {
78
+ export declare class AvailabilityGrid {
79
79
  private engine;
80
80
  private control;
81
81
  private config;
@@ -89,7 +89,7 @@ export declare class TemporalGrid {
89
89
  private visibleCourts;
90
90
  private initialSnapshot;
91
91
  private isDirty;
92
- constructor(config: TemporalGridConfig);
92
+ constructor(config: AvailabilityGridConfig);
93
93
  /**
94
94
  * Render the component into a container
95
95
  */
@@ -132,7 +132,7 @@ export declare class TemporalGrid {
132
132
  /**
133
133
  * Get the controller instance
134
134
  */
135
- getControl(): TemporalGridControl | null;
135
+ getControl(): AvailabilityGridControl | null;
136
136
  /**
137
137
  * Set the selected day
138
138
  */
@@ -143,7 +143,7 @@ export declare class TemporalGrid {
143
143
  refresh(): void;
144
144
  }
145
145
  /**
146
- * Create and render a temporal grid
146
+ * Create and render a availability grid
147
147
  */
148
- export declare function createTemporalGrid(config: TemporalGridConfig, container: HTMLElement): TemporalGrid;
148
+ export declare function createAvailabilityGrid(config: AvailabilityGridConfig, container: HTMLElement): AvailabilityGrid;
149
149
  export {};
@@ -19,6 +19,21 @@ export interface EngineBlockPopoverOptions {
19
19
  engine: AvailabilityEngine;
20
20
  day: string;
21
21
  onBlockChanged: () => void;
22
+ /**
23
+ * Optional callback rendered as a "Manage Registrations" menu item for
24
+ * PRACTICE blocks. Provides the resolved block descriptor (courtId, date,
25
+ * sub-window times) so the consumer can resolve to its bookingId without
26
+ * a round trip — the factory derives bookingId from `${courtId}-${date}-${startTime}`
27
+ * when the booking lacks an explicit one.
28
+ */
29
+ onManageRegistrations?: (args: {
30
+ blockId: string;
31
+ courtId: string;
32
+ venueId: string;
33
+ date: string;
34
+ startTime: string;
35
+ endTime: string;
36
+ }) => void;
22
37
  }
23
38
  export interface BlockPopoverManager {
24
39
  show(target: HTMLElement, options: BlockPopoverOptions): void;
@@ -54,7 +54,7 @@ export interface MockParticipantsConfig {
54
54
  *
55
55
  * Features:
56
56
  * - Gender selection (Any/Male/Female)
57
- * - Participant count (8-256)
57
+ * - Participant count (8-128)
58
58
  * - Age range with automatic validation (ageMax >= ageMin)
59
59
  * - Number of countries to limit nationality diversity
60
60
  * - Optional WTN/UTR ratings
@@ -0,0 +1,7 @@
1
+ import { MatchUp } from '../../types';
2
+ export interface StructureMinimapOptions {
3
+ matchUps: MatchUp[];
4
+ width?: number;
5
+ quarterCount?: number;
6
+ }
7
+ export declare function buildStructureMinimap({ matchUps, width, quarterCount }: StructureMinimapOptions): HTMLDivElement | null;
@@ -13,7 +13,7 @@
13
13
  *
14
14
  * - computeActiveStripDropTarget(grid, courtId, dragged)
15
15
  * Picks a row when a matchUp is dropped onto a court's strip cell.
16
- * It infers a "temporal floor" from the existing grid:
16
+ * It infers a "scheduled floor" from the existing grid:
17
17
  * (a) any row across all courts where the dragged matchUp's
18
18
  * participants already appear — the dragged matchUp must land
19
19
  * below those rows;
@@ -20,7 +20,7 @@ export { buildScheduleInspectorPanel } from './ui/inspectorPanel';
20
20
  export { buildCourtGridSlot } from './ui/courtGridSlot';
21
21
  export { buildSchedulePageLayout } from './ui/schedulePageLayout';
22
22
  export { buildActiveStripPanel } from './ui/activeStrip';
23
- export type { ActiveStripPanel, ActiveStripPanelCallbacks, ActiveStripPanelData, ActiveStripPanelOptions, ActiveStripCourtMeta } from './ui/activeStrip';
23
+ export type { ActiveStripPanel, ActiveStripPanelCallbacks, ActiveStripPanelData, ActiveStripPanelOptions, ActiveStripCourtMeta, ActiveStripCourtBlock } from './ui/activeStrip';
24
24
  export { buildScheduleGridCell, mapMatchUpToCellData, DEFAULT_SCHEDULE_CELL_CONFIG } from './ui/scheduleGridCell';
25
25
  export { activateScheduleCellTypeAhead } from './ui/scheduleCellTypeAhead';
26
26
  export type { ScheduleCellTypeAheadOptions } from './ui/scheduleCellTypeAhead';
@@ -249,5 +249,19 @@ export interface ScheduleCellData {
249
249
  bookingType?: string;
250
250
  rowCount?: number;
251
251
  notes?: string;
252
+ /**
253
+ * Participant labels to render below the booking type. Pre-formatted
254
+ * by the consumer so the cell stays display-only — e.g.
255
+ * `["Smith / Jones (14:00–14:30)", "Ortiz (14:30–15:00)"]`.
256
+ *
257
+ * NOTE: as of 2026-06-01 there is no expected consumer. The Now/Live
258
+ * strip uses a separate banner path (`ActiveStripCourtBlock.detail`),
259
+ * and PRACTICE bookings are time-windowed — they don't currently
260
+ * surface as grid cells, which have fixed row positions, not fixed
261
+ * times. The field is kept available for future use (e.g. if a
262
+ * tournament chooses to materialize PRACTICE bookings as cells) but
263
+ * no production callsite populates it today.
264
+ */
265
+ registrations?: string[];
252
266
  };
253
267
  }
@@ -4,11 +4,34 @@ export interface ActiveStripCourtMeta {
4
4
  courtId: string;
5
5
  label: string;
6
6
  }
7
+ /**
8
+ * Active availability block surfaced on a court for the current clock time.
9
+ * When present, the strip renders a labeled banner inside the court's cell
10
+ * (e.g. "PRACTICE 14:00–16:00") so the TD sees at a glance that the court
11
+ * has a non-matchUp time reservation in effect.
12
+ *
13
+ * The strip itself is data-driven and does NOT poll the clock; consumers
14
+ * are expected to refresh `ActiveStripPanelData` periodically (e.g. every
15
+ * 30s) with the blocks active at "now".
16
+ */
17
+ export interface ActiveStripCourtBlock {
18
+ /** Block type label, used as the banner intent class (e.g. "PRACTICE", "MAINTENANCE"). */
19
+ type: string;
20
+ /** Banner text. Caller controls formatting — e.g. "PRACTICE 14:00–16:00". */
21
+ label: string;
22
+ /** Optional short note (block.reason, registrant name from a future practice-registration system, etc.). */
23
+ detail?: string;
24
+ }
7
25
  export interface ActiveStripPanelData {
8
26
  /** Court columns, in display order. The strip computes one cell per column. */
9
27
  grid: ActiveStripGrid;
10
28
  /** Optional display labels per courtId. Falls back to courtId. */
11
29
  courts?: ActiveStripCourtMeta[];
30
+ /**
31
+ * Optional map of courtId → active availability block. When provided, the
32
+ * strip renders a colored banner inside the court's active cell.
33
+ */
34
+ courtBlocks?: Record<string, ActiveStripCourtBlock>;
12
35
  /**
13
36
  * CSS grid-template-columns applied to the strip root. When provided, the
14
37
  * strip lays out as `display: grid` with a leading spacer occupying the
@@ -1,11 +1,12 @@
1
- import { SchedulingProfile, ValidationResult, TemporalAdapter, DependencyAdapter, FlattenedRound } from '../types';
1
+ import { SchedulingProfile, ValidationResult, AvailabilityAdapter, DemandAdapter, DependencyAdapter, FlattenedRound } from '../types';
2
2
  export interface ValidateProfileParams {
3
3
  profile: SchedulingProfile;
4
- temporal?: TemporalAdapter;
4
+ availability?: AvailabilityAdapter;
5
+ demand?: DemandAdapter;
5
6
  dependencies?: DependencyAdapter;
6
7
  venueOrder?: string[];
7
8
  }
8
- export declare function validateProfile({ profile, temporal, dependencies, venueOrder }: ValidateProfileParams): ValidationResult[];
9
+ export declare function validateProfile({ profile, availability, demand, dependencies, venueOrder }: ValidateProfileParams): ValidationResult[];
9
10
  export declare function validateRoundPrecedenceLocal({ profile }: {
10
11
  profile: SchedulingProfile;
11
12
  venueOrder?: string[];
@@ -20,5 +20,5 @@ export { buildIssuesPanel } from './ui/issuesPanel';
20
20
  export { buildRoundCard } from './ui/roundCard';
21
21
  export { createCardPopoverManager } from './ui/cardPopover';
22
22
  export { buildSchedulingProfileLayout } from './ui/schedulingProfileLayout';
23
- export type { SchedulingProfile, ScheduleDay, VenueSchedule, RoundProfile, RoundSegment, VenueInfo, CatalogRoundItem, CatalogGroupBy, RoundKey, RoundLocator, DragPayload, CatalogDragPayload, PlannedDragPayload, DropTarget, DropResult, Severity, ValidationCode, FixActionKind, FixAction, ValidationResult, SeverityCounts, IssueIndex, ProfileStoreState, ProfileChangeListener, TemporalAdapter, DemandAdapter, DependencyAdapter, SchedulingProfileConfig, UIPanel, FlattenedRound, PlannedRoundBehavior } from './types';
23
+ export type { SchedulingProfile, ScheduleDay, VenueSchedule, RoundProfile, RoundSegment, VenueInfo, CatalogRoundItem, CatalogGroupBy, RoundKey, RoundLocator, DragPayload, CatalogDragPayload, PlannedDragPayload, DropTarget, DropResult, Severity, ValidationCode, FixActionKind, FixAction, ValidationResult, SeverityCounts, IssueIndex, ProfileStoreState, ProfileChangeListener, AvailabilityAdapter, DemandAdapter, DependencyAdapter, SchedulingProfileConfig, UIPanel, FlattenedRound, PlannedRoundBehavior } from './types';
24
24
  export declare function createSchedulingProfile(config: SchedulingProfileConfig, container: HTMLElement): SchedulingProfileControl;
@@ -85,7 +85,7 @@ export interface DropResult {
85
85
  }
86
86
  export type Severity = 'ERROR' | 'WARN' | 'INFO';
87
87
  export type ValidationCode = 'DATE_UNAVAILABLE' | 'DUPLICATE_ROUND' | 'DUPLICATE_SEGMENT' | 'INVALID_SEGMENT_CONFIG' | 'ROUND_ORDER_VIOLATION' | 'DEPENDENCY_VIOLATION' | 'DAY_OVERLOAD' | 'DROP_REJECTED';
88
- export type FixActionKind = 'JUMP_TO_ITEM' | 'OPEN_TEMPORAL_GRID' | 'MOVE_ITEM_AFTER' | 'MOVE_ITEM_BEFORE';
88
+ export type FixActionKind = 'JUMP_TO_ITEM' | 'OPEN_AVAILABILITY_GRID' | 'MOVE_ITEM_AFTER' | 'MOVE_ITEM_BEFORE';
89
89
  export interface FixAction {
90
90
  kind: FixActionKind;
91
91
  label: string;
@@ -150,7 +150,7 @@ export interface ProfileStoreState {
150
150
  plannedRoundBehavior: PlannedRoundBehavior;
151
151
  }
152
152
  export type ProfileChangeListener = (state: ProfileStoreState) => void;
153
- export interface TemporalAdapter {
153
+ export interface AvailabilityAdapter {
154
154
  isDateAvailable: (date: string) => {
155
155
  ok: boolean;
156
156
  reason?: string;
@@ -179,7 +179,7 @@ export interface SchedulingProfileConfig {
179
179
  catalogSide?: 'left' | 'right';
180
180
  initialProfile?: SchedulingProfile;
181
181
  selectedDate?: string;
182
- temporalAdapter?: TemporalAdapter;
182
+ availabilityAdapter?: AvailabilityAdapter;
183
183
  demandAdapter?: DemandAdapter;
184
184
  dependencyAdapter?: DependencyAdapter;
185
185
  venueOrder?: string[];