courthive-components 3.2.0 → 3.4.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.
- package/dist/components/policy-catalog/editors/scoring/domain/scoringProjections.d.ts +23 -0
- package/dist/components/policy-catalog/editors/scoring/index.d.ts +3 -0
- package/dist/components/policy-catalog/editors/scoring/scoringEditorControl.d.ts +21 -0
- package/dist/components/policy-catalog/editors/scoring/scoringEditorPanel.d.ts +6 -0
- package/dist/components/policy-catalog/editors/scoring/scoringEditorStore.d.ts +33 -0
- package/dist/components/policy-catalog/editors/scoring/sections/allowedFormatsSection.d.ts +6 -0
- package/dist/components/policy-catalog/editors/scoring/sections/defaultsSection.d.ts +6 -0
- package/dist/components/policy-catalog/editors/scoring/sections/matchUpFormatPicker.d.ts +35 -0
- package/dist/components/policy-catalog/editors/scoring/sections/statusCodesSection.d.ts +6 -0
- package/dist/components/policy-catalog/editors/scoring/sections/tagListEditor.d.ts +24 -0
- package/dist/components/policy-catalog/editors/scoring/types.d.ts +60 -0
- package/dist/components/policy-catalog/engine/policyCatalogStore.d.ts +11 -0
- package/dist/components/policy-catalog/index.d.ts +2 -0
- package/dist/components/policy-catalog/types.d.ts +13 -1
- package/dist/components/policy-catalog/ui/editorShell.d.ts +1 -0
- package/dist/components/schedule-page/types.d.ts +7 -1
- package/dist/courthive-components.css +1 -1
- package/dist/courthive-components.es.js +2080 -987
- package/dist/courthive-components.umd.js +14 -14
- package/dist/{dist-CwJOJWf0.mjs → dist-DiYU0jFr.mjs} +529 -487
- package/dist/{range-CBX41Ttl.mjs → range-CRxwaxeo.mjs} +125 -58
- package/dist/types.d.ts +14 -2
- package/package.json +6 -6
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ScoringPolicyData, AllowedFormatEntry } from '../types';
|
|
2
|
+
type RegistryEntry = {
|
|
3
|
+
key?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
format?: string;
|
|
6
|
+
desc?: string;
|
|
7
|
+
desc2?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function lookupRegistryFormat(format: string | undefined): RegistryEntry | undefined;
|
|
10
|
+
export declare const MATCH_UP_FORMAT_REGISTRY_SORTED: RegistryEntry[];
|
|
11
|
+
export declare function formatStringOf(entry: AllowedFormatEntry): string;
|
|
12
|
+
export declare function formatNameOf(entry: AllowedFormatEntry): string;
|
|
13
|
+
export declare function formatDescriptionOf(entry: AllowedFormatEntry): string;
|
|
14
|
+
export declare function asMatchUpFormatEntry(entry: AllowedFormatEntry): {
|
|
15
|
+
name?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
matchUpFormat: string;
|
|
18
|
+
categoryNames?: string[];
|
|
19
|
+
categoryTypes?: string[];
|
|
20
|
+
};
|
|
21
|
+
export declare const FORMAT_STANDARD = "SET3-S:6/TB7";
|
|
22
|
+
export declare function emptyScoringPolicy(): ScoringPolicyData;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { ScoringEditorControl, createScoringEditor } from './scoringEditorControl';
|
|
2
|
+
export type { ScoringPolicyData, ScoringEditorConfig, MatchUpStatusKey, MatchUpFormatEntry, AllowedFormatEntry, } from './types';
|
|
3
|
+
export { MATCH_UP_FORMAT_REGISTRY_SORTED, lookupRegistryFormat, emptyScoringPolicy, FORMAT_STANDARD, } from './domain/scoringProjections';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ScoringEditorStore } from './scoringEditorStore';
|
|
2
|
+
import { ScoringPolicyData, ScoringEditorConfig } from './types';
|
|
3
|
+
import { PolicyEditorInstance as CatalogEditorInstance } from '../../types';
|
|
4
|
+
export declare class ScoringEditorControl {
|
|
5
|
+
private readonly store;
|
|
6
|
+
private readonly panel;
|
|
7
|
+
private readonly unsubscribe;
|
|
8
|
+
private container;
|
|
9
|
+
constructor(config: ScoringEditorConfig);
|
|
10
|
+
render(container: HTMLElement): void;
|
|
11
|
+
destroy(): void;
|
|
12
|
+
getData(): ScoringPolicyData;
|
|
13
|
+
setData(data: ScoringPolicyData): void;
|
|
14
|
+
getStore(): ScoringEditorStore;
|
|
15
|
+
static createEditorInstance(config: {
|
|
16
|
+
initialData: Record<string, unknown>;
|
|
17
|
+
onChange: (data: Record<string, unknown>) => void;
|
|
18
|
+
readonly?: boolean;
|
|
19
|
+
}): CatalogEditorInstance;
|
|
20
|
+
}
|
|
21
|
+
export declare function createScoringEditor(config: ScoringEditorConfig, container: HTMLElement): ScoringEditorControl;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ScoringPolicyData, ScoringEditorState, ScoringEditorSection, ScoringEditorChangeListener, ScoringEditorConfig, MatchUpStatusKey, AllowedFormatField, MatchUpFormatEntry } from './types';
|
|
2
|
+
export declare class ScoringEditorStore {
|
|
3
|
+
private state;
|
|
4
|
+
private readonly listeners;
|
|
5
|
+
private readonly config;
|
|
6
|
+
constructor(config: ScoringEditorConfig);
|
|
7
|
+
isReadonly(): boolean;
|
|
8
|
+
getState(): ScoringEditorState;
|
|
9
|
+
getData(): ScoringPolicyData;
|
|
10
|
+
setData(data: ScoringPolicyData): void;
|
|
11
|
+
toggleSection(sectionId: ScoringEditorSection): void;
|
|
12
|
+
toggleStatus(key: MatchUpStatusKey): void;
|
|
13
|
+
setAdvancedOpen(value: boolean): void;
|
|
14
|
+
setDefaultMatchUpFormat(value: string): void;
|
|
15
|
+
setRequireParticipants(value: boolean): void;
|
|
16
|
+
setRequireAllPositions(value: 'default' | 'true' | 'false'): void;
|
|
17
|
+
setAllowChangePropagation(value: boolean): void;
|
|
18
|
+
setAllowDeletionDraws(value: boolean): void;
|
|
19
|
+
setAllowDeletionStructures(value: boolean): void;
|
|
20
|
+
addAllowedFormat(seed?: Partial<MatchUpFormatEntry>): void;
|
|
21
|
+
removeAllowedFormat(index: number): void;
|
|
22
|
+
setAllowedFormatField(index: number, field: AllowedFormatField, value: string): void;
|
|
23
|
+
isAllowedFormatDuplicate(format: string, excludeIndex?: number): boolean;
|
|
24
|
+
addAllowedFormatCategory(index: number, kind: 'categoryNames' | 'categoryTypes', value: string): void;
|
|
25
|
+
removeAllowedFormatCategory(index: number, kind: 'categoryNames' | 'categoryTypes', valueIndex: number): void;
|
|
26
|
+
addStatusCode(status: MatchUpStatusKey, value: string): void;
|
|
27
|
+
removeStatusCode(status: MatchUpStatusKey, index: number): void;
|
|
28
|
+
addProcessCode(value: string): void;
|
|
29
|
+
removeProcessCode(index: number): void;
|
|
30
|
+
subscribe(listener: ScoringEditorChangeListener): () => void;
|
|
31
|
+
private commitDraft;
|
|
32
|
+
private emit;
|
|
33
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MatchUp Format Picker — Preset dropdown + free-text + structured builder.
|
|
3
|
+
*
|
|
4
|
+
* V1 UX:
|
|
5
|
+
* ┌─ Preset ──────────────────────────────────────────┐
|
|
6
|
+
* │ [Standard (BO3, sets to 6, TB7) ▾] │
|
|
7
|
+
* │ ↳ shows the matching preset when the underlying │
|
|
8
|
+
* │ format string is one we ship; "Custom" when │
|
|
9
|
+
* │ it isn't. │
|
|
10
|
+
* ├─ Custom format (visible only on "Custom" preset) ─┤
|
|
11
|
+
* │ [SET3-S:6/TB7 ] [✓] │
|
|
12
|
+
* ├─ Build ▾ (collapsible structured editor) ────────┤
|
|
13
|
+
* │ bestOf [3 ▾] │
|
|
14
|
+
* │ set type ◉ Standard ○ Tiebreak ○ Timed │
|
|
15
|
+
* │ …conditional fields per set type… │
|
|
16
|
+
* │ [ ] Different final-set rules │
|
|
17
|
+
* │ Result: SET3-S:6/TB7 [✓ valid] │
|
|
18
|
+
* └──────────────────────────────────────────────────┘
|
|
19
|
+
*
|
|
20
|
+
* The structured builder targets the SET-rooted tennis-family case (which
|
|
21
|
+
* covers 95%+ of the consumers' real-world formats). Sports with other
|
|
22
|
+
* roots (HAL, QTR, RND, MAP…) still set the value via the free-text
|
|
23
|
+
* field; the picker round-trips them but exposes no specialized UI.
|
|
24
|
+
*/
|
|
25
|
+
export interface MatchUpFormatPickerConfig {
|
|
26
|
+
initialValue?: string;
|
|
27
|
+
readonly?: boolean;
|
|
28
|
+
onChange: (value: string) => void;
|
|
29
|
+
}
|
|
30
|
+
export interface MatchUpFormatPickerHandle {
|
|
31
|
+
element: HTMLElement;
|
|
32
|
+
setValue(value: string): void;
|
|
33
|
+
destroy(): void;
|
|
34
|
+
}
|
|
35
|
+
export declare function buildMatchUpFormatPicker(config: MatchUpFormatPickerConfig): MatchUpFormatPickerHandle;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small chip-list editor used by the "Allowed match-up formats" section
|
|
3
|
+
* and each of the six status-code refinement groups. Repeats the same
|
|
4
|
+
* UX: existing items render as removable chips, a single text input +
|
|
5
|
+
* Add button appends new values.
|
|
6
|
+
*
|
|
7
|
+
* The host owns the array — the editor only emits add(value) /
|
|
8
|
+
* remove(index). State for the input text is purely local DOM.
|
|
9
|
+
*/
|
|
10
|
+
export interface TagListEditorConfig {
|
|
11
|
+
values: string[];
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
readonly?: boolean;
|
|
14
|
+
validate?: (value: string) => boolean;
|
|
15
|
+
invalidMessage?: string;
|
|
16
|
+
onAdd: (value: string) => void;
|
|
17
|
+
onRemove: (index: number) => void;
|
|
18
|
+
}
|
|
19
|
+
export interface TagListEditorHandle {
|
|
20
|
+
element: HTMLElement;
|
|
21
|
+
setValues(values: string[]): void;
|
|
22
|
+
destroy(): void;
|
|
23
|
+
}
|
|
24
|
+
export declare function buildTagListEditor(config: TagListEditorConfig): TagListEditorHandle;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoring Policy Editor — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the factory's scoring policy data shape (see
|
|
5
|
+
* factory/src/fixtures/policies/POLICY_SCORING_DEFAULT.ts).
|
|
6
|
+
*
|
|
7
|
+
* The factory does not export a TypeScript interface for the scoring
|
|
8
|
+
* policy itself — the fixture defines the shape via runtime defaults.
|
|
9
|
+
* We re-derive the shape here so the editor can stay type-safe without
|
|
10
|
+
* dragging factory internals into courthive-components.
|
|
11
|
+
*/
|
|
12
|
+
export type MatchUpStatusKey = 'ABANDONED' | 'CANCELLED' | 'DEFAULTED' | 'INCOMPLETE' | 'RETIRED' | 'WALKOVER';
|
|
13
|
+
export declare const MATCH_UP_STATUS_KEYS: MatchUpStatusKey[];
|
|
14
|
+
export type RequireAllPositionsTriState = 'default' | 'true' | 'false';
|
|
15
|
+
export interface AllowDeletionWithScoresPresent {
|
|
16
|
+
drawDefinitions?: boolean;
|
|
17
|
+
structures?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface StageSequenceOverride {
|
|
20
|
+
requireAllPositionsAssigned?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface MatchUpFormatEntry {
|
|
23
|
+
name?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
matchUpFormat: string;
|
|
26
|
+
categoryNames?: string[];
|
|
27
|
+
categoryTypes?: string[];
|
|
28
|
+
}
|
|
29
|
+
export type AllowedFormatEntry = string | MatchUpFormatEntry;
|
|
30
|
+
export type AllowedFormatField = 'name' | 'description' | 'matchUpFormat';
|
|
31
|
+
export interface ScoringPolicyData {
|
|
32
|
+
policyName?: string;
|
|
33
|
+
defaultMatchUpFormat?: string;
|
|
34
|
+
matchUpFormats?: AllowedFormatEntry[];
|
|
35
|
+
requireParticipantsForScoring?: boolean;
|
|
36
|
+
requireAllPositionsAssigned?: boolean;
|
|
37
|
+
allowChangePropagation?: boolean;
|
|
38
|
+
allowDeletionWithScoresPresent?: AllowDeletionWithScoresPresent;
|
|
39
|
+
matchUpStatusCodes?: Partial<Record<MatchUpStatusKey, string[]>>;
|
|
40
|
+
stage?: Record<string, {
|
|
41
|
+
stageSequence?: Record<string, StageSequenceOverride>;
|
|
42
|
+
}>;
|
|
43
|
+
processCodes?: {
|
|
44
|
+
incompleteAssignmentsOnDefault?: string[];
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export type ScoringEditorSection = 'defaults' | 'allowedFormats' | 'statusCodes';
|
|
48
|
+
export interface ScoringEditorState {
|
|
49
|
+
draft: ScoringPolicyData;
|
|
50
|
+
expandedSections: Set<ScoringEditorSection>;
|
|
51
|
+
expandedStatuses: Set<MatchUpStatusKey>;
|
|
52
|
+
advancedOpen: boolean;
|
|
53
|
+
dirty: boolean;
|
|
54
|
+
}
|
|
55
|
+
export type ScoringEditorChangeListener = (state: ScoringEditorState) => void;
|
|
56
|
+
export interface ScoringEditorConfig {
|
|
57
|
+
initialPolicy?: ScoringPolicyData;
|
|
58
|
+
readonly?: boolean;
|
|
59
|
+
onChange?: (policy: ScoringPolicyData) => void;
|
|
60
|
+
}
|
|
@@ -10,6 +10,7 @@ export declare class PolicyCatalogStore {
|
|
|
10
10
|
setCatalogGroupBy(mode: CatalogGroupBy): void;
|
|
11
11
|
selectPolicy(id: string): void;
|
|
12
12
|
clearSelection(): void;
|
|
13
|
+
renamePolicy(name: string): void;
|
|
13
14
|
updateEditorDraft(data: Record<string, unknown>): void;
|
|
14
15
|
markDirty(): void;
|
|
15
16
|
markClean(): void;
|
|
@@ -18,8 +19,18 @@ export declare class PolicyCatalogStore {
|
|
|
18
19
|
applyPolicy(): void;
|
|
19
20
|
addNewPolicy(policyType: string): string;
|
|
20
21
|
duplicatePolicy(sourceId: string): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Swap a placeholder id (returned from addNewPolicy/duplicatePolicy) for a
|
|
24
|
+
* canonical id assigned by the persistence backend. Idempotent and a no-op
|
|
25
|
+
* when the placeholder is gone (e.g. user deleted before reconciliation).
|
|
26
|
+
*/
|
|
27
|
+
reconcilePolicyId(localId: string, serverId: string): void;
|
|
21
28
|
deletePolicy(id: string): void;
|
|
22
29
|
subscribe(listener: PolicyCatalogChangeListener): () => void;
|
|
23
30
|
private setState;
|
|
24
31
|
private emit;
|
|
32
|
+
private localIdCounter;
|
|
33
|
+
private nextLocalId;
|
|
34
|
+
private appendAndSelect;
|
|
35
|
+
private runCreateAndReconcile;
|
|
25
36
|
}
|
|
@@ -17,6 +17,8 @@ export { buildJsonEditor } from './ui/jsonEditor';
|
|
|
17
17
|
export { SchedulingEditorControl, createSchedulingEditor, SchedulingEditorStore, validateSchedulingPolicy, formatCodeLabel, emptySchedulingPolicy, buildSchedulingEditorPanel } from './editors/scheduling';
|
|
18
18
|
export { RankingPointsEditorControl, createRankingPointsEditor, RankingPointsEditorStore, buildRankingPointsEditorPanel, emptyRankingPolicy } from './editors/ranking';
|
|
19
19
|
export { SeedingEditorControl, createSeedingEditor, SeedingEditorStore, buildSeedingEditorPanel, emptySeedingPolicy, POSITIONING_OPTIONS, DRAW_TYPE_OPTIONS } from './editors/seeding';
|
|
20
|
+
export { ScoringEditorControl, createScoringEditor, MATCH_UP_FORMAT_REGISTRY_SORTED, lookupRegistryFormat, emptyScoringPolicy, FORMAT_STANDARD, } from './editors/scoring';
|
|
21
|
+
export type { ScoringPolicyData, ScoringEditorConfig, MatchUpStatusKey, MatchUpFormatEntry, AllowedFormatEntry, } from './editors/scoring';
|
|
20
22
|
export type { PolicyCatalogItem, PolicyCatalogState, PolicyCatalogChangeListener, PolicyCatalogConfig, PolicyEditorInstance, PolicyEditorPlugin, PolicySource, PolicyTypeGroup, PolicyTypeMeta, CatalogGroupBy, UIPanel } from './types';
|
|
21
23
|
export type { SchedulingPolicyData, SchedulingEditorState, SchedulingEditorSection, SchedulingEditorChangeListener, SchedulingEditorConfig, SchedulingValidationResult, ValidationSeverity, MinutesEntry, AverageTimeEntry, RecoveryTimeEntry, MatchUpAverageTime, MatchUpRecoveryTime } from './editors/scheduling';
|
|
22
24
|
export type { RankingPolicyData, RankingPointsEditorState, RankingEditorSection, RankingPointsEditorChangeListener, RankingPointsEditorConfig, AwardProfileData, QualityWinProfileData, AggregationRulesData, TableLayout } from './editors/ranking';
|
|
@@ -25,6 +25,12 @@ export interface PolicyCatalogState {
|
|
|
25
25
|
groupBy: CatalogGroupBy;
|
|
26
26
|
selectedId: string | null;
|
|
27
27
|
editorDraft: Record<string, unknown> | null;
|
|
28
|
+
/**
|
|
29
|
+
* Live name buffer for the selected policy. Populated on selection from the
|
|
30
|
+
* catalog item and mutated by the rename input so renames survive across
|
|
31
|
+
* editor remounts. `savePolicy` writes this back to the catalog item.
|
|
32
|
+
*/
|
|
33
|
+
editedName: string | null;
|
|
28
34
|
dirty: boolean;
|
|
29
35
|
}
|
|
30
36
|
export type PolicyCatalogChangeListener = (state: PolicyCatalogState) => void;
|
|
@@ -47,7 +53,13 @@ export interface PolicyCatalogConfig {
|
|
|
47
53
|
editorPlugins?: PolicyEditorPlugin[];
|
|
48
54
|
onPolicySaved?: (item: PolicyCatalogItem) => void;
|
|
49
55
|
onPolicyApplied?: (item: PolicyCatalogItem) => void;
|
|
50
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Fired when "+" creates a new policy. If the host persists the new policy
|
|
58
|
+
* to a backend that mints its own canonical id, return that id (sync or
|
|
59
|
+
* Promise) — the store will reconcile the local placeholder id so subsequent
|
|
60
|
+
* Save calls hit the right backend record. Return void to keep the local id.
|
|
61
|
+
*/
|
|
62
|
+
onPolicyCreated?: (item: PolicyCatalogItem) => string | void | Promise<string | void>;
|
|
51
63
|
onPolicyDeleted?: (id: string) => void;
|
|
52
64
|
onSelectionChanged?: (item: PolicyCatalogItem | null) => void;
|
|
53
65
|
}
|
|
@@ -17,6 +17,12 @@ export interface CatalogMatchUpItem {
|
|
|
17
17
|
drawId: string;
|
|
18
18
|
drawName?: string;
|
|
19
19
|
structureId: string;
|
|
20
|
+
/** Human-readable structure label set by the factory (e.g. "Main",
|
|
21
|
+
* "Consolation", "Compass NE"). Optional because some structures
|
|
22
|
+
* ship without one — the catalog falls back to a labeled stage and
|
|
23
|
+
* finally the eventName alone so the "by structure" group header
|
|
24
|
+
* never shows a raw structureId GUID. */
|
|
25
|
+
structureName?: string;
|
|
20
26
|
/** Draw stage — MAIN / CONSOLATION / PLAYOFF / QUALIFYING / ROUND_ROBIN /
|
|
21
27
|
* etc. Rendered as a chip when present and not MAIN so a Quarterfinal in
|
|
22
28
|
* the consolation bracket reads distinctly from a Quarterfinal in the
|
|
@@ -53,7 +59,7 @@ export interface ScheduleIssue {
|
|
|
53
59
|
/** All matchUpIds involved in this conflict (for click-to-scroll fallback) */
|
|
54
60
|
conflictMatchUpIds?: string[];
|
|
55
61
|
}
|
|
56
|
-
export type MatchUpCatalogGroupBy = 'event' | 'draw' | 'round' | 'structure';
|
|
62
|
+
export type MatchUpCatalogGroupBy = 'event' | 'draw' | 'round' | 'structure' | 'time';
|
|
57
63
|
export interface CatalogFilters {
|
|
58
64
|
eventType?: string;
|
|
59
65
|
eventName?: string;
|