@wemake4u/form-controls 2.0.1 → 2.0.2
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.
|
@@ -9638,6 +9638,8 @@ var SirioNumber = class SirioNumber extends SirioAdornedControlBase {
|
|
|
9638
9638
|
...ngDevMode ? { debugName: "showSpinner" } : /* istanbul ignore next */ {},
|
|
9639
9639
|
transform: booleanAttribute
|
|
9640
9640
|
});
|
|
9641
|
+
incrementLabel = input("Aumenta", ...ngDevMode ? [{ debugName: "incrementLabel" }] : /* istanbul ignore next */ []);
|
|
9642
|
+
decrementLabel = input("Diminuisci", ...ngDevMode ? [{ debugName: "decrementLabel" }] : /* istanbul ignore next */ []);
|
|
9641
9643
|
step = input(1, {
|
|
9642
9644
|
...ngDevMode ? { debugName: "step" } : /* istanbul ignore next */ {},
|
|
9643
9645
|
transform: (v) => optionalNumber$2(v) ?? 1
|
|
@@ -9925,6 +9927,20 @@ var SirioNumber = class SirioNumber extends SirioAdornedControlBase {
|
|
|
9925
9927
|
isRequired: false,
|
|
9926
9928
|
transformFunction: null
|
|
9927
9929
|
},
|
|
9930
|
+
incrementLabel: {
|
|
9931
|
+
classPropertyName: "incrementLabel",
|
|
9932
|
+
publicName: "incrementLabel",
|
|
9933
|
+
isSignal: true,
|
|
9934
|
+
isRequired: false,
|
|
9935
|
+
transformFunction: null
|
|
9936
|
+
},
|
|
9937
|
+
decrementLabel: {
|
|
9938
|
+
classPropertyName: "decrementLabel",
|
|
9939
|
+
publicName: "decrementLabel",
|
|
9940
|
+
isSignal: true,
|
|
9941
|
+
isRequired: false,
|
|
9942
|
+
transformFunction: null
|
|
9943
|
+
},
|
|
9928
9944
|
step: {
|
|
9929
9945
|
classPropertyName: "step",
|
|
9930
9946
|
publicName: "step",
|
|
@@ -9943,7 +9959,7 @@ var SirioNumber = class SirioNumber extends SirioAdornedControlBase {
|
|
|
9943
9959
|
}],
|
|
9944
9960
|
usesInheritance: true,
|
|
9945
9961
|
ngImport: i0,
|
|
9946
|
-
template: "<wm-sirio-field\n [inputId]=\"inputId()\"\n [helpId]=\"helpId()\"\n [errorId]=\"errorId()\"\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [required]=\"isRequired()\"\n [errorMessage]=\"feedbackMessage()\"\n [state]=\"validationState()\"\n>\n <div class=\"sirio-input-group\">\n @if (prefix()) {\n <span class=\"sirio-input-group-text\" [id]=\"prefixId()\">{{ prefix() }}</span>\n }\n <ng-content select=\"[wmSirioPrefix]\" />\n <span\n class=\"sirio-number-field\"\n [class.sirio-number-after-prefix]=\"hasPrefix()\"\n [class.sirio-number-before-suffix]=\"hasSuffix()\"\n [class.sirio-number-no-spinner]=\"!showSpinner()\"\n >\n <input\n #field\n class=\"sirio-form-control\"\n type=\"text\"\n role=\"spinbutton\"\n autocomplete=\"off\"\n [attr.inputmode]=\"inputMode()\"\n [style.text-align]=\"textAlign()\"\n [class.sirio-is-invalid]=\"showError()\"\n [class.sirio-is-valid]=\"validationState() === 'valid'\"\n [class.sirio-is-warning]=\"validationState() === 'warning'\"\n [class.filled]=\"value() !== null\"\n [id]=\"inputId()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.name]=\"name()\"\n [value]=\"text()\"\n [attr.placeholder]=\"placeholder() || null\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuetext]=\"text() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-invalid]=\"showError() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n />\n <!-- Sirio up/down icon as mouse buttons; keyboard users use Arrow Up/Down (spinbutton). -->\n @if (showSpinner()) {\n <span\n class=\"sirio-number-spinner\"\n [class.sirio-number-spinner-invalid]=\"showError() || pendingVisible()\"\n aria-hidden=\"true\"\n >\n <button\n type=\"button\"\n tabindex=\"-1\"\n [disabled]=\"isDisabled() || readonly()\"\n (pointerdown)=\"startRepeat($event, 1)\"\n ></button>\n <button\n type=\"button\"\n tabindex=\"-1\"\n [disabled]=\"isDisabled() || readonly()\"\n (pointerdown)=\"startRepeat($event, -1)\"\n ></button>\n </span>\n }\n </span>\n <ng-content select=\"[wmSirioSuffix]\" />\n @if (suffix()) {\n <span class=\"sirio-input-group-text\" [id]=\"suffixId()\">{{ suffix() }}</span>\n }\n </div>\n</wm-sirio-field>\n",
|
|
9962
|
+
template: "<wm-sirio-field\n [inputId]=\"inputId()\"\n [helpId]=\"helpId()\"\n [errorId]=\"errorId()\"\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [required]=\"isRequired()\"\n [errorMessage]=\"feedbackMessage()\"\n [state]=\"validationState()\"\n>\n <div class=\"sirio-input-group\">\n @if (prefix()) {\n <span class=\"sirio-input-group-text\" [id]=\"prefixId()\">{{ prefix() }}</span>\n }\n <ng-content select=\"[wmSirioPrefix]\" />\n <span\n class=\"sirio-number-field\"\n [class.sirio-number-after-prefix]=\"hasPrefix()\"\n [class.sirio-number-before-suffix]=\"hasSuffix()\"\n [class.sirio-number-no-spinner]=\"!showSpinner()\"\n >\n <input\n #field\n class=\"sirio-form-control\"\n type=\"text\"\n role=\"spinbutton\"\n autocomplete=\"off\"\n [attr.inputmode]=\"inputMode()\"\n [style.text-align]=\"textAlign()\"\n [class.sirio-is-invalid]=\"showError()\"\n [class.sirio-is-valid]=\"validationState() === 'valid'\"\n [class.sirio-is-warning]=\"validationState() === 'warning'\"\n [class.filled]=\"value() !== null\"\n [id]=\"inputId()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.name]=\"name()\"\n [value]=\"text()\"\n [attr.placeholder]=\"placeholder() || null\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuetext]=\"text() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-invalid]=\"showError() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n />\n <!-- Sirio up/down icon as mouse buttons; keyboard users use Arrow Up/Down (spinbutton). -->\n @if (showSpinner()) {\n <span\n class=\"sirio-number-spinner\"\n [class.sirio-number-spinner-invalid]=\"showError() || pendingVisible()\"\n aria-hidden=\"true\"\n >\n <button\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"incrementLabel()\"\n [disabled]=\"isDisabled() || readonly()\"\n (pointerdown)=\"startRepeat($event, 1)\"\n ></button>\n <button\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"decrementLabel()\"\n [disabled]=\"isDisabled() || readonly()\"\n (pointerdown)=\"startRepeat($event, -1)\"\n ></button>\n </span>\n }\n </span>\n <ng-content select=\"[wmSirioSuffix]\" />\n @if (suffix()) {\n <span class=\"sirio-input-group-text\" [id]=\"suffixId()\">{{ suffix() }}</span>\n }\n </div>\n</wm-sirio-field>\n",
|
|
9947
9963
|
styles: [".sirio-input-group>::ng-deep :focus,.sirio-input-group>::ng-deep :focus-visible,.sirio-number-field:focus-within{position:relative;z-index:3}.sirio-number-field{position:relative;display:flex;flex:1 1 auto;width:1%;min-width:0}.sirio-number-field>input{width:100%;font-family:Roboto Mono,monospace}.sirio-number-field:not(.sirio-number-no-spinner)>input{padding-right:44px}.sirio-number-field:not(.sirio-number-no-spinner)>input.sirio-is-invalid{padding-right:68px}.sirio-number-field.sirio-number-after-prefix>input{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.sirio-number-field.sirio-number-before-suffix>input{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.sirio-number-spinner{position:absolute;top:50%;right:12px;width:22px;height:28px;transform:translateY(-50%);display:flex;flex-direction:column;background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23454d56' viewBox='0 0 320 512'%3E%3Cpath d='M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41m255-105L177 64c-9.4-9.4-24.6-9.4-33.9 0L24 183c-15.1 15.1-4.4 41 17 41h238c21.4 0 32.1-25.9 17-41'/%3E%3C/svg%3E\");background-position:50% 50%;background-repeat:no-repeat;background-size:10px;z-index:4}.sirio-number-spinner.sirio-number-spinner-invalid{right:38px}.sirio-number-spinner button{flex:1 1 50%;padding:0;border:0;border-radius:2px;background:transparent;cursor:pointer}.sirio-number-spinner button:hover:not(:disabled){background-color:#2f6dd526}.sirio-number-spinner button:active:not(:disabled){background-color:#00368f4d}.sirio-number-spinner button:disabled{cursor:default}.sirio-input-group:has(.sirio-is-invalid) ::ng-deep .sirio-input-group-text{border-color:#aa224f}.sirio-input-group:has(.sirio-form-control:disabled,.sirio-form-control.disabled,.sirio-form-control[readonly]) ::ng-deep .sirio-input-group-text{background-color:#e3e5e8;color:#5b6571}.sirio-input-group:has(.sirio-form-control:disabled,.sirio-form-control.disabled,.sirio-form-control[readonly]):not(:has(.sirio-is-invalid)) ::ng-deep .sirio-input-group-text{border-color:#e3e5e8}.sirio-input-group:has(.sirio-form-control:disabled,.sirio-form-control.disabled,.sirio-form-control[readonly]):not(:has(.sirio-is-invalid)) ::ng-deep .sirio-input-group-text:has(~.sirio-number-field){position:relative;z-index:2;border-right:1px solid #c6ccd2}.sirio-input-group:has(.sirio-form-control:disabled,.sirio-form-control.disabled,.sirio-form-control[readonly]):not(:has(.sirio-is-invalid)) ::ng-deep .sirio-number-field~.sirio-input-group-text{position:relative;z-index:2;border-left:1px solid #c6ccd2}:host .sirio-form-control[aria-readonly=true]:not(:disabled,.disabled,:focus-visible,.sirio-is-invalid,.sirio-is-valid,.sirio-is-warning){border-color:#e3e5e8}:host .sirio-input-group-autocomplete>.sirio-dropdown>.sirio-form-control[readonly]:not(:disabled,.disabled,:focus,.sirio-is-invalid,.sirio-is-valid,.sirio-is-warning){border-color:#e3e5e8}:host(:not(.wm-sirio-readonly-outline)) .sirio-form-control[aria-readonly=true]:not(:disabled,.disabled){background-color:#e3e5e8;color:#5b6571}:host(.wm-sirio-readonly-outline) .sirio-form-control[readonly]:not(:disabled,.disabled),:host(.wm-sirio-readonly-outline) .sirio-form-control[aria-readonly=true]:not(:disabled,.disabled){background-color:#fff!important;color:#454d56}:host(.wm-sirio-readonly-outline) .sirio-input-group:has(.sirio-form-control[readonly]:not(:disabled,.disabled)) ::ng-deep .sirio-input-group-text{background-color:#e9ecef;color:#454d56}\n"],
|
|
9948
9964
|
dependencies: [{
|
|
9949
9965
|
kind: "component",
|
|
@@ -9978,7 +9994,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
9978
9994
|
imports: [SirioField],
|
|
9979
9995
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
9980
9996
|
providers: [provideSirioControl(() => SirioNumber, { validator: true })],
|
|
9981
|
-
template: "<wm-sirio-field\n [inputId]=\"inputId()\"\n [helpId]=\"helpId()\"\n [errorId]=\"errorId()\"\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [required]=\"isRequired()\"\n [errorMessage]=\"feedbackMessage()\"\n [state]=\"validationState()\"\n>\n <div class=\"sirio-input-group\">\n @if (prefix()) {\n <span class=\"sirio-input-group-text\" [id]=\"prefixId()\">{{ prefix() }}</span>\n }\n <ng-content select=\"[wmSirioPrefix]\" />\n <span\n class=\"sirio-number-field\"\n [class.sirio-number-after-prefix]=\"hasPrefix()\"\n [class.sirio-number-before-suffix]=\"hasSuffix()\"\n [class.sirio-number-no-spinner]=\"!showSpinner()\"\n >\n <input\n #field\n class=\"sirio-form-control\"\n type=\"text\"\n role=\"spinbutton\"\n autocomplete=\"off\"\n [attr.inputmode]=\"inputMode()\"\n [style.text-align]=\"textAlign()\"\n [class.sirio-is-invalid]=\"showError()\"\n [class.sirio-is-valid]=\"validationState() === 'valid'\"\n [class.sirio-is-warning]=\"validationState() === 'warning'\"\n [class.filled]=\"value() !== null\"\n [id]=\"inputId()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.name]=\"name()\"\n [value]=\"text()\"\n [attr.placeholder]=\"placeholder() || null\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuetext]=\"text() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-invalid]=\"showError() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n />\n <!-- Sirio up/down icon as mouse buttons; keyboard users use Arrow Up/Down (spinbutton). -->\n @if (showSpinner()) {\n <span\n class=\"sirio-number-spinner\"\n [class.sirio-number-spinner-invalid]=\"showError() || pendingVisible()\"\n aria-hidden=\"true\"\n >\n <button\n type=\"button\"\n tabindex=\"-1\"\n [disabled]=\"isDisabled() || readonly()\"\n (pointerdown)=\"startRepeat($event, 1)\"\n ></button>\n <button\n type=\"button\"\n tabindex=\"-1\"\n [disabled]=\"isDisabled() || readonly()\"\n (pointerdown)=\"startRepeat($event, -1)\"\n ></button>\n </span>\n }\n </span>\n <ng-content select=\"[wmSirioSuffix]\" />\n @if (suffix()) {\n <span class=\"sirio-input-group-text\" [id]=\"suffixId()\">{{ suffix() }}</span>\n }\n </div>\n</wm-sirio-field>\n",
|
|
9997
|
+
template: "<wm-sirio-field\n [inputId]=\"inputId()\"\n [helpId]=\"helpId()\"\n [errorId]=\"errorId()\"\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [required]=\"isRequired()\"\n [errorMessage]=\"feedbackMessage()\"\n [state]=\"validationState()\"\n>\n <div class=\"sirio-input-group\">\n @if (prefix()) {\n <span class=\"sirio-input-group-text\" [id]=\"prefixId()\">{{ prefix() }}</span>\n }\n <ng-content select=\"[wmSirioPrefix]\" />\n <span\n class=\"sirio-number-field\"\n [class.sirio-number-after-prefix]=\"hasPrefix()\"\n [class.sirio-number-before-suffix]=\"hasSuffix()\"\n [class.sirio-number-no-spinner]=\"!showSpinner()\"\n >\n <input\n #field\n class=\"sirio-form-control\"\n type=\"text\"\n role=\"spinbutton\"\n autocomplete=\"off\"\n [attr.inputmode]=\"inputMode()\"\n [style.text-align]=\"textAlign()\"\n [class.sirio-is-invalid]=\"showError()\"\n [class.sirio-is-valid]=\"validationState() === 'valid'\"\n [class.sirio-is-warning]=\"validationState() === 'warning'\"\n [class.filled]=\"value() !== null\"\n [id]=\"inputId()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.name]=\"name()\"\n [value]=\"text()\"\n [attr.placeholder]=\"placeholder() || null\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuetext]=\"text() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-invalid]=\"showError() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n />\n <!-- Sirio up/down icon as mouse buttons; keyboard users use Arrow Up/Down (spinbutton). -->\n @if (showSpinner()) {\n <span\n class=\"sirio-number-spinner\"\n [class.sirio-number-spinner-invalid]=\"showError() || pendingVisible()\"\n aria-hidden=\"true\"\n >\n <button\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"incrementLabel()\"\n [disabled]=\"isDisabled() || readonly()\"\n (pointerdown)=\"startRepeat($event, 1)\"\n ></button>\n <button\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"decrementLabel()\"\n [disabled]=\"isDisabled() || readonly()\"\n (pointerdown)=\"startRepeat($event, -1)\"\n ></button>\n </span>\n }\n </span>\n <ng-content select=\"[wmSirioSuffix]\" />\n @if (suffix()) {\n <span class=\"sirio-input-group-text\" [id]=\"suffixId()\">{{ suffix() }}</span>\n }\n </div>\n</wm-sirio-field>\n",
|
|
9982
9998
|
styles: [".sirio-input-group>::ng-deep :focus,.sirio-input-group>::ng-deep :focus-visible,.sirio-number-field:focus-within{position:relative;z-index:3}.sirio-number-field{position:relative;display:flex;flex:1 1 auto;width:1%;min-width:0}.sirio-number-field>input{width:100%;font-family:Roboto Mono,monospace}.sirio-number-field:not(.sirio-number-no-spinner)>input{padding-right:44px}.sirio-number-field:not(.sirio-number-no-spinner)>input.sirio-is-invalid{padding-right:68px}.sirio-number-field.sirio-number-after-prefix>input{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.sirio-number-field.sirio-number-before-suffix>input{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.sirio-number-spinner{position:absolute;top:50%;right:12px;width:22px;height:28px;transform:translateY(-50%);display:flex;flex-direction:column;background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23454d56' viewBox='0 0 320 512'%3E%3Cpath d='M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41m255-105L177 64c-9.4-9.4-24.6-9.4-33.9 0L24 183c-15.1 15.1-4.4 41 17 41h238c21.4 0 32.1-25.9 17-41'/%3E%3C/svg%3E\");background-position:50% 50%;background-repeat:no-repeat;background-size:10px;z-index:4}.sirio-number-spinner.sirio-number-spinner-invalid{right:38px}.sirio-number-spinner button{flex:1 1 50%;padding:0;border:0;border-radius:2px;background:transparent;cursor:pointer}.sirio-number-spinner button:hover:not(:disabled){background-color:#2f6dd526}.sirio-number-spinner button:active:not(:disabled){background-color:#00368f4d}.sirio-number-spinner button:disabled{cursor:default}.sirio-input-group:has(.sirio-is-invalid) ::ng-deep .sirio-input-group-text{border-color:#aa224f}.sirio-input-group:has(.sirio-form-control:disabled,.sirio-form-control.disabled,.sirio-form-control[readonly]) ::ng-deep .sirio-input-group-text{background-color:#e3e5e8;color:#5b6571}.sirio-input-group:has(.sirio-form-control:disabled,.sirio-form-control.disabled,.sirio-form-control[readonly]):not(:has(.sirio-is-invalid)) ::ng-deep .sirio-input-group-text{border-color:#e3e5e8}.sirio-input-group:has(.sirio-form-control:disabled,.sirio-form-control.disabled,.sirio-form-control[readonly]):not(:has(.sirio-is-invalid)) ::ng-deep .sirio-input-group-text:has(~.sirio-number-field){position:relative;z-index:2;border-right:1px solid #c6ccd2}.sirio-input-group:has(.sirio-form-control:disabled,.sirio-form-control.disabled,.sirio-form-control[readonly]):not(:has(.sirio-is-invalid)) ::ng-deep .sirio-number-field~.sirio-input-group-text{position:relative;z-index:2;border-left:1px solid #c6ccd2}:host .sirio-form-control[aria-readonly=true]:not(:disabled,.disabled,:focus-visible,.sirio-is-invalid,.sirio-is-valid,.sirio-is-warning){border-color:#e3e5e8}:host .sirio-input-group-autocomplete>.sirio-dropdown>.sirio-form-control[readonly]:not(:disabled,.disabled,:focus,.sirio-is-invalid,.sirio-is-valid,.sirio-is-warning){border-color:#e3e5e8}:host(:not(.wm-sirio-readonly-outline)) .sirio-form-control[aria-readonly=true]:not(:disabled,.disabled){background-color:#e3e5e8;color:#5b6571}:host(.wm-sirio-readonly-outline) .sirio-form-control[readonly]:not(:disabled,.disabled),:host(.wm-sirio-readonly-outline) .sirio-form-control[aria-readonly=true]:not(:disabled,.disabled){background-color:#fff!important;color:#454d56}:host(.wm-sirio-readonly-outline) .sirio-input-group:has(.sirio-form-control[readonly]:not(:disabled,.disabled)) ::ng-deep .sirio-input-group-text{background-color:#e9ecef;color:#454d56}\n"]
|
|
9983
9999
|
}]
|
|
9984
10000
|
}],
|
|
@@ -10040,6 +10056,22 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
10040
10056
|
required: false
|
|
10041
10057
|
}]
|
|
10042
10058
|
}],
|
|
10059
|
+
incrementLabel: [{
|
|
10060
|
+
type: i0.Input,
|
|
10061
|
+
args: [{
|
|
10062
|
+
isSignal: true,
|
|
10063
|
+
alias: "incrementLabel",
|
|
10064
|
+
required: false
|
|
10065
|
+
}]
|
|
10066
|
+
}],
|
|
10067
|
+
decrementLabel: [{
|
|
10068
|
+
type: i0.Input,
|
|
10069
|
+
args: [{
|
|
10070
|
+
isSignal: true,
|
|
10071
|
+
alias: "decrementLabel",
|
|
10072
|
+
required: false
|
|
10073
|
+
}]
|
|
10074
|
+
}],
|
|
10043
10075
|
step: [{
|
|
10044
10076
|
type: i0.Input,
|
|
10045
10077
|
args: [{
|
|
@@ -14084,7 +14116,7 @@ var SirioDataGrid = class SirioDataGrid {
|
|
|
14084
14116
|
isSignal: true
|
|
14085
14117
|
}],
|
|
14086
14118
|
ngImport: i0,
|
|
14087
|
-
template: "<!-- Controls of a column filter: in the header popover (labelled = false) or in the card panel. -->\n<ng-template #filterControls let-column let-labelled=\"labelled\">\n @if (operatorsOf(column).length) {\n <ng-container *ngTemplateOutlet=\"conditionControls; context: { $implicit: column, labelled: labelled }\" />\n } @else {\n @switch (column.filter()) {\n @case ('number') {\n <ng-container *ngTemplateOutlet=\"range; context: { $implicit: column, labelled: labelled, date: false }\" />\n }\n @case ('date') {\n <ng-container *ngTemplateOutlet=\"range; context: { $implicit: column, labelled: labelled, date: true }\" />\n }\n @case ('select') {\n <!-- Without filterOptions: the values present in the column (TanStack faceted values). -->\n <wm-sirio-select\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [options]=\"filterOptionsOf(column)\"\n [multiple]=\"column.filterMultiple()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column)\"\n (ngModelChange)=\"setFilter(column, $event)\"\n />\n }\n @case ('boolean') {\n <wm-sirio-select\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [options]=\"booleanOptions()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column)\"\n (ngModelChange)=\"setFilter(column, $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [placeholder]=\"column.filterPlaceholder()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column) ?? ''\"\n (ngModelChange)=\"setFilter(column, $event, false)\"\n />\n }\n }\n }\n</ng-template>\n\n<!-- Filter with operators: \"Condizione\" choice, then the value (two bounds for \"Compreso tra\", none for \"Vuoto\"). -->\n<ng-template #conditionControls let-column let-labelled=\"labelled\">\n @let condition = conditionOf(column);\n @let op = condition.operator;\n <fieldset class=\"wm-sirio-grid-filter-range\">\n <legend [class.sr-only]=\"!labelled\" class=\"sirio-label\">{{ column.header() }}</legend>\n <wm-sirio-select\n [label]=\"filterConditionLabel()\"\n [options]=\"operatorOptions(column)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"op\"\n (ngModelChange)=\"setOperator(column, $event)\"\n />\n @if (op !== 'blank' && op !== 'notBlank') {\n @switch (column.filter()) {\n @case ('number') {\n <wm-sirio-number\n [label]=\"op === 'between' ? filterFromLabel() : filterValueLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n @if (op === 'between') {\n <wm-sirio-number [label]=\"filterToLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"condition.to ?? null\" (ngModelChange)=\"setConditionPart(column, 'to', $event)\" />\n }\n }\n @case ('date') {\n <wm-sirio-date\n [label]=\"op === 'between' ? filterFromLabel() : filterValueLabel()\"\n [max]=\"op === 'between' ? ($any(condition.to) ?? null) : null\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n @if (op === 'between') {\n <wm-sirio-date\n [label]=\"filterToLabel()\"\n [min]=\"$any(condition.value) ?? null\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.to ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'to', $event)\"\n />\n }\n }\n @case ('select') {\n <wm-sirio-select\n [label]=\"filterValueLabel()\"\n [options]=\"filterOptionsOf(column)\"\n [multiple]=\"column.filterMultiple()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n }\n @case ('boolean') {\n <wm-sirio-select\n [label]=\"filterValueLabel()\"\n [options]=\"booleanOptions()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [label]=\"filterValueLabel()\"\n [placeholder]=\"column.filterPlaceholder()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? ''\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event, false)\"\n />\n }\n }\n }\n </fieldset>\n</ng-template>\n\n<!-- Range filter (number / date): \"Da\" and \"A\", grouped by the column header in the card panel. -->\n<ng-template #range let-column let-labelled=\"labelled\" let-date=\"date\">\n @let value = rangeOf(column);\n <fieldset class=\"wm-sirio-grid-filter-range\">\n <legend [class.sr-only]=\"!labelled\" class=\"sirio-label\">{{ column.header() }}</legend>\n @if (date) {\n <wm-sirio-date [label]=\"filterFromLabel()\" [max]=\"$any(value.to) ?? null\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.from ?? null\" (ngModelChange)=\"setRange(column, 'from', $event)\" />\n <wm-sirio-date [label]=\"filterToLabel()\" [min]=\"$any(value.from) ?? null\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.to ?? null\" (ngModelChange)=\"setRange(column, 'to', $event)\" />\n } @else {\n <wm-sirio-number [label]=\"filterFromLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.from ?? null\" (ngModelChange)=\"setRange(column, 'from', $event)\" />\n <wm-sirio-number [label]=\"filterToLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.to ?? null\" (ngModelChange)=\"setRange(column, 'to', $event)\" />\n }\n </fieldset>\n</ng-template>\n\n<!-- Filter button of a column with its popover (in the header, or in the filter row with `filterRow`). -->\n<ng-template #filterBtnTpl let-column let-inRow=\"inRow\">\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-filter\"\n iconOnly\n class=\"wm-sirio-grid-filter-btn\"\n draggable=\"false\"\n [class.wm-sirio-grid-filter-active]=\"isFiltered(column)\"\n [white]=\"variant() === 'dark'\"\n [label]=\"filterButtonLabel(column, inRow)\"\n [wmSirioPopover]=\"filterPanel\"\n [popoverTitle]=\"filterLabel() + ' ' + column.header()\"\n popoverPlacement=\"bottom-end\"\n (opened)=\"focusFilter(column)\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n <ng-template #filterPanel>\n <div class=\"wm-sirio-grid-filter-panel\" [id]=\"baseId + '-filter-' + filterIndex(column)\">\n <ng-container *ngTemplateOutlet=\"filterControls; context: { $implicit: column, labelled: false }\" />\n <button wmSirioButton=\"tertiary-light\" size=\"small\" type=\"button\" class=\"wm-sirio-grid-filter-clear\" [disabled]=\"!isFiltered(column)\" (click)=\"clearFilter(column)\">\n {{ clearFilterLabel() }}\n </button>\n </div>\n </ng-template>\n</ng-template>\n\n<!-- Cell of the filter row: the simple condition in a field, the others as a summary (the button opens the popover). -->\n<ng-template #filterRowCell let-column>\n @let inline = inlineFilterOf(column);\n @let aria = filterLabel() + ' ' + column.header();\n <div class=\"wm-sirio-grid-filter-inline\" (keydown.escape)=\"clearFilter(column)\">\n @switch (inline.kind) {\n @case ('summary') {\n <span class=\"wm-sirio-grid-filter-summary\" [attr.title]=\"inline.summary\">{{ inline.summary }}</span>\n }\n @case ('number') {\n <wm-sirio-number [ariaLabel]=\"aria\" [placeholder]=\"inline.placeholder\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"inline.value\" (ngModelChange)=\"setInlineFilter(column, $event)\" />\n }\n @case ('date') {\n <wm-sirio-date [ariaLabel]=\"aria\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"inline.value\" (ngModelChange)=\"setInlineFilter(column, $event)\" />\n }\n @case ('select') {\n <wm-sirio-select\n [ariaLabel]=\"aria\"\n [options]=\"column.filter() === 'boolean' ? booleanOptions() : filterOptionsOf(column)\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"inline.value\"\n (ngModelChange)=\"setInlineFilter(column, $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [ariaLabel]=\"aria\"\n [placeholder]=\"inline.placeholder\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"inline.value ?? ''\"\n (ngModelChange)=\"setInlineFilter(column, $event, false)\"\n />\n }\n }\n <ng-container *ngTemplateOutlet=\"filterBtnTpl; context: { $implicit: column, inRow: true }\" />\n </div>\n</ng-template>\n\n<!-- Expand / collapse button of a row (tree rows, groups, detail rows). -->\n<ng-template #toggle let-row let-text=\"text\">\n <button\n type=\"button\"\n class=\"wm-sirio-grid-toggle\"\n [attr.aria-expanded]=\"row.getIsExpanded()\"\n [attr.aria-label]=\"expandLabel(row, text)\"\n [attr.title]=\"expandLabel(row, text)\"\n (click)=\"row.toggleExpanded()\"\n >\n <span [class]=\"row.getIsExpanded() ? 'fas fa-chevron-down' : 'fas fa-chevron-right'\" aria-hidden=\"true\"></span>\n </button>\n</ng-template>\n\n@let groups = groupableColumns().length > 0 && !server();\n@let expandTools = activeGrouping().length > 0 || treeMode() || hasDetail();\n@let formTools = canAdd() || deletableSelected().length > 0;\n@if (groups || expandTools || formTools || ((resizable() || reorderable()) && columnsCustomized())) {\n <div class=\"wm-sirio-grid-toolbar\">\n @if (groups) {\n <wm-sirio-select\n class=\"wm-sirio-grid-groupby\"\n [label]=\"groupByLabel()\"\n [options]=\"groupOptions()\"\n multiple\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"grouping()\"\n (ngModelChange)=\"setGrouping($event)\"\n />\n }\n <div class=\"wm-sirio-grid-toolbar-actions\">\n @if (canAdd()) {\n <button wmSirioButton=\"secondary\" size=\"small\" type=\"button\" icon=\"fa-plus\" iconPosition=\"start\" (click)=\"addRow()\">\n {{ addLabel() }}\n </button>\n }\n @if (deletableSelected().length) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-trash\" iconPosition=\"start\" (click)=\"deleteSelected()\">\n {{ deleteSelectedLabel() }} ({{ deletableSelected().length }})\n </button>\n }\n @if (expandTools) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-angle-double-down\" iconPosition=\"start\" (click)=\"expandAll(true)\">\n {{ expandAllLabel() }}\n </button>\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-angle-double-up\" iconPosition=\"start\" (click)=\"expandAll(false)\">\n {{ collapseAllLabel() }}\n </button>\n }\n @if ((resizable() || reorderable()) && columnsCustomized()) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-undo\" iconPosition=\"start\" (click)=\"resetColumns()\">\n {{ resetColumnsLabel() }}\n </button>\n }\n </div>\n </div>\n}\n\n@if (filterColumns().length && cardMode() && filterButton() !== 'none') {\n <!-- Card layout: the header (and its filter buttons) is hidden by the kit, filters go here. -->\n <div class=\"wm-sirio-grid-filters-mobile\">\n <button\n wmSirioButton=\"secondary\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-filter\"\n iconPosition=\"start\"\n [attr.aria-expanded]=\"filtersOpen()\"\n [attr.aria-controls]=\"filtersOpen() ? baseId + '-filters' : null\"\n (click)=\"filtersOpen.set(!filtersOpen())\"\n >\n {{ filtersLabel() }}@if (filterChips().length) {&ngsp;({{ filterChips().length }})}\n </button>\n @if (filtersOpen()) {\n <div class=\"wm-sirio-grid-filters-panel\" role=\"group\" [id]=\"baseId + '-filters'\" [attr.aria-label]=\"filtersLabel()\">\n @for (column of filterColumns(); track column) {\n <ng-container *ngTemplateOutlet=\"filterControls; context: { $implicit: column, labelled: true }\" />\n }\n </div>\n }\n </div>\n}\n@if (showFilterChips() && !filterRowActive() && filterChips().length) {\n <div class=\"wm-sirio-grid-chips\">\n <wm-sirio-filter-chips [chips]=\"filterChips()\" [label]=\"filtersLabel()\" (removed)=\"onChipRemoved($event)\" />\n @if (filterChips().length > 1) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" (click)=\"clearFilters()\">{{ clearFiltersLabel() }}</button>\n }\n </div>\n}\n<div\n #scroller\n class=\"wm-sirio-grid-scroller\"\n [class.sirio-table-responsive]=\"responsive() && !cardMode()\"\n [class.sirio-table-overflow-start]=\"responsive() && !cardMode() && overflowStart()\"\n [class.sirio-table-overflow-end]=\"responsive() && !cardMode() && overflowEnd()\"\n [class.sirio-table-th-fixed]=\"stickyHeader() && !cardMode()\"\n [class.wm-sirio-grid-pinned-left]=\"hasPinLeft()\"\n [class.wm-sirio-grid-pinned-right]=\"hasPinRight()\"\n (scroll)=\"updateOverflow()\"\n (focusin)=\"navigation() && revealFocused($event)\"\n [style.--wm-grid-pin-left]=\"pinBlockWidths().left + 'px'\"\n [style.--wm-grid-pin-right]=\"pinBlockWidths().right + 'px'\"\n>\n <table\n #table\n class=\"sirio-table\"\n [class.sirio-table-dark]=\"variant() === 'dark'\"\n [class.sirio-table-light]=\"variant() === 'striped'\"\n [class.sirio-table-xs]=\"size() === 'xs'\"\n [class.sirio-table-sm]=\"size() === 'sm'\"\n [class.sirio-table-lg]=\"size() === 'lg'\"\n [class.sirio-table-card]=\"cardOnMobile()\"\n [class.wm-sirio-grid-card-active]=\"cardMode()\"\n [class.wm-sirio-grid-selectable]=\"selection() !== 'none'\"\n [class.wm-sirio-grid-fixed-layout]=\"fixedLayout()\"\n [class.wm-sirio-grid-grouped]=\"headerDepth() > 0\"\n [class.wm-sirio-grid-filter-hover]=\"filterButton() === 'hover'\"\n [style.width.px]=\"tableWidth()\"\n [attr.aria-busy]=\"isLoading() || null\"\n [attr.role]=\"gridRole()\"\n [attr.aria-multiselectable]=\"gridRole() && selection() === 'multiple' ? true : null\"\n >\n @if (caption()) {\n <caption [class.sr-only]=\"!captionVisible()\">{{ caption() }}</caption>\n }\n @if (fixedLayout()) {\n <!-- Fixed layout: the widths come from the columns (the first header row may be a group row). -->\n <colgroup>\n @if (checkColumn()) {\n <col [style.width.px]=\"toolColumnWidth\" />\n }\n @if (hasDetail()) {\n <col [style.width.px]=\"toolColumnWidth\" />\n }\n @if (rowNumbers()) {\n <col [style.width.px]=\"rowNumberWidth\" />\n }\n @for (column of visibleColumns(); track column) {\n <col [style.width.px]=\"widthOf(column)\" />\n }\n @if (actionsColumn()) {\n <col [style.width.px]=\"actionsWidth()\" />\n }\n </colgroup>\n }\n <thead>\n <!-- Grouped headers: a row per group level, then the column headers (rowspan below shorter group paths). -->\n @for (headerRow of headerRows(); track $index; let r = $index) {\n <tr>\n @if (r === 0) {\n @if (checkColumn()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\" [attr.rowspan]=\"headerRowspan()\">\n @if (selection() === 'multiple') {\n <div class=\"sirio-table-check\">\n <div class=\"sirio-form-check\">\n <input\n type=\"checkbox\"\n [id]=\"baseId + '-all'\"\n [checked]=\"allPageSelected()\"\n [indeterminate]=\"pageSelectedCount() > 0 && !allPageSelected()\"\n [disabled]=\"!selectableRows().length\"\n (change)=\"toggleAll($any($event.target).checked)\"\n />\n <label [attr.for]=\"baseId + '-all'\"><span class=\"sr-only\">{{ selectAllText() }}</span></label>\n </div>\n </div>\n } @else {\n <span class=\"sr-only\">{{ selectionHeaderLabel() }}</span>\n }\n </th>\n }\n @if (hasDetail()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\" [attr.rowspan]=\"headerRowspan()\"><span class=\"sr-only\">{{ expandRowLabel() }}</span></th>\n }\n @if (rowNumbers()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\" [attr.rowspan]=\"headerRowspan()\">\n <span aria-hidden=\"true\">{{ rowNumberHeader() }}</span><span class=\"sr-only\">{{ rowNumberLabel() }}</span>\n </th>\n }\n }\n @for (cell of headerRow; track cell.track) {\n @if (cell.kind === 'group') {\n <th\n scope=\"colgroup\"\n class=\"wm-sirio-grid-group-th\"\n [attr.colspan]=\"cell.colspan > 1 ? cell.colspan : null\"\n [wmSirioGridPin]=\"cell.pin\"\n [style.top.px]=\"headerTop(r)\"\n >\n {{ cell.label }}\n </th>\n } @else {\n @let column = cell.column;\n @let direction = directionOf(column);\n @let id = columnId(column);\n @let drop = dropTarget();\n <th\n scope=\"col\"\n [attr.data-column]=\"id\"\n [attr.rowspan]=\"cell.rowspan > 1 ? cell.rowspan : null\"\n [style.top.px]=\"headerTop(r)\"\n [wmSirioGridPin]=\"id\"\n [class]=\"'wm-sirio-grid-align-' + column.alignment() + ' ' + column.headerClassText()\"\n [style]=\"column.headerStyleObject()\"\n [class.sirio-sorting]=\"column.sortable()\"\n [class.sirio-sorting-asc]=\"direction === 'asc'\"\n [class.sirio-sorting-desc]=\"direction === 'desc'\"\n [class.wm-sirio-grid-th-resizable]=\"canResize(column)\"\n [class.wm-sirio-grid-fit]=\"column.fit()\"\n [class.wm-sirio-grid-th-draggable]=\"reorderable() && !cardMode()\"\n [class.wm-sirio-grid-th-dragging]=\"dragId() === id\"\n [class.wm-sirio-grid-drop-before]=\"drop?.id === id && drop?.side === 'before'\"\n [class.wm-sirio-grid-drop-after]=\"drop?.id === id && drop?.side === 'after'\"\n [style.width]=\"cssWidthOf(column)\"\n [style.min-width]=\"cssMinWidthOf(column)\"\n [attr.aria-sort]=\"ariaSortOf(column)\"\n [attr.aria-describedby]=\"headerHintId(column)\"\n [attr.tabindex]=\"headerFocusable(column) ? 0 : null\"\n [attr.draggable]=\"reorderable() && !cardMode() ? 'true' : null\"\n (click)=\"onHeaderClick(column, $event)\"\n (keydown)=\"onHeaderKey(column, $event)\"\n (dragstart)=\"onDragStart(column, $event)\"\n (dragover)=\"onDragOver(column, $event)\"\n (drop)=\"onDrop($event)\"\n (dragend)=\"onDragEnd()\"\n >\n <!-- One line: the title is cut with an ellipsis, sort index and filter button stay visible. -->\n <span class=\"wm-sirio-grid-th-inner\">\n <span class=\"wm-sirio-grid-th-label\" [attr.title]=\"column.header()\">\n @if (column.headerTemplate(); as header) {\n <ng-container *ngTemplateOutlet=\"header; context: { $implicit: column }\" />\n } @else {\n {{ column.header() }}\n }\n </span>\n @if (sortIndexOf(column); as sortIndex) {\n <span class=\"wm-sirio-grid-sort-index\" aria-hidden=\"true\">{{ sortIndex }}</span>\n }\n @if (column.filter() && !filterRowActive() && filterButton() !== 'none') {\n <ng-container *ngTemplateOutlet=\"filterBtnTpl; context: { $implicit: column }\" />\n }\n </span>\n @if (canResize(column)) {\n <!-- Mouse handle: from the keyboard the focused header resizes with Alt+arrows (as ag-grid). -->\n <span\n class=\"wm-sirio-grid-resizer\"\n aria-hidden=\"true\"\n draggable=\"false\"\n [attr.title]=\"resizeColumnLabel() + ' ' + column.header()\"\n (pointerdown)=\"onResizeStart(column, $event)\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (dragstart)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (dblclick)=\"resetColumnWidth(column)\"\n ></span>\n }\n </th>\n }\n }\n @if (r === 0 && actionsColumn()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [attr.rowspan]=\"headerRowspan()\">\n <span class=\"sr-only\">{{ actionsHeader() }}</span>\n </th>\n }\n </tr>\n }\n @if (filterRowActive()) {\n @let top = headerTop(headerRows().length);\n <!-- Filter row: cells of fields, not column headers (the body cells keep the titles as headers). -->\n <tr class=\"wm-sirio-grid-filter-row\">\n @if (checkColumn()) {\n <th class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\"></th>\n }\n @if (hasDetail()) {\n <th class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\"></th>\n }\n @if (rowNumbers()) {\n <th class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\"></th>\n }\n @for (column of visibleColumns(); track column) {\n <th [wmSirioGridPin]=\"columnId(column)\" [attr.data-filter-column]=\"columnId(column)\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\">\n @if (column.filter()) {\n <ng-container *ngTemplateOutlet=\"filterRowCell; context: { $implicit: column }\" />\n }\n </th>\n }\n @if (actionsColumn()) {\n <th class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\"></th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @if (isLoading() && !renderedRows().length) {\n <tr class=\"wm-sirio-grid-message\">\n <td [attr.colspan]=\"colCount()\">\n <!-- The pending status region announces the text: the visible copy is hidden from AT. -->\n <wm-sirio-pending placement=\"inline\" [active]=\"true\" [label]=\"loadingText()\" />\n <span aria-hidden=\"true\">{{ loadingText() }}</span>\n </td>\n </tr>\n } @else if (errorContext(); as failure) {\n <!-- Failed server data source: message and \"Riprova\" (or the wmSirioGridError template). -->\n <tr class=\"wm-sirio-grid-message wm-sirio-grid-error\">\n <td [attr.colspan]=\"colCount()\" role=\"alert\">\n @if (errorTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: failure\" />\n } @else if (loadErrorText()) {\n <span class=\"fas fa-exclamation-triangle sirio-text-danger\" aria-hidden=\"true\"></span>&ngsp;{{ loadErrorText() }}&ngsp;\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-redo\" iconPosition=\"start\" (click)=\"reload()\">\n {{ retryLabel() }}\n </button>\n }\n </td>\n </tr>\n } @else {\n @for (row of renderedRows(); track row.id; let i = $index) {\n @if (row.getIsGrouped()) {\n <!-- Group row: toggle + value + count in the grouped column, aggregates in the others. -->\n @let groupColumn = groupColumnOf(row);\n <tr class=\"wm-sirio-grid-group-row\" [attr.aria-level]=\"gridRole() === 'treegrid' ? row.depth + 1 : null\">\n @if (checkColumn()) {\n <td class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\"></td>\n }\n @if (hasDetail()) {\n <td class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\"></td>\n }\n @if (rowNumbers()) {\n <td class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\"></td>\n }\n @for (column of visibleColumns(); track column) {\n <td\n [class]=\"'wm-sirio-grid-align-' + column.alignment()\"\n [class.font-mono]=\"column !== groupColumn && !!column.aggregate()\"\n [attr.data-label]=\"column.header()\"\n [wmSirioGridPin]=\"columnId(column)\"\n >\n @if (column === groupColumn) {\n @let groupText = column.formatValue(row.groupingValue);\n <span class=\"wm-sirio-grid-cell-inner\" [style.padding-inline-start.px]=\"indentOf(row)\">\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: column.header() + ' ' + groupText }\" />\n <strong>{{ groupText }}</strong>&ngsp;<span class=\"wm-sirio-grid-group-count font-mono\">({{ row.getLeafRows().length }})</span>\n </span>\n } @else if (column.aggregate()) {\n {{ aggregateText(column, row) }}\n }\n </td>\n }\n @if (actionsColumn()) {\n <td class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\"></td>\n }\n </tr>\n } @else {\n @let item = row.original;\n @let selected = isSelected(item);\n @let selectable = canSelect(item);\n @let look = rowLook(item, i);\n <tr\n [class]=\"look.cls\"\n [style]=\"look.style\"\n [class.wm-sirio-grid-row-selected]=\"selected\"\n [class.wm-sirio-grid-row-clickable]=\"clickSelect() && selectable\"\n [attr.tabindex]=\"keySelect() && selectable && !navigation() ? 0 : null\"\n [attr.aria-describedby]=\"keySelect() && selectable ? baseId + '-hint-select' : null\"\n [attr.aria-disabled]=\"selection() !== 'none' && !selectable ? 'true' : null\"\n [class.wm-sirio-grid-row-child]=\"row.depth > 0\"\n [attr.aria-selected]=\"selection() === 'none' ? null : selected\"\n [attr.aria-level]=\"gridRole() === 'treegrid' ? row.depth + 1 : null\"\n [class.wm-sirio-grid-row-invalid]=\"formMode() && rowInvalid(item)\"\n (click)=\"onRowActivate(row, i, $event)\"\n (dblclick)=\"onRowDoubleClick(row, $event)\"\n (keydown)=\"onRowKey(row, i, $event)\"\n >\n @if (checkColumn()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\">\n @if (selectable || !hideUnselectable()) {\n <div class=\"sirio-table-check\">\n <div class=\"sirio-form-check\">\n <input\n [type]=\"singleRadio() ? 'radio' : 'checkbox'\"\n [id]=\"baseId + '-row-' + i\"\n [attr.name]=\"singleRadio() ? baseId + '-row' : null\"\n [checked]=\"selected\"\n [disabled]=\"!selectable\"\n (change)=\"toggleRow(item, $any($event.target).checked)\"\n />\n <label [attr.for]=\"baseId + '-row-' + i\"><span class=\"sr-only\">{{ selectRowLabel()(item, i) }}</span></label>\n </div>\n </div>\n }\n </td>\n }\n @if (hasDetail()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\">\n @if (row.getCanExpand() && !row.subRows.length) {\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: rowName()(item, i) }\" />\n }\n </td>\n }\n @if (rowNumbers()) {\n <!-- Row header for screen readers; a td keeps the kit cell look (stripes, card layout). -->\n <td role=\"rowheader\" class=\"w-0 wm-sirio-grid-rownum-col font-mono\" wmSirioGridPin=\"__rownum\" [attr.data-label]=\"rowNumberLabel()\">{{ rowNumberOf(row) }}</td>\n }\n @for (column of visibleColumns(); track column) {\n @let cell = cellLook(column, item);\n <td\n [class]=\"cell.cls\"\n [style]=\"cell.style\"\n [class.font-mono]=\"column.isMono(item)\"\n [class.wm-sirio-grid-nowrap]=\"!column.wrap()\"\n [class.wm-sirio-grid-fit]=\"column.fit()\"\n [attr.data-label]=\"column.header()\"\n [wmSirioGridPin]=\"columnId(column)\"\n >\n @if (column === firstColumn() && (treeMode() || row.depth > 0)) {\n <span class=\"wm-sirio-grid-cell-inner\" [style.padding-inline-start.px]=\"indentOf(row)\">\n @if (treeMode()) {\n @if (row.subRows.length) {\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: column.textOf(item) }\" />\n } @else {\n <span class=\"wm-sirio-grid-toggle-spacer\" aria-hidden=\"true\"></span>\n }\n }\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: column, item: item, i: i }\" />\n </span>\n } @else {\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: column, item: item, i: i }\" />\n }\n </td>\n }\n @if (actionsColumn()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [attr.data-label]=\"actionsHeader()\">\n <span class=\"wm-sirio-grid-actions\">\n @if (rowInvalid(item)) {\n <span class=\"wm-sirio-grid-invalid\" [attr.title]=\"invalidRowLabel()\">\n <span class=\"fas fa-exclamation-circle sirio-text-danger\" aria-hidden=\"true\"></span>\n <span class=\"sr-only\">{{ invalidRowLabel() }}</span>\n </span>\n }\n @if (editorTemplate()) {\n @let editable = canEdit(item);\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n iconOnly\n [icon]=\"editable ? 'fa-pen' : 'fa-eye'\"\n [white]=\"variant() === 'dark'\"\n [label]=\"actionLabel(editable ? editLabel() : viewLabel(), item, i)\"\n (click)=\"editRow(item)\"\n ></button>\n }\n @if (canDelete(item)) {\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-trash\"\n iconOnly\n [white]=\"variant() === 'dark'\"\n [label]=\"actionLabel(deleteLabel(), item, i)\"\n (click)=\"deleteRow(item)\"\n ></button>\n }\n </span>\n </td>\n }\n </tr>\n @if (hasDetail() && row.getIsExpanded() && !row.subRows.length) {\n <tr class=\"wm-sirio-grid-detail-row\">\n <td [attr.colspan]=\"colCount()\">\n <ng-container *ngTemplateOutlet=\"detailTemplate()!; context: { $implicit: item, row: item }\" />\n </td>\n </tr>\n }\n }\n } @empty {\n <tr class=\"wm-sirio-grid-message\">\n <td [attr.colspan]=\"colCount()\">\n @if (emptyTemplate(); as empty) {\n <ng-container *ngTemplateOutlet=\"empty\" />\n } @else {\n {{ emptyText() }}\n }\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n@if (formError(); as error) {\n <span class=\"sirio-form-feedback sirio-visible sirio-feedback-invalid wm-sirio-grid-form-error\" role=\"alert\">{{ error }}</span>\n}\n@if (pageable() && total() > 0) {\n <wm-sirio-pagination\n [total]=\"total()\"\n [hasMore]=\"totalOpen()\"\n [moreLabel]=\"moreLabel()\"\n [(page)]=\"page\"\n [(pageSize)]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [variant]=\"paginationVariant()\"\n [siblings]=\"paginationSiblings()\"\n [showItems]=\"paginationShowItems()\"\n [ariaLabel]=\"paginationName()\"\n (paged)=\"onPaged()\"\n />\n}\n\n<ng-template #cellContent let-column let-item=\"item\" let-i=\"i\">\n @if (column.cellTemplate(); as cell) {\n <ng-container *ngTemplateOutlet=\"cell; context: { $implicit: item, row: item, value: column.valueOf(item), index: i }\" />\n } @else {\n {{ column.textOf(item) }}\n }\n</ng-template>\n\n@if (formMode() && editorTemplate(); as editor) {\n <!-- Edit dialog of a form array row: the form of wmSirioGridEditor bound to a copy of the row. -->\n <wm-sirio-dialog\n [(open)]=\"editorOpen\"\n [title]=\"editorTitle()\"\n [icon]=\"null\"\n [size]=\"editorSize()\"\n [closeLabel]=\"closeLabel()\"\n [closeOnBackdrop]=\"false\"\n (opened)=\"onEditorOpened()\"\n (closed)=\"onEditorClosed()\"\n >\n @if (editing(); as session) {\n @if (saveError(); as error) {\n <wm-sirio-alert type=\"error\" class=\"wm-sirio-grid-save-error\" [title]=\"saveErrorTitle()\" [dismissible]=\"false\">{{ error }}</wm-sirio-alert>\n }\n <div class=\"wm-sirio-grid-editor\" [id]=\"baseId + '-editor'\">\n <ng-container *ngTemplateOutlet=\"editor; context: session.context\" />\n </div>\n }\n <div wmSirioDialogFooter>\n @if (editing()?.context?.readonly) {\n <button wmSirioButton=\"primary\" type=\"button\" (click)=\"closeEditor()\">{{ closeLabel() }}</button>\n } @else {\n <button wmSirioButton=\"secondary\" type=\"button\" [disabled]=\"saving()\" (click)=\"closeEditor()\">{{ cancelLabel() }}</button>\n <button wmSirioButton=\"primary\" type=\"button\" [disabled]=\"saving()\" [attr.aria-busy]=\"saving() || null\" (click)=\"saveEditor()\">\n @if (saving()) {\n <wm-sirio-pending placement=\"inline\" [active]=\"true\" [label]=\"saveLabel()\" />\n }\n {{ saveLabel() }}\n </button>\n }\n </div>\n </wm-sirio-dialog>\n}\n\n<span class=\"sr-only\" [id]=\"baseId + '-hint-sort'\">{{ multiSortHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-select'\">{{ selectRowHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-reorder'\">{{ reorderHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-resize'\">{{ resizeHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-filter'\">{{ filterHint() }}</span>\n<span class=\"sr-only\" role=\"status\">{{ status() }}</span>\n<span class=\"sr-only\" aria-live=\"polite\">{{ announcement() }}</span>\n",
|
|
14119
|
+
template: "<!-- Controls of a column filter: in the header popover (labelled = false) or in the card panel. -->\n<ng-template #filterControls let-column let-labelled=\"labelled\">\n @if (operatorsOf(column).length) {\n <ng-container *ngTemplateOutlet=\"conditionControls; context: { $implicit: column, labelled: labelled }\" />\n } @else {\n @switch (column.filter()) {\n @case ('number') {\n <ng-container *ngTemplateOutlet=\"range; context: { $implicit: column, labelled: labelled, date: false }\" />\n }\n @case ('date') {\n <ng-container *ngTemplateOutlet=\"range; context: { $implicit: column, labelled: labelled, date: true }\" />\n }\n @case ('select') {\n <!-- Without filterOptions: the values present in the column (TanStack faceted values). -->\n <wm-sirio-select\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [options]=\"filterOptionsOf(column)\"\n [multiple]=\"column.filterMultiple()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column)\"\n (ngModelChange)=\"setFilter(column, $event)\"\n />\n }\n @case ('boolean') {\n <wm-sirio-select\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [options]=\"booleanOptions()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column)\"\n (ngModelChange)=\"setFilter(column, $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [placeholder]=\"column.filterPlaceholder()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column) ?? ''\"\n (ngModelChange)=\"setFilter(column, $event, false)\"\n />\n }\n }\n }\n</ng-template>\n\n<!-- Filter with operators: \"Condizione\" choice, then the value (two bounds for \"Compreso tra\", none for \"Vuoto\"). -->\n<ng-template #conditionControls let-column let-labelled=\"labelled\">\n @let condition = conditionOf(column);\n @let op = condition.operator;\n <fieldset class=\"wm-sirio-grid-filter-range\">\n <legend [class.sr-only]=\"!labelled\" class=\"sirio-label\">{{ column.header() }}</legend>\n <wm-sirio-select\n [label]=\"filterConditionLabel()\"\n [options]=\"operatorOptions(column)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"op\"\n (ngModelChange)=\"setOperator(column, $event)\"\n />\n @if (op !== 'blank' && op !== 'notBlank') {\n @switch (column.filter()) {\n @case ('number') {\n <wm-sirio-number\n [label]=\"op === 'between' ? filterFromLabel() : filterValueLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n @if (op === 'between') {\n <wm-sirio-number [label]=\"filterToLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"condition.to ?? null\" (ngModelChange)=\"setConditionPart(column, 'to', $event)\" />\n }\n }\n @case ('date') {\n <wm-sirio-date\n [label]=\"op === 'between' ? filterFromLabel() : filterValueLabel()\"\n [max]=\"op === 'between' ? ($any(condition.to) ?? null) : null\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n @if (op === 'between') {\n <wm-sirio-date\n [label]=\"filterToLabel()\"\n [min]=\"$any(condition.value) ?? null\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.to ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'to', $event)\"\n />\n }\n }\n @case ('select') {\n <wm-sirio-select\n [label]=\"filterValueLabel()\"\n [options]=\"filterOptionsOf(column)\"\n [multiple]=\"column.filterMultiple()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n }\n @case ('boolean') {\n <wm-sirio-select\n [label]=\"filterValueLabel()\"\n [options]=\"booleanOptions()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [label]=\"filterValueLabel()\"\n [placeholder]=\"column.filterPlaceholder()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? ''\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event, false)\"\n />\n }\n }\n }\n </fieldset>\n</ng-template>\n\n<!-- Range filter (number / date): \"Da\" and \"A\", grouped by the column header in the card panel. -->\n<ng-template #range let-column let-labelled=\"labelled\" let-date=\"date\">\n @let value = rangeOf(column);\n <fieldset class=\"wm-sirio-grid-filter-range\">\n <legend [class.sr-only]=\"!labelled\" class=\"sirio-label\">{{ column.header() }}</legend>\n @if (date) {\n <wm-sirio-date [label]=\"filterFromLabel()\" [max]=\"$any(value.to) ?? null\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.from ?? null\" (ngModelChange)=\"setRange(column, 'from', $event)\" />\n <wm-sirio-date [label]=\"filterToLabel()\" [min]=\"$any(value.from) ?? null\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.to ?? null\" (ngModelChange)=\"setRange(column, 'to', $event)\" />\n } @else {\n <wm-sirio-number [label]=\"filterFromLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.from ?? null\" (ngModelChange)=\"setRange(column, 'from', $event)\" />\n <wm-sirio-number [label]=\"filterToLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.to ?? null\" (ngModelChange)=\"setRange(column, 'to', $event)\" />\n }\n </fieldset>\n</ng-template>\n\n<!-- Filter button of a column with its popover (in the header, or in the filter row with `filterRow`). -->\n<ng-template #filterBtnTpl let-column let-inRow=\"inRow\">\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-filter\"\n iconOnly\n class=\"wm-sirio-grid-filter-btn\"\n draggable=\"false\"\n [class.wm-sirio-grid-filter-active]=\"isFiltered(column)\"\n [white]=\"variant() === 'dark'\"\n [label]=\"filterButtonLabel(column, inRow)\"\n [wmSirioPopover]=\"filterPanel\"\n [popoverTitle]=\"filterLabel() + ' ' + column.header()\"\n popoverPlacement=\"bottom-end\"\n (opened)=\"focusFilter(column)\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n <ng-template #filterPanel>\n <div class=\"wm-sirio-grid-filter-panel\" [id]=\"baseId + '-filter-' + filterIndex(column)\">\n <ng-container *ngTemplateOutlet=\"filterControls; context: { $implicit: column, labelled: false }\" />\n <button wmSirioButton=\"tertiary-light\" size=\"small\" type=\"button\" class=\"wm-sirio-grid-filter-clear\" [disabled]=\"!isFiltered(column)\" (click)=\"clearFilter(column)\">\n {{ clearFilterLabel() }}\n </button>\n </div>\n </ng-template>\n</ng-template>\n\n<!-- Cell of the filter row: the simple condition in a field, the others as a summary (the button opens the popover). -->\n<ng-template #filterRowCell let-column>\n @let inline = inlineFilterOf(column);\n @let aria = filterLabel() + ' ' + column.header();\n <div class=\"wm-sirio-grid-filter-inline\" (keydown.escape)=\"clearFilter(column)\">\n @switch (inline.kind) {\n @case ('summary') {\n <span class=\"wm-sirio-grid-filter-summary\" [attr.title]=\"inline.summary\">{{ inline.summary }}</span>\n }\n @case ('number') {\n <wm-sirio-number [ariaLabel]=\"aria\" [placeholder]=\"inline.placeholder\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"inline.value\" (ngModelChange)=\"setInlineFilter(column, $event)\" />\n }\n @case ('date') {\n <wm-sirio-date [ariaLabel]=\"aria\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"inline.value\" (ngModelChange)=\"setInlineFilter(column, $event)\" />\n }\n @case ('select') {\n <wm-sirio-select\n [ariaLabel]=\"aria\"\n [options]=\"column.filter() === 'boolean' ? booleanOptions() : filterOptionsOf(column)\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"inline.value\"\n (ngModelChange)=\"setInlineFilter(column, $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [ariaLabel]=\"aria\"\n [placeholder]=\"inline.placeholder\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"inline.value ?? ''\"\n (ngModelChange)=\"setInlineFilter(column, $event, false)\"\n />\n }\n }\n <ng-container *ngTemplateOutlet=\"filterBtnTpl; context: { $implicit: column, inRow: true }\" />\n </div>\n</ng-template>\n\n<!-- Expand / collapse button of a row (tree rows, groups, detail rows). -->\n<ng-template #toggle let-row let-text=\"text\">\n <button\n type=\"button\"\n class=\"wm-sirio-grid-toggle\"\n [attr.aria-expanded]=\"row.getIsExpanded()\"\n [attr.aria-label]=\"expandLabel(row, text)\"\n [attr.title]=\"expandLabel(row, text)\"\n (click)=\"row.toggleExpanded()\"\n >\n <span [class]=\"row.getIsExpanded() ? 'fas fa-chevron-down' : 'fas fa-chevron-right'\" aria-hidden=\"true\"></span>\n </button>\n</ng-template>\n\n@let groups = groupableColumns().length > 0 && !server();\n@let expandTools = activeGrouping().length > 0 || treeMode() || hasDetail();\n@let formTools = canAdd() || deletableSelected().length > 0;\n@if (groups || expandTools || formTools || ((resizable() || reorderable()) && columnsCustomized())) {\n <div class=\"wm-sirio-grid-toolbar\">\n @if (groups) {\n <wm-sirio-select\n class=\"wm-sirio-grid-groupby\"\n [label]=\"groupByLabel()\"\n [options]=\"groupOptions()\"\n multiple\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"grouping()\"\n (ngModelChange)=\"setGrouping($event)\"\n />\n }\n <div class=\"wm-sirio-grid-toolbar-actions\">\n @if (canAdd()) {\n <button wmSirioButton=\"secondary\" size=\"small\" type=\"button\" icon=\"fa-plus\" iconPosition=\"start\" (click)=\"addRow()\">\n {{ addLabel() }}\n </button>\n }\n @if (deletableSelected().length) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-trash\" iconPosition=\"start\" (click)=\"deleteSelected()\">\n {{ deleteSelectedLabel() }} ({{ deletableSelected().length }})\n </button>\n }\n @if (expandTools) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-angle-double-down\" iconPosition=\"start\" (click)=\"expandAll(true)\">\n {{ expandAllLabel() }}\n </button>\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-angle-double-up\" iconPosition=\"start\" (click)=\"expandAll(false)\">\n {{ collapseAllLabel() }}\n </button>\n }\n @if ((resizable() || reorderable()) && columnsCustomized()) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-undo\" iconPosition=\"start\" (click)=\"resetColumns()\">\n {{ resetColumnsLabel() }}\n </button>\n }\n </div>\n </div>\n}\n\n@if (filterColumns().length && cardMode() && filterButton() !== 'none') {\n <!-- Card layout: the header (and its filter buttons) is hidden by the kit, filters go here. -->\n <div class=\"wm-sirio-grid-filters-mobile\">\n <button\n wmSirioButton=\"secondary\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-filter\"\n iconPosition=\"start\"\n [attr.aria-expanded]=\"filtersOpen()\"\n [attr.aria-controls]=\"filtersOpen() ? baseId + '-filters' : null\"\n (click)=\"filtersOpen.set(!filtersOpen())\"\n >\n {{ filtersLabel() }}@if (filterChips().length) {&ngsp;({{ filterChips().length }})}\n </button>\n @if (filtersOpen()) {\n <div class=\"wm-sirio-grid-filters-panel\" role=\"group\" [id]=\"baseId + '-filters'\" [attr.aria-label]=\"filtersLabel()\">\n @for (column of filterColumns(); track column) {\n <ng-container *ngTemplateOutlet=\"filterControls; context: { $implicit: column, labelled: true }\" />\n }\n </div>\n }\n </div>\n}\n@if (showFilterChips() && !filterRowActive() && filterChips().length) {\n <div class=\"wm-sirio-grid-chips\">\n <wm-sirio-filter-chips [chips]=\"filterChips()\" [label]=\"filtersLabel()\" (removed)=\"onChipRemoved($event)\" />\n @if (filterChips().length > 1) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" (click)=\"clearFilters()\">{{ clearFiltersLabel() }}</button>\n }\n </div>\n}\n<div\n #scroller\n class=\"wm-sirio-grid-scroller\"\n [class.sirio-table-responsive]=\"responsive() && !cardMode()\"\n [class.sirio-table-overflow-start]=\"responsive() && !cardMode() && overflowStart()\"\n [class.sirio-table-overflow-end]=\"responsive() && !cardMode() && overflowEnd()\"\n [class.sirio-table-th-fixed]=\"stickyHeader() && !cardMode()\"\n [class.wm-sirio-grid-pinned-left]=\"hasPinLeft()\"\n [class.wm-sirio-grid-pinned-right]=\"hasPinRight()\"\n (scroll)=\"updateOverflow()\"\n (focusin)=\"navigation() && revealFocused($event)\"\n [style.--wm-grid-pin-left]=\"pinBlockWidths().left + 'px'\"\n [style.--wm-grid-pin-right]=\"pinBlockWidths().right + 'px'\"\n>\n <table\n #table\n class=\"sirio-table\"\n [class.sirio-table-dark]=\"variant() === 'dark'\"\n [class.sirio-table-light]=\"variant() === 'striped'\"\n [class.sirio-table-xs]=\"size() === 'xs'\"\n [class.sirio-table-sm]=\"size() === 'sm'\"\n [class.sirio-table-lg]=\"size() === 'lg'\"\n [class.sirio-table-card]=\"cardOnMobile()\"\n [class.wm-sirio-grid-card-active]=\"cardMode()\"\n [class.wm-sirio-grid-selectable]=\"selection() !== 'none'\"\n [class.wm-sirio-grid-fixed-layout]=\"fixedLayout()\"\n [class.wm-sirio-grid-grouped]=\"headerDepth() > 0\"\n [class.wm-sirio-grid-filter-hover]=\"filterButton() === 'hover'\"\n [style.width.px]=\"tableWidth()\"\n [attr.aria-busy]=\"isLoading() || null\"\n [attr.role]=\"gridRole()\"\n [attr.aria-multiselectable]=\"gridRole() && selection() === 'multiple' ? true : null\"\n >\n @if (caption()) {\n <caption [class.sr-only]=\"!captionVisible()\">{{ caption() }}</caption>\n }\n @if (fixedLayout()) {\n <!-- Fixed layout: the widths come from the columns (the first header row may be a group row). -->\n <colgroup>\n @if (checkColumn()) {\n <col [style.width.px]=\"toolColumnWidth\" />\n }\n @if (hasDetail()) {\n <col [style.width.px]=\"toolColumnWidth\" />\n }\n @if (rowNumbers()) {\n <col [style.width.px]=\"rowNumberWidth\" />\n }\n @for (column of visibleColumns(); track column) {\n <col [style.width.px]=\"widthOf(column)\" />\n }\n @if (actionsColumn()) {\n <col [style.width.px]=\"actionsWidth()\" />\n }\n </colgroup>\n }\n <thead>\n <!-- Grouped headers: a row per group level, then the column headers (rowspan below shorter group paths). -->\n @for (headerRow of headerRows(); track $index; let r = $index) {\n <tr>\n @if (r === 0) {\n @if (checkColumn()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\" [attr.rowspan]=\"headerRowspan()\">\n @if (selection() === 'multiple') {\n <div class=\"sirio-table-check\">\n <div class=\"sirio-form-check\">\n <input\n type=\"checkbox\"\n [id]=\"baseId + '-all'\"\n [checked]=\"allPageSelected()\"\n [indeterminate]=\"pageSelectedCount() > 0 && !allPageSelected()\"\n [disabled]=\"!selectableRows().length\"\n (change)=\"toggleAll($any($event.target).checked)\"\n />\n <label [attr.for]=\"baseId + '-all'\"><span class=\"sr-only\">{{ selectAllText() }}</span></label>\n </div>\n </div>\n } @else {\n <span class=\"sr-only\">{{ selectionHeaderLabel() }}</span>\n }\n </th>\n }\n @if (hasDetail()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\" [attr.rowspan]=\"headerRowspan()\"><span class=\"sr-only\">{{ expandRowLabel() }}</span></th>\n }\n @if (rowNumbers()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\" [attr.rowspan]=\"headerRowspan()\">\n <span aria-hidden=\"true\">{{ rowNumberHeader() }}</span><span class=\"sr-only\">{{ rowNumberLabel() }}</span>\n </th>\n }\n }\n @for (cell of headerRow; track cell.track) {\n @if (cell.kind === 'group') {\n <th\n scope=\"colgroup\"\n class=\"wm-sirio-grid-group-th\"\n [attr.colspan]=\"cell.colspan > 1 ? cell.colspan : null\"\n [wmSirioGridPin]=\"cell.pin\"\n [style.top.px]=\"headerTop(r)\"\n >\n {{ cell.label }}\n </th>\n } @else {\n @let column = cell.column;\n @let direction = directionOf(column);\n @let id = columnId(column);\n @let drop = dropTarget();\n <th\n scope=\"col\"\n [attr.data-column]=\"id\"\n [attr.rowspan]=\"cell.rowspan > 1 ? cell.rowspan : null\"\n [style.top.px]=\"headerTop(r)\"\n [wmSirioGridPin]=\"id\"\n [class]=\"'wm-sirio-grid-align-' + column.alignment() + ' ' + column.headerClassText()\"\n [style]=\"column.headerStyleObject()\"\n [class.sirio-sorting]=\"column.sortable()\"\n [class.sirio-sorting-asc]=\"direction === 'asc'\"\n [class.sirio-sorting-desc]=\"direction === 'desc'\"\n [class.wm-sirio-grid-th-resizable]=\"canResize(column)\"\n [class.wm-sirio-grid-fit]=\"column.fit()\"\n [class.wm-sirio-grid-th-draggable]=\"reorderable() && !cardMode()\"\n [class.wm-sirio-grid-th-dragging]=\"dragId() === id\"\n [class.wm-sirio-grid-drop-before]=\"drop?.id === id && drop?.side === 'before'\"\n [class.wm-sirio-grid-drop-after]=\"drop?.id === id && drop?.side === 'after'\"\n [style.width]=\"cssWidthOf(column)\"\n [style.min-width]=\"cssMinWidthOf(column)\"\n [attr.aria-sort]=\"ariaSortOf(column)\"\n [attr.aria-describedby]=\"headerHintId(column)\"\n [attr.tabindex]=\"headerFocusable(column) ? 0 : null\"\n [attr.draggable]=\"reorderable() && !cardMode() ? 'true' : null\"\n (click)=\"onHeaderClick(column, $event)\"\n (keydown)=\"onHeaderKey(column, $event)\"\n (dragstart)=\"onDragStart(column, $event)\"\n (dragover)=\"onDragOver(column, $event)\"\n (drop)=\"onDrop($event)\"\n (dragend)=\"onDragEnd()\"\n >\n <!-- One line: the title is cut with an ellipsis, sort index and filter button stay visible. -->\n <span class=\"wm-sirio-grid-th-inner\">\n <span class=\"wm-sirio-grid-th-label\" [attr.title]=\"column.header()\">\n @if (column.headerTemplate(); as header) {\n <ng-container *ngTemplateOutlet=\"header; context: { $implicit: column }\" />\n } @else {\n {{ column.header() }}\n }\n </span>\n @if (sortIndexOf(column); as sortIndex) {\n <span class=\"wm-sirio-grid-sort-index\" aria-hidden=\"true\">{{ sortIndex }}</span>\n }\n @if (column.filter() && !filterRowActive() && filterButton() !== 'none') {\n <ng-container *ngTemplateOutlet=\"filterBtnTpl; context: { $implicit: column }\" />\n }\n </span>\n @if (canResize(column)) {\n <!-- Mouse handle: from the keyboard the focused header resizes with Alt+arrows (as ag-grid). -->\n <span\n class=\"wm-sirio-grid-resizer\"\n aria-hidden=\"true\"\n draggable=\"false\"\n [attr.title]=\"resizeColumnLabel() + ' ' + column.header()\"\n (pointerdown)=\"onResizeStart(column, $event)\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (dragstart)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (dblclick)=\"resetColumnWidth(column)\"\n ></span>\n }\n </th>\n }\n }\n @if (r === 0 && actionsColumn()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [attr.rowspan]=\"headerRowspan()\">\n <span class=\"sr-only\">{{ actionsHeader() }}</span>\n </th>\n }\n </tr>\n }\n @if (filterRowActive()) {\n @let top = headerTop(headerRows().length);\n <!-- Filter row: cells of fields, not column headers (the body cells keep the titles as headers).\n th for the kit header styles; scope only for the checkers that require it on every th\n (the gridcell / cell role prevails, so the cells head nothing). -->\n <tr class=\"wm-sirio-grid-filter-row\">\n @if (checkColumn()) {\n <th class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\"></th>\n }\n @if (hasDetail()) {\n <th class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\"></th>\n }\n @if (rowNumbers()) {\n <th class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\"></th>\n }\n @for (column of visibleColumns(); track column) {\n <th [wmSirioGridPin]=\"columnId(column)\" [attr.data-filter-column]=\"columnId(column)\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\">\n @if (column.filter()) {\n <ng-container *ngTemplateOutlet=\"filterRowCell; context: { $implicit: column }\" />\n }\n </th>\n }\n @if (actionsColumn()) {\n <th class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\"></th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @if (isLoading() && !renderedRows().length) {\n <tr class=\"wm-sirio-grid-message\">\n <td [attr.colspan]=\"colCount()\">\n <!-- The pending status region announces the text: the visible copy is hidden from AT. -->\n <wm-sirio-pending placement=\"inline\" [active]=\"true\" [label]=\"loadingText()\" />\n <span aria-hidden=\"true\">{{ loadingText() }}</span>\n </td>\n </tr>\n } @else if (errorContext(); as failure) {\n <!-- Failed server data source: message and \"Riprova\" (or the wmSirioGridError template). -->\n <tr class=\"wm-sirio-grid-message wm-sirio-grid-error\">\n <td [attr.colspan]=\"colCount()\" role=\"alert\">\n @if (errorTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: failure\" />\n } @else if (loadErrorText()) {\n <span class=\"fas fa-exclamation-triangle sirio-text-danger\" aria-hidden=\"true\"></span>&ngsp;{{ loadErrorText() }}&ngsp;\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-redo\" iconPosition=\"start\" (click)=\"reload()\">\n {{ retryLabel() }}\n </button>\n }\n </td>\n </tr>\n } @else {\n @for (row of renderedRows(); track row.id; let i = $index) {\n @if (row.getIsGrouped()) {\n <!-- Group row: toggle + value + count in the grouped column, aggregates in the others. -->\n @let groupColumn = groupColumnOf(row);\n <tr class=\"wm-sirio-grid-group-row\" [attr.aria-level]=\"gridRole() === 'treegrid' ? row.depth + 1 : null\">\n @if (checkColumn()) {\n <td class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\"></td>\n }\n @if (hasDetail()) {\n <td class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\"></td>\n }\n @if (rowNumbers()) {\n <td class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\"></td>\n }\n @for (column of visibleColumns(); track column) {\n <td\n [class]=\"'wm-sirio-grid-align-' + column.alignment()\"\n [class.font-mono]=\"column !== groupColumn && !!column.aggregate()\"\n [attr.data-label]=\"column.header()\"\n [wmSirioGridPin]=\"columnId(column)\"\n >\n @if (column === groupColumn) {\n @let groupText = column.formatValue(row.groupingValue);\n <span class=\"wm-sirio-grid-cell-inner\" [style.padding-inline-start.px]=\"indentOf(row)\">\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: column.header() + ' ' + groupText }\" />\n <strong>{{ groupText }}</strong>&ngsp;<span class=\"wm-sirio-grid-group-count font-mono\">({{ row.getLeafRows().length }})</span>\n </span>\n } @else if (column.aggregate()) {\n {{ aggregateText(column, row) }}\n }\n </td>\n }\n @if (actionsColumn()) {\n <td class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\"></td>\n }\n </tr>\n } @else {\n @let item = row.original;\n @let selected = isSelected(item);\n @let selectable = canSelect(item);\n @let look = rowLook(item, i);\n <tr\n [class]=\"look.cls\"\n [style]=\"look.style\"\n [class.wm-sirio-grid-row-selected]=\"selected\"\n [class.wm-sirio-grid-row-clickable]=\"clickSelect() && selectable\"\n [attr.tabindex]=\"keySelect() && selectable && !navigation() ? 0 : null\"\n [attr.aria-describedby]=\"keySelect() && selectable ? baseId + '-hint-select' : null\"\n [attr.aria-disabled]=\"selection() !== 'none' && !selectable ? 'true' : null\"\n [class.wm-sirio-grid-row-child]=\"row.depth > 0\"\n [attr.aria-selected]=\"selection() === 'none' ? null : selected\"\n [attr.aria-level]=\"gridRole() === 'treegrid' ? row.depth + 1 : null\"\n [class.wm-sirio-grid-row-invalid]=\"formMode() && rowInvalid(item)\"\n (click)=\"onRowActivate(row, i, $event)\"\n (dblclick)=\"onRowDoubleClick(row, $event)\"\n (keydown)=\"onRowKey(row, i, $event)\"\n >\n @if (checkColumn()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\">\n @if (selectable || !hideUnselectable()) {\n <div class=\"sirio-table-check\">\n <div class=\"sirio-form-check\">\n <input\n [type]=\"singleRadio() ? 'radio' : 'checkbox'\"\n [id]=\"baseId + '-row-' + i\"\n [attr.name]=\"singleRadio() ? baseId + '-row' : null\"\n [checked]=\"selected\"\n [disabled]=\"!selectable\"\n (change)=\"toggleRow(item, $any($event.target).checked)\"\n />\n <label [attr.for]=\"baseId + '-row-' + i\"><span class=\"sr-only\">{{ selectRowLabel()(item, i) }}</span></label>\n </div>\n </div>\n }\n </td>\n }\n @if (hasDetail()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\">\n @if (row.getCanExpand() && !row.subRows.length) {\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: rowName()(item, i) }\" />\n }\n </td>\n }\n @if (rowNumbers()) {\n <!-- Row header for screen readers; a td keeps the kit cell look (stripes, card layout). -->\n <td role=\"rowheader\" class=\"w-0 wm-sirio-grid-rownum-col font-mono\" wmSirioGridPin=\"__rownum\" [attr.data-label]=\"rowNumberLabel()\">{{ rowNumberOf(row) }}</td>\n }\n @for (column of visibleColumns(); track column) {\n @let cell = cellLook(column, item);\n <td\n [class]=\"cell.cls\"\n [style]=\"cell.style\"\n [class.font-mono]=\"column.isMono(item)\"\n [class.wm-sirio-grid-nowrap]=\"!column.wrap()\"\n [class.wm-sirio-grid-fit]=\"column.fit()\"\n [attr.data-label]=\"column.header()\"\n [wmSirioGridPin]=\"columnId(column)\"\n >\n @if (column === firstColumn() && (treeMode() || row.depth > 0)) {\n <span class=\"wm-sirio-grid-cell-inner\" [style.padding-inline-start.px]=\"indentOf(row)\">\n @if (treeMode()) {\n @if (row.subRows.length) {\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: column.textOf(item) }\" />\n } @else {\n <span class=\"wm-sirio-grid-toggle-spacer\" aria-hidden=\"true\"></span>\n }\n }\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: column, item: item, i: i }\" />\n </span>\n } @else {\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: column, item: item, i: i }\" />\n }\n </td>\n }\n @if (actionsColumn()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [attr.data-label]=\"actionsHeader()\">\n <span class=\"wm-sirio-grid-actions\">\n @if (rowInvalid(item)) {\n <span class=\"wm-sirio-grid-invalid\" [attr.title]=\"invalidRowLabel()\">\n <span class=\"fas fa-exclamation-circle sirio-text-danger\" aria-hidden=\"true\"></span>\n <span class=\"sr-only\">{{ invalidRowLabel() }}</span>\n </span>\n }\n @if (editorTemplate()) {\n @let editable = canEdit(item);\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n iconOnly\n [icon]=\"editable ? 'fa-pen' : 'fa-eye'\"\n [white]=\"variant() === 'dark'\"\n [label]=\"actionLabel(editable ? editLabel() : viewLabel(), item, i)\"\n (click)=\"editRow(item)\"\n ></button>\n }\n @if (canDelete(item)) {\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-trash\"\n iconOnly\n [white]=\"variant() === 'dark'\"\n [label]=\"actionLabel(deleteLabel(), item, i)\"\n (click)=\"deleteRow(item)\"\n ></button>\n }\n </span>\n </td>\n }\n </tr>\n @if (hasDetail() && row.getIsExpanded() && !row.subRows.length) {\n <tr class=\"wm-sirio-grid-detail-row\">\n <td [attr.colspan]=\"colCount()\">\n <ng-container *ngTemplateOutlet=\"detailTemplate()!; context: { $implicit: item, row: item }\" />\n </td>\n </tr>\n }\n }\n } @empty {\n <tr class=\"wm-sirio-grid-message\">\n <td [attr.colspan]=\"colCount()\">\n @if (emptyTemplate(); as empty) {\n <ng-container *ngTemplateOutlet=\"empty\" />\n } @else {\n {{ emptyText() }}\n }\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n@if (formError(); as error) {\n <span class=\"sirio-form-feedback sirio-visible sirio-feedback-invalid wm-sirio-grid-form-error\" role=\"alert\">{{ error }}</span>\n}\n@if (pageable() && total() > 0) {\n <wm-sirio-pagination\n [total]=\"total()\"\n [hasMore]=\"totalOpen()\"\n [moreLabel]=\"moreLabel()\"\n [(page)]=\"page\"\n [(pageSize)]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [variant]=\"paginationVariant()\"\n [siblings]=\"paginationSiblings()\"\n [showItems]=\"paginationShowItems()\"\n [ariaLabel]=\"paginationName()\"\n (paged)=\"onPaged()\"\n />\n}\n\n<ng-template #cellContent let-column let-item=\"item\" let-i=\"i\">\n @if (column.cellTemplate(); as cell) {\n <ng-container *ngTemplateOutlet=\"cell; context: { $implicit: item, row: item, value: column.valueOf(item), index: i }\" />\n } @else {\n {{ column.textOf(item) }}\n }\n</ng-template>\n\n@if (formMode() && editorTemplate(); as editor) {\n <!-- Edit dialog of a form array row: the form of wmSirioGridEditor bound to a copy of the row. -->\n <wm-sirio-dialog\n [(open)]=\"editorOpen\"\n [title]=\"editorTitle()\"\n [icon]=\"null\"\n [size]=\"editorSize()\"\n [closeLabel]=\"closeLabel()\"\n [closeOnBackdrop]=\"false\"\n (opened)=\"onEditorOpened()\"\n (closed)=\"onEditorClosed()\"\n >\n @if (editing(); as session) {\n @if (saveError(); as error) {\n <wm-sirio-alert type=\"error\" class=\"wm-sirio-grid-save-error\" [title]=\"saveErrorTitle()\" [dismissible]=\"false\">{{ error }}</wm-sirio-alert>\n }\n <div class=\"wm-sirio-grid-editor\" [id]=\"baseId + '-editor'\">\n <ng-container *ngTemplateOutlet=\"editor; context: session.context\" />\n </div>\n }\n <div wmSirioDialogFooter>\n @if (editing()?.context?.readonly) {\n <button wmSirioButton=\"primary\" type=\"button\" (click)=\"closeEditor()\">{{ closeLabel() }}</button>\n } @else {\n <button wmSirioButton=\"secondary\" type=\"button\" [disabled]=\"saving()\" (click)=\"closeEditor()\">{{ cancelLabel() }}</button>\n <button wmSirioButton=\"primary\" type=\"button\" [disabled]=\"saving()\" [attr.aria-busy]=\"saving() || null\" (click)=\"saveEditor()\">\n @if (saving()) {\n <wm-sirio-pending placement=\"inline\" [active]=\"true\" [label]=\"saveLabel()\" />\n }\n {{ saveLabel() }}\n </button>\n }\n </div>\n </wm-sirio-dialog>\n}\n\n<span class=\"sr-only\" [id]=\"baseId + '-hint-sort'\">{{ multiSortHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-select'\">{{ selectRowHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-reorder'\">{{ reorderHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-resize'\">{{ resizeHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-filter'\">{{ filterHint() }}</span>\n<span class=\"sr-only\" role=\"status\">{{ status() }}</span>\n<span class=\"sr-only\" aria-live=\"polite\">{{ announcement() }}</span>\n",
|
|
14088
14120
|
styles: [
|
|
14089
14121
|
":host{display:block}:host(.wm-sirio-grid-sized){display:flex;flex-direction:column;min-height:10rem}:host(.wm-sirio-grid-sized)>*{flex:none}:host(.wm-sirio-grid-sized)>.wm-sirio-grid-scroller{flex:1 1 auto;max-height:none;min-height:0;overflow-y:auto}:host(.wm-sirio-grid-sized)>.wm-sirio-grid-scroller>table{align-self:flex-start}.wm-sirio-grid-scroller:not(.sirio-table-responsive){display:block}.sirio-table-th-fixed .sirio-table,.sirio-table-column-fixed-first .sirio-table,.sirio-table-action-fixed .sirio-table{margin-bottom:0}.wm-sirio-grid-align-start{text-align:start}.wm-sirio-grid-align-center{text-align:center}.wm-sirio-grid-align-end{text-align:end}th.sirio-sorting:focus:not(:focus-visible){outline:none}th.sirio-sorting{-webkit-user-select:none;user-select:none}th.sirio-sorting:before{content:none}th.sirio-sorting-asc:after{background-position:50% calc(50% + 4px)}th.sirio-sorting-desc:after{background-position:50% calc(50% - 4px)}.wm-sirio-grid-check-col .sirio-table-check{justify-content:center}.wm-sirio-grid-check-col .sirio-form-check label{min-height:24px;margin-bottom:0;padding-left:0}table.sirio-table tr.wm-sirio-grid-row-bg:nth-child(n)>td{background-color:var(--wm-grid-row-bg)!important}table.sirio-table tr.wm-sirio-grid-row-selected:nth-child(n)>td{background-color:#e8effa!important}table.sirio-table tr:nth-child(n)>td.wm-sirio-grid-cell-bg{background-color:var(--wm-grid-cell-bg)!important}tr.wm-sirio-grid-row-selected>td:first-child{--wm-grid-bar: inset 4px 0 0 0 #2f6dd5}tr.wm-sirio-grid-row-invalid>td:first-child{--wm-grid-bar: inset 4px 0 0 0 #aa224f}.wm-sirio-grid-actions{align-items:center;display:inline-flex;gap:4px;white-space:nowrap}.wm-sirio-grid-actions .sirio-btn+.sirio-btn{margin-left:0}.wm-sirio-grid-form-error{margin:8px 0 0}.wm-sirio-grid-save-error{display:block;margin-bottom:24px}tr:is(.wm-sirio-grid-row-selected,.wm-sirio-grid-row-invalid)>td:first-child:not(.wm-sirio-grid-pin){box-shadow:var(--wm-grid-bar)}tr.wm-sirio-grid-row-clickable{cursor:pointer}tr.wm-sirio-grid-row-clickable:focus-visible{outline:2px solid #2f6dd5;outline-offset:-2px}tr.wm-sirio-grid-row-clickable:hover>td{background-color:#f2f6fc}tr.wm-sirio-grid-message>td{color:#5b6571;text-align:center}tr.wm-sirio-grid-message wm-sirio-pending{margin-right:8px;vertical-align:middle}tbody{isolation:isolate}table[aria-busy=true] tbody>tr:not(.wm-sirio-grid-message){opacity:.6;transition:opacity .15s}.sirio-table-card tr.wm-sirio-grid-message>td:before{content:none!important}.sirio-table-card td.wm-sirio-grid-check-col{justify-content:flex-start}.sirio-table-card tr.wm-sirio-grid-row-selected{border-color:#2f6dd5}.sirio-table-card tr.wm-sirio-grid-row-selected>td:first-child{box-shadow:none}caption:not(.sr-only){caption-side:top;color:#454d56;font-weight:600;padding:0 0 8px;text-align:start}.wm-sirio-grid-toolbar{align-items:flex-end;display:flex;flex-wrap:wrap;gap:8px 24px;margin-bottom:16px}.wm-sirio-grid-groupby{display:block;flex:0 1 320px;min-width:220px}.wm-sirio-grid-groupby ::ng-deep wm-sirio-field{margin-bottom:0}.wm-sirio-grid-toolbar-actions{display:flex;flex-wrap:wrap;gap:8px;margin-inline-start:auto}.wm-sirio-grid-sort-index{background-color:#2f6dd5;border-radius:10px;color:#fff;display:inline-block;font-size:12px;font-weight:600;line-height:18px;margin-inline-start:4px;min-width:18px;text-align:center;vertical-align:middle}.sirio-table-dark .wm-sirio-grid-sort-index{background-color:#18cee7;color:#002460}th.wm-sirio-grid-th-resizable{position:relative}.sirio-table-th-fixed thead th.wm-sirio-grid-th-resizable,.sirio-table-responsive thead th.wm-sirio-grid-th-resizable{position:sticky}.wm-sirio-grid-resizer{bottom:0;cursor:col-resize;inset-inline-end:0;position:absolute;top:0;touch-action:none;width:8px;z-index:2}.wm-sirio-grid-resizer:after{background-color:#aec6ef;bottom:8px;content:\"\";inset-inline-start:3px;position:absolute;top:8px;width:2px}.wm-sirio-grid-resizer:hover:after,.wm-sirio-grid-resizer:focus-visible:after{background-color:#2f6dd5}.wm-sirio-grid-resizer:focus-visible{outline:2px solid #2f6dd5;outline-offset:-2px}td.wm-sirio-grid-nowrap{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}table.wm-sirio-grid-fixed-layout{table-layout:fixed}table.wm-sirio-grid-fixed-layout th,table.wm-sirio-grid-fixed-layout td{overflow:hidden;text-overflow:ellipsis}table.wm-sirio-grid-fixed-layout .wm-sirio-grid-check-col,table.wm-sirio-grid-fixed-layout .wm-sirio-grid-expand-col{width:48px}th.wm-sirio-grid-th-draggable{cursor:grab}th.wm-sirio-grid-th-draggable.sirio-sorting{cursor:pointer}th.wm-sirio-grid-th-dragging{opacity:.5}th.wm-sirio-grid-drop-before{box-shadow:inset 4px 0 #2f6dd5}th.wm-sirio-grid-drop-after{box-shadow:inset -4px 0 #2f6dd5}th.wm-sirio-grid-th-draggable:focus-visible{outline:2px solid #2f6dd5;outline-offset:-3px}.wm-sirio-grid-cell-inner{align-items:center;display:inline-flex;gap:4px}.wm-sirio-grid-toggle{align-items:center;background:transparent;border:0;border-radius:4px;color:#2f6dd5;cursor:pointer;display:inline-flex;flex:0 0 auto;height:28px;justify-content:center;padding:0;width:28px}.wm-sirio-grid-toggle:hover{background-color:#d9e4f7}.wm-sirio-grid-toggle:focus-visible{outline:2px solid #2f6dd5;outline-offset:0}.wm-sirio-grid-toggle-spacer{display:inline-block;flex:0 0 auto;width:28px}.wm-sirio-grid-expand-col{text-align:center}tr.wm-sirio-grid-group-row>td{background-color:#f2f6fc;font-weight:600}.wm-sirio-grid-group-count{color:#5b6571;font-weight:400}tr.wm-sirio-grid-detail-row>td{background-color:#f2f6fc;box-shadow:inset 4px 0 #2f6dd5;padding:16px 24px}.wm-sirio-grid-card-active tr.wm-sirio-grid-detail-row>td:before,.wm-sirio-grid-card-active tr.wm-sirio-grid-group-row>td:empty{display:none}th.wm-sirio-grid-group-th{text-align:center}.sirio-table-th-fixed .wm-sirio-grid-grouped th:not(.wm-sirio-grid-pin-edge-left,.wm-sirio-grid-pin-edge-right){box-shadow:inset -1px -1px #aec6ef}.sirio-table-th-fixed .wm-sirio-grid-grouped.sirio-table-dark th:not(.wm-sirio-grid-pin-edge-left,.wm-sirio-grid-pin-edge-right){box-shadow:inset -1px -1px #2f6dd5}.wm-sirio-grid-rownum-col{color:#5b6571;font-variant-numeric:tabular-nums;text-align:end;white-space:nowrap}table.wm-sirio-grid-fixed-layout .wm-sirio-grid-rownum-col{width:64px}.sirio-table-responsive .wm-sirio-grid-pin{position:sticky}th.wm-sirio-grid-pin{z-index:11}td.wm-sirio-grid-pin{background-color:#fff}td.wm-sirio-grid-pin-l{border-right-style:hidden;box-shadow:var(--wm-grid-bar, 0 0 rgba(0, 0, 0, 0)),inset -1px 0 #d9e4f7}td.wm-sirio-grid-pin-r{border-left-style:hidden;box-shadow:inset 1px 0 #d9e4f7}.wm-sirio-grid-pin-edge-left{box-shadow:inset -1px 0 #d9e4f7}.wm-sirio-grid-pin-edge-right{box-shadow:inset 1px 0 #d9e4f7}.sirio-table-th-fixed thead th.wm-sirio-grid-pin-edge-left{box-shadow:inset 1px 1px #d9e4f7,inset -1px 0 #d9e4f7}.sirio-table-th-fixed thead th.wm-sirio-grid-pin-edge-left:first-child{box-shadow:inset 0 1px #d9e4f7,inset -1px 0 #d9e4f7}.sirio-table-th-fixed thead th.wm-sirio-grid-pin-edge-right{box-shadow:inset 1px 1px #d9e4f7}.sirio-table.sirio-table-dark th.wm-sirio-grid-pin-l{border-right-style:hidden!important;box-shadow:inset -1px 0 #2f6dd5}.sirio-table.sirio-table-dark th.wm-sirio-grid-pin-r{border-left-style:hidden;box-shadow:inset 1px 0 #2f6dd5}.sirio-table-th-fixed .sirio-table.sirio-table-dark thead th{border-right-width:0!important;border-bottom-width:0!important;box-shadow:inset -1px -1px #2f6dd5}.sirio-table-th-fixed .sirio-table.sirio-table-dark thead th:last-child{box-shadow:inset 0 -1px #2f6dd5}.sirio-table-th-fixed .sirio-table.sirio-table-dark thead th.wm-sirio-grid-pin-edge-right{box-shadow:inset 1px 0 #2f6dd5,inset -1px -1px #2f6dd5}.sirio-table-th-fixed .sirio-table.sirio-table-dark thead th.wm-sirio-grid-pin-edge-right:last-child{box-shadow:inset 1px 0 #2f6dd5,inset 0 -1px #2f6dd5}.sirio-table-responsive.sirio-table-overflow-start:before{left:var(--wm-grid-pin-left, 0);margin-right:-4px;z-index:12}.sirio-table-responsive.sirio-table-overflow-end:after{right:var(--wm-grid-pin-right, 0);margin-left:-4px;z-index:12}@media(min-width:768px){.sirio-table-responsive.sirio-table-overflow-start:before{margin-right:-8px}.sirio-table-responsive.sirio-table-overflow-end:after{margin-left:-8px}}.sirio-table-responsive{border:1px solid #d9e4f7;border-top:none;border-radius:4px}.sirio-table tr>:last-child{border-right-style:hidden!important}.sirio-table tr>:first-child{border-left-style:hidden!important}.wm-sirio-grid-th-inner{display:flex;align-items:center;gap:4px}.wm-sirio-grid-align-end>.wm-sirio-grid-th-inner{flex-direction:row-reverse}.wm-sirio-grid-align-center>.wm-sirio-grid-th-inner{justify-content:center}.wm-sirio-grid-th-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n",
|
|
14090
14122
|
".wm-sirio-grid-filter-btn{flex:none;margin-inline-start:auto}.wm-sirio-grid-filter-hover th:not(:hover):not(:focus-within)>.wm-sirio-grid-th-inner>.wm-sirio-grid-filter-btn:not(.wm-sirio-grid-filter-active){opacity:0}.wm-sirio-grid-filter-btn.wm-sirio-grid-filter-active{background-color:#2f6dd5;border-color:#2f6dd5;color:#fff}.sirio-table-dark .wm-sirio-grid-filter-btn.wm-sirio-grid-filter-active{background-color:#18cee7;border-color:#18cee7;color:#002460}.wm-sirio-grid-filter-panel{padding-top:8px;width:224px}:is(.wm-sirio-grid-filter-panel,.wm-sirio-grid-filters-panel) ::ng-deep .sirio-dropdown-select>span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:is(.wm-sirio-grid-filter-panel,.wm-sirio-grid-filters-panel) :is(wm-sirio-textbox,wm-sirio-select,wm-sirio-number,wm-sirio-date){display:block}.wm-sirio-grid-filter-panel ::ng-deep wm-sirio-field{margin-bottom:12px}.wm-sirio-grid-filter-panel ::ng-deep .sirio-label{color:#fff}.wm-sirio-grid-filter-range{border:0;margin:0;min-width:0;padding:0}.wm-sirio-grid-filter-range>legend{font-size:inherit;float:none;width:auto}.wm-sirio-grid-filters-mobile{margin-bottom:16px}.wm-sirio-grid-filters-panel{border:1px solid #d9e4f7;margin-top:12px;padding:16px 16px 0}.wm-sirio-grid-chips{align-items:center;display:flex;flex-wrap:wrap;gap:8px 16px;margin-bottom:16px}tr.wm-sirio-grid-filter-row>th{padding:4px 6px;background:#eef3fb}.sirio-table-dark tr.wm-sirio-grid-filter-row>th{background:#00368f}.wm-sirio-grid-filter-inline{display:flex;align-items:center}.wm-sirio-grid-filter-inline>:not(button){flex:1;min-width:0}.wm-sirio-grid-filter-inline ::ng-deep wm-sirio-field{margin-bottom:0}.wm-sirio-grid-filter-inline ::ng-deep .sirio-form-control{height:32px;padding-block:0;font-size:14px}.wm-sirio-grid-filter-inline ::ng-deep input{padding-inline:6px}.wm-sirio-grid-filter-inline ::ng-deep input::-webkit-search-cancel-button{display:none}.wm-sirio-grid-filter-summary{overflow:hidden;padding:0 8px;border:1px solid #aec6ef;background:#f2f6fc;color:#00173d;font-size:14px;line-height:30px;text-overflow:ellipsis;white-space:nowrap}.wm-sirio-grid-filter-clear.sirio-btn{background-color:#18cee7;border-color:#18cee7;color:#001c4a}.wm-sirio-grid-filter-clear.sirio-btn:hover{background-color:#8ce7f3;border-color:#8ce7f3;color:#001c4a}.wm-sirio-grid-filter-clear.sirio-btn:not(:disabled):active{background-color:#0f7d8a;border-color:#0f7d8a;color:#fff}.wm-sirio-grid-filter-clear.sirio-btn:disabled{background-color:transparent;border-color:#fff6;color:#fff9}.wm-sirio-grid-filter-clear.sirio-btn:focus-visible{outline-color:#fff!important}\n",
|
|
@@ -14232,6 +14264,8 @@ var SirioDataGrid = class SirioDataGrid {
|
|
|
14232
14264
|
"padDecimals",
|
|
14233
14265
|
"grouping",
|
|
14234
14266
|
"showSpinner",
|
|
14267
|
+
"incrementLabel",
|
|
14268
|
+
"decrementLabel",
|
|
14235
14269
|
"step"
|
|
14236
14270
|
]
|
|
14237
14271
|
},
|
|
@@ -14358,7 +14392,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
14358
14392
|
"[style.max-height]": "maxHeight()"
|
|
14359
14393
|
},
|
|
14360
14394
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
14361
|
-
template: "<!-- Controls of a column filter: in the header popover (labelled = false) or in the card panel. -->\n<ng-template #filterControls let-column let-labelled=\"labelled\">\n @if (operatorsOf(column).length) {\n <ng-container *ngTemplateOutlet=\"conditionControls; context: { $implicit: column, labelled: labelled }\" />\n } @else {\n @switch (column.filter()) {\n @case ('number') {\n <ng-container *ngTemplateOutlet=\"range; context: { $implicit: column, labelled: labelled, date: false }\" />\n }\n @case ('date') {\n <ng-container *ngTemplateOutlet=\"range; context: { $implicit: column, labelled: labelled, date: true }\" />\n }\n @case ('select') {\n <!-- Without filterOptions: the values present in the column (TanStack faceted values). -->\n <wm-sirio-select\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [options]=\"filterOptionsOf(column)\"\n [multiple]=\"column.filterMultiple()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column)\"\n (ngModelChange)=\"setFilter(column, $event)\"\n />\n }\n @case ('boolean') {\n <wm-sirio-select\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [options]=\"booleanOptions()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column)\"\n (ngModelChange)=\"setFilter(column, $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [placeholder]=\"column.filterPlaceholder()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column) ?? ''\"\n (ngModelChange)=\"setFilter(column, $event, false)\"\n />\n }\n }\n }\n</ng-template>\n\n<!-- Filter with operators: \"Condizione\" choice, then the value (two bounds for \"Compreso tra\", none for \"Vuoto\"). -->\n<ng-template #conditionControls let-column let-labelled=\"labelled\">\n @let condition = conditionOf(column);\n @let op = condition.operator;\n <fieldset class=\"wm-sirio-grid-filter-range\">\n <legend [class.sr-only]=\"!labelled\" class=\"sirio-label\">{{ column.header() }}</legend>\n <wm-sirio-select\n [label]=\"filterConditionLabel()\"\n [options]=\"operatorOptions(column)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"op\"\n (ngModelChange)=\"setOperator(column, $event)\"\n />\n @if (op !== 'blank' && op !== 'notBlank') {\n @switch (column.filter()) {\n @case ('number') {\n <wm-sirio-number\n [label]=\"op === 'between' ? filterFromLabel() : filterValueLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n @if (op === 'between') {\n <wm-sirio-number [label]=\"filterToLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"condition.to ?? null\" (ngModelChange)=\"setConditionPart(column, 'to', $event)\" />\n }\n }\n @case ('date') {\n <wm-sirio-date\n [label]=\"op === 'between' ? filterFromLabel() : filterValueLabel()\"\n [max]=\"op === 'between' ? ($any(condition.to) ?? null) : null\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n @if (op === 'between') {\n <wm-sirio-date\n [label]=\"filterToLabel()\"\n [min]=\"$any(condition.value) ?? null\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.to ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'to', $event)\"\n />\n }\n }\n @case ('select') {\n <wm-sirio-select\n [label]=\"filterValueLabel()\"\n [options]=\"filterOptionsOf(column)\"\n [multiple]=\"column.filterMultiple()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n }\n @case ('boolean') {\n <wm-sirio-select\n [label]=\"filterValueLabel()\"\n [options]=\"booleanOptions()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [label]=\"filterValueLabel()\"\n [placeholder]=\"column.filterPlaceholder()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? ''\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event, false)\"\n />\n }\n }\n }\n </fieldset>\n</ng-template>\n\n<!-- Range filter (number / date): \"Da\" and \"A\", grouped by the column header in the card panel. -->\n<ng-template #range let-column let-labelled=\"labelled\" let-date=\"date\">\n @let value = rangeOf(column);\n <fieldset class=\"wm-sirio-grid-filter-range\">\n <legend [class.sr-only]=\"!labelled\" class=\"sirio-label\">{{ column.header() }}</legend>\n @if (date) {\n <wm-sirio-date [label]=\"filterFromLabel()\" [max]=\"$any(value.to) ?? null\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.from ?? null\" (ngModelChange)=\"setRange(column, 'from', $event)\" />\n <wm-sirio-date [label]=\"filterToLabel()\" [min]=\"$any(value.from) ?? null\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.to ?? null\" (ngModelChange)=\"setRange(column, 'to', $event)\" />\n } @else {\n <wm-sirio-number [label]=\"filterFromLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.from ?? null\" (ngModelChange)=\"setRange(column, 'from', $event)\" />\n <wm-sirio-number [label]=\"filterToLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.to ?? null\" (ngModelChange)=\"setRange(column, 'to', $event)\" />\n }\n </fieldset>\n</ng-template>\n\n<!-- Filter button of a column with its popover (in the header, or in the filter row with `filterRow`). -->\n<ng-template #filterBtnTpl let-column let-inRow=\"inRow\">\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-filter\"\n iconOnly\n class=\"wm-sirio-grid-filter-btn\"\n draggable=\"false\"\n [class.wm-sirio-grid-filter-active]=\"isFiltered(column)\"\n [white]=\"variant() === 'dark'\"\n [label]=\"filterButtonLabel(column, inRow)\"\n [wmSirioPopover]=\"filterPanel\"\n [popoverTitle]=\"filterLabel() + ' ' + column.header()\"\n popoverPlacement=\"bottom-end\"\n (opened)=\"focusFilter(column)\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n <ng-template #filterPanel>\n <div class=\"wm-sirio-grid-filter-panel\" [id]=\"baseId + '-filter-' + filterIndex(column)\">\n <ng-container *ngTemplateOutlet=\"filterControls; context: { $implicit: column, labelled: false }\" />\n <button wmSirioButton=\"tertiary-light\" size=\"small\" type=\"button\" class=\"wm-sirio-grid-filter-clear\" [disabled]=\"!isFiltered(column)\" (click)=\"clearFilter(column)\">\n {{ clearFilterLabel() }}\n </button>\n </div>\n </ng-template>\n</ng-template>\n\n<!-- Cell of the filter row: the simple condition in a field, the others as a summary (the button opens the popover). -->\n<ng-template #filterRowCell let-column>\n @let inline = inlineFilterOf(column);\n @let aria = filterLabel() + ' ' + column.header();\n <div class=\"wm-sirio-grid-filter-inline\" (keydown.escape)=\"clearFilter(column)\">\n @switch (inline.kind) {\n @case ('summary') {\n <span class=\"wm-sirio-grid-filter-summary\" [attr.title]=\"inline.summary\">{{ inline.summary }}</span>\n }\n @case ('number') {\n <wm-sirio-number [ariaLabel]=\"aria\" [placeholder]=\"inline.placeholder\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"inline.value\" (ngModelChange)=\"setInlineFilter(column, $event)\" />\n }\n @case ('date') {\n <wm-sirio-date [ariaLabel]=\"aria\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"inline.value\" (ngModelChange)=\"setInlineFilter(column, $event)\" />\n }\n @case ('select') {\n <wm-sirio-select\n [ariaLabel]=\"aria\"\n [options]=\"column.filter() === 'boolean' ? booleanOptions() : filterOptionsOf(column)\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"inline.value\"\n (ngModelChange)=\"setInlineFilter(column, $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [ariaLabel]=\"aria\"\n [placeholder]=\"inline.placeholder\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"inline.value ?? ''\"\n (ngModelChange)=\"setInlineFilter(column, $event, false)\"\n />\n }\n }\n <ng-container *ngTemplateOutlet=\"filterBtnTpl; context: { $implicit: column, inRow: true }\" />\n </div>\n</ng-template>\n\n<!-- Expand / collapse button of a row (tree rows, groups, detail rows). -->\n<ng-template #toggle let-row let-text=\"text\">\n <button\n type=\"button\"\n class=\"wm-sirio-grid-toggle\"\n [attr.aria-expanded]=\"row.getIsExpanded()\"\n [attr.aria-label]=\"expandLabel(row, text)\"\n [attr.title]=\"expandLabel(row, text)\"\n (click)=\"row.toggleExpanded()\"\n >\n <span [class]=\"row.getIsExpanded() ? 'fas fa-chevron-down' : 'fas fa-chevron-right'\" aria-hidden=\"true\"></span>\n </button>\n</ng-template>\n\n@let groups = groupableColumns().length > 0 && !server();\n@let expandTools = activeGrouping().length > 0 || treeMode() || hasDetail();\n@let formTools = canAdd() || deletableSelected().length > 0;\n@if (groups || expandTools || formTools || ((resizable() || reorderable()) && columnsCustomized())) {\n <div class=\"wm-sirio-grid-toolbar\">\n @if (groups) {\n <wm-sirio-select\n class=\"wm-sirio-grid-groupby\"\n [label]=\"groupByLabel()\"\n [options]=\"groupOptions()\"\n multiple\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"grouping()\"\n (ngModelChange)=\"setGrouping($event)\"\n />\n }\n <div class=\"wm-sirio-grid-toolbar-actions\">\n @if (canAdd()) {\n <button wmSirioButton=\"secondary\" size=\"small\" type=\"button\" icon=\"fa-plus\" iconPosition=\"start\" (click)=\"addRow()\">\n {{ addLabel() }}\n </button>\n }\n @if (deletableSelected().length) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-trash\" iconPosition=\"start\" (click)=\"deleteSelected()\">\n {{ deleteSelectedLabel() }} ({{ deletableSelected().length }})\n </button>\n }\n @if (expandTools) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-angle-double-down\" iconPosition=\"start\" (click)=\"expandAll(true)\">\n {{ expandAllLabel() }}\n </button>\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-angle-double-up\" iconPosition=\"start\" (click)=\"expandAll(false)\">\n {{ collapseAllLabel() }}\n </button>\n }\n @if ((resizable() || reorderable()) && columnsCustomized()) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-undo\" iconPosition=\"start\" (click)=\"resetColumns()\">\n {{ resetColumnsLabel() }}\n </button>\n }\n </div>\n </div>\n}\n\n@if (filterColumns().length && cardMode() && filterButton() !== 'none') {\n <!-- Card layout: the header (and its filter buttons) is hidden by the kit, filters go here. -->\n <div class=\"wm-sirio-grid-filters-mobile\">\n <button\n wmSirioButton=\"secondary\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-filter\"\n iconPosition=\"start\"\n [attr.aria-expanded]=\"filtersOpen()\"\n [attr.aria-controls]=\"filtersOpen() ? baseId + '-filters' : null\"\n (click)=\"filtersOpen.set(!filtersOpen())\"\n >\n {{ filtersLabel() }}@if (filterChips().length) {&ngsp;({{ filterChips().length }})}\n </button>\n @if (filtersOpen()) {\n <div class=\"wm-sirio-grid-filters-panel\" role=\"group\" [id]=\"baseId + '-filters'\" [attr.aria-label]=\"filtersLabel()\">\n @for (column of filterColumns(); track column) {\n <ng-container *ngTemplateOutlet=\"filterControls; context: { $implicit: column, labelled: true }\" />\n }\n </div>\n }\n </div>\n}\n@if (showFilterChips() && !filterRowActive() && filterChips().length) {\n <div class=\"wm-sirio-grid-chips\">\n <wm-sirio-filter-chips [chips]=\"filterChips()\" [label]=\"filtersLabel()\" (removed)=\"onChipRemoved($event)\" />\n @if (filterChips().length > 1) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" (click)=\"clearFilters()\">{{ clearFiltersLabel() }}</button>\n }\n </div>\n}\n<div\n #scroller\n class=\"wm-sirio-grid-scroller\"\n [class.sirio-table-responsive]=\"responsive() && !cardMode()\"\n [class.sirio-table-overflow-start]=\"responsive() && !cardMode() && overflowStart()\"\n [class.sirio-table-overflow-end]=\"responsive() && !cardMode() && overflowEnd()\"\n [class.sirio-table-th-fixed]=\"stickyHeader() && !cardMode()\"\n [class.wm-sirio-grid-pinned-left]=\"hasPinLeft()\"\n [class.wm-sirio-grid-pinned-right]=\"hasPinRight()\"\n (scroll)=\"updateOverflow()\"\n (focusin)=\"navigation() && revealFocused($event)\"\n [style.--wm-grid-pin-left]=\"pinBlockWidths().left + 'px'\"\n [style.--wm-grid-pin-right]=\"pinBlockWidths().right + 'px'\"\n>\n <table\n #table\n class=\"sirio-table\"\n [class.sirio-table-dark]=\"variant() === 'dark'\"\n [class.sirio-table-light]=\"variant() === 'striped'\"\n [class.sirio-table-xs]=\"size() === 'xs'\"\n [class.sirio-table-sm]=\"size() === 'sm'\"\n [class.sirio-table-lg]=\"size() === 'lg'\"\n [class.sirio-table-card]=\"cardOnMobile()\"\n [class.wm-sirio-grid-card-active]=\"cardMode()\"\n [class.wm-sirio-grid-selectable]=\"selection() !== 'none'\"\n [class.wm-sirio-grid-fixed-layout]=\"fixedLayout()\"\n [class.wm-sirio-grid-grouped]=\"headerDepth() > 0\"\n [class.wm-sirio-grid-filter-hover]=\"filterButton() === 'hover'\"\n [style.width.px]=\"tableWidth()\"\n [attr.aria-busy]=\"isLoading() || null\"\n [attr.role]=\"gridRole()\"\n [attr.aria-multiselectable]=\"gridRole() && selection() === 'multiple' ? true : null\"\n >\n @if (caption()) {\n <caption [class.sr-only]=\"!captionVisible()\">{{ caption() }}</caption>\n }\n @if (fixedLayout()) {\n <!-- Fixed layout: the widths come from the columns (the first header row may be a group row). -->\n <colgroup>\n @if (checkColumn()) {\n <col [style.width.px]=\"toolColumnWidth\" />\n }\n @if (hasDetail()) {\n <col [style.width.px]=\"toolColumnWidth\" />\n }\n @if (rowNumbers()) {\n <col [style.width.px]=\"rowNumberWidth\" />\n }\n @for (column of visibleColumns(); track column) {\n <col [style.width.px]=\"widthOf(column)\" />\n }\n @if (actionsColumn()) {\n <col [style.width.px]=\"actionsWidth()\" />\n }\n </colgroup>\n }\n <thead>\n <!-- Grouped headers: a row per group level, then the column headers (rowspan below shorter group paths). -->\n @for (headerRow of headerRows(); track $index; let r = $index) {\n <tr>\n @if (r === 0) {\n @if (checkColumn()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\" [attr.rowspan]=\"headerRowspan()\">\n @if (selection() === 'multiple') {\n <div class=\"sirio-table-check\">\n <div class=\"sirio-form-check\">\n <input\n type=\"checkbox\"\n [id]=\"baseId + '-all'\"\n [checked]=\"allPageSelected()\"\n [indeterminate]=\"pageSelectedCount() > 0 && !allPageSelected()\"\n [disabled]=\"!selectableRows().length\"\n (change)=\"toggleAll($any($event.target).checked)\"\n />\n <label [attr.for]=\"baseId + '-all'\"><span class=\"sr-only\">{{ selectAllText() }}</span></label>\n </div>\n </div>\n } @else {\n <span class=\"sr-only\">{{ selectionHeaderLabel() }}</span>\n }\n </th>\n }\n @if (hasDetail()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\" [attr.rowspan]=\"headerRowspan()\"><span class=\"sr-only\">{{ expandRowLabel() }}</span></th>\n }\n @if (rowNumbers()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\" [attr.rowspan]=\"headerRowspan()\">\n <span aria-hidden=\"true\">{{ rowNumberHeader() }}</span><span class=\"sr-only\">{{ rowNumberLabel() }}</span>\n </th>\n }\n }\n @for (cell of headerRow; track cell.track) {\n @if (cell.kind === 'group') {\n <th\n scope=\"colgroup\"\n class=\"wm-sirio-grid-group-th\"\n [attr.colspan]=\"cell.colspan > 1 ? cell.colspan : null\"\n [wmSirioGridPin]=\"cell.pin\"\n [style.top.px]=\"headerTop(r)\"\n >\n {{ cell.label }}\n </th>\n } @else {\n @let column = cell.column;\n @let direction = directionOf(column);\n @let id = columnId(column);\n @let drop = dropTarget();\n <th\n scope=\"col\"\n [attr.data-column]=\"id\"\n [attr.rowspan]=\"cell.rowspan > 1 ? cell.rowspan : null\"\n [style.top.px]=\"headerTop(r)\"\n [wmSirioGridPin]=\"id\"\n [class]=\"'wm-sirio-grid-align-' + column.alignment() + ' ' + column.headerClassText()\"\n [style]=\"column.headerStyleObject()\"\n [class.sirio-sorting]=\"column.sortable()\"\n [class.sirio-sorting-asc]=\"direction === 'asc'\"\n [class.sirio-sorting-desc]=\"direction === 'desc'\"\n [class.wm-sirio-grid-th-resizable]=\"canResize(column)\"\n [class.wm-sirio-grid-fit]=\"column.fit()\"\n [class.wm-sirio-grid-th-draggable]=\"reorderable() && !cardMode()\"\n [class.wm-sirio-grid-th-dragging]=\"dragId() === id\"\n [class.wm-sirio-grid-drop-before]=\"drop?.id === id && drop?.side === 'before'\"\n [class.wm-sirio-grid-drop-after]=\"drop?.id === id && drop?.side === 'after'\"\n [style.width]=\"cssWidthOf(column)\"\n [style.min-width]=\"cssMinWidthOf(column)\"\n [attr.aria-sort]=\"ariaSortOf(column)\"\n [attr.aria-describedby]=\"headerHintId(column)\"\n [attr.tabindex]=\"headerFocusable(column) ? 0 : null\"\n [attr.draggable]=\"reorderable() && !cardMode() ? 'true' : null\"\n (click)=\"onHeaderClick(column, $event)\"\n (keydown)=\"onHeaderKey(column, $event)\"\n (dragstart)=\"onDragStart(column, $event)\"\n (dragover)=\"onDragOver(column, $event)\"\n (drop)=\"onDrop($event)\"\n (dragend)=\"onDragEnd()\"\n >\n <!-- One line: the title is cut with an ellipsis, sort index and filter button stay visible. -->\n <span class=\"wm-sirio-grid-th-inner\">\n <span class=\"wm-sirio-grid-th-label\" [attr.title]=\"column.header()\">\n @if (column.headerTemplate(); as header) {\n <ng-container *ngTemplateOutlet=\"header; context: { $implicit: column }\" />\n } @else {\n {{ column.header() }}\n }\n </span>\n @if (sortIndexOf(column); as sortIndex) {\n <span class=\"wm-sirio-grid-sort-index\" aria-hidden=\"true\">{{ sortIndex }}</span>\n }\n @if (column.filter() && !filterRowActive() && filterButton() !== 'none') {\n <ng-container *ngTemplateOutlet=\"filterBtnTpl; context: { $implicit: column }\" />\n }\n </span>\n @if (canResize(column)) {\n <!-- Mouse handle: from the keyboard the focused header resizes with Alt+arrows (as ag-grid). -->\n <span\n class=\"wm-sirio-grid-resizer\"\n aria-hidden=\"true\"\n draggable=\"false\"\n [attr.title]=\"resizeColumnLabel() + ' ' + column.header()\"\n (pointerdown)=\"onResizeStart(column, $event)\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (dragstart)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (dblclick)=\"resetColumnWidth(column)\"\n ></span>\n }\n </th>\n }\n }\n @if (r === 0 && actionsColumn()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [attr.rowspan]=\"headerRowspan()\">\n <span class=\"sr-only\">{{ actionsHeader() }}</span>\n </th>\n }\n </tr>\n }\n @if (filterRowActive()) {\n @let top = headerTop(headerRows().length);\n <!-- Filter row: cells of fields, not column headers (the body cells keep the titles as headers). -->\n <tr class=\"wm-sirio-grid-filter-row\">\n @if (checkColumn()) {\n <th class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\"></th>\n }\n @if (hasDetail()) {\n <th class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\"></th>\n }\n @if (rowNumbers()) {\n <th class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\"></th>\n }\n @for (column of visibleColumns(); track column) {\n <th [wmSirioGridPin]=\"columnId(column)\" [attr.data-filter-column]=\"columnId(column)\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\">\n @if (column.filter()) {\n <ng-container *ngTemplateOutlet=\"filterRowCell; context: { $implicit: column }\" />\n }\n </th>\n }\n @if (actionsColumn()) {\n <th class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [style.top.px]=\"top\" [attr.role]=\"filterCellRole()\"></th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @if (isLoading() && !renderedRows().length) {\n <tr class=\"wm-sirio-grid-message\">\n <td [attr.colspan]=\"colCount()\">\n <!-- The pending status region announces the text: the visible copy is hidden from AT. -->\n <wm-sirio-pending placement=\"inline\" [active]=\"true\" [label]=\"loadingText()\" />\n <span aria-hidden=\"true\">{{ loadingText() }}</span>\n </td>\n </tr>\n } @else if (errorContext(); as failure) {\n <!-- Failed server data source: message and \"Riprova\" (or the wmSirioGridError template). -->\n <tr class=\"wm-sirio-grid-message wm-sirio-grid-error\">\n <td [attr.colspan]=\"colCount()\" role=\"alert\">\n @if (errorTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: failure\" />\n } @else if (loadErrorText()) {\n <span class=\"fas fa-exclamation-triangle sirio-text-danger\" aria-hidden=\"true\"></span>&ngsp;{{ loadErrorText() }}&ngsp;\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-redo\" iconPosition=\"start\" (click)=\"reload()\">\n {{ retryLabel() }}\n </button>\n }\n </td>\n </tr>\n } @else {\n @for (row of renderedRows(); track row.id; let i = $index) {\n @if (row.getIsGrouped()) {\n <!-- Group row: toggle + value + count in the grouped column, aggregates in the others. -->\n @let groupColumn = groupColumnOf(row);\n <tr class=\"wm-sirio-grid-group-row\" [attr.aria-level]=\"gridRole() === 'treegrid' ? row.depth + 1 : null\">\n @if (checkColumn()) {\n <td class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\"></td>\n }\n @if (hasDetail()) {\n <td class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\"></td>\n }\n @if (rowNumbers()) {\n <td class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\"></td>\n }\n @for (column of visibleColumns(); track column) {\n <td\n [class]=\"'wm-sirio-grid-align-' + column.alignment()\"\n [class.font-mono]=\"column !== groupColumn && !!column.aggregate()\"\n [attr.data-label]=\"column.header()\"\n [wmSirioGridPin]=\"columnId(column)\"\n >\n @if (column === groupColumn) {\n @let groupText = column.formatValue(row.groupingValue);\n <span class=\"wm-sirio-grid-cell-inner\" [style.padding-inline-start.px]=\"indentOf(row)\">\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: column.header() + ' ' + groupText }\" />\n <strong>{{ groupText }}</strong>&ngsp;<span class=\"wm-sirio-grid-group-count font-mono\">({{ row.getLeafRows().length }})</span>\n </span>\n } @else if (column.aggregate()) {\n {{ aggregateText(column, row) }}\n }\n </td>\n }\n @if (actionsColumn()) {\n <td class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\"></td>\n }\n </tr>\n } @else {\n @let item = row.original;\n @let selected = isSelected(item);\n @let selectable = canSelect(item);\n @let look = rowLook(item, i);\n <tr\n [class]=\"look.cls\"\n [style]=\"look.style\"\n [class.wm-sirio-grid-row-selected]=\"selected\"\n [class.wm-sirio-grid-row-clickable]=\"clickSelect() && selectable\"\n [attr.tabindex]=\"keySelect() && selectable && !navigation() ? 0 : null\"\n [attr.aria-describedby]=\"keySelect() && selectable ? baseId + '-hint-select' : null\"\n [attr.aria-disabled]=\"selection() !== 'none' && !selectable ? 'true' : null\"\n [class.wm-sirio-grid-row-child]=\"row.depth > 0\"\n [attr.aria-selected]=\"selection() === 'none' ? null : selected\"\n [attr.aria-level]=\"gridRole() === 'treegrid' ? row.depth + 1 : null\"\n [class.wm-sirio-grid-row-invalid]=\"formMode() && rowInvalid(item)\"\n (click)=\"onRowActivate(row, i, $event)\"\n (dblclick)=\"onRowDoubleClick(row, $event)\"\n (keydown)=\"onRowKey(row, i, $event)\"\n >\n @if (checkColumn()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\">\n @if (selectable || !hideUnselectable()) {\n <div class=\"sirio-table-check\">\n <div class=\"sirio-form-check\">\n <input\n [type]=\"singleRadio() ? 'radio' : 'checkbox'\"\n [id]=\"baseId + '-row-' + i\"\n [attr.name]=\"singleRadio() ? baseId + '-row' : null\"\n [checked]=\"selected\"\n [disabled]=\"!selectable\"\n (change)=\"toggleRow(item, $any($event.target).checked)\"\n />\n <label [attr.for]=\"baseId + '-row-' + i\"><span class=\"sr-only\">{{ selectRowLabel()(item, i) }}</span></label>\n </div>\n </div>\n }\n </td>\n }\n @if (hasDetail()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\">\n @if (row.getCanExpand() && !row.subRows.length) {\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: rowName()(item, i) }\" />\n }\n </td>\n }\n @if (rowNumbers()) {\n <!-- Row header for screen readers; a td keeps the kit cell look (stripes, card layout). -->\n <td role=\"rowheader\" class=\"w-0 wm-sirio-grid-rownum-col font-mono\" wmSirioGridPin=\"__rownum\" [attr.data-label]=\"rowNumberLabel()\">{{ rowNumberOf(row) }}</td>\n }\n @for (column of visibleColumns(); track column) {\n @let cell = cellLook(column, item);\n <td\n [class]=\"cell.cls\"\n [style]=\"cell.style\"\n [class.font-mono]=\"column.isMono(item)\"\n [class.wm-sirio-grid-nowrap]=\"!column.wrap()\"\n [class.wm-sirio-grid-fit]=\"column.fit()\"\n [attr.data-label]=\"column.header()\"\n [wmSirioGridPin]=\"columnId(column)\"\n >\n @if (column === firstColumn() && (treeMode() || row.depth > 0)) {\n <span class=\"wm-sirio-grid-cell-inner\" [style.padding-inline-start.px]=\"indentOf(row)\">\n @if (treeMode()) {\n @if (row.subRows.length) {\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: column.textOf(item) }\" />\n } @else {\n <span class=\"wm-sirio-grid-toggle-spacer\" aria-hidden=\"true\"></span>\n }\n }\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: column, item: item, i: i }\" />\n </span>\n } @else {\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: column, item: item, i: i }\" />\n }\n </td>\n }\n @if (actionsColumn()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [attr.data-label]=\"actionsHeader()\">\n <span class=\"wm-sirio-grid-actions\">\n @if (rowInvalid(item)) {\n <span class=\"wm-sirio-grid-invalid\" [attr.title]=\"invalidRowLabel()\">\n <span class=\"fas fa-exclamation-circle sirio-text-danger\" aria-hidden=\"true\"></span>\n <span class=\"sr-only\">{{ invalidRowLabel() }}</span>\n </span>\n }\n @if (editorTemplate()) {\n @let editable = canEdit(item);\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n iconOnly\n [icon]=\"editable ? 'fa-pen' : 'fa-eye'\"\n [white]=\"variant() === 'dark'\"\n [label]=\"actionLabel(editable ? editLabel() : viewLabel(), item, i)\"\n (click)=\"editRow(item)\"\n ></button>\n }\n @if (canDelete(item)) {\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-trash\"\n iconOnly\n [white]=\"variant() === 'dark'\"\n [label]=\"actionLabel(deleteLabel(), item, i)\"\n (click)=\"deleteRow(item)\"\n ></button>\n }\n </span>\n </td>\n }\n </tr>\n @if (hasDetail() && row.getIsExpanded() && !row.subRows.length) {\n <tr class=\"wm-sirio-grid-detail-row\">\n <td [attr.colspan]=\"colCount()\">\n <ng-container *ngTemplateOutlet=\"detailTemplate()!; context: { $implicit: item, row: item }\" />\n </td>\n </tr>\n }\n }\n } @empty {\n <tr class=\"wm-sirio-grid-message\">\n <td [attr.colspan]=\"colCount()\">\n @if (emptyTemplate(); as empty) {\n <ng-container *ngTemplateOutlet=\"empty\" />\n } @else {\n {{ emptyText() }}\n }\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n@if (formError(); as error) {\n <span class=\"sirio-form-feedback sirio-visible sirio-feedback-invalid wm-sirio-grid-form-error\" role=\"alert\">{{ error }}</span>\n}\n@if (pageable() && total() > 0) {\n <wm-sirio-pagination\n [total]=\"total()\"\n [hasMore]=\"totalOpen()\"\n [moreLabel]=\"moreLabel()\"\n [(page)]=\"page\"\n [(pageSize)]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [variant]=\"paginationVariant()\"\n [siblings]=\"paginationSiblings()\"\n [showItems]=\"paginationShowItems()\"\n [ariaLabel]=\"paginationName()\"\n (paged)=\"onPaged()\"\n />\n}\n\n<ng-template #cellContent let-column let-item=\"item\" let-i=\"i\">\n @if (column.cellTemplate(); as cell) {\n <ng-container *ngTemplateOutlet=\"cell; context: { $implicit: item, row: item, value: column.valueOf(item), index: i }\" />\n } @else {\n {{ column.textOf(item) }}\n }\n</ng-template>\n\n@if (formMode() && editorTemplate(); as editor) {\n <!-- Edit dialog of a form array row: the form of wmSirioGridEditor bound to a copy of the row. -->\n <wm-sirio-dialog\n [(open)]=\"editorOpen\"\n [title]=\"editorTitle()\"\n [icon]=\"null\"\n [size]=\"editorSize()\"\n [closeLabel]=\"closeLabel()\"\n [closeOnBackdrop]=\"false\"\n (opened)=\"onEditorOpened()\"\n (closed)=\"onEditorClosed()\"\n >\n @if (editing(); as session) {\n @if (saveError(); as error) {\n <wm-sirio-alert type=\"error\" class=\"wm-sirio-grid-save-error\" [title]=\"saveErrorTitle()\" [dismissible]=\"false\">{{ error }}</wm-sirio-alert>\n }\n <div class=\"wm-sirio-grid-editor\" [id]=\"baseId + '-editor'\">\n <ng-container *ngTemplateOutlet=\"editor; context: session.context\" />\n </div>\n }\n <div wmSirioDialogFooter>\n @if (editing()?.context?.readonly) {\n <button wmSirioButton=\"primary\" type=\"button\" (click)=\"closeEditor()\">{{ closeLabel() }}</button>\n } @else {\n <button wmSirioButton=\"secondary\" type=\"button\" [disabled]=\"saving()\" (click)=\"closeEditor()\">{{ cancelLabel() }}</button>\n <button wmSirioButton=\"primary\" type=\"button\" [disabled]=\"saving()\" [attr.aria-busy]=\"saving() || null\" (click)=\"saveEditor()\">\n @if (saving()) {\n <wm-sirio-pending placement=\"inline\" [active]=\"true\" [label]=\"saveLabel()\" />\n }\n {{ saveLabel() }}\n </button>\n }\n </div>\n </wm-sirio-dialog>\n}\n\n<span class=\"sr-only\" [id]=\"baseId + '-hint-sort'\">{{ multiSortHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-select'\">{{ selectRowHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-reorder'\">{{ reorderHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-resize'\">{{ resizeHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-filter'\">{{ filterHint() }}</span>\n<span class=\"sr-only\" role=\"status\">{{ status() }}</span>\n<span class=\"sr-only\" aria-live=\"polite\">{{ announcement() }}</span>\n",
|
|
14395
|
+
template: "<!-- Controls of a column filter: in the header popover (labelled = false) or in the card panel. -->\n<ng-template #filterControls let-column let-labelled=\"labelled\">\n @if (operatorsOf(column).length) {\n <ng-container *ngTemplateOutlet=\"conditionControls; context: { $implicit: column, labelled: labelled }\" />\n } @else {\n @switch (column.filter()) {\n @case ('number') {\n <ng-container *ngTemplateOutlet=\"range; context: { $implicit: column, labelled: labelled, date: false }\" />\n }\n @case ('date') {\n <ng-container *ngTemplateOutlet=\"range; context: { $implicit: column, labelled: labelled, date: true }\" />\n }\n @case ('select') {\n <!-- Without filterOptions: the values present in the column (TanStack faceted values). -->\n <wm-sirio-select\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [options]=\"filterOptionsOf(column)\"\n [multiple]=\"column.filterMultiple()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column)\"\n (ngModelChange)=\"setFilter(column, $event)\"\n />\n }\n @case ('boolean') {\n <wm-sirio-select\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [options]=\"booleanOptions()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column)\"\n (ngModelChange)=\"setFilter(column, $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [label]=\"labelled ? column.header() : ''\"\n [ariaLabel]=\"labelled ? null : filterLabel() + ' ' + column.header()\"\n [placeholder]=\"column.filterPlaceholder()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"filterValueOf(column) ?? ''\"\n (ngModelChange)=\"setFilter(column, $event, false)\"\n />\n }\n }\n }\n</ng-template>\n\n<!-- Filter with operators: \"Condizione\" choice, then the value (two bounds for \"Compreso tra\", none for \"Vuoto\"). -->\n<ng-template #conditionControls let-column let-labelled=\"labelled\">\n @let condition = conditionOf(column);\n @let op = condition.operator;\n <fieldset class=\"wm-sirio-grid-filter-range\">\n <legend [class.sr-only]=\"!labelled\" class=\"sirio-label\">{{ column.header() }}</legend>\n <wm-sirio-select\n [label]=\"filterConditionLabel()\"\n [options]=\"operatorOptions(column)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"op\"\n (ngModelChange)=\"setOperator(column, $event)\"\n />\n @if (op !== 'blank' && op !== 'notBlank') {\n @switch (column.filter()) {\n @case ('number') {\n <wm-sirio-number\n [label]=\"op === 'between' ? filterFromLabel() : filterValueLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n @if (op === 'between') {\n <wm-sirio-number [label]=\"filterToLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"condition.to ?? null\" (ngModelChange)=\"setConditionPart(column, 'to', $event)\" />\n }\n }\n @case ('date') {\n <wm-sirio-date\n [label]=\"op === 'between' ? filterFromLabel() : filterValueLabel()\"\n [max]=\"op === 'between' ? ($any(condition.to) ?? null) : null\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n @if (op === 'between') {\n <wm-sirio-date\n [label]=\"filterToLabel()\"\n [min]=\"$any(condition.value) ?? null\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.to ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'to', $event)\"\n />\n }\n }\n @case ('select') {\n <wm-sirio-select\n [label]=\"filterValueLabel()\"\n [options]=\"filterOptionsOf(column)\"\n [multiple]=\"column.filterMultiple()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n }\n @case ('boolean') {\n <wm-sirio-select\n [label]=\"filterValueLabel()\"\n [options]=\"booleanOptions()\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? null\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [label]=\"filterValueLabel()\"\n [placeholder]=\"column.filterPlaceholder()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"condition.value ?? ''\"\n (ngModelChange)=\"setConditionPart(column, 'value', $event, false)\"\n />\n }\n }\n }\n </fieldset>\n</ng-template>\n\n<!-- Range filter (number / date): \"Da\" and \"A\", grouped by the column header in the card panel. -->\n<ng-template #range let-column let-labelled=\"labelled\" let-date=\"date\">\n @let value = rangeOf(column);\n <fieldset class=\"wm-sirio-grid-filter-range\">\n <legend [class.sr-only]=\"!labelled\" class=\"sirio-label\">{{ column.header() }}</legend>\n @if (date) {\n <wm-sirio-date [label]=\"filterFromLabel()\" [max]=\"$any(value.to) ?? null\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.from ?? null\" (ngModelChange)=\"setRange(column, 'from', $event)\" />\n <wm-sirio-date [label]=\"filterToLabel()\" [min]=\"$any(value.from) ?? null\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.to ?? null\" (ngModelChange)=\"setRange(column, 'to', $event)\" />\n } @else {\n <wm-sirio-number [label]=\"filterFromLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.from ?? null\" (ngModelChange)=\"setRange(column, 'from', $event)\" />\n <wm-sirio-number [label]=\"filterToLabel()\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"value.to ?? null\" (ngModelChange)=\"setRange(column, 'to', $event)\" />\n }\n </fieldset>\n</ng-template>\n\n<!-- Filter button of a column with its popover (in the header, or in the filter row with `filterRow`). -->\n<ng-template #filterBtnTpl let-column let-inRow=\"inRow\">\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-filter\"\n iconOnly\n class=\"wm-sirio-grid-filter-btn\"\n draggable=\"false\"\n [class.wm-sirio-grid-filter-active]=\"isFiltered(column)\"\n [white]=\"variant() === 'dark'\"\n [label]=\"filterButtonLabel(column, inRow)\"\n [wmSirioPopover]=\"filterPanel\"\n [popoverTitle]=\"filterLabel() + ' ' + column.header()\"\n popoverPlacement=\"bottom-end\"\n (opened)=\"focusFilter(column)\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n <ng-template #filterPanel>\n <div class=\"wm-sirio-grid-filter-panel\" [id]=\"baseId + '-filter-' + filterIndex(column)\">\n <ng-container *ngTemplateOutlet=\"filterControls; context: { $implicit: column, labelled: false }\" />\n <button wmSirioButton=\"tertiary-light\" size=\"small\" type=\"button\" class=\"wm-sirio-grid-filter-clear\" [disabled]=\"!isFiltered(column)\" (click)=\"clearFilter(column)\">\n {{ clearFilterLabel() }}\n </button>\n </div>\n </ng-template>\n</ng-template>\n\n<!-- Cell of the filter row: the simple condition in a field, the others as a summary (the button opens the popover). -->\n<ng-template #filterRowCell let-column>\n @let inline = inlineFilterOf(column);\n @let aria = filterLabel() + ' ' + column.header();\n <div class=\"wm-sirio-grid-filter-inline\" (keydown.escape)=\"clearFilter(column)\">\n @switch (inline.kind) {\n @case ('summary') {\n <span class=\"wm-sirio-grid-filter-summary\" [attr.title]=\"inline.summary\">{{ inline.summary }}</span>\n }\n @case ('number') {\n <wm-sirio-number [ariaLabel]=\"aria\" [placeholder]=\"inline.placeholder\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"inline.value\" (ngModelChange)=\"setInlineFilter(column, $event)\" />\n }\n @case ('date') {\n <wm-sirio-date [ariaLabel]=\"aria\" [ngModelOptions]=\"{ standalone: true }\" [ngModel]=\"inline.value\" (ngModelChange)=\"setInlineFilter(column, $event)\" />\n }\n @case ('select') {\n <wm-sirio-select\n [ariaLabel]=\"aria\"\n [options]=\"column.filter() === 'boolean' ? booleanOptions() : filterOptionsOf(column)\"\n [placeholder]=\"filterAllLabel()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"inline.value\"\n (ngModelChange)=\"setInlineFilter(column, $event)\"\n />\n }\n @default {\n <wm-sirio-textbox\n type=\"search\"\n [ariaLabel]=\"aria\"\n [placeholder]=\"inline.placeholder\"\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"inline.value ?? ''\"\n (ngModelChange)=\"setInlineFilter(column, $event, false)\"\n />\n }\n }\n <ng-container *ngTemplateOutlet=\"filterBtnTpl; context: { $implicit: column, inRow: true }\" />\n </div>\n</ng-template>\n\n<!-- Expand / collapse button of a row (tree rows, groups, detail rows). -->\n<ng-template #toggle let-row let-text=\"text\">\n <button\n type=\"button\"\n class=\"wm-sirio-grid-toggle\"\n [attr.aria-expanded]=\"row.getIsExpanded()\"\n [attr.aria-label]=\"expandLabel(row, text)\"\n [attr.title]=\"expandLabel(row, text)\"\n (click)=\"row.toggleExpanded()\"\n >\n <span [class]=\"row.getIsExpanded() ? 'fas fa-chevron-down' : 'fas fa-chevron-right'\" aria-hidden=\"true\"></span>\n </button>\n</ng-template>\n\n@let groups = groupableColumns().length > 0 && !server();\n@let expandTools = activeGrouping().length > 0 || treeMode() || hasDetail();\n@let formTools = canAdd() || deletableSelected().length > 0;\n@if (groups || expandTools || formTools || ((resizable() || reorderable()) && columnsCustomized())) {\n <div class=\"wm-sirio-grid-toolbar\">\n @if (groups) {\n <wm-sirio-select\n class=\"wm-sirio-grid-groupby\"\n [label]=\"groupByLabel()\"\n [options]=\"groupOptions()\"\n multiple\n [ngModelOptions]=\"{ standalone: true }\"\n [ngModel]=\"grouping()\"\n (ngModelChange)=\"setGrouping($event)\"\n />\n }\n <div class=\"wm-sirio-grid-toolbar-actions\">\n @if (canAdd()) {\n <button wmSirioButton=\"secondary\" size=\"small\" type=\"button\" icon=\"fa-plus\" iconPosition=\"start\" (click)=\"addRow()\">\n {{ addLabel() }}\n </button>\n }\n @if (deletableSelected().length) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-trash\" iconPosition=\"start\" (click)=\"deleteSelected()\">\n {{ deleteSelectedLabel() }} ({{ deletableSelected().length }})\n </button>\n }\n @if (expandTools) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-angle-double-down\" iconPosition=\"start\" (click)=\"expandAll(true)\">\n {{ expandAllLabel() }}\n </button>\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-angle-double-up\" iconPosition=\"start\" (click)=\"expandAll(false)\">\n {{ collapseAllLabel() }}\n </button>\n }\n @if ((resizable() || reorderable()) && columnsCustomized()) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-undo\" iconPosition=\"start\" (click)=\"resetColumns()\">\n {{ resetColumnsLabel() }}\n </button>\n }\n </div>\n </div>\n}\n\n@if (filterColumns().length && cardMode() && filterButton() !== 'none') {\n <!-- Card layout: the header (and its filter buttons) is hidden by the kit, filters go here. -->\n <div class=\"wm-sirio-grid-filters-mobile\">\n <button\n wmSirioButton=\"secondary\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-filter\"\n iconPosition=\"start\"\n [attr.aria-expanded]=\"filtersOpen()\"\n [attr.aria-controls]=\"filtersOpen() ? baseId + '-filters' : null\"\n (click)=\"filtersOpen.set(!filtersOpen())\"\n >\n {{ filtersLabel() }}@if (filterChips().length) {&ngsp;({{ filterChips().length }})}\n </button>\n @if (filtersOpen()) {\n <div class=\"wm-sirio-grid-filters-panel\" role=\"group\" [id]=\"baseId + '-filters'\" [attr.aria-label]=\"filtersLabel()\">\n @for (column of filterColumns(); track column) {\n <ng-container *ngTemplateOutlet=\"filterControls; context: { $implicit: column, labelled: true }\" />\n }\n </div>\n }\n </div>\n}\n@if (showFilterChips() && !filterRowActive() && filterChips().length) {\n <div class=\"wm-sirio-grid-chips\">\n <wm-sirio-filter-chips [chips]=\"filterChips()\" [label]=\"filtersLabel()\" (removed)=\"onChipRemoved($event)\" />\n @if (filterChips().length > 1) {\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" (click)=\"clearFilters()\">{{ clearFiltersLabel() }}</button>\n }\n </div>\n}\n<div\n #scroller\n class=\"wm-sirio-grid-scroller\"\n [class.sirio-table-responsive]=\"responsive() && !cardMode()\"\n [class.sirio-table-overflow-start]=\"responsive() && !cardMode() && overflowStart()\"\n [class.sirio-table-overflow-end]=\"responsive() && !cardMode() && overflowEnd()\"\n [class.sirio-table-th-fixed]=\"stickyHeader() && !cardMode()\"\n [class.wm-sirio-grid-pinned-left]=\"hasPinLeft()\"\n [class.wm-sirio-grid-pinned-right]=\"hasPinRight()\"\n (scroll)=\"updateOverflow()\"\n (focusin)=\"navigation() && revealFocused($event)\"\n [style.--wm-grid-pin-left]=\"pinBlockWidths().left + 'px'\"\n [style.--wm-grid-pin-right]=\"pinBlockWidths().right + 'px'\"\n>\n <table\n #table\n class=\"sirio-table\"\n [class.sirio-table-dark]=\"variant() === 'dark'\"\n [class.sirio-table-light]=\"variant() === 'striped'\"\n [class.sirio-table-xs]=\"size() === 'xs'\"\n [class.sirio-table-sm]=\"size() === 'sm'\"\n [class.sirio-table-lg]=\"size() === 'lg'\"\n [class.sirio-table-card]=\"cardOnMobile()\"\n [class.wm-sirio-grid-card-active]=\"cardMode()\"\n [class.wm-sirio-grid-selectable]=\"selection() !== 'none'\"\n [class.wm-sirio-grid-fixed-layout]=\"fixedLayout()\"\n [class.wm-sirio-grid-grouped]=\"headerDepth() > 0\"\n [class.wm-sirio-grid-filter-hover]=\"filterButton() === 'hover'\"\n [style.width.px]=\"tableWidth()\"\n [attr.aria-busy]=\"isLoading() || null\"\n [attr.role]=\"gridRole()\"\n [attr.aria-multiselectable]=\"gridRole() && selection() === 'multiple' ? true : null\"\n >\n @if (caption()) {\n <caption [class.sr-only]=\"!captionVisible()\">{{ caption() }}</caption>\n }\n @if (fixedLayout()) {\n <!-- Fixed layout: the widths come from the columns (the first header row may be a group row). -->\n <colgroup>\n @if (checkColumn()) {\n <col [style.width.px]=\"toolColumnWidth\" />\n }\n @if (hasDetail()) {\n <col [style.width.px]=\"toolColumnWidth\" />\n }\n @if (rowNumbers()) {\n <col [style.width.px]=\"rowNumberWidth\" />\n }\n @for (column of visibleColumns(); track column) {\n <col [style.width.px]=\"widthOf(column)\" />\n }\n @if (actionsColumn()) {\n <col [style.width.px]=\"actionsWidth()\" />\n }\n </colgroup>\n }\n <thead>\n <!-- Grouped headers: a row per group level, then the column headers (rowspan below shorter group paths). -->\n @for (headerRow of headerRows(); track $index; let r = $index) {\n <tr>\n @if (r === 0) {\n @if (checkColumn()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\" [attr.rowspan]=\"headerRowspan()\">\n @if (selection() === 'multiple') {\n <div class=\"sirio-table-check\">\n <div class=\"sirio-form-check\">\n <input\n type=\"checkbox\"\n [id]=\"baseId + '-all'\"\n [checked]=\"allPageSelected()\"\n [indeterminate]=\"pageSelectedCount() > 0 && !allPageSelected()\"\n [disabled]=\"!selectableRows().length\"\n (change)=\"toggleAll($any($event.target).checked)\"\n />\n <label [attr.for]=\"baseId + '-all'\"><span class=\"sr-only\">{{ selectAllText() }}</span></label>\n </div>\n </div>\n } @else {\n <span class=\"sr-only\">{{ selectionHeaderLabel() }}</span>\n }\n </th>\n }\n @if (hasDetail()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\" [attr.rowspan]=\"headerRowspan()\"><span class=\"sr-only\">{{ expandRowLabel() }}</span></th>\n }\n @if (rowNumbers()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\" [attr.rowspan]=\"headerRowspan()\">\n <span aria-hidden=\"true\">{{ rowNumberHeader() }}</span><span class=\"sr-only\">{{ rowNumberLabel() }}</span>\n </th>\n }\n }\n @for (cell of headerRow; track cell.track) {\n @if (cell.kind === 'group') {\n <th\n scope=\"colgroup\"\n class=\"wm-sirio-grid-group-th\"\n [attr.colspan]=\"cell.colspan > 1 ? cell.colspan : null\"\n [wmSirioGridPin]=\"cell.pin\"\n [style.top.px]=\"headerTop(r)\"\n >\n {{ cell.label }}\n </th>\n } @else {\n @let column = cell.column;\n @let direction = directionOf(column);\n @let id = columnId(column);\n @let drop = dropTarget();\n <th\n scope=\"col\"\n [attr.data-column]=\"id\"\n [attr.rowspan]=\"cell.rowspan > 1 ? cell.rowspan : null\"\n [style.top.px]=\"headerTop(r)\"\n [wmSirioGridPin]=\"id\"\n [class]=\"'wm-sirio-grid-align-' + column.alignment() + ' ' + column.headerClassText()\"\n [style]=\"column.headerStyleObject()\"\n [class.sirio-sorting]=\"column.sortable()\"\n [class.sirio-sorting-asc]=\"direction === 'asc'\"\n [class.sirio-sorting-desc]=\"direction === 'desc'\"\n [class.wm-sirio-grid-th-resizable]=\"canResize(column)\"\n [class.wm-sirio-grid-fit]=\"column.fit()\"\n [class.wm-sirio-grid-th-draggable]=\"reorderable() && !cardMode()\"\n [class.wm-sirio-grid-th-dragging]=\"dragId() === id\"\n [class.wm-sirio-grid-drop-before]=\"drop?.id === id && drop?.side === 'before'\"\n [class.wm-sirio-grid-drop-after]=\"drop?.id === id && drop?.side === 'after'\"\n [style.width]=\"cssWidthOf(column)\"\n [style.min-width]=\"cssMinWidthOf(column)\"\n [attr.aria-sort]=\"ariaSortOf(column)\"\n [attr.aria-describedby]=\"headerHintId(column)\"\n [attr.tabindex]=\"headerFocusable(column) ? 0 : null\"\n [attr.draggable]=\"reorderable() && !cardMode() ? 'true' : null\"\n (click)=\"onHeaderClick(column, $event)\"\n (keydown)=\"onHeaderKey(column, $event)\"\n (dragstart)=\"onDragStart(column, $event)\"\n (dragover)=\"onDragOver(column, $event)\"\n (drop)=\"onDrop($event)\"\n (dragend)=\"onDragEnd()\"\n >\n <!-- One line: the title is cut with an ellipsis, sort index and filter button stay visible. -->\n <span class=\"wm-sirio-grid-th-inner\">\n <span class=\"wm-sirio-grid-th-label\" [attr.title]=\"column.header()\">\n @if (column.headerTemplate(); as header) {\n <ng-container *ngTemplateOutlet=\"header; context: { $implicit: column }\" />\n } @else {\n {{ column.header() }}\n }\n </span>\n @if (sortIndexOf(column); as sortIndex) {\n <span class=\"wm-sirio-grid-sort-index\" aria-hidden=\"true\">{{ sortIndex }}</span>\n }\n @if (column.filter() && !filterRowActive() && filterButton() !== 'none') {\n <ng-container *ngTemplateOutlet=\"filterBtnTpl; context: { $implicit: column }\" />\n }\n </span>\n @if (canResize(column)) {\n <!-- Mouse handle: from the keyboard the focused header resizes with Alt+arrows (as ag-grid). -->\n <span\n class=\"wm-sirio-grid-resizer\"\n aria-hidden=\"true\"\n draggable=\"false\"\n [attr.title]=\"resizeColumnLabel() + ' ' + column.header()\"\n (pointerdown)=\"onResizeStart(column, $event)\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (dragstart)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (dblclick)=\"resetColumnWidth(column)\"\n ></span>\n }\n </th>\n }\n }\n @if (r === 0 && actionsColumn()) {\n <th scope=\"col\" class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [attr.rowspan]=\"headerRowspan()\">\n <span class=\"sr-only\">{{ actionsHeader() }}</span>\n </th>\n }\n </tr>\n }\n @if (filterRowActive()) {\n @let top = headerTop(headerRows().length);\n <!-- Filter row: cells of fields, not column headers (the body cells keep the titles as headers).\n th for the kit header styles; scope only for the checkers that require it on every th\n (the gridcell / cell role prevails, so the cells head nothing). -->\n <tr class=\"wm-sirio-grid-filter-row\">\n @if (checkColumn()) {\n <th class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\"></th>\n }\n @if (hasDetail()) {\n <th class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\"></th>\n }\n @if (rowNumbers()) {\n <th class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\"></th>\n }\n @for (column of visibleColumns(); track column) {\n <th [wmSirioGridPin]=\"columnId(column)\" [attr.data-filter-column]=\"columnId(column)\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\">\n @if (column.filter()) {\n <ng-container *ngTemplateOutlet=\"filterRowCell; context: { $implicit: column }\" />\n }\n </th>\n }\n @if (actionsColumn()) {\n <th class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [style.top.px]=\"top\" scope=\"col\" [attr.role]=\"filterCellRole()\"></th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @if (isLoading() && !renderedRows().length) {\n <tr class=\"wm-sirio-grid-message\">\n <td [attr.colspan]=\"colCount()\">\n <!-- The pending status region announces the text: the visible copy is hidden from AT. -->\n <wm-sirio-pending placement=\"inline\" [active]=\"true\" [label]=\"loadingText()\" />\n <span aria-hidden=\"true\">{{ loadingText() }}</span>\n </td>\n </tr>\n } @else if (errorContext(); as failure) {\n <!-- Failed server data source: message and \"Riprova\" (or the wmSirioGridError template). -->\n <tr class=\"wm-sirio-grid-message wm-sirio-grid-error\">\n <td [attr.colspan]=\"colCount()\" role=\"alert\">\n @if (errorTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: failure\" />\n } @else if (loadErrorText()) {\n <span class=\"fas fa-exclamation-triangle sirio-text-danger\" aria-hidden=\"true\"></span>&ngsp;{{ loadErrorText() }}&ngsp;\n <button wmSirioButton=\"tertiary\" size=\"small\" type=\"button\" icon=\"fa-redo\" iconPosition=\"start\" (click)=\"reload()\">\n {{ retryLabel() }}\n </button>\n }\n </td>\n </tr>\n } @else {\n @for (row of renderedRows(); track row.id; let i = $index) {\n @if (row.getIsGrouped()) {\n <!-- Group row: toggle + value + count in the grouped column, aggregates in the others. -->\n @let groupColumn = groupColumnOf(row);\n <tr class=\"wm-sirio-grid-group-row\" [attr.aria-level]=\"gridRole() === 'treegrid' ? row.depth + 1 : null\">\n @if (checkColumn()) {\n <td class=\"w-0 wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\"></td>\n }\n @if (hasDetail()) {\n <td class=\"w-0 wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\"></td>\n }\n @if (rowNumbers()) {\n <td class=\"w-0 wm-sirio-grid-rownum-col\" wmSirioGridPin=\"__rownum\"></td>\n }\n @for (column of visibleColumns(); track column) {\n <td\n [class]=\"'wm-sirio-grid-align-' + column.alignment()\"\n [class.font-mono]=\"column !== groupColumn && !!column.aggregate()\"\n [attr.data-label]=\"column.header()\"\n [wmSirioGridPin]=\"columnId(column)\"\n >\n @if (column === groupColumn) {\n @let groupText = column.formatValue(row.groupingValue);\n <span class=\"wm-sirio-grid-cell-inner\" [style.padding-inline-start.px]=\"indentOf(row)\">\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: column.header() + ' ' + groupText }\" />\n <strong>{{ groupText }}</strong>&ngsp;<span class=\"wm-sirio-grid-group-count font-mono\">({{ row.getLeafRows().length }})</span>\n </span>\n } @else if (column.aggregate()) {\n {{ aggregateText(column, row) }}\n }\n </td>\n }\n @if (actionsColumn()) {\n <td class=\"w-0 wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\"></td>\n }\n </tr>\n } @else {\n @let item = row.original;\n @let selected = isSelected(item);\n @let selectable = canSelect(item);\n @let look = rowLook(item, i);\n <tr\n [class]=\"look.cls\"\n [style]=\"look.style\"\n [class.wm-sirio-grid-row-selected]=\"selected\"\n [class.wm-sirio-grid-row-clickable]=\"clickSelect() && selectable\"\n [attr.tabindex]=\"keySelect() && selectable && !navigation() ? 0 : null\"\n [attr.aria-describedby]=\"keySelect() && selectable ? baseId + '-hint-select' : null\"\n [attr.aria-disabled]=\"selection() !== 'none' && !selectable ? 'true' : null\"\n [class.wm-sirio-grid-row-child]=\"row.depth > 0\"\n [attr.aria-selected]=\"selection() === 'none' ? null : selected\"\n [attr.aria-level]=\"gridRole() === 'treegrid' ? row.depth + 1 : null\"\n [class.wm-sirio-grid-row-invalid]=\"formMode() && rowInvalid(item)\"\n (click)=\"onRowActivate(row, i, $event)\"\n (dblclick)=\"onRowDoubleClick(row, $event)\"\n (keydown)=\"onRowKey(row, i, $event)\"\n >\n @if (checkColumn()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-check-col\" wmSirioGridPin=\"__select\">\n @if (selectable || !hideUnselectable()) {\n <div class=\"sirio-table-check\">\n <div class=\"sirio-form-check\">\n <input\n [type]=\"singleRadio() ? 'radio' : 'checkbox'\"\n [id]=\"baseId + '-row-' + i\"\n [attr.name]=\"singleRadio() ? baseId + '-row' : null\"\n [checked]=\"selected\"\n [disabled]=\"!selectable\"\n (change)=\"toggleRow(item, $any($event.target).checked)\"\n />\n <label [attr.for]=\"baseId + '-row-' + i\"><span class=\"sr-only\">{{ selectRowLabel()(item, i) }}</span></label>\n </div>\n </div>\n }\n </td>\n }\n @if (hasDetail()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-expand-col\" wmSirioGridPin=\"__expand\">\n @if (row.getCanExpand() && !row.subRows.length) {\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: rowName()(item, i) }\" />\n }\n </td>\n }\n @if (rowNumbers()) {\n <!-- Row header for screen readers; a td keeps the kit cell look (stripes, card layout). -->\n <td role=\"rowheader\" class=\"w-0 wm-sirio-grid-rownum-col font-mono\" wmSirioGridPin=\"__rownum\" [attr.data-label]=\"rowNumberLabel()\">{{ rowNumberOf(row) }}</td>\n }\n @for (column of visibleColumns(); track column) {\n @let cell = cellLook(column, item);\n <td\n [class]=\"cell.cls\"\n [style]=\"cell.style\"\n [class.font-mono]=\"column.isMono(item)\"\n [class.wm-sirio-grid-nowrap]=\"!column.wrap()\"\n [class.wm-sirio-grid-fit]=\"column.fit()\"\n [attr.data-label]=\"column.header()\"\n [wmSirioGridPin]=\"columnId(column)\"\n >\n @if (column === firstColumn() && (treeMode() || row.depth > 0)) {\n <span class=\"wm-sirio-grid-cell-inner\" [style.padding-inline-start.px]=\"indentOf(row)\">\n @if (treeMode()) {\n @if (row.subRows.length) {\n <ng-container *ngTemplateOutlet=\"toggle; context: { $implicit: row, text: column.textOf(item) }\" />\n } @else {\n <span class=\"wm-sirio-grid-toggle-spacer\" aria-hidden=\"true\"></span>\n }\n }\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: column, item: item, i: i }\" />\n </span>\n } @else {\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: column, item: item, i: i }\" />\n }\n </td>\n }\n @if (actionsColumn()) {\n <td class=\"w-0 sirio-table-btn wm-sirio-grid-actions-col\" wmSirioGridPin=\"__actions\" [attr.data-label]=\"actionsHeader()\">\n <span class=\"wm-sirio-grid-actions\">\n @if (rowInvalid(item)) {\n <span class=\"wm-sirio-grid-invalid\" [attr.title]=\"invalidRowLabel()\">\n <span class=\"fas fa-exclamation-circle sirio-text-danger\" aria-hidden=\"true\"></span>\n <span class=\"sr-only\">{{ invalidRowLabel() }}</span>\n </span>\n }\n @if (editorTemplate()) {\n @let editable = canEdit(item);\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n iconOnly\n [icon]=\"editable ? 'fa-pen' : 'fa-eye'\"\n [white]=\"variant() === 'dark'\"\n [label]=\"actionLabel(editable ? editLabel() : viewLabel(), item, i)\"\n (click)=\"editRow(item)\"\n ></button>\n }\n @if (canDelete(item)) {\n <button\n wmSirioButton=\"ghost\"\n size=\"small\"\n type=\"button\"\n icon=\"fa-trash\"\n iconOnly\n [white]=\"variant() === 'dark'\"\n [label]=\"actionLabel(deleteLabel(), item, i)\"\n (click)=\"deleteRow(item)\"\n ></button>\n }\n </span>\n </td>\n }\n </tr>\n @if (hasDetail() && row.getIsExpanded() && !row.subRows.length) {\n <tr class=\"wm-sirio-grid-detail-row\">\n <td [attr.colspan]=\"colCount()\">\n <ng-container *ngTemplateOutlet=\"detailTemplate()!; context: { $implicit: item, row: item }\" />\n </td>\n </tr>\n }\n }\n } @empty {\n <tr class=\"wm-sirio-grid-message\">\n <td [attr.colspan]=\"colCount()\">\n @if (emptyTemplate(); as empty) {\n <ng-container *ngTemplateOutlet=\"empty\" />\n } @else {\n {{ emptyText() }}\n }\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n@if (formError(); as error) {\n <span class=\"sirio-form-feedback sirio-visible sirio-feedback-invalid wm-sirio-grid-form-error\" role=\"alert\">{{ error }}</span>\n}\n@if (pageable() && total() > 0) {\n <wm-sirio-pagination\n [total]=\"total()\"\n [hasMore]=\"totalOpen()\"\n [moreLabel]=\"moreLabel()\"\n [(page)]=\"page\"\n [(pageSize)]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [variant]=\"paginationVariant()\"\n [siblings]=\"paginationSiblings()\"\n [showItems]=\"paginationShowItems()\"\n [ariaLabel]=\"paginationName()\"\n (paged)=\"onPaged()\"\n />\n}\n\n<ng-template #cellContent let-column let-item=\"item\" let-i=\"i\">\n @if (column.cellTemplate(); as cell) {\n <ng-container *ngTemplateOutlet=\"cell; context: { $implicit: item, row: item, value: column.valueOf(item), index: i }\" />\n } @else {\n {{ column.textOf(item) }}\n }\n</ng-template>\n\n@if (formMode() && editorTemplate(); as editor) {\n <!-- Edit dialog of a form array row: the form of wmSirioGridEditor bound to a copy of the row. -->\n <wm-sirio-dialog\n [(open)]=\"editorOpen\"\n [title]=\"editorTitle()\"\n [icon]=\"null\"\n [size]=\"editorSize()\"\n [closeLabel]=\"closeLabel()\"\n [closeOnBackdrop]=\"false\"\n (opened)=\"onEditorOpened()\"\n (closed)=\"onEditorClosed()\"\n >\n @if (editing(); as session) {\n @if (saveError(); as error) {\n <wm-sirio-alert type=\"error\" class=\"wm-sirio-grid-save-error\" [title]=\"saveErrorTitle()\" [dismissible]=\"false\">{{ error }}</wm-sirio-alert>\n }\n <div class=\"wm-sirio-grid-editor\" [id]=\"baseId + '-editor'\">\n <ng-container *ngTemplateOutlet=\"editor; context: session.context\" />\n </div>\n }\n <div wmSirioDialogFooter>\n @if (editing()?.context?.readonly) {\n <button wmSirioButton=\"primary\" type=\"button\" (click)=\"closeEditor()\">{{ closeLabel() }}</button>\n } @else {\n <button wmSirioButton=\"secondary\" type=\"button\" [disabled]=\"saving()\" (click)=\"closeEditor()\">{{ cancelLabel() }}</button>\n <button wmSirioButton=\"primary\" type=\"button\" [disabled]=\"saving()\" [attr.aria-busy]=\"saving() || null\" (click)=\"saveEditor()\">\n @if (saving()) {\n <wm-sirio-pending placement=\"inline\" [active]=\"true\" [label]=\"saveLabel()\" />\n }\n {{ saveLabel() }}\n </button>\n }\n </div>\n </wm-sirio-dialog>\n}\n\n<span class=\"sr-only\" [id]=\"baseId + '-hint-sort'\">{{ multiSortHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-select'\">{{ selectRowHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-reorder'\">{{ reorderHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-resize'\">{{ resizeHint() }}</span>\n<span class=\"sr-only\" [id]=\"baseId + '-hint-filter'\">{{ filterHint() }}</span>\n<span class=\"sr-only\" role=\"status\">{{ status() }}</span>\n<span class=\"sr-only\" aria-live=\"polite\">{{ announcement() }}</span>\n",
|
|
14362
14396
|
styles: [
|
|
14363
14397
|
":host{display:block}:host(.wm-sirio-grid-sized){display:flex;flex-direction:column;min-height:10rem}:host(.wm-sirio-grid-sized)>*{flex:none}:host(.wm-sirio-grid-sized)>.wm-sirio-grid-scroller{flex:1 1 auto;max-height:none;min-height:0;overflow-y:auto}:host(.wm-sirio-grid-sized)>.wm-sirio-grid-scroller>table{align-self:flex-start}.wm-sirio-grid-scroller:not(.sirio-table-responsive){display:block}.sirio-table-th-fixed .sirio-table,.sirio-table-column-fixed-first .sirio-table,.sirio-table-action-fixed .sirio-table{margin-bottom:0}.wm-sirio-grid-align-start{text-align:start}.wm-sirio-grid-align-center{text-align:center}.wm-sirio-grid-align-end{text-align:end}th.sirio-sorting:focus:not(:focus-visible){outline:none}th.sirio-sorting{-webkit-user-select:none;user-select:none}th.sirio-sorting:before{content:none}th.sirio-sorting-asc:after{background-position:50% calc(50% + 4px)}th.sirio-sorting-desc:after{background-position:50% calc(50% - 4px)}.wm-sirio-grid-check-col .sirio-table-check{justify-content:center}.wm-sirio-grid-check-col .sirio-form-check label{min-height:24px;margin-bottom:0;padding-left:0}table.sirio-table tr.wm-sirio-grid-row-bg:nth-child(n)>td{background-color:var(--wm-grid-row-bg)!important}table.sirio-table tr.wm-sirio-grid-row-selected:nth-child(n)>td{background-color:#e8effa!important}table.sirio-table tr:nth-child(n)>td.wm-sirio-grid-cell-bg{background-color:var(--wm-grid-cell-bg)!important}tr.wm-sirio-grid-row-selected>td:first-child{--wm-grid-bar: inset 4px 0 0 0 #2f6dd5}tr.wm-sirio-grid-row-invalid>td:first-child{--wm-grid-bar: inset 4px 0 0 0 #aa224f}.wm-sirio-grid-actions{align-items:center;display:inline-flex;gap:4px;white-space:nowrap}.wm-sirio-grid-actions .sirio-btn+.sirio-btn{margin-left:0}.wm-sirio-grid-form-error{margin:8px 0 0}.wm-sirio-grid-save-error{display:block;margin-bottom:24px}tr:is(.wm-sirio-grid-row-selected,.wm-sirio-grid-row-invalid)>td:first-child:not(.wm-sirio-grid-pin){box-shadow:var(--wm-grid-bar)}tr.wm-sirio-grid-row-clickable{cursor:pointer}tr.wm-sirio-grid-row-clickable:focus-visible{outline:2px solid #2f6dd5;outline-offset:-2px}tr.wm-sirio-grid-row-clickable:hover>td{background-color:#f2f6fc}tr.wm-sirio-grid-message>td{color:#5b6571;text-align:center}tr.wm-sirio-grid-message wm-sirio-pending{margin-right:8px;vertical-align:middle}tbody{isolation:isolate}table[aria-busy=true] tbody>tr:not(.wm-sirio-grid-message){opacity:.6;transition:opacity .15s}.sirio-table-card tr.wm-sirio-grid-message>td:before{content:none!important}.sirio-table-card td.wm-sirio-grid-check-col{justify-content:flex-start}.sirio-table-card tr.wm-sirio-grid-row-selected{border-color:#2f6dd5}.sirio-table-card tr.wm-sirio-grid-row-selected>td:first-child{box-shadow:none}caption:not(.sr-only){caption-side:top;color:#454d56;font-weight:600;padding:0 0 8px;text-align:start}.wm-sirio-grid-toolbar{align-items:flex-end;display:flex;flex-wrap:wrap;gap:8px 24px;margin-bottom:16px}.wm-sirio-grid-groupby{display:block;flex:0 1 320px;min-width:220px}.wm-sirio-grid-groupby ::ng-deep wm-sirio-field{margin-bottom:0}.wm-sirio-grid-toolbar-actions{display:flex;flex-wrap:wrap;gap:8px;margin-inline-start:auto}.wm-sirio-grid-sort-index{background-color:#2f6dd5;border-radius:10px;color:#fff;display:inline-block;font-size:12px;font-weight:600;line-height:18px;margin-inline-start:4px;min-width:18px;text-align:center;vertical-align:middle}.sirio-table-dark .wm-sirio-grid-sort-index{background-color:#18cee7;color:#002460}th.wm-sirio-grid-th-resizable{position:relative}.sirio-table-th-fixed thead th.wm-sirio-grid-th-resizable,.sirio-table-responsive thead th.wm-sirio-grid-th-resizable{position:sticky}.wm-sirio-grid-resizer{bottom:0;cursor:col-resize;inset-inline-end:0;position:absolute;top:0;touch-action:none;width:8px;z-index:2}.wm-sirio-grid-resizer:after{background-color:#aec6ef;bottom:8px;content:\"\";inset-inline-start:3px;position:absolute;top:8px;width:2px}.wm-sirio-grid-resizer:hover:after,.wm-sirio-grid-resizer:focus-visible:after{background-color:#2f6dd5}.wm-sirio-grid-resizer:focus-visible{outline:2px solid #2f6dd5;outline-offset:-2px}td.wm-sirio-grid-nowrap{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}table.wm-sirio-grid-fixed-layout{table-layout:fixed}table.wm-sirio-grid-fixed-layout th,table.wm-sirio-grid-fixed-layout td{overflow:hidden;text-overflow:ellipsis}table.wm-sirio-grid-fixed-layout .wm-sirio-grid-check-col,table.wm-sirio-grid-fixed-layout .wm-sirio-grid-expand-col{width:48px}th.wm-sirio-grid-th-draggable{cursor:grab}th.wm-sirio-grid-th-draggable.sirio-sorting{cursor:pointer}th.wm-sirio-grid-th-dragging{opacity:.5}th.wm-sirio-grid-drop-before{box-shadow:inset 4px 0 #2f6dd5}th.wm-sirio-grid-drop-after{box-shadow:inset -4px 0 #2f6dd5}th.wm-sirio-grid-th-draggable:focus-visible{outline:2px solid #2f6dd5;outline-offset:-3px}.wm-sirio-grid-cell-inner{align-items:center;display:inline-flex;gap:4px}.wm-sirio-grid-toggle{align-items:center;background:transparent;border:0;border-radius:4px;color:#2f6dd5;cursor:pointer;display:inline-flex;flex:0 0 auto;height:28px;justify-content:center;padding:0;width:28px}.wm-sirio-grid-toggle:hover{background-color:#d9e4f7}.wm-sirio-grid-toggle:focus-visible{outline:2px solid #2f6dd5;outline-offset:0}.wm-sirio-grid-toggle-spacer{display:inline-block;flex:0 0 auto;width:28px}.wm-sirio-grid-expand-col{text-align:center}tr.wm-sirio-grid-group-row>td{background-color:#f2f6fc;font-weight:600}.wm-sirio-grid-group-count{color:#5b6571;font-weight:400}tr.wm-sirio-grid-detail-row>td{background-color:#f2f6fc;box-shadow:inset 4px 0 #2f6dd5;padding:16px 24px}.wm-sirio-grid-card-active tr.wm-sirio-grid-detail-row>td:before,.wm-sirio-grid-card-active tr.wm-sirio-grid-group-row>td:empty{display:none}th.wm-sirio-grid-group-th{text-align:center}.sirio-table-th-fixed .wm-sirio-grid-grouped th:not(.wm-sirio-grid-pin-edge-left,.wm-sirio-grid-pin-edge-right){box-shadow:inset -1px -1px #aec6ef}.sirio-table-th-fixed .wm-sirio-grid-grouped.sirio-table-dark th:not(.wm-sirio-grid-pin-edge-left,.wm-sirio-grid-pin-edge-right){box-shadow:inset -1px -1px #2f6dd5}.wm-sirio-grid-rownum-col{color:#5b6571;font-variant-numeric:tabular-nums;text-align:end;white-space:nowrap}table.wm-sirio-grid-fixed-layout .wm-sirio-grid-rownum-col{width:64px}.sirio-table-responsive .wm-sirio-grid-pin{position:sticky}th.wm-sirio-grid-pin{z-index:11}td.wm-sirio-grid-pin{background-color:#fff}td.wm-sirio-grid-pin-l{border-right-style:hidden;box-shadow:var(--wm-grid-bar, 0 0 rgba(0, 0, 0, 0)),inset -1px 0 #d9e4f7}td.wm-sirio-grid-pin-r{border-left-style:hidden;box-shadow:inset 1px 0 #d9e4f7}.wm-sirio-grid-pin-edge-left{box-shadow:inset -1px 0 #d9e4f7}.wm-sirio-grid-pin-edge-right{box-shadow:inset 1px 0 #d9e4f7}.sirio-table-th-fixed thead th.wm-sirio-grid-pin-edge-left{box-shadow:inset 1px 1px #d9e4f7,inset -1px 0 #d9e4f7}.sirio-table-th-fixed thead th.wm-sirio-grid-pin-edge-left:first-child{box-shadow:inset 0 1px #d9e4f7,inset -1px 0 #d9e4f7}.sirio-table-th-fixed thead th.wm-sirio-grid-pin-edge-right{box-shadow:inset 1px 1px #d9e4f7}.sirio-table.sirio-table-dark th.wm-sirio-grid-pin-l{border-right-style:hidden!important;box-shadow:inset -1px 0 #2f6dd5}.sirio-table.sirio-table-dark th.wm-sirio-grid-pin-r{border-left-style:hidden;box-shadow:inset 1px 0 #2f6dd5}.sirio-table-th-fixed .sirio-table.sirio-table-dark thead th{border-right-width:0!important;border-bottom-width:0!important;box-shadow:inset -1px -1px #2f6dd5}.sirio-table-th-fixed .sirio-table.sirio-table-dark thead th:last-child{box-shadow:inset 0 -1px #2f6dd5}.sirio-table-th-fixed .sirio-table.sirio-table-dark thead th.wm-sirio-grid-pin-edge-right{box-shadow:inset 1px 0 #2f6dd5,inset -1px -1px #2f6dd5}.sirio-table-th-fixed .sirio-table.sirio-table-dark thead th.wm-sirio-grid-pin-edge-right:last-child{box-shadow:inset 1px 0 #2f6dd5,inset 0 -1px #2f6dd5}.sirio-table-responsive.sirio-table-overflow-start:before{left:var(--wm-grid-pin-left, 0);margin-right:-4px;z-index:12}.sirio-table-responsive.sirio-table-overflow-end:after{right:var(--wm-grid-pin-right, 0);margin-left:-4px;z-index:12}@media(min-width:768px){.sirio-table-responsive.sirio-table-overflow-start:before{margin-right:-8px}.sirio-table-responsive.sirio-table-overflow-end:after{margin-left:-8px}}.sirio-table-responsive{border:1px solid #d9e4f7;border-top:none;border-radius:4px}.sirio-table tr>:last-child{border-right-style:hidden!important}.sirio-table tr>:first-child{border-left-style:hidden!important}.wm-sirio-grid-th-inner{display:flex;align-items:center;gap:4px}.wm-sirio-grid-align-end>.wm-sirio-grid-th-inner{flex-direction:row-reverse}.wm-sirio-grid-align-center>.wm-sirio-grid-th-inner{justify-content:center}.wm-sirio-grid-th-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n",
|
|
14364
14398
|
".wm-sirio-grid-filter-btn{flex:none;margin-inline-start:auto}.wm-sirio-grid-filter-hover th:not(:hover):not(:focus-within)>.wm-sirio-grid-th-inner>.wm-sirio-grid-filter-btn:not(.wm-sirio-grid-filter-active){opacity:0}.wm-sirio-grid-filter-btn.wm-sirio-grid-filter-active{background-color:#2f6dd5;border-color:#2f6dd5;color:#fff}.sirio-table-dark .wm-sirio-grid-filter-btn.wm-sirio-grid-filter-active{background-color:#18cee7;border-color:#18cee7;color:#002460}.wm-sirio-grid-filter-panel{padding-top:8px;width:224px}:is(.wm-sirio-grid-filter-panel,.wm-sirio-grid-filters-panel) ::ng-deep .sirio-dropdown-select>span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:is(.wm-sirio-grid-filter-panel,.wm-sirio-grid-filters-panel) :is(wm-sirio-textbox,wm-sirio-select,wm-sirio-number,wm-sirio-date){display:block}.wm-sirio-grid-filter-panel ::ng-deep wm-sirio-field{margin-bottom:12px}.wm-sirio-grid-filter-panel ::ng-deep .sirio-label{color:#fff}.wm-sirio-grid-filter-range{border:0;margin:0;min-width:0;padding:0}.wm-sirio-grid-filter-range>legend{font-size:inherit;float:none;width:auto}.wm-sirio-grid-filters-mobile{margin-bottom:16px}.wm-sirio-grid-filters-panel{border:1px solid #d9e4f7;margin-top:12px;padding:16px 16px 0}.wm-sirio-grid-chips{align-items:center;display:flex;flex-wrap:wrap;gap:8px 16px;margin-bottom:16px}tr.wm-sirio-grid-filter-row>th{padding:4px 6px;background:#eef3fb}.sirio-table-dark tr.wm-sirio-grid-filter-row>th{background:#00368f}.wm-sirio-grid-filter-inline{display:flex;align-items:center}.wm-sirio-grid-filter-inline>:not(button){flex:1;min-width:0}.wm-sirio-grid-filter-inline ::ng-deep wm-sirio-field{margin-bottom:0}.wm-sirio-grid-filter-inline ::ng-deep .sirio-form-control{height:32px;padding-block:0;font-size:14px}.wm-sirio-grid-filter-inline ::ng-deep input{padding-inline:6px}.wm-sirio-grid-filter-inline ::ng-deep input::-webkit-search-cancel-button{display:none}.wm-sirio-grid-filter-summary{overflow:hidden;padding:0 8px;border:1px solid #aec6ef;background:#f2f6fc;color:#00173d;font-size:14px;line-height:30px;text-overflow:ellipsis;white-space:nowrap}.wm-sirio-grid-filter-clear.sirio-btn{background-color:#18cee7;border-color:#18cee7;color:#001c4a}.wm-sirio-grid-filter-clear.sirio-btn:hover{background-color:#8ce7f3;border-color:#8ce7f3;color:#001c4a}.wm-sirio-grid-filter-clear.sirio-btn:not(:disabled):active{background-color:#0f7d8a;border-color:#0f7d8a;color:#fff}.wm-sirio-grid-filter-clear.sirio-btn:disabled{background-color:transparent;border-color:#fff6;color:#fff9}.wm-sirio-grid-filter-clear.sirio-btn:focus-visible{outline-color:#fff!important}\n",
|