diff --git a/projects/composition/src/app/api-data/cps-table.json b/projects/composition/src/app/api-data/cps-table.json index b2645850..365e2f63 100644 --- a/projects/composition/src/app/api-data/cps-table.json +++ b/projects/composition/src/app/api-data/cps-table.json @@ -29,6 +29,22 @@ "default": "field", "description": "A key used to retrieve the field from columns." }, + { + "name": "colFilterTypeName", + "optional": false, + "readonly": false, + "type": "string", + "default": "filterType", + "description": "A key used to retrieve the filter type from columns." + }, + { + "name": "colDateFormatName", + "optional": false, + "readonly": false, + "type": "string", + "default": "dateFormat", + "description": "A key used to retrieve the date format from columns." + }, { "name": "striped", "optional": false, @@ -141,6 +157,22 @@ "default": "false", "description": "Makes all columns sortable if columns prop is provided." }, + { + "name": "filterableByColumns", + "optional": false, + "readonly": false, + "type": "boolean", + "default": "false", + "description": "Enable filtering on all columns." + }, + { + "name": "autoColumnFilterType", + "optional": false, + "readonly": false, + "type": "boolean", + "default": "true", + "description": "If true, automatically detects filter type based on values, otherwise sets 'text' filter type for all columns.\nNote: This setting only takes effect if 'filterableByColumns' is true." + }, { "name": "sortMode", "optional": false, @@ -509,6 +541,14 @@ "default": "[]", "description": "Array of initial columns to show in the table. If not provided, all columns are initially visible." }, + { + "name": "renderDataAsHTML", + "optional": false, + "readonly": false, + "type": "boolean", + "default": "false", + "description": "If set to true, row data are rendered using innerHTML." + }, { "name": "data", "optional": false, diff --git a/projects/composition/src/app/pages/table-page/table-page.component.html b/projects/composition/src/app/pages/table-page/table-page.component.html index 0e906b2e..20d474e6 100644 --- a/projects/composition/src/app/pages/table-page/table-page.component.html +++ b/projects/composition/src/app/pages/table-page/table-page.component.html @@ -28,7 +28,7 @@ {{ item.a | uppercase }} - {{ item.b | date : 'MM/dd/yyyy' }} + {{ item.b | date: 'MM/dd/yyyy' }} {{ item.c | percent }} {{ item.d ? '✔' : '✘' }} @@ -47,7 +47,8 @@ [virtualScroll]="true" [showColumnsToggleBtn]="true" scrollHeight="500px" - toolbarTitle="Sortable table with virtual scroller, global filter and internal columns toggle"> + toolbarTitle="Sortable table with virtual scroller, global filter, internal columns toggle and with column filtering enabled" + [filterableByColumns]="true"> @@ -78,7 +79,7 @@ {{ item.a | uppercase }} - {{ item.b | date : 'MM/dd/yyyy' }} + {{ item.b | date: 'MM/dd/yyyy' }} {{ item.c | percent }} {{ item.d ? '✔' : '✘' }} @@ -117,7 +118,7 @@ {{ item.a | uppercase }} - {{ item.b | date : 'MM/dd/yyyy' }} + {{ item.b | date: 'MM/dd/yyyy' }} {{ item.c | percent }} {{ item.d ? '✔' : '✘' }} @@ -164,7 +165,7 @@ {{ item.a | uppercase }} - {{ item.b | date : 'MM/dd/yyyy' }} + {{ item.b | date: 'MM/dd/yyyy' }} {{ item.c | percent }} {{ item.d ? '✔' : '✘' }} @@ -193,7 +194,7 @@ {{ item.a | uppercase }} - {{ item.b | date : 'MM/dd/yyyy' }} + {{ item.b | date: 'MM/dd/yyyy' }} {{ item.c | percent }} {{ item.d ? '✔' : '✘' }} @@ -219,7 +220,7 @@ {{ item.a | uppercase }} - {{ item.b | date : 'MM/dd/yyyy' }} + {{ item.b | date: 'MM/dd/yyyy' }} {{ item.c | percent }} {{ item.d ? '✔' : '✘' }} @@ -248,5 +249,19 @@ toolbarTitle="Table in data loading state"> + + + + diff --git a/projects/composition/src/app/pages/table-page/table-page.component.ts b/projects/composition/src/app/pages/table-page/table-page.component.ts index 281374ac..bb4e9ac7 100644 --- a/projects/composition/src/app/pages/table-page/table-page.component.ts +++ b/projects/composition/src/app/pages/table-page/table-page.component.ts @@ -55,6 +55,21 @@ export class TablePageComponent implements OnInit { isRemoveBtnVisible = false; + renderAsHTML = true; + + dataWithHTML = [ + { + a: '

hello

', + b: '

world', + c: 'link to github' + }, + { + a: 'this is sanitized ', + b: '', + c: 'null === undefined' + } + ]; + data = [ { a: 'a1', @@ -332,12 +347,27 @@ export class TablePageComponent implements OnInit { selCols: { [key: string]: any }[] = []; - dataVirtual: { a: string; b: string; c: number }[] = []; + dataVirtual: { + a: string; + b: string; + c: number; + d: Date; + e: boolean; + f: Date; + }[] = []; colsVirtual = [ - { field: 'a', header: 'A' }, - { field: 'b', header: 'B' }, - { field: 'c', header: 'C' } + { field: 'a', header: 'String' }, + { field: 'b', header: 'String (only 5 distinct values)' }, + { field: 'c', header: 'Number' }, + { field: 'd', header: 'Date', dateFormat: 'dd. MM. yyyy' }, + { field: 'e', header: 'Boolean' }, + { + field: 'f', + header: 'Date but with category filter', + filterType: 'category', + dateFormat: 'yyyy/MM/dd HH:mm:ss' + } ]; componentData = ComponentData; @@ -348,9 +378,20 @@ export class TablePageComponent implements OnInit { } private _genVirtualData() { + const sevenRandomDates = Array.from( + { length: 7 }, + () => new Date(Math.round(Math.random() * 1e12)) + ); let c = 0.0; for (let i = 0; i <= 1000; i++) { - this.dataVirtual.push({ a: 'a' + i, b: 'b' + i, c }); + this.dataVirtual.push({ + a: 'a' + i, + b: 'b' + (i % 5), + c, + d: new Date(new Date().valueOf() - Math.random() * 1e12), + e: Math.random() > 0.5, + f: sevenRandomDates[i % 7] + }); c = parseFloat((c += 0.1).toFixed(1)); } diff --git a/projects/cps-ui-kit/src/lib/components/cps-table/cps-table.component.html b/projects/cps-ui-kit/src/lib/components/cps-table/cps-table.component.html index 534f9842..f6289efd 100644 --- a/projects/cps-ui-kit/src/lib/components/cps-table/cps-table.component.html +++ b/projects/cps-ui-kit/src/lib/components/cps-table/cps-table.component.html @@ -200,14 +200,45 @@ - - {{ col[colHeaderName] }} - + @if (filterableByColumns) { + + {{ col[colHeaderName] }} + + } @else { + + {{ col[colHeaderName] }} + + } - - {{ col[colHeaderName] }} - + @if (filterableByColumns) { + + {{ col[colHeaderName] }} + + } @else { + + {{ col[colHeaderName] }} + + } - - {{ rowData[col[colFieldName]] }} - + @if (renderDataAsHTML) { + + } @else { + + {{ + col[colDateFormatName] + ? (rowData[col[colFieldName]] | date: col[colDateFormatName]) + : rowData[col[colFieldName]] + }} + + } typeof item[column] === 'boolean')) { + return 'boolean'; + } else if (data.every((item) => typeof item[column] === 'number')) { + return 'number'; + } else if (data.every((item) => item[column] instanceof Date)) { + return 'date'; + } else if ( + data.reduce((acc, item) => acc.add(item[column]), new Set()).size < 6 + ) { + return 'category'; + } + return 'text'; + } +} diff --git a/projects/cps-ui-kit/src/public-api.ts b/projects/cps-ui-kit/src/public-api.ts index d9ab9093..544c266b 100644 --- a/projects/cps-ui-kit/src/public-api.ts +++ b/projects/cps-ui-kit/src/public-api.ts @@ -19,6 +19,7 @@ export * from './lib/components/cps-table/directives/cps-table-column-filter.dir export * from './lib/components/cps-table/directives/cps-table-header-selectable.directive'; export * from './lib/components/cps-table/directives/cps-table-row-selectable.directive'; export * from './lib/components/cps-table/cps-column-filter-types'; +export * from './lib/components/cps-table/pipes/cps-detect-filter-type.pipe'; export * from './lib/components/cps-tree-table/cps-tree-table.component'; export * from './lib/components/cps-tree-table/directives/cps-tree-table-column-sortable.directive'; export * from './lib/components/cps-tree-table/directives/cps-tree-table-column-filter.directive';