diff --git a/src/app/components/pb-schema/pb-schema.component.html b/src/app/components/pb-schema/pb-schema.component.html
index da8c17896e1553b0f12975efa13821b69f3eed6d..0c35fbbc4b40a13759e109003a1374cbcbd59d44 100644
--- a/src/app/components/pb-schema/pb-schema.component.html
+++ b/src/app/components/pb-schema/pb-schema.component.html
@@ -8,6 +8,10 @@
 
     <div id="pb-schema-toolbar">
 
+        <button type="button" id="add-basin" mat-raised-button color="accent" (click)="onAddBasinClick()">
+            {{ uitextAddBasin }}
+        </button>
+
         <div class="hyd-window-btns">
             <span class="related-entity-title">
                 {{ prefixedItemDescription }}
@@ -16,33 +20,16 @@
                 <mat-option *ngFor="let i of addManyOptionsList" [value]="i">
                     {{ i }}
                 </mat-option>
-            </mat-select> -->
-            <button type="button" mat-icon-button color="primary" title="example button">
-              <mat-icon>add_box</mat-icon>
-            </button>
-            <!-- <button type="button" mat-icon-button color="primary" [disabled]="! enableAddButton" (click)="onAddClick()"
+            </mat-select>
+            <button type="button" mat-icon-button color="primary" [disabled]="! enableAddButton" (click)="onAddClick()"
               [title]="uitextAdd">
                 <mat-icon>add_box</mat-icon>
-            </button>
-            <button type="button" mat-icon-button color="primary" [disabled]="! enableCopyButton" (click)="onCopyClick()"
-              [title]="uitextCopy">
-                <mat-icon>content_copy</mat-icon>
-            </button>
-            |
+            </button> -->
             <button type="button" mat-icon-button color="primary" [disabled]="! enableRemoveButton" (click)="onRemoveClick()"
               [title]="uitextRemove">
                 <mat-icon>delete</mat-icon>
             </button>
-            <button type="button" mat-icon-button color="primary" [disabled]="! enableUpButton" (click)="onMoveUpClick()"
-              [title]="uitextMoveUp">
-                <mat-icon *ngIf="! selectionIsOneDevice">arrow_upward</mat-icon>
-                <mat-icon *ngIf="selectionIsOneDevice">arrow_back</mat-icon>
-            </button>
-            <button type="button" mat-icon-button color="primary" [disabled]="! enableDownButton" (click)="onMoveDownClick()"
-              [title]="uitextMoveDown">
-                <mat-icon *ngIf="! selectionIsOneDevice">arrow_downward</mat-icon>
-                <mat-icon *ngIf="selectionIsOneDevice">arrow_forward</mat-icon>
-            </button>
+            <!-- 
             |
             <button type="button" mat-icon-button color="primary" (click)="exportAsSpreadsheet()"
               [title]="uitextExportAsSpreadsheet">
@@ -51,12 +38,6 @@
         </div>
     </div>
 
-    <div *ngIf="error">{{ uitextDrawingError }}</div>
-
     <div id="schema" #schema></div>
 
-    <!-- <div *ngIf="showDebug">
-        <pre>{{ graphDef }}</pre>
-    </div> -->
-
 </mat-card-content>
diff --git a/src/app/components/pb-schema/pb-schema.component.scss b/src/app/components/pb-schema/pb-schema.component.scss
index 1b30459a2a99cf49a58b888f5615fc20dcb6ca0d..eccdfe35b464b52ef685a490a05e48478e83a489 100644
--- a/src/app/components/pb-schema/pb-schema.component.scss
+++ b/src/app/components/pb-schema/pb-schema.component.scss
@@ -3,22 +3,15 @@
 :host {
     display: block;
     width: 100%;
-    // reduce margins to avoid inner field-sets being too narrow on 360px display
-    /* margin-left: -8px;
-    margin-right: -8px; */
 }
 
 mat-card-header {
-    /* margin-left: -8px;
-    margin-right: -8px; */
     margin-left: -16px;
     margin-right: -16px;
     padding-left: 16px;
     padding-top: 8px;
     color: white;
 
-    // Pourquoi n'est-ce pas hérité de calculator.component.scss ?
-    // À cause de la surcharge de mat-card-header ci-dessus ?
     mat-card-title {
         font-size: 16px !important;
         margin-bottom: 8px;
@@ -30,7 +23,7 @@ mat-card-content {
 }
 
 #pb-schema-toolbar {
-    #edit-pab-table {
+    #add-basin {
         float: left;
     }
     .related-entity-title {
diff --git a/src/app/components/pb-schema/pb-schema.component.ts b/src/app/components/pb-schema/pb-schema.component.ts
index 02a921050786469d7930e3431f8ea802e9595840..a5556947341f19b025cd9cf35af3d0193f50f367 100644
--- a/src/app/components/pb-schema/pb-schema.component.ts
+++ b/src/app/components/pb-schema/pb-schema.component.ts
@@ -32,8 +32,6 @@ export class PbSchemaComponent implements AfterViewInit, OnInit {
     /** handle on SVG container */
     private nativeElement: any;
 
-    public error: boolean;
-
     /** flag de validité des FieldSet enfants */
     private _isValid = false;
 
@@ -66,14 +64,17 @@ export class PbSchemaComponent implements AfterViewInit, OnInit {
     }
 
     public ngAfterContentInit(): void {
-        this.error = false;
         mermaid.initialize({
             flowchart: {
                 curve: "basis"
             }
         });
         this.nativeElement = this.schema.nativeElement;
+        this.render();
+    }
 
+    private render() {
+        this.nativeElement.innerHTML = ""; // or diagram goes blank when refreshing…
         // generate graph description
         const graphDefinition = this.graphDefinition();
         // draw
@@ -83,10 +84,19 @@ export class PbSchemaComponent implements AfterViewInit, OnInit {
             });
         } catch (e) {
             console.error(e);
-            this.error = true;
         }
     }
 
+    /**
+     * Builds the interactive schema from the PreBarrage model
+     */
+    private refresh() {
+        console.log("riz fraîche");
+        this.render();
+        this.refreshEventListeners();
+        this.updateValidity();
+    }
+
     public ngAfterViewInit(): void {
         this.refreshEventListeners();
         this.updateValidity();
@@ -118,14 +128,16 @@ export class PbSchemaComponent implements AfterViewInit, OnInit {
         def.push(`${this.downstreamId}("${this.i18nService.localizeText("INFO_LIB_AVAL")}")`);
 
         // debug
-        const b1 = new PbBassin(new PbBassinParams(0.1, 42));
-        this.model.addChild(b1);
-        const b2 = new PbBassin(new PbBassinParams(0.15, 38));
-        this.model.addChild(b2);
-        this.model.addChild(new PbCloison(undefined, b1));
-        this.model.addChild(new PbCloison(b1, b2));
-        this.model.addChild(new PbCloison(b2, undefined));
-        this.model.addChild(new PbCloison(b1, undefined));
+        if (this.model.children.length === 0) {
+            const b1 = new PbBassin(new PbBassinParams(0.1, 42));
+            this.model.addChild(b1);
+            const b2 = new PbBassin(new PbBassinParams(0.15, 38));
+            this.model.addChild(b2);
+            this.model.addChild(new PbCloison(undefined, b1));
+            this.model.addChild(new PbCloison(b1, b2));
+            this.model.addChild(new PbCloison(b2, undefined));
+            this.model.addChild(new PbCloison(b1, undefined));
+        }
 
         for (const b of this.model.bassins) {
             // basin
@@ -257,108 +269,55 @@ export class PbSchemaComponent implements AfterViewInit, OnInit {
         if (item instanceof PbCloison) {
             const upstreamBasinName = item.bassinAmont === undefined
                 ? this.i18nService.localizeText("INFO_LIB_AMONT")
-                : "B" + (item.bassinAmont.findPositionInParent() + 1);
+                : "B" + (this.findBasinPosition(item.bassinAmont) + 1);
             const downstreamBasinName = item.bassinAval === undefined
                 ? this.i18nService.localizeText("INFO_LIB_AVAL")
-                : "B" + (item.bassinAval.findPositionInParent() + 1);
+                : "B" + (this.findBasinPosition(item.bassinAval) + 1);
             desc = upstreamBasinName + "-" + downstreamBasinName;
 
         } else if (item instanceof PbBassin) {
-            desc = this.i18nService.localizeText("INFO_PB_BASSIN_N") + (item.findPositionInParent() + 1);
+            desc = this.i18nService.localizeText("INFO_PB_BASSIN_N") + (this.findBasinPosition(item) + 1);
         } // else undefined
         return desc;
     }
 
-    /**
-     * Returns true if current cell is bound to a model that says its input value is
-     * no valid, or if characters typed in the input field are not a valid number
-     * (read from cell.uiValidity, see inputValueChanged() above)
-     */
-    /* public isInvalid(cell: any): boolean {
-        let valid = true;
-        if (this.hasModel(cell) && cell.model instanceof ParamDefinition) {
-            valid = valid && cell.model.isValid;
-        }
-        if (cell.uiValidity !== undefined) {
-            valid = valid && cell.uiValidity;
-        }
-        return ! valid;
-    } */
-
-    /**
-     * returns true if every wall (including downwall) has its nth device
-     * selected (or has no nth device)
-     */
-    /* public isDeviceColumnSelected(n: number): boolean {
-        let ok = true;
-        for (const c of this.model.children) {
-            const nthChild = c.getChildren()[n];
-            if (nthChild) {
-                ok = ok && this.selectedItems.includes(nthChild);
-            }
-        }
-        const nthChildDW = this.model.downWall.getChildren()[n];
-        if (nthChildDW) {
-            ok = ok && this.selectedItems.includes(nthChildDW);
-        }
-        return ok;
-    } */
-
-    // quick getter for 1st selected item
-    /* public get selectedItem() {
-        if (this.selectedItems.length === 0) {
-            throw new Error("get selectedItem() : no item selected");
+    private findBasinPosition(basin: PbBassin): number {
+        let i = 0;
+        for (const b of this.model.bassins) {
+            if (b === basin) break;
+            i++;
         }
-        return this.selectedItems[0];
-    } */
+        return i;
+    }
 
     // at this time @Input data is supposed to be already populated
     public ngOnInit() {
         this.model = this.pbSchema.pb;
-        this.refresh();
     }
 
-    /** Unselects all selected text (side-effect of shift+clicking) */
-    /* private clearSelection() {
-        if (window.getSelection) {
-            const sel = window.getSelection();
-            sel.removeAllRanges();
-        }
-    } */
+    public get enableRemoveButton() {
+        return (this._selectedItem !== undefined);
+    }
 
-    /**
-     * Builds the interactive schema from the PreBarrage model
-     */
-    private refresh() {
-        this.updateValidity();
+    /** Removes a basin or wall, and all related items */
+    public onRemoveClick() {
+        this.model.deleteChild(this._selectedItem.findPositionInParent());
+        this.refresh();
     }
 
-    /* public get relatedEntityTitle() {
-        let title = "";
-        if (this.onlyDevicesAreSelected()) {
-            title = this.i18nService.localizeText("INFO_PAB_OUVRAGES");
-        } else if (this.onlyWallsAreSelected()) {
-            title = this.i18nService.localizeText("INFO_PAB_BASSINS");
-        }
-        if (title !== "") {
-            title += " :";
-        }
-        return title;
+    public get uitextRemove() {
+        return this.i18nService.localizeText("INFO_FIELDSET_REMOVE");
     }
 
-    public get enableAddButton() {
-        return (
-            this.onlyDevicesOfTheSameColumnAreSelected()
-            || (
-                this.selectedItems.length === 1
-                && ! (this.selectedItem instanceof CloisonAval) // exclude downwall
-            )
-        );
+    public onAddBasinClick() {
+        console.log("Ajoute un bassin, coquin !");
+        this.model.addChild(new PbBassin(new PbBassinParams(20, 99)));
+        this.refresh();
     }
 
-    public get enableCopyButton() {
-        return this.enableAddButton;
-    } */
+    public get uitextAddBasin() {
+        return this.i18nService.localizeText("INFO_PB_ADD_BASIN");
+    }
 
     /**
      * Computes the global Pab validity : validity of every cell of every row
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index 09b6c4cfee0def998aac0f61c41ee7a0d781f515..57397c48de90b1358e0b4bfd158db69b58e02f49 100644
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -516,6 +516,7 @@
     "INFO_PARAMFIELD_VARIATED": "Variated",
     "INFO_PARAMMODE_LIST": "Values list",
     "INFO_PARAMMODE_MINMAX": "Min/max",
+    "INFO_PB_ADD_BASIN": "Add new basin",
     "INFO_PB_BASSIN_N": "Basin #",
     "INFO_PB_CLOISON": "Wall",
     "INFO_PB_SCHEMA": "Basins layout",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 8e418c3817598e549e360962f1eaa0accaf20703..3ff3a647d635f80893c04f4d25e902783ac3fcc9 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -517,6 +517,7 @@
     "INFO_PARAMFIELD_VARIATED": "Varié",
     "INFO_PARAMMODE_LIST": "Liste de valeurs",
     "INFO_PARAMMODE_MINMAX": "Min/max",
+    "INFO_PB_ADD_BASIN": "Ajouter un bassin",
     "INFO_PB_BASSIN_N": "Bassin n°",
     "INFO_PB_CLOISON": "Cloison",
     "INFO_PB_SCHEMA": "Organisation des bassins",