@smallpearl/ngx-helper 0.31.16 → 0.31.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/entity-field/src/entity-field.d.ts +2 -2
- package/fesm2022/smallpearl-ngx-helper-entity-field.mjs.map +1 -1
- package/fesm2022/smallpearl-ngx-helper-mat-entity-list.mjs +4 -2
- package/fesm2022/smallpearl-ngx-helper-mat-entity-list.mjs.map +1 -1
- package/fesm2022/smallpearl-ngx-helper-stationary-with-line-items.mjs +8 -3
- package/fesm2022/smallpearl-ngx-helper-stationary-with-line-items.mjs.map +1 -1
- package/package.json +12 -12
- package/stationary-with-line-items/src/stationary-with-line-items.component.d.ts +2 -0
|
@@ -12,7 +12,7 @@ export type SPEntityFieldSpec<TEntity extends {
|
|
|
12
12
|
[P in IdKey]: PropertyKey;
|
|
13
13
|
}, IdKey extends string = 'id'> = {
|
|
14
14
|
name: string;
|
|
15
|
-
label?: string
|
|
15
|
+
label?: string | Observable<string>;
|
|
16
16
|
valueOptions?: {
|
|
17
17
|
dateTimeFormat?: SPIntlDateFormat;
|
|
18
18
|
isCurrency?: boolean;
|
|
@@ -50,7 +50,7 @@ export declare class SPEntityField<TEntity extends {
|
|
|
50
50
|
/**
|
|
51
51
|
* @returns the label for the field.
|
|
52
52
|
*/
|
|
53
|
-
label(): string
|
|
53
|
+
label(): string | Observable<string>;
|
|
54
54
|
/**
|
|
55
55
|
* Given an entity, returns the value of the field matching the
|
|
56
56
|
* SPEntityFieldSpec<> in fieldSpec.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smallpearl-ngx-helper-entity-field.mjs","sources":["../../../../projects/smallpearl/ngx-helper/entity-field/src/entity-field.ts","../../../../projects/smallpearl/ngx-helper/entity-field/src/provider.ts","../../../../projects/smallpearl/ngx-helper/entity-field/smallpearl-ngx-helper-entity-field.ts"],"sourcesContent":["import {\n spFormatCurrency,\n spFormatDate,\n SPIntlDateFormat,\n} from '@smallpearl/ngx-helper/locale';\nimport { SPEntityFieldConfig } from './provider';\nimport { Observable } from 'rxjs';\n\ntype FieldValueTypes = string | number | Date | boolean;\n\n/**\n * This structure defines the data formatting details for a field of the\n * entity. All entity fields need not necessarily be actual entity object's\n * properties. Fields can also be computed fields, in which case the valueFn\n * should be initialized with a valid function to provide the field's value.\n */\nexport type SPEntityFieldSpec<TEntity extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'> = {\n // Column name. If valueFn is not specified, this will be used as the\n // key name to retrieve the value for the column from TEntity.\n name: string;\n // If omitted, 'name' will be used as field label.\n label?: string
|
|
1
|
+
{"version":3,"file":"smallpearl-ngx-helper-entity-field.mjs","sources":["../../../../projects/smallpearl/ngx-helper/entity-field/src/entity-field.ts","../../../../projects/smallpearl/ngx-helper/entity-field/src/provider.ts","../../../../projects/smallpearl/ngx-helper/entity-field/smallpearl-ngx-helper-entity-field.ts"],"sourcesContent":["import {\n spFormatCurrency,\n spFormatDate,\n SPIntlDateFormat,\n} from '@smallpearl/ngx-helper/locale';\nimport { SPEntityFieldConfig } from './provider';\nimport { Observable } from 'rxjs';\n\ntype FieldValueTypes = string | number | Date | boolean;\n\n/**\n * This structure defines the data formatting details for a field of the\n * entity. All entity fields need not necessarily be actual entity object's\n * properties. Fields can also be computed fields, in which case the valueFn\n * should be initialized with a valid function to provide the field's value.\n */\nexport type SPEntityFieldSpec<TEntity extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'> = {\n // Column name. If valueFn is not specified, this will be used as the\n // key name to retrieve the value for the column from TEntity.\n name: string;\n // If omitted, 'name' will be used as field label.\n label?: string|Observable<string>;\n // Column value specific formatting options. Currently, only used for\n // Date types.\n valueOptions?: {\n // Specify the same format string argument that is passed to DatePipe.\n dateTimeFormat?: SPIntlDateFormat;\n // If boolean, number field will be formatted using spFormatCurrency()\n // using the current currency or 'currency' value below.\n isCurrency?: boolean;\n // Currency code, if different from default locale.\n currency?: string;\n // CSS class name; if provided will be applied to field value's wrapper\n // element. This will be <td> & <th>.\n class?: string;\n // Alignment options. Field's value will be aligned based on this.\n alignment?: 'start'|'center'|'end';\n // A fixed string or a function that returns an array of strings\n // to be used as the routerlink for the column value.\n routerLink?: ((e: TEntity) => string[])|[string];\n };\n // If the column value cannot be derived by simple TEntity[name] lookup,\n // use this function to return a custom computed or formatted value.\n valueFn?: (item: TEntity) => FieldValueTypes | Observable<FieldValueTypes>;\n};\n\n/**\n * A class that represents a SPEntityFieldSpec<>. This is typically used\n * by the library to evaluate a SPEntityFieldSpec<> object.\n */\nexport class SPEntityField<TEntity extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'> {\n public _fieldSpec!: SPEntityFieldSpec<TEntity, IdKey>;\n\n constructor(\n spec: SPEntityFieldSpec<TEntity, IdKey> | string,\n public fieldConfig?: SPEntityFieldConfig\n ) {\n if (typeof spec === 'string') {\n this._fieldSpec = {\n name: spec,\n };\n } else {\n this._fieldSpec = spec;\n }\n }\n\n get spec() {\n return this._fieldSpec;\n }\n\n /**\n * Returns the effective fieldValueOptions by merging the global field\n * options (if one has been spefified) with the local field value options.\n * @returns SPEntityFieldSpec<any>['valueOptions']\n */\n get options() {\n let globalFieldValueOptions: SPEntityFieldSpec<any>['valueOptions'] = {};\n if (this.fieldConfig && this.fieldConfig?.fieldValueOptions && this.fieldConfig.fieldValueOptions.has(this._fieldSpec.name)) {\n globalFieldValueOptions = this.fieldConfig.fieldValueOptions.get(this._fieldSpec.name);\n }\n return {\n ...globalFieldValueOptions,\n ...(this._fieldSpec?.valueOptions ?? {})\n };\n }\n /**\n * @returns the label for the field.\n */\n label() {\n return this._fieldSpec.label ?? this._fieldSpec.name\n }\n\n /**\n * Given an entity, returns the value of the field matching the\n * SPEntityFieldSpec<> in fieldSpec.\n * @param entity TEntity instance which will be evaluated for\n * SPEntityFieldSpec<>.\n * @returns\n */\n value(entity: TEntity) {\n let val = undefined;\n if (!this._fieldSpec.valueFn) {\n if (\n this.fieldConfig &&\n this.fieldConfig?.fieldValueFns &&\n this.fieldConfig.fieldValueFns.has(this._fieldSpec.name)\n ) {\n val = this.fieldConfig.fieldValueFns.get(this._fieldSpec.name)!(entity, this._fieldSpec.name);\n } else {\n val = (entity as any)[this._fieldSpec.name];\n }\n } else {\n val = this._fieldSpec.valueFn(entity);\n }\n const valueOptions = this.options;\n if (val instanceof Date) {\n val = spFormatDate(val);\n } else if (\n typeof val === 'number' &&\n valueOptions?.isCurrency\n ) {\n val = spFormatCurrency(val, this._fieldSpec?.valueOptions?.currency);\n } else if (typeof val === 'boolean') {\n val = val ? '✔' : '✖';\n }\n return val;\n }\n\n /**\n * If specified, will be added to the CSS classes of the field's wrapper\n * element.\n */\n get class() {\n return this._fieldSpec?.valueOptions?.class ?? '';\n }\n\n hasRouterLink(entity: TEntity) {\n return !!this._fieldSpec?.valueOptions?.routerLink;\n }\n\n getRouterLink(entity: TEntity) {\n const rl = this._fieldSpec?.valueOptions?.routerLink;\n if (rl) {\n if (typeof rl == 'function') {\n return rl(entity);\n }\n return rl\n }\n return [];\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { SPEntityFieldSpec } from './entity-field';\n\n\nexport type FIELD_VALUE_FN = (entity: any, fieldName: string) => string|number|Date|boolean;\n\n/**\n * Global config for SPEntityField component.\n */\nexport interface SPEntityFieldConfig {\n /**\n * These are global field value functions.\n *\n * If a value function for a field is not explicitly specified, this map is\n * looked up with the field name. If an entry exists in this table, it will\n * be used to render the field's value.\n *\n * This is useful for formatting certain fields which tend to have the\n * same name across the app. For instance fields such as 'amount', 'total'\n * or 'balance'. Or 'date', 'timestamp', etc.\n */\n fieldValueFns?: Map<string, FIELD_VALUE_FN>;\n /**\n * Similar to above, but allows setting the options for certain fields\n * globally. As in the case of `fieldValueFns`, the per field specification,\n * if one exists, takes precedence over the global setting.\n */\n fieldValueOptions?: Map<string, SPEntityFieldSpec<any>['valueOptions']>;\n}\n\nexport const SP_ENTITY_FIELD_CONFIG = new InjectionToken<SPEntityFieldConfig>(\n 'SPEntityFieldConfig'\n);\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ import { withEntities, selectAllEntities, getEntitiesCount, addEntities, hasEnti
|
|
|
22
22
|
import { SPEntityField, SP_ENTITY_FIELD_CONFIG } from '@smallpearl/ngx-helper/entity-field';
|
|
23
23
|
import { InfiniteScrollDirective } from 'ngx-infinite-scroll';
|
|
24
24
|
import { plural } from 'pluralize';
|
|
25
|
-
import { Subscription, Subject, takeUntil, tap, filter, distinctUntilChanged, switchMap, finalize,
|
|
25
|
+
import { Subscription, Subject, takeUntil, tap, filter, distinctUntilChanged, switchMap, finalize, Observable, of } from 'rxjs';
|
|
26
26
|
|
|
27
27
|
const SP_MAT_ENTITY_LIST_HTTP_CONTEXT = new HttpContextToken(() => ({
|
|
28
28
|
entityName: '',
|
|
@@ -639,7 +639,9 @@ class SPMatEntityListComponent {
|
|
|
639
639
|
}
|
|
640
640
|
getColumnLabel(field) {
|
|
641
641
|
if (field._fieldSpec.label) {
|
|
642
|
-
return
|
|
642
|
+
return field._fieldSpec.label instanceof Observable
|
|
643
|
+
? field._fieldSpec.label
|
|
644
|
+
: of(field._fieldSpec.label);
|
|
643
645
|
}
|
|
644
646
|
if (this.entityListConfig && this.entityListConfig.columnLabelFn) {
|
|
645
647
|
const label = this.entityListConfig.columnLabelFn(this.entityName(), field._fieldSpec.name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smallpearl-ngx-helper-mat-entity-list.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-entity-list/src/mat-entity-list-types.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-list/src/providers.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-list/src/config.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-list/src/mat-entity-list.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-list/smallpearl-ngx-helper-mat-entity-list.ts"],"sourcesContent":["import { HttpContextToken } from \"@angular/common/http\";\nimport { Observable } from \"rxjs\";\n\nexport interface SPMatEntityListHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n}\n\nexport const SP_MAT_ENTITY_LIST_HTTP_CONTEXT =\n new HttpContextToken<SPMatEntityListHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n }));\n\n/**\n * Pagination HTTP request params. Actually copied from Angular's HttpParams\n * declaration. The ReadonlyArray<string|number|boolean> is a bit of an\n * overkill for pagination params, but what the heck. When you copy-paste,\n * do it in full!\n */\nexport type SPPageParams = { [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>; }\n\n/**\n * An interface that the clients should provide, either via a global config\n * (see above), that handles parsing the GET response and returns the entities\n * stored therein. This class will allow the entity-list component to be\n * used across different pagination response types as long as the appropriate\n * SPMatEntityListPaginator class is provided to the component.\n */\nexport interface SPMatEntityListPaginator {\n getRequestPageParams: (endpoint: string, pageIndex: number, pageSize: number) => SPPageParams;\n parseRequestResponse: <\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >(\n entityName: string,\n entityNamePlural: string,\n endpoint: string,\n params: SPPageParams,\n resp: any\n ) => { total: number; entities: TEntity[] };\n}\n\n/**\n * 'entity' is really TEntity arg of SPMatEntityListComponent<TEntity>.\n * 'column' is the column name. This allows the same value function to support\n * multiple columns further enabing DRY.\n */\nexport type COLUMN_VALUE_FN = (entity: any, column: string) => string|number|Date|boolean;\n\n/**\n * Global config for SPMatEntityList component.\n */\nexport interface SPMatEntityListConfig {\n urlResolver?: (endpoint: string) => string;\n paginator?: SPMatEntityListPaginator;\n defaultPageSize?: number;\n pageSizes?: Array<number>;\n /**\n * Provide a method to return the labels for the columns. This is useful when\n * the columns are specified as the JSON object key names and the labels are\n * to be transformed into a uniform manner (uppercase) or when the labels\n * are to be dynamically localized. Note that the response can be an\n * Observable<string> if the label is to be fetched/changed asynchronously\n * (as that can happen in an app that supports dynamic changing of the UI\n * language).\n * @param entityName\n * @param columnName\n * @returns\n */\n columnLabelFn?: (entityName: string, columnName: string) => string | Observable<string>;\n}\n\n/**\n * Type for custom entities loader function, which if provided will be called\n * instead of HttpClient.get.\n */\nexport type SPMatEntityListEntityLoaderFn = (params: any) => Observable<any>;\n","import { InjectionToken } from '@angular/core';\nimport { SPMatEntityListConfig } from './mat-entity-list-types';\n\nexport const SP_MAT_ENTITY_LIST_CONFIG = new InjectionToken<SPMatEntityListConfig>(\n 'SPMatEntityListConfig'\n);\n","import { inject } from '@angular/core';\nimport { SPMatEntityListConfig } from './mat-entity-list-types';\nimport { SP_MAT_ENTITY_LIST_CONFIG } from './providers';\n\nexport const DefaultSPMatEntityListConfig: SPMatEntityListConfig = {\n urlResolver: (endpoint: string) => endpoint,\n paginator: undefined,\n defaultPageSize: 50,\n pageSizes: [10, 25, 50, 100],\n columnLabelFn: (entityName: string, columnName: string) => columnName,\n};\n\n/**\n * To be called from an object's constructor.\n */\nexport function getEntityListConfig(): SPMatEntityListConfig {\n const entityListConfig = inject(SP_MAT_ENTITY_LIST_CONFIG, {\n optional: true,\n });\n return {\n ...DefaultSPMatEntityListConfig,\n ...(entityListConfig ?? {}),\n };\n}\n","import { CommonModule } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken, HttpParams } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ContentChildren,\n Directive,\n effect,\n ElementRef,\n EventEmitter,\n inject,\n Injector,\n input,\n OnDestroy,\n OnInit,\n Output,\n QueryList,\n runInInjectionContext,\n signal,\n viewChild,\n viewChildren\n} from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatPaginatorModule, PageEvent } from '@angular/material/paginator';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatSort, MatSortModule } from '@angular/material/sort';\nimport {\n MatColumnDef,\n MatTable,\n MatTableDataSource,\n MatTableModule,\n} from '@angular/material/table';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { RouterModule } from '@angular/router';\nimport { createStore } from '@ngneat/elf';\nimport {\n addEntities,\n deleteEntities,\n getEntitiesCount,\n hasEntity,\n selectAllEntities,\n updateEntities,\n upsertEntities,\n withEntities,\n} from '@ngneat/elf-entities';\nimport {\n SP_ENTITY_FIELD_CONFIG,\n SPEntityField,\n SPEntityFieldSpec\n} from '@smallpearl/ngx-helper/entity-field';\nimport { InfiniteScrollDirective } from 'ngx-infinite-scroll';\nimport { plural } from 'pluralize';\nimport {\n distinctUntilChanged,\n filter,\n finalize,\n Observable,\n of,\n Subject,\n Subscription,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs';\nimport { getEntityListConfig } from './config';\nimport {\n SP_MAT_ENTITY_LIST_HTTP_CONTEXT,\n SPMatEntityListEntityLoaderFn,\n SPMatEntityListPaginator\n} from './mat-entity-list-types';\n\n@Directive({\n selector: '[headerAlignment]',\n standalone: true\n})\nexport class HeaderAlignmentDirective implements AfterViewInit {\n\n headerAlignment = input<string>();\n\n constructor(private el: ElementRef) {\n // this.el.nativeElement.style.backgroundColor = 'yellow';\n }\n\n ngAfterViewInit(): void {\n if (this.headerAlignment()) {\n const sortHeader = this.el.nativeElement.querySelector('.mat-sort-header-container');\n if (sortHeader) {\n sortHeader.style.justifyContent = this.headerAlignment();\n } else {\n this.el.nativeElement.style.justifyContent = this.headerAlignment();\n }\n }\n }\n}\n\n/**\n * Represents a request to load entities from the remote. This is used to\n * compare two requests to determine if they are equal. This is useful to\n * prevent duplicate requests being sent to the remote.\n */\nclass LoadRequest {\n constructor(\n public endpoint: string,\n public params: HttpParams,\n public force = false\n ) {}\n\n // Returns true if two LoadRequest objects are equal and this object's\n // 'force' is not set to true.\n isEqualToAndNotForced(prev: LoadRequest): boolean {\n // console.log(\n // `isEqualToAndNotForced - ${this.endpoint}, ${this.params.toString()} ${\n // this.force\n // }, other: ${prev.endpoint}, ${prev.params.toString()}, ${prev.force}`\n // );\n return this.force\n ? false\n : this.endpoint.localeCompare(prev.endpoint) === 0 &&\n this.params.toString().localeCompare(prev.params.toString()) === 0;\n }\n}\n\n/**\n * A component to display a list of entities loaded from remote.\n */\n@Component({\n imports: [\n CommonModule,\n RouterModule,\n MatTableModule,\n MatSortModule,\n MatPaginatorModule,\n MatButtonModule,\n MatInputModule,\n MatProgressSpinnerModule,\n InfiniteScrollDirective,\n HeaderAlignmentDirective,\n ],\n selector: 'sp-mat-entity-list',\n template: `\n <div\n class=\"entities-list-wrapper\"\n infiniteScroll\n [infiniteScrollDistance]=\"infiniteScrollDistance()\"\n [infiniteScrollThrottle]=\"infiniteScrollThrottle()\"\n [infiniteScrollContainer]=\"infiniteScrollContainer()\"\n [scrollWindow]=\"infiniteScrollWindow()\"\n [infiniteScrollDisabled]=\"\n pagination() !== 'infinite' || !_paginator || !hasMore()\n \"\n (scrolled)=\"infiniteScrollLoadNextPage($event)\"\n >\n <div\n class=\"busy-overlay\"\n [ngClass]=\"{ show: pagination() === 'discrete' && loading() }\"\n >\n <ng-container *ngTemplateOutlet=\"busySpinner\"></ng-container>\n </div>\n <table mat-table [dataSource]=\"dataSource()\">\n <tr mat-header-row *matHeaderRowDef=\"_displayedColumns()\"></tr>\n <tr\n mat-row\n [class.active-row]=\"activeEntityId() === row[this.idKey()]\"\n *matRowDef=\"let row; columns: _displayedColumns()\"\n (click)=\"toggleActiveEntity(row)\"\n ></tr>\n </table>\n @if (pagination() == 'discrete' && _paginator) {\n <mat-paginator\n showFirstLastButtons\n [length]=\"entityCount()\"\n [pageSize]=\"_pageSize()\"\n [pageIndex]=\"pageIndex()\"\n [pageSizeOptions]=\"[]\"\n [hidePageSize]=\"true\"\n (page)=\"handlePageEvent($event)\"\n [disabled]=\"loading()\"\n aria-label=\"Select page\"\n ></mat-paginator>\n }\n <div\n class=\"infinite-scroll-loading\"\n [ngClass]=\"{ show: pagination() === 'infinite' && loading() }\"\n >\n <ng-container *ngTemplateOutlet=\"busySpinner\"></ng-container>\n </div>\n </div>\n <!-- We keep the column definitions outside the <table> so that they can\n be dynamically added to the MatTable. -->\n <span matSort=\"sorter()\">\n @for (column of __columns(); track $index) {\n <ng-container [matColumnDef]=\"column.spec.name\">\n @if (disableSort()) {\n <th\n [class]=\"column.class\"\n [headerAlignment]=\"column.options.alignment\"\n mat-header-cell\n *matHeaderCellDef\n >\n {{ getColumnLabel(column) | async }}\n </th>\n } @else {\n <th\n [class]=\"column.class\"\n [headerAlignment]=\"column.options.alignment\"\n mat-header-cell\n mat-sort-header\n *matHeaderCellDef\n >\n {{ getColumnLabel(column) | async }}\n </th>\n }\n <td\n [class]=\"column.class\"\n [style.text-align]=\"column.options.alignment\"\n mat-cell\n *matCellDef=\"let element\"\n [routerLink]=\"column.getRouterLink(element)\"\n >\n @if (column.hasRouterLink(element)) {\n <a [routerLink]=\"column.getRouterLink(element)\">\n <span [innerHTML]=\"column.value(element)\"></span>\n </a>\n } @else { @let val = column.value(element);\n <span [innerHTML]=\"isAsync(val) ? (val | async) : val\"></span>\n }\n </td>\n </ng-container>\n }\n </span>\n <ng-template #busySpinner>\n <div class=\"busy-spinner\">\n <mat-spinner mode=\"indeterminate\" diameter=\"28\"></mat-spinner>\n </div>\n </ng-template>\n `,\n styles: [\n `\n .entities-list-wrapper {\n position: relative;\n }\n .busy-overlay {\n display: none;\n height: 100%;\n width: 100%;\n position: absolute;\n top: 0px;\n left: 0px;\n z-index: 1000;\n opacity: 0.6;\n background-color: transparent;\n }\n .show {\n display: block;\n }\n .busy-spinner {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .infinite-scroll-loading {\n display: none;\n width: 100%;\n padding: 8px;\n }\n .active-row {\n font-weight: bold;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SPMatEntityListComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> implements OnInit, OnDestroy, AfterViewInit\n{\n /* CLIENT PROVIDED PARAMETERS */\n entityName = input.required<string>();\n entityNamePlural = input<string>();\n\n /**\n * The endpoint from where the entities are to be retrieved\n */\n endpoint = input<string>('');\n /**\n * Custom entities loader function, which if provided will be called\n * instead of HttpClient.get.\n */\n entityLoaderFn = input<SPMatEntityListEntityLoaderFn | undefined>(undefined);\n /**\n * The columns of the entity to be displayed. This is an array of\n * SPEntityFieldSpec objects. If there's a one-to-one mapping between the\n * column's field name, its title & the rendered value, a string can be\n * specified instead. That is, the value of this property is a heterogeneous\n * array consisting of SPEntityFieldSpec<> objects and strings.\n */\n columns = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>>([]);\n\n /**\n * Names of columns that are displayed. This will default to all the columns\n * listed in columns.\n */\n displayedColumns = input<string[]>([]); // ['name', 'cell', 'gender'];\n\n /**\n * Number of entities per page. If this is not set and paginator is defined,\n * the number of entities int in the first request, will be taken as the\n * page size.\n */\n pageSize = input<number>(0);\n /**\n * Entity idKey, if idKey is different from the default 'id'.\n */\n idKey = input<string>('id');\n /**\n * Type of pagination -- continuous or discrete. 'infinite' pagination\n * uses an 'infiniteScroll' and 'discrete' pagination uses a mat-paginator\n * at the bottom to navigate between pages.\n */\n pagination = input<'infinite' | 'discrete' | 'none'>('discrete');\n /**\n * Component specific paginator. Only used if pagination != 'none'.\n */\n paginator = input<SPMatEntityListPaginator>();\n /**\n *\n */\n sorter = input<MatSort>();\n /**\n * Disable sorting of rows\n */\n disableSort = input<boolean>(false);\n /**\n * Wrappers for infiniteScroll properties, for customization by the client\n */\n infiniteScrollContainer = input<any>('');\n infiniteScrollDistance = input<number>(1);\n infiniteScrollThrottle = input<number>(400);\n infiniteScrollWindow = input<boolean>(false);\n /**\n * Custom context to be set for HttpClient requests. In the client code\n * specify this property by initializing a member variable as:\n\n ```\n Component({\n ...\n template: `\n <sp-mat-entity-list\n [httpReqContext]=\"httpReqContext\"\n ></sp-mat-entity-list>\n `\n })\n export class YourComponent {\n httpReqContext: [HttpContextToken<any>, any] = [\n SIDELOAD_TO_COMPOSITE_PARAMS, 'customers'\n ];\n }\n ```\n *\n * Of course if you want to pass multiple context properties, declare the type\n * as an array of array. That is, `[[HttpContextToken<any>, any]]` and\n * initialize it appropriately.\n */\n httpReqContext = input<\n [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]\n >();\n /* END CLIENT PROVIDED PARAMETERS */\n\n // *** INTERNAL *** //\n _entityNamePlural = computed(() =>\n this.entityNamePlural()\n ? this.entityNamePlural()\n : plural(this.entityName())\n );\n\n _httpReqContext = computed(() => {\n let reqContext = this.httpReqContext();\n const context = new HttpContext();\n if (reqContext && Array.isArray(reqContext)) {\n if (reqContext.length == 2 && !Array.isArray(reqContext[0])) {\n // one dimensional array of a key, value pair.\n context.set(reqContext[0], reqContext[1]);\n } else {\n reqContext.forEach(([k, v]) => context.set(k, v));\n }\n }\n context.set(SP_MAT_ENTITY_LIST_HTTP_CONTEXT, {\n entityName: this.entityName(),\n entityNamePlural: this._entityNamePlural(),\n endpoint: this.endpoint(),\n });\n return context;\n });\n deferViewInit = input<boolean>(false);\n firstLoadDone = false;\n allColumnNames = signal<string[]>([]);\n _displayedColumns = computed(() =>\n this.displayedColumns().length > 0\n ? this.displayedColumns().filter(\n (colName) =>\n this.allColumnNames().find((name) => name === colName) !== undefined\n )\n : this.allColumnNames()\n );\n dataSource = signal<MatTableDataSource<TEntity>>(\n new MatTableDataSource<TEntity>()\n );\n\n table = viewChild(MatTable);\n sort = viewChild(MatSort);\n // These are our own <ng-container matColumnDef></ng-container>\n // which we create for each column that we create by the declaration:\n // <ng-container *ngFor=\"let column of columns()\" [matColumnDef]=\"column.name\">\n viewColumnDefs = viewChildren(MatColumnDef);\n // These are the <ng-container matColumnDef></ng-container> placed\n // inside <sp-mat-entity-list></<sp-mat-entity-list> by the client to override\n // the default <ng-container matColumnDef> created by the component.\n @ContentChildren(MatColumnDef) clientColumnDefs!: QueryList<MatColumnDef>;\n\n contentColumnDefs: MatColumnDef[] = [];\n\n subs$ = new Subscription();\n destroy$ = new Subject<void>();\n\n // Pagination state\n entityCount = signal<number>(0);\n pageIndex = signal<number>(0);\n\n // Mechanism to default pageSize to last entities length.\n lastFetchedEntitiesCount = signal<number>(0);\n _pageSize = computed<number>(() =>\n this.pageSize()\n ? this.pageSize()\n : this.entityListConfig.defaultPageSize ?? this.lastFetchedEntitiesCount()\n );\n // Effective columns, derived from columns(), which can either be an array\n // of objects of array of strings.\n _columns = computed<SPEntityFieldSpec<TEntity, IdKey>[]>(() => {\n const columns = this.columns();\n let fields: SPEntityField<TEntity, IdKey>[] = [];\n let cols: SPEntityFieldSpec<TEntity, IdKey>[] = [];\n columns.forEach((colDef) => {\n // fields.push(new SPEntityField(colDef))\n if (typeof colDef === 'string') {\n cols.push({ name: String(colDef) });\n } else if (typeof colDef === 'object') {\n cols.push(colDef as SPEntityFieldSpec<TEntity, IdKey>);\n }\n });\n return cols;\n });\n\n __columns = computed<SPEntityField<TEntity, IdKey>[]>(() =>\n this.columns().map(\n (colDef) => new SPEntityField<TEntity, IdKey>(colDef, this.fieldConfig)\n )\n );\n\n // We isolate retrieving items from the remote and providing the items\n // to the component into two distinct operations. The retrieval operation\n // retrieves data asynchronously and then stores the data in a local store.\n // The UI would be 'listening' to a reactive callback that would be triggered\n // whenever items in the store changes. This is because store is an immutable\n // data structure and any changes (addition/deletion) to it would result in\n // the entire store being replaced with a copy with the changes applied.\n\n // Ideally we should declare this as\n // store!: Store<...>. But @ngneat/elf does not provide a generic type\n // for Store<...>, which can be composed from its type arguments. Instead it\n // uses type composition using its arguments to generate store's type\n // implicitly. So we use the same mechanism to enforce type safety in our\n // code. The code below results in a type declaration for store that is\n // dependent on the components generic arguments. (Making use of TypeScript's\n // type deduction system from variable assignment). Later on in the\n // constructor we reassign this.store with a new object that uses the\n // client provided idKey() value as the identifying key for each entity in\n // the sore.\n store = createStore(\n { name: Math.random().toString(36).slice(2) },\n withEntities<TEntity, IdKey>({ idKey: this.idKey() as IdKey })\n );\n // We'll initialize this in ngOnInit() when 'store' is initialized with the\n // correct TEntity store that can be safely indexed using IdKey.\n entities$!: Observable<TEntity[]>;\n // Effective paginator, coalescing local paginator and paginator from global\n // config.\n _paginator!: SPMatEntityListPaginator | undefined;\n // We will toggle this during every entity load.\n loading = signal<boolean>(false);\n // We will update this after every load and pagination() == 'infinite'\n hasMore = signal<boolean>(true);\n\n activeEntity = signal<TEntity | undefined>(undefined);\n activeEntityId = computed(() =>\n this.activeEntity() ? (this.activeEntity() as any)[this.idKey()] : undefined\n );\n _prevActiveEntity!: TEntity | undefined;\n _activeEntityChange = effect(() => {\n runInInjectionContext(this.injector, () => {\n const activeEntity = this.activeEntity();\n // Though we can raise the selectEntity event directly from effect handler,\n // that would prevent the event handler from being able to update any\n // signals from inside it. So we generate the event asyncronously.\n // Also, this effect handler will be invoked for the initial 'undefined'\n // during which we shouldn't emit the selectEntity event. Therefore we\n // keep another state variable to filter out this state.\n if (activeEntity || this._prevActiveEntity) {\n setTimeout(() => {\n this._prevActiveEntity = activeEntity;\n this.selectEntity.emit(activeEntity);\n // if (this._prevActiveEntity && !activeEntity) {\n // this.selectEntity.emit(activeEntity);\n // } else if (activeEntity) {\n // this.selectEntity.emit(activeEntity);\n // }\n });\n }\n });\n });\n @Output() selectEntity = new EventEmitter<TEntity | undefined>();\n\n fieldConfig = inject(SP_ENTITY_FIELD_CONFIG, { optional: true })!;\n entityListConfig = getEntityListConfig();\n\n /**\n * A signal that can be used to trigger loading of more entities from the\n * remote. This can be visualized as the event loop of the entity list\n * component.\n */\n loadRequest$ = new Subject<LoadRequest>();\n\n endpointChanged = effect(() => {\n runInInjectionContext(this.injector, () => {\n if (this.endpoint()) {\n // console.log(`endpointChanged - ${this.endpoint()}`);\n setTimeout(() => {\n this.refresh();\n });\n }\n });\n });\n\n constructor(\n protected http: HttpClient,\n private sanitizer: DomSanitizer,\n private injector: Injector\n ) {}\n\n ngOnInit() {\n // This is the reactive callback that listens for changes to table entities\n // which are reflected in the mat-table.\n this.store = createStore(\n { name: Math.random().toString(36).slice(2) },\n withEntities<TEntity, IdKey>({ idKey: this.idKey() as IdKey })\n );\n this.entities$ = this.store.pipe(selectAllEntities());\n this._paginator = this.paginator()\n ? this.paginator()\n : this.entityListConfig?.paginator;\n\n this.entities$\n .pipe(\n takeUntil(this.destroy$),\n tap((entities) => {\n // .data is a setter property, which ought to trigger the necessary\n // signals resulting in mat-table picking up the changes without\n // requiring us to call cdr.detectChanges() explicitly.\n this.dataSource().data = entities;\n })\n )\n .subscribe();\n\n this.loadRequest$\n .pipe(\n takeUntil(this.destroy$),\n filter((lr) => lr.endpoint !== '' || lr.force === true),\n distinctUntilChanged((prev, current) =>\n current.isEqualToAndNotForced(prev)\n ),\n switchMap((lr: LoadRequest) => this.doActualLoad(lr))\n )\n .subscribe();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n ngAfterViewInit(): void {\n if (!this.deferViewInit()) {\n this.buildContentColumnDefs();\n this.buildColumns();\n this.setupSort();\n this.loadMoreEntities();\n }\n }\n\n /**\n * Clear all entities in store and reload them from endpoint as if\n * the entities are being loaded for the first time.\n */\n refresh(force = false) {\n this.pageIndex.set(0);\n this.loadMoreEntities(force);\n }\n\n addEntity(entity: TEntity) {\n const pagination = this.pagination();\n const count = this.store.query(getEntitiesCount());\n if (\n pagination === 'infinite' ||\n pagination === 'none' ||\n count < this._pageSize()\n ) {\n this.store.update(addEntities(entity));\n } else {\n // 'discrete' pagination, refresh the crud items from the beginning.\n // Let component client set the behavior using a property\n // this.pageIndex.set(0);\n // this.loadMoreEntities();\n }\n }\n\n /**\n * Update an entity with a modified version. Can be used by CRUD UPDATE\n * operation to update an entity in the local store that is used to as the\n * source of MatTableDataSource.\n * @param id\n * @param entity\n */\n updateEntity(id: TEntity[IdKey], entity: TEntity) {\n if (this.store.query(hasEntity(id))) {\n this.store.update(updateEntities(id, entity));\n }\n }\n\n /**\n * Clients can call this method when it has deleted and entity via a CRUD\n * operation. Depending on the pagination mode, MatEntityList implements\n * an appropriate behavior.\n *\n * If the pagination is 'infinite', the relevent entity is removed from our\n * entity list. View will be repained as data store has changed.\n *\n * If the pagination is 'discrete', the entity is removed from the page.\n * If this is the only entity in the page, the current pageNumber is\n * decremented by 1 if it's possible (if the current pageNumber > 1).\n * The page is reloaded from remote.\n */\n removeEntity(id: TEntity[IdKey]) {\n const paginator = this._paginator;\n if (paginator) {\n if (this.pagination() === 'infinite') {\n // This will cause store to mutate which will trigger this.entity$ to\n // emit which in turn will update our MatTableDataSource instance.\n this.store.update(deleteEntities(id));\n } else {\n // Logic\n this.store.update(deleteEntities(id));\n const count = this.store.query(getEntitiesCount());\n if (count == 0) {\n // No more entities in this page\n // Go back one page\n if (this.pageIndex() > 0) {\n this.pageIndex.set(this.pageIndex() - 1);\n }\n }\n // load the page again\n this.loadMoreEntities();\n }\n } else {\n // Just remove the entity that has been deleted.\n this.store.update(deleteEntities(id));\n }\n }\n\n /**\n * Build the contentColumnDefs array by enumerating all of client's projected\n * content with matColumnDef directive.\n */\n buildContentColumnDefs() {\n const clientColumnDefs = this.clientColumnDefs;\n if (clientColumnDefs) {\n this.contentColumnDefs = clientColumnDefs.toArray();\n }\n }\n\n /**\n * Build the effective columns by parsing our own <ng-container matColumnDef>\n * statements for each column in columns() property and client's\n * <ng-container matColumnDef> provided via content projection.\n */\n buildColumns() {\n const matTable = this.table();\n\n if (matTable) {\n const columnNames = new Set<string>();\n const columnDefs: MatColumnDef[] = [];\n\n this._columns().forEach((colDef) => {\n if (!columnNames.has(colDef.name)) {\n const matColDef = this.viewColumnDefs().find(\n (cd) => cd.name === colDef.name\n );\n const clientColDef = this.contentColumnDefs.find(\n (cd) => cd.name === colDef.name\n );\n const columnDef = clientColDef ? clientColDef : matColDef;\n if (columnDef) {\n columnDefs.push(columnDef);\n columnNames.add(colDef.name);\n }\n }\n });\n columnDefs.forEach((cd) => {\n matTable.addColumnDef(cd);\n });\n\n this.allColumnNames.set(Array.from(columnNames));\n // this.displayedColumns.set(Array.from(columnNames) as string[]);\n }\n }\n\n setupSort() {\n const matSort = this.sort();\n if (matSort) {\n this.dataSource().sort = matSort;\n }\n }\n\n infiniteScrollLoadNextPage(ev: any) {\n // console.log(`infiniteScrollLoadNextPage - ${JSON.stringify(ev)}`);\n if (this._paginator) {\n this.loadMoreEntities();\n }\n }\n\n loadMoreEntities(forceRefresh = false) {\n this.loadRequest$.next(this.createNextLoadRequest(forceRefresh));\n }\n\n /**\n * Creates a LoadRequest object for loading entities using the current state\n * of the component. Therefore, if the request is for next page of entities,\n * the LoadRequest object will have the updated page index. However, if\n * pagination has been reset (refer to refresh()), the LoadRequest object\n * will be for the first page of data. Note that when 'endpoint' value\n * changes, the component's pagination state is reset causing a refresh()\n * to be called, which in turn will create a new LoadRequest object for the\n * first page of data.\n * @returns LoadRequest object for the next load request.\n */\n private createNextLoadRequest(forceRefresh: boolean): LoadRequest {\n let pageParams = {};\n const parts = this.endpoint().split('?');\n const endpoint = parts[0];\n if (this._paginator) {\n pageParams = this._paginator.getRequestPageParams(\n endpoint,\n this.pageIndex(),\n this.pageSize()\n );\n }\n let httpParams = new HttpParams();\n for (const key in pageParams) {\n httpParams = httpParams.append(key, (pageParams as any)[key]);\n }\n if (parts.length > 1) {\n const embeddedParams = new HttpParams({ fromString: parts[1] });\n embeddedParams.keys().forEach((key) => {\n const value = embeddedParams.getAll(key);\n (value || []).forEach((v) => {\n httpParams = httpParams.append(key, v);\n });\n });\n }\n return new LoadRequest(\n endpoint,\n httpParams,\n forceRefresh || !!this.entityLoaderFn()\n );\n }\n\n /**\n * Does the actual load of entities from the remote or via calling the\n * entityLoaderFn. This method is the workhorse of the entity list\n * 'loader-loop'.\n * @param lr\n * @returns Observable that emits the response from the remote or from\n * entityLoaderFn().\n */\n private doActualLoad(lr: LoadRequest) {\n // console.log(`doActualLoad - endpoint: ${lr.endpoint}, params: ${lr.params.toString()}`);\n const loaderFn = this.entityLoaderFn();\n const params = lr.params;\n const obs =\n loaderFn !== undefined\n ? loaderFn({ params })\n : this.http.get<any>(this.getUrl(lr.endpoint), {\n context: this._httpReqContext(),\n params,\n });\n\n this.loading.set(true);\n return obs.pipe(\n tap((resp) => {\n // TODO: defer this to a pagination provider so that we can support\n // many types of pagination. DRF itself has different schemes. And\n // express may have yet another pagination protocol.\n this.firstLoadDone = true;\n if (this._paginator) {\n // Convert HttpParams to JS object\n const paramsObj: any = {};\n params.keys().forEach((key) => {\n paramsObj[key] = params.get(key);\n });\n const { entities, total } = this._paginator.parseRequestResponse(\n this.entityName(),\n this._entityNamePlural()!,\n this.endpoint(),\n paramsObj,\n resp\n );\n this.entityCount.set(total);\n this.lastFetchedEntitiesCount.set(entities.length);\n // this.pageIndex.set(this.pageIndex() + 1)\n // entities = this._paginator.getEntitiesFromResponse(entities);\n if (this.pagination() === 'discrete') {\n this.store.reset();\n } else if (this.pagination() === 'infinite') {\n const pageSize = this._pageSize();\n const entityCount = this.entityCount();\n if (pageSize > 0) {\n const pageCount =\n Math.floor(entityCount / pageSize) +\n (entityCount % pageSize ? 1 : 0);\n this.hasMore.set(this.pageIndex() === pageCount);\n } else {\n this.hasMore.set(false);\n }\n }\n // store the entities in the store\n // TODO: remove as any\n this.store.update(upsertEntities(entities as any));\n } else {\n this.store.update(\n upsertEntities(this.findArrayInResult(resp) as TEntity[])\n );\n }\n }),\n finalize(() => this.loading.set(false))\n );\n }\n\n private findArrayInResult(res: any): any[] | undefined {\n if (Array.isArray(res)) {\n return res;\n }\n for (const key in res) {\n if (Object.prototype.hasOwnProperty.call(res, key)) {\n const element = res[key];\n if (Array.isArray(element)) {\n return element;\n }\n }\n }\n return [];\n }\n\n handlePageEvent(e: PageEvent) {\n this.pageIndex.set(e.pageIndex);\n this.loadMoreEntities();\n }\n\n getUrl(endpoint: string) {\n return this.entityListConfig?.urlResolver\n ? this.entityListConfig?.urlResolver(endpoint)\n : endpoint;\n }\n\n toggleActiveEntity(entity: TEntity | undefined) {\n if (entity) {\n if (entity === this.activeEntity()) {\n this.activeEntity.set(undefined);\n } else {\n this.activeEntity.set(entity);\n }\n } else {\n this.activeEntity.set(undefined);\n }\n }\n\n getColumnLabel(field: SPEntityField<TEntity, IdKey>): Observable<string> {\n if (field._fieldSpec.label) {\n return of(field._fieldSpec.label);\n }\n if (this.entityListConfig && this.entityListConfig.columnLabelFn) {\n const label = this.entityListConfig.columnLabelFn(\n this.entityName(),\n field._fieldSpec.name\n );\n return label instanceof Observable ? label : of(label);\n }\n return of(field._fieldSpec.name);\n }\n\n isAsync(val: any) {\n return val instanceof Observable;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"smallpearl-ngx-helper-mat-entity-list.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-entity-list/src/mat-entity-list-types.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-list/src/providers.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-list/src/config.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-list/src/mat-entity-list.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-list/smallpearl-ngx-helper-mat-entity-list.ts"],"sourcesContent":["import { HttpContextToken } from \"@angular/common/http\";\nimport { Observable } from \"rxjs\";\n\nexport interface SPMatEntityListHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n}\n\nexport const SP_MAT_ENTITY_LIST_HTTP_CONTEXT =\n new HttpContextToken<SPMatEntityListHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n }));\n\n/**\n * Pagination HTTP request params. Actually copied from Angular's HttpParams\n * declaration. The ReadonlyArray<string|number|boolean> is a bit of an\n * overkill for pagination params, but what the heck. When you copy-paste,\n * do it in full!\n */\nexport type SPPageParams = { [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>; }\n\n/**\n * An interface that the clients should provide, either via a global config\n * (see above), that handles parsing the GET response and returns the entities\n * stored therein. This class will allow the entity-list component to be\n * used across different pagination response types as long as the appropriate\n * SPMatEntityListPaginator class is provided to the component.\n */\nexport interface SPMatEntityListPaginator {\n getRequestPageParams: (endpoint: string, pageIndex: number, pageSize: number) => SPPageParams;\n parseRequestResponse: <\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >(\n entityName: string,\n entityNamePlural: string,\n endpoint: string,\n params: SPPageParams,\n resp: any\n ) => { total: number; entities: TEntity[] };\n}\n\n/**\n * 'entity' is really TEntity arg of SPMatEntityListComponent<TEntity>.\n * 'column' is the column name. This allows the same value function to support\n * multiple columns further enabing DRY.\n */\nexport type COLUMN_VALUE_FN = (entity: any, column: string) => string|number|Date|boolean;\n\n/**\n * Global config for SPMatEntityList component.\n */\nexport interface SPMatEntityListConfig {\n urlResolver?: (endpoint: string) => string;\n paginator?: SPMatEntityListPaginator;\n defaultPageSize?: number;\n pageSizes?: Array<number>;\n /**\n * Provide a method to return the labels for the columns. This is useful when\n * the columns are specified as the JSON object key names and the labels are\n * to be transformed into a uniform manner (uppercase) or when the labels\n * are to be dynamically localized. Note that the response can be an\n * Observable<string> if the label is to be fetched/changed asynchronously\n * (as that can happen in an app that supports dynamic changing of the UI\n * language).\n * @param entityName\n * @param columnName\n * @returns\n */\n columnLabelFn?: (entityName: string, columnName: string) => string | Observable<string>;\n}\n\n/**\n * Type for custom entities loader function, which if provided will be called\n * instead of HttpClient.get.\n */\nexport type SPMatEntityListEntityLoaderFn = (params: any) => Observable<any>;\n","import { InjectionToken } from '@angular/core';\nimport { SPMatEntityListConfig } from './mat-entity-list-types';\n\nexport const SP_MAT_ENTITY_LIST_CONFIG = new InjectionToken<SPMatEntityListConfig>(\n 'SPMatEntityListConfig'\n);\n","import { inject } from '@angular/core';\nimport { SPMatEntityListConfig } from './mat-entity-list-types';\nimport { SP_MAT_ENTITY_LIST_CONFIG } from './providers';\n\nexport const DefaultSPMatEntityListConfig: SPMatEntityListConfig = {\n urlResolver: (endpoint: string) => endpoint,\n paginator: undefined,\n defaultPageSize: 50,\n pageSizes: [10, 25, 50, 100],\n columnLabelFn: (entityName: string, columnName: string) => columnName,\n};\n\n/**\n * To be called from an object's constructor.\n */\nexport function getEntityListConfig(): SPMatEntityListConfig {\n const entityListConfig = inject(SP_MAT_ENTITY_LIST_CONFIG, {\n optional: true,\n });\n return {\n ...DefaultSPMatEntityListConfig,\n ...(entityListConfig ?? {}),\n };\n}\n","import { CommonModule } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken, HttpParams } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ContentChildren,\n Directive,\n effect,\n ElementRef,\n EventEmitter,\n inject,\n Injector,\n input,\n OnDestroy,\n OnInit,\n Output,\n QueryList,\n runInInjectionContext,\n signal,\n viewChild,\n viewChildren\n} from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatPaginatorModule, PageEvent } from '@angular/material/paginator';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatSort, MatSortModule } from '@angular/material/sort';\nimport {\n MatColumnDef,\n MatTable,\n MatTableDataSource,\n MatTableModule,\n} from '@angular/material/table';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { RouterModule } from '@angular/router';\nimport { createStore } from '@ngneat/elf';\nimport {\n addEntities,\n deleteEntities,\n getEntitiesCount,\n hasEntity,\n selectAllEntities,\n updateEntities,\n upsertEntities,\n withEntities,\n} from '@ngneat/elf-entities';\nimport {\n SP_ENTITY_FIELD_CONFIG,\n SPEntityField,\n SPEntityFieldSpec\n} from '@smallpearl/ngx-helper/entity-field';\nimport { InfiniteScrollDirective } from 'ngx-infinite-scroll';\nimport { plural } from 'pluralize';\nimport {\n distinctUntilChanged,\n filter,\n finalize,\n Observable,\n of,\n Subject,\n Subscription,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs';\nimport { getEntityListConfig } from './config';\nimport {\n SP_MAT_ENTITY_LIST_HTTP_CONTEXT,\n SPMatEntityListEntityLoaderFn,\n SPMatEntityListPaginator\n} from './mat-entity-list-types';\n\n@Directive({\n selector: '[headerAlignment]',\n standalone: true\n})\nexport class HeaderAlignmentDirective implements AfterViewInit {\n\n headerAlignment = input<string>();\n\n constructor(private el: ElementRef) {\n // this.el.nativeElement.style.backgroundColor = 'yellow';\n }\n\n ngAfterViewInit(): void {\n if (this.headerAlignment()) {\n const sortHeader = this.el.nativeElement.querySelector('.mat-sort-header-container');\n if (sortHeader) {\n sortHeader.style.justifyContent = this.headerAlignment();\n } else {\n this.el.nativeElement.style.justifyContent = this.headerAlignment();\n }\n }\n }\n}\n\n/**\n * Represents a request to load entities from the remote. This is used to\n * compare two requests to determine if they are equal. This is useful to\n * prevent duplicate requests being sent to the remote.\n */\nclass LoadRequest {\n constructor(\n public endpoint: string,\n public params: HttpParams,\n public force = false\n ) {}\n\n // Returns true if two LoadRequest objects are equal and this object's\n // 'force' is not set to true.\n isEqualToAndNotForced(prev: LoadRequest): boolean {\n // console.log(\n // `isEqualToAndNotForced - ${this.endpoint}, ${this.params.toString()} ${\n // this.force\n // }, other: ${prev.endpoint}, ${prev.params.toString()}, ${prev.force}`\n // );\n return this.force\n ? false\n : this.endpoint.localeCompare(prev.endpoint) === 0 &&\n this.params.toString().localeCompare(prev.params.toString()) === 0;\n }\n}\n\n/**\n * A component to display a list of entities loaded from remote.\n */\n@Component({\n imports: [\n CommonModule,\n RouterModule,\n MatTableModule,\n MatSortModule,\n MatPaginatorModule,\n MatButtonModule,\n MatInputModule,\n MatProgressSpinnerModule,\n InfiniteScrollDirective,\n HeaderAlignmentDirective,\n ],\n selector: 'sp-mat-entity-list',\n template: `\n <div\n class=\"entities-list-wrapper\"\n infiniteScroll\n [infiniteScrollDistance]=\"infiniteScrollDistance()\"\n [infiniteScrollThrottle]=\"infiniteScrollThrottle()\"\n [infiniteScrollContainer]=\"infiniteScrollContainer()\"\n [scrollWindow]=\"infiniteScrollWindow()\"\n [infiniteScrollDisabled]=\"\n pagination() !== 'infinite' || !_paginator || !hasMore()\n \"\n (scrolled)=\"infiniteScrollLoadNextPage($event)\"\n >\n <div\n class=\"busy-overlay\"\n [ngClass]=\"{ show: pagination() === 'discrete' && loading() }\"\n >\n <ng-container *ngTemplateOutlet=\"busySpinner\"></ng-container>\n </div>\n <table mat-table [dataSource]=\"dataSource()\">\n <tr mat-header-row *matHeaderRowDef=\"_displayedColumns()\"></tr>\n <tr\n mat-row\n [class.active-row]=\"activeEntityId() === row[this.idKey()]\"\n *matRowDef=\"let row; columns: _displayedColumns()\"\n (click)=\"toggleActiveEntity(row)\"\n ></tr>\n </table>\n @if (pagination() == 'discrete' && _paginator) {\n <mat-paginator\n showFirstLastButtons\n [length]=\"entityCount()\"\n [pageSize]=\"_pageSize()\"\n [pageIndex]=\"pageIndex()\"\n [pageSizeOptions]=\"[]\"\n [hidePageSize]=\"true\"\n (page)=\"handlePageEvent($event)\"\n [disabled]=\"loading()\"\n aria-label=\"Select page\"\n ></mat-paginator>\n }\n <div\n class=\"infinite-scroll-loading\"\n [ngClass]=\"{ show: pagination() === 'infinite' && loading() }\"\n >\n <ng-container *ngTemplateOutlet=\"busySpinner\"></ng-container>\n </div>\n </div>\n <!-- We keep the column definitions outside the <table> so that they can\n be dynamically added to the MatTable. -->\n <span matSort=\"sorter()\">\n @for (column of __columns(); track $index) {\n <ng-container [matColumnDef]=\"column.spec.name\">\n @if (disableSort()) {\n <th\n [class]=\"column.class\"\n [headerAlignment]=\"column.options.alignment\"\n mat-header-cell\n *matHeaderCellDef\n >\n {{ getColumnLabel(column) | async }}\n </th>\n } @else {\n <th\n [class]=\"column.class\"\n [headerAlignment]=\"column.options.alignment\"\n mat-header-cell\n mat-sort-header\n *matHeaderCellDef\n >\n {{ getColumnLabel(column) | async }}\n </th>\n }\n <td\n [class]=\"column.class\"\n [style.text-align]=\"column.options.alignment\"\n mat-cell\n *matCellDef=\"let element\"\n [routerLink]=\"column.getRouterLink(element)\"\n >\n @if (column.hasRouterLink(element)) {\n <a [routerLink]=\"column.getRouterLink(element)\">\n <span [innerHTML]=\"column.value(element)\"></span>\n </a>\n } @else { @let val = column.value(element);\n <span [innerHTML]=\"isAsync(val) ? (val | async) : val\"></span>\n }\n </td>\n </ng-container>\n }\n </span>\n <ng-template #busySpinner>\n <div class=\"busy-spinner\">\n <mat-spinner mode=\"indeterminate\" diameter=\"28\"></mat-spinner>\n </div>\n </ng-template>\n `,\n styles: [\n `\n .entities-list-wrapper {\n position: relative;\n }\n .busy-overlay {\n display: none;\n height: 100%;\n width: 100%;\n position: absolute;\n top: 0px;\n left: 0px;\n z-index: 1000;\n opacity: 0.6;\n background-color: transparent;\n }\n .show {\n display: block;\n }\n .busy-spinner {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .infinite-scroll-loading {\n display: none;\n width: 100%;\n padding: 8px;\n }\n .active-row {\n font-weight: bold;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SPMatEntityListComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> implements OnInit, OnDestroy, AfterViewInit\n{\n /* CLIENT PROVIDED PARAMETERS */\n entityName = input.required<string>();\n entityNamePlural = input<string>();\n\n /**\n * The endpoint from where the entities are to be retrieved\n */\n endpoint = input<string>('');\n /**\n * Custom entities loader function, which if provided will be called\n * instead of HttpClient.get.\n */\n entityLoaderFn = input<SPMatEntityListEntityLoaderFn | undefined>(undefined);\n /**\n * The columns of the entity to be displayed. This is an array of\n * SPEntityFieldSpec objects. If there's a one-to-one mapping between the\n * column's field name, its title & the rendered value, a string can be\n * specified instead. That is, the value of this property is a heterogeneous\n * array consisting of SPEntityFieldSpec<> objects and strings.\n */\n columns = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>>([]);\n\n /**\n * Names of columns that are displayed. This will default to all the columns\n * listed in columns.\n */\n displayedColumns = input<string[]>([]); // ['name', 'cell', 'gender'];\n\n /**\n * Number of entities per page. If this is not set and paginator is defined,\n * the number of entities int in the first request, will be taken as the\n * page size.\n */\n pageSize = input<number>(0);\n /**\n * Entity idKey, if idKey is different from the default 'id'.\n */\n idKey = input<string>('id');\n /**\n * Type of pagination -- continuous or discrete. 'infinite' pagination\n * uses an 'infiniteScroll' and 'discrete' pagination uses a mat-paginator\n * at the bottom to navigate between pages.\n */\n pagination = input<'infinite' | 'discrete' | 'none'>('discrete');\n /**\n * Component specific paginator. Only used if pagination != 'none'.\n */\n paginator = input<SPMatEntityListPaginator>();\n /**\n *\n */\n sorter = input<MatSort>();\n /**\n * Disable sorting of rows\n */\n disableSort = input<boolean>(false);\n /**\n * Wrappers for infiniteScroll properties, for customization by the client\n */\n infiniteScrollContainer = input<any>('');\n infiniteScrollDistance = input<number>(1);\n infiniteScrollThrottle = input<number>(400);\n infiniteScrollWindow = input<boolean>(false);\n /**\n * Custom context to be set for HttpClient requests. In the client code\n * specify this property by initializing a member variable as:\n\n ```\n Component({\n ...\n template: `\n <sp-mat-entity-list\n [httpReqContext]=\"httpReqContext\"\n ></sp-mat-entity-list>\n `\n })\n export class YourComponent {\n httpReqContext: [HttpContextToken<any>, any] = [\n SIDELOAD_TO_COMPOSITE_PARAMS, 'customers'\n ];\n }\n ```\n *\n * Of course if you want to pass multiple context properties, declare the type\n * as an array of array. That is, `[[HttpContextToken<any>, any]]` and\n * initialize it appropriately.\n */\n httpReqContext = input<\n [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]\n >();\n /* END CLIENT PROVIDED PARAMETERS */\n\n // *** INTERNAL *** //\n _entityNamePlural = computed(() =>\n this.entityNamePlural()\n ? this.entityNamePlural()\n : plural(this.entityName())\n );\n\n _httpReqContext = computed(() => {\n let reqContext = this.httpReqContext();\n const context = new HttpContext();\n if (reqContext && Array.isArray(reqContext)) {\n if (reqContext.length == 2 && !Array.isArray(reqContext[0])) {\n // one dimensional array of a key, value pair.\n context.set(reqContext[0], reqContext[1]);\n } else {\n reqContext.forEach(([k, v]) => context.set(k, v));\n }\n }\n context.set(SP_MAT_ENTITY_LIST_HTTP_CONTEXT, {\n entityName: this.entityName(),\n entityNamePlural: this._entityNamePlural(),\n endpoint: this.endpoint(),\n });\n return context;\n });\n deferViewInit = input<boolean>(false);\n firstLoadDone = false;\n allColumnNames = signal<string[]>([]);\n _displayedColumns = computed(() =>\n this.displayedColumns().length > 0\n ? this.displayedColumns().filter(\n (colName) =>\n this.allColumnNames().find((name) => name === colName) !== undefined\n )\n : this.allColumnNames()\n );\n dataSource = signal<MatTableDataSource<TEntity>>(\n new MatTableDataSource<TEntity>()\n );\n\n table = viewChild(MatTable);\n sort = viewChild(MatSort);\n // These are our own <ng-container matColumnDef></ng-container>\n // which we create for each column that we create by the declaration:\n // <ng-container *ngFor=\"let column of columns()\" [matColumnDef]=\"column.name\">\n viewColumnDefs = viewChildren(MatColumnDef);\n // These are the <ng-container matColumnDef></ng-container> placed\n // inside <sp-mat-entity-list></<sp-mat-entity-list> by the client to override\n // the default <ng-container matColumnDef> created by the component.\n @ContentChildren(MatColumnDef) clientColumnDefs!: QueryList<MatColumnDef>;\n\n contentColumnDefs: MatColumnDef[] = [];\n\n subs$ = new Subscription();\n destroy$ = new Subject<void>();\n\n // Pagination state\n entityCount = signal<number>(0);\n pageIndex = signal<number>(0);\n\n // Mechanism to default pageSize to last entities length.\n lastFetchedEntitiesCount = signal<number>(0);\n _pageSize = computed<number>(() =>\n this.pageSize()\n ? this.pageSize()\n : this.entityListConfig.defaultPageSize ?? this.lastFetchedEntitiesCount()\n );\n // Effective columns, derived from columns(), which can either be an array\n // of objects of array of strings.\n _columns = computed<SPEntityFieldSpec<TEntity, IdKey>[]>(() => {\n const columns = this.columns();\n let fields: SPEntityField<TEntity, IdKey>[] = [];\n let cols: SPEntityFieldSpec<TEntity, IdKey>[] = [];\n columns.forEach((colDef) => {\n // fields.push(new SPEntityField(colDef))\n if (typeof colDef === 'string') {\n cols.push({ name: String(colDef) });\n } else if (typeof colDef === 'object') {\n cols.push(colDef as SPEntityFieldSpec<TEntity, IdKey>);\n }\n });\n return cols;\n });\n\n __columns = computed<SPEntityField<TEntity, IdKey>[]>(() =>\n this.columns().map(\n (colDef) => new SPEntityField<TEntity, IdKey>(colDef, this.fieldConfig)\n )\n );\n\n // We isolate retrieving items from the remote and providing the items\n // to the component into two distinct operations. The retrieval operation\n // retrieves data asynchronously and then stores the data in a local store.\n // The UI would be 'listening' to a reactive callback that would be triggered\n // whenever items in the store changes. This is because store is an immutable\n // data structure and any changes (addition/deletion) to it would result in\n // the entire store being replaced with a copy with the changes applied.\n\n // Ideally we should declare this as\n // store!: Store<...>. But @ngneat/elf does not provide a generic type\n // for Store<...>, which can be composed from its type arguments. Instead it\n // uses type composition using its arguments to generate store's type\n // implicitly. So we use the same mechanism to enforce type safety in our\n // code. The code below results in a type declaration for store that is\n // dependent on the components generic arguments. (Making use of TypeScript's\n // type deduction system from variable assignment). Later on in the\n // constructor we reassign this.store with a new object that uses the\n // client provided idKey() value as the identifying key for each entity in\n // the sore.\n store = createStore(\n { name: Math.random().toString(36).slice(2) },\n withEntities<TEntity, IdKey>({ idKey: this.idKey() as IdKey })\n );\n // We'll initialize this in ngOnInit() when 'store' is initialized with the\n // correct TEntity store that can be safely indexed using IdKey.\n entities$!: Observable<TEntity[]>;\n // Effective paginator, coalescing local paginator and paginator from global\n // config.\n _paginator!: SPMatEntityListPaginator | undefined;\n // We will toggle this during every entity load.\n loading = signal<boolean>(false);\n // We will update this after every load and pagination() == 'infinite'\n hasMore = signal<boolean>(true);\n\n activeEntity = signal<TEntity | undefined>(undefined);\n activeEntityId = computed(() =>\n this.activeEntity() ? (this.activeEntity() as any)[this.idKey()] : undefined\n );\n _prevActiveEntity!: TEntity | undefined;\n _activeEntityChange = effect(() => {\n runInInjectionContext(this.injector, () => {\n const activeEntity = this.activeEntity();\n // Though we can raise the selectEntity event directly from effect handler,\n // that would prevent the event handler from being able to update any\n // signals from inside it. So we generate the event asyncronously.\n // Also, this effect handler will be invoked for the initial 'undefined'\n // during which we shouldn't emit the selectEntity event. Therefore we\n // keep another state variable to filter out this state.\n if (activeEntity || this._prevActiveEntity) {\n setTimeout(() => {\n this._prevActiveEntity = activeEntity;\n this.selectEntity.emit(activeEntity);\n // if (this._prevActiveEntity && !activeEntity) {\n // this.selectEntity.emit(activeEntity);\n // } else if (activeEntity) {\n // this.selectEntity.emit(activeEntity);\n // }\n });\n }\n });\n });\n @Output() selectEntity = new EventEmitter<TEntity | undefined>();\n\n fieldConfig = inject(SP_ENTITY_FIELD_CONFIG, { optional: true })!;\n entityListConfig = getEntityListConfig();\n\n /**\n * A signal that can be used to trigger loading of more entities from the\n * remote. This can be visualized as the event loop of the entity list\n * component.\n */\n loadRequest$ = new Subject<LoadRequest>();\n\n endpointChanged = effect(() => {\n runInInjectionContext(this.injector, () => {\n if (this.endpoint()) {\n // console.log(`endpointChanged - ${this.endpoint()}`);\n setTimeout(() => {\n this.refresh();\n });\n }\n });\n });\n\n constructor(\n protected http: HttpClient,\n private sanitizer: DomSanitizer,\n private injector: Injector\n ) {}\n\n ngOnInit() {\n // This is the reactive callback that listens for changes to table entities\n // which are reflected in the mat-table.\n this.store = createStore(\n { name: Math.random().toString(36).slice(2) },\n withEntities<TEntity, IdKey>({ idKey: this.idKey() as IdKey })\n );\n this.entities$ = this.store.pipe(selectAllEntities());\n this._paginator = this.paginator()\n ? this.paginator()\n : this.entityListConfig?.paginator;\n\n this.entities$\n .pipe(\n takeUntil(this.destroy$),\n tap((entities) => {\n // .data is a setter property, which ought to trigger the necessary\n // signals resulting in mat-table picking up the changes without\n // requiring us to call cdr.detectChanges() explicitly.\n this.dataSource().data = entities;\n })\n )\n .subscribe();\n\n this.loadRequest$\n .pipe(\n takeUntil(this.destroy$),\n filter((lr) => lr.endpoint !== '' || lr.force === true),\n distinctUntilChanged((prev, current) =>\n current.isEqualToAndNotForced(prev)\n ),\n switchMap((lr: LoadRequest) => this.doActualLoad(lr))\n )\n .subscribe();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n ngAfterViewInit(): void {\n if (!this.deferViewInit()) {\n this.buildContentColumnDefs();\n this.buildColumns();\n this.setupSort();\n this.loadMoreEntities();\n }\n }\n\n /**\n * Clear all entities in store and reload them from endpoint as if\n * the entities are being loaded for the first time.\n */\n refresh(force = false) {\n this.pageIndex.set(0);\n this.loadMoreEntities(force);\n }\n\n addEntity(entity: TEntity) {\n const pagination = this.pagination();\n const count = this.store.query(getEntitiesCount());\n if (\n pagination === 'infinite' ||\n pagination === 'none' ||\n count < this._pageSize()\n ) {\n this.store.update(addEntities(entity));\n } else {\n // 'discrete' pagination, refresh the crud items from the beginning.\n // Let component client set the behavior using a property\n // this.pageIndex.set(0);\n // this.loadMoreEntities();\n }\n }\n\n /**\n * Update an entity with a modified version. Can be used by CRUD UPDATE\n * operation to update an entity in the local store that is used to as the\n * source of MatTableDataSource.\n * @param id\n * @param entity\n */\n updateEntity(id: TEntity[IdKey], entity: TEntity) {\n if (this.store.query(hasEntity(id))) {\n this.store.update(updateEntities(id, entity));\n }\n }\n\n /**\n * Clients can call this method when it has deleted and entity via a CRUD\n * operation. Depending on the pagination mode, MatEntityList implements\n * an appropriate behavior.\n *\n * If the pagination is 'infinite', the relevent entity is removed from our\n * entity list. View will be repained as data store has changed.\n *\n * If the pagination is 'discrete', the entity is removed from the page.\n * If this is the only entity in the page, the current pageNumber is\n * decremented by 1 if it's possible (if the current pageNumber > 1).\n * The page is reloaded from remote.\n */\n removeEntity(id: TEntity[IdKey]) {\n const paginator = this._paginator;\n if (paginator) {\n if (this.pagination() === 'infinite') {\n // This will cause store to mutate which will trigger this.entity$ to\n // emit which in turn will update our MatTableDataSource instance.\n this.store.update(deleteEntities(id));\n } else {\n // Logic\n this.store.update(deleteEntities(id));\n const count = this.store.query(getEntitiesCount());\n if (count == 0) {\n // No more entities in this page\n // Go back one page\n if (this.pageIndex() > 0) {\n this.pageIndex.set(this.pageIndex() - 1);\n }\n }\n // load the page again\n this.loadMoreEntities();\n }\n } else {\n // Just remove the entity that has been deleted.\n this.store.update(deleteEntities(id));\n }\n }\n\n /**\n * Build the contentColumnDefs array by enumerating all of client's projected\n * content with matColumnDef directive.\n */\n buildContentColumnDefs() {\n const clientColumnDefs = this.clientColumnDefs;\n if (clientColumnDefs) {\n this.contentColumnDefs = clientColumnDefs.toArray();\n }\n }\n\n /**\n * Build the effective columns by parsing our own <ng-container matColumnDef>\n * statements for each column in columns() property and client's\n * <ng-container matColumnDef> provided via content projection.\n */\n buildColumns() {\n const matTable = this.table();\n\n if (matTable) {\n const columnNames = new Set<string>();\n const columnDefs: MatColumnDef[] = [];\n\n this._columns().forEach((colDef) => {\n if (!columnNames.has(colDef.name)) {\n const matColDef = this.viewColumnDefs().find(\n (cd) => cd.name === colDef.name\n );\n const clientColDef = this.contentColumnDefs.find(\n (cd) => cd.name === colDef.name\n );\n const columnDef = clientColDef ? clientColDef : matColDef;\n if (columnDef) {\n columnDefs.push(columnDef);\n columnNames.add(colDef.name);\n }\n }\n });\n columnDefs.forEach((cd) => {\n matTable.addColumnDef(cd);\n });\n\n this.allColumnNames.set(Array.from(columnNames));\n // this.displayedColumns.set(Array.from(columnNames) as string[]);\n }\n }\n\n setupSort() {\n const matSort = this.sort();\n if (matSort) {\n this.dataSource().sort = matSort;\n }\n }\n\n infiniteScrollLoadNextPage(ev: any) {\n // console.log(`infiniteScrollLoadNextPage - ${JSON.stringify(ev)}`);\n if (this._paginator) {\n this.loadMoreEntities();\n }\n }\n\n loadMoreEntities(forceRefresh = false) {\n this.loadRequest$.next(this.createNextLoadRequest(forceRefresh));\n }\n\n /**\n * Creates a LoadRequest object for loading entities using the current state\n * of the component. Therefore, if the request is for next page of entities,\n * the LoadRequest object will have the updated page index. However, if\n * pagination has been reset (refer to refresh()), the LoadRequest object\n * will be for the first page of data. Note that when 'endpoint' value\n * changes, the component's pagination state is reset causing a refresh()\n * to be called, which in turn will create a new LoadRequest object for the\n * first page of data.\n * @returns LoadRequest object for the next load request.\n */\n private createNextLoadRequest(forceRefresh: boolean): LoadRequest {\n let pageParams = {};\n const parts = this.endpoint().split('?');\n const endpoint = parts[0];\n if (this._paginator) {\n pageParams = this._paginator.getRequestPageParams(\n endpoint,\n this.pageIndex(),\n this.pageSize()\n );\n }\n let httpParams = new HttpParams();\n for (const key in pageParams) {\n httpParams = httpParams.append(key, (pageParams as any)[key]);\n }\n if (parts.length > 1) {\n const embeddedParams = new HttpParams({ fromString: parts[1] });\n embeddedParams.keys().forEach((key) => {\n const value = embeddedParams.getAll(key);\n (value || []).forEach((v) => {\n httpParams = httpParams.append(key, v);\n });\n });\n }\n return new LoadRequest(\n endpoint,\n httpParams,\n forceRefresh || !!this.entityLoaderFn()\n );\n }\n\n /**\n * Does the actual load of entities from the remote or via calling the\n * entityLoaderFn. This method is the workhorse of the entity list\n * 'loader-loop'.\n * @param lr\n * @returns Observable that emits the response from the remote or from\n * entityLoaderFn().\n */\n private doActualLoad(lr: LoadRequest) {\n // console.log(`doActualLoad - endpoint: ${lr.endpoint}, params: ${lr.params.toString()}`);\n const loaderFn = this.entityLoaderFn();\n const params = lr.params;\n const obs =\n loaderFn !== undefined\n ? loaderFn({ params })\n : this.http.get<any>(this.getUrl(lr.endpoint), {\n context: this._httpReqContext(),\n params,\n });\n\n this.loading.set(true);\n return obs.pipe(\n tap((resp) => {\n // TODO: defer this to a pagination provider so that we can support\n // many types of pagination. DRF itself has different schemes. And\n // express may have yet another pagination protocol.\n this.firstLoadDone = true;\n if (this._paginator) {\n // Convert HttpParams to JS object\n const paramsObj: any = {};\n params.keys().forEach((key) => {\n paramsObj[key] = params.get(key);\n });\n const { entities, total } = this._paginator.parseRequestResponse(\n this.entityName(),\n this._entityNamePlural()!,\n this.endpoint(),\n paramsObj,\n resp\n );\n this.entityCount.set(total);\n this.lastFetchedEntitiesCount.set(entities.length);\n // this.pageIndex.set(this.pageIndex() + 1)\n // entities = this._paginator.getEntitiesFromResponse(entities);\n if (this.pagination() === 'discrete') {\n this.store.reset();\n } else if (this.pagination() === 'infinite') {\n const pageSize = this._pageSize();\n const entityCount = this.entityCount();\n if (pageSize > 0) {\n const pageCount =\n Math.floor(entityCount / pageSize) +\n (entityCount % pageSize ? 1 : 0);\n this.hasMore.set(this.pageIndex() === pageCount);\n } else {\n this.hasMore.set(false);\n }\n }\n // store the entities in the store\n // TODO: remove as any\n this.store.update(upsertEntities(entities as any));\n } else {\n this.store.update(\n upsertEntities(this.findArrayInResult(resp) as TEntity[])\n );\n }\n }),\n finalize(() => this.loading.set(false))\n );\n }\n\n private findArrayInResult(res: any): any[] | undefined {\n if (Array.isArray(res)) {\n return res;\n }\n for (const key in res) {\n if (Object.prototype.hasOwnProperty.call(res, key)) {\n const element = res[key];\n if (Array.isArray(element)) {\n return element;\n }\n }\n }\n return [];\n }\n\n handlePageEvent(e: PageEvent) {\n this.pageIndex.set(e.pageIndex);\n this.loadMoreEntities();\n }\n\n getUrl(endpoint: string) {\n return this.entityListConfig?.urlResolver\n ? this.entityListConfig?.urlResolver(endpoint)\n : endpoint;\n }\n\n toggleActiveEntity(entity: TEntity | undefined) {\n if (entity) {\n if (entity === this.activeEntity()) {\n this.activeEntity.set(undefined);\n } else {\n this.activeEntity.set(entity);\n }\n } else {\n this.activeEntity.set(undefined);\n }\n }\n\n getColumnLabel(field: SPEntityField<TEntity, IdKey>): Observable<string> {\n if (field._fieldSpec.label) {\n return field._fieldSpec.label instanceof Observable\n ? field._fieldSpec.label\n : of(field._fieldSpec.label);\n }\n if (this.entityListConfig && this.entityListConfig.columnLabelFn) {\n const label = this.entityListConfig.columnLabelFn(\n this.entityName(),\n field._fieldSpec.name\n );\n return label instanceof Observable ? label : of(label);\n }\n return of(field._fieldSpec.name);\n }\n\n isAsync(val: any) {\n return val instanceof Observable;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { CommonModule, UpperCasePipe } from '@angular/common';
|
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { input, computed, Component, ChangeDetectionStrategy, inject } from '@angular/core';
|
|
5
5
|
import { SP_ENTITY_FIELD_CONFIG, SPEntityField } from '@smallpearl/ngx-helper/entity-field';
|
|
6
|
+
import { Observable, of } from 'rxjs';
|
|
6
7
|
|
|
7
8
|
// @Component({
|
|
8
9
|
// standalone: true,
|
|
@@ -157,6 +158,10 @@ class StationaryWithLineItemsComponent {
|
|
|
157
158
|
}
|
|
158
159
|
return [];
|
|
159
160
|
}
|
|
161
|
+
fieldLabel(field) {
|
|
162
|
+
const label = field.label();
|
|
163
|
+
return label instanceof Observable ? label : of(label);
|
|
164
|
+
}
|
|
160
165
|
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: StationaryWithLineItemsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
161
166
|
/** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.6", type: StationaryWithLineItemsComponent, isStandalone: true, selector: "sp-stationary-with-line-items", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, number: { classPropertyName: "number", publicName: "number", isSignal: true, isRequired: false, transformFunction: null }, leftHeader: { classPropertyName: "leftHeader", publicName: "leftHeader", isSignal: true, isRequired: false, transformFunction: null }, leftHeaderTemplate: { classPropertyName: "leftHeaderTemplate", publicName: "leftHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null }, rightHeader: { classPropertyName: "rightHeader", publicName: "rightHeader", isSignal: true, isRequired: false, transformFunction: null }, rightHeaderTemplate: { classPropertyName: "rightHeaderTemplate", publicName: "rightHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, leftFooter: { classPropertyName: "leftFooter", publicName: "leftFooter", isSignal: true, isRequired: false, transformFunction: null }, leftFooterTemplate: { classPropertyName: "leftFooterTemplate", publicName: "leftFooterTemplate", isSignal: true, isRequired: false, transformFunction: null }, rightFooter: { classPropertyName: "rightFooter", publicName: "rightFooter", isSignal: true, isRequired: false, transformFunction: null }, rightFooterTemplate: { classPropertyName: "rightFooterTemplate", publicName: "rightFooterTemplate", isSignal: true, isRequired: false, transformFunction: null }, itemFieldName: { classPropertyName: "itemFieldName", publicName: "itemFieldName", isSignal: true, isRequired: false, transformFunction: null }, itemColumnFields: { classPropertyName: "itemColumnFields", publicName: "itemColumnFields", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
162
167
|
<div class="stationary-wrapper mat-body">
|
|
@@ -205,7 +210,7 @@ class StationaryWithLineItemsComponent {
|
|
|
205
210
|
<table>
|
|
206
211
|
<thead>
|
|
207
212
|
@for (field of _itemColumnFields(); track $index) {
|
|
208
|
-
<th [class]="field.class" [style.text-align]="field.spec.valueOptions?.alignment">{{ field
|
|
213
|
+
<th [class]="field.class" [style.text-align]="field.spec.valueOptions?.alignment">{{ (fieldLabel(field) | async) | uppercase }}</th>
|
|
209
214
|
}
|
|
210
215
|
</thead>
|
|
211
216
|
<tbody>
|
|
@@ -260,7 +265,7 @@ class StationaryWithLineItemsComponent {
|
|
|
260
265
|
</div>
|
|
261
266
|
</div>
|
|
262
267
|
</div>
|
|
263
|
-
`, isInline: true, styles: [".stationary-wrapper{padding:2em 1em}.title{font-size:1.6em;font-weight:600;text-align:end;margin-bottom:.5em}.number{font-size:1.1em;font-weight:500;text-align:end;margin-bottom:.5em}.header,.footer{display:flex;flex-direction:row;margin-top:1em}.left-header,.left-footer{display:flex;align-items:bottom;text-align:start;padding-right:1em;min-width:50%;overflow-wrap:break-word;text-wrap:wrap}.right-header,.right-footer{display:flex;justify-content:flex-end;min-width:50%;overflow:clip}.items{margin:2em 0}.items table{width:100%;border:0px solid lightgray}.items table thead{background-color:#000;color:#fff}.items table thead th{padding:.4em}.items table td{padding:.8em .4em;border-bottom:1px solid lightgray;border-right:0px solid lightgray}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "component", type: FieldsRendererComponent, selector: "sp-fields-renderer", inputs: ["entity", "fields"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
268
|
+
`, isInline: true, styles: [".stationary-wrapper{padding:2em 1em}.title{font-size:1.6em;font-weight:600;text-align:end;margin-bottom:.5em}.number{font-size:1.1em;font-weight:500;text-align:end;margin-bottom:.5em}.header,.footer{display:flex;flex-direction:row;margin-top:1em}.left-header,.left-footer{display:flex;align-items:bottom;text-align:start;padding-right:1em;min-width:50%;overflow-wrap:break-word;text-wrap:wrap}.right-header,.right-footer{display:flex;justify-content:flex-end;min-width:50%;overflow:clip}.items{margin:2em 0}.items table{width:100%;border:0px solid lightgray}.items table thead{background-color:#000;color:#fff}.items table thead th{padding:.4em}.items table td{padding:.8em .4em;border-bottom:1px solid lightgray;border-right:0px solid lightgray}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "component", type: FieldsRendererComponent, selector: "sp-fields-renderer", inputs: ["entity", "fields"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
264
269
|
}
|
|
265
270
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: StationaryWithLineItemsComponent, decorators: [{
|
|
266
271
|
type: Component,
|
|
@@ -315,7 +320,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
|
|
|
315
320
|
<table>
|
|
316
321
|
<thead>
|
|
317
322
|
@for (field of _itemColumnFields(); track $index) {
|
|
318
|
-
<th [class]="field.class" [style.text-align]="field.spec.valueOptions?.alignment">{{ field
|
|
323
|
+
<th [class]="field.class" [style.text-align]="field.spec.valueOptions?.alignment">{{ (fieldLabel(field) | async) | uppercase }}</th>
|
|
319
324
|
}
|
|
320
325
|
</thead>
|
|
321
326
|
<tbody>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smallpearl-ngx-helper-stationary-with-line-items.mjs","sources":["../../../../projects/smallpearl/ngx-helper/stationary-with-line-items/src/stationary-with-line-items.component.ts","../../../../projects/smallpearl/ngx-helper/stationary-with-line-items/smallpearl-ngx-helper-stationary-with-line-items.ts"],"sourcesContent":["import { CommonModule, UpperCasePipe } from '@angular/common';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, inject, input, OnInit, TemplateRef } from '@angular/core';\nimport { SP_ENTITY_FIELD_CONFIG, SPEntityField, SPEntityFieldSpec } from '@smallpearl/ngx-helper/entity-field';\n\n\n// @Component({\n// standalone: true,\n// imports: [],\n// selector: 'sp-string-or-object-renderer',\n// template: `\n// @if (isString()) {\n// {{ value() }}\n// } @else {\n// <table>\n// @for (row of objectAsArray(); track $index) {\n// <tr>\n// @for (col of row; track $index) {\n// <td [style]=\"'text-align: ' + valueAlignment()\">{{ col }}</td>\n// }\n// </tr>\n// }\n// </table>\n// }\n// `,\n// changeDetection: ChangeDetectionStrategy.OnPush\n// })\n// export class StringOrObjectRendererComponent implements OnInit {\n// value = input.required<any>();\n// valueAlignment = input<string>()\n// isString = computed(() => typeof this.value() === 'string');\n// objectAsArray = computed(() => {\n// const arrayValues = [];\n// const value = this.value();\n// if (typeof value !== 'string') {\n// for (const key in this.value()) {\n// const keyValue = this.value()[key];\n// arrayValues.push([key, keyValue]);\n// }\n// }\n// return arrayValues;\n// });\n\n// constructor() { }\n\n// ngOnInit() { }\n// }\n\n@Component({\n imports: [],\n selector: 'sp-fields-renderer',\n template: `\n @if (isString()) {\n {{ stringValue() }}\n } @else {\n <div class=\"\">\n <table>\n <tbody>\n @for (field of fields(); track $index) {\n <tr>\n <td [class]=\"field.class\">{{ field.label() }}:</td>\n <td [class]=\"field.class\">{{ field.value(entity()) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n `,\n styles: `\n .field-values {\n padding: 0.2em 0;\n text-align: end;\n }\n tr td:first-of-type {\n padding-right: 1em;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class FieldsRendererComponent<TEntity extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'> implements OnInit {\n entity = input.required<TEntity>();\n fields = input.required<SPEntityField<TEntity, IdKey>[]>();\n\n isString = computed(() => typeof this.fields() === 'string');\n // If the field is a single string, looks up entity's properties\n // for matching field name as the string and if it doesn't exist returns\n // the string itself as the value.\n stringValue = computed(() => {\n const fields = this.fields();\n if (typeof fields === 'string') {\n return (this.entity() as any)[fields] ?? fields;\n }\n return '';\n });\n\n constructor(public cdr: ChangeDetectorRef) {}\n\n ngOnInit() {}\n}\n\n/**\n * A component that renders a stationary with line items, such as invoice,\n * payment receipt, bill, bill payment record, journal entry, etc. All these\n * documents have a uniform format and this component abstracts out the\n * information displayed in this type of document as properties that the client\n * can provide while it takes care of the rendering.\n *\n * Ideally we would declare this as a wrapper class with the actual rendering\n * to be performed by an inner replaceable component. This way the app will be\n * able to support multiple stationary designs, which eventually can be\n * chosen by the user. Perhaps even providing them a feature to design the\n * stationary.\n *\n * This is the first towards that long path ahead.\n */\n@Component({\n imports: [\n CommonModule,\n UpperCasePipe,\n FieldsRendererComponent\n ],\n selector: 'sp-stationary-with-line-items',\n template: `\n <div class=\"stationary-wrapper mat-body\">\n <div class=\"title\">{{ title() }}</div>\n @if (number()) {\n <div class=\"number\">#{{ number() }}</div>\n }\n <div class=\"header\">\n <div class=\"left-header\">\n @if (leftHeaderTemplate()) {\n <ng-container *ngTemplateOutlet=\"leftHeaderTemplate() ?? null\"></ng-container>\n } @else {\n @if (leftHeader()) {\n @if (isString(leftHeader())) {\n {{ leftHeader() }}\n } @else {\n <sp-fields-renderer\n [entity]=\"entity()\"\n [fields]=\"_leftHeaderFields()\"\n ></sp-fields-renderer>\n }\n }\n }\n </div>\n <div class=\"right-header\">\n @if (rightHeaderTemplate()) {\n <ng-container *ngTemplateOutlet=\"rightHeaderTemplate() ?? null\"></ng-container>\n } @else {\n @if (rightHeader()) {\n @if (isString(rightHeader())) {\n {{ rightHeader() }}\n } @else {\n <sp-fields-renderer\n [entity]=\"entity()\"\n [fields]=\"_rightHeaderFields()\"\n ></sp-fields-renderer>\n }\n }\n }\n </div>\n </div> <!-- end <div class=\"header\"> -->\n\n <!-- items -->\n @if (itemColumnFields()) {\n <div class=\"items\">\n <table>\n <thead>\n @for (field of _itemColumnFields(); track $index) {\n <th [class]=\"field.class\" [style.text-align]=\"field.spec.valueOptions?.alignment\">{{ field.label() | uppercase }}</th>\n }\n </thead>\n <tbody>\n <!-- enumerate each element of the 'items' array and render the\n specified columns for each. -->\n @for (row of _items(); track $index) {\n <tr>\n @for (field of _itemColumnFields(); track $index) {\n <td [class]=\"field.class\" [style.text-align]=\"field.spec.valueOptions?.alignment\" [innerHtml]=\"field.value(row)\"></td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n <!-- end items -->\n\n <!-- footer -->\n <div class=\"footer\">\n <div class=\"left-footer\">\n @if (leftFooterTemplate()) {\n <ng-container *ngTemplateOutlet=\"leftFooterTemplate() ?? null\"></ng-container>\n } @else {\n @if (leftFooter()) {\n @if (isString(leftFooter())) {\n {{ leftFooter() }}\n } @else {\n <sp-fields-renderer\n [entity]=\"entity()\"\n [fields]=\"_leftFooterFields()\"\n ></sp-fields-renderer>\n }\n }\n }\n </div>\n <div class=\"right-footer\">\n @if (rightFooterTemplate()) {\n <ng-container *ngTemplateOutlet=\"rightFooterTemplate() ?? null\"></ng-container>\n } @else {\n @if (rightFooter()) {\n @if (isString(rightFooter())) {\n {{ rightFooter() }}\n } @else {\n <sp-fields-renderer\n [entity]=\"entity()\"\n [fields]=\"_rightFooterFields()\"\n ></sp-fields-renderer>\n }\n }\n }\n </div>\n </div>\n </div>\n `,\n styles: `\n .stationary-wrapper {\n padding: 2em 1em;\n }\n .title {\n font-size: 1.6em;\n font-weight: 600;\n text-align: end;\n margin-bottom: 0.5em;\n }\n .number {\n font-size: 1.1em;\n font-weight: 500;\n text-align: end;\n margin-bottom: 0.5em;\n }\n .header, .footer {\n display: flex;\n flex-direction: row;\n margin-top: 1em;\n }\n .left-header, .left-footer {\n display: flex;\n align-items: bottom;\n text-align: start;\n padding-right: 1em;\n min-width: 50%;\n overflow-wrap: break-word;\n text-wrap: wrap;\n }\n .right-header, .right-footer {\n display: flex;\n justify-content: flex-end;\n min-width: 50%;\n overflow: clip;\n }\n .items {\n margin: 2em 0;\n }\n .items table {\n width: 100%;\n border: 0px solid lightgray;\n }\n .items table thead {\n background-color: black;\n color: white;\n & th {\n padding: 0.4em;\n }\n }\n .items table td {\n padding: 0.8em 0.4em;\n border-bottom: 1px solid lightgray;\n border-right: 0px solid lightgray\n }\n .footer {\n\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class StationaryWithLineItemsComponent<TEntity extends { [P in IdKey]: PropertyKey }, TEntityLineItem extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'> implements OnInit {\n entity = input.required<TEntity>();\n title = input.required<string>();\n number = input<string|number>();\n\n leftHeader = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string>();\n _leftHeaderFields = computed(() => this.getSPEntityFields(this.leftHeader()));\n leftHeaderTemplate = input<TemplateRef<any>>();\n\n rightHeader = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string>();\n _rightHeaderFields = computed(() => this.getSPEntityFields(this.rightHeader()));\n rightHeaderTemplate = input<TemplateRef<any>>();\n\n items = input<{[key: string]: string}[]>();\n\n leftFooter = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string>();\n _leftFooterFields = computed(() => this.getSPEntityFields(this.leftFooter()));\n leftFooterTemplate = input<TemplateRef<any>>();\n\n rightFooter = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string>();\n _rightFooterFields = computed(() => this.getSPEntityFields(this.rightFooter()));\n rightFooterTemplate = input<TemplateRef<any>>();\n\n itemFieldName = input<string>('items');\n itemColumnFields = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>>();\n _itemColumnFields = computed(() => this.getSPEntityFields(this.itemColumnFields()));\n\n _items = computed(() => (this.entity() as any)[this.itemFieldName()]);\n\n ngxEntityFieldConfig = inject(SP_ENTITY_FIELD_CONFIG, { optional: true })!;\n\n constructor() {}\n\n ngOnInit() {}\n\n isString(value: any) {\n return typeof value === 'string';\n }\n\n /**\n * Make the method a generic as we'll be using it for both TEntity and its\n * child TEntityLineItem objects.\n * @param fieldSpecs\n * @returns\n */\n getSPEntityFields<T>(fieldSpecs: Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string|undefined): Array<SPEntityField<TEntity, IdKey>> {\n if (fieldSpecs && typeof fieldSpecs !== 'string') {\n return fieldSpecs.map(spec => new SPEntityField<TEntity, IdKey>(spec, this.ngxEntityFieldConfig));\n }\n return [];\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"smallpearl-ngx-helper-stationary-with-line-items.mjs","sources":["../../../../projects/smallpearl/ngx-helper/stationary-with-line-items/src/stationary-with-line-items.component.ts","../../../../projects/smallpearl/ngx-helper/stationary-with-line-items/smallpearl-ngx-helper-stationary-with-line-items.ts"],"sourcesContent":["import { CommonModule, UpperCasePipe } from '@angular/common';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, inject, input, OnInit, TemplateRef } from '@angular/core';\nimport { SP_ENTITY_FIELD_CONFIG, SPEntityField, SPEntityFieldSpec } from '@smallpearl/ngx-helper/entity-field';\nimport { Observable, of } from 'rxjs';\n\n\n// @Component({\n// standalone: true,\n// imports: [],\n// selector: 'sp-string-or-object-renderer',\n// template: `\n// @if (isString()) {\n// {{ value() }}\n// } @else {\n// <table>\n// @for (row of objectAsArray(); track $index) {\n// <tr>\n// @for (col of row; track $index) {\n// <td [style]=\"'text-align: ' + valueAlignment()\">{{ col }}</td>\n// }\n// </tr>\n// }\n// </table>\n// }\n// `,\n// changeDetection: ChangeDetectionStrategy.OnPush\n// })\n// export class StringOrObjectRendererComponent implements OnInit {\n// value = input.required<any>();\n// valueAlignment = input<string>()\n// isString = computed(() => typeof this.value() === 'string');\n// objectAsArray = computed(() => {\n// const arrayValues = [];\n// const value = this.value();\n// if (typeof value !== 'string') {\n// for (const key in this.value()) {\n// const keyValue = this.value()[key];\n// arrayValues.push([key, keyValue]);\n// }\n// }\n// return arrayValues;\n// });\n\n// constructor() { }\n\n// ngOnInit() { }\n// }\n\n@Component({\n imports: [],\n selector: 'sp-fields-renderer',\n template: `\n @if (isString()) {\n {{ stringValue() }}\n } @else {\n <div class=\"\">\n <table>\n <tbody>\n @for (field of fields(); track $index) {\n <tr>\n <td [class]=\"field.class\">{{ field.label() }}:</td>\n <td [class]=\"field.class\">{{ field.value(entity()) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n `,\n styles: `\n .field-values {\n padding: 0.2em 0;\n text-align: end;\n }\n tr td:first-of-type {\n padding-right: 1em;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class FieldsRendererComponent<TEntity extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'> implements OnInit {\n entity = input.required<TEntity>();\n fields = input.required<SPEntityField<TEntity, IdKey>[]>();\n\n isString = computed(() => typeof this.fields() === 'string');\n // If the field is a single string, looks up entity's properties\n // for matching field name as the string and if it doesn't exist returns\n // the string itself as the value.\n stringValue = computed(() => {\n const fields = this.fields();\n if (typeof fields === 'string') {\n return (this.entity() as any)[fields] ?? fields;\n }\n return '';\n });\n\n constructor(public cdr: ChangeDetectorRef) {}\n\n ngOnInit() {}\n}\n\n/**\n * A component that renders a stationary with line items, such as invoice,\n * payment receipt, bill, bill payment record, journal entry, etc. All these\n * documents have a uniform format and this component abstracts out the\n * information displayed in this type of document as properties that the client\n * can provide while it takes care of the rendering.\n *\n * Ideally we would declare this as a wrapper class with the actual rendering\n * to be performed by an inner replaceable component. This way the app will be\n * able to support multiple stationary designs, which eventually can be\n * chosen by the user. Perhaps even providing them a feature to design the\n * stationary.\n *\n * This is the first towards that long path ahead.\n */\n@Component({\n imports: [\n CommonModule,\n UpperCasePipe,\n FieldsRendererComponent\n ],\n selector: 'sp-stationary-with-line-items',\n template: `\n <div class=\"stationary-wrapper mat-body\">\n <div class=\"title\">{{ title() }}</div>\n @if (number()) {\n <div class=\"number\">#{{ number() }}</div>\n }\n <div class=\"header\">\n <div class=\"left-header\">\n @if (leftHeaderTemplate()) {\n <ng-container *ngTemplateOutlet=\"leftHeaderTemplate() ?? null\"></ng-container>\n } @else {\n @if (leftHeader()) {\n @if (isString(leftHeader())) {\n {{ leftHeader() }}\n } @else {\n <sp-fields-renderer\n [entity]=\"entity()\"\n [fields]=\"_leftHeaderFields()\"\n ></sp-fields-renderer>\n }\n }\n }\n </div>\n <div class=\"right-header\">\n @if (rightHeaderTemplate()) {\n <ng-container *ngTemplateOutlet=\"rightHeaderTemplate() ?? null\"></ng-container>\n } @else {\n @if (rightHeader()) {\n @if (isString(rightHeader())) {\n {{ rightHeader() }}\n } @else {\n <sp-fields-renderer\n [entity]=\"entity()\"\n [fields]=\"_rightHeaderFields()\"\n ></sp-fields-renderer>\n }\n }\n }\n </div>\n </div> <!-- end <div class=\"header\"> -->\n\n <!-- items -->\n @if (itemColumnFields()) {\n <div class=\"items\">\n <table>\n <thead>\n @for (field of _itemColumnFields(); track $index) {\n <th [class]=\"field.class\" [style.text-align]=\"field.spec.valueOptions?.alignment\">{{ (fieldLabel(field) | async) | uppercase }}</th>\n }\n </thead>\n <tbody>\n <!-- enumerate each element of the 'items' array and render the\n specified columns for each. -->\n @for (row of _items(); track $index) {\n <tr>\n @for (field of _itemColumnFields(); track $index) {\n <td [class]=\"field.class\" [style.text-align]=\"field.spec.valueOptions?.alignment\" [innerHtml]=\"field.value(row)\"></td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n <!-- end items -->\n\n <!-- footer -->\n <div class=\"footer\">\n <div class=\"left-footer\">\n @if (leftFooterTemplate()) {\n <ng-container *ngTemplateOutlet=\"leftFooterTemplate() ?? null\"></ng-container>\n } @else {\n @if (leftFooter()) {\n @if (isString(leftFooter())) {\n {{ leftFooter() }}\n } @else {\n <sp-fields-renderer\n [entity]=\"entity()\"\n [fields]=\"_leftFooterFields()\"\n ></sp-fields-renderer>\n }\n }\n }\n </div>\n <div class=\"right-footer\">\n @if (rightFooterTemplate()) {\n <ng-container *ngTemplateOutlet=\"rightFooterTemplate() ?? null\"></ng-container>\n } @else {\n @if (rightFooter()) {\n @if (isString(rightFooter())) {\n {{ rightFooter() }}\n } @else {\n <sp-fields-renderer\n [entity]=\"entity()\"\n [fields]=\"_rightFooterFields()\"\n ></sp-fields-renderer>\n }\n }\n }\n </div>\n </div>\n </div>\n `,\n styles: `\n .stationary-wrapper {\n padding: 2em 1em;\n }\n .title {\n font-size: 1.6em;\n font-weight: 600;\n text-align: end;\n margin-bottom: 0.5em;\n }\n .number {\n font-size: 1.1em;\n font-weight: 500;\n text-align: end;\n margin-bottom: 0.5em;\n }\n .header, .footer {\n display: flex;\n flex-direction: row;\n margin-top: 1em;\n }\n .left-header, .left-footer {\n display: flex;\n align-items: bottom;\n text-align: start;\n padding-right: 1em;\n min-width: 50%;\n overflow-wrap: break-word;\n text-wrap: wrap;\n }\n .right-header, .right-footer {\n display: flex;\n justify-content: flex-end;\n min-width: 50%;\n overflow: clip;\n }\n .items {\n margin: 2em 0;\n }\n .items table {\n width: 100%;\n border: 0px solid lightgray;\n }\n .items table thead {\n background-color: black;\n color: white;\n & th {\n padding: 0.4em;\n }\n }\n .items table td {\n padding: 0.8em 0.4em;\n border-bottom: 1px solid lightgray;\n border-right: 0px solid lightgray\n }\n .footer {\n\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class StationaryWithLineItemsComponent<TEntity extends { [P in IdKey]: PropertyKey }, TEntityLineItem extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'> implements OnInit {\n entity = input.required<TEntity>();\n title = input.required<string>();\n number = input<string|number>();\n\n leftHeader = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string>();\n _leftHeaderFields = computed(() => this.getSPEntityFields(this.leftHeader()));\n leftHeaderTemplate = input<TemplateRef<any>>();\n\n rightHeader = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string>();\n _rightHeaderFields = computed(() => this.getSPEntityFields(this.rightHeader()));\n rightHeaderTemplate = input<TemplateRef<any>>();\n\n items = input<{[key: string]: string}[]>();\n\n leftFooter = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string>();\n _leftFooterFields = computed(() => this.getSPEntityFields(this.leftFooter()));\n leftFooterTemplate = input<TemplateRef<any>>();\n\n rightFooter = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string>();\n _rightFooterFields = computed(() => this.getSPEntityFields(this.rightFooter()));\n rightFooterTemplate = input<TemplateRef<any>>();\n\n itemFieldName = input<string>('items');\n itemColumnFields = input<Array<SPEntityFieldSpec<TEntity, IdKey> | string>>();\n _itemColumnFields = computed(() => this.getSPEntityFields(this.itemColumnFields()));\n\n _items = computed(() => (this.entity() as any)[this.itemFieldName()]);\n\n ngxEntityFieldConfig = inject(SP_ENTITY_FIELD_CONFIG, { optional: true })!;\n\n constructor() {}\n\n ngOnInit() {}\n\n isString(value: any) {\n return typeof value === 'string';\n }\n\n /**\n * Make the method a generic as we'll be using it for both TEntity and its\n * child TEntityLineItem objects.\n * @param fieldSpecs\n * @returns\n */\n getSPEntityFields<T>(fieldSpecs: Array<SPEntityFieldSpec<TEntity, IdKey> | string>|string|undefined): Array<SPEntityField<TEntity, IdKey>> {\n if (fieldSpecs && typeof fieldSpecs !== 'string') {\n return fieldSpecs.map(spec => new SPEntityField<TEntity, IdKey>(spec, this.ngxEntityFieldConfig));\n }\n return [];\n }\n\n fieldLabel(field: SPEntityField<TEntity, IdKey>): Observable<string> {\n const label = field.label()\n return label instanceof Observable ? label : of(label);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"path": "src/assets/i18n/"
|
|
7
7
|
}
|
|
8
8
|
],
|
|
9
|
-
"version": "0.31.
|
|
9
|
+
"version": "0.31.17",
|
|
10
10
|
"peerDependencies": {
|
|
11
11
|
"@angular/common": "^19.1.0",
|
|
12
12
|
"@angular/core": "^19.1.0",
|
|
@@ -47,26 +47,26 @@
|
|
|
47
47
|
"types": "./entity-field/index.d.ts",
|
|
48
48
|
"default": "./fesm2022/smallpearl-ngx-helper-entity-field.mjs"
|
|
49
49
|
},
|
|
50
|
-
"./
|
|
51
|
-
"types": "./
|
|
52
|
-
"default": "./fesm2022/smallpearl-ngx-helper-
|
|
50
|
+
"./forms": {
|
|
51
|
+
"types": "./forms/index.d.ts",
|
|
52
|
+
"default": "./fesm2022/smallpearl-ngx-helper-forms.mjs"
|
|
53
|
+
},
|
|
54
|
+
"./mat-context-menu": {
|
|
55
|
+
"types": "./mat-context-menu/index.d.ts",
|
|
56
|
+
"default": "./fesm2022/smallpearl-ngx-helper-mat-context-menu.mjs"
|
|
53
57
|
},
|
|
54
58
|
"./locale": {
|
|
55
59
|
"types": "./locale/index.d.ts",
|
|
56
60
|
"default": "./fesm2022/smallpearl-ngx-helper-locale.mjs"
|
|
57
61
|
},
|
|
62
|
+
"./mat-busy-wheel": {
|
|
63
|
+
"types": "./mat-busy-wheel/index.d.ts",
|
|
64
|
+
"default": "./fesm2022/smallpearl-ngx-helper-mat-busy-wheel.mjs"
|
|
65
|
+
},
|
|
58
66
|
"./hover-dropdown": {
|
|
59
67
|
"types": "./hover-dropdown/index.d.ts",
|
|
60
68
|
"default": "./fesm2022/smallpearl-ngx-helper-hover-dropdown.mjs"
|
|
61
69
|
},
|
|
62
|
-
"./mat-context-menu": {
|
|
63
|
-
"types": "./mat-context-menu/index.d.ts",
|
|
64
|
-
"default": "./fesm2022/smallpearl-ngx-helper-mat-context-menu.mjs"
|
|
65
|
-
},
|
|
66
|
-
"./forms": {
|
|
67
|
-
"types": "./forms/index.d.ts",
|
|
68
|
-
"default": "./fesm2022/smallpearl-ngx-helper-forms.mjs"
|
|
69
|
-
},
|
|
70
70
|
"./mat-entity-crud": {
|
|
71
71
|
"types": "./mat-entity-crud/index.d.ts",
|
|
72
72
|
"default": "./fesm2022/smallpearl-ngx-helper-mat-entity-crud.mjs"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ChangeDetectorRef, OnInit, TemplateRef } from '@angular/core';
|
|
2
2
|
import { SPEntityField, SPEntityFieldSpec } from '@smallpearl/ngx-helper/entity-field';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
export declare class FieldsRendererComponent<TEntity extends {
|
|
5
6
|
[P in IdKey]: PropertyKey;
|
|
@@ -67,6 +68,7 @@ export declare class StationaryWithLineItemsComponent<TEntity extends {
|
|
|
67
68
|
* @returns
|
|
68
69
|
*/
|
|
69
70
|
getSPEntityFields<T>(fieldSpecs: Array<SPEntityFieldSpec<TEntity, IdKey> | string> | string | undefined): Array<SPEntityField<TEntity, IdKey>>;
|
|
71
|
+
fieldLabel(field: SPEntityField<TEntity, IdKey>): Observable<string>;
|
|
70
72
|
static ɵfac: i0.ɵɵFactoryDeclaration<StationaryWithLineItemsComponent<any, any, any>, never>;
|
|
71
73
|
static ɵcmp: i0.ɵɵComponentDeclaration<StationaryWithLineItemsComponent<any, any, any>, "sp-stationary-with-line-items", never, { "entity": { "alias": "entity"; "required": true; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "number": { "alias": "number"; "required": false; "isSignal": true; }; "leftHeader": { "alias": "leftHeader"; "required": false; "isSignal": true; }; "leftHeaderTemplate": { "alias": "leftHeaderTemplate"; "required": false; "isSignal": true; }; "rightHeader": { "alias": "rightHeader"; "required": false; "isSignal": true; }; "rightHeaderTemplate": { "alias": "rightHeaderTemplate"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "leftFooter": { "alias": "leftFooter"; "required": false; "isSignal": true; }; "leftFooterTemplate": { "alias": "leftFooterTemplate"; "required": false; "isSignal": true; }; "rightFooter": { "alias": "rightFooter"; "required": false; "isSignal": true; }; "rightFooterTemplate": { "alias": "rightFooterTemplate"; "required": false; "isSignal": true; }; "itemFieldName": { "alias": "itemFieldName"; "required": false; "isSignal": true; }; "itemColumnFields": { "alias": "itemColumnFields"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
72
74
|
}
|