diff --git a/src/app/calculators/verificateur/config.json b/src/app/calculators/verificateur/config.json index 204203e1f4e30cf9b957e1e07f7d1e3bd26c6157..5b03751eda6393520a76969e37a8c169ce5dc25f 100644 --- a/src/app/calculators/verificateur/config.json +++ b/src/app/calculators/verificateur/config.json @@ -24,7 +24,6 @@ { "type": "select", "id": "select_species_list", - "default": "SPECIES_1", "source": "verificateur_species", "multiple": true } diff --git a/src/app/components/generic-select/generic-select.component.html b/src/app/components/generic-select/generic-select.component.html index dd35d4673766d3dbb56cbca32f6ff111c90c9662..4d420c8209a4e617005a080d6cb9589430b8406f 100644 --- a/src/app/components/generic-select/generic-select.component.html +++ b/src/app/components/generic-select/generic-select.component.html @@ -3,13 +3,17 @@ <mat-select-trigger *ngIf="isMultiple"> {{ selectedValue && selectedValue[0] ? selectedValue[0].label : '' }} <span *ngIf="selectedValue?.length > 1" class="multiple-selection-label"> - (+ {{selectedValue.length - 1}} {{selectedValue?.length === 2 ? 'other' : 'others'}}) + (+ {{ selectedValue.length - 1 }} {{ selectedValue?.length === 2 ? uitextAndOther : uitextAndOthers }}) </span> </mat-select-trigger> <mat-option *ngFor="let e of entries" [value]="e" [title]="entryLabel(e)"> {{ entryLabel(e) }} </mat-option> </mat-select> + <button mat-button *ngIf="showClearButton" matSuffix mat-icon-button + aria-label="Clear" (click)="selectedValue=[]; $event.stopPropagation()"> + <mat-icon>close</mat-icon> + </button> <div *ngIf="enableHelpButton" class="overlap-select"> <mat-icon id="help-select" (click)="openHelp($event)" [title]="uitextOpenHelp" color="accent"> help diff --git a/src/app/components/results-chart/chart-type.component.ts b/src/app/components/results-chart/chart-type.component.ts index b136874f67414420948f7ee80a6f3b498c198134..7b24c70988b2a020bca313ce0b0ab77092dbf9f0 100644 --- a/src/app/components/results-chart/chart-type.component.ts +++ b/src/app/components/results-chart/chart-type.component.ts @@ -57,6 +57,10 @@ export class ChartTypeSelectComponent implements IObservable { return false; } + public get showClearButton(): boolean { + return false; + } + public get label() { return this.intlService.localizeText("INFO_PARAMFIELD_CHART_TYPE"); } diff --git a/src/app/components/select-field-line/select-field-line.component.ts b/src/app/components/select-field-line/select-field-line.component.ts index b660c875cc738d6b884554387ccde66056d89de6..f2c43341da3dddd48d88d66c2dd2a0ecf95fc468 100644 --- a/src/app/components/select-field-line/select-field-line.component.ts +++ b/src/app/components/select-field-line/select-field-line.component.ts @@ -97,13 +97,27 @@ export class SelectFieldLineComponent implements OnInit { return false; } + public get showClearButton(): boolean { + return this.isMultiple && this.selectedValue && ! (Array.isArray(this.selectedValue) && this.selectedValue.length === 0); + } + public get uitextOpenHelp() { return this.i18nService.localizeText("INFO_CALCULATOR_OPEN_HELP"); } + public get uitextAndOther() { + return this.i18nService.localizeText("INFO_SELECT_MULTIPLE_AND_OTHER"); + } + + public get uitextAndOthers() { + return this.i18nService.localizeText("INFO_SELECT_MULTIPLE_AND_OTHERS"); + } + // called every time we navigate to the module ngOnInit(): void { + console.log("> ngOnInit()", this.selectId); if (this._select instanceof SelectFieldReference) { + console.log(">> updateEntries() !", this.selectId); this._select.updateEntries(); } } diff --git a/src/app/formulaire/elements/select-field-reference.ts b/src/app/formulaire/elements/select-field-reference.ts index 924d1a869b7c38717218b2537190727a7145a0dd..c4024feea76a86f7aa518dc4fd106f22ab230aae 100644 --- a/src/app/formulaire/elements/select-field-reference.ts +++ b/src/app/formulaire/elements/select-field-reference.ts @@ -2,6 +2,8 @@ import { SelectField } from "./select-field"; import { SelectEntry } from "./select-entry"; import { FormulaireNode } from "./formulaire-node"; +import { arraysAreEqual } from "../../util"; + /** * A select field that populates itself with references to * available objects (for ex. Nub or ParamDefinition) @@ -46,7 +48,7 @@ export abstract class SelectFieldReference extends SelectField { // if no entry is available anymore, unset value if (this.entries.length === 0) { if (this.multiple) { - super.setValue([ undefined ]); + super.setValue([]); } else { super.setValue(undefined); } @@ -64,16 +66,24 @@ export abstract class SelectFieldReference extends SelectField { * Updates selectedValue; notifies observers only if * value.id has changed */ - public setValue(v: SelectEntry) { + public setValue(v: SelectEntry | SelectEntry[]) { const previousSelectedEntry = this._selectedEntry; this._selectedEntry = v; - if ( + // if value changed + let valueChanged = ( ! previousSelectedEntry - || ( // @TODO manage multiple values + || ( ! Array.isArray(previousSelectedEntry) + && ! Array.isArray(v) && previousSelectedEntry.id !== v.id ) - ) { + || ( + Array.isArray(previousSelectedEntry) + && Array.isArray(v) + && arraysAreEqual(previousSelectedEntry, v, "id", true) + ) + ); + if (valueChanged) { this.notifySelectValueChanged(); } } @@ -94,7 +104,11 @@ export abstract class SelectFieldReference extends SelectField { for (const e of this._entries) { if (e.id === id) { found = true; - this.setValue(e); + if (this._multiple) { + this.setValue([ e ]); + } else { + this.setValue(e); + } } } if (! found) { @@ -105,7 +119,11 @@ export abstract class SelectFieldReference extends SelectField { protected setDefaultValue() { // default to first available entry if any if (this._entries.length > 0) { - this.setValue(this._entries[0]); + if (this._multiple) { + this.setValue([ this._entries[0] ]); + } else { + this.setValue(this._entries[0]); + } } else { // notify observers that no value is selected anymore this.notifySelectValueChanged(); diff --git a/src/app/formulaire/elements/select-field.ts b/src/app/formulaire/elements/select-field.ts index 5fdf96889cf7bb4d93bf70d6c80c51aa7395f654..4818e570918731128fe9a2e13284374b36b1ab83 100644 --- a/src/app/formulaire/elements/select-field.ts +++ b/src/app/formulaire/elements/select-field.ts @@ -67,7 +67,11 @@ export class SelectField extends Field { public addEntry(e: SelectEntry) { this._entries.push(e); if (! this._selectedEntry) { - this.setValue(e); + if (this._multiple) { + this.setValue([ e ]); + } else { + this.setValue(e); + } } } @@ -207,9 +211,11 @@ export class SelectField extends Field { } break; + // possible values depend on Session case "verificateur_species": // add UIDs of all Espece type Nubs in the session const especeNubs = Session.getInstance().getAllNubs().filter((element) => element.calcType === CalculatorType.Espece); + console.log("especeNubs", especeNubs); for (const en of especeNubs) { this.addEntry(new SelectEntry(en.uid, en.uid, "Espèce personnalisée : " + en.uid)); } diff --git a/src/app/util.ts b/src/app/util.ts index 6f5719bc5b0888c222f55633d3a6171b17a90e81..cfc9ca3af92300c9750aeb3941619dd2a01e3d9e 100644 --- a/src/app/util.ts +++ b/src/app/util.ts @@ -161,3 +161,25 @@ export function generateValuesCombination( return formula(nub, vals); } } + +export function arraysAreEqual(arrayA: any[], arrayB: any[], property?: string, sort = false): boolean { + if (sort) { + arrayA.sort((a, b) => a-b); + arrayB.sort((a, b) => a-b); + } + let equal = true; + if (arrayA.length === arrayB.length) { + for (let i=0; i < arrayA.length; i++) { + const eA = arrayA[i]; + const eB = arrayB[i]; + if (property === undefined) { + equal = equal && (eA === eB); + } else { + equal = equal && (eA[property] === eB[property]); + } + } + } else { + equal = false; + } + return equal; +} diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index ade6d6943c30c97f67410e716e246675e924c004..fb4e4605e9cb9f3e531e22ee2eab7e34d00428f0 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -472,6 +472,8 @@ "INFO_RESULTS_EXPORT_AS_SPREADSHEET": "Export as XLSX", "INFO_SECTIONPARAMETREE_TITRE_COURT": "Param. section", "INFO_SECTIONPARAMETREE_TITRE": "Parametric section", + "INFO_SELECT_MULTIPLE_AND_OTHER": "other", + "INFO_SELECT_MULTIPLE_AND_OTHERS": "others", "INFO_SETUP_ENABLE_HOTKEYS": "Enable keyboard shortcuts", "INFO_SETUP_ENABLE_EMPTY_FIELDS": "Create new calculators with empty fields (no default values)", "INFO_SETUP_ENABLE_NOTIFICATIONS": "Enable on-screen notifications", diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index 021a098f1cfc099b00a6149a831d2e02df4cd00f..da9489786236b7f7d42117d08e049d7fc8a7a2e3 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -473,6 +473,8 @@ "INFO_RESULTS_EXPORT_AS_SPREADSHEET": "Exporter en XLSX", "INFO_SECTIONPARAMETREE_TITRE_COURT": "Sec. param.", "INFO_SECTIONPARAMETREE_TITRE": "Section paramétrée", + "INFO_SELECT_MULTIPLE_AND_OTHER": "autre", + "INFO_SELECT_MULTIPLE_AND_OTHERS": "autres", "INFO_SETUP_ENABLE_HOTKEYS": "Activer les raccourcis clavier", "INFO_SETUP_ENABLE_EMPTY_FIELDS": "Créer les nouveaux modules avec des champs vides (aucune valeur par défaut)", "INFO_SETUP_ENABLE_NOTIFICATIONS": "Activer les notifications à l'écran",