diff --git a/libs/shared/src/features/data-table/data-table.component.html b/libs/shared/src/features/data-table/data-table.component.html
index b85436fc8..19cf6b8f5 100644
--- a/libs/shared/src/features/data-table/data-table.component.html
+++ b/libs/shared/src/features/data-table/data-table.component.html
@@ -19,10 +19,23 @@
@for(column of tableOptions.displayColumns; track column){
- {{ column }} |
- {{ el[column] }} |
+ {{ column | formatValue: tableOptions.formatHeader }} |
+
+
+ @if(valueTemplates[column]){
+
+
+ } @else {
+
+ {{ el[column] }}
+ }
+ |
}
+
string;
/** Bind to row click events */
handleRowClick?: (row: any) => void;
}
+/**
+ * Simple pipe that allows providing a custom formatter function,
+ * used to modify cell values in a pure way
+ */
+@Pipe({
+ standalone: true,
+ name: 'formatValue',
+})
+export class FormatValuePipe implements PipeTransform {
+ transform(value: T, formatter: (v: T) => U) {
+ if (!formatter) return value;
+ return formatter(value);
+ }
+}
+
/**
* The `picsa-data-table` component is a lightweight wrapper around `mat-table`, used
* to simplify display of basic tables.
- *
- * By default the table has support for sort, pagination and data search (filter)
+ * @example
+ * ```
+ *
+ * ```
+ * The table has support for sort, pagination and data search (filter),
+ * enabled by default and configurable by an options input @see IDataTableOptions
+ * @example
+ * ```
+ *
+ * ```
+ * The table will display all cell values directly, without any additional formatting
+ * If needing to render values within a custom template this can be done via `valueTemplates`
+ * @example
+ * ```
+ *
+ *
+ * {{value | modifierPipe}}
+ *
+ *
+ * ```
*
* For more advanced use cases such as custom column display prefer to directly use `mat-table`
*/
@@ -38,6 +84,7 @@ export interface IDataTableOptions {
standalone: true,
imports: [
CommonModule,
+ FormatValuePipe,
MatButtonModule,
MatFormFieldModule,
MatIconModule,
@@ -56,6 +103,13 @@ export class PicsaDataTableComponent implements OnChanges {
/** User option overrides */
@Input() options: IDataTableOptions = {};
+ /**
+ * Optional references to display specific column values in a custom template,
+ * indexed by column name. E.g. `{colA: myCustomTemplate}`
+ * https://angular.io/guide/content-projection#conditional-content-projection
+ */
+ @Input() valueTemplates: Record> = {};
+
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@@ -66,6 +120,7 @@ export class PicsaDataTableComponent implements OnChanges {
search: true,
sort: true,
handleRowClick: () => null,
+ formatHeader: (v) => v.split('_').map(capitalise).join(' '),
};
public dataSource: MatTableDataSource;
diff --git a/libs/utils/data.ts b/libs/utils/data.ts
index 226c4e398..7ff664814 100644
--- a/libs/utils/data.ts
+++ b/libs/utils/data.ts
@@ -84,3 +84,9 @@ export function jsonNestedProperty(obj: any, nestedPath: string) {
export function base64ToBlob(base64String, mimetype: string) {
return createBlobFromBase64(base64String, mimetype);
}
+
+/** Capitalise the first letter of a string */
+export function capitalise(str: string) {
+ if (typeof str !== 'string') return str;
+ return str.charAt(0).toUpperCase() + str.slice(1);
+}