+
+ @if (data$ | async; as getDataResponse) {
+
+
+
+
+ @for (column of config.columns; track column) {
+ |
+ @if (column.headerCell) {
+ @if (typeof column.headerCell === 'boolean') {
+ {{ column.attribute }}
+ } @else {
+
+ @if (!column?.headerCell?.component) {
+ @if (typeof column.headerCell.value === 'string') {
+
+ }
+ } @else {
+
+ }
+ }
+ }
+ |
+ }
+
+
+
+ @for (item of getDataResponse?.data?.data; track item) {
+
+
+ @for (column of config.columns; track column) {
+ |
+ @if (column.valueCell) {
+ @if (typeof column.valueCell === 'boolean') {
+ {{ resolveValue(item, column) }}
+ } @else {
+ @if (!column.valueCell.component) {
+ {{ resolveValue(item, column, column.valueCell) }}
+ } @else {
+
+ }
+ }
+ }
+ |
+ }
+
+ }
+
+
+
+ @if ((getDataResponse?.data?.meta?.totalPages ?? 1) > 1) {
+
+
+
+
+
+
+
+ }
+ }
+
diff --git a/admin/src/app/components/generic-table/generic-table.ts b/admin/src/app/components/generic-table/generic-table.ts
new file mode 100644
index 0000000..27ca733
--- /dev/null
+++ b/admin/src/app/components/generic-table/generic-table.ts
@@ -0,0 +1,91 @@
+import { Component, inject, Input, OnInit } from '@angular/core';
+import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
+import { ColumnDefinition } from './column-definition.interface';
+import { AsyncPipe, NgClass, NgComponentOutlet } from '@angular/common';
+import { CellDefinition } from './cell-definition.interface';
+import { GetDataResponse } from './data-provider.interface';
+import { DomSanitizer } from '@angular/platform-browser';
+import { GenericTableConfig } from './generic-table.config';
+import { startWith, switchMap } from 'rxjs/operators';
+import { GenericTableSearchForm } from './generic-table-search-form/generic-table-search-form';
+
+@Component({
+ selector: 'app-generic-table',
+ templateUrl: './generic-table.html',
+ imports: [NgClass, AsyncPipe, NgComponentOutlet, GenericTableSearchForm],
+ standalone: true,
+})
+export class GenericTable