Select collectionsMat table rows based on mouse and Shift as Excel

i work with angular material table,my table contains a selection Model to handle the selected All and selected One and contains some columns and some rows.
what i have now that i can select all or select one element and all is good,
what i need is to handle the event Shift click as Excel to select the checkbox as a multiples rows.
and when i select a collection in same time there checkbox will be selected and i have the possibility to uncheck one one i click on it.(i found this behaviour in ag grid table but i need that with mat table )
my Html code is like that :

<ng-container matColumnDef="select">
  <th mat-header-cell *matHeaderCellDef>
    <mat-checkbox 
      id="allCheck" 
      (change)="setAllChekedOrUnchecked($event)"
      [checked]="isAllElementSelected" 
      [indeterminate]="iSsomeElementsSelected">
    </mat-checkbox>
  </th>
  <td mat-cell *matCellDef="let row">
    <mat-checkbox 
      [checked]="row.complete" 
      (click)="oneElementSelected($event, row)">
    </mat-checkbox>
  </td>
</ng-container>
<ng-container matColumnDef="entityCode">
  <th mat-header-cell *matHeaderCellDef>TOUTES</th>
  <td mat-cell *matCellDef="let element" style="cursor: pointer">
    <span (click)="openConfirmationDialog(element)">{{ element.entityCode }}</span>
  </td> 
</ng-container>`

my ts file :

dataSource!: MatTableDataSource<any>;
selection = new SelectionModel<Interclassement>(true, []);
selectedElements: Interclassement[] = [];

setAllChekedOrUnchecked($event: MatLegacyCheckboxChange) {
  this.dataSource.data.forEach(elt => {
    elt.complete = $event.checked;
  });
  this.isAllElementSelected = $event.checked;
  
  if ($event.checked) {
    this.selection.select(...this.dataSource.data);
  } else {
    this.selection.clear();
  }
  
  this.iSsomeElementsSelected = this.someElementsSelected();
}

iSsomeElementsSelected: boolean = false;

someElementsSelected() {
  return this.selection.selected.some(t => t.complete && !this.isAllElementSelected);
}

oneElementSelected($event: any, row: any) {
  if ($event.checked) {
    this.selection.select(row);
  } else {
    this.selection.deselect(row);
  }
  
  row.complete = $event.checked;
  this.isAllElementSelected = this.selection.selected.length === this.dataSource.data.length;
  this.iSsomeElementsSelected = this.someElementsSelected();
}

// Shift+Click logic : but it doesn't work.
lastSelectedId: number | null = null;

getRowRange(idA: number, idB: number): any[] {
  const rows = this.dataSource.data;
  const startIndex = rows.findIndex(row => row.id === idA);
  const endIndex = rows.findIndex(row => row.id === idB);

  if (startIndex === -1 || endIndex === -1) {
    throw new Error('Invalid row range');
  }

  const [from, to] = startIndex < endIndex ? [startIndex, endIndex] : [endIndex, startIndex];
  return rows.slice(from, to + 1);
}

toggleSelection(event: MouseEvent, row: any) {
  if (event.shiftKey && this.lastSelectedId !== null) {
    const rowsToToggle = this.getRowRange(this.lastSelectedId, row.id);
    const shouldSelect = !this.selection.isSelected(rowsToToggle[0]);

    rowsToToggle.forEach(row => {
      if (shouldSelect) {
        this.selection.select(row);
      } else {
        this.selection.deselect(row);
      }
    });
  } else {
    this.selection.toggle(row);
  }

  this.lastSelectedId = row.id;
}