@evotecit/canopyx 0.1.3 → 0.2.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 (85) hide show
  1. package/CanopyX.Html/Assets/canopyx-calendar-edit.js +113 -0
  2. package/CanopyX.Html/Assets/canopyx-calendar-ics.js +87 -0
  3. package/CanopyX.Html/Assets/canopyx-calendar-recurrence.js +36 -0
  4. package/CanopyX.Html/Assets/canopyx-calendar.css +279 -0
  5. package/CanopyX.Html/Assets/canopyx-calendar.js +307 -0
  6. package/CanopyX.Html/Assets/canopyx-cell-range.css +38 -0
  7. package/CanopyX.Html/Assets/canopyx-cell-range.js +141 -0
  8. package/CanopyX.Html/Assets/canopyx-column-groups.css +18 -0
  9. package/CanopyX.Html/Assets/canopyx-column-groups.js +51 -0
  10. package/CanopyX.Html/Assets/canopyx-data.js +14 -0
  11. package/CanopyX.Html/Assets/canopyx-detail-rows.css +18 -0
  12. package/CanopyX.Html/Assets/canopyx-detail-rows.js +51 -0
  13. package/CanopyX.Html/Assets/canopyx-editing.css +44 -0
  14. package/CanopyX.Html/Assets/canopyx-editing.js +134 -0
  15. package/CanopyX.Html/Assets/canopyx-enhance.js +126 -0
  16. package/CanopyX.Html/Assets/canopyx-export.js +18 -0
  17. package/CanopyX.Html/Assets/canopyx-facets.css +86 -0
  18. package/CanopyX.Html/Assets/canopyx-facets.js +65 -0
  19. package/CanopyX.Html/Assets/canopyx-filter-editor.css +15 -18
  20. package/CanopyX.Html/Assets/canopyx-filter-editor.js +23 -17
  21. package/CanopyX.Html/Assets/canopyx-format-editor.css +77 -0
  22. package/CanopyX.Html/Assets/canopyx-format-editor.js +30 -0
  23. package/CanopyX.Html/Assets/canopyx-formatting.css +40 -0
  24. package/CanopyX.Html/Assets/canopyx-formatting.js +101 -0
  25. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +352 -246
  26. package/CanopyX.Html/Assets/canopyx-grid.css +139 -117
  27. package/CanopyX.Html/Assets/canopyx-grid.js +352 -246
  28. package/CanopyX.Html/Assets/canopyx-grouping.css +39 -0
  29. package/CanopyX.Html/Assets/canopyx-grouping.js +85 -0
  30. package/CanopyX.Html/Assets/canopyx-highlight.css +34 -0
  31. package/CanopyX.Html/Assets/canopyx-highlight.js +80 -0
  32. package/CanopyX.Html/Assets/canopyx-history.js +13 -0
  33. package/CanopyX.Html/Assets/canopyx-interactive.css +18 -6
  34. package/CanopyX.Html/Assets/canopyx-interactive.js +179 -100
  35. package/CanopyX.Html/Assets/canopyx-labels-de.js +304 -0
  36. package/CanopyX.Html/Assets/canopyx-labels-es.js +304 -0
  37. package/CanopyX.Html/Assets/canopyx-labels-fr.js +529 -0
  38. package/CanopyX.Html/Assets/canopyx-labels-it.js +529 -0
  39. package/CanopyX.Html/Assets/canopyx-labels-pl.js +304 -0
  40. package/CanopyX.Html/Assets/canopyx-layouts.css +48 -0
  41. package/CanopyX.Html/Assets/canopyx-layouts.js +39 -0
  42. package/CanopyX.Html/Assets/canopyx-link.css +19 -0
  43. package/CanopyX.Html/Assets/canopyx-link.js +38 -0
  44. package/CanopyX.Html/Assets/canopyx-links.js +14 -0
  45. package/CanopyX.Html/Assets/canopyx-live.css +24 -0
  46. package/CanopyX.Html/Assets/canopyx-live.js +88 -0
  47. package/CanopyX.Html/Assets/canopyx-module.mjs +180 -100
  48. package/CanopyX.Html/Assets/canopyx-pager.css +10 -0
  49. package/CanopyX.Html/Assets/canopyx-pager.js +14 -0
  50. package/CanopyX.Html/Assets/canopyx-record-panel.css +111 -0
  51. package/CanopyX.Html/Assets/canopyx-record-panel.js +178 -0
  52. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +406 -342
  53. package/CanopyX.Html/Assets/canopyx-reporting.css +140 -135
  54. package/CanopyX.Html/Assets/canopyx-reporting.js +406 -342
  55. package/CanopyX.Html/Assets/canopyx-search.js +32 -0
  56. package/CanopyX.Html/Assets/canopyx-timeline.css +80 -0
  57. package/CanopyX.Html/Assets/canopyx-timeline.js +88 -0
  58. package/CanopyX.Html/Assets/canopyx-tree-tools.css +103 -0
  59. package/CanopyX.Html/Assets/canopyx-tree-tools.js +92 -0
  60. package/CanopyX.Html/Assets/canopyx.css +17 -5
  61. package/CanopyX.Html/Assets/canopyx.js +175 -96
  62. package/JavaScript/calendar.d.ts +362 -0
  63. package/JavaScript/cell-ranges.d.ts +76 -0
  64. package/JavaScript/column-groups.d.ts +32 -0
  65. package/JavaScript/editing.d.ts +257 -0
  66. package/JavaScript/enhance.d.ts +202 -0
  67. package/JavaScript/facets.d.ts +58 -0
  68. package/JavaScript/formatting.d.ts +88 -0
  69. package/JavaScript/grid.d.ts +409 -56
  70. package/JavaScript/hosts.d.ts +177 -2
  71. package/JavaScript/index.d.ts +53 -4
  72. package/JavaScript/live.d.ts +115 -0
  73. package/JavaScript/locales/de.mjs +304 -0
  74. package/JavaScript/locales/es.mjs +304 -0
  75. package/JavaScript/locales/fr.d.ts +6 -0
  76. package/JavaScript/locales/fr.mjs +527 -0
  77. package/JavaScript/locales/it.d.ts +6 -0
  78. package/JavaScript/locales/it.mjs +527 -0
  79. package/JavaScript/locales/pl.mjs +304 -0
  80. package/JavaScript/plugins.d.ts +113 -0
  81. package/JavaScript/protocol.d.ts +139 -6
  82. package/JavaScript/records.d.ts +136 -0
  83. package/README.md +61 -9
  84. package/README.nuget.md +1 -1
  85. package/package.json +99 -3
@@ -0,0 +1,362 @@
1
+ // The calendar of flat grids (docs/calendar.md, docs/resource-timeline.md): month, week, day, N days, agenda, year and the
2
+ // resource timeline over the grid's own records, with the grid's query, record panel, linked views, facets, live data and editing.
3
+ import type { InlineView, RemoteView } from "./protocol.js";
4
+ import type { GridRow, GridColumnId, GridQuery } from "./grid.js";
5
+ import type { GridLiveDefinition } from "./live.js";
6
+ import type { GridFacetPanelDefinition } from "./facets.js";
7
+
8
+ /** The views a calendar offers. */
9
+ /** mini: a small month like a date picker; weekList and dayList: each day's events as a list; months: stacked months that scroll. */
10
+ export type GridCalendarView = "month" | "week" | "day" | "days" | "agenda" | "year" | "timeline" | "mini" | "weekList" | "dayList" | "months";
11
+
12
+ /** The grid toolbar controls a calendar may show above itself. */
13
+ export type GridCalendarToolbarItem = "search" | "filters" | "columns" | "views" | "export" | "more";
14
+
15
+ /** An event source with a legend switch; ics names a same-origin iCalendar file whose events join read-only. */
16
+ export interface GridCalendarSource {
17
+ id: string;
18
+ label: string;
19
+ tone?: string;
20
+ ics?: string;
21
+ /** Starts switched off. */
22
+ hidden?: boolean;
23
+ }
24
+ /** The resource timeline's zoom levels. */
25
+ export type GridCalendarZoom = "hour" | "day" | "week" | "month" | "quarter";
26
+ /** A time of day, "HH:mm" (24:00 allowed for an end). */
27
+ export type GridCalendarTime = `${number}:${number}`;
28
+ /** A weekday, 0 (Sunday) to 6 (Saturday). */
29
+ export type GridCalendarWeekday = 0 | 1 | 2 | 3 | 4 | 5 | 6;
30
+
31
+ /** Editing a calendar: moving, resizing and dragging across resources through the grid's editing contract. */
32
+ export interface GridCalendarEditing<Row extends GridRow = GridRow> {
33
+ /** Events move (default true). */
34
+ move?: boolean;
35
+ /** Events change their start or end (default true; needs an end column). */
36
+ resize?: boolean;
37
+ /** Events move across resources in the timeline and resource columns (default true; needs a resource column). */
38
+ resources?: boolean;
39
+ /** Events may overlap on one resource (default true); false refuses a drop that overlaps. */
40
+ overlap?: boolean;
41
+ /** Events stay inside working hours, the resource's business hours and outside unavailable time (default false). */
42
+ workingHours?: boolean;
43
+ /** A text column of comma-separated resource ids each record may move to. */
44
+ allowedResources?: GridColumnId<Row>;
45
+ /** Minutes a drag snaps to: 1, 5, 10, 15, 20, 30 or 60 (default slotMinutes). */
46
+ snapMinutes?: 1 | 5 | 10 | 15 | 20 | 30 | 60;
47
+ /** "auto" (default) commits each drop through commitChanges; "manual" leaves changes for the edit bar. */
48
+ commit?: "auto" | "manual";
49
+ }
50
+
51
+ /** The resources of the timeline and of resource columns: an ordinary CanopyX tree, with aggregates in its columns. */
52
+ export interface GridCalendarResources {
53
+ /** A tree view document (inline roots, or a remote source with lazy children); node ids are resource ids. */
54
+ view: InlineView | RemoteView;
55
+ /** The resource pane's width, 120..800 pixels (default 280). */
56
+ width?: number;
57
+ /** The heading of the resource pane in print. */
58
+ label?: string;
59
+ /** Tree column ids filled with each resource's (and group's) event count, busy hours or overlap count. */
60
+ aggregates?: Readonly<Record<string, "count" | "busy" | "overlap">>;
61
+ }
62
+
63
+ /** A background range: a holiday, a freeze, a maintenance window, or time a resource is unavailable. */
64
+ export interface GridCalendarRange {
65
+ start: string;
66
+ end: string;
67
+ label: string;
68
+ tone?: string;
69
+ /** A resource id; absent covers every resource. */
70
+ resource?: string;
71
+ kind?: "background" | "unavailable";
72
+ /** An RRULE (the calendar's subset) the range repeats by. */
73
+ recurrence?: string;
74
+ /** Shades the time outside the range (outside the union of the inverse ranges of the same resource, or the global ones); the label names the shaded time. */
75
+ inverse?: boolean;
76
+ }
77
+
78
+ /** The calendar field of a grid definition (the C# CanopyCalendar writes it). Columns are the grid's own column ids. */
79
+ export interface GridCalendarDefinition<Row extends GridRow = GridRow> {
80
+ /** The date column with each event's start (required). */
81
+ start: GridColumnId<Row>;
82
+ end?: GridColumnId<Row>;
83
+ title?: GridColumnId<Row>;
84
+ subtitle?: GridColumnId<Row>;
85
+ /** A text column holding booleans: true makes an all-day event (dates read as UTC dates, the end exclusive). */
86
+ allDay?: GridColumnId<Row>;
87
+ /** A text column with the event's resource id (a node id of resources.view). */
88
+ resource?: GridColumnId<Row>;
89
+ /** The column whose presenter draws the event's status; its tone colours the event. */
90
+ status?: GridColumnId<Row>;
91
+ /** A text column with an RRULE (FREQ DAILY, WEEKLY, MONTHLY or YEARLY with INTERVAL, COUNT, UNTIL, BYDAY, BYMONTHDAY, BYMONTH, BYSETPOS, WKST). */
92
+ recurrence?: GridColumnId<Row>;
93
+ /** A text column of EXDATE values separated by commas, semicolons or white space (at most 1,000): instants with Z or an offset, wall times in the series zone, or yyyy-MM-dd dates. */
94
+ exceptions?: GridColumnId<Row>;
95
+ /** With recurrenceId: the id of the series an overriding record replaces an occurrence of. */
96
+ series?: GridColumnId<Row>;
97
+ /** With series: the original start of the replaced occurrence. */
98
+ recurrenceId?: GridColumnId<Row>;
99
+ /** A text column; "background" draws the record as a background range. */
100
+ display?: GridColumnId<Row>;
101
+ /** The end of a series' last occurrence (null for endless), which servers read to find series in a range. */
102
+ seriesEnd?: GridColumnId<Row>;
103
+ view?: GridCalendarView;
104
+ views?: readonly GridCalendarView[];
105
+ /** The first date shown, yyyy-MM-dd (default today). */
106
+ date?: string;
107
+ /** Days of the "days" view, 2..14 (default 3). */
108
+ days?: number;
109
+ firstDay?: GridCalendarWeekday;
110
+ hiddenDays?: readonly GridCalendarWeekday[];
111
+ slotMinutes?: 5 | 10 | 15 | 20 | 30 | 60;
112
+ minTime?: GridCalendarTime;
113
+ maxTime?: GridCalendarTime;
114
+ scrollTime?: GridCalendarTime;
115
+ workingHours?: { days?: readonly GridCalendarWeekday[]; start: GridCalendarTime; end: GridCalendarTime };
116
+ nowIndicator?: boolean;
117
+ /** Events per month cell before "+N more", 1..20, or "auto" from the row height (default). */
118
+ eventLimit?: number | "auto";
119
+ eventStyle?: "quiet" | "strong";
120
+ /** "utc", "local" or an IANA zone; the grid's timeZone by default. An IANA zone is also the zone recurring series expand in (otherwise UTC). */
121
+ timeZone?: string;
122
+ /** true, or the editing settings; absent leaves the calendar read-only. */
123
+ editable?: boolean | GridCalendarEditing<Row>;
124
+ resources?: GridCalendarResources;
125
+ zoom?: GridCalendarZoom;
126
+ zooms?: readonly GridCalendarZoom[];
127
+ /** Concurrency thresholds of group lanes, rising: { at, tone }. */
128
+ capacity?: { thresholds: readonly { at: number; tone: string }[]; label?: string };
129
+ ranges?: readonly GridCalendarRange[];
130
+ /** Business hours per resource (no resource: every resource). */
131
+ availability?: readonly { resource?: string; days?: readonly GridCalendarWeekday[]; start: GridCalendarTime; end: GridCalendarTime }[];
132
+ /** Occurrences one range shows, 1..100000 (default 20000). */
133
+ limit?: number;
134
+ /** The view phones start in. */
135
+ phone?: GridCalendarView;
136
+ /** Which grid toolbar controls show: true (all, default), false (calendar controls only) or a list. */
137
+ toolbar?: boolean | readonly GridCalendarToolbarItem[];
138
+ /** What activating an event opens: the record drawer (default) or a small details popover. */
139
+ details?: "drawer" | "popover";
140
+ /** A text column with the event's description (popover, hover card). */
141
+ description?: GridColumnId<Row>;
142
+ /** A text column with each record's tone name; wins over the status tone. */
143
+ tone?: GridColumnId<Row>;
144
+ /** A text column with each record's source id (see sources). */
145
+ source?: GridColumnId<Row>;
146
+ /** 1..50 event sources with a legend; requires source unless every source has ics. */
147
+ sources?: readonly GridCalendarSource[];
148
+ /** Creating events by click, drag over slots or days, Enter or N; minutes (5..1440, default 60) is a clicked slot's length. */
149
+ create?: boolean | { minutes?: number; allDay?: boolean };
150
+ /** Accepts rows dragged from a grid whose view has dragRows, and elements marked data-canopyx-event. */
151
+ drop?: boolean;
152
+ /** What moving an occurrence of a series changes; this and following need series and recurrenceId. Default ask with them, else all. */
153
+ occurrence?: "ask" | "this" | "following" | "all";
154
+ weekNumbers?: false | "iso" | "locale";
155
+ /** Day names and numbers open that day (default true). */
156
+ navLinks?: boolean;
157
+ /** yyyy-MM-dd, start inclusive, end exclusive: navigation, selection, creation and drops stay inside. */
158
+ validRange?: { start?: string; end?: string };
159
+ /** The month always shows six weeks. */
160
+ fixedWeeks?: boolean;
161
+ /** The month shows the days of the months around it (default true). */
162
+ outsideDays?: boolean;
163
+ /** The timeline's span instead of the zoom's default. */
164
+ span?: { count: number; unit: "day" | "week" | "month" };
165
+ /** Context menus on events, slots, days and timeline cells (default true). */
166
+ menu?: boolean;
167
+ /** A delayed hover card on pointer devices (default true). */
168
+ hover?: boolean;
169
+ /** The year view lists each day's events instead of shading only. */
170
+ yearEvents?: boolean;
171
+ /** The agenda's period (default month). */
172
+ agendaSpan?: "day" | "week" | "month" | "year";
173
+ /** Months of the stacked months view, 2..24 (default 6). */
174
+ months?: number;
175
+ /** A print button in the calendar bar. */
176
+ print?: boolean;
177
+ }
178
+
179
+ /** An occurrence as the calendar shows it. */
180
+ export interface GridCalendarEvent {
181
+ /** The record id, or record@start for an occurrence of a series. */
182
+ readonly id: string;
183
+ readonly record: string;
184
+ readonly start: string;
185
+ readonly end: string;
186
+ readonly allDay: boolean;
187
+ readonly title: string;
188
+ readonly resource: string | null;
189
+ readonly recurring: boolean;
190
+ readonly background?: boolean;
191
+ /** The event's source id (sources), or null. */
192
+ readonly source?: string | null;
193
+ /** An event of an iCalendar source: read-only, and its record id is not a record of the grid. */
194
+ readonly external?: boolean;
195
+ }
196
+
197
+ /** The template hook: draws an event's content into a fresh element; return true to own it. Text is the host's to escape. */
198
+ export type GridCalendarTemplate = (context: {
199
+ readonly event: GridCalendarEvent;
200
+ readonly row: GridRow;
201
+ readonly element: HTMLElement;
202
+ readonly kind: "bar" | "chip" | "block" | "item" | "lane";
203
+ readonly labels: Readonly<Record<string, string>>;
204
+ }) => boolean | void;
205
+
206
+ /** What a context menu is about. */
207
+ export interface GridCalendarMenuContext {
208
+ readonly kind: "event" | "slot" | "day" | "resource";
209
+ readonly event?: GridCalendarEvent;
210
+ /** yyyy-MM-dd of a slot, day or timeline cell. */
211
+ readonly day?: string;
212
+ /** Minutes after midnight of a slot; null for a day. */
213
+ readonly minutes?: number | null;
214
+ readonly resource?: string | null;
215
+ }
216
+ /** A context menu item: a default (open, move, new) kept by id, or the host's own with a label and run. */
217
+ export interface GridCalendarMenuItem {
218
+ id?: string | null;
219
+ label?: string;
220
+ run?: (context: GridCalendarMenuContext) => unknown;
221
+ disabled?: boolean;
222
+ }
223
+
224
+ /** The host's calendar options. */
225
+ export interface GridCalendarOptions {
226
+ render?: GridCalendarTemplate;
227
+ /** Changes a context menu: return the items to show, null or false for none (the browser's menu stays), or nothing to keep the defaults. */
228
+ menu?: (context: GridCalendarMenuContext, defaults: readonly { readonly id: string; readonly label: string }[]) => readonly GridCalendarMenuItem[] | null | false | void;
229
+ /** Decides how an occurrence change applies before the calendar asks: a mode, false to cancel, or nothing to keep the setting. */
230
+ occurrence?: (change: GridOccurrenceChange) => "this" | "following" | "all" | false | void | PromiseLike<"this" | "following" | "all" | false | void>;
231
+ }
232
+
233
+ /** canopyx:eventCreate (cancelable; cancel it to open your own form): the proposed new event. */
234
+ export interface GridEventCreate {
235
+ readonly start: string;
236
+ readonly end: string;
237
+ readonly allDay: boolean;
238
+ readonly resource: string | null;
239
+ }
240
+ /** canopyx:eventReceive (cancelable): an item dropped on the calendar and where it lands. */
241
+ export interface GridEventReceive extends GridEventCreate {
242
+ readonly item: { readonly source: "grid" | "element"; readonly view?: string; readonly id: string | null; readonly title: string; readonly minutes: number | null; readonly allDay: boolean; readonly cells: Readonly<Record<string, string | number | boolean | null>> };
243
+ }
244
+
245
+ /** A basic calendar's event: no grid schema to write. A yyyy-MM-dd start makes an all-day event. */
246
+ export interface CalendarEventInput {
247
+ id?: string;
248
+ title: string;
249
+ start: Date | string;
250
+ end?: Date | string | null;
251
+ allDay?: boolean;
252
+ description?: string;
253
+ tone?: string;
254
+ resource?: string;
255
+ recurrence?: string;
256
+ exceptions?: string;
257
+ source?: string;
258
+ }
259
+ /** The options of CanopyX.createCalendar: a preset's defaults, each overridden by its own option. */
260
+ export interface CalendarOptions {
261
+ events?: readonly CalendarEventInput[];
262
+ /** basic (default): calendar controls only, read-only, a details popover; standard: search, filters and export; scheduler: editing, creating, the drawer and with resources the timeline. */
263
+ preset?: "basic" | "standard" | "scheduler";
264
+ id?: string;
265
+ label?: string;
266
+ views?: readonly GridCalendarView[];
267
+ view?: GridCalendarView;
268
+ date?: string;
269
+ timeZone?: string;
270
+ firstDay?: GridCalendarWeekday;
271
+ toolbar?: boolean | readonly GridCalendarToolbarItem[];
272
+ details?: "drawer" | "popover";
273
+ /** true opens the record drawer, false the popover. */
274
+ drawer?: boolean;
275
+ /** Adds the Export control to a calendar without a toolbar. */
276
+ export?: boolean;
277
+ editable?: boolean | GridCalendarEditing;
278
+ create?: boolean | { minutes?: number; allDay?: boolean };
279
+ drop?: boolean;
280
+ print?: boolean;
281
+ sources?: readonly GridCalendarSource[];
282
+ /** A resource tree document, or a list of { id, label, parent? }. */
283
+ resources?: readonly { id: string; label?: string; parent?: string | null }[] | InlineView | RemoteView;
284
+ timeline?: boolean;
285
+ live?: boolean | GridLiveDefinition;
286
+ facets?: readonly string[] | GridFacetPanelDefinition;
287
+ links?: boolean;
288
+ /** Any other calendar key, applied last; its functions (render, menu, occurrence) are the host's calendar hooks. */
289
+ calendar?: Omit<Partial<GridCalendarDefinition>, "menu" | "occurrence"> & Omit<GridCalendarOptions, "menu" | "occurrence"> &
290
+ { menu?: boolean | GridCalendarOptions["menu"]; occurrence?: GridCalendarDefinition["occurrence"] | GridCalendarOptions["occurrence"] };
291
+ [hostOption: string]: unknown;
292
+ }
293
+
294
+ /** The calendar's state, from getCalendar() and the canopyx:calendar event. */
295
+ export interface GridCalendarState {
296
+ readonly view: GridCalendarView;
297
+ readonly date: string;
298
+ readonly zoom: GridCalendarZoom;
299
+ readonly from: string;
300
+ readonly to: string;
301
+ readonly timeZone: string;
302
+ readonly events: number;
303
+ readonly collapsed: readonly string[];
304
+ }
305
+
306
+ /** The calendar part of the grid state (saved views keep it). */
307
+ export interface GridCalendarSavedState {
308
+ view: GridCalendarView;
309
+ date: string | null;
310
+ zoom: GridCalendarZoom;
311
+ collapsed?: string[];
312
+ }
313
+
314
+ /** canopyx:occurrenceChange: moving one occurrence of a series; cancel it to keep the series and handle the occurrence yourself. */
315
+ export interface GridOccurrenceChange {
316
+ readonly id: string;
317
+ readonly occurrence: string;
318
+ readonly start: string;
319
+ readonly end: string;
320
+ readonly resource: string | null;
321
+ }
322
+
323
+ /** The request a hosted source's range capability receives for the visible range. */
324
+ export interface GridRangeQuery<Q extends GridQuery = GridQuery> {
325
+ readonly protocol: "canopyx/2"; readonly type: "gridRangeQuery"; readonly view: string;
326
+ readonly query: Q;
327
+ readonly from: string; readonly to: string;
328
+ readonly start: string; readonly end?: string; readonly recurrence?: string; readonly seriesEnd?: string; readonly resource?: string;
329
+ readonly resources?: readonly string[];
330
+ readonly calendarView?: GridCalendarView;
331
+ readonly limit: number;
332
+ }
333
+ /** The answer to a range query: the overlapping records, ordered by start. */
334
+ export interface GridRangePage<Row extends GridRow = GridRow> {
335
+ readonly protocol: "canopyx/2"; readonly type: "gridRangePage"; readonly view: string; readonly revision: string;
336
+ readonly from: string; readonly to: string;
337
+ readonly matched: number; readonly truncated: boolean;
338
+ readonly items: readonly Row[];
339
+ }
340
+ /** A hosted source that answers range queries (CanopyX.AspNetCore maps POST {pattern}/range). */
341
+ export interface GridRangeSource<Row extends GridRow = GridRow> {
342
+ range?(request: GridRangeQuery, options: { signal: AbortSignal }): GridRangePage<Row> | PromiseLike<GridRangePage<Row>>;
343
+ }
344
+
345
+ /** Calendar methods of a flat grid; each loads the calendar part first. */
346
+ export interface GridCalendarApi {
347
+ getCalendar(): GridCalendarState | Promise<GridCalendarState>;
348
+ setCalendarView(view: GridCalendarView): Promise<GridCalendarState>;
349
+ /** yyyy-MM-dd */
350
+ setCalendarDate(date: string): Promise<GridCalendarState>;
351
+ setCalendarZoom(zoom: GridCalendarZoom): Promise<GridCalendarState>;
352
+ calendarStep(direction: 1 | -1): Promise<GridCalendarState>;
353
+ calendarToday(): Promise<GridCalendarState>;
354
+ getCalendarEvents(): readonly GridCalendarEvent[] | Promise<readonly GridCalendarEvent[]>;
355
+ /** iCalendar text of the visible events (default) or of the grid's export scopes. */
356
+ exportCalendar(options?: { scope?: "visible" | "filtered" | "selected" | "all"; fileName?: string; download?: boolean }): Promise<{ blob: Blob; fileName: string; text: string }>;
357
+ /** Opens an event's record (by occurrence or record id). */
358
+ openCalendarEvent(id: string): Promise<unknown>;
359
+ clearCalendarSelection(): void | Promise<void>;
360
+ /** Shows (true) or hides a source's events; omitted switches it. Resolves with whether they show. */
361
+ setCalendarSource(id: string, visible?: boolean): boolean | Promise<boolean>;
362
+ }
@@ -0,0 +1,76 @@
1
+ import type { CellValue } from "./protocol.js";
2
+
3
+ /** Cell-range selection (docs/cell-ranges.md): true, or the switches. */
4
+ export type GridRangeSelection = boolean | {
5
+ /** False turns the pointer and keyboard input off; the API still works. */
6
+ readonly enabled?: boolean;
7
+ /** Ctrl or Cmd adds ranges (default true). */
8
+ readonly multiple?: boolean;
9
+ /** Shows the fill handle on a single range (default false). */
10
+ readonly fillHandle?: boolean;
11
+ };
12
+ /** How cell ranges copy and paste. */
13
+ export interface GridClipboardSettings {
14
+ /** Copies start with the column titles and the group rows (default false). */
15
+ readonly copyHeaders?: boolean;
16
+ /** The shown text or raw values (default "display"). */
17
+ readonly copyValues?: "display" | "raw";
18
+ /** Ctrl/Cmd+V and the cell menu paste (default true). */
19
+ readonly paste?: boolean;
20
+ }
21
+ /** A range: row positions in the shown order and column ids, both inclusive. */
22
+ export interface GridCellRange {
23
+ readonly startRow: number;
24
+ readonly endRow: number;
25
+ readonly startColumn: string;
26
+ readonly endColumn: string;
27
+ }
28
+ /** A cell a paste or fill offers: its row id, column, position, the pasted text, the value read from it and the old value. */
29
+ export interface GridPasteCell {
30
+ readonly id: string;
31
+ readonly column: string;
32
+ readonly row: number;
33
+ readonly text: string;
34
+ readonly value: CellValue;
35
+ readonly previous: CellValue;
36
+ }
37
+ /** A cell that did not take its value, and why. */
38
+ export interface GridPasteRefusal extends GridPasteCell { readonly reason: string; }
39
+ /** The detail of the cancelable canopyx:paste event and the argument of onPaste. */
40
+ export interface GridPasteEvent {
41
+ readonly source: "clipboard" | "api" | "fill";
42
+ /** The cells whose text reads as a value of their column. */
43
+ readonly cells: readonly GridPasteCell[];
44
+ /** The cells refused already: text their column cannot read. */
45
+ readonly refused: readonly GridPasteRefusal[];
46
+ /**
47
+ * A grid without the editing part applies nothing itself: a handler that applies the values answers with the cells it
48
+ * refused (or false for all), so the grid can report them. With the editing part the cells go through editing after the event.
49
+ */
50
+ respondWith(result: { readonly refused?: readonly { readonly id: string; readonly column: string; readonly reason?: string }[] } | boolean |
51
+ PromiseLike<{ readonly refused?: readonly { readonly id: string; readonly column: string; readonly reason?: string }[] } | boolean>): void;
52
+ }
53
+ /** What a paste or fill did. */
54
+ export interface GridPasteResult {
55
+ readonly applied: number;
56
+ readonly refused: readonly GridPasteRefusal[];
57
+ readonly cancelled: boolean;
58
+ }
59
+ export interface GridCopyOptions {
60
+ readonly headers?: boolean;
61
+ readonly values?: "display" | "raw";
62
+ }
63
+ /** Cell-range members of every flat grid. Before the part loads the read answers empty and the actions load it; actions run at once once it is in and answer with a promise that rejects when they fail. */
64
+ export interface GridCellRangeApi {
65
+ getCellRanges(): readonly GridCellRange[];
66
+ /** Replaces the ranges; omitted ends make a range of one cell. */
67
+ setCellRanges(ranges: readonly (Pick<GridCellRange, "startRow" | "startColumn"> & Partial<GridCellRange>)[]): Promise<void>;
68
+ clearCellRanges(): Promise<void>;
69
+ selectAllCells(): Promise<void>;
70
+ /** The ranges (or the focused cell) as tab-separated text, loading rows that are not cached. */
71
+ getCellRangeText(options?: GridCopyOptions): Promise<string>;
72
+ /** Copies the ranges (or the focused cell) as text and a typed table; resolves with the text. */
73
+ copyCellRanges(options?: GridCopyOptions): Promise<string>;
74
+ /** Pastes tab-separated text at a row position and column, or at the ranges. */
75
+ pasteCells(text: string, at?: { readonly row: number; readonly column: string }): Promise<GridPasteResult>;
76
+ }
@@ -0,0 +1,32 @@
1
+ /** A group of columns drawn as a header above them (docs/column-groups.md). Groups nest up to three levels. */
2
+ export interface GridColumnGroup {
3
+ readonly id: string;
4
+ /** Header text, 1 to 256 characters. */
5
+ readonly title: string;
6
+ /** Columns directly below the group, in any order; a column belongs to one group at most. */
7
+ readonly columns?: readonly string[];
8
+ /** Groups nested below this one. */
9
+ readonly groups?: readonly GridColumnGroup[];
10
+ /** Initial pin of every column of a top-level group; null scrolls. Nested groups take none. */
11
+ readonly pinned?: "left" | "right" | null;
12
+ }
13
+ /** A column group as the grid shows it now. */
14
+ export interface GridColumnGroupState {
15
+ readonly id: string;
16
+ readonly title: string;
17
+ /** Every column below the group, in the current column order. */
18
+ readonly columns: readonly string[];
19
+ /** The columns of the group that are on screen. */
20
+ readonly visibleColumns: readonly string[];
21
+ /** The pin of the group's columns. */
22
+ readonly pin: "none" | "left" | "right";
23
+ readonly groups: readonly GridColumnGroupState[];
24
+ }
25
+
26
+ /** Column group members of every flat grid. Before the part loads the read answers empty and the action loads it; the action answers with a promise that rejects when it fails. */
27
+ export interface GridColumnGroupApi {
28
+ /** The groups in their current order. */
29
+ getColumnGroups(): readonly GridColumnGroupState[];
30
+ /** Shows or hides every column of a group. */
31
+ setColumnGroupVisible(id: string, visible: boolean): Promise<void>;
32
+ }