# Master Page

## Component nesting

- Vertical Layout
  - Filter Panel
    - Inputs
    - Additional filter action buttons
  - Toolbar (connected to Filter Panel and Grid)
    - Additional grid batch actions
  - Grid

## Implementation

### Template

```html
<mate-vertical-layout-ng theme="padding spacing" style="align-items: stretch;">
  <mate-filter-panel-ng (searchClick)="onSearch()" (resetClick)="onReset()">
    <mate-text-field-ng label="Username" (valueChanged)="usernameFilter = $event.detail.value"></mate-text-field-ng>
    <mate-text-field-ng label="Vorname" (valueChanged)="prenameFilter = $event.detail.value"></mate-text-field-ng>
    <mate-text-field-ng label="Nachname" (valueChanged)="familyNameFilter = $event.detail.value"></mate-text-field-ng>
  </mate-filter-panel-ng>
  <hr />
  <mate-toolbar-ng title-text="Users">
    <mate-button-ng (click)="onDelete()">Loeschen</mate-button-ng>
  </mate-toolbar-ng>
  <mate-grid-ng #grid [items]="items" theme="column-borders"
    [rowProvider]="rowProvider"
    [primaryActionColumnProvider]="primaryActionColumnProvider">
    <mate-grid-sort-column-ng header="Username" path="username" [resizable]="true"></mate-grid-sort-column-ng>
    <mate-grid-sort-column-ng header="Geburtstag" [resizable]="true" [renderer]="birthdateRenderer"></mate-grid-sort-column-ng>
    <mate-grid-sort-column-ng header="Geschlecht" [resizable]="true" [renderer]="genderRenderer"></mate-grid-sort-column-ng>
    <mate-grid-sort-column-ng header="Vorname" path="prename" [resizable]="true"></mate-grid-sort-column-ng>
    <mate-grid-sort-column-ng header="Nachname" path="familyName"></mate-grid-sort-column-ng>
  </mate-grid-ng>
</mate-vertical-layout-ng>
```

### Component

```typescript
@Component({
  selector: 'app-master-page',
  standalone: true,
  imports: [
    MateFilterPanelWrapperComponent,
    MateToolbarComponent,
    MateTextFieldComponent,
    MateButtonComponent,
    MateGridComponent,
    MateGridSortColumnComponent,
  ],
  templateUrl: './master-page.component.html',
})
export class MasterPageComponent {
  @ViewChild('grid') grid: any;

  items = [...allItems];
  usernameFilter = '';
  prenameFilter = '';
  familyNameFilter = '';

  rowProvider = (item: any) => {
    if (!item) return {};
    return { disabled: item.username.startsWith('s'), hasDetails: item.gender === DummyGender.Female };
  };

  primaryActionColumnProvider = (item: any) => {
    if (!item) return {};
    return {
      tooltipText: 'Aktionen fuer ' + item.username,
      children: [
        { text: 'Bearbeiten' },
        { text: 'Loeschen', disabled: true, tooltipText: 'Du kannst dieses Element nicht loeschen' },
        { text: 'Children', children: [
          { text: 'Test', tooltipText: 'My tooltip' },
          { text: 'Male', hidden: item.gender !== DummyGender.Male }
        ]}
      ]
    };
  };

  birthdateRenderer = (item: any) =>
    item.birthdate.toLocaleString('de-DE', { year: 'numeric', month: '2-digit', day: '2-digit' });

  genderRenderer = (item: any) =>
    item.gender === DummyGender.Female ? 'Weiblich' : item.gender === DummyGender.Male ? 'Maennlich' : 'Divers';

  private arrayFilter(value: string, property: string) {
    return (item: any) => {
      if (!value || value.length < 1) return true;
      const itemVal = item[property];
      if (!itemVal || itemVal.length < 1) return false;
      return itemVal.toLowerCase().includes(value.toLowerCase());
    };
  }

  onSearch() {
    this.items = allItems
      .filter(this.arrayFilter(this.usernameFilter, 'username'))
      .filter(this.arrayFilter(this.prenameFilter, 'prename'))
      .filter(this.arrayFilter(this.familyNameFilter, 'familyName'));
  }

  onReset() {
    this.usernameFilter = '';
    this.prenameFilter = '';
    this.familyNameFilter = '';
    this.items = [...allItems];
  }

  onDelete() {
    if (this.grid?.selectedItems) {
      this.grid.selectedItems.forEach((item: any) => allItems.splice(allItems.indexOf(item), 1));
      this.items = [...allItems];
    }
  }
}
```

For lazy loading examples see Grid component examples.