@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
@@ -1,6 +1,7 @@
1
1
  // Generated from CanopyX/Views/Locales/labels.json by Build/Sync-Assets.ps1.
2
2
  (function (global) {
3
3
  const labels = Object.freeze({
4
+ gridNoExportColumns: "Żadna widoczna kolumna nie obsługuje eksportu.",
4
5
  searchPlaceholder: "Szukaj",
5
6
  searchResults: "Wyniki wyszukiwania",
6
7
  searchResultCount: "Wyniki: {count}",
@@ -14,6 +15,24 @@ const labels = Object.freeze({
14
15
  gridFilters: "Filtry",
15
16
  gridFitContent: "Dopasuj do zawartości",
16
17
  gridUnpin: "Odepnij",
18
+ matchesHighlight: "Wyróżniaj dopasowania",
19
+ matchesCount: "[one]{count} dopasowanie[few]{count} dopasowania[many]{count} dopasowań[other]{count} dopasowania",
20
+ matchesPosition: "{current} z {count}",
21
+ matchesNone: "Brak dopasowań",
22
+ matchesLoaded: "[one]{count} dopasowanie we wczytanych wierszach[few]{count} dopasowania we wczytanych wierszach[many]{count} dopasowań we wczytanych wierszach[other]{count} dopasowania we wczytanych wierszach",
23
+ matchesPrevious: "Poprzednie dopasowanie",
24
+ matchesNext: "Następne dopasowanie",
25
+ matchesAnnounce: "Dopasowanie {current} z {count}, {column}",
26
+ layoutMenu: "Układ",
27
+ layoutFit: "Dopasuj do szerokości",
28
+ layoutScroll: "Wszystkie kolumny, przewijanie w poziomie",
29
+ layoutCards: "Karty",
30
+ layoutDensity: "Gęstość",
31
+ layoutCompact: "Zwarta",
32
+ layoutNormal: "Normalna",
33
+ layoutComfortable: "Swobodna",
34
+ layoutChanged: "Układ: {mode}, {density}",
35
+ layoutSort: "Sortuj według",
17
36
  gridWhere: "Gdzie",
18
37
  gridComplexFilter: "Ta kolumna należy do mieszanej grupy warunków. Edytuj ją w Filtrach.",
19
38
  gridClearColumnFilter: "Wyczyść filtr",
@@ -83,6 +102,9 @@ const labels = Object.freeze({
83
102
  gridPreviousPage: "Poprzednia strona",
84
103
  gridNextPage: "Następna strona",
85
104
  gridLastPage: "Ostatnia strona",
105
+ gridPageInfo: "Wyświetlanie wierszy od {first} do {last} z {count}",
106
+ gridPageInfoFiltered: "Wyświetlanie wierszy od {first} do {last} z {count} (odfiltrowano z {total})",
107
+ gridPageButton: "Strona {page}",
86
108
  gridClearQuery: "Wyczyść wyszukiwanie i filtry",
87
109
  gridRemoveSearch: "Wyczyść wyszukiwanie: {search}",
88
110
  gridGroupedFilters: "Grupy filtrów (warunki: {count})",
@@ -92,9 +114,30 @@ const labels = Object.freeze({
92
114
  gridFilteredResults: "Przefiltrowane wyniki",
93
115
  gridSelectedRows: "Zaznaczone wiersze",
94
116
  gridAllResults: "Wszystkie wyniki",
117
+ gridVisibleRows: "Widoczne wiersze",
118
+ gridAllRows: "Wszystkie wiersze",
95
119
  gridDownloadCsv: "Pobierz plik CSV",
96
120
  gridCopy: "Kopiuj",
97
121
  gridDetails: "Szczegóły rekordu",
122
+ gridCellRangeSelected: "Zaznaczono wiersze: {rows} × kolumny: {columns}",
123
+ gridCellRangesSelected: "Zaznaczone zakresy: {ranges}, komórki: {cells}",
124
+ gridCellRangeCleared: "Wyczyszczono zaznaczenie komórek",
125
+ gridCopyCells: "Kopiuj komórki",
126
+ gridCopyCellsWithHeaders: "Kopiuj komórki z nagłówkami",
127
+ gridPasteCells: "Wklej",
128
+ gridSelectAllCells: "Zaznacz wszystkie komórki",
129
+ gridCellsCopied: "Skopiowano wiersze: {rows} × kolumny: {columns}",
130
+ gridCellsPasted: "Wklejone komórki: {count}",
131
+ gridPasteRefused: "Niewklejone komórki: {count}",
132
+ gridPasteReadOnly: "Tej komórki nie można zmienić.",
133
+ gridPasteType: "„{value}” nie jest prawidłową wartością dla: {column}.",
134
+ gridPasteReport: "Raport wklejania",
135
+ gridPasteCell: "Wiersz {row}, {column}: {reason}",
136
+ gridFillHandle: "Przeciągnij, aby wypełnić komórki poniżej",
137
+ gridCellsFilled: "Wypełnione komórki: {count}",
138
+ gridCellMenu: "Akcje komórek",
139
+ gridClearCellRanges: "Wyczyść zaznaczenie komórek",
140
+ gridRowPicked: "Podniesiono {title}. Przejdź do kalendarza i naciśnij Enter, aby go upuścić.",
98
141
  gridColumn: "Kolumna",
99
142
  gridOperator: "Warunek",
100
143
  gridValue: "Wartość (daty w UTC)",
@@ -174,6 +217,28 @@ const labels = Object.freeze({
174
217
  gridGroupCollapse: "Zwiń grupę",
175
218
  gridSummary: "Podsumowanie wyników",
176
219
  gridGroupOrder: "Kolejność grup jest ustalona w raporcie",
220
+ gridAggregateCount: "liczba {value}",
221
+ gridAggregateSum: "suma {value}",
222
+ gridAggregateAverage: "śr. {value}",
223
+ gridAggregateMinimum: "min. {value}",
224
+ gridAggregateMaximum: "maks. {value}",
225
+ gridGroupBy: "Grupuj według tej kolumny",
226
+ gridUngroup: "Przestań grupować według tej kolumny",
227
+ gridGroupDrop: "Przeciągnij tutaj nagłówek kolumny, aby pogrupować wiersze",
228
+ gridExpandAll: "Rozwiń wszystko",
229
+ gridCollapseAll: "Zwiń wszystko",
230
+ gridExpandLevel: "Rozwiń poziom {level}",
231
+ gridCollapseLevel: "Zwiń poziom {level}",
232
+ gridGroupMove: "Alt+Strzałka w lewo i Alt+Strzałka w prawo przesuwają ten poziom",
233
+ gridGroupSortBy: "Sortuj grupy według",
234
+ gridGroupSortValue: "według wartości",
235
+ gridGroupSortAggregate: "według: {aggregate}",
236
+ gridSelectGroup: "Zaznacz rekordy grupy {group}",
237
+ gridAggregateDistinct: "unikalne {value}",
238
+ gridShowDetail: "Pokaż szczegóły",
239
+ gridHideDetail: "Ukryj szczegóły",
240
+ gridDetailOf: "Szczegóły: {record}",
241
+ gridDetailFailed: "Nie udało się wczytać szczegółów: {error}",
177
242
  gridExportProgress: "Rekordy: {completed} z {total}",
178
243
  gridExportReading: "Rekordy: {completed}",
179
244
  gridExportCancelled: "Eksport anulowany",
@@ -208,11 +273,250 @@ const labels = Object.freeze({
208
273
  showMoreUnknownTotal: "Pokaż więcej (wczytano {loaded})",
209
274
  pageLoaded: "Wczytano {loaded} z {total}",
210
275
  itemsLoaded: "Elementy: {count}",
276
+ recordBack: "Wstecz",
277
+ recordBackTo: "Wróć do: {record}",
278
+ recordTrail: "Ścieżka rekordów",
279
+ recordShowing: "Wyświetlono: {record}",
280
+ recordTabs: "Widoki rekordu",
281
+ recordSections: "Przejdź do sekcji",
282
+ recordOtherFields: "Pozostałe pola",
283
+ recordShowEmpty: "Pokaż puste pola ({count})",
284
+ recordHideEmpty: "Ukryj puste pola",
285
+ recordActions: "Akcje rekordu",
286
+ recordCopyValues: "Kopiuj wartości",
287
+ recordCopyJson: "Kopiuj jako JSON",
288
+ recordCopyLink: "Kopiuj link",
289
+ recordCopied: "Skopiowano do schowka",
290
+ recordPrint: "Drukuj rekord",
291
+ recordExportCsv: "Eksportuj CSV",
292
+ recordExportJson: "Eksportuj JSON",
293
+ recordOpenAll: "Otwórz wszystkie w tabeli",
294
+ recordLoadMore: "Wczytaj więcej",
295
+ recordCount: "{shown} z {total}",
296
+ recordItems: "Elementy: {count}",
297
+ recordMore: "+{count}",
298
+ recordShowAll: "Pokaż wszystkie ({count})",
299
+ recordRetry: "Ponów",
300
+ recordLoadFailed: "Nie udało się wczytać szczegółów rekordu: {error}",
301
+ recordUnavailable: "Rekord {id} nie jest tutaj dostępny.",
302
+ recordField: "Pole",
303
+ recordValue: "Wartość",
304
+ recordSection: "Sekcja",
305
+ recordBefore: "Przed",
306
+ recordAfter: "Po",
307
+ recordAdded: "Dodano",
308
+ recordRemoved: "Usunięto",
309
+ recordChanged: "Zmienione pola: {count}",
211
310
  yes: "Tak",
212
311
  no: "Nie",
213
312
  utcTime: "{time} UTC",
214
313
  localTime: "{time} czasu lokalnego",
215
314
  mountError: "Nie można wyświetlić widoku: {error}",
315
+ gridEditCell: "Edytuj: {column}",
316
+ gridEditSave: "Zapisz",
317
+ gridEditCancel: "Anuluj",
318
+ gridEditDiscard: "Odrzuć zmiany",
319
+ gridEditUndo: "Cofnij",
320
+ gridEditRedo: "Ponów",
321
+ gridEditEdited: "Zmieniono",
322
+ gridEditChanges: "Niezapisane zmiany: {count}",
323
+ gridEditErrors: "Błędy: {count}",
324
+ gridEditSaving: "Zapisywanie…",
325
+ gridEditSaved: "Zapisane wiersze: {count}",
326
+ gridEditFailed: "Niezapisane wiersze: {count}",
327
+ gridEditRequired: "{column}: pole wymagane.",
328
+ gridEditNumber: "{column}: wpisz liczbę.",
329
+ gridEditDate: "{column}: wpisz poprawną datę.",
330
+ gridEditMin: "{column}: wartość nie może być mniejsza niż {min}.",
331
+ gridEditMax: "{column}: wartość nie może być większa niż {max}.",
332
+ gridEditStep: "{column}: wartość musi być wielokrotnością {step}.",
333
+ gridEditMinLength: "{column}: minimalna liczba znaków to {min}.",
334
+ gridEditMaxLength: "{column}: maksymalna liczba znaków to {max}.",
335
+ gridEditPattern: "{column}: niepoprawny format.",
336
+ gridEditChoice: "{column}: wybierz wartość z listy.",
337
+ gridEditConflict: "Ktoś inny zmienił ten wiersz. Odśwież go i spróbuj ponownie.",
338
+ gridEditRejected: "Nie zapisano: {error}",
339
+ gridEditNotSaved: "Nie zapisano.",
340
+ gridEditNoMatches: "Brak dopasowań",
341
+ gridEditSearching: "Wyszukiwanie…",
342
+ gridEditUndone: "Cofnięto: {column}",
343
+ gridEditRedone: "Ponowiono: {column}",
344
+ gridEditNone: "(brak)",
345
+ gridLiveOrderChanged: "Kolejność się zmieniła",
346
+ gridLiveResort: "Sortuj ponownie",
347
+ gridLiveNewData: "Nowe dane",
348
+ gridLiveRefresh: "Odśwież",
349
+ gridLiveOrderHint: "Wiersze zostają na swoich miejscach, gdy dane się zmieniają. Posortuj ponownie, aby przenieść je na miejsca zgodne z sortowaniem.",
350
+ gridLiveChanged: "Zmienione wiersze: dodane {added}, zaktualizowane {updated}, usunięte {removed}",
351
+ gridLiveSorted: "Wiersze przeniesiono na miejsca zgodne z sortowaniem.",
352
+ gridLiveRecordRemoved: "Ten rekord został usunięty.",
353
+ gridFacetPanel: "Filtruj według",
354
+ gridFacetPanelHide: "Ukryj panel filtrów",
355
+ gridFacetPanelShow: "Pokaż panel filtrów",
356
+ gridFacetShowMore: "Pokaż więcej: {count}",
357
+ gridFacetShowFewer: "Pokaż mniej",
358
+ gridFacetEmptyValue: "(Puste)",
359
+ gridFacetFrom: "Od",
360
+ gridFacetTo: "Do",
361
+ gridFacetHistogram: "Rozkład: {column}",
362
+ gridFacetBin: "Od {from} do {to}, wiersze: {count}",
363
+ gridFacetNoChart: "Zbyt wiele wartości do wykresu",
364
+ gridFacetClear: "Wyczyść: {column}",
365
+ gridFacetCustom: "Tę kolumnę filtruje inny warunek.",
366
+ gridFacetResult: "Pasujące wiersze: {count}",
367
+ gridFacetSelected: "Zaznaczone: {count}",
368
+ gridFacetValueCount: "{value}, wiersze: {count}",
369
+ gridFacetCollapse: "Zwiń: {column}",
370
+ gridFacetExpand: "Rozwiń: {column}",
371
+ gridFacetInvalid: "Wpisz poprawną wartość.",
372
+ gridFacetReversed: "Wartość „Od” nie może być późniejsza niż „Do”.",
373
+ linkFilteredBy: "Filtr z {source}: {values}",
374
+ linkRemoveFilter: "Usuń filtr z {source}: {values}",
375
+ linkFiltered: "Filtr z {source}, wiersze: {count}",
376
+ linkHighlighted: "Wyróżnione wiersze z {source}: {count}",
377
+ linkHighlightedRows: "Wyróżnione wiersze: {count}",
378
+ linkCleared: "Usunięto powiązane filtry",
379
+ formatRules: "Formatowanie warunkowe",
380
+ formatLegend: "Legenda formatowania",
381
+ formatUpTo: "Do",
382
+ formatAbove: "Powyżej",
383
+ formatHiddenFlagged: "Sformatowane ukryte pola: {count} ({rules})",
384
+ formatRule: "Reguła {number}",
385
+ formatAddRule: "Dodaj regułę",
386
+ formatEditRule: "Edytuj: {rule}",
387
+ formatDeleteRule: "Usuń: {rule}",
388
+ formatMoveUp: "Przenieś wyżej: {rule}",
389
+ formatMoveDown: "Przenieś niżej: {rule}",
390
+ formatEnableRule: "Stosuj: {rule}",
391
+ formatNoRules: "Brak reguł formatowania.",
392
+ formatName: "Nazwa",
393
+ formatDescription: "Opis dla czytnika ekranu",
394
+ formatOnlyRowsWhere: "Tylko wiersze, w których",
395
+ formatEveryRow: "Każdy wiersz",
396
+ formatNone: "Żaden",
397
+ formatApplyTo: "Zastosuj do",
398
+ formatTargetCell: "Komórka",
399
+ formatTargetRow: "Cały wiersz",
400
+ formatTargetColumns: "Wybrane kolumny",
401
+ formatStyle: "Styl",
402
+ formatHighlight: "Wyróżnienie",
403
+ formatDataBar: "Pasek danych",
404
+ formatColorScale: "Skala kolorów",
405
+ formatBands: "Progi",
406
+ formatTone: "Ton",
407
+ formatEmphasis: "Wyróżnienie tonu",
408
+ formatFill: "Wypełnienie",
409
+ formatTextOnly: "Kolor tekstu",
410
+ formatStrong: "Pogrubione wypełnienie",
411
+ formatIcon: "Ikona",
412
+ formatNoIcon: "Bez ikony",
413
+ formatAutomatic: "Automatycznie",
414
+ formatBadge: "Plakietka",
415
+ formatCue: "Wskazówka tekstowa",
416
+ formatLowest: "Najniższa",
417
+ formatMidpoint: "Punkt środkowy",
418
+ formatHighest: "Najwyższa",
419
+ formatAddBand: "+ Próg",
420
+ formatRemoveBand: "Usuń próg",
421
+ formatSave: "Zapisz regułę",
422
+ formatCancel: "Anuluj",
423
+ formatShowLegend: "Pokaż legendę",
424
+ formatInvalid: "Uzupełnij regułę przed zapisaniem.",
425
+ formatMatchCase: "Uwzględnij wielkość liter",
426
+ formatToneDanger: "Zagrożenie",
427
+ formatToneWarning: "Ostrzeżenie",
428
+ formatToneSuccess: "Sukces",
429
+ formatToneInfo: "Informacja",
430
+ formatToneNeutral: "Neutralny",
431
+ formatToneMuted: "Wyciszony",
432
+ formatNotContains: "nie zawiera",
433
+ formatEndsWith: "kończy się na",
434
+ formatNotIn: "nie jest żadną z",
435
+ formatBetween: "między",
436
+ formatLike: "pasuje do wzorca z symbolami wieloznacznymi",
437
+ formatMatches: "pasuje do wyrażenia",
438
+ formatOlderThan: "starsze niż (dni)",
439
+ formatWithinLast: "w ciągu ostatnich (dni)",
440
+ formatNotLike: "nie pasuje do wzorca z symbolami wieloznacznymi",
441
+ formatNotMatches: "nie pasuje do wyrażenia",
442
+ formatBetweenExclusive: "między (bez granic)",
443
+ calendarToday: "Dzisiaj",
444
+ calendarPrevious: "Poprzedni okres",
445
+ calendarNext: "Następny okres",
446
+ calendarViews: "Widok kalendarza",
447
+ calendarMonth: "Miesiąc",
448
+ calendarWeek: "Tydzień",
449
+ calendarDay: "Dzień",
450
+ calendarDays: "{count} dni",
451
+ calendarAgenda: "Harmonogram",
452
+ calendarYear: "Rok",
453
+ calendarTimeline: "Oś czasu",
454
+ calendarGoTo: "Przejdź do daty",
455
+ calendarAllDay: "Cały dzień",
456
+ calendarMore: "+{count} więcej",
457
+ calendarMoreLabel: "Pokaż więcej wydarzeń z dnia {date}: {count}",
458
+ calendarDayEvents: "Wydarzenia z dnia {date}",
459
+ calendarNoEvents: "Brak wydarzeń w tym okresie",
460
+ calendarEvents: "[one]{count} wydarzenie[few]{count} wydarzenia[many]{count} wydarzeń[other]{count} wydarzenia",
461
+ calendarShowing: "{view}, {range}",
462
+ calendarRepeats: "Powtarza się",
463
+ calendarTruncated: "Pokazano pierwsze wydarzenia: {count}. Zawęź okres lub filtry, aby zobaczyć resztę.",
464
+ calendarLoading: "Wczytywanie wydarzeń…",
465
+ calendarLoadError: "Nie udało się wczytać wydarzeń: {error}",
466
+ calendarNow: "Teraz",
467
+ calendarZoom: "Skala",
468
+ calendarZoomHour: "Godziny",
469
+ calendarZoomDay: "Dni",
470
+ calendarZoomWeek: "Tygodnie",
471
+ calendarZoomMonth: "Miesiące",
472
+ calendarZoomQuarter: "Kwartały",
473
+ calendarResources: "Zasoby",
474
+ calendarCapacity: "Równoczesne wydarzenia",
475
+ calendarCapacityAt: "Jednocześnie: {count}",
476
+ calendarBusy: "Zajęte: {hours} h",
477
+ calendarOverlaps: "[one]{count} kolizja[few]{count} kolizje[many]{count} kolizji[other]{count} kolizji",
478
+ calendarUnavailable: "Niedostępne",
479
+ calendarOutsideHours: "Poza godzinami pracy",
480
+ calendarConflict: "Koliduje z: {title}",
481
+ calendarNotAllowed: "{resource} nie może przyjąć tego wydarzenia",
482
+ calendarMoved: "Przeniesiono {title} na {time}",
483
+ calendarResized: "Nowy koniec wydarzenia {title}: {time}",
484
+ calendarSeriesMoved: "Przeniesiono wszystkie wystąpienia: {title}",
485
+ calendarSeriesTime: "Tutaj można przesunąć tylko godzinę całej serii.",
486
+ calendarMoveHelp: "Strzałki przesuwają, Shift ze strzałkami zmienia koniec, Alt ze strzałką w górę lub w dół zmienia zasób, Enter zapisuje, Escape anuluje.",
487
+ calendarEdit: "Przenieś lub zmień długość: {title}",
488
+ calendarSaveFailed: "Nie zapisano {title}: {error}",
489
+ calendarExport: "iCalendar (.ics)",
490
+ calendarTimeRange: "{start} – {end}",
491
+ calendarSelected: "Zaznaczono: {range}",
492
+ calendarLane: "{resource}, {events}",
493
+ calendarHighlighted: "[one]Wyróżniono {count} wydarzenie[few]Wyróżniono {count} wydarzenia[many]Wyróżniono {count} wydarzeń[other]Wyróżniono {count} wydarzenia",
494
+ calendarMini: "Mały miesiąc",
495
+ calendarWeekList: "Lista tygodnia",
496
+ calendarDayList: "Lista dnia",
497
+ calendarMonths: "Miesiące",
498
+ calendarWeekNumber: "Tydzień {number}",
499
+ calendarWeekShort: "T{number}",
500
+ calendarNewEvent: "Nowe wydarzenie",
501
+ calendarEventTitle: "Tytuł",
502
+ calendarCreate: "Dodaj",
503
+ calendarCancel: "Anuluj",
504
+ calendarCreated: "Dodano {title} na {time}",
505
+ calendarReceived: "Zaplanowano {title} na {time}",
506
+ calendarOccurrenceTitle: "Zmień wydarzenie cykliczne",
507
+ calendarOccurrenceReadOnly: "Nie można zapisać tej części serii, ponieważ niektóre wartości są tylko do odczytu.",
508
+ calendarThisEvent: "To wydarzenie",
509
+ calendarThisAndFollowing: "To i następne wydarzenia",
510
+ calendarAllEvents: "Wszystkie wydarzenia",
511
+ calendarSources: "Kalendarze",
512
+ calendarImportFailed: "Nie udało się odczytać {source}: {error}",
513
+ calendarActions: "Akcje dla {title}",
514
+ calendarOpen: "Otwórz",
515
+ calendarMove: "Przenieś",
516
+ calendarNewHere: "Nowe wydarzenie tutaj",
517
+ calendarOutsideRange: "Poza datami, które pokazuje ten kalendarz",
518
+ calendarClose: "Zamknij",
519
+ calendarDetailsOf: "Szczegóły: {title}",
216
520
  });
217
521
  const staticLabels = Object.freeze({
218
522
  overflowNote: "Pokazano {shown} z {total} wierszy.",
@@ -0,0 +1,48 @@
1
+ /* The Layout menu: radio groups for the mode and the density. */
2
+ .cx-chrome .cx-grid-layout > .cx-grid-panel{display:block;width:var(--cx-size-244px);padding:var(--cx-size-6px) var(--cx-size-8px);}
3
+ .cx-layout-group{padding:var(--cx-size-4px) 0;}
4
+ .cx-layout-group + .cx-layout-group{border-top:var(--cx-size-1px) solid var(--cx-line);margin-top:var(--cx-size-4px);padding-top:var(--cx-size-8px);}
5
+ .cx-layout-title{padding:0 var(--cx-size-6px) var(--cx-size-4px);font-size:var(--cx-size-12px);font-weight:700;color:var(--cx-muted);}
6
+ .cx-layout-choice{display:flex;align-items:center;gap:var(--cx-size-8px);min-height:var(--cx-size-32px);padding:0 var(--cx-size-6px);border-radius:var(--cx-radius-sm);cursor:pointer;}
7
+ .cx-layout-choice:hover{background:var(--cx-hover-bg);}
8
+ .cx-layout-choice input{flex:none;width:var(--cx-size-16px);height:var(--cx-size-16px);margin:0;accent-color:var(--cx-accent);}
9
+ .cx-layout-choice:has(input:focus-visible){outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:calc(-1 * var(--cx-size-2px));}
10
+ .cx-chrome.cx-phone .cx-grid-layout > summary{width:var(--cx-size-44px);font-size:0;padding:0;}
11
+ .cx-chrome.cx-phone .cx-layout-choice{min-height:var(--cx-size-44px);}
12
+ .cx-layouts:not(.cx-data-grid)[data-cx-density="compact"]{--cx-font-size:13px;--cx-cell-px:6px;}
13
+ .cx-layouts:not(.cx-data-grid)[data-cx-density="comfortable"]{--cx-cell-px:12px;}
14
+ .cx-layouts:not(.cx-data-grid)[data-cx-layout="scroll"] .cx-hcell:first-child,.cx-layouts:not(.cx-data-grid)[data-cx-layout="scroll"] .cx-row > .cx-tree{position:sticky;left:0;z-index:1;}
15
+ .cx-layouts:not(.cx-data-grid)[data-cx-layout="scroll"] .cx-hcell:first-child{z-index:2;background:var(--cx-head-bg);}
16
+ .cx-layouts:not(.cx-data-grid)[data-cx-layout="scroll"] .cx-row > .cx-tree{background:inherit;}
17
+ .cx-data-grid[data-cx-layout="cards"] .cx-grid{overflow-x:hidden;}
18
+ .cx-data-grid[data-cx-layout="cards"] :is(.cx-canvas,.cx-head){width:100% !important;min-width:0;}
19
+ .cx-data-grid[data-cx-layout="cards"] .cx-head{display:none;}
20
+ .cx-chrome .cx-grid-sort > .cx-grid-panel{display:block;width:var(--cx-size-280px);padding:var(--cx-size-6px) var(--cx-size-8px);}
21
+ .cx-sort-list{display:flex;flex-direction:column;gap:var(--cx-size-2px);}
22
+ .cx-grid-sort .cx-grid-selection-controls{padding:var(--cx-size-4px) var(--cx-size-6px) var(--cx-size-8px);margin-bottom:var(--cx-size-6px);border-bottom:var(--cx-size-1px) solid var(--cx-line);}
23
+ .cx-sort-choice{display:flex;align-items:center;gap:var(--cx-size-4px);min-height:var(--cx-size-32px);}
24
+ .cx-chrome .cx-sort-choice .cx-sort-column{flex:1;min-width:0;justify-content:start;border:0;border-radius:var(--cx-radius-sm);background:transparent;overflow:hidden;text-overflow:ellipsis;}
25
+ .cx-chrome .cx-sort-choice span.cx-sort-column{padding:0 var(--cx-size-11px);color:var(--cx-muted);}
26
+ .cx-chrome .cx-sort-choice .cx-sort-column[aria-pressed="true"]{color:var(--cx-accent-text);background:var(--cx-accent-soft);font-weight:600;}
27
+ .cx-chrome .cx-sort-choice .cx-sort-menu{flex:none;border:0;background:transparent;color:var(--cx-text-2);}
28
+ .cx-chrome.cx-phone .cx-grid-sort > summary{width:var(--cx-size-44px);font-size:0;padding:0;}
29
+ .cx-chrome.cx-phone .cx-sort-choice{min-height:var(--cx-size-44px);}
30
+ .cx-chrome.cx-phone .cx-sort-choice .cx-button{min-height:var(--cx-size-44px);}
31
+ .cx-data-grid[data-cx-layout="cards"] .cx-row:not(.cx-status):not(.cx-grid-group){
32
+ width:100% !important;min-width:0;display:grid;grid-template-columns:repeat(var(--cx-card-cols,1),minmax(0,1fr));grid-template-rows:var(--cx-card-title);grid-auto-rows:var(--cx-card-field);
33
+ grid-auto-flow:row dense;align-content:start;column-gap:var(--cx-size-16px);row-gap:var(--cx-card-gap);padding:var(--cx-card-pad) var(--cx-size-16px);
34
+ }
35
+ .cx-data-grid[data-cx-layout="cards"] .cx-row:is(.cx-status,.cx-grid-group){width:100% !important;}
36
+ .cx-data-grid[data-cx-layout="cards"] .cx-row:not(.cx-status):not(.cx-grid-group) > .cx-cell{
37
+ width:auto !important;height:auto;min-width:0;padding:0;position:relative !important;left:auto !important;right:auto !important;box-shadow:none;background:transparent;
38
+ flex-direction:column;align-items:flex-start;justify-content:center;gap:var(--cx-size-1px);text-align:left;
39
+ }
40
+ .cx-data-grid[data-cx-layout="cards"] .cx-row:not(.cx-status):not(.cx-grid-group) > .cx-cell:first-child{grid-column:1/-1;height:var(--cx-card-title);flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--cx-size-6px);font-weight:600;font-size:calc(var(--cx-font-size) + 1px);}
41
+ .cx-data-grid[data-cx-layout="cards"] .cx-row:not(.cx-status):not(.cx-grid-group) > .cx-cell[data-cx-card="wide"]{grid-column:span var(--cx-card-span,1);}
42
+ .cx-data-grid[data-cx-layout="cards"] .cx-cell[data-cx-label]::before{content:attr(data-cx-label) / "";display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--cx-size-11d5px);font-weight:600;line-height:1.35;color:var(--cx-muted);}
43
+ .cx-data-grid[data-cx-layout="cards"] .cx-cell > :is(.cx-text,.cx-presenter-text){max-width:100%;}
44
+ .cx-data-grid[data-cx-layout="cards"] .cx-row:not(.cx-status):not(.cx-grid-group) > .cx-cell:first-child::before{content:none;}
45
+ .cx-data-grid[data-cx-layout="cards"] .cx-row[aria-selected="true"]{box-shadow:inset var(--cx-size-3px) 0 0 var(--cx-accent);}
46
+ @media (forced-colors:active){
47
+ .cx-data-grid[data-cx-layout="cards"] .cx-row[aria-selected="true"]{forced-color-adjust:none;box-shadow:inset var(--cx-size-3px) 0 0 Highlight;}
48
+ }
@@ -0,0 +1,39 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"fa8c686f21626884",install(context){if(installed.has(context.VIEW_MODES))return;const{VIEW_MODES,TreeGrid,h,setText,fill,numberFormat,foldText,cellText,cellValue,isCellObject,setAttr,toneOf,watchFlyout,densityRowHeight,MAX_PROTOCOL_INTEGER,LAYOUT_DENSITIES,plural,svgIcon}=context;const CARD_METRICS={compact:{pad:8,field:36,gap:4,title:24},default:{pad:12,field:40,gap:6,title:26},comfortable:{pad:16,field:44,gap:8,title:28}};const CARD_FIELD=140,CARD_GUTTER=16,CARD_COLUMN_GAP=16,CARD_WIDE=["longText","tags","list"];function cardWide(column){return!!column.wrap||!!column.flex||CARD_WIDE.includes(column.presenter?.kind)}
2
+ function cardGeometry(view){const metrics=CARD_METRICS[view.density],width=Math.max(0,(view.grid.clientWidth||view.host.clientWidth)- 2*CARD_GUTTER);const fields=(view.cols||[]).slice(1),most=Math.max(1,Math.floor((width+CARD_COLUMN_GAP)/ (CARD_FIELD + CARD_COLUMN_GAP)));
3
+ const slots=fields.reduce((sum,field)=>sum +(cardWide(field)&&most>1?2:1),0)||1;const columns=Math.min(most,Math.ceil(slots / Math.ceil(slots / most))), span = Math.min(2, columns), rows = [];
4
+ for(const field of fields){const size=cardWide(field)?span:1;for(let row=0,placed=false;!placed;row++){const cells=rows[row]||=new Array(columns).fill(false);for(let at=0;at+size<=columns&&!placed;at++)if(cells.slice(at,at+size).every(used=>!used)){cells.fill(true,at,at+size);placed=true}}}
5
+ const lines=rows.length;return{columns,span,metrics,height:2*metrics.pad+metrics.title +(lines?metrics.gap+lines*metrics.field +(lines-1)*metrics.gap:0)+ 1}}
6
+ function cardStyle(view,geometry){const style=view.host.style,{metrics}=geometry;style.setProperty("--cx-card-cols",String(geometry.columns));style.setProperty("--cx-card-span",String(geometry.span));style.setProperty("--cx-card-pad",metrics.pad+"px");style.setProperty("--cx-card-field",metrics.field+"px");style.setProperty("--cx-card-gap",metrics.gap+"px");style.setProperty("--cx-card-title",metrics.title+"px")}
7
+ function layoutAnchor(view){const rows=view.rowProjection||view,top=view.logicalTop(),count=rows.rowCount();if(!count)return null;const index=rows.rowAt(top),height=(view.autoRows?null:view.rowH)||1;return{index,share:Math.max(0,Math.min(1,(top-rows.rowTop(index))/ height)) };
8
+ }
9
+ function layoutRows(view,anchor){const rows=view.rowProjection||view;for(const row of[...view.rowCache.values(),...view.placeholders.values()])row.hpx=view.rowH;if(view.autoRows){view.rowOffsets=null;view.rowHeights?.clear();view.measureNeeded=true;view.render()}
10
+ else{const bounds=view.rowBounds(),count=view.rowProjection?rows.rowCount():Math.max(0,bounds.last-bounds.first+1);view.total=count*view.rowH;view.syncScrollRange(anchor?rows.rowTop(anchor.index)+ anchor.share*view.rowH:0)}
11
+ if(anchor&&view.autoRows)view.setLogicalTop(rows.rowTop(anchor.index));view.render()}
12
+ function layoutApplyGrid(view,mode){const anchor=layoutAnchor(view);if(mode==="cards"){if(view.cardAutoRows===undefined){view.cardAutoRows=view.autoRows;view.autoRows=false}}
13
+ else if(view.cardAutoRows!==undefined){view.autoRows=view.cardAutoRows;view.cardAutoRows=undefined;view.rowOffsets=null}
14
+ view.fitFont=null;view.fitKey=null;view.layout=(view.layout||0)+ 1;view.version++;view.layoutApplying=true;try{view.buildHeader();view.syncColumnControls()}finally{view.layoutApplying=false}
15
+ if(mode==="cards"){const geometry=cardGeometry(view);cardStyle(view,geometry);view.rowH=geometry.height}
16
+ else view.rowH=densityRowHeight(view,view.density);layoutRows(view,anchor);view.syncPinnedShadows?.()}
17
+ function layoutApplyTree(view){const before=view.rowH,after=densityRowHeight(view,view.density);if(before!==after){const anchor=view.captureScrollAnchor();view.rowH=after;const status=row=>{if(row&&row.hpx===before)row.hpx=after};status(view.root._status);for(const row of view.keyMap.values()){if(!row.h?.detail&&row.hpx===before)row.hpx=after;status(row._status)}
18
+ for(const row of view.rows)if(row.status)status(row);view.retop();if(anchor)view.restoreScrollAnchor(anchor)}
19
+ view.fitKey=null;view.version++;if(view.fitReady)view.applyWidths();view.render()}
20
+ function layoutApply(view,mode,density){const active=document.activeElement,held=view.canvas.contains(active)?active:null;const cell=held?.closest(".cx-cell"),row=view.focused,column=cell&&view.cols[view.rowCells(cell.parentNode).indexOf(cell)]?.id;view.layoutMode=mode;view.density=density;view.host.setAttribute("data-cx-density",density);if(mode==="fit")view.host.removeAttribute("data-cx-layout");else view.host.setAttribute("data-cx-layout",mode);view.host.style.setProperty("--cx-row-h",densityRowHeight(view,density)+ "px");if(view.kind==="grid")layoutApplyGrid(view,mode);else layoutApplyTree(view);if(held&&row&&view.rendered.get(row)){const at=column?view.cols.findIndex(item=>item.id===column):-1;if(at>=0)view.focusCell(row,at,null);else view.rendered.get(row).focus({preventScroll:true})}}
21
+ const LAYOUT_ICON='<rect x="4" y="4" width="16" height="7" rx="1.5"/><rect x="4" y="13" width="16" height="7" rx="1.5"/>';let layoutSeq=0;function layoutGroup(view,legend,name,choices,current,choose){const group=h("div","cx-layout-group"),title=h("div","cx-layout-title");title.id=name+"-title";group.setAttribute("role","radiogroup");group.setAttribute("aria-labelledby",title.id);setText(title,legend);group.appendChild(title);for(const[value,text]of choices){const label=h("label","cx-layout-choice"),input=h("input");input.type="radio";input.name=name;input.value=value;input.checked=value===current;input.addEventListener("change",()=>{if(input.checked)choose(value)});label.append(input,document.createTextNode(text));group.appendChild(label)}
22
+ return group}
23
+ function layoutModeText(view,mode){return view.labels[mode==="fit"?"layoutFit":mode==="scroll"?"layoutScroll":"layoutCards"]}
24
+ function layoutDensityText(view,density){return view.labels[density==="compact"?"layoutCompact":density==="comfortable"?"layoutComfortable":"layoutNormal"]}
25
+ function layoutMenu(view){if(view.tools.layout===false||typeof view.controlPanel!=="function")return;const{details,panel}=view.controlPanel(view.labels.layoutMenu,"cx-grid-layout"),id=view.id+"-layout-" + ++layoutSeq;const icon=details.firstChild.querySelector("svg");if(icon)icon.replaceWith(svgIcon(LAYOUT_ICON));const choose=change=>Promise.resolve().then(()=>VIEW_MODES.setLayout(view,change)).catch(error=>view.emit("error",{error}));const render=()=>{const options=view.layoutOptions;if(panel.firstChild){for(const input of panel.querySelectorAll("input"))input.checked=input.value===view.layoutMode||input.value===view.density;return}
26
+ panel.replaceChildren(...[options.modes.length>1&&layoutGroup(view,view.labels.layoutMenu,id+"-mode",options.modes.map(mode=>[mode,layoutModeText(view,mode)]),view.layoutMode,mode=>choose({mode})),layoutGroup(view,view.labels.layoutDensity,id+"-density",LAYOUT_DENSITIES.map(density=>[density,layoutDensityText(view,density)]),view.density,density=>choose({density}))].filter(Boolean))};render();view.layoutMenu={details,render};const anchor=view.toolbar.querySelector(".cx-grid-views")||view.spacer;if(anchor&&anchor.parentNode===view.toolbar)view.toolbar.insertBefore(details,anchor)}
27
+ VIEW_MODES.layoutsStart=view=>{if(!view.layoutMenu)layoutMenu(view);if(!view.sortMenu)sortMenu(view);if(view.layoutStarted)return;view.layoutStarted=true;view.host.classList.add("cx-layouts");view.lifetime.signal.addEventListener("abort",()=>{view.host.classList.remove("cx-layouts");for(const name of["cols","span","pad","field","gap","title"])view.host.style.removeProperty("--cx-card-"+name)},{once:true});view.host.setAttribute("data-cx-density",view.density);if(view.layoutMode!=="fit"||view.kind==="grid"&&view.density!==view.declaredDensity)layoutApply(view,view.layoutMode,view.density)};VIEW_MODES.setLayout=(view,change)=>{if(!change||typeof change!=="object"||Array.isArray(change)||Object.keys(change).some(key=>!["mode","density"].includes(key))||
28
+ change.mode!==undefined&&!view.layoutOptions.modes.includes(change.mode)||change.density!==undefined&&!LAYOUT_DENSITIES.includes(change.density))
29
+ throw new Error("CanopyX: setLayout takes a mode the view allows and a density.");if(!view.layoutStarted)VIEW_MODES.layoutsStart(view);const mode=change.mode??view.layoutMode,density=change.density??view.density;if(mode!==view.layoutMode||density!==view.density){layoutApply(view,mode,density);view.layoutMenu?.render();view.sortMenu?.sync();if(view.live){setText(view.live,"");setText(view.live,fill(view.labels.layoutChanged,{mode:layoutModeText(view,mode),density:layoutDensityText(view,density)}))}
30
+ view.stateChanged();view.emit("layout",{mode,density})}
31
+ return Promise.resolve(view.getLayout())};if(VIEW_MODES.DataGrid){const proto=VIEW_MODES.DataGrid.prototype,paint=proto.fillRow,widths=proto.applyWidths;proto.fillRow=function(element,row){paint.call(this,element,row);if(this.layoutMode!=="cards"||!element._cells||row.status||row.group)return;element._cells.forEach((slot,index)=>{const column=this.cols[index],cell=slot&&slot.cell;if(!column||!cell)return;const label=index?column.title:null,wide=index&&cardWide(column)?"wide":null;if((cell.getAttribute("data-cx-label")??null)!==label){if(label===null)cell.removeAttribute("data-cx-label");else cell.setAttribute("data-cx-label",label)}
32
+ if((cell.getAttribute("data-cx-card")??null)!==wide){if(wide)cell.setAttribute("data-cx-card",wide);else cell.removeAttribute("data-cx-card")}})};proto.applyWidths=function(...args){const result=widths.apply(this,args);if(this.layoutMode==="cards"&&!this.layoutApplying&&this.cols&&this.sized){const geometry=cardGeometry(this);cardStyle(this,geometry);if(geometry.height!==this.rowH){const anchor=layoutAnchor(this);this.rowH=geometry.height;this.layout=(this.layout||0)+ 1;this.version++;layoutRows(this,anchor)}}
33
+ return result}}
34
+ const SORT_ICON='<path d="M8 5v14M4.5 15.5 8 19l3.5-3.5M16 19V5M12.5 8.5 16 5l3.5 3.5"/>';function sortMenuRender(view,panel){const query=view.acceptedQuery,sorts=query?query.sort:[],parts=[];if(view.selectionControls)parts.push(view.selectionControls);const list=h("div","cx-sort-list");list.setAttribute("role","group");list.setAttribute("aria-label",view.labels.layoutSort);for(const column of view.cols||[]){if(!column.sortable&&view.tools.columnMenus===false)continue;const row=h("div","cx-sort-choice"),at=sorts.findIndex(sort=>sort.column===column.id),sort=sorts[at];if(column.sortable){const button=h("button","cx-button cx-sort-column"),arrow=sort?sort.direction==="asc"?" \u2191":" \u2193":"";button.type="button";setText(button,column.title+arrow +(sort&&sorts.length>1?" " +(at+1):""));button.setAttribute("aria-pressed",String(!!sort));button.setAttribute("aria-label",column.title +(sort?", "+view.labels[sort.direction==="asc"?"gridSortAscending":"gridSortDescending"]:""));button.addEventListener("click",event=>view.querySortHeader(column.id,event));row.appendChild(button)}else{const title=h("span","cx-sort-column");setText(title,column.title);row.appendChild(title)}
35
+ if(view.tools.columnMenus!==false&&typeof view.openColumnMenu==="function"){const menu=h("button","cx-button icon cx-sort-menu");menu.type="button";menu.setAttribute("aria-label",fill(view.labels.gridColumnMenu,{column:column.title}));menu.setAttribute("aria-haspopup","menu");menu.appendChild(document.createTextNode("\u22ef"));menu.addEventListener("click",()=>view.openColumnMenu(column.id,menu));row.appendChild(menu)}
36
+ list.appendChild(row)}
37
+ parts.push(list);panel.replaceChildren(...parts)}
38
+ function sortMenu(view){if(view.kind!=="grid"||view.tools.layout===false||!view.layoutOptions.modes.includes("cards")||typeof view.controlPanel!=="function")return;const{details,panel}=view.controlPanel(view.labels.layoutSort,"cx-grid-sort",target=>sortMenuRender(view,target));const icon=details.firstChild.querySelector("svg");if(icon)icon.replaceWith(svgIcon(SORT_ICON));const anchor=view.layoutMenu?.details||view.toolbar.querySelector(".cx-grid-views")||view.spacer;if(anchor&&anchor.parentNode===view.toolbar)view.toolbar.insertBefore(details,anchor);view.host.addEventListener("canopyx:query",()=>{if(details.open)sortMenuRender(view,panel)},{signal:view.lifetime.signal});view.sortMenu={details,sync:()=>{details.hidden=view.layoutMode!=="cards";if(details.hidden)details.open=false}};view.sortMenu.sync()}
39
+ installed.add(context.VIEW_MODES)}};(global.CanopyXParts||=[]).push(["layouts",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,19 @@
1
+ /* Linked views: external filter chips and highlighted rows. The info tone keeps both apart from the reader's own chips and selection. */
2
+ .cx-has-linked,.cx-link-bar,.cx-link-chip{--cx-linked-bg:color-mix(in srgb,var(--cx-tone-info) 14%,var(--cx-surface));}
3
+ .cx-has-linked .cx-row[data-cx-linked="true"]{background:var(--cx-linked-bg);}
4
+ .cx-has-linked .cx-row[data-cx-linked="true"][aria-selected="true"]{background:color-mix(in srgb,var(--cx-tone-info) 14%,var(--cx-selected-bg));}
5
+ .cx-has-linked .cx-row[data-cx-linked="true"] [data-cx-pin]{background:var(--cx-linked-bg);}
6
+ .cx-has-linked .cx-row[data-cx-linked="true"] > :first-child{box-shadow:inset var(--cx-size-3px) 0 0 var(--cx-tone-info);}
7
+ .cx-link-bar{flex:none;display:flex;flex-wrap:wrap;gap:var(--cx-size-6px);padding:0 0 var(--cx-size-8px);min-width:0;}
8
+ .cx-link-chip{max-width:100%;height:var(--cx-size-24px);min-height:var(--cx-size-24px);padding:0 var(--cx-size-9px);border:0;border-radius:var(--cx-size-12px);background:var(--cx-linked-bg);color:var(--cx-text);font:inherit;font-size:var(--cx-size-13px);white-space:nowrap;overflow:hidden;cursor:pointer;}
9
+ .cx-data-grid .cx-link-chip.cx-grid-chip{background:var(--cx-linked-bg);}
10
+ .cx-link-chip:hover{background:color-mix(in srgb,var(--cx-tone-info) 22%,var(--cx-surface));}
11
+ .cx-link-chip:focus-visible{outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:var(--cx-size-1px);}
12
+ @media (forced-colors:active){
13
+ .cx-has-linked .cx-row[data-cx-linked="true"]{outline:var(--cx-size-2px) dashed Highlight;outline-offset:var(--cx-size-neg-2px);}
14
+ .cx-link-chip{border:var(--cx-size-1px) solid ButtonText;}
15
+ }
16
+ @media print{
17
+ .cx-link-bar{padding:0 0 var(--cx-size-4px);}
18
+ .cx-link-chip{background:transparent;padding:0;height:auto;white-space:normal;}
19
+ }
@@ -0,0 +1,38 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"fa0c9e888463553b",install(context){if(installed.has(context.LINK_IMPL))return;const{LINK_IMPL,h,setText,filterChipContent,fill,numberFormat,cellValue,setAttr,cellMatches}=context;const{TreeGrid,DataGrid}=LINK_IMPL;const LINK_SOURCE=/^[A-Za-z0-9][\w.:-]{0,127}$/, LINK_MAX_KEYS = 10000, LINK_MAX_VALUES = 1000;
2
+ const linkText=(value,name,max)=>{if(value===undefined)return undefined;if(typeof value!=="string"||!/\S/.test(value) || value.length > max) throw new Error("CanopyX: link " + name + " must be visible text of at most " + max + " characters.");
3
+ return value};const linkIsoDate=value=>typeof value==="string"&&/^\d{4}-\d\d-\d\dT.*(?:Z|[+-]\d\d:\d\d)$/.test(value) && Number.isFinite(Date.parse(value));
4
+ function linkColumn(grid,field){const column=grid.view.columns.find(item=>item.id===field);if(!column)throw new Error("CanopyX: a link names the undeclared column '"+field+"'.");return column}
5
+ function linkOperand(column,value){if(value===null||value===undefined||typeof value==="object")throw new Error("CanopyX: link values are non-null raw values.");if(column.kind==="number"){const number=typeof value==="number"?value:Number(value);if(!Number.isFinite(number)||typeof value==="boolean"||value===""||Math.abs(number)>Number.MAX_SAFE_INTEGER)throw new Error("CanopyX: the column '"+column.id+"' links by numbers.");return number}
6
+ if(column.kind==="datetime"&&!linkIsoDate(value))throw new Error("CanopyX: the column '"+column.id+"' links by ISO dates with a time zone.");return typeof value==="boolean"||column.kind==="datetime"?value:String(value)}
7
+ function linkFilter(grid,source,input){if(!input||typeof input!=="object"||Array.isArray(input))throw new Error("CanopyX: an external filter is an object.");const column=linkColumn(grid,input.field),filter={source,field:column.id};if((input.values===undefined)===(input.range===undefined))throw new Error("CanopyX: an external filter has values or a range.");if(input.values!==undefined){if(!Array.isArray(input.values)||!input.values.length||input.values.length>LINK_MAX_VALUES)throw new Error("CanopyX: an external filter has 1 to "+LINK_MAX_VALUES+" values.");filter.values=Array.from(new Set(input.values.map(value=>linkOperand(column,value))))}else{const range=input.range;if(!Array.isArray(range)||range.length!==2||range[0]==null&&range[1]==null||column.kind==="text")throw new Error("CanopyX: a range is [from, to] on a number or date column.");filter.range=range.map(value=>value==null?null:linkOperand(column,value))}
8
+ filter.label=linkText(input.label,"label",256);filter.sourceLabel=linkText(input.sourceLabel,"source label",128)||source;filter.persist=input.persist===true;return filter}
9
+ function linkValuesText(grid,filter,describeRange=false){const shown=filter.values?filter.values.slice(0,3).map(String):[filter.range.map(value=>value==null?"…":String(value)).join(" – ")];const values=shown.join(", ")+(filter.values&&filter.values.length>3?" +"+numberFormat(grid.lang).format(filter.values.length-3):"");return!filter.label?values:describeRange&&filter.range&&filter.label!==values?filter.label+" ("+values+")":filter.label}
10
+ function linkCell(grid,record,field){return grid.kind==="tree"&&field===grid.view.columns[0].id&&!Object.hasOwn(record.cells||{},field)?record.label:cellValue((record.cells||{})[field])}
11
+ function linkPredicates(filters){return filters.flatMap(filter=>filter.values?[{column:filter.field,operator:filter.values.length===1?"eq":"in",values:filter.values.slice()}]:
12
+ [filter.range[0]==null?null:{column:filter.field,operator:"ge",values:[filter.range[0]]},filter.range[1]==null?null:{column:filter.field,operator:"le",values:[filter.range[1]]}].filter(Boolean))}
13
+ function linkMatcher(grid){const predicates=linkPredicates(grid.linkFilters).map(predicate=>{const column=linkColumn(grid,predicate.column);return[predicate,column.kind===undefined?{...column,kind:"text"}:column]});return record=>predicates.every(([predicate,column])=>cellMatches(linkCell(grid,record,column.id),predicate,column))}
14
+ const LINK_COMMON={setExternalFilter(source,filter){return this.linkSet(source,filter,"api")},clearExternalFilters(source){return source===undefined?this.linkApply([],"api"):this.linkSet(source,null,"api")},linkSet(source,filter,reason){if(typeof source!=="string"||!LINK_SOURCE.test(source))throw new Error("CanopyX: a link source is 1 to 128 letters, digits, '.', ':', '_' or '-'.");const list=filter==null?[]:(Array.isArray(filter)?filter:[filter]).map(item=>linkFilter(this,source,item));if(list.length>8)throw new Error("CanopyX: one source applies at most 8 external filters.");const next=(this.linkFilters||[]).filter(item=>item.source!==source).concat(list);if(next.length>32)throw new Error("CanopyX: a view takes at most 32 external filters.");return this.linkApply(next,reason)},async linkApply(next,reason){if(this.destroyed)return false;if(JSON.stringify(next)===JSON.stringify(this.linkFilters||[]))return this.linkPending||true;const pending=this.linkCommit(next,reason);this.linkPending=pending;try{return await pending}finally{if(this.linkPending===pending)this.linkPending=null}},linkChanged(reason){const committed=this.linkCommitted||[],last=committed[committed.length-1],count=this.linkCount();this.emit("externalfilter",{filters:this.getExternalFilters(),reason:reason||"api"});setText(this.live,!last?this.labels.linkCleared:count==null?fill(this.labels.linkFilteredBy,{source:last.sourceLabel,values:linkValuesText(this,last)}):
15
+ fill(this.labels.linkFiltered,{source:last.sourceLabel,count:numberFormat(this.lang).format(count)}))},linkChip(source,run){const filters=this.linkCommitted.filter(item=>item.source===source),first=filters[0];const values=filters.map(item=>linkValuesText(this,item)).join("; ");const description=filters.map(item=>linkValuesText(this,item,true)).join("; ");const text=fill(this.labels.linkFilteredBy,{source:first.sourceLabel,values});const button=h("button","cx-button cx-link-chip" +(this.kind==="grid"?" cx-grid-chip":""));button.type="button";filterChipContent(button,text);button.title=fill(this.labels.linkFilteredBy,{source:first.sourceLabel,values:description});button.setAttribute("aria-label",fill(this.labels.linkRemoveFilter,{source:first.sourceLabel,values:description}));button.setAttribute("data-cx-condition","link-"+source);button.setAttribute("data-cx-link-source",source);button.onclick=()=>{button.focus({preventScroll:true});run()};return button},linkSources(){return Array.from(new Set((this.linkCommitted||[]).map(item=>item.source)))},linkRemove(source){try{this.linkSet(source,null,"user").catch(error=>{if(!error||error.name!=="AbortError")this.emit("error",{error})})}
16
+ catch(error){this.emit("error",{error})}}};Object.assign(TreeGrid.prototype,LINK_COMMON);if(DataGrid)Object.assign(DataGrid.prototype,LINK_COMMON);if(DataGrid){const{gridQueryStart}=LINK_IMPL;const proto=DataGrid.prototype,SET_QUERY=proto.setQuery,FOR_CHANGE=proto.queryForChange,GET_STATE=proto.getState;const SUMMARY=proto.syncQuerySummary,CHROME=proto.syncGridChrome,NOTICE=proto.setNotice,DESTROY=proto.destroy;const same=(a,b)=>JSON.stringify(a)===JSON.stringify(b),LINK_OWN=LINK_IMPL.queryOwn;const strip=(filters,tail)=>{filters=filters||[];if(!tail||!tail.length||filters.length<tail.length)return filters;return tail.every((filter,index)=>same(filters[filters.length-tail.length+index],filter))?filters.slice(0,filters.length-tail.length):filters};const tailOf=(grid,pending)=>pending&&grid.pendingQuery&&grid.linkSent?grid.linkSent.ext:grid.linkAcceptedExt;Object.assign(proto,{setQuery(input,paging){const desired=this.linkFilters||[];if(!desired.length&&!this.linkAcceptedExt&&!this.linkSent)return SET_QUERY.call(this,input,paging);const ext=linkPredicates(desired),own=!input||!input.filters?[]:input[LINK_OWN]?input.filters:strip(input.filters,tailOf(this,true));const before=this.queryEpoch,promise=SET_QUERY.call(this,{...(input||{}),filters:own.concat(ext),[LINK_OWN]:undefined},paging);if(this.queryEpoch!==before)this.linkSent={epoch:this.queryEpoch,ext,desired:desired.slice()};return promise.catch(error=>{if((!error||error.name!=="AbortError")&&!this.destroyed&&!this.pendingQuery){if(this.lastFailedQuery&&this.linkSent?.epoch===this.queryEpoch)
17
+ this.lastFailedQuery={...this.lastFailedQuery,filters:strip(this.lastFailedQuery.filters,this.linkSent.ext),[LINK_OWN]:true};this.linkFilters=(this.linkCommitted||[]).slice();this.linkReason=null;this.linkSent=null;this.syncQuerySummary()}
18
+ throw error})},queryForChange(includeQueuedInput,includeExternal){const query=FOR_CHANGE.call(this,includeQueuedInput),tail=tailOf(this,true);if(includeExternal)return query;return tail&&query.filters?{...query,filters:strip(query.filters,tail),[LINK_OWN]:true}:query},getState(){const state=GET_STATE.call(this);if(!this.linkAcceptedExt)return state;const own=strip(state.query.filters,this.linkAcceptedExt);const kept=linkPredicates((this.linkCommitted||[]).filter(filter=>filter.persist)).filter(filter=>!own.some(item=>same(item,filter)));return{...state,query:{...state.query,filters:own.concat(kept)}}},async linkCommit(next,reason){this.linkFilters=next;this.linkReason=reason;if(!this.acceptedQuery&&!this.pendingQuery)await this.ready;try{await this.setQuery(gridQueryStart(this.queryForChange(true)));return true}
19
+ catch(error){if(error&&error.name==="AbortError")return false;throw error}},linkClearAll(){this.linkFilters=[];this.linkReason="user"},linkCount(){return this.snapshot?this.snapshot.matched:0},linkChips(){this.syncQuerySummary()},syncGridChrome(){CHROME.call(this);const summary=this.linkAcceptedExt&&this.acceptedQuery&&this.toolbar.querySelector(".cx-grid-filters > summary");if(!summary)return;const group=item=>item?item.filters.length+item.groups.reduce((sum,child)=>sum+group(child),0):0;const count=strip(this.acceptedQuery.filters,this.linkAcceptedExt).length+group(this.acceptedQuery.filterGroup);summary.classList.toggle("active",!!count);summary.querySelector(".badge")?.remove();if(count){const badge=h("span","badge");setText(badge,String(count));summary.appendChild(badge)}},syncQuerySummary(){let changed=false;if(this.acceptedQuery&&this.acceptedQuery!==this.linkSeenQuery){this.linkSeenQuery=this.acceptedQuery;const sent=this.linkSent&&this.linkSent.epoch===this.queryEpoch?this.linkSent:null;if(sent){this.linkAcceptedExt=sent.ext;changed=!same(this.linkCommitted||[],sent.desired);this.linkCommitted=sent.desired}}
20
+ const active=document.activeElement,key=this.queryChips&&this.queryChips.contains(active)?active.getAttribute("data-cx-condition"):null;SUMMARY.call(this);if(this.queryChips&&this.acceptedQuery&&this.linkAcceptedExt){const tail=this.linkAcceptedExt.length,filters=this.acceptedQuery.filters;for(let index=filters.length-tail;index<filters.length;index++)this.queryChips.querySelector('[data-cx-condition="filter-'+index+'"]')?.remove();const chips=this.linkSources().map(source=>this.linkChip(source,()=>this.linkRemove(source)));this.queryChips.prepend(...chips);const clear=this.queryChips.querySelector('[data-cx-condition="clear"]');if(clear&&chips.length){const run=clear.onclick;clear.onclick=event=>{this.linkClearAll();run(event)}}
21
+ if(key&&key.startsWith("link-")){const target=[...this.queryChips.children].find(item=>item.getAttribute("data-cx-condition")===key)||this.queryChips.querySelector(".cx-link-chip, .cx-grid-chip");(target||this.searchInput||this.grid).focus({preventScroll:true})}}
22
+ if(changed){const reason=this.linkReason;this.linkReason=null;this.linkChanged(reason)}},setNotice(...args){NOTICE.apply(this,args);const clear=(this.linkFilters?.length||this.linkCommitted?.length)&&this.notice.querySelector(".acts button");if(clear){const run=clear.onclick;clear.onclick=event=>{this.linkClearAll();run(event)}}},destroy(){this.host.classList.remove("cx-has-linked");return DESTROY.call(this)}})}
23
+ const SET_FILTER=TreeGrid.prototype.setFilter,APPLY_SNAPSHOT=TreeGrid.prototype.applyQuerySnapshot;function linkTreeFilter(grid){const base=grid.linkBase||null,external=grid.linkFilters&&grid.linkFilters.length;if(!external)return base;const matches=linkMatcher(grid);return{match:node=>matches(node)&&(!base||base.match(node)),keep:base&&base.keep?node=>matches(node)&&(base.match(node)||base.keep(node)):undefined,linked:true}}
24
+ Object.assign(TreeGrid.prototype,{setFilter(filter,options){const value=typeof filter==="function"?{match:filter}:filter||null;this.linkBase=value&&value.linked?this.linkBase:value;SET_FILTER.call(this,linkTreeFilter(this),this.linkFilters&&this.linkFilters.length?{autoExpand:true}:options)},applyQuerySnapshot(...args){APPLY_SNAPSHOT.apply(this,args);this.linkBase=null;if(this.linkFilters&&this.linkFilters.length)SET_FILTER.call(this,linkTreeFilter(this),{autoExpand:true})},linkCommit(next,reason){const declared=this.filter&&this.filter===this.declaredFilter;if(this.linkBase===undefined)this.linkBase=this.filter&&!this.filter.linked?this.filter:null;this.linkFilters=next;this.linkCommitted=next.slice();SET_FILTER.call(this,linkTreeFilter(this),{autoExpand:true});if(declared)this.declaredFilter=this.filter;this.linkChips();this.flushLayout();if(this.rafId){cancelAnimationFrame(this.rafId);this.rafId=0}
25
+ this.render();this.linkChanged(reason);return Promise.resolve(true)},linkCount(){return this.rows.filter(row=>!row.status&&(!this.filter||row._fm===2)).length},linkChips(){const sources=this.linkSources(),active=document.activeElement;const key=this.linkBar&&this.linkBar.contains(active)?active.getAttribute("data-cx-condition"):null;if(!sources.length){if(this.linkBar){const had=!!key;this.linkBar.remove();this.linkBar=null;if(had)this.grid.focus({preventScroll:true})}
26
+ return}
27
+ if(!this.linkBar){this.linkBar=h("div","cx-link-bar");this.toolbar.after(this.linkBar)}
28
+ this.linkBar.replaceChildren(...sources.map(source=>this.linkChip(source,()=>this.linkRemove(source))));const target=key&&[...this.linkBar.children].find(item=>item.getAttribute("data-cx-condition")===key);if(key)(target||this.linkBar.firstElementChild||this.grid).focus({preventScroll:true})}});const DESTROY=TreeGrid.prototype.destroy;TreeGrid.prototype.destroy=function(){this.linkBar?.remove();this.linkBar=null;this.host.classList.remove("cx-has-linked");return DESTROY.call(this)};const linkMark=(grid,element,row)=>setAttr(element,"data-cx-linked",row&&!row.status&&grid.linkHighlight&&grid.linkHighlight.has(row.key)?"true":null);for(const View of[TreeGrid,DataGrid])if(View){const FILL=View.prototype.fillRow;View.prototype.fillRow=function(element,row){FILL.call(this,element,row);linkMark(this,element,row)}}
29
+ const LINK_HIGHLIGHT={async setHighlight(keys,options){if(!Array.isArray(keys)||keys.length>LINK_MAX_KEYS||keys.some(key=>typeof key!=="string"||!key.length))
30
+ throw new Error("CanopyX: a highlight is an array of at most "+LINK_MAX_KEYS+" row keys.");options=options||{};const source=linkText(options.source,"source",128);if(this.destroyed)return 0;const set=keys.length?new Set(keys):null;this.linkHighlight=set;for(const[row,element]of this.rendered)linkMark(this,element,row);this.host.classList.toggle("cx-has-linked",!!set);setText(this.live,set?fill(source?this.labels.linkHighlighted:this.labels.linkHighlightedRows,{count:numberFormat(this.lang).format(set.size),source}):"");if(set&&options.scroll!==false)await this.linkReveal(set).catch(()=>{});return set?set.size:0},clearHighlight(){return this.setHighlight([])}};Object.assign(TreeGrid.prototype,LINK_HIGHLIGHT,{async linkReveal(keys){let first=null,at=Infinity;for(const key of keys){const node=this.keyMap.get(key);if(!node)continue;const index=this.indexOf(node),order=index>=0?index:Number.MAX_SAFE_INTEGER-1;if(order<at){first=node;at=order}}
31
+ if(!first||this.linkHighlight!==keys)return;await this.expandPath(this.pathOf(first),{select:false,focus:false,reveal:false});if(!this.destroyed&&this.linkHighlight===keys&&this.indexOf(first)>=0)this.ensureVisible(first)}});if(DataGrid)Object.assign(DataGrid.prototype,LINK_HIGHLIGHT,{async linkReveal(keys){if(this.pendingQuery||!this.acceptedQuery)return;const epoch=this.queryEpoch,lifetime=this.dataLifetime;const current=()=>!this.destroyed&&!lifetime.signal.aborted&&epoch===this.queryEpoch&&!this.pendingQuery&&this.linkHighlight===keys;let index=-1;for(const row of this.rowCache.values())if(keys.has(row.key)&&(index<0||row._ri<index))index=row._ri;if(index!==0&&this.view.source.kind==="inline"&&(!this.opts.source||this.enhanceStore)&&!this.view.reporting?.grouping&&this.snapshot?.matched){const query=this.acceptedQuery,end=index<0?this.snapshot.matched:index;const top=this.logicalTop(),focused=this.focused,navigation=this.pendingNavigation;for(let offset=0;offset<end&&current();){const page=await this.source.query({...query,offset,limit:Math.min(10000,end-offset)},{signal:lifetime.signal});if(!current())return;const found=page.items.findIndex(item=>keys.has(item.id));if(found>=0){index=offset+found;break}
32
+ if(!page.items.length)break;offset +=page.items.length}
33
+ if(this.focused!==focused||this.pendingNavigation!==navigation||this.logicalTop()!==top)return}
34
+ if(index>=0&&current())await this.scrollToRow(index)}});const LINK_ROWS=1000,LINK_COLUMN_VALUES=100;function linkValues(grid,records){const values=Object.create(null);for(const column of grid.view.columns){const seen=new Set();for(const record of records){const value=linkCell(grid,record,column.id);if(value!=null&&seen.size<LINK_COLUMN_VALUES)seen.add(value)}
35
+ if(seen.size)values[column.id]=Array.from(seen)}
36
+ return values}
37
+ function linkLabel(grid,records){const first=grid.view.columns[0].id,shown=records.slice(0,3).map(record=>linkCell(grid,record,first)).filter(value=>value!=null).map(String);return shown.join(", ")+(records.length>3?" +"+numberFormat(grid.lang).format(records.length-3):"")}
38
+ const LINK_EVENTS={startLinkEvents(){this.linkWatch();return Promise.resolve()},linkWatch(){if(this.linkWatching||this.destroyed)return;this.linkWatching=true;const signal=this.lifetime.signal;this.host.addEventListener("canopyx:select",event=>this.linkSelected(event.detail||{}),{signal});if(this.kind==="grid")this.host.addEventListener("canopyx:query",()=>this.linkQueried(),{signal})},linkSelected(detail){if(detail.selection&&detail.selection.kind==="query")return;const nodes=detail.nodes||[],keys=this.kind==="tree"?nodes.slice(0,LINK_MAX_KEYS).map(node=>node.id):(detail.ids||[]).slice(0,LINK_MAX_KEYS);const shape=JSON.stringify(keys);if(shape===(this.linkSelectShape||"[]"))return;this.linkSelectShape=shape;const records=this.kind==="tree"?nodes.slice(0,LINK_ROWS):this.linkRecords(keys);this.emit("linkchange",{view:this.view.id,action:keys.length?"select":"clear",scope:"select",keys,values:linkValues(this,records),label:linkLabel(this,records)})},linkQueried(){const query=this.queryForChange(),mine=[];const collect=group=>{for(const filter of group.filters||[])if(filter.operator==="eq"||filter.operator==="in")mine.push(filter);for(const child of group.groups||[])collect(child)};collect({filters:query.filters,groups:query.filterGroup?[query.filterGroup]:[]});const shape=JSON.stringify(mine);if(shape===(this.linkOwnShape||"[]"))return;this.linkOwnShape=shape;const values=Object.create(null);for(const filter of mine)values[filter.column]=Array.from(new Set((values[filter.column]||[]).concat(filter.values)));const label=Object.values(values).map(list=>list.slice(0,3).join(", ")).join("; ");this.emit("linkchange",{view:this.view.id,action:mine.length?"filter":"clear",scope:"filter",keys:[],values,label})}};Object.assign(TreeGrid.prototype,LINK_EVENTS);if(DataGrid)Object.assign(DataGrid.prototype,LINK_EVENTS,{linkRecords(ids){const wanted=new Set(ids.slice(0,LINK_ROWS)),found=new Map();for(const row of this.rowCache.values())if(wanted.has(row.key))found.set(row.key,row.h);return ids.filter(id=>found.has(id)).map(id=>found.get(id))}});installed.add(context.LINK_IMPL)}};(global.CanopyXParts||=[]).push(["link",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,14 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"f1ab7e32b501ce37",install(context){if(installed.has(context.TreeGrid.prototype))return;const{TreeGrid,navigationScope}=context;Object.assign(TreeGrid.prototype,{deepLinkName(){return "cx."+encodeURIComponent(this.view.id)},hashParams(){return(global.location.hash||"").replace(/^#/, "").split("&").filter(Boolean);
2
+ },currentLink(){if(this.opts.parseLink){return(global.location.hash||"").replace(/^#/, "");
3
+ }
4
+ const prefix=this.deepLinkName()+ "=";const param=this.hashParams().find((p)=>p.startsWith(prefix));return param?param.slice(prefix.length):null},openDeepLink(){const link=this.view.deepLink?this.currentLink():null;if(link!==this.link&&this.linkOpening)this.linkOpening.abort();if(link==null||link===this.link){if(link==null)this.link=null;return link!=null&&this.linkTask&&this.linkTask.link===link?this.linkTask.promise:Promise.resolve()}
5
+ this.link=link;if(this.linkOpening)this.linkOpening.abort();const current=this.linkOpening=new AbortController();const promise=this.openLink(link,current);this.linkTask={link,promise};promise.then(()=>{if(this.linkTask&&this.linkTask.promise===promise)this.linkTask=null});return promise},async openLink(link,current){const navigation=navigationScope(this,current.signal,true);try{const ids=this.opts.parseLink?await navigation.wait(this.opts.parseLink(link)):link.split("/").filter(Boolean).map(decodeURIComponent);if(Array.isArray(ids)&&ids.length&&!navigation.cancelled()&&
6
+ !await this.navigatePath(ids,{select:true,focus:false},navigation)&&!navigation.cancelled()){this.link=null}}catch(e){if(!navigation.cancelled()){this.link=null;this.announce(e&&e.message?e.message:String(e))}}finally{const cancelled=navigation.cancelled();navigation.dispose();if(this.linkOpening===current){if(cancelled&&this.link===link)this.link=null;this.linkOpening=null}
7
+ current.abort()}},writeDeepLink(w,revision=this.selectionRevision){if(!this.view.deepLink){return}
8
+ let hash;if(this.opts.formatLink){let link=null;try{link=this.opts.formatLink(w?this.pathOf(w):[],w?w.h:null)}catch(e){if(global.console)global.console.error(e)}
9
+ if(link==null||this.destroyed||revision!==this.selectionRevision){return}
10
+ hash="#"+String(link).replace(/^#/, "");
11
+ }else{const prefix=this.deepLinkName()+ "=";const params=this.hashParams().filter((p)=>!p.startsWith(prefix));if(w)params.push(prefix+this.pathOf(w).map(encodeURIComponent).join("/"));hash="#"+params.join("&")}
12
+ try{global.history.replaceState(global.history.state,"",global.location.href.replace(/#.*$/, "") + hash);
13
+ }catch(e){global.location.hash=hash}
14
+ this.link=this.currentLink();this.locationEvent=null}});installed.add(context.TreeGrid.prototype)}};(global.CanopyXParts||=[]).push(["links",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,24 @@
1
+ /* Live data: the order prompt sits in the toolbar (over the rows without one);changed cells flash (a still outline with reduced motion). */
2
+ .cx-data-grid.cx-live-grid{position:relative;}
3
+ .cx-data-grid .cx-live-bar{display:inline-flex;align-items:center;gap:var(--cx-size-6px);flex:none;max-width:100%;height:var(--cx-control-h);padding:0 var(--cx-size-2px) 0 var(--cx-size-10px);border-radius:var(--cx-radius);background:var(--cx-accent-soft);color:var(--cx-text);font-size:var(--cx-size-13d5px);white-space:nowrap;}
4
+ .cx-data-grid .cx-live-bar[hidden]{display:none;}
5
+ .cx-data-grid .cx-live-bar.cx-live-float{position:absolute;left:50%;z-index:4;transform:translateX(-50%);max-width:calc(100% - var(--cx-size-24px));border:var(--cx-size-1px) solid var(--cx-line-strong);background:var(--cx-surface);box-shadow:var(--cx-panel-shadow);}
6
+ .cx-data-grid .cx-live-bar .cx-ico{flex:none;width:var(--cx-size-16px);height:var(--cx-size-16px);color:var(--cx-accent);}
7
+ .cx-data-grid .cx-live-bar-text{overflow:hidden;text-overflow:ellipsis;}
8
+ .cx-data-grid .cx-live-bar .cx-button{height:var(--cx-size-28px);min-height:var(--cx-size-28px);padding:0 var(--cx-size-10px);border:var(--cx-size-1px) solid color-mix(in srgb,var(--cx-accent) 45%,var(--cx-surface));border-radius:var(--cx-radius-sm);background:var(--cx-surface);color:var(--cx-text);font:inherit;font-size:var(--cx-size-13px);font-weight:600;cursor:pointer;}
9
+ .cx-data-grid .cx-live-bar .cx-button:hover{background:color-mix(in srgb,var(--cx-accent) 10%,var(--cx-surface));}
10
+ .cx-data-grid .cx-live-bar .cx-button:focus-visible{outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:var(--cx-size-1px);}
11
+ .cx-data-grid.cx-phone .cx-live-bar{height:var(--cx-size-44px);padding:0 0 0 var(--cx-size-8px);background:transparent;}
12
+ .cx-data-grid.cx-phone .cx-live-bar:not(.cx-live-float) .cx-live-bar-text{position:absolute;width:var(--cx-size-1px);height:var(--cx-size-1px);overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
13
+ .cx-data-grid.cx-phone .cx-live-bar .cx-button{height:var(--cx-size-44px);min-height:var(--cx-size-44px);min-width:var(--cx-size-44px);background:var(--cx-accent-soft);}
14
+ @keyframes cx-live-flash{from{box-shadow:inset 0 0 0 var(--cx-size-999px) color-mix(in srgb,var(--cx-accent) 28%,transparent);}to{box-shadow:inset 0 0 0 var(--cx-size-999px) transparent;}}
15
+ .cx-data-grid .cx-cell.cx-live-flash{animation:cx-live-flash var(--cx-live-flash-ms,1200ms) ease-out both;}
16
+ @media (prefers-reduced-motion:reduce){
17
+ .cx-data-grid .cx-cell.cx-live-flash{box-shadow:inset 0 0 0 var(--cx-size-2px) color-mix(in srgb,var(--cx-accent) 60%,transparent);}
18
+ }
19
+ @media (forced-colors:active){
20
+ .cx-data-grid .cx-live-bar{border:var(--cx-size-1px) solid CanvasText;background:Canvas;color:CanvasText;}
21
+ .cx-data-grid .cx-live-bar .cx-button{border:var(--cx-size-1px) solid ButtonText;background:ButtonFace;color:ButtonText;}
22
+ .cx-data-grid .cx-cell.cx-live-flash{animation:none;outline:var(--cx-size-2px) solid Highlight;outline-offset:calc(var(--cx-size-2px) * -1);}
23
+ }
24
+ @media print{.cx-data-grid .cx-live-bar{display:none;}}