<cds-table-container [cdsLayer]="layer"
                     [cdsTheme]="theme"
                     class="content-theme">
  <cds-table-header *ngIf="headerTitle">
    <h4 cdsTableHeaderTitle
        i18n>
      @if (isHeaderTitleString) {
        {{ headerTitle }}
    } @else {
      <ng-container *ngTemplateOutlet="headerTitle"></ng-container>
    }
    </h4>
    <p cdsTableHeaderDescription
       i18n
       *ngIf="headerDescription">
      {{headerDescription}}
    </p>
  </cds-table-header>
  <cds-table-toolbar #toolbar
                     *ngIf="toolHeader"
                     (cancel)="onBatchActionsCancel()"
                     [model]="selectionType === 'multiClick' ? model : []"
                     [batchText]="{ SINGLE: '1 item selected', MULTIPLE: '{{count}} items selected' }">
    <!-- batch actions -->
    <cds-table-toolbar-actions *ngIf="tableActions?.dropDownActions.length > 0">
      <ng-container *ngFor="let action of tableActions?.dropDownActions">
        <button *ngIf="tableActions.currentAction !== action"
                cdsButton="primary"
                [tabindex]="toolbar.selected ? 0 : -1"
                class="{{ tableActions.toClassName(action) }}"
                title="{{ tableActions.useDisableDesc(action) }}"
                (click)="tableActions.useClickAction(action)"
                [routerLink]="tableActions.useRouterLink(action)"
                [preserveFragment]="action.preserveFragment ? '' : null"
                [disabled]="tableActions.disableSelectionAction(action)"
                [attr.aria-label]="action.name"
                i18n>
          {{ action.name }}
        </button>
      </ng-container>
    </cds-table-toolbar-actions>
    <!-- end batch actions -->
    <cds-table-toolbar-content>
      <!-- search -->
      <cds-table-toolbar-search *ngIf="searchField"
                                [expandable]="false"
                                [(ngModel)]="search"
                                aria-label="search"
                                (valueChange)="updateFilter($event)"
                                (clear)="onClearSearch()">
      </cds-table-toolbar-search>
      <!-- end search -->
      <!-- column filters -->
      <ng-container *ngIf="columnFilters.length !== 0">
        <div class="d-inline-flex position-relative">
        <svg [cdsIcon]="icons.filter"
             [size]="icons.size16"></svg>
        </div>
        <cds-select (valueChange)="onSelectFilter($event)"
                    display="inline"
                    id="filter_name">
          <ng-container *ngFor="let filter of columnFilters">
            <option [value]="filter.column.name"
                    [selected]="filter.column.name === selectedFilter.column.name">{{ filter.column.name }}</option>
          </ng-container>
        </cds-select>
        <cds-select (valueChange)="onChangeFilter($event)"
                    display="inline"
                    id="filter_option">
          <option *ngIf="!selectedFilter.value"
                  i18n>Any</option>
          <ng-container *ngFor="let option of selectedFilter.options">
            <option [value]="option.raw"
                    [selected]="option.raw === selectedFilter?.value?.raw">{{ option.formatted }}</option>
          </ng-container>
        </cds-select>
      </ng-container>
      <!-- end column filters -->
      <!-- refresh button -->
      <cds-icon-button
              [kind]="status.type"
              [disabled]="!fetchData?.observers?.length"
              (click)="refreshBtn()"
              [title]="status.msg"
              [description]="status.msg"
              i18n-title
              i18n-description
              class="toolbar-action"
              placement="bottom"
              *ngIf="fetchData?.observers?.length > 0">
        <svg [cdsIcon]="icons.refresh"
             [size]="icons.size16"
             [ngClass]="{ 'cds--toolbar-action__icon': true, 'reload': loadingIndicator }"></svg>
      </cds-icon-button>
      <!-- end refresh button -->
      <!-- show hide columns -->
      <button cdsButton="ghost"
              class="toolbar-action"
              [cdsOverflowMenu]="showHideColumnsRef"
              placement="bottom"
              [flip]="true"
              [offset]="{ x: 3, y: 0 }">
        <svg [cdsIcon]="icons.dataTable"
             [size]="icons.size16"
             class="cds--toolbar-action__icon"></svg>
      </button>
      <ng-template #showHideColumnsRef>
        <div class="vstack gap-3 p-3"
             (click)="$event.stopPropagation()"
             [cdsTheme]="theme">
          <ng-container *ngFor="let column of localColumns">
            <cds-checkbox *ngIf="!column?.isInvisible"
                          id="{{ column.prop }}{{ tableName }}"
                          name="{{ column.prop }}{{ tableName }}"
                          [checked]="!column?.isHidden"
                          (checkedChange)="toggleColumn(column);">{{ column.name }}
          </cds-checkbox>
          </ng-container>
        </div>
      </ng-template>
      <!-- end show hide columns -->
      <!-- actions -->
      <ng-content select=".table-actions"></ng-content>
      <!-- end actions -->
    </cds-table-toolbar-content>
  </cds-table-toolbar>
  <!-- filter chips for column filters -->
  <div class="d-flex justify-content-end align-items-center filter-tags"
       *ngIf="toolHeader && columnFiltered">
  <div class="d-flex gap-2">
    <ng-container *ngFor="let filter of columnFilters">
      <cds-tag *ngIf="filter.value"
               type="outline"
               class="align-self-center">
        <span class="me-2">{{ filter.column.name }}: {{ filter.value.formatted }}</span>
        <button class="cds--tag__close-icon"
                (click)="onChangeFilter(filter)">
          <svg [cdsIcon]="icons.destroy"
               [size]="icons.size16"></svg>
        </button>
      </cds-tag>
    </ng-container>
    <button cdsButton="ghost"
            (click)="onClearFilters($event)">
      <ng-container i18n>Clear filters</ng-container>
    </button>
  </div>
  </div>
  <!-- end filter chips for column filters -->
  <table cdsTable
         [sortable]="sortable"
         [noBorder]="false"
         [size]="size"
         [striped]="false"
         [skeleton]="loadingIndicator">
    <thead cdsTableHead
           [sortable]="sortable"
           (deselectAll)="onDeselectAll()"
           (selectAll)="onSelectAll()"
           (sort)="changeSorting($event)"
           [model]="model"
           [selectAllCheckbox]="selectAllCheckbox"
           [selectAllCheckboxSomeSelected]="selectAllCheckboxSomeSelected"
           [showSelectionColumn]="showSelectionColumn"
           [enableSingleSelect]="enableSingleSelect"
           [skeleton]="loadingIndicator"
           [stickyHeader]="false">
    </thead>
    <tbody cdsTableBody
           *ngIf="!noData; else noDataTemplate"
           [enableSingleSelect]="enableSingleSelect"
           [skeleton]="loadingIndicator">
      <ng-container *ngFor="let row of model.data; let i = index; trackBy: trackByFn.bind(this, identifier)">
        <tr	cdsTableRow
            [model]="model"
            [row]="row"
            [size]="size"
            [selected]="model.isRowSelected(i)"
            [expandable]="model.isRowExpandable(i)"
            [expanded]="model.isRowExpanded(i)"
            [showSelectionColumn]="showSelectionColumn"
            [skeleton]="loadingIndicator"
            (selectRow)="onSelect(i)"
            (deselectRow)="onDeselect(i)"
            (expandRow)="model.expandRow(i, !model.isRowExpanded(i))"
            (rowClick)="onSelect(i)"
            *ngIf="!model.isRowFiltered(i)">
        </tr>
        <tr	cdsTableExpandedRow
            cdsExpandedRowHover
            *ngIf="model.isRowExpandable(i) && !shouldExpandAsTable(row) && !model.isRowFiltered(i)"
            [row]="row"
            [expanded]="model.isRowExpanded(i)"
            [skeleton]="loadingIndicator">
        </tr>
        <ng-container	*ngIf="model.isRowExpandable(i) && shouldExpandAsTable(row) && model.isRowExpanded(i) && !model.isRowFiltered(i)">
          <tr	cdsTableRow
              *ngFor="let expandedDataRow of firstExpandedDataInRow(row)"
              [model]="model"
              [showSelectionColumnCheckbox]="false"
              [showSelectionColumn]="showSelectionColumn"
              [row]="expandedDataRow"
              [size]="size"
              [selected]="model.isRowSelected(i)"
              [skeleton]="loadingIndicator">
          </tr>
        </ng-container>
      </ng-container>
    </tbody>
  </table>
  <cds-pagination [model]="model"
                  (selectPage)="onPageChange($event)"
                  [disabled]="limit === 0"
                  [skeleton]="loadingIndicator"
                  [pageInputDisabled]="limit === 0">
  </cds-pagination>
</cds-table-container>

<ng-template #noDataTemplate>
  <tbody>
    <tr cdstablerow>
      <td *ngIf="!rows?.length && !loadingIndicator"
          class="no-data"
          cdstabledata
          [attr.colspan]="visibleColumns.length + 2">
        <span class="d-flex justify-content-center align-items-center"
              i18n>No data to display</span>
      </td>
    </tr>
  </tbody>
</ng-template>

<ng-template #rowDetailTpl
             let-row="data">
  @if (row[identifier] === expanded?.[identifier] && !scrollable) {
  <div
    (mouseenter)="onRowDetailHover($event)"
    data-testid="datatable-row-detail">
    <ng-template [ngTemplateOutlet]="rowDetail.template"></ng-template>
  </div>
  } @else if (row[identifier] === expanded?.[identifier] && scrollable) {
  <div
    (mouseenter)="onRowDetailHover($event)"
    data-testid="datatable-row-detail"
    class="scrollable-expanded-row">
    <ng-template [ngTemplateOutlet]="rowDetail.template"></ng-template>
  </div>
  }
</ng-template>

<ng-template #defaultValueTpl
             let-value="data.value"
             let-expanded="expanded"
             let-column="data.column">
  <span [ngClass]="column?.cellClass">{{ value }}</span>
</ng-template>

<ng-template #tableActionTpl>
  <cds-overflow-menu *ngIf="tableActions?.dropDownActions.length > 1 && selectionType !== 'multiClick'"
                     [flip]="true"
                     data-testid="table-action-btn"
                     class="d-flex justify-content-end">
    <ng-container *ngFor="let action of tableActions?.dropDownActions">
      <cds-overflow-menu-option *ngIf="tableActions.currentAction !== action"
                                class="{{ tableActions.toClassName(action) }}"
                                title="{{ tableActions.useDisableDesc(action) }}"
                                (click)="tableActions.useClickAction(action)"
                                [routerLink]="tableActions.useRouterLink(action)"
                                [preserveFragment]="action.preserveFragment ? '' : null"
                                [disabled]="tableActions.disableSelectionAction(action)"
                                [attr.aria-label]="action.name"
                                data-testid="table-action-option-btn"
                                i18n>
        {{ action.name }}
      </cds-overflow-menu-option>
    </ng-container>
  </cds-overflow-menu>
</ng-template>


<!-- cell templates that can be accessed from outside -->
<ng-template #tableCellBoldTpl
             let-value="data.value">
  <strong>{{ value }}</strong>
</ng-template>

<ng-template #sparklineTpl
             let-row="data.row"
             let-value="data.value">
  <div class="position-relative">
    <cd-sparkline [data]="value"
                  [isBinary]="row.cdIsBinary"></cd-sparkline>
  </div>
</ng-template>

<ng-template #routerLinkTpl
             let-row="data.row"
             let-value="data.value">
  <a [routerLink]="[row.cdLink]"
     [queryParams]="row.cdParams">{{ value }}</a>
</ng-template>

<ng-template #checkIconTpl
             let-value="data.value">
@if (value | boolean) {
  <cd-icon type="check"></cd-icon>
}
</ng-template>

<ng-template #perSecondTpl
             let-row="data.row"
             let-value="data.value">
  {{ value | dimless }} /s
</ng-template>

<ng-template #executingTpl
             let-column="data.column"
             let-row="data.row"
             let-value="data.value">
  <i [ngClass]="[icons.spinner, icons.spin]"
     *ngIf="row.cdExecuting"></i>
  <span [ngClass]="column?.customTemplateConfig?.valueClass">
    {{ value }}
  </span>
  <span *ngIf="row.cdExecuting"
        [ngClass]="column?.customTemplateConfig?.executingClass ? column?.customTemplateConfig.executingClass : 'text-muted italic'">({{ row.cdExecuting }})</span>
</ng-template>
<ng-template #classAddingTpl
             let-value="data.value">
  <span *ngIf="value">
    <span *ngIf="!(value=='active')||(value=='expired')||(value=='pending')">
      {{ value }}
    </span>
    <cds-tag *ngIf="(value==='active')||(value=== 'expired')||(value=== 'pending')"
             class="{{ value | pipeFunction:useCustomClass:this }}">
       {{value}}
    </cds-tag>
  </span>
</ng-template>
<ng-template #tagTpl
             let-column="data.column"
             let-value="data.value">
  <span *ngFor="let item of (value | array); last as last">
    <cds-tag [size]="'md'"
             class="table-tag"
             [class]="(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.class) ? column.customTemplateConfig.map[item].class : (column?.customTemplateConfig?.class ? column.customTemplateConfig.class : 'tag-primary')"
             *ngIf="(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.value) ? column.customTemplateConfig.map[item].value : column?.customTemplateConfig?.prefix ? column.customTemplateConfig.prefix + item : item">
      {{(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.value) ? column.customTemplateConfig.map[item].value : column?.customTemplateConfig?.prefix ? column.customTemplateConfig.prefix + item : item }}
    </cds-tag>
    <span *ngIf="!last">&nbsp;</span>
  </span>
</ng-template>

<ng-template #mapTpl
             let-column="data.column"
             let-value="data.value">
  <span>{{ value | map:column?.customTemplateConfig }}</span>
</ng-template>

<ng-template #tooltipTpl
             let-column="data.column"
             let-value="data.value">
  <span *ngFor="let item of (value | array);">
    <cds-tag
      i18n
      i18n-ngbTooltip
      class="{{(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.class) ? column.customTemplateConfig.map[item].class : ''}}"
      ngbTooltip="{{(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.tooltip) ? column.customTemplateConfig.map[item].tooltip : ''}}">
      {{value}}
  </cds-tag>
  </span>
</ng-template>

<ng-template #truncateTpl
             let-column="data.column"
             let-value="data.value">
  <span data-toggle="tooltip"
        [title]="value">{{ value | truncate:column?.customTemplateConfig?.length:column?.customTemplateConfig?.omission }}</span>
</ng-template>

<ng-template #rowDetailsTpl
             let-row="data.row"
             let-isExpanded="data.expanded"
             ngx-datatable-cell-template>
  <a href="javascript:void(0)"
     [class.expand-collapse-icon-right]="!isExpanded"
     [class.expand-collapse-icon-down]="isExpanded"
     class="expand-collapse-icon tc_expand-collapse"
     title="Expand/Collapse Row"
     i18n-title
     (click)="toggleExpandRow(row, isExpanded, $event)">
  </a>
</ng-template>

<ng-template #timeAgoTpl
             let-value="data.value">
  <span data-toggle="tooltip"
        [title]="value | cdDate">{{ value | relativeDate }}</span>
</ng-template>

<ng-template #pathTpl
             let-value="data.value">
  <cd-copy-2-clipboard-button *ngIf="value"
                              [source]="value"
                              [byId]="false"
                              size="lg"
                              text="{{ value | path }}">
  </cd-copy-2-clipboard-button>
</ng-template>

<ng-template #copyTpl
             let-value="data.value">
  <cd-copy-2-clipboard-button *ngIf="value"
                              [source]="value"
                              [byId]="false"
                              [size]="lg"
                              [text]="value">
  </cd-copy-2-clipboard-button>
</ng-template>

<ng-template #editingTpl
             let-value="data.value"
             let-row="data.row"
             let-column="data.column">
  @if (isCellEditing(row?.[identifier], column?.prop)) {
  <form [formGroup]="formGroup"
        #formDir="ngForm">
    <div cdsRow>
      <div cdsCol>
        <cds-text-label [invalid]="formGroup.controls[row?.[identifier] + '-' + column?.prop]?.invalid && formGroup.controls[row?.[identifier] + '-' + column?.prop]?.dirty"
                        [invalidText]="errorTpl">
          <input type="text"
                 cdsText
                 size="sm"
                 [id]="row?.[identifier] + '-' + column?.prop"
                 [formControlName]="row?.[identifier] + '-' + column?.prop"
                 (input)="valueChange(row?.[identifier], column?.prop, $event.target.value)"
                 [invalid]="formGroup.controls[row?.[identifier] + '-' + column?.prop]?.invalid && formGroup.controls[row?.[identifier] + '-' + column?.prop]?.dirty">
        </cds-text-label>
        <ng-template #errorTpl>
          @for (errorKey of formGroup?.get(row?.[identifier] + '-' + column?.prop)?.errors | keyvalue; track $index) {
          @if (formGroup?.showError(row?.[identifier] + '-' + column?.prop, formDir, errorKey.key)) {
          <ng-container i18n>
            {{ column.customTemplateConfig?.errorMessages?.[errorKey.key] || ('Invalid ' + column.name) }}
          </ng-container>
          }}
        </ng-template>
      </div>
      <div cdsCol
           [columnNumbers]="{sm:1}"
           class="cds-p-0 cds-pt-3">
        <button cdsButton="ghost"
                size="sm"
                id="cell-inline-save-btn"
                type="button"
                (click)="saveCellItem(row, column?.prop)">
          <cd-icon type="check"></cd-icon>
        </button>
      </div>
    </div>
  </form>
  } @else {
  <div cdsRow>
    <div cdsCol
         class="cds-pt-3">
      {{ value }}
    </div>
    <div cdsCol
         [columnNumbers]="{lg: 5}"
         class="edit-btn">
      <button cdsButton="ghost"
              size="sm"
              id="cell-inline-edit-btn"
              (click)="editCellItem(row[identifier], column, value)">
        <cd-icon type="edit"></cd-icon>
      </button>
    </div>
  </div>
  }
</ng-template>

<ng-template #redirectTpl
             let-value="data.value"
             let-row="data.row"
             let-column="data.column">
@if (column.customTemplateConfig?.customRowProperty && row[column.customTemplateConfig?.customRowProperty]) {
  <a [routerLink]="row[column.customTemplateConfig?.customRowProperty]">{{value}}</a>
} @else if (column.customTemplateConfig?.redirectLink) {
  <a [routerLink]="column.customTemplateConfig?.redirectLink | redirectLinkResolver:value">{{value}}</a>
} @else {
  {{ value }}
}
</ng-template>
