diff --git a/src/app/components/pab-table/pab-table.component.ts b/src/app/components/pab-table/pab-table.component.ts index beef1d66822a1ee1df474dab65c2b2a7f33a36cc..a36aee80100e37084915b49f6ab772ba037a44e1 100644 --- a/src/app/components/pab-table/pab-table.component.ts +++ b/src/app/components/pab-table/pab-table.component.ts @@ -878,11 +878,52 @@ export class PabTableComponent implements AfterViewInit, OnInit { } public get enableRemoveButton() { + let containsDownwall = false; + let containsOrphanNub = false; + let tooFewDevices = false; + let wallsCount = 0; + const devicesCountById = {}; + const deletedWallsUids = []; + + for (const se of this.selectedItems) { + if (se instanceof Structure) { // device + if (devicesCountById[se.parent.uid] === undefined) { + devicesCountById[se.parent.uid] = 0; + } + devicesCountById[se.parent.uid]++; + } else { // wall + wallsCount++; + deletedWallsUids.push(se.uid); + } + if (se instanceof CloisonAval) { + containsDownwall = true; // cannot remove downwall + } + if (! se.parent) { + containsOrphanNub = true; // not supposed to happen but who knows + } + } + + // at least one device must remain in each basin, unless this basin is removed too + for (const structureId in devicesCountById) { + if (! deletedWallsUids.includes(structureId)) { + let wall: Nub; + if (this.model.downWall.uid === structureId) { + wall = this.model.downWall; + } else { + wall = this.model.getChild(structureId); + } + if (wall.getChildren().length <= devicesCountById[structureId]) { + tooFewDevices = true; + } + } + } + return ( - this.selectedItems.length === 1 - && ! (this.selectedItem instanceof CloisonAval) // exclude downwall - && this.selectedItem.parent - && this.selectedItem.parent.getChildren().length > 1 + this.selectedItems.length > 0 + && wallsCount < this.model.children.length // at least one basin must remain + && ! containsDownwall + && ! containsOrphanNub + && ! tooFewDevices ); } @@ -1040,15 +1081,44 @@ export class PabTableComponent implements AfterViewInit, OnInit { } public onRemoveClick() { - const pos = this.selectedItem.findPositionInParent() + 1; - this.selectedItem.parent.deleteChild(this.selectedItem.findPositionInParent()); - if (this.selectedItem instanceof Structure) { - this.notifService.notify(sprintf(this.i18nService.localizeText("INFO_DEVICE_REMOVED"), pos)); - } else { - this.notifService.notify(sprintf(this.i18nService.localizeText("INFO_WALL_REMOVED"), pos)); + let wallsCount = 0; + let devicesCount = 0; + const deletedWallsUids = []; + + // first pass: gather deleted structures UIDs + for (const se of this.selectedItems) { + if (! (se instanceof Structure)) { + wallsCount++; + deletedWallsUids.push(se.uid); + } + } + + // second pass: remove + for (const se of this.selectedItems) { + if (se instanceof Structure) { // device + // do not remove device if parent structure is to be removed too + if (! deletedWallsUids.includes(se.parent.uid)) { + se.parent.deleteChild(se.findPositionInParent()); + devicesCount++; + } + } else { + // remove wall + se.parent.deleteChild(se.findPositionInParent()); + } } this.selectedItems = []; this.refresh(); + + // notify + let msg: string; + if (wallsCount === 0) { + msg = sprintf(this.i18nService.localizeText("INFO_DEVICES_REMOVED"), devicesCount); + } else if (devicesCount === 0) { + msg = sprintf(this.i18nService.localizeText("INFO_WALLS_REMOVED"), wallsCount); + } else { + msg = sprintf(this.i18nService.localizeText("INFO_WALLS_AND_DEVICES_REMOVED"), wallsCount, devicesCount); + } + this.notifService.notify(msg); } public get uitextAdd(): string { diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index 5e8589a68068344dd63aa3075f97d2cd4501ec38..c107256cbfd39792eba921b46a626fec44fcb58b 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -122,6 +122,7 @@ "INFO_DEVICE_COPIED_N_TIMES": "Device #%s copied %s times", "INFO_DEVICE_MOVED": "Device #%s moved", "INFO_DEVICE_REMOVED": "Device #%s removed", + "INFO_DEVICES_REMOVED": "%s device(s) removed", "INFO_FIELDSET_ADD": "Add", "INFO_FIELDSET_COPY": "Copy", "INFO_FIELDSET_REMOVE": "Remove", @@ -135,6 +136,8 @@ "INFO_WALL_COPIED_N_TIMES": "Wall #%s copied %s times", "INFO_WALL_MOVED": "Wall #%s moved", "INFO_WALL_REMOVED": "Wall #%s removed", + "INFO_WALLS_AND_DEVICES_REMOVED": "%s wall(s) and %s device(s) removed", + "INFO_WALLS_REMOVED": "%s wall(s) removed", "INFO_LECHAPTCALMON_TITRE_COURT": "Lechapt-C.", "INFO_LECHAPTCALMON_TITRE": "Lechapt-Calmon", "INFO_LIB_LENGTHS": "Every length", diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index c28d769f082518f610c87a933f6b55c3361be5b9..478772b1b2adb3016778d987eadedc9793d8c7f5 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -122,6 +122,7 @@ "INFO_DEVICE_COPIED_N_TIMES": "Ouvrage n°%s copié %s fois", "INFO_DEVICE_MOVED": "Ouvrage n°%s déplacé", "INFO_DEVICE_REMOVED": "Ouvrage n°%s supprimé", + "INFO_DEVICES_REMOVED": "%s ouvrage(s) supprimé(s)", "INFO_FIELDSET_ADD": "Ajouter", "INFO_FIELDSET_COPY": "Copier", "INFO_FIELDSET_REMOVE": "Supprimer", @@ -135,6 +136,8 @@ "INFO_WALL_COPIED_N_TIMES": "Cloison n°%s copiée %s fois", "INFO_WALL_MOVED": "Cloison n°%s déplacée", "INFO_WALL_REMOVED": "Cloison n°%s supprimée", + "INFO_WALLS_AND_DEVICES_REMOVED": "%s cloison(s) et %s ouvrage(s) supprimé(s)", + "INFO_WALLS_REMOVED": "%s cloison(s) supprimée(s)", "INFO_LECHAPTCALMON_TITRE_COURT": "Lechapt-C.", "INFO_LECHAPTCALMON_TITRE": "Lechapt-Calmon", "INFO_LIB_LENGTHS": "Toutes les longueurs",