@evotecit/canopyx 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CanopyX.Html/Assets/canopyx-data.js +5 -4
- package/CanopyX.Html/Assets/canopyx-editing.css +1 -6
- package/CanopyX.Html/Assets/canopyx-editing.js +4 -39
- package/CanopyX.Html/Assets/canopyx-flow-entry.css +178 -0
- package/CanopyX.Html/Assets/canopyx-flow-entry.js +78 -0
- package/CanopyX.Html/Assets/canopyx-flow-module.mjs +80 -0
- package/CanopyX.Html/Assets/canopyx-flow.css +180 -0
- package/CanopyX.Html/Assets/canopyx-flow.js +214 -0
- package/CanopyX.Html/Assets/canopyx-forms.css +8 -0
- package/CanopyX.Html/Assets/canopyx-forms.js +39 -0
- package/CanopyX.Html/Assets/canopyx-grid-module.mjs +42 -23
- package/CanopyX.Html/Assets/canopyx-grid.css +2 -0
- package/CanopyX.Html/Assets/canopyx-grid.js +42 -23
- package/CanopyX.Html/Assets/canopyx-grouping.js +2 -2
- package/CanopyX.Html/Assets/canopyx-interactive.js +7 -7
- package/CanopyX.Html/Assets/canopyx-labels-de.js +105 -0
- package/CanopyX.Html/Assets/canopyx-labels-es.js +105 -0
- package/CanopyX.Html/Assets/canopyx-labels-fr.js +105 -0
- package/CanopyX.Html/Assets/canopyx-labels-it.js +105 -0
- package/CanopyX.Html/Assets/canopyx-labels-pl.js +105 -0
- package/CanopyX.Html/Assets/canopyx-live.js +2 -2
- package/CanopyX.Html/Assets/canopyx-matrix.css +153 -0
- package/CanopyX.Html/Assets/canopyx-matrix.js +153 -0
- package/CanopyX.Html/Assets/canopyx-module.mjs +7 -7
- package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +43 -24
- package/CanopyX.Html/Assets/canopyx-reporting.css +2 -0
- package/CanopyX.Html/Assets/canopyx-reporting.js +43 -24
- package/CanopyX.Html/Assets/canopyx-tree-tools.js +3 -2
- package/CanopyX.Html/Assets/canopyx.js +7 -7
- package/JavaScript/flow.d.ts +232 -0
- package/JavaScript/grid.d.ts +11 -5
- package/JavaScript/locales/de.mjs +105 -0
- package/JavaScript/locales/es.mjs +105 -0
- package/JavaScript/locales/fr.mjs +105 -0
- package/JavaScript/locales/it.mjs +105 -0
- package/JavaScript/locales/pl.mjs +105 -0
- package/JavaScript/matrix.d.ts +160 -0
- package/README.md +4 -2
- package/package.json +24 -1
|
@@ -516,6 +516,111 @@ const labels = Object.freeze({
|
|
|
516
516
|
calendarOutsideRange: "Al di fuori delle date di questo calendario",
|
|
517
517
|
calendarClose: "Chiudi",
|
|
518
518
|
calendarDetailsOf: "Dettagli di {title}",
|
|
519
|
+
flowSteps: "Passaggi",
|
|
520
|
+
flowStepOf: "Passaggio {current} di {count}",
|
|
521
|
+
flowStepAnnounce: "Passaggio {current} di {count}, {title}",
|
|
522
|
+
flowNext: "Avanti",
|
|
523
|
+
flowBack: "Indietro",
|
|
524
|
+
flowSubmit: "Invia",
|
|
525
|
+
flowSubmitting: "Invio in corso…",
|
|
526
|
+
flowReviewTitle: "Controlla le risposte",
|
|
527
|
+
flowChange: "Modifica",
|
|
528
|
+
flowChangeField: "Modifica {field}",
|
|
529
|
+
flowNotProvided: "Non indicato",
|
|
530
|
+
flowOptional: "(facoltativo)",
|
|
531
|
+
flowStepOptional: "Facoltativo",
|
|
532
|
+
flowStepComplete: "Completato",
|
|
533
|
+
flowStepCurrent: "Passaggio corrente",
|
|
534
|
+
flowStepErrors: "Errori: {count}",
|
|
535
|
+
flowStepLocked: "Completa prima i passaggi precedenti",
|
|
536
|
+
flowStepNotStarted: "Non iniziato",
|
|
537
|
+
flowErrorSummary: "Correggi questi punti prima di continuare",
|
|
538
|
+
flowReady: "Pronto per l'invio",
|
|
539
|
+
flowNotReady: "Errori da correggere: {count}",
|
|
540
|
+
flowWarnings: "Avvisi: {count}",
|
|
541
|
+
flowChangesOnly: "Mostra solo le modifiche",
|
|
542
|
+
flowNoChanges: "Nessuna risposta è cambiata.",
|
|
543
|
+
flowWas: "Prima: {value}",
|
|
544
|
+
flowChangedCount: "Risposte modificate: {count}",
|
|
545
|
+
flowSecretSet: "Impostato",
|
|
546
|
+
flowSecretKept: "Invariato",
|
|
547
|
+
flowSecretNotSet: "Non impostato",
|
|
548
|
+
flowSecretHint: "È salvato un valore. Lascia vuoto per mantenerlo.",
|
|
549
|
+
flowSecretShow: "Mostra",
|
|
550
|
+
flowSecretHide: "Nascondi",
|
|
551
|
+
flowSecretReveal: "Mostra {field}",
|
|
552
|
+
flowOn: "Attivo",
|
|
553
|
+
flowOff: "Disattivo",
|
|
554
|
+
flowAdd: "Aggiungi",
|
|
555
|
+
flowAddItem: "Aggiungi a {field}",
|
|
556
|
+
flowRemoveItem: "Rimuovi {item}",
|
|
557
|
+
flowItemLabel: "{field}, elemento {index}",
|
|
558
|
+
flowSelectAll: "Seleziona tutto",
|
|
559
|
+
flowSelectNone: "Cancella",
|
|
560
|
+
flowSelectedCount: "{count} di {total} selezionati",
|
|
561
|
+
flowUnit: "Unità",
|
|
562
|
+
flowUnitSeconds: "secondi",
|
|
563
|
+
flowUnitMinutes: "minuti",
|
|
564
|
+
flowUnitHours: "ore",
|
|
565
|
+
flowUnitDays: "giorni",
|
|
566
|
+
flowSeconds: "[one]{count} secondo[other]{count} secondi",
|
|
567
|
+
flowMinutes: "[one]{count} minuto[other]{count} minuti",
|
|
568
|
+
flowHours: "[one]{count} ora[other]{count} ore",
|
|
569
|
+
flowDays: "[one]{count} giorno[other]{count} giorni",
|
|
570
|
+
flowDurationInvalid: "{field} deve essere un numero intero.",
|
|
571
|
+
flowItemsMin: "{field} richiede almeno {min}.",
|
|
572
|
+
flowItemsMax: "{field} ne consente al massimo {max}.",
|
|
573
|
+
flowItemEmail: "«{item}» non è un indirizzo email.",
|
|
574
|
+
flowItemHost: "«{item}» non è un nome host.",
|
|
575
|
+
flowItemIp: "«{item}» non è un indirizzo IP.",
|
|
576
|
+
flowItemCidr: "«{item}» non è un intervallo di rete.",
|
|
577
|
+
flowItemUrl: "«{item}» non è un indirizzo web.",
|
|
578
|
+
flowItemPattern: "«{item}» non ha il formato previsto.",
|
|
579
|
+
flowSaved: "Salvato",
|
|
580
|
+
flowAccepted: "In corso",
|
|
581
|
+
flowProgress: "{done} di {total}",
|
|
582
|
+
flowConflict: "Queste impostazioni sono cambiate durante la modifica.",
|
|
583
|
+
flowReload: "Ricarica le impostazioni correnti",
|
|
584
|
+
flowNotSubmitted: "Le risposte non sono state inviate.",
|
|
585
|
+
flowNoHost: "Nessun host ha ricevuto le risposte.",
|
|
586
|
+
flowStartAgain: "Ricomincia",
|
|
587
|
+
flowCopy: "Copia",
|
|
588
|
+
flowCopied: "Copiato",
|
|
589
|
+
flowSavedIt: "L'ho salvato",
|
|
590
|
+
flowShownOnce: "Mostrato una sola volta. Copialo ora.",
|
|
591
|
+
matrixRows: "Righe",
|
|
592
|
+
matrixColumns: "Colonne",
|
|
593
|
+
matrixSearch: "Cerca righe e colonne",
|
|
594
|
+
matrixSortBy: "Ordina per",
|
|
595
|
+
matrixGroupBy: "Raggruppa per",
|
|
596
|
+
matrixByLabel: "Nome",
|
|
597
|
+
matrixByTotal: "Totale",
|
|
598
|
+
matrixAsListed: "Come elencato",
|
|
599
|
+
matrixNoGrouping: "Nessun gruppo",
|
|
600
|
+
matrixDescending: "Decrescente",
|
|
601
|
+
matrixOnlyProblems: "Solo problemi",
|
|
602
|
+
matrixHideEmpty: "Nascondi righe e colonne vuote",
|
|
603
|
+
matrixSize: "{rows} × {columns}",
|
|
604
|
+
matrixShown: "Righe: {rows} di {totalRows}, colonne: {columns} di {totalColumns}",
|
|
605
|
+
matrixAttention: "Richiedono attenzione: {count}",
|
|
606
|
+
matrixLegend: "Stati",
|
|
607
|
+
matrixFilter: "Filtra",
|
|
608
|
+
matrixClearFilters: "Cancella filtri",
|
|
609
|
+
matrixNoMatches: "Nessuna riga o colonna corrisponde.",
|
|
610
|
+
matrixSelf: "Stesso elemento",
|
|
611
|
+
matrixNoData: "Nessun dato",
|
|
612
|
+
matrixCell: "{row} e {column}: {state}",
|
|
613
|
+
matrixTotal: "Totale",
|
|
614
|
+
matrixItemTotal: "{item}: {count}",
|
|
615
|
+
matrixExpandGroup: "Espandi {group}",
|
|
616
|
+
matrixCollapseGroup: "Comprimi {group}",
|
|
617
|
+
matrixGroupCount: "Elementi: {count}",
|
|
618
|
+
matrixDetails: "Dettagli",
|
|
619
|
+
matrixClose: "Chiudi",
|
|
620
|
+
matrixValue: "Valore",
|
|
621
|
+
matrixState: "Stato",
|
|
622
|
+
matrixAllClear: "Niente richiede attenzione",
|
|
623
|
+
matrixShowMore: "Mostra altro",
|
|
519
624
|
});
|
|
520
625
|
const staticLabels = Object.freeze({
|
|
521
626
|
overflowNote: "Righe mostrate: {shown} su {total}.",
|
|
@@ -516,6 +516,111 @@ const labels = Object.freeze({
|
|
|
516
516
|
calendarOutsideRange: "Poza datami, które pokazuje ten kalendarz",
|
|
517
517
|
calendarClose: "Zamknij",
|
|
518
518
|
calendarDetailsOf: "Szczegóły: {title}",
|
|
519
|
+
flowSteps: "Kroki",
|
|
520
|
+
flowStepOf: "Krok {current} z {count}",
|
|
521
|
+
flowStepAnnounce: "Krok {current} z {count}: {title}",
|
|
522
|
+
flowNext: "Dalej",
|
|
523
|
+
flowBack: "Wstecz",
|
|
524
|
+
flowSubmit: "Wyślij",
|
|
525
|
+
flowSubmitting: "Wysyłanie…",
|
|
526
|
+
flowReviewTitle: "Sprawdź odpowiedzi",
|
|
527
|
+
flowChange: "Zmień",
|
|
528
|
+
flowChangeField: "Zmień: {field}",
|
|
529
|
+
flowNotProvided: "Nie podano",
|
|
530
|
+
flowOptional: "(opcjonalnie)",
|
|
531
|
+
flowStepOptional: "Opcjonalny",
|
|
532
|
+
flowStepComplete: "Ukończono",
|
|
533
|
+
flowStepCurrent: "Bieżący krok",
|
|
534
|
+
flowStepErrors: "Błędy: {count}",
|
|
535
|
+
flowStepLocked: "Najpierw ukończ wcześniejsze kroki",
|
|
536
|
+
flowStepNotStarted: "Nierozpoczęty",
|
|
537
|
+
flowErrorSummary: "Popraw te pola, zanim przejdziesz dalej",
|
|
538
|
+
flowReady: "Gotowe do wysłania",
|
|
539
|
+
flowNotReady: "Błędy do poprawienia: {count}",
|
|
540
|
+
flowWarnings: "Ostrzeżenia: {count}",
|
|
541
|
+
flowChangesOnly: "Pokaż tylko zmiany",
|
|
542
|
+
flowNoChanges: "Żadna odpowiedź się nie zmieniła.",
|
|
543
|
+
flowWas: "Było: {value}",
|
|
544
|
+
flowChangedCount: "Zmienione odpowiedzi: {count}",
|
|
545
|
+
flowSecretSet: "Ustawiono",
|
|
546
|
+
flowSecretKept: "Bez zmian",
|
|
547
|
+
flowSecretNotSet: "Nie ustawiono",
|
|
548
|
+
flowSecretHint: "Wartość jest zapisana. Zostaw puste, aby ją zachować.",
|
|
549
|
+
flowSecretShow: "Pokaż",
|
|
550
|
+
flowSecretHide: "Ukryj",
|
|
551
|
+
flowSecretReveal: "Pokaż: {field}",
|
|
552
|
+
flowOn: "Włączone",
|
|
553
|
+
flowOff: "Wyłączone",
|
|
554
|
+
flowAdd: "Dodaj",
|
|
555
|
+
flowAddItem: "Dodaj do: {field}",
|
|
556
|
+
flowRemoveItem: "Usuń: {item}",
|
|
557
|
+
flowItemLabel: "{field}, pozycja {index}",
|
|
558
|
+
flowSelectAll: "Zaznacz wszystko",
|
|
559
|
+
flowSelectNone: "Wyczyść",
|
|
560
|
+
flowSelectedCount: "Zaznaczono {count} z {total}",
|
|
561
|
+
flowUnit: "Jednostka",
|
|
562
|
+
flowUnitSeconds: "sekundy",
|
|
563
|
+
flowUnitMinutes: "minuty",
|
|
564
|
+
flowUnitHours: "godziny",
|
|
565
|
+
flowUnitDays: "dni",
|
|
566
|
+
flowSeconds: "[one]{count} sekunda[few]{count} sekundy[many]{count} sekund[other]{count} sekundy",
|
|
567
|
+
flowMinutes: "[one]{count} minuta[few]{count} minuty[many]{count} minut[other]{count} minuty",
|
|
568
|
+
flowHours: "[one]{count} godzina[few]{count} godziny[many]{count} godzin[other]{count} godziny",
|
|
569
|
+
flowDays: "[one]{count} dzień[few]{count} dni[many]{count} dni[other]{count} dnia",
|
|
570
|
+
flowDurationInvalid: "{field}: wpisz liczbę całkowitą.",
|
|
571
|
+
flowItemsMin: "{field}: wymagane co najmniej {min}.",
|
|
572
|
+
flowItemsMax: "{field}: dozwolone najwyżej {max}.",
|
|
573
|
+
flowItemEmail: "„{item}” nie jest adresem e-mail.",
|
|
574
|
+
flowItemHost: "„{item}” nie jest nazwą hosta.",
|
|
575
|
+
flowItemIp: "„{item}” nie jest adresem IP.",
|
|
576
|
+
flowItemCidr: "„{item}” nie jest zakresem sieci.",
|
|
577
|
+
flowItemUrl: "„{item}” nie jest adresem internetowym.",
|
|
578
|
+
flowItemPattern: "„{item}” ma nieoczekiwany format.",
|
|
579
|
+
flowSaved: "Zapisano",
|
|
580
|
+
flowAccepted: "W toku",
|
|
581
|
+
flowProgress: "{done} z {total}",
|
|
582
|
+
flowConflict: "Te ustawienia zmieniły się podczas edycji.",
|
|
583
|
+
flowReload: "Wczytaj bieżące ustawienia",
|
|
584
|
+
flowNotSubmitted: "Odpowiedzi nie zostały wysłane.",
|
|
585
|
+
flowNoHost: "Żaden host nie odebrał odpowiedzi.",
|
|
586
|
+
flowStartAgain: "Zacznij od nowa",
|
|
587
|
+
flowCopy: "Kopiuj",
|
|
588
|
+
flowCopied: "Skopiowano",
|
|
589
|
+
flowSavedIt: "Mam to zapisane",
|
|
590
|
+
flowShownOnce: "Widoczne tylko raz. Skopiuj teraz.",
|
|
591
|
+
matrixRows: "Wiersze",
|
|
592
|
+
matrixColumns: "Kolumny",
|
|
593
|
+
matrixSearch: "Szukaj wierszy i kolumn",
|
|
594
|
+
matrixSortBy: "Sortuj według",
|
|
595
|
+
matrixGroupBy: "Grupuj według",
|
|
596
|
+
matrixByLabel: "Nazwa",
|
|
597
|
+
matrixByTotal: "Razem",
|
|
598
|
+
matrixAsListed: "Jak na liście",
|
|
599
|
+
matrixNoGrouping: "Bez grup",
|
|
600
|
+
matrixDescending: "Malejąco",
|
|
601
|
+
matrixOnlyProblems: "Tylko problemy",
|
|
602
|
+
matrixHideEmpty: "Ukryj puste wiersze i kolumny",
|
|
603
|
+
matrixSize: "{rows} × {columns}",
|
|
604
|
+
matrixShown: "Wiersze: {rows} z {totalRows}, kolumny: {columns} z {totalColumns}",
|
|
605
|
+
matrixAttention: "Wymaga uwagi: {count}",
|
|
606
|
+
matrixLegend: "Stany",
|
|
607
|
+
matrixFilter: "Filtruj",
|
|
608
|
+
matrixClearFilters: "Wyczyść filtry",
|
|
609
|
+
matrixNoMatches: "Brak pasujących wierszy lub kolumn.",
|
|
610
|
+
matrixSelf: "Ten sam element",
|
|
611
|
+
matrixNoData: "Brak danych",
|
|
612
|
+
matrixCell: "{row} i {column}: {state}",
|
|
613
|
+
matrixTotal: "Razem",
|
|
614
|
+
matrixItemTotal: "{item}: {count}",
|
|
615
|
+
matrixExpandGroup: "Rozwiń {group}",
|
|
616
|
+
matrixCollapseGroup: "Zwiń {group}",
|
|
617
|
+
matrixGroupCount: "Elementy: {count}",
|
|
618
|
+
matrixDetails: "Szczegóły",
|
|
619
|
+
matrixClose: "Zamknij",
|
|
620
|
+
matrixValue: "Wartość",
|
|
621
|
+
matrixState: "Stan",
|
|
622
|
+
matrixAllClear: "Nic nie wymaga uwagi",
|
|
623
|
+
matrixShowMore: "Pokaż więcej",
|
|
519
624
|
});
|
|
520
625
|
const staticLabels = Object.freeze({
|
|
521
626
|
overflowNote: "Pokazano {shown} z {total} wierszy.",
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Type declarations for the matrix view (docs/matrix.md): the matrix document, its state and the API of createMatrix.
|
|
2
|
+
import type { CellValue } from "./protocol.js";
|
|
3
|
+
|
|
4
|
+
/** A state a cell can hold, listed worst first: a collapsed group shows the worst state of its cells. */
|
|
5
|
+
export interface MatrixState {
|
|
6
|
+
/** A letter, then up to 63 letters, digits, hyphens and underscores. */
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
/** A CanopyX tone (success, warning, danger, info, muted, neutral) or a host tone the theme defines. */
|
|
10
|
+
tone?: string;
|
|
11
|
+
/** The symbol cells and the legend draw, so a state never relies on colour alone. */
|
|
12
|
+
symbol: "check" | "cross" | "warning" | "info" | "dot" | "dash" | "question" | "clock" | "pause";
|
|
13
|
+
/** Cells in this state count in the totals and stay when the reader shows only problems. */
|
|
14
|
+
attention?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A property of an axis's items: shown in tooltips, used to group, sort and filter. */
|
|
18
|
+
export interface MatrixAttribute {
|
|
19
|
+
id: string;
|
|
20
|
+
title: string;
|
|
21
|
+
kind?: "text" | "number" | "datetime";
|
|
22
|
+
/** The filter panel lists its values with their counts. */
|
|
23
|
+
facet?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** An entity on an axis: a row or a column. */
|
|
27
|
+
export interface MatrixItem {
|
|
28
|
+
id: string;
|
|
29
|
+
label: string;
|
|
30
|
+
secondary?: string;
|
|
31
|
+
/** An http, https or mailto address, or a relative one. */
|
|
32
|
+
href?: string;
|
|
33
|
+
values?: Record<string, CellValue | { value: CellValue; text?: string }>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** One axis of the matrix. */
|
|
37
|
+
export interface MatrixAxis {
|
|
38
|
+
title?: string;
|
|
39
|
+
noun?: string;
|
|
40
|
+
attributes?: MatrixAttribute[];
|
|
41
|
+
items: MatrixItem[];
|
|
42
|
+
groupBy?: string;
|
|
43
|
+
sort?: MatrixSort;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** How an axis is sorted: by its labels, its totals or an attribute. */
|
|
47
|
+
export interface MatrixSort {
|
|
48
|
+
by: "#label" | "#total" | (string & {});
|
|
49
|
+
direction?: "asc" | "desc";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A cell's extras: [row index, column index, value, text, title, [label, value][]]. */
|
|
53
|
+
export type MatrixNote = [number, number, number | null, (string | null)?, (string | null)?, ([string, string][] | null)?];
|
|
54
|
+
|
|
55
|
+
/** The matrix document: `{ protocol: "canopyx/2", type: "matrix" }`. */
|
|
56
|
+
export interface MatrixDocument {
|
|
57
|
+
protocol: "canopyx/2";
|
|
58
|
+
type: "matrix";
|
|
59
|
+
id: string;
|
|
60
|
+
label: string;
|
|
61
|
+
rows: MatrixAxis;
|
|
62
|
+
/** The column axis; a square matrix has none and takes its columns from its rows. */
|
|
63
|
+
columns?: MatrixAxis;
|
|
64
|
+
square?: boolean;
|
|
65
|
+
/** The column title of a square matrix. */
|
|
66
|
+
columnTitle?: string;
|
|
67
|
+
/** What the self cells of a square matrix show. */
|
|
68
|
+
diagonal?: "self" | "data";
|
|
69
|
+
states: MatrixState[];
|
|
70
|
+
/** One string per row: a state digit (0-9, a-z) per column, "." for no data. */
|
|
71
|
+
cells: string[];
|
|
72
|
+
notes?: MatrixNote[];
|
|
73
|
+
totals?: { states?: string[]; rows?: boolean; columns?: boolean };
|
|
74
|
+
attentionOnly?: boolean;
|
|
75
|
+
/** Opens hiding the rows and columns whose visible cells all lack data. */
|
|
76
|
+
hideEmpty?: boolean;
|
|
77
|
+
cellWidth?: number;
|
|
78
|
+
density?: "compact" | "normal" | "comfortable";
|
|
79
|
+
details?: "dialog" | "host";
|
|
80
|
+
phone?: "scroll" | "cards";
|
|
81
|
+
legend?: boolean;
|
|
82
|
+
/** As tall as the content when it fits, with the host's height as the bound. Default true. */
|
|
83
|
+
autoHeight?: boolean;
|
|
84
|
+
labels?: Record<string, string>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** The reader's query: search, filters by attribute value, only problems, hide empty, and each axis's sort, groups and collapsed groups. */
|
|
88
|
+
export interface MatrixQueryState {
|
|
89
|
+
search: string;
|
|
90
|
+
attentionOnly: boolean;
|
|
91
|
+
hideEmpty: boolean;
|
|
92
|
+
filters: { rows: Record<string, string[]>; columns: Record<string, string[]> };
|
|
93
|
+
sort: { rows: MatrixSort | null; columns: MatrixSort | null };
|
|
94
|
+
group: { rows: string | null; columns: string | null };
|
|
95
|
+
collapsed: { rows: string[]; columns: string[] };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** What canopyx:matrixCell carries: the row and column (or their groups), the state and the cell's extras. */
|
|
99
|
+
export interface MatrixCellDetail {
|
|
100
|
+
matrix: string;
|
|
101
|
+
row: string | null;
|
|
102
|
+
rowGroup: string | null;
|
|
103
|
+
column: string | null;
|
|
104
|
+
columnGroup: string | null;
|
|
105
|
+
/** The state id, "self" for a self cell, or null without data. */
|
|
106
|
+
state: string | null;
|
|
107
|
+
value: number | null;
|
|
108
|
+
text: string | null;
|
|
109
|
+
title: string | null;
|
|
110
|
+
details: [string, string][];
|
|
111
|
+
/** The cells a rolled-up cell covers, and how many of them need attention. */
|
|
112
|
+
members: number;
|
|
113
|
+
attention: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** A state to apply: any part of the query, down to one axis of filters, sorts, groups or collapsed groups. */
|
|
117
|
+
export interface MatrixStateInput {
|
|
118
|
+
search?: string;
|
|
119
|
+
attentionOnly?: boolean;
|
|
120
|
+
hideEmpty?: boolean;
|
|
121
|
+
filters?: { rows?: Record<string, string[] | null>; columns?: Record<string, string[] | null> };
|
|
122
|
+
sort?: { rows?: MatrixSort | null; columns?: MatrixSort | null };
|
|
123
|
+
group?: { rows?: string | null; columns?: string | null };
|
|
124
|
+
collapsed?: { rows?: string[]; columns?: string[] };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Options of createMatrix and CanopyX.configure for a matrix fragment. */
|
|
128
|
+
export interface MatrixOptions {
|
|
129
|
+
view: MatrixDocument;
|
|
130
|
+
labels?: Record<string, string>;
|
|
131
|
+
state?: MatrixStateInput;
|
|
132
|
+
onReady?: (detail: { matrix: string }) => void;
|
|
133
|
+
/** Called before the details dialog; preventDefault on the event keeps it closed. */
|
|
134
|
+
onCell?: (detail: MatrixCellDetail, event: CustomEvent<MatrixCellDetail>) => void;
|
|
135
|
+
onStateChange?: (state: MatrixQueryState) => void;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** The API of a matrix. Call it once `ready` has settled; a call made before the matrix part is in waits for it and returns a promise instead. */
|
|
139
|
+
export interface MatrixApi {
|
|
140
|
+
readonly element: HTMLElement;
|
|
141
|
+
readonly view: MatrixDocument;
|
|
142
|
+
readonly ready: Promise<MatrixApi>;
|
|
143
|
+
sort(axis: "rows" | "columns", by: MatrixSort["by"] | null, direction?: "asc" | "desc"): void;
|
|
144
|
+
group(axis: "rows" | "columns", attribute: string | null): void;
|
|
145
|
+
filter(axis: "rows" | "columns", attribute: string, values: string[] | null): void;
|
|
146
|
+
setSearch(text: string): void;
|
|
147
|
+
setAttentionOnly(on: boolean): void;
|
|
148
|
+
getState(): Readonly<MatrixQueryState>;
|
|
149
|
+
setState(state: MatrixStateInput): void;
|
|
150
|
+
/** The ids of the visible items, members of collapsed groups included, in order. */
|
|
151
|
+
getVisible(): Readonly<{ rows: string[]; columns: string[] }>;
|
|
152
|
+
/** Moves focus to a cell; false when the row or column is not shown. */
|
|
153
|
+
focusCell(row: string, column: string): boolean;
|
|
154
|
+
/** Replaces the document, keeping the query that still applies (live refresh). */
|
|
155
|
+
update(view: MatrixDocument): void;
|
|
156
|
+
destroy(): void;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Creates a status matrix in a host element (docs/matrix.md). Ships with the grid and reporting entry points. */
|
|
160
|
+
export declare function createMatrix(host: HTMLElement, options: MatrixOptions): MatrixApi;
|
package/README.md
CHANGED
|
@@ -20,14 +20,16 @@ Turn application data into searchable trees, sortable tables and standalone HTML
|
|
|
20
20
|
- **Application views** backed by paged or cursor-based data sources, with selection and detail callbacks.
|
|
21
21
|
- **Email and print tables** rendered from the same .NET view without JavaScript.
|
|
22
22
|
- **Calendars and resource timelines** of the same records: month, week, day, agenda and year views, resources grouped as a tree with capacity per group, recurring events, drag to reschedule through the grid's editing, and iCalendar export.
|
|
23
|
+
- **Status matrices**: a state for each pair of two sets of entities, with totals, sorting, filtering and grouping on both axes, sticky headers and both axes windowed ([docs/matrix.md](docs/matrix.md)).
|
|
24
|
+
- **Guided flows** for setup and edit tasks: steps with typed fields, conditions as data, validation, a review page with change links, secrets that never echo, and one proposal to the host ([docs/flow.md](docs/flow.md)).
|
|
23
25
|
|
|
24
|
-

|
|
25
27
|
|
|
26
28
|
The same explorer in the dark theme, alongside its script-free output for email and print:
|
|
27
29
|
|
|
28
30
|
| Dark theme | Static outline |
|
|
29
31
|
| --- | --- |
|
|
30
|
-
|  |  |
|
|
31
33
|
|
|
32
34
|
## Features
|
|
33
35
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evotecit/canopyx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Interactive tree grids and data tables with virtual rows, search, filters and offline HTML reports.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
"types": "./JavaScript/grid.d.ts",
|
|
23
23
|
"import": "./CanopyX.Html/Assets/canopyx-grid-module.mjs"
|
|
24
24
|
},
|
|
25
|
+
"./flow": {
|
|
26
|
+
"types": "./JavaScript/flow.d.ts",
|
|
27
|
+
"import": "./CanopyX.Html/Assets/canopyx-flow-module.mjs"
|
|
28
|
+
},
|
|
29
|
+
"./flow-entry.js": "./CanopyX.Html/Assets/canopyx-flow-entry.js",
|
|
30
|
+
"./flow-entry.css": "./CanopyX.Html/Assets/canopyx-flow-entry.css",
|
|
25
31
|
"./grid.css": "./CanopyX.Html/Assets/canopyx-grid.css",
|
|
26
32
|
"./grid.js": "./CanopyX.Html/Assets/canopyx-grid.js",
|
|
27
33
|
"./reporting": {
|
|
@@ -38,6 +44,12 @@
|
|
|
38
44
|
"./pager.css": "./CanopyX.Html/Assets/canopyx-pager.css",
|
|
39
45
|
"./enhance.js": "./CanopyX.Html/Assets/canopyx-enhance.js",
|
|
40
46
|
"./data.js": "./CanopyX.Html/Assets/canopyx-data.js",
|
|
47
|
+
"./forms.js": "./CanopyX.Html/Assets/canopyx-forms.js",
|
|
48
|
+
"./forms.css": "./CanopyX.Html/Assets/canopyx-forms.css",
|
|
49
|
+
"./flow.js": "./CanopyX.Html/Assets/canopyx-flow.js",
|
|
50
|
+
"./flow.css": "./CanopyX.Html/Assets/canopyx-flow.css",
|
|
51
|
+
"./matrix.js": "./CanopyX.Html/Assets/canopyx-matrix.js",
|
|
52
|
+
"./matrix.css": "./CanopyX.Html/Assets/canopyx-matrix.css",
|
|
41
53
|
"./editing.js": "./CanopyX.Html/Assets/canopyx-editing.js",
|
|
42
54
|
"./editing.css": "./CanopyX.Html/Assets/canopyx-editing.css",
|
|
43
55
|
"./column-groups.js": "./CanopyX.Html/Assets/canopyx-column-groups.js",
|
|
@@ -126,6 +138,15 @@
|
|
|
126
138
|
"CanopyX.Html/Assets/canopyx-pager.css",
|
|
127
139
|
"CanopyX.Html/Assets/canopyx-enhance.js",
|
|
128
140
|
"CanopyX.Html/Assets/canopyx-data.js",
|
|
141
|
+
"CanopyX.Html/Assets/canopyx-flow-module.mjs",
|
|
142
|
+
"CanopyX.Html/Assets/canopyx-flow-entry.js",
|
|
143
|
+
"CanopyX.Html/Assets/canopyx-flow-entry.css",
|
|
144
|
+
"CanopyX.Html/Assets/canopyx-forms.js",
|
|
145
|
+
"CanopyX.Html/Assets/canopyx-forms.css",
|
|
146
|
+
"CanopyX.Html/Assets/canopyx-flow.js",
|
|
147
|
+
"CanopyX.Html/Assets/canopyx-flow.css",
|
|
148
|
+
"CanopyX.Html/Assets/canopyx-matrix.js",
|
|
149
|
+
"CanopyX.Html/Assets/canopyx-matrix.css",
|
|
129
150
|
"CanopyX.Html/Assets/canopyx-editing.js",
|
|
130
151
|
"CanopyX.Html/Assets/canopyx-editing.css",
|
|
131
152
|
"CanopyX.Html/Assets/canopyx-column-groups.js",
|
|
@@ -165,6 +186,8 @@
|
|
|
165
186
|
"CanopyX.Html/Assets/canopyx-timeline.css"
|
|
166
187
|
],
|
|
167
188
|
"keywords": [
|
|
189
|
+
"forms",
|
|
190
|
+
"wizard",
|
|
168
191
|
"treegrid",
|
|
169
192
|
"treeview",
|
|
170
193
|
"data-grid",
|