diff --git a/src/app/components/dialog-edit-pab/dialog-edit-pab.component.html b/src/app/components/dialog-edit-pab/dialog-edit-pab.component.html index 7af52003ef083fb128146db689d82332a7c789fa..e96cc7807839a60dd10cd6fc0a8b7f3b024d6032 100644 --- a/src/app/components/dialog-edit-pab/dialog-edit-pab.component.html +++ b/src/app/components/dialog-edit-pab/dialog-edit-pab.component.html @@ -5,6 +5,9 @@ <div mat-dialog-content> <!-- récap selection --> + <div id="selection-abstract"> + {{ selectionAbstract }} + </div> <!-- champ à modifier --> <mat-form-field class="select-form-field"> @@ -24,7 +27,7 @@ </mat-radio-button> <mat-form-field class="input-form-field"> <input matInput [(ngModel)]="valueToSet" name="valueToSet" #valueToSetRef="ngModel" - (keydown.enter)="onEnterPressed($event)" required pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$"> + required pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$"> </mat-form-field> <mat-error *ngIf="varAction === 'set-value' && valueToSetRef.invalid"> {{ uitextMustBeANumber }} @@ -37,7 +40,7 @@ </mat-radio-button> <mat-form-field class="input-form-field"> <input matInput [(ngModel)]="delta" name="delta" #deltaRef="ngModel" - (keydown.enter)="onEnterPressed($event)" required pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$"> + required pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$"> </mat-form-field> <mat-error *ngIf="varAction === 'delta' && deltaRef.invalid"> {{ uitextMustBeANumber }} @@ -45,8 +48,11 @@ </div> <div class="radio-button-and-input-wrapper"> - <mat-radio-button value="interpolate"> + <mat-radio-button value="interpolate" [disabled]="! interpolationEnabled"> {{ uitextInterpolate }} + <span class="interpolation-bounds"> + {{ interpolationBounds }} + </span> </mat-radio-button> </div> diff --git a/src/app/components/dialog-edit-pab/dialog-edit-pab.component.scss b/src/app/components/dialog-edit-pab/dialog-edit-pab.component.scss index e306389d627ec05e12bf68faed0cc2c6cd2a4f41..d8f214cbebe7f7aae7dffb37cece5d77e1bcfe54 100644 --- a/src/app/components/dialog-edit-pab/dialog-edit-pab.component.scss +++ b/src/app/components/dialog-edit-pab/dialog-edit-pab.component.scss @@ -3,6 +3,11 @@ overflow: inherit; // wtf } +#selection-abstract { + font-size: .9em; + margin-bottom: 2em; +} + mat-form-field.select-form-field { width: 100%; margin-bottom: 10px; @@ -13,6 +18,23 @@ mat-form-field.select-form-field { mat-radio-button { width: 60%; + + &[value="interpolate"] { + width: 100%; + + ::ng-deep label.mat-radio-label { + width: 100%; + + > .mat-radio-label-content { + width: 100%; + + .interpolation-bounds { + float: right; + color: #707070; + } + } + } + } } mat-form-field.input-form-field { diff --git a/src/app/components/dialog-edit-pab/dialog-edit-pab.component.ts b/src/app/components/dialog-edit-pab/dialog-edit-pab.component.ts index ba4512af58c800adf268f2251af2fff769fa31b4..7bb57443c27ce729314244b1a9bc694efd05ca0d 100644 --- a/src/app/components/dialog-edit-pab/dialog-edit-pab.component.ts +++ b/src/app/components/dialog-edit-pab/dialog-edit-pab.component.ts @@ -1,7 +1,10 @@ import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; import { Inject, Component } from "@angular/core"; + import { I18nService } from "../../services/internationalisation/internationalisation.service"; +import { sprintf } from "sprintf-js"; + @Component({ selector: "dialog-edit-pab", templateUrl: "dialog-edit-pab.component.html", @@ -15,9 +18,6 @@ export class DialogEditPabComponent { /** symbols of the variables eligible to modification */ public availableVariableSymbols: string[]; - /** variable to modify on every selected object */ - public variable: string; - /** action to apply to the variable */ public varAction: string; @@ -27,82 +27,169 @@ export class DialogEditPabComponent { /** delta to apply (add) to all occurrences of the variable */ public delta: number; - constructor( - public dialogRef: MatDialogRef<DialogEditPabComponent>, - private intlService: I18nService, - @Inject(MAT_DIALOG_DATA) public data: any - ) { - this.availableVariables = this.data.availableVariables; - this.availableVariableSymbols = this.availableVariables.map(av => av.value); - this.variable = this.availableVariableSymbols[0]; - // default action - this.varAction = "set-value"; - // example values for validation / avoiding using a placeholder - this.valueToSet = 1.5; - this.delta = -0.01; - } - - public onEnterPressed($event) { - console.log("enter pressed !!"); - } + /** true if selected devices are contained in one unique column */ + public vertical: boolean; - public applyValues() { - console.log("Apply values !!", this.varAction, this.variable, this.valueToSet, this.delta); + /** variable to modify on every selected object */ + private _variable: string; + + /** number of selected walls and devices */ + private selectedItemsAbstract: { walls: number, wallsDevices: number, devices: number }; + + constructor( + public dialogRef: MatDialogRef<DialogEditPabComponent>, + private intlService: I18nService, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.selectedItemsAbstract = this.data.selectedItemsAbstract; + this.vertical = this.data.vertical; + this.availableVariables = this.data.availableVariables; + // console.log("AV VAR", this.availableVariables); + this.availableVariableSymbols = this.availableVariables.map(av => av.value); + this.variable = this.availableVariableSymbols[0]; + // default action + this.varAction = "set-value"; + // example values for validation / avoiding using a placeholder + this.valueToSet = this.availableVariables[0].first; + this.delta = 0; + } + + public get variable(): string { + return this._variable; + } + + // preloads valueToSet depending on variable chosen + public set variable(v: string) { + this._variable = v; + // find variable details from key + for (const av of this.availableVariables) { + if (av.value === this.variable) { + this.valueToSet = av.first; + } } - - public buttonDisabled(value: any, delta: any) { - return ( - (this.varAction === "set-value" && ! value.valid) - || (this.varAction === "delta" && ! delta.valid) + } + + /** closes dialog and tells parent to apply modifications */ + public applyValues() { + this.dialogRef.close({ + action: this.varAction, + variable: this.variable, + value: this.valueToSet, + delta: this.delta + }); + } + + public buttonDisabled(value: any, delta: any) { + return ( + (this.varAction === "set-value" && ! value.valid) + || (this.varAction === "delta" && ! delta.valid) + ); + } + + /** returns a short text summing up what is selected */ + public get selectionAbstract() { + let abstract = ""; + if (this.selectedItemsAbstract.walls > 0) { + // devices outside of complete walls ? + if (this.selectedItemsAbstract.devices > 0) { + abstract = sprintf( + this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_N_WALLS_P_DEVICES"), + this.selectedItemsAbstract.walls, + this.selectedItemsAbstract.devices, + this.selectedItemsAbstract.wallsDevices + this.selectedItemsAbstract.devices + ); + } else { + // only complete walls + abstract = sprintf( + this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_N_WALLS"), + this.selectedItemsAbstract.walls, + this.selectedItemsAbstract.wallsDevices + ); + } + } else { + // no complete wall, devices only + abstract = sprintf( + this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_N_DEVICES"), + this.selectedItemsAbstract.devices ); } + return abstract; + } - public variableLabel(v: string) { - for (const av of this.availableVariables) { - if (av.value === v) { - return av.label; + public variableLabel(v: string) { + for (const av of this.availableVariables) { + if (av.value === v) { + return av.label; + } + } + } + + public get interpolationEnabled() { + return ( + this.vertical + && (this.selectedItemsAbstract.devices + this.selectedItemsAbstract.wallsDevices) > 1 + ); + } + + public get interpolationBounds() { + let bounds = ""; + if (this.interpolationEnabled) { + // find variable details from key + let varDetails: any; + for (const v of this.availableVariables) { + if (v.value === this.variable) { + varDetails = v; } } + if (varDetails) { + bounds = sprintf( + this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_INTERPOLATION_BOUNDS"), + varDetails.first, + varDetails.last + ); + } } + return bounds; + } - public get uitextEditPabTitle() { - return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_TITLE"); - } + public get uitextEditPabTitle() { + return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_TITLE"); + } - public get uitextVariable() { - return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_OPTION_VARIABLE"); - } + public get uitextVariable() { + return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_OPTION_VARIABLE"); + } - public get uitextSetValue() { - return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_OPTION_SET_VALUE"); - } + public get uitextSetValue() { + return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_OPTION_SET_VALUE"); + } - public get uitextDelta() { - return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_OPTION_DELTA"); - } + public get uitextDelta() { + return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_OPTION_DELTA"); + } - public get uitextInterpolate() { - return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_OPTION_INTERPOLATE"); - } + public get uitextInterpolate() { + return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_OPTION_INTERPOLATE"); + } - public get uitextSetValueInput() { - return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_SET_VALUE_INPUT"); - } + public get uitextSetValueInput() { + return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_SET_VALUE_INPUT"); + } - public get uitextDeltaInput() { - return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_DELTA_INPUT"); - } + public get uitextDeltaInput() { + return this.intlService.localizeText("INFO_DIALOG_EDIT_PAB_DELTA_INPUT"); + } - public get uitextMustBeANumber(): string { - return this.intlService.localizeText("ERROR_PARAM_MUST_BE_A_NUMBER"); - } + public get uitextMustBeANumber(): string { + return this.intlService.localizeText("ERROR_PARAM_MUST_BE_A_NUMBER"); + } - public get uitextSave() { - return this.intlService.localizeText("INFO_OPTION_SAVE"); - } + public get uitextSave() { + return this.intlService.localizeText("INFO_OPTION_SAVE"); + } - public get uitextCancel() { - return this.intlService.localizeText("INFO_OPTION_CANCEL"); - } + public get uitextCancel() { + return this.intlService.localizeText("INFO_OPTION_CANCEL"); + } } diff --git a/src/app/components/pab-table/pab-table.component.ts b/src/app/components/pab-table/pab-table.component.ts index 0550e449d0cd245661969191e56a3fbd80f7b5e9..1397a59ce3a059b08ffb3a9bfdb235517234f7ee 100644 --- a/src/app/components/pab-table/pab-table.component.ts +++ b/src/app/components/pab-table/pab-table.component.ts @@ -778,6 +778,7 @@ export class PabTableComponent implements /* DoCheck, AfterViewInit, */ OnInit { // show modal dialog for values edition public showEditPab() { if (this.selectedItems.length > 0) { + // list variables eligible to modification const availableVariables: any[] = []; for (const c of this.selectedItems) { @@ -793,16 +794,83 @@ export class PabTableComponent implements /* DoCheck, AfterViewInit, */ OnInit { } } } + // find their min/max values (2nd pass) + for (const av of availableVariables) { + for (const c of this.selectedItems) { + for (const p of c.parameterIterator) { + if (p.visible && p.symbol === av.value) { + if (av.first === undefined) { + av.first = p.singleValue; + } + av.last = p.singleValue; + } + } + } + } + + // sum up selected items + const walls: ParallelStructure[] = []; + const wallsDevices: Structure[] = []; + const devices: Structure[] = []; + let vertical = true; // @TODO vertical AND consecutive ! + let firstDevicePosition: number; + // 1st pass + for (const s of this.selectedItems) { + if (s instanceof ParallelStructure) { + walls.push(s); + for (const c of s.structures) { + if (firstDevicePosition === undefined) { + firstDevicePosition = c.findPositionInParent(); + } else { + vertical = (vertical && (c.findPositionInParent() === firstDevicePosition)); + } + wallsDevices.push(c); + } + } + } + // 2nd pass + for (const c of this.selectedItems) { + if (c instanceof Structure) { + if (! wallsDevices.includes(c)) { + if (firstDevicePosition === undefined) { + firstDevicePosition = c.findPositionInParent(); + } else { + vertical = (vertical && (c.findPositionInParent() === firstDevicePosition)); + } + devices.push(c); + } + } + } + // open dialog const dialogRef = this.editPabDialog.open( DialogEditPabComponent, { data: { - availableVariables: availableVariables + availableVariables: availableVariables, + selectedItemsAbstract: { + walls: walls.length, + wallsDevices: wallsDevices.length, + devices: devices.length + }, + vertical: vertical // used to enable interpolation }, disableClose: true } ); + dialogRef.afterClosed().subscribe(result => { + if (result) { + console.log("Apply values in parent !!", result.action, result.variable, result.value, result.delta); + switch (result.action) { + case "set-value": + break; + case "delta": + break; + case "interpolate": + break; + } + } + }); } } diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index 641530ef434336a1efbcde9ab963293d28c0a8c2..4bdcf9c59fa9dc6413c1f1cdf72dcb443aa09e9c 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -58,11 +58,15 @@ "INFO_DEVER_TITRE_COURT": "Free weir", "INFO_DEVER_TITRE": "Free flow weir stage-discharge laws", "INFO_DIALOG_COMPUTED_VALUE_TITLE": "Edit initial value", - "INFO_DIALOG_EDIT_PAB_TITLE": "Edit values", + "INFO_DIALOG_EDIT_PAB_INTERPOLATION_BOUNDS": "between %s and %s", + "INFO_DIALOG_EDIT_PAB_N_DEVICES": "%s device(s)", + "INFO_DIALOG_EDIT_PAB_N_WALLS": "%s wall(s) : %s device(s)", + "INFO_DIALOG_EDIT_PAB_N_WALLS_P_DEVICES": "%s wall(s) + %s device(s) : %s devices", "INFO_DIALOG_EDIT_PAB_OPTION_VARIABLE": "Variable to edit", "INFO_DIALOG_EDIT_PAB_OPTION_SET_VALUE": "Fixed value", "INFO_DIALOG_EDIT_PAB_OPTION_DELTA": "Delta", "INFO_DIALOG_EDIT_PAB_OPTION_INTERPOLATE": "Interpolate", + "INFO_DIALOG_EDIT_PAB_TITLE": "Edit values", "INFO_DIALOG_EMPTY_CURRENT_SESSION": "Empty current session", "INFO_DIALOG_FIX_MISSING_DEPENDENCIES": "Fix missing dependencies", "INFO_DIALOG_FORMAT_VERSIONS_MISMATCH": "File format versions mismatch (file: %s, jalhyd: %s)", diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index f288ce478933b0f1df5b97fda801587574c7effd..a0eda8f5fa1e82e4e9b31b7143d0cbed29cd0a23 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -58,11 +58,15 @@ "INFO_DEVER_TITRE_COURT": "Déver. dénoyés", "INFO_DEVER_TITRE": "Lois de déversoirs dénoyés", "INFO_DIALOG_COMPUTED_VALUE_TITLE": "Modifier la valeur initiale", - "INFO_DIALOG_EDIT_PAB_TITLE": "Modifier les valeurs", + "INFO_DIALOG_EDIT_PAB_INTERPOLATION_BOUNDS": "entre %s et %s", + "INFO_DIALOG_EDIT_PAB_N_DEVICES": "%s ouvrage(s)", + "INFO_DIALOG_EDIT_PAB_N_WALLS": "%s cloison(s) : %s ouvrage(s)", + "INFO_DIALOG_EDIT_PAB_N_WALLS_P_DEVICES": "%s cloison(s) + %s ouvrage(s) : %s ouvrages", "INFO_DIALOG_EDIT_PAB_OPTION_VARIABLE": "Variable à modifier", "INFO_DIALOG_EDIT_PAB_OPTION_SET_VALUE": "Valeur fixe", "INFO_DIALOG_EDIT_PAB_OPTION_DELTA": "Delta", "INFO_DIALOG_EDIT_PAB_OPTION_INTERPOLATE": "Interpoler", + "INFO_DIALOG_EDIT_PAB_TITLE": "Modifier les valeurs", "INFO_DIALOG_EMPTY_CURRENT_SESSION": "Vider la session courante", "INFO_DIALOG_FIX_MISSING_DEPENDENCIES": "Résoudre les dépendances", "INFO_DIALOG_FORMAT_VERSIONS_MISMATCH": "Mauvaise version du format de fichier (fichier: %s, jalhyd: %s)",