@dflat-core/web 1.7.2079 → 1.7.2080

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.
@@ -20132,6 +20132,11 @@ const FilterOperators = {
20132
20132
  label: "n'est aucune de"
20133
20133
  }]
20134
20134
  };
20135
+ const EditorOperators = {
20136
+ ...FilterOperators,
20137
+ text: [...FilterOperators.text, ...FilterOperators.list],
20138
+ number: [...FilterOperators.number, ...FilterOperators.list]
20139
+ };
20135
20140
  var FilterEditorComponent = class FilterEditorComponent {
20136
20141
  constructor() {
20137
20142
  this.columns = [];
@@ -20207,7 +20212,18 @@ var FilterEditorComponent = class FilterEditorComponent {
20207
20212
  return this.columns.find((c) => c.key === key);
20208
20213
  }
20209
20214
  operatorsOf(condition) {
20210
- return FilterOperators[this.columnOf(condition.Property)?.type ?? "text"];
20215
+ return EditorOperators[this.columnOf(condition.Property)?.type ?? "text"];
20216
+ }
20217
+ hasKnownValues(condition) {
20218
+ return !!this.columnOf(condition.Property)?.values?.length;
20219
+ }
20220
+ addValue(condition, input) {
20221
+ const value = (input.value ?? "").trim();
20222
+ input.value = "";
20223
+ if (value && !(condition.Values ?? []).includes(value)) condition.Values = [...condition.Values ?? [], value];
20224
+ }
20225
+ removeValue(condition, value) {
20226
+ condition.Values = (condition.Values ?? []).filter((v) => v !== value);
20211
20227
  }
20212
20228
  hasValue(condition) {
20213
20229
  return !ViewFilterNoValueOperators.includes(condition.Operator);
@@ -20292,7 +20308,7 @@ var FilterEditorComponent = class FilterEditorComponent {
20292
20308
  summary(group = this.filter) {
20293
20309
  return [...group.Conditions.map((c) => {
20294
20310
  const column = this.columnOf(c.Property);
20295
- const operator = FilterOperators[column?.type ?? "text"].find((o) => o.value === c.Operator)?.label ?? c.Operator;
20311
+ const operator = this.operatorsOf(c).find((o) => o.value === c.Operator)?.label ?? c.Operator;
20296
20312
  const values = this.isList(c) ? (c.Values ?? []).map((v) => column?.values?.find((x) => x.value === v)?.label ?? v).join(", ") : !this.hasValue(c) ? "" : this.hasSecondValue(c) ? `${c.Value ?? "…"} et ${c.Value2 ?? "…"}` : c.Value ?? "…";
20297
20313
  return `${column?.label ?? c.Property} ${operator}${values ? " « " + values + " »" : ""}`;
20298
20314
  }), ...(group.Groups ?? []).map((g) => `(${this.summary(g)})`)].join(group.Logic === "or" ? " OU " : " ET ") || "Aucun filtre";
@@ -20323,8 +20339,8 @@ var FilterEditorComponent = class FilterEditorComponent {
20323
20339
  panelFields: "panelFields"
20324
20340
  },
20325
20341
  ngImport: i0,
20326
- template: "<div class=\"fe\">\r\n <div class=\"fe-tabs\" role=\"tablist\" *ngIf=\"!section\">\r\n <button type=\"button\" class=\"fe-tab\" [class.active]=\"tab === 'filters'\" (click)=\"tab = 'filters'\">Filtres</button>\r\n <button type=\"button\" class=\"fe-tab\" [class.active]=\"tab === 'sort'\" (click)=\"tab = 'sort'\">Tri</button>\r\n </div>\r\n\r\n <div class=\"fe-body\" *ngIf=\"shownTab === 'filters'\">\r\n <!-- Filtres de l'écran (FilterPanel) : valeurs enregistrées avec la vue, appliquées au FilterPanel. -->\r\n <div class=\"fe-panel\" *ngIf=\"panelFields.length || shownPanelFields().length\">\r\n <div class=\"fe-panel-title\">Filtres de l'écran</div>\r\n <div class=\"fe-panel-field\" *ngFor=\"let field of shownPanelFields(); trackBy: trackKey\">\r\n <span [title]=\"field.label\">{{ field.label }}</span>\r\n <ng-container [ngSwitch]=\"field.type\">\r\n <select *ngSwitchCase=\"'list'\" class=\"form-control\" [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\">\r\n <option value=\"\">Choisir…</option>\r\n <option *ngFor=\"let option of field.values\" [value]=\"option.value\">{{ option.label }}</option>\r\n </select>\r\n <select *ngSwitchCase=\"'bool'\" class=\"form-control\" [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\">\r\n <option value=\"\">Choisir…</option>\r\n <option value=\"true\">Oui</option>\r\n <option value=\"false\">Non</option>\r\n </select>\r\n <input *ngSwitchDefault class=\"form-control\" [type]=\"field.type === 'number' ? 'number' : field.type === 'date' ? 'date' : 'text'\"\r\n [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\" />\r\n </ng-container>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer le filtre de l'écran\" (click)=\"removePanelField(field)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n <!-- Ajout d'un filtre de l'écran : les champs du FilterPanel pas encore utilisés. -->\r\n <div class=\"fe-adds\" *ngIf=\"availablePanelFields().length\">\r\n <select class=\"form-control fe-add-panel\" [ngModel]=\"''\" (ngModelChange)=\"addPanelField($event)\">\r\n <option value=\"\">+ Filtre de l'écran</option>\r\n <option *ngFor=\"let field of availablePanelFields(); trackBy: trackKey\" [value]=\"field.key\">{{ field.label }}</option>\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"fe-panel-title\" *ngIf=\"panelFields.length || shownPanelFields().length\">Filtre additionnel</div>\r\n <ng-container *ngTemplateOutlet=\"groupTpl; context: { group: filter, parent: null, index: 0, depth: 0 }\"></ng-container>\r\n <div class=\"fe-summary\">{{ summary() }}</div>\r\n </div>\r\n\r\n <div class=\"fe-body\" *ngIf=\"shownTab === 'sort'\">\r\n <div class=\"fe-sort\" *ngFor=\"let level of sort; let i = index; trackBy: trackIndex\">\r\n <span class=\"fe-sort-label\">{{ i === 0 ? 'Trier par' : 'Puis par' }}</span>\r\n <select class=\"form-control\" [(ngModel)]=\"level.property\">\r\n <option *ngFor=\"let column of columns\" [value]=\"column.key\">{{ column.label }}</option>\r\n </select>\r\n <select class=\"form-control fe-sort-direction\" [(ngModel)]=\"level.direction\">\r\n <option value=\"asc\">Croissant</option>\r\n <option value=\"desc\">Décroissant</option>\r\n </select>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Monter\" [disabled]=\"i === 0\" (click)=\"moveSort(i, -1)\"><i class=\"fa fa-arrow-up\"></i></button>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Descendre\" [disabled]=\"i === sort.length - 1\" (click)=\"moveSort(i, 1)\"><i class=\"fa fa-arrow-down\"></i></button>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer\" (click)=\"removeSort(i)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n <div class=\"fe-adds\"><button type=\"button\" class=\"fe-add\" (click)=\"addSort()\">+ Niveau</button></div>\r\n </div>\r\n\r\n <div class=\"fe-foot\">\r\n <label class=\"fe-save\" *ngIf=\"!embedded\" [class.disabled]=\"!canSaveInView\"\r\n [title]=\"canSaveInView ? '' : 'La vue par défaut est en lecture seule : dupliquez-la pour y enregistrer un filtre'\">\r\n <input type=\"checkbox\" [(ngModel)]=\"saveInView\" [disabled]=\"!canSaveInView\" />\r\n <span>Enregistrer dans la vue{{ viewLabel ? ' « ' + viewLabel + ' »' : '' }}</span>\r\n </label>\r\n <button type=\"button\" class=\"fe-clear\" (click)=\"clear()\">Tout effacer</button>\r\n </div>\r\n</div>\r\n\r\n<!-- Groupe : relation ET / OU, conditions, groupes imbriqués. -->\r\n<ng-template #groupTpl let-group=\"group\" let-parent=\"parent\" let-index=\"index\" let-depth=\"depth\">\r\n <div class=\"fe-group\" [class.or]=\"group.Logic === 'or'\" [class.nested]=\"depth > 0\">\r\n <div class=\"fe-group-head\">\r\n <span class=\"fe-logic\">\r\n <button type=\"button\" [class.on]=\"group.Logic === 'and'\" class=\"and\" (click)=\"setLogic(group, 'and')\">ET</button>\r\n <button type=\"button\" [class.on]=\"group.Logic === 'or'\" class=\"or\" (click)=\"setLogic(group, 'or')\">OU</button>\r\n </span>\r\n <span class=\"fe-group-hint\">{{ group.Logic === 'and' ? 'Toutes les conditions' : 'Au moins une condition' }}</span>\r\n <button type=\"button\" *ngIf=\"parent\" class=\"fe-icon fe-group-remove\" title=\"Retirer le groupe\" (click)=\"removeGroup(parent, index)\">\r\n <i class=\"fa fa-times\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fe-cond\" *ngFor=\"let condition of group.Conditions; let i = index; trackBy: trackIndex\">\r\n <select class=\"form-control\" [(ngModel)]=\"condition.Property\" (ngModelChange)=\"onColumnChange(condition)\">\r\n <option *ngFor=\"let column of columns\" [value]=\"column.key\">{{ column.label }}</option>\r\n </select>\r\n <select class=\"form-control\" [(ngModel)]=\"condition.Operator\" (ngModelChange)=\"onOperatorChange(condition)\">\r\n <option *ngFor=\"let op of operatorsOf(condition)\" [value]=\"op.value\">{{ op.label }}</option>\r\n </select>\r\n <span class=\"fe-value\">\r\n <ng-container *ngIf=\"isList(condition); else valueTpl\">\r\n <span class=\"fe-chips\">\r\n <button type=\"button\" *ngFor=\"let option of columnOf(condition.Property)?.values\" class=\"fe-chip\"\r\n [class.on]=\"condition.Values?.includes(option.value)\" (click)=\"toggleValue(condition, option.value)\">{{ option.label }}</button>\r\n </span>\r\n </ng-container>\r\n <ng-template #valueTpl>\r\n <ng-container *ngIf=\"hasValue(condition)\">\r\n <input class=\"form-control\" [type]=\"inputType(condition)\" [(ngModel)]=\"condition.Value\" />\r\n <input *ngIf=\"hasSecondValue(condition)\" class=\"form-control\" [type]=\"inputType(condition)\" [(ngModel)]=\"condition.Value2\" />\r\n </ng-container>\r\n </ng-template>\r\n </span>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer la condition\" (click)=\"removeCondition(group, i)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n\r\n <ng-container *ngFor=\"let sub of group.Groups; let gi = index; trackBy: trackIndex\">\r\n <ng-container *ngTemplateOutlet=\"groupTpl; context: { group: sub, parent: group, index: gi, depth: depth + 1 }\"></ng-container>\r\n </ng-container>\r\n\r\n <div class=\"fe-adds\">\r\n <button type=\"button\" class=\"fe-add\" (click)=\"addCondition(group)\">+ Condition</button>\r\n <button type=\"button\" class=\"fe-add\" *ngIf=\"depth < maxDepth - 1\" (click)=\"addGroup(group)\">+ Groupe</button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n",
20327
- styles: [".home-page{font-family:Open sans,sans-serif;background:#fff;-webkit-font-smoothing:antialiased;height:100%;width:100%;padding:16px}.main-container{margin:0 50px}.main-container-modal{width:calc(100% - 50px);margin:10px 25px 0}.moyen-titre{font-weight:700;font-size:24px;color:#4d5a81;margin:8px 0;border-bottom:solid 1px #DBE4FF}.grand-titre{font-weight:700;font-size:28px;color:#4d5a81;margin:0 0 8px}.petit-titre{font-weight:700;font-size:16px;color:#4d5a81;margin:0 0 8px}.petit-titre.underlined{border-bottom:solid 1px #4D5A81}.paragraph{padding:0 15px}.paragraph-highlight{padding:5px 15px 0 12px;border-left:5px solid #8EA7F8;border-bottom:1px solid #DBE4FF;border-top:1px solid #DBE4FF;border-right:1px solid #DBE4FF;background-color:#f7faff}.highlight{background-color:#f7faff;border:1px solid #DBE4FF;border-radius:5px;padding:15px;color:#3c5dc4;margin:0 0 16px}.highlight p{margin-bottom:0}.highlight:before{position:relative;display:block;float:left;width:24px;height:24px;content:\" \";background-size:24px 24px;-webkit-background-size:24px 24px;background-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"53.294\" height=\"50.629\" viewBox=\"0 0 53.294 50.629\">%0D%0A <path id=\"allerg\\e8ne\" d=\"M830.494,25.793l-5.814,6.783.727,8.963-8.721,1.938-4.6,7.752L803.847,47.6l-8.236,3.634-4.6-7.51-8.721-1.938.727-8.963L777.2,26.035l5.814-6.783-.727-8.963,8.721-1.938L795.61.6l8.236,3.634L812.083.6l4.6,7.752,8.721,1.938-.727,8.963Zm-24.467,2.422V13.681h-4.845V28.216Zm0,9.69V33.06h-4.845v4.845Z\" transform=\"translate(-777.2 -0.6)\"/>%0D%0A</svg>%0D%0A');background-repeat:no-repeat;margin:0 8px 24px 0;filter:invert(31%) sepia(51%) saturate(1323%) hue-rotate(199deg) brightness(99%) contrast(94%)}.notification{background-color:#dbe4ff;border:1px solid #C4D0F9;border-radius:5px;color:#4d5a81;margin:16px;padding:5px 15px;text-align:justify}.notification:before{position:relative;display:block;float:left;width:24px;height:24px;content:\" \";background-size:24px 24px;-webkit-background-size:24px 24px;background-image:url('data:image/svg+xml,<svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"fas\" data-icon=\"info-circle\" class=\"svg-inline--fa fa-info-circle fa-w-16\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path fill=\"currentColor\" d=\"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"></path></svg>');background-repeat:no-repeat;margin:0 8px 0 0;filter:invert(31%) sepia(8%) saturate(2329%) hue-rotate(188deg) brightness(103%) contrast(85%)}.notification-text{padding:0 15px 0 30px;font-size:16px}.fe-panel{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(260px,100%),1fr));gap:6px 12px;margin-bottom:12px}.fe-panel .fe-adds{grid-column:1/-1}.fe-add-panel{width:auto;border-style:dashed;color:#4465c9}.fe-panel-title{grid-column:1/-1;margin:4px 0 2px;font-weight:600}.fe-panel-field{display:grid;grid-template-columns:120px minmax(0,1fr) auto;align-items:center;gap:8px;margin:0;font-weight:400}.fe-panel-field>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fe{display:flex;flex-direction:column;color:#4d5a81;font-size:13px}.fe-tabs{display:flex;gap:4px;padding:8px 14px 0;border-bottom:1px solid #DBE4FF}.fe-tab{padding:6px 12px;border:none;border-bottom:2px solid transparent;background:none;color:#9fa9c7;font:inherit;font-weight:700;cursor:pointer}.fe-tab.active{color:#4465c9;border-bottom-color:#5272d3}.fe-body{display:flex;flex-direction:column;gap:10px;max-height:60vh;overflow-y:auto;padding:12px 14px}.fe-group{display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid #DBE4FF;border-left:4px solid #3b57b8;border-radius:0 4px 4px 0;background:#fff}.fe-group.or{border-left-color:#e07b12}.fe-group.nested{background:#f6f8fd}.fe-group-head{display:flex;align-items:center;gap:8px;font-size:12px;color:#9fa9c7}.fe-group-remove{margin-left:auto}.fe-logic{display:inline-flex;border:1px solid #DBE4FF;border-radius:999px;overflow:hidden}.fe-logic button{padding:2px 10px;border:none;background:none;color:#9fa9c7;font:inherit;font-size:11px;font-weight:800;cursor:pointer}.fe-logic button.on.and{background:#3b57b8;color:#fff}.fe-logic button.on.or{background:#e07b12;color:#fff}.fe-cond{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) minmax(0,1.4fr) 28px;gap:6px;align-items:center;padding:4px 6px;border:1px solid #DBE4FF;border-left:3px solid #3b57b8;border-radius:0 4px 4px 0;background:#fff}.fe-group.or>.fe-cond{border-left-color:#e07b12}@media(max-width:600px){.fe-cond{grid-template-columns:minmax(0,1fr) minmax(0,1fr) 28px}.fe-cond .fe-value{grid-column:1/3}}select.form-control,input.form-control{height:30px;min-width:0;padding:2px 6px;font-size:13px}.fe-value{display:flex;gap:6px;min-width:0}.fe-value input{flex:1}.fe-chips{display:flex;flex-wrap:wrap;gap:4px}.fe-chip{padding:2px 8px;border:1px solid #C1D0FD;border-radius:999px;background:#fff;color:#4d5a81;font:inherit;font-size:12px;cursor:pointer}.fe-chip.on{background:#5272d3;border-color:#5272d3;color:#fff}.fe-icon{width:28px;height:28px;padding:0;border:none;border-radius:6px;background:none;color:#9fa9c7;cursor:pointer}.fe-icon:hover:not(:disabled){background:#ebf0ff;color:#4d5a81}.fe-icon:disabled{opacity:.3;cursor:default}.fe-adds{display:flex;gap:8px;flex-wrap:wrap}.fe-add{padding:3px 10px;border:1px dashed #C1D0FD;border-radius:6px;background:none;color:#4465c9;font:inherit;font-size:12px;cursor:pointer}.fe-summary{padding:8px 10px;border-radius:6px;background:#ebf0ff;font-size:12px;word-break:break-word}.fe-sort{display:grid;grid-template-columns:64px minmax(0,1fr) 120px 28px 28px 28px;gap:6px;align-items:center}.fe-sort-label{font-size:12px;color:#9fa9c7}.fe-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 14px;border-top:1px solid #DBE4FF}.fe-save{display:inline-flex;align-items:center;gap:6px;margin:0;font-weight:400;cursor:pointer}.fe-save.disabled{opacity:.55;cursor:default}.fe-save input{margin:0}.fe-clear{border:none;background:none;color:#4465c9;font:inherit;cursor:pointer}\n"],
20342
+ template: "<div class=\"fe\">\r\n <div class=\"fe-tabs\" role=\"tablist\" *ngIf=\"!section\">\r\n <button type=\"button\" class=\"fe-tab\" [class.active]=\"tab === 'filters'\" (click)=\"tab = 'filters'\">Filtres</button>\r\n <button type=\"button\" class=\"fe-tab\" [class.active]=\"tab === 'sort'\" (click)=\"tab = 'sort'\">Tri</button>\r\n </div>\r\n\r\n <div class=\"fe-body\" *ngIf=\"shownTab === 'filters'\">\r\n <!-- Filtres de l'écran (FilterPanel) : valeurs enregistrées avec la vue, appliquées au FilterPanel. -->\r\n <div class=\"fe-panel\" *ngIf=\"panelFields.length || shownPanelFields().length\">\r\n <div class=\"fe-panel-title\">Filtres de l'écran</div>\r\n <div class=\"fe-panel-field\" *ngFor=\"let field of shownPanelFields(); trackBy: trackKey\">\r\n <span [title]=\"field.label\">{{ field.label }}</span>\r\n <ng-container [ngSwitch]=\"field.type\">\r\n <select *ngSwitchCase=\"'list'\" class=\"form-control\" [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\">\r\n <option value=\"\">Choisir…</option>\r\n <option *ngFor=\"let option of field.values\" [value]=\"option.value\">{{ option.label }}</option>\r\n </select>\r\n <select *ngSwitchCase=\"'bool'\" class=\"form-control\" [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\">\r\n <option value=\"\">Choisir…</option>\r\n <option value=\"true\">Oui</option>\r\n <option value=\"false\">Non</option>\r\n </select>\r\n <input *ngSwitchDefault class=\"form-control\" [type]=\"field.type === 'number' ? 'number' : field.type === 'date' ? 'date' : 'text'\"\r\n [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\" />\r\n </ng-container>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer le filtre de l'écran\" (click)=\"removePanelField(field)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n <!-- Ajout d'un filtre de l'écran : les champs du FilterPanel pas encore utilisés. -->\r\n <div class=\"fe-adds\" *ngIf=\"availablePanelFields().length\">\r\n <select class=\"form-control fe-add-panel\" [ngModel]=\"''\" (ngModelChange)=\"addPanelField($event)\">\r\n <option value=\"\">+ Filtre de l'écran</option>\r\n <option *ngFor=\"let field of availablePanelFields(); trackBy: trackKey\" [value]=\"field.key\">{{ field.label }}</option>\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"fe-panel-title\" *ngIf=\"panelFields.length || shownPanelFields().length\">Filtre additionnel</div>\r\n <ng-container *ngTemplateOutlet=\"groupTpl; context: { group: filter, parent: null, index: 0, depth: 0 }\"></ng-container>\r\n <div class=\"fe-summary\">{{ summary() }}</div>\r\n </div>\r\n\r\n <div class=\"fe-body\" *ngIf=\"shownTab === 'sort'\">\r\n <div class=\"fe-sort\" *ngFor=\"let level of sort; let i = index; trackBy: trackIndex\">\r\n <span class=\"fe-sort-label\">{{ i === 0 ? 'Trier par' : 'Puis par' }}</span>\r\n <select class=\"form-control\" [(ngModel)]=\"level.property\">\r\n <option *ngFor=\"let column of columns\" [value]=\"column.key\">{{ column.label }}</option>\r\n </select>\r\n <select class=\"form-control fe-sort-direction\" [(ngModel)]=\"level.direction\">\r\n <option value=\"asc\">Croissant</option>\r\n <option value=\"desc\">Décroissant</option>\r\n </select>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Monter\" [disabled]=\"i === 0\" (click)=\"moveSort(i, -1)\"><i class=\"fa fa-arrow-up\"></i></button>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Descendre\" [disabled]=\"i === sort.length - 1\" (click)=\"moveSort(i, 1)\"><i class=\"fa fa-arrow-down\"></i></button>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer\" (click)=\"removeSort(i)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n <div class=\"fe-adds\"><button type=\"button\" class=\"fe-add\" (click)=\"addSort()\">+ Niveau</button></div>\r\n </div>\r\n\r\n <div class=\"fe-foot\">\r\n <label class=\"fe-save\" *ngIf=\"!embedded\" [class.disabled]=\"!canSaveInView\"\r\n [title]=\"canSaveInView ? '' : 'La vue par défaut est en lecture seule : dupliquez-la pour y enregistrer un filtre'\">\r\n <input type=\"checkbox\" [(ngModel)]=\"saveInView\" [disabled]=\"!canSaveInView\" />\r\n <span>Enregistrer dans la vue{{ viewLabel ? ' « ' + viewLabel + ' »' : '' }}</span>\r\n </label>\r\n <button type=\"button\" class=\"fe-clear\" (click)=\"clear()\">Tout effacer</button>\r\n </div>\r\n</div>\r\n\r\n<!-- Groupe : relation ET / OU, conditions, groupes imbriqués. -->\r\n<ng-template #groupTpl let-group=\"group\" let-parent=\"parent\" let-index=\"index\" let-depth=\"depth\">\r\n <div class=\"fe-group\" [class.or]=\"group.Logic === 'or'\" [class.nested]=\"depth > 0\">\r\n <div class=\"fe-group-head\">\r\n <span class=\"fe-logic\">\r\n <button type=\"button\" [class.on]=\"group.Logic === 'and'\" class=\"and\" (click)=\"setLogic(group, 'and')\">ET</button>\r\n <button type=\"button\" [class.on]=\"group.Logic === 'or'\" class=\"or\" (click)=\"setLogic(group, 'or')\">OU</button>\r\n </span>\r\n <span class=\"fe-group-hint\">{{ group.Logic === 'and' ? 'Toutes les conditions' : 'Au moins une condition' }}</span>\r\n <button type=\"button\" *ngIf=\"parent\" class=\"fe-icon fe-group-remove\" title=\"Retirer le groupe\" (click)=\"removeGroup(parent, index)\">\r\n <i class=\"fa fa-times\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fe-cond\" *ngFor=\"let condition of group.Conditions; let i = index; trackBy: trackIndex\">\r\n <select class=\"form-control\" [(ngModel)]=\"condition.Property\" (ngModelChange)=\"onColumnChange(condition)\">\r\n <option *ngFor=\"let column of columns\" [value]=\"column.key\">{{ column.label }}</option>\r\n </select>\r\n <select class=\"form-control\" [(ngModel)]=\"condition.Operator\" (ngModelChange)=\"onOperatorChange(condition)\">\r\n <option *ngFor=\"let op of operatorsOf(condition)\" [value]=\"op.value\">{{ op.label }}</option>\r\n </select>\r\n <span class=\"fe-value\">\r\n <ng-container *ngIf=\"isList(condition); else valueTpl\">\r\n <span class=\"fe-chips\" *ngIf=\"hasKnownValues(condition); else typedValuesTpl\">\r\n <button type=\"button\" *ngFor=\"let option of columnOf(condition.Property)?.values\" class=\"fe-chip\"\r\n [class.on]=\"condition.Values?.includes(option.value)\" (click)=\"toggleValue(condition, option.value)\">{{ option.label }}</button>\r\n </span>\r\n <!-- Texte, nombre : valeurs saisies une à une (ou cochées par le « Filtre avancé » de la grille). -->\r\n <ng-template #typedValuesTpl>\r\n <span class=\"fe-chips\">\r\n <button type=\"button\" *ngFor=\"let value of condition.Values\" class=\"fe-chip on\" title=\"Retirer cette valeur\"\r\n (click)=\"removeValue(condition, value)\">{{ value }} <i class=\"fa fa-times\"></i></button>\r\n <input #valueInput class=\"form-control fe-chip-input\" [type]=\"inputType(condition)\" placeholder=\"Ajouter une valeur\"\r\n (keydown.enter)=\"addValue(condition, valueInput); $event.preventDefault()\" (blur)=\"addValue(condition, valueInput)\" />\r\n </span>\r\n </ng-template>\r\n </ng-container>\r\n <ng-template #valueTpl>\r\n <ng-container *ngIf=\"hasValue(condition)\">\r\n <input class=\"form-control\" [type]=\"inputType(condition)\" [(ngModel)]=\"condition.Value\" />\r\n <input *ngIf=\"hasSecondValue(condition)\" class=\"form-control\" [type]=\"inputType(condition)\" [(ngModel)]=\"condition.Value2\" />\r\n </ng-container>\r\n </ng-template>\r\n </span>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer la condition\" (click)=\"removeCondition(group, i)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n\r\n <ng-container *ngFor=\"let sub of group.Groups; let gi = index; trackBy: trackIndex\">\r\n <ng-container *ngTemplateOutlet=\"groupTpl; context: { group: sub, parent: group, index: gi, depth: depth + 1 }\"></ng-container>\r\n </ng-container>\r\n\r\n <div class=\"fe-adds\">\r\n <button type=\"button\" class=\"fe-add\" (click)=\"addCondition(group)\">+ Condition</button>\r\n <button type=\"button\" class=\"fe-add\" *ngIf=\"depth < maxDepth - 1\" (click)=\"addGroup(group)\">+ Groupe</button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n",
20343
+ styles: [".home-page{font-family:Open sans,sans-serif;background:#fff;-webkit-font-smoothing:antialiased;height:100%;width:100%;padding:16px}.main-container{margin:0 50px}.main-container-modal{width:calc(100% - 50px);margin:10px 25px 0}.moyen-titre{font-weight:700;font-size:24px;color:#4d5a81;margin:8px 0;border-bottom:solid 1px #DBE4FF}.grand-titre{font-weight:700;font-size:28px;color:#4d5a81;margin:0 0 8px}.petit-titre{font-weight:700;font-size:16px;color:#4d5a81;margin:0 0 8px}.petit-titre.underlined{border-bottom:solid 1px #4D5A81}.paragraph{padding:0 15px}.paragraph-highlight{padding:5px 15px 0 12px;border-left:5px solid #8EA7F8;border-bottom:1px solid #DBE4FF;border-top:1px solid #DBE4FF;border-right:1px solid #DBE4FF;background-color:#f7faff}.highlight{background-color:#f7faff;border:1px solid #DBE4FF;border-radius:5px;padding:15px;color:#3c5dc4;margin:0 0 16px}.highlight p{margin-bottom:0}.highlight:before{position:relative;display:block;float:left;width:24px;height:24px;content:\" \";background-size:24px 24px;-webkit-background-size:24px 24px;background-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"53.294\" height=\"50.629\" viewBox=\"0 0 53.294 50.629\">%0D%0A <path id=\"allerg\\e8ne\" d=\"M830.494,25.793l-5.814,6.783.727,8.963-8.721,1.938-4.6,7.752L803.847,47.6l-8.236,3.634-4.6-7.51-8.721-1.938.727-8.963L777.2,26.035l5.814-6.783-.727-8.963,8.721-1.938L795.61.6l8.236,3.634L812.083.6l4.6,7.752,8.721,1.938-.727,8.963Zm-24.467,2.422V13.681h-4.845V28.216Zm0,9.69V33.06h-4.845v4.845Z\" transform=\"translate(-777.2 -0.6)\"/>%0D%0A</svg>%0D%0A');background-repeat:no-repeat;margin:0 8px 24px 0;filter:invert(31%) sepia(51%) saturate(1323%) hue-rotate(199deg) brightness(99%) contrast(94%)}.notification{background-color:#dbe4ff;border:1px solid #C4D0F9;border-radius:5px;color:#4d5a81;margin:16px;padding:5px 15px;text-align:justify}.notification:before{position:relative;display:block;float:left;width:24px;height:24px;content:\" \";background-size:24px 24px;-webkit-background-size:24px 24px;background-image:url('data:image/svg+xml,<svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"fas\" data-icon=\"info-circle\" class=\"svg-inline--fa fa-info-circle fa-w-16\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path fill=\"currentColor\" d=\"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"></path></svg>');background-repeat:no-repeat;margin:0 8px 0 0;filter:invert(31%) sepia(8%) saturate(2329%) hue-rotate(188deg) brightness(103%) contrast(85%)}.notification-text{padding:0 15px 0 30px;font-size:16px}.fe-panel{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(260px,100%),1fr));gap:6px 12px;margin-bottom:12px}.fe-panel .fe-adds{grid-column:1/-1}.fe-add-panel{width:auto;border-style:dashed;color:#4465c9}.fe-panel-title{grid-column:1/-1;margin:4px 0 2px;font-weight:600}.fe-panel-field{display:grid;grid-template-columns:120px minmax(0,1fr) auto;align-items:center;gap:8px;margin:0;font-weight:400}.fe-panel-field>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fe{display:flex;flex-direction:column;color:#4d5a81;font-size:13px}.fe-tabs{display:flex;gap:4px;padding:8px 14px 0;border-bottom:1px solid #DBE4FF}.fe-tab{padding:6px 12px;border:none;border-bottom:2px solid transparent;background:none;color:#9fa9c7;font:inherit;font-weight:700;cursor:pointer}.fe-tab.active{color:#4465c9;border-bottom-color:#5272d3}.fe-body{display:flex;flex-direction:column;gap:10px;max-height:60vh;overflow-y:auto;padding:12px 14px}.fe-group{display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid #DBE4FF;border-left:4px solid #3b57b8;border-radius:0 4px 4px 0;background:#fff}.fe-group.or{border-left-color:#e07b12}.fe-group.nested{background:#f6f8fd}.fe-group-head{display:flex;align-items:center;gap:8px;font-size:12px;color:#9fa9c7}.fe-group-remove{margin-left:auto}.fe-logic{display:inline-flex;border:1px solid #DBE4FF;border-radius:999px;overflow:hidden}.fe-logic button{padding:2px 10px;border:none;background:none;color:#9fa9c7;font:inherit;font-size:11px;font-weight:800;cursor:pointer}.fe-logic button.on.and{background:#3b57b8;color:#fff}.fe-logic button.on.or{background:#e07b12;color:#fff}.fe-cond{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) minmax(0,1.4fr) 28px;gap:6px;align-items:center;padding:4px 6px;border:1px solid #DBE4FF;border-left:3px solid #3b57b8;border-radius:0 4px 4px 0;background:#fff}.fe-group.or>.fe-cond{border-left-color:#e07b12}@media(max-width:600px){.fe-cond{grid-template-columns:minmax(0,1fr) minmax(0,1fr) 28px}.fe-cond .fe-value{grid-column:1/3}}select.form-control,input.form-control{height:30px;min-width:0;padding:2px 6px;font-size:13px}.fe-value{display:flex;gap:6px;min-width:0}.fe-value input{flex:1}.fe-chips{display:flex;flex-wrap:wrap;gap:4px}.fe-chip{padding:2px 8px;border:1px solid #C1D0FD;border-radius:999px;background:#fff;color:#4d5a81;font:inherit;font-size:12px;cursor:pointer}.fe-chip.on{background:#5272d3;border-color:#5272d3;color:#fff}.fe-chip i{margin-left:2px;font-size:10px}.fe-chip-input{flex:1;min-width:120px}.fe-icon{width:28px;height:28px;padding:0;border:none;border-radius:6px;background:none;color:#9fa9c7;cursor:pointer}.fe-icon:hover:not(:disabled){background:#ebf0ff;color:#4d5a81}.fe-icon:disabled{opacity:.3;cursor:default}.fe-adds{display:flex;gap:8px;flex-wrap:wrap}.fe-add{padding:3px 10px;border:1px dashed #C1D0FD;border-radius:6px;background:none;color:#4465c9;font:inherit;font-size:12px;cursor:pointer}.fe-summary{padding:8px 10px;border-radius:6px;background:#ebf0ff;font-size:12px;word-break:break-word}.fe-sort{display:grid;grid-template-columns:64px minmax(0,1fr) 120px 28px 28px 28px;gap:6px;align-items:center}.fe-sort-label{font-size:12px;color:#9fa9c7}.fe-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 14px;border-top:1px solid #DBE4FF}.fe-save{display:inline-flex;align-items:center;gap:6px;margin:0;font-weight:400;cursor:pointer}.fe-save.disabled{opacity:.55;cursor:default}.fe-save input{margin:0}.fe-clear{border:none;background:none;color:#4465c9;font:inherit;cursor:pointer}\n"],
20328
20344
  dependencies: [
20329
20345
  {
20330
20346
  kind: "ngmodule",
@@ -20444,8 +20460,8 @@ i0.ɵɵngDeclareClassMetadata({
20444
20460
  standalone: true,
20445
20461
  imports: [CommonModule, FormsModule],
20446
20462
  changeDetection: ChangeDetectionStrategy.Eager,
20447
- template: "<div class=\"fe\">\r\n <div class=\"fe-tabs\" role=\"tablist\" *ngIf=\"!section\">\r\n <button type=\"button\" class=\"fe-tab\" [class.active]=\"tab === 'filters'\" (click)=\"tab = 'filters'\">Filtres</button>\r\n <button type=\"button\" class=\"fe-tab\" [class.active]=\"tab === 'sort'\" (click)=\"tab = 'sort'\">Tri</button>\r\n </div>\r\n\r\n <div class=\"fe-body\" *ngIf=\"shownTab === 'filters'\">\r\n <!-- Filtres de l'écran (FilterPanel) : valeurs enregistrées avec la vue, appliquées au FilterPanel. -->\r\n <div class=\"fe-panel\" *ngIf=\"panelFields.length || shownPanelFields().length\">\r\n <div class=\"fe-panel-title\">Filtres de l'écran</div>\r\n <div class=\"fe-panel-field\" *ngFor=\"let field of shownPanelFields(); trackBy: trackKey\">\r\n <span [title]=\"field.label\">{{ field.label }}</span>\r\n <ng-container [ngSwitch]=\"field.type\">\r\n <select *ngSwitchCase=\"'list'\" class=\"form-control\" [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\">\r\n <option value=\"\">Choisir…</option>\r\n <option *ngFor=\"let option of field.values\" [value]=\"option.value\">{{ option.label }}</option>\r\n </select>\r\n <select *ngSwitchCase=\"'bool'\" class=\"form-control\" [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\">\r\n <option value=\"\">Choisir…</option>\r\n <option value=\"true\">Oui</option>\r\n <option value=\"false\">Non</option>\r\n </select>\r\n <input *ngSwitchDefault class=\"form-control\" [type]=\"field.type === 'number' ? 'number' : field.type === 'date' ? 'date' : 'text'\"\r\n [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\" />\r\n </ng-container>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer le filtre de l'écran\" (click)=\"removePanelField(field)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n <!-- Ajout d'un filtre de l'écran : les champs du FilterPanel pas encore utilisés. -->\r\n <div class=\"fe-adds\" *ngIf=\"availablePanelFields().length\">\r\n <select class=\"form-control fe-add-panel\" [ngModel]=\"''\" (ngModelChange)=\"addPanelField($event)\">\r\n <option value=\"\">+ Filtre de l'écran</option>\r\n <option *ngFor=\"let field of availablePanelFields(); trackBy: trackKey\" [value]=\"field.key\">{{ field.label }}</option>\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"fe-panel-title\" *ngIf=\"panelFields.length || shownPanelFields().length\">Filtre additionnel</div>\r\n <ng-container *ngTemplateOutlet=\"groupTpl; context: { group: filter, parent: null, index: 0, depth: 0 }\"></ng-container>\r\n <div class=\"fe-summary\">{{ summary() }}</div>\r\n </div>\r\n\r\n <div class=\"fe-body\" *ngIf=\"shownTab === 'sort'\">\r\n <div class=\"fe-sort\" *ngFor=\"let level of sort; let i = index; trackBy: trackIndex\">\r\n <span class=\"fe-sort-label\">{{ i === 0 ? 'Trier par' : 'Puis par' }}</span>\r\n <select class=\"form-control\" [(ngModel)]=\"level.property\">\r\n <option *ngFor=\"let column of columns\" [value]=\"column.key\">{{ column.label }}</option>\r\n </select>\r\n <select class=\"form-control fe-sort-direction\" [(ngModel)]=\"level.direction\">\r\n <option value=\"asc\">Croissant</option>\r\n <option value=\"desc\">Décroissant</option>\r\n </select>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Monter\" [disabled]=\"i === 0\" (click)=\"moveSort(i, -1)\"><i class=\"fa fa-arrow-up\"></i></button>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Descendre\" [disabled]=\"i === sort.length - 1\" (click)=\"moveSort(i, 1)\"><i class=\"fa fa-arrow-down\"></i></button>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer\" (click)=\"removeSort(i)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n <div class=\"fe-adds\"><button type=\"button\" class=\"fe-add\" (click)=\"addSort()\">+ Niveau</button></div>\r\n </div>\r\n\r\n <div class=\"fe-foot\">\r\n <label class=\"fe-save\" *ngIf=\"!embedded\" [class.disabled]=\"!canSaveInView\"\r\n [title]=\"canSaveInView ? '' : 'La vue par défaut est en lecture seule : dupliquez-la pour y enregistrer un filtre'\">\r\n <input type=\"checkbox\" [(ngModel)]=\"saveInView\" [disabled]=\"!canSaveInView\" />\r\n <span>Enregistrer dans la vue{{ viewLabel ? ' « ' + viewLabel + ' »' : '' }}</span>\r\n </label>\r\n <button type=\"button\" class=\"fe-clear\" (click)=\"clear()\">Tout effacer</button>\r\n </div>\r\n</div>\r\n\r\n<!-- Groupe : relation ET / OU, conditions, groupes imbriqués. -->\r\n<ng-template #groupTpl let-group=\"group\" let-parent=\"parent\" let-index=\"index\" let-depth=\"depth\">\r\n <div class=\"fe-group\" [class.or]=\"group.Logic === 'or'\" [class.nested]=\"depth > 0\">\r\n <div class=\"fe-group-head\">\r\n <span class=\"fe-logic\">\r\n <button type=\"button\" [class.on]=\"group.Logic === 'and'\" class=\"and\" (click)=\"setLogic(group, 'and')\">ET</button>\r\n <button type=\"button\" [class.on]=\"group.Logic === 'or'\" class=\"or\" (click)=\"setLogic(group, 'or')\">OU</button>\r\n </span>\r\n <span class=\"fe-group-hint\">{{ group.Logic === 'and' ? 'Toutes les conditions' : 'Au moins une condition' }}</span>\r\n <button type=\"button\" *ngIf=\"parent\" class=\"fe-icon fe-group-remove\" title=\"Retirer le groupe\" (click)=\"removeGroup(parent, index)\">\r\n <i class=\"fa fa-times\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fe-cond\" *ngFor=\"let condition of group.Conditions; let i = index; trackBy: trackIndex\">\r\n <select class=\"form-control\" [(ngModel)]=\"condition.Property\" (ngModelChange)=\"onColumnChange(condition)\">\r\n <option *ngFor=\"let column of columns\" [value]=\"column.key\">{{ column.label }}</option>\r\n </select>\r\n <select class=\"form-control\" [(ngModel)]=\"condition.Operator\" (ngModelChange)=\"onOperatorChange(condition)\">\r\n <option *ngFor=\"let op of operatorsOf(condition)\" [value]=\"op.value\">{{ op.label }}</option>\r\n </select>\r\n <span class=\"fe-value\">\r\n <ng-container *ngIf=\"isList(condition); else valueTpl\">\r\n <span class=\"fe-chips\">\r\n <button type=\"button\" *ngFor=\"let option of columnOf(condition.Property)?.values\" class=\"fe-chip\"\r\n [class.on]=\"condition.Values?.includes(option.value)\" (click)=\"toggleValue(condition, option.value)\">{{ option.label }}</button>\r\n </span>\r\n </ng-container>\r\n <ng-template #valueTpl>\r\n <ng-container *ngIf=\"hasValue(condition)\">\r\n <input class=\"form-control\" [type]=\"inputType(condition)\" [(ngModel)]=\"condition.Value\" />\r\n <input *ngIf=\"hasSecondValue(condition)\" class=\"form-control\" [type]=\"inputType(condition)\" [(ngModel)]=\"condition.Value2\" />\r\n </ng-container>\r\n </ng-template>\r\n </span>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer la condition\" (click)=\"removeCondition(group, i)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n\r\n <ng-container *ngFor=\"let sub of group.Groups; let gi = index; trackBy: trackIndex\">\r\n <ng-container *ngTemplateOutlet=\"groupTpl; context: { group: sub, parent: group, index: gi, depth: depth + 1 }\"></ng-container>\r\n </ng-container>\r\n\r\n <div class=\"fe-adds\">\r\n <button type=\"button\" class=\"fe-add\" (click)=\"addCondition(group)\">+ Condition</button>\r\n <button type=\"button\" class=\"fe-add\" *ngIf=\"depth < maxDepth - 1\" (click)=\"addGroup(group)\">+ Groupe</button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n",
20448
- styles: [".home-page{font-family:Open sans,sans-serif;background:#fff;-webkit-font-smoothing:antialiased;height:100%;width:100%;padding:16px}.main-container{margin:0 50px}.main-container-modal{width:calc(100% - 50px);margin:10px 25px 0}.moyen-titre{font-weight:700;font-size:24px;color:#4d5a81;margin:8px 0;border-bottom:solid 1px #DBE4FF}.grand-titre{font-weight:700;font-size:28px;color:#4d5a81;margin:0 0 8px}.petit-titre{font-weight:700;font-size:16px;color:#4d5a81;margin:0 0 8px}.petit-titre.underlined{border-bottom:solid 1px #4D5A81}.paragraph{padding:0 15px}.paragraph-highlight{padding:5px 15px 0 12px;border-left:5px solid #8EA7F8;border-bottom:1px solid #DBE4FF;border-top:1px solid #DBE4FF;border-right:1px solid #DBE4FF;background-color:#f7faff}.highlight{background-color:#f7faff;border:1px solid #DBE4FF;border-radius:5px;padding:15px;color:#3c5dc4;margin:0 0 16px}.highlight p{margin-bottom:0}.highlight:before{position:relative;display:block;float:left;width:24px;height:24px;content:\" \";background-size:24px 24px;-webkit-background-size:24px 24px;background-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"53.294\" height=\"50.629\" viewBox=\"0 0 53.294 50.629\">%0D%0A <path id=\"allerg\\e8ne\" d=\"M830.494,25.793l-5.814,6.783.727,8.963-8.721,1.938-4.6,7.752L803.847,47.6l-8.236,3.634-4.6-7.51-8.721-1.938.727-8.963L777.2,26.035l5.814-6.783-.727-8.963,8.721-1.938L795.61.6l8.236,3.634L812.083.6l4.6,7.752,8.721,1.938-.727,8.963Zm-24.467,2.422V13.681h-4.845V28.216Zm0,9.69V33.06h-4.845v4.845Z\" transform=\"translate(-777.2 -0.6)\"/>%0D%0A</svg>%0D%0A');background-repeat:no-repeat;margin:0 8px 24px 0;filter:invert(31%) sepia(51%) saturate(1323%) hue-rotate(199deg) brightness(99%) contrast(94%)}.notification{background-color:#dbe4ff;border:1px solid #C4D0F9;border-radius:5px;color:#4d5a81;margin:16px;padding:5px 15px;text-align:justify}.notification:before{position:relative;display:block;float:left;width:24px;height:24px;content:\" \";background-size:24px 24px;-webkit-background-size:24px 24px;background-image:url('data:image/svg+xml,<svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"fas\" data-icon=\"info-circle\" class=\"svg-inline--fa fa-info-circle fa-w-16\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path fill=\"currentColor\" d=\"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"></path></svg>');background-repeat:no-repeat;margin:0 8px 0 0;filter:invert(31%) sepia(8%) saturate(2329%) hue-rotate(188deg) brightness(103%) contrast(85%)}.notification-text{padding:0 15px 0 30px;font-size:16px}.fe-panel{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(260px,100%),1fr));gap:6px 12px;margin-bottom:12px}.fe-panel .fe-adds{grid-column:1/-1}.fe-add-panel{width:auto;border-style:dashed;color:#4465c9}.fe-panel-title{grid-column:1/-1;margin:4px 0 2px;font-weight:600}.fe-panel-field{display:grid;grid-template-columns:120px minmax(0,1fr) auto;align-items:center;gap:8px;margin:0;font-weight:400}.fe-panel-field>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fe{display:flex;flex-direction:column;color:#4d5a81;font-size:13px}.fe-tabs{display:flex;gap:4px;padding:8px 14px 0;border-bottom:1px solid #DBE4FF}.fe-tab{padding:6px 12px;border:none;border-bottom:2px solid transparent;background:none;color:#9fa9c7;font:inherit;font-weight:700;cursor:pointer}.fe-tab.active{color:#4465c9;border-bottom-color:#5272d3}.fe-body{display:flex;flex-direction:column;gap:10px;max-height:60vh;overflow-y:auto;padding:12px 14px}.fe-group{display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid #DBE4FF;border-left:4px solid #3b57b8;border-radius:0 4px 4px 0;background:#fff}.fe-group.or{border-left-color:#e07b12}.fe-group.nested{background:#f6f8fd}.fe-group-head{display:flex;align-items:center;gap:8px;font-size:12px;color:#9fa9c7}.fe-group-remove{margin-left:auto}.fe-logic{display:inline-flex;border:1px solid #DBE4FF;border-radius:999px;overflow:hidden}.fe-logic button{padding:2px 10px;border:none;background:none;color:#9fa9c7;font:inherit;font-size:11px;font-weight:800;cursor:pointer}.fe-logic button.on.and{background:#3b57b8;color:#fff}.fe-logic button.on.or{background:#e07b12;color:#fff}.fe-cond{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) minmax(0,1.4fr) 28px;gap:6px;align-items:center;padding:4px 6px;border:1px solid #DBE4FF;border-left:3px solid #3b57b8;border-radius:0 4px 4px 0;background:#fff}.fe-group.or>.fe-cond{border-left-color:#e07b12}@media(max-width:600px){.fe-cond{grid-template-columns:minmax(0,1fr) minmax(0,1fr) 28px}.fe-cond .fe-value{grid-column:1/3}}select.form-control,input.form-control{height:30px;min-width:0;padding:2px 6px;font-size:13px}.fe-value{display:flex;gap:6px;min-width:0}.fe-value input{flex:1}.fe-chips{display:flex;flex-wrap:wrap;gap:4px}.fe-chip{padding:2px 8px;border:1px solid #C1D0FD;border-radius:999px;background:#fff;color:#4d5a81;font:inherit;font-size:12px;cursor:pointer}.fe-chip.on{background:#5272d3;border-color:#5272d3;color:#fff}.fe-icon{width:28px;height:28px;padding:0;border:none;border-radius:6px;background:none;color:#9fa9c7;cursor:pointer}.fe-icon:hover:not(:disabled){background:#ebf0ff;color:#4d5a81}.fe-icon:disabled{opacity:.3;cursor:default}.fe-adds{display:flex;gap:8px;flex-wrap:wrap}.fe-add{padding:3px 10px;border:1px dashed #C1D0FD;border-radius:6px;background:none;color:#4465c9;font:inherit;font-size:12px;cursor:pointer}.fe-summary{padding:8px 10px;border-radius:6px;background:#ebf0ff;font-size:12px;word-break:break-word}.fe-sort{display:grid;grid-template-columns:64px minmax(0,1fr) 120px 28px 28px 28px;gap:6px;align-items:center}.fe-sort-label{font-size:12px;color:#9fa9c7}.fe-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 14px;border-top:1px solid #DBE4FF}.fe-save{display:inline-flex;align-items:center;gap:6px;margin:0;font-weight:400;cursor:pointer}.fe-save.disabled{opacity:.55;cursor:default}.fe-save input{margin:0}.fe-clear{border:none;background:none;color:#4465c9;font:inherit;cursor:pointer}\n"]
20463
+ template: "<div class=\"fe\">\r\n <div class=\"fe-tabs\" role=\"tablist\" *ngIf=\"!section\">\r\n <button type=\"button\" class=\"fe-tab\" [class.active]=\"tab === 'filters'\" (click)=\"tab = 'filters'\">Filtres</button>\r\n <button type=\"button\" class=\"fe-tab\" [class.active]=\"tab === 'sort'\" (click)=\"tab = 'sort'\">Tri</button>\r\n </div>\r\n\r\n <div class=\"fe-body\" *ngIf=\"shownTab === 'filters'\">\r\n <!-- Filtres de l'écran (FilterPanel) : valeurs enregistrées avec la vue, appliquées au FilterPanel. -->\r\n <div class=\"fe-panel\" *ngIf=\"panelFields.length || shownPanelFields().length\">\r\n <div class=\"fe-panel-title\">Filtres de l'écran</div>\r\n <div class=\"fe-panel-field\" *ngFor=\"let field of shownPanelFields(); trackBy: trackKey\">\r\n <span [title]=\"field.label\">{{ field.label }}</span>\r\n <ng-container [ngSwitch]=\"field.type\">\r\n <select *ngSwitchCase=\"'list'\" class=\"form-control\" [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\">\r\n <option value=\"\">Choisir…</option>\r\n <option *ngFor=\"let option of field.values\" [value]=\"option.value\">{{ option.label }}</option>\r\n </select>\r\n <select *ngSwitchCase=\"'bool'\" class=\"form-control\" [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\">\r\n <option value=\"\">Choisir…</option>\r\n <option value=\"true\">Oui</option>\r\n <option value=\"false\">Non</option>\r\n </select>\r\n <input *ngSwitchDefault class=\"form-control\" [type]=\"field.type === 'number' ? 'number' : field.type === 'date' ? 'date' : 'text'\"\r\n [ngModel]=\"panelValue(field)\" (ngModelChange)=\"setPanelValue(field, $event)\" />\r\n </ng-container>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer le filtre de l'écran\" (click)=\"removePanelField(field)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n <!-- Ajout d'un filtre de l'écran : les champs du FilterPanel pas encore utilisés. -->\r\n <div class=\"fe-adds\" *ngIf=\"availablePanelFields().length\">\r\n <select class=\"form-control fe-add-panel\" [ngModel]=\"''\" (ngModelChange)=\"addPanelField($event)\">\r\n <option value=\"\">+ Filtre de l'écran</option>\r\n <option *ngFor=\"let field of availablePanelFields(); trackBy: trackKey\" [value]=\"field.key\">{{ field.label }}</option>\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"fe-panel-title\" *ngIf=\"panelFields.length || shownPanelFields().length\">Filtre additionnel</div>\r\n <ng-container *ngTemplateOutlet=\"groupTpl; context: { group: filter, parent: null, index: 0, depth: 0 }\"></ng-container>\r\n <div class=\"fe-summary\">{{ summary() }}</div>\r\n </div>\r\n\r\n <div class=\"fe-body\" *ngIf=\"shownTab === 'sort'\">\r\n <div class=\"fe-sort\" *ngFor=\"let level of sort; let i = index; trackBy: trackIndex\">\r\n <span class=\"fe-sort-label\">{{ i === 0 ? 'Trier par' : 'Puis par' }}</span>\r\n <select class=\"form-control\" [(ngModel)]=\"level.property\">\r\n <option *ngFor=\"let column of columns\" [value]=\"column.key\">{{ column.label }}</option>\r\n </select>\r\n <select class=\"form-control fe-sort-direction\" [(ngModel)]=\"level.direction\">\r\n <option value=\"asc\">Croissant</option>\r\n <option value=\"desc\">Décroissant</option>\r\n </select>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Monter\" [disabled]=\"i === 0\" (click)=\"moveSort(i, -1)\"><i class=\"fa fa-arrow-up\"></i></button>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Descendre\" [disabled]=\"i === sort.length - 1\" (click)=\"moveSort(i, 1)\"><i class=\"fa fa-arrow-down\"></i></button>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer\" (click)=\"removeSort(i)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n <div class=\"fe-adds\"><button type=\"button\" class=\"fe-add\" (click)=\"addSort()\">+ Niveau</button></div>\r\n </div>\r\n\r\n <div class=\"fe-foot\">\r\n <label class=\"fe-save\" *ngIf=\"!embedded\" [class.disabled]=\"!canSaveInView\"\r\n [title]=\"canSaveInView ? '' : 'La vue par défaut est en lecture seule : dupliquez-la pour y enregistrer un filtre'\">\r\n <input type=\"checkbox\" [(ngModel)]=\"saveInView\" [disabled]=\"!canSaveInView\" />\r\n <span>Enregistrer dans la vue{{ viewLabel ? ' « ' + viewLabel + ' »' : '' }}</span>\r\n </label>\r\n <button type=\"button\" class=\"fe-clear\" (click)=\"clear()\">Tout effacer</button>\r\n </div>\r\n</div>\r\n\r\n<!-- Groupe : relation ET / OU, conditions, groupes imbriqués. -->\r\n<ng-template #groupTpl let-group=\"group\" let-parent=\"parent\" let-index=\"index\" let-depth=\"depth\">\r\n <div class=\"fe-group\" [class.or]=\"group.Logic === 'or'\" [class.nested]=\"depth > 0\">\r\n <div class=\"fe-group-head\">\r\n <span class=\"fe-logic\">\r\n <button type=\"button\" [class.on]=\"group.Logic === 'and'\" class=\"and\" (click)=\"setLogic(group, 'and')\">ET</button>\r\n <button type=\"button\" [class.on]=\"group.Logic === 'or'\" class=\"or\" (click)=\"setLogic(group, 'or')\">OU</button>\r\n </span>\r\n <span class=\"fe-group-hint\">{{ group.Logic === 'and' ? 'Toutes les conditions' : 'Au moins une condition' }}</span>\r\n <button type=\"button\" *ngIf=\"parent\" class=\"fe-icon fe-group-remove\" title=\"Retirer le groupe\" (click)=\"removeGroup(parent, index)\">\r\n <i class=\"fa fa-times\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fe-cond\" *ngFor=\"let condition of group.Conditions; let i = index; trackBy: trackIndex\">\r\n <select class=\"form-control\" [(ngModel)]=\"condition.Property\" (ngModelChange)=\"onColumnChange(condition)\">\r\n <option *ngFor=\"let column of columns\" [value]=\"column.key\">{{ column.label }}</option>\r\n </select>\r\n <select class=\"form-control\" [(ngModel)]=\"condition.Operator\" (ngModelChange)=\"onOperatorChange(condition)\">\r\n <option *ngFor=\"let op of operatorsOf(condition)\" [value]=\"op.value\">{{ op.label }}</option>\r\n </select>\r\n <span class=\"fe-value\">\r\n <ng-container *ngIf=\"isList(condition); else valueTpl\">\r\n <span class=\"fe-chips\" *ngIf=\"hasKnownValues(condition); else typedValuesTpl\">\r\n <button type=\"button\" *ngFor=\"let option of columnOf(condition.Property)?.values\" class=\"fe-chip\"\r\n [class.on]=\"condition.Values?.includes(option.value)\" (click)=\"toggleValue(condition, option.value)\">{{ option.label }}</button>\r\n </span>\r\n <!-- Texte, nombre : valeurs saisies une à une (ou cochées par le « Filtre avancé » de la grille). -->\r\n <ng-template #typedValuesTpl>\r\n <span class=\"fe-chips\">\r\n <button type=\"button\" *ngFor=\"let value of condition.Values\" class=\"fe-chip on\" title=\"Retirer cette valeur\"\r\n (click)=\"removeValue(condition, value)\">{{ value }} <i class=\"fa fa-times\"></i></button>\r\n <input #valueInput class=\"form-control fe-chip-input\" [type]=\"inputType(condition)\" placeholder=\"Ajouter une valeur\"\r\n (keydown.enter)=\"addValue(condition, valueInput); $event.preventDefault()\" (blur)=\"addValue(condition, valueInput)\" />\r\n </span>\r\n </ng-template>\r\n </ng-container>\r\n <ng-template #valueTpl>\r\n <ng-container *ngIf=\"hasValue(condition)\">\r\n <input class=\"form-control\" [type]=\"inputType(condition)\" [(ngModel)]=\"condition.Value\" />\r\n <input *ngIf=\"hasSecondValue(condition)\" class=\"form-control\" [type]=\"inputType(condition)\" [(ngModel)]=\"condition.Value2\" />\r\n </ng-container>\r\n </ng-template>\r\n </span>\r\n <button type=\"button\" class=\"fe-icon\" title=\"Retirer la condition\" (click)=\"removeCondition(group, i)\"><i class=\"fa fa-times\"></i></button>\r\n </div>\r\n\r\n <ng-container *ngFor=\"let sub of group.Groups; let gi = index; trackBy: trackIndex\">\r\n <ng-container *ngTemplateOutlet=\"groupTpl; context: { group: sub, parent: group, index: gi, depth: depth + 1 }\"></ng-container>\r\n </ng-container>\r\n\r\n <div class=\"fe-adds\">\r\n <button type=\"button\" class=\"fe-add\" (click)=\"addCondition(group)\">+ Condition</button>\r\n <button type=\"button\" class=\"fe-add\" *ngIf=\"depth < maxDepth - 1\" (click)=\"addGroup(group)\">+ Groupe</button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n",
20464
+ styles: [".home-page{font-family:Open sans,sans-serif;background:#fff;-webkit-font-smoothing:antialiased;height:100%;width:100%;padding:16px}.main-container{margin:0 50px}.main-container-modal{width:calc(100% - 50px);margin:10px 25px 0}.moyen-titre{font-weight:700;font-size:24px;color:#4d5a81;margin:8px 0;border-bottom:solid 1px #DBE4FF}.grand-titre{font-weight:700;font-size:28px;color:#4d5a81;margin:0 0 8px}.petit-titre{font-weight:700;font-size:16px;color:#4d5a81;margin:0 0 8px}.petit-titre.underlined{border-bottom:solid 1px #4D5A81}.paragraph{padding:0 15px}.paragraph-highlight{padding:5px 15px 0 12px;border-left:5px solid #8EA7F8;border-bottom:1px solid #DBE4FF;border-top:1px solid #DBE4FF;border-right:1px solid #DBE4FF;background-color:#f7faff}.highlight{background-color:#f7faff;border:1px solid #DBE4FF;border-radius:5px;padding:15px;color:#3c5dc4;margin:0 0 16px}.highlight p{margin-bottom:0}.highlight:before{position:relative;display:block;float:left;width:24px;height:24px;content:\" \";background-size:24px 24px;-webkit-background-size:24px 24px;background-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"53.294\" height=\"50.629\" viewBox=\"0 0 53.294 50.629\">%0D%0A <path id=\"allerg\\e8ne\" d=\"M830.494,25.793l-5.814,6.783.727,8.963-8.721,1.938-4.6,7.752L803.847,47.6l-8.236,3.634-4.6-7.51-8.721-1.938.727-8.963L777.2,26.035l5.814-6.783-.727-8.963,8.721-1.938L795.61.6l8.236,3.634L812.083.6l4.6,7.752,8.721,1.938-.727,8.963Zm-24.467,2.422V13.681h-4.845V28.216Zm0,9.69V33.06h-4.845v4.845Z\" transform=\"translate(-777.2 -0.6)\"/>%0D%0A</svg>%0D%0A');background-repeat:no-repeat;margin:0 8px 24px 0;filter:invert(31%) sepia(51%) saturate(1323%) hue-rotate(199deg) brightness(99%) contrast(94%)}.notification{background-color:#dbe4ff;border:1px solid #C4D0F9;border-radius:5px;color:#4d5a81;margin:16px;padding:5px 15px;text-align:justify}.notification:before{position:relative;display:block;float:left;width:24px;height:24px;content:\" \";background-size:24px 24px;-webkit-background-size:24px 24px;background-image:url('data:image/svg+xml,<svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"fas\" data-icon=\"info-circle\" class=\"svg-inline--fa fa-info-circle fa-w-16\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path fill=\"currentColor\" d=\"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"></path></svg>');background-repeat:no-repeat;margin:0 8px 0 0;filter:invert(31%) sepia(8%) saturate(2329%) hue-rotate(188deg) brightness(103%) contrast(85%)}.notification-text{padding:0 15px 0 30px;font-size:16px}.fe-panel{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(260px,100%),1fr));gap:6px 12px;margin-bottom:12px}.fe-panel .fe-adds{grid-column:1/-1}.fe-add-panel{width:auto;border-style:dashed;color:#4465c9}.fe-panel-title{grid-column:1/-1;margin:4px 0 2px;font-weight:600}.fe-panel-field{display:grid;grid-template-columns:120px minmax(0,1fr) auto;align-items:center;gap:8px;margin:0;font-weight:400}.fe-panel-field>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fe{display:flex;flex-direction:column;color:#4d5a81;font-size:13px}.fe-tabs{display:flex;gap:4px;padding:8px 14px 0;border-bottom:1px solid #DBE4FF}.fe-tab{padding:6px 12px;border:none;border-bottom:2px solid transparent;background:none;color:#9fa9c7;font:inherit;font-weight:700;cursor:pointer}.fe-tab.active{color:#4465c9;border-bottom-color:#5272d3}.fe-body{display:flex;flex-direction:column;gap:10px;max-height:60vh;overflow-y:auto;padding:12px 14px}.fe-group{display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid #DBE4FF;border-left:4px solid #3b57b8;border-radius:0 4px 4px 0;background:#fff}.fe-group.or{border-left-color:#e07b12}.fe-group.nested{background:#f6f8fd}.fe-group-head{display:flex;align-items:center;gap:8px;font-size:12px;color:#9fa9c7}.fe-group-remove{margin-left:auto}.fe-logic{display:inline-flex;border:1px solid #DBE4FF;border-radius:999px;overflow:hidden}.fe-logic button{padding:2px 10px;border:none;background:none;color:#9fa9c7;font:inherit;font-size:11px;font-weight:800;cursor:pointer}.fe-logic button.on.and{background:#3b57b8;color:#fff}.fe-logic button.on.or{background:#e07b12;color:#fff}.fe-cond{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) minmax(0,1.4fr) 28px;gap:6px;align-items:center;padding:4px 6px;border:1px solid #DBE4FF;border-left:3px solid #3b57b8;border-radius:0 4px 4px 0;background:#fff}.fe-group.or>.fe-cond{border-left-color:#e07b12}@media(max-width:600px){.fe-cond{grid-template-columns:minmax(0,1fr) minmax(0,1fr) 28px}.fe-cond .fe-value{grid-column:1/3}}select.form-control,input.form-control{height:30px;min-width:0;padding:2px 6px;font-size:13px}.fe-value{display:flex;gap:6px;min-width:0}.fe-value input{flex:1}.fe-chips{display:flex;flex-wrap:wrap;gap:4px}.fe-chip{padding:2px 8px;border:1px solid #C1D0FD;border-radius:999px;background:#fff;color:#4d5a81;font:inherit;font-size:12px;cursor:pointer}.fe-chip.on{background:#5272d3;border-color:#5272d3;color:#fff}.fe-chip i{margin-left:2px;font-size:10px}.fe-chip-input{flex:1;min-width:120px}.fe-icon{width:28px;height:28px;padding:0;border:none;border-radius:6px;background:none;color:#9fa9c7;cursor:pointer}.fe-icon:hover:not(:disabled){background:#ebf0ff;color:#4d5a81}.fe-icon:disabled{opacity:.3;cursor:default}.fe-adds{display:flex;gap:8px;flex-wrap:wrap}.fe-add{padding:3px 10px;border:1px dashed #C1D0FD;border-radius:6px;background:none;color:#4465c9;font:inherit;font-size:12px;cursor:pointer}.fe-summary{padding:8px 10px;border-radius:6px;background:#ebf0ff;font-size:12px;word-break:break-word}.fe-sort{display:grid;grid-template-columns:64px minmax(0,1fr) 120px 28px 28px 28px;gap:6px;align-items:center}.fe-sort-label{font-size:12px;color:#9fa9c7}.fe-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 14px;border-top:1px solid #DBE4FF}.fe-save{display:inline-flex;align-items:center;gap:6px;margin:0;font-weight:400;cursor:pointer}.fe-save.disabled{opacity:.55;cursor:default}.fe-save input{margin:0}.fe-clear{border:none;background:none;color:#4465c9;font:inherit;cursor:pointer}\n"]
20449
20465
  }]
20450
20466
  }],
20451
20467
  propDecorators: {