@smallpearl/ngx-helper 0.29.23 → 0.29.25

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.
@@ -615,8 +615,8 @@ class SPMatEntityCrudComponent extends SPMatEntityListComponent {
615
615
  }
616
616
  return true;
617
617
  }
618
- refresh() {
619
- this.spEntitiesList()?.refresh();
618
+ refresh(force = false) {
619
+ this.spEntitiesList()?.refresh(force);
620
620
  }
621
621
  closeCreateEdit(cancelled) {
622
622
  this.createEditViewActive.set(false);
@@ -700,7 +700,7 @@ class SPMatEntityCrudComponent extends SPMatEntityListComponent {
700
700
  }));
701
701
  }
702
702
  else if (refreshAfterEdit === 'all') {
703
- this.spEntitiesList()?.refresh();
703
+ this.refresh(true);
704
704
  return of(null);
705
705
  }
706
706
  return of(entity);
@@ -1 +1 @@
1
- {"version":3,"file":"smallpearl-ngx-helper-mat-entity-crud.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/mat-entity-crud-types.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/providers.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/default-config.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/form-view-host.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/preview-host.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/mat-entity-crud.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/preview-pane.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/mat-entity-crud-form-base.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/smallpearl-ngx-helper-mat-entity-crud.ts"],"sourcesContent":["import { HttpContextToken } from \"@angular/common/http\";\nimport { SPContextMenuItem } from \"@smallpearl/ngx-helper/mat-context-menu\";\nimport { Observable } from \"rxjs\";\n\n/**\n * Prototype of the function to parse the CRUD action response.\n */\nexport type SPMatEntityCrudResponseParser = (\n entityName: string,\n idKey: string,\n method: 'create' | 'retrieve' | 'update' | 'delete',\n resp: any\n) => any|undefined;\n\n\n/**\n * Global config for SPMatEntityList component.\n */\nexport interface SPMatEntityCrudConfig {\n i18n: {\n newItemLabel: (itemLabel: string) => string;\n editItemLabel: (itemLabel: string) => string;\n edit: string;\n delete: string;\n deleteItemHeader: (itemLabel: string) => string;\n deleteItemMessage: (itemLabel: string) => string;\n itemDeletedNotification: (itemLabel: string) => string;\n createdItemNotification: (itemLabel: string) => string;\n updatedItemNotification: (itemLabel: string) => string;\n loseChangesPrompt: string;\n }\n defaultItemActions?: SPContextMenuItem[];\n listPaneWrapperClass?: string;\n previewPaneWrapperClass?: string;\n previewPaneContentClass?: string;\n /**\n * Global crud response parser.\n */\n crudOpResponseParser?: SPMatEntityCrudResponseParser;\n}\n\n/**\n * This is the interface through which the client provided CRUD form component\n * interacts with the 'host' SPMatEntityCrudComponent. When the form wants to\n * submit an entity to the server (for create or update), it should call the\n * one of the create or update methods. The interface also other methods for\n * the form component to interact with SPMatEntityCrudComponent such as\n * refresh its entities list, close the form pane, etc.\n *\n * The interface name has a 'Bridge' as the interface acts as a bridge between\n * the client provided form handler component and the host\n * SPMatEntityCrudComponent.\n */\nexport interface SPMatEntityCrudCreateEditBridge {\n /**\n * Close the edit/update form pane. This WON'T call the 'cancelEditCallback'\n * even if one is registered.\n */\n close: (cancel: boolean) => void;\n /**\n * Client form view can register a callback that will be invoked by the\n * framework when user cancels the create/edit operation by clicking on the\n * close button on the top right.\n * @param callback\n * @returns None\n */\n registerCanCancelEditCallback: (callback: () => boolean) => void;\n // Parameters of type any are entity values are typically the output of\n // form.value and therefore their types would not necessarily match TEntity.\n // id can be typed as TEntity[Idkey], but TSC doesn't allow that yet.\n /**\n * Create a new instance of TEntity, by sending a POST request to remote.\n * @param entityValue This is the typically the output of Reactive form's\n * form.value. Since this value's shape may be different from TEntity and is\n * known only to client form, we use 'any'.\n * @returns None\n * @inner Implementation will show a busy wheel centered on the form\n * view while the async function to update the object remains active.\n */\n create: (entityValue: any) => Observable<any>;\n /**\n * Update the entity with id `id` with new values in entityValue.\n * @param id TEntity id\n * @param entityValue Entity values to be updated.\n * @returns None\n * @inner Implementation will show a busy wheel centered on the form\n * view while the async function to update the object remains active.\n */\n update: (id: any, entityValue: any) => Observable<any>;\n}\n\n/**\n * Prototype of the function that will be used instead of HttpClient for\n * CRUD operations.\n * @param op - the CRUD operation being requested\n * @param entityValue - The entity or entity value upon which the operation\n * is being requested. for 'create' & 'update' this will be the value\n * of the reactive form. This is typically form.value or the 2nd arg to create\n * & update methods of SPMatEntityCrudCreateEditBridge.\n */\nexport type CRUD_OP_FN<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> = (\n op: 'get' | 'create' | 'update' | 'delete',\n id: TEntity[IdKey] | undefined, // valid only for 'get', 'update' & 'delete'\n entityValue: any, // valid only for 'create' & 'update'\n entityCrudComponent: any,\n) => Observable<TEntity | null>;\n\n\nexport type ALLOW_ITEM_ACTION_FN<TEntity> = (entity: TEntity, action: string) => boolean;\n\n/**\n * This interface is used to define sub types for the \"New {{item}}\" button on\n * top of the CRUD UI. An array of these is provided as the value to the\n * component property 'newItemSubTypes'.\n */\nexport interface NewItemSubType {\n /**\n * A role string that will be passed as argument to the (action) event\n * handler. This string allows the event handler to distinguish the selected\n * sub-type.\n *\n * The special keyword '_new_' can be used to activate the\n * `createEditTemplate` template if one is provided. In this case the params\n * element value (see below) can be used in the template to distinguish\n * between different menu items.\n */\n role: string;\n /**\n * Label displayed in the menu representing this role.\n */\n label: string;\n /**\n * Arbitrary value that will be passed to the 'createEditTemplate' in the\n * $implicit template context as 'params'. You can access this in the\n * template like below (see `data.params`):-\n ```\n <ng-template #createEdit let-data>\n <app-create-edit-entity-demo\n [bridge]=\"data.bridge\"\n [entity]=\"data.entity\"\n [params]=\"data.params\"\n ></app-create-edit-entity-demo>\n </ng-template>\n ```\n\n If params is an object and it includes the key 'title', its value will be\n used as the title for the edit form.\n */\n params?: any;\n}\n\nexport type CrudOp = 'create'|'retrieve'|'update'|'delete'|undefined;\n\nexport interface SPMatEntityCrudHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n op: CrudOp;\n}\n\nexport const SP_MAT_ENTITY_CRUD_HTTP_CONTEXT =\n new HttpContextToken<SPMatEntityCrudHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n op: undefined,\n }));\n","import { InjectionToken } from '@angular/core';\nimport { SPMatEntityCrudConfig } from './mat-entity-crud-types';\n\nexport const SP_MAT_ENTITY_CRUD_CONFIG = new InjectionToken<SPMatEntityCrudConfig>('SPMatEntityCrudConfig');\n","import { inject } from \"@angular/core\";\nimport { SPMatEntityCrudConfig } from \"./mat-entity-crud-types\";\nimport { SP_MAT_ENTITY_CRUD_CONFIG } from \"./providers\";\n\nfunction defaultCrudResponseParser(\n entityName: string,\n idKey: string,\n method: 'create' | 'retrieve' | 'update' | 'delete',\n resp: any\n) {\n // If the response is an object with a property '<idKey>', return it as\n // TEntity.\n if (resp.hasOwnProperty(idKey)) {\n return resp;\n }\n // If the response has an object indexed at '<entityName>' and it has\n // the property '<idKey>', return it as TEntity.\n if (resp.hasOwnProperty(entityName)) {\n const obj = resp[entityName];\n if (obj.hasOwnProperty(idKey)) {\n return obj;\n }\n }\n // Return undefined, indicating that we could't parse the response.\n return undefined;\n}\n\nexport const DefaultSPMatEntityCrudConfig: SPMatEntityCrudConfig = {\n i18n: {\n newItemLabel: (itemLabel: string) => `New ${itemLabel}`,\n editItemLabel: (itemLabel: string) => `Edit ${itemLabel}`,\n edit: 'Edit',\n delete: 'Delete',\n deleteItemHeader: (itemLabel: string) => `Confirm Delete ${itemLabel}`,\n deleteItemMessage: (itemLabel: string) => `Are you sure you want to delete this ${itemLabel}`,\n itemDeletedNotification: (itemLabel: string) => `${itemLabel} deleted`,\n createdItemNotification: (itemLabel: string) => `${itemLabel} created.`,\n updatedItemNotification: (itemLabel: string) => `${ itemLabel } saved.`,\n loseChangesPrompt: 'OK to lose changes?'\n },\n crudOpResponseParser: defaultCrudResponseParser\n};\n\n/**\n * To be called from an object constructor as it internally calls Angular's\n * inject() API.\n * @param userConfig\n * @returns\n */\nexport function getEntityCrudConfig(): SPMatEntityCrudConfig {\n const userCrudConfig = inject(SP_MAT_ENTITY_CRUD_CONFIG, {\n optional: true,\n });\n return {\n ...DefaultSPMatEntityCrudConfig,\n ...(userCrudConfig ?? {}),\n };\n}\n","import { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n EmbeddedViewRef,\n input,\n OnDestroy,\n OnInit,\n signal,\n TemplateRef,\n viewChild,\n ViewContainerRef\n} from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { SPMatHostBusyWheelDirective } from '@smallpearl/ngx-helper/mat-busy-wheel';\nimport { Subscription, tap } from 'rxjs';\nimport { getEntityCrudConfig } from './default-config';\nimport { SPMatEntityCrudComponentBase } from './mat-entity-crud-internal-types';\nimport { SPMatEntityCrudConfig, SPMatEntityCrudCreateEditBridge } from './mat-entity-crud-types';\n\n@Component({\n imports: [CommonModule, MatButtonModule, MatIconModule, SPMatHostBusyWheelDirective],\n selector: 'sp-create-edit-entity-host',\n template: `\n <div spHostBusyWheel=\"formBusyWheel\">\n <div class=\"create-edit-topbar\">\n <div class=\"title\">\n {{ title() }}\n </div>\n <div class=\"spacer\"></div>\n <div class=\"close\">\n <button mat-icon-button (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n <ng-container #clientFormContainer></ng-container>\n </div>\n `,\n styles: `\n .create-edit-topbar {\n display: flex;\n flex-direction: row;\n align-items: center;\n min-height: 48px;\n }\n .create-edit-topbar .title {\n font-size: 1.5em;\n font-weight: 500;\n }\n .create-edit-topbar .spacer {\n flex-grow: 1;\n }\n .create-edit-topbar .close {\n\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class FormViewHostComponent<TEntity> implements SPMatEntityCrudCreateEditBridge, OnInit, OnDestroy\n{\n entityCrudComponentBase = input.required<SPMatEntityCrudComponentBase<TEntity>>();\n clientViewTemplate = input<TemplateRef<any> | null>(null);\n itemLabel = input.required<string>();\n itemLabelPlural = input.required<string>();\n\n entity = signal<TEntity|undefined>(undefined);\n title = signal<string>('');\n params = signal<any>(undefined);\n clientFormView!: EmbeddedViewRef<any> | null;\n vc = viewChild('clientFormContainer', { read: ViewContainerRef });\n config!: SPMatEntityCrudConfig;\n sub$ = new Subscription();\n\n constructor() {\n this.config = getEntityCrudConfig();\n }\n\n ngOnInit() {}\n\n ngOnDestroy(): void {\n this.sub$.unsubscribe();\n }\n\n show(entity: TEntity|undefined, params?: any) {\n this.entity.set(entity);\n if (params && params?.title) {\n this.title.set(params.title);\n } else {\n this.title.set(entity ? this.config.i18n.editItemLabel(this.itemLabel()) : this.config.i18n.newItemLabel(this.itemLabel()));\n }\n this.params.set(params);\n this.createClientView();\n }\n\n close(cancel: boolean) {\n this.entityCrudComponentBase().closeCreateEdit(cancel);\n // destroy the client's form component\n this.destroyClientView();\n }\n\n registerCanCancelEditCallback(callback: () => boolean) {\n this.entityCrudComponentBase().registerCanCancelEditCallback(callback);\n }\n\n create(entityValue: any) {\n // console.log(\n // `SPCreateEditEntityHostComponent.create - entity: ${JSON.stringify(\n // entityValue\n // )}`\n // );\n const crudComponent = this.entityCrudComponentBase();\n return crudComponent?.create(entityValue).pipe(\n tap(() => this.close(false)),\n );\n }\n\n update(id: any, entityValue: any) {\n // console.log(\n // `SPCreateEditEntityHostComponent.update - id: ${String(\n // id\n // )}, entity: ${entityValue}`\n // );\n const crudComponent = this.entityCrudComponentBase();\n return crudComponent?.update(id, entityValue).pipe(\n tap(() => this.close(false)),\n );\n }\n\n /**\n * Creates the client view provided via template\n */\n createClientView() {\n /** Render preview component if one was provided */\n const ft = this.clientViewTemplate();\n const vc = this.vc();\n if (ft && vc) {\n this.clientFormView = vc.createEmbeddedView(ft, {\n $implicit: {\n bridge: this,\n entity: this.entity(),\n params: this.params()\n },\n });\n this.clientFormView.detectChanges();\n }\n }\n\n destroyClientView() {\n if (this.clientFormView) {\n this.clientFormView.destroy();\n this.clientFormView = null;\n }\n }\n\n onClose() {\n // Can we give the client form component a chance to intercept this\n // and cancel the closure?\n if (this.entityCrudComponentBase().canCancelEdit()) {\n this.entityCrudComponentBase().closeCreateEdit(true);\n this.destroyClientView();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n EmbeddedViewRef,\n input,\n OnDestroy,\n OnInit,\n signal,\n TemplateRef,\n viewChild,\n ViewContainerRef\n} from '@angular/core';\nimport { SPMatEntityCrudComponentBase } from './mat-entity-crud-internal-types';\n\n@Component({\n imports: [],\n selector: 'sp-entity-crud-preview-host',\n template: ` <ng-container #previewComponent></ng-container> `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class PreviewHostComponent<TEntity> implements OnInit, OnDestroy {\n vc = viewChild('previewComponent', { read: ViewContainerRef });\n\n entityCrudComponentBase = input.required<SPMatEntityCrudComponentBase<TEntity>>();\n clientViewTemplate = input<TemplateRef<any> | null>(null);\n entity = signal<TEntity|undefined>(undefined);\n clientView!: EmbeddedViewRef<any> | null;\n\n constructor() {\n // effect(() => {\n // const tmpl = this.clientViewTemplate();\n // this.createClientView(tmpl);\n // });\n }\n\n ngOnInit(): void {}\n\n ngOnDestroy(): void {}\n\n show(entity: TEntity|undefined, params?: any) {\n this.entity.set(entity);\n // if (params && params?.title) {\n // this.title.set(params.title);\n // } else {\n // this.title.set(entity ? this.config.i18n.editItemLabel(this.itemLabel()) : this.config.i18n.newItemLabel(this.itemLabel()));\n // }\n // this.params.set(params);\n this.createClientView();\n }\n\n close() {\n // this.entityCrudComponentBase().closeCreateEdit(cancel);\n // destroy the client's form component\n this.destroyClientView();\n }\n\n private createClientView() {\n if (this.clientView) {\n // We have only one view in the ng-container. So we might as well\n // call clear() to remove all views contained in it.\n this.vc()!.clear();\n this.clientView.destroy();\n }\n /** Render preview component if one was provided */\n const ft = this.clientViewTemplate();\n const vc = this.vc();\n if (ft && vc) {\n this.clientView = this.vc()!.createEmbeddedView(\n ft,\n {\n $implicit: {\n entity: this.entity(),\n entityCrudComponent: this.entityCrudComponentBase(),\n },\n }\n );\n this.clientView.detectChanges();\n }\n }\n\n\n destroyClientView() {\n if (this.clientView) {\n this.clientView.destroy();\n this.clientView = null;\n }\n }\n\n // close() {\n // this.closePreview.emit();\n // }\n}\n","import { CommonModule } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ContentChildren,\n EventEmitter,\n Injector,\n input,\n Output,\n QueryList,\n signal,\n TemplateRef,\n viewChild,\n viewChildren\n} from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';\nimport { MatSortModule } from '@angular/material/sort';\nimport { MatColumnDef, MatTableModule } from '@angular/material/table';\nimport { RouterModule } from '@angular/router';\nimport {\n showBusyWheelUntilComplete,\n SPMatHostBusyWheelDirective\n} from '@smallpearl/ngx-helper/mat-busy-wheel';\nimport {\n SPContextMenuItem,\n SPMatContextMenuComponent,\n} from '@smallpearl/ngx-helper/mat-context-menu';\nimport { SPMatEntityListComponent } from '@smallpearl/ngx-helper/mat-entity-list';\n\nimport { MatMenuModule } from '@angular/material/menu';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { SPEntityFieldSpec } from '@smallpearl/ngx-helper/entity-field';\nimport { AngularSplitModule } from 'angular-split';\nimport { startCase } from 'lodash';\nimport { plural } from 'pluralize';\nimport { map, Observable, of, Subscription, switchMap, tap } from 'rxjs';\nimport { getEntityCrudConfig } from './default-config';\nimport { FormViewHostComponent } from './form-view-host.component';\nimport { SPMatEntityCrudComponentBase } from './mat-entity-crud-internal-types';\nimport {\n ALLOW_ITEM_ACTION_FN,\n CRUD_OP_FN,\n CrudOp,\n NewItemSubType,\n SP_MAT_ENTITY_CRUD_HTTP_CONTEXT,\n SPMatEntityCrudConfig,\n SPMatEntityCrudResponseParser,\n} from './mat-entity-crud-types';\nimport { PreviewHostComponent } from './preview-host.component';\n\n@Component({\n imports: [\n CommonModule,\n RouterModule,\n MatButtonModule,\n MatTableModule,\n MatSortModule,\n MatMenuModule,\n MatSnackBarModule,\n AngularSplitModule,\n SPMatEntityListComponent,\n SPMatContextMenuComponent,\n FormViewHostComponent,\n SPMatHostBusyWheelDirective,\n PreviewHostComponent,\n ],\n selector: 'sp-mat-entity-crud',\n template: `\n <as-split direction=\"horizontal\" [gutterSize]=\"6\">\n <as-split-area [size]=\"entitiesPaneWidth()\" [visible]=\"!entitiesPaneHidden()\">\n <div\n [class]=\"crudConfig.listPaneWrapperClass\"\n >\n <ng-content select=\"[breadCrumbs]\"></ng-content>\n\n <ng-template #defaultActionButtons>\n <div class=\"action-bar-actions\">\n @if (!disableCreate()) { @if (newItemSubTypes()) {\n <!-- New {{item}} displays a dropdown menu from which the subtype can be selected -->\n <button\n type=\"button\"\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"newSubTypesMenu\"\n >\n {{\n newItemLabel() ??\n crudConfig.i18n.newItemLabel(this._itemLabel())\n }}&nbsp;&#9660;\n <!-- down arrow-head -->\n </button>\n <mat-menu #newSubTypesMenu=\"matMenu\">\n @for (subtype of newItemSubTypes(); track $index) { @if\n (subtype.role) {\n <button mat-menu-item (click)=\"handleNewItemSubType(subtype)\">\n {{ subtype.label }}\n </button>\n } @else {\n <div style=\"padding: .2em 0.5em;\">\n <strong>{{ subtype.label }}</strong>\n </div>\n } }\n </mat-menu>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n (click)=\"onCreate($event)\"\n [routerLink]=\"newItemLink()\"\n >\n {{\n newItemLabel() ??\n crudConfig.i18n.newItemLabel(this._itemLabel())\n }}\n </button>\n } }\n </div>\n </ng-template>\n\n <ng-template #defaultHeaderTemplate>\n <div class=\"action-bar\">\n <div class=\"action-bar-title\">\n {{ _title() }}\n </div>\n <span class=\"spacer\"></span>\n <!-- Hide the action buttons when Preview/Edit pane is active -->\n @if (!entityPaneActive()) {\n <ng-container\n [ngTemplateOutlet]=\"actionsTemplate() || defaultActionButtons\"\n ></ng-container>\n }\n </div>\n </ng-template>\n <ng-container\n [ngTemplateOutlet]=\"headerTemplate() || defaultHeaderTemplate\"\n ></ng-container>\n <sp-mat-entity-list\n [entityName]=\"entityName()\"\n [entityNamePlural]=\"entityNamePlural()\"\n [_deferViewInit]=\"true\"\n [endpoint]=\"endpoint()\"\n [entityLoaderFn]=\"entityLoaderFn()\"\n [columns]=\"columnsWithAction()\"\n [displayedColumns]=\"visibleColumns()\"\n [idKey]=\"idKey()\"\n [pagination]=\"pagination()\"\n [paginator]=\"paginator()\"\n [pageSize]=\"pageSize()\"\n [sorter]=\"sorter()\"\n [disableSort]=\"disableSort()\"\n (selectEntity)=\"handleSelectEntity($event)\"\n [httpReqContext]=\"httpReqContext()\"\n >\n </sp-mat-entity-list>\n </div>\n\n <!--\n We'll be initializing the contentColumnDefs separately and not\n relying on <sp-mat-entity-list>'s internal @ContentChildre() querylist\n for building this. So we define this independenly and not as\n <sp-mat-entity-list> content.\n -->\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td\n mat-cell\n *matCellDef=\"let element\"\n (click)=\"$event.stopImmediatePropagation()\"\n >\n @if (_itemActions().length) {\n <sp-mat-context-menu\n [menuItems]=\"_itemActions()\"\n (selected)=\"onItemAction($event, element)\"\n [contextData]=\"element\"\n [hasBackdrop]=\"true\"\n ></sp-mat-context-menu>\n }\n </td>\n </ng-container>\n\n <!--\n <div\n [class]=\"crudConfig.listPaneWrapperClass\"\n [ngStyle]=\"{ display: createEditViewActive() ? 'inherit' : 'none' }\"\n spHostBusyWheel=\"formBusyWheel\"\n >\n <ng-content select=\"[breadCrumbs]\"></ng-content>\n <sp-create-edit-entity-host\n [itemLabel]=\"_itemLabel()\"\n [itemLabelPlural]=\"_itemLabelPlural()\"\n [entityCrudComponentBase]=\"this\"\n [clientViewTemplate]=\"createEditFormTemplate()\"\n ></sp-create-edit-entity-host>\n </div>\n -->\n </as-split-area>\n <as-split-area [size]=\"entityPaneWidth()\" [visible]=\"entityPaneActive()\">\n <div [class]=\"crudConfig.previewPaneWrapperClass\" spHostBusyWheel=\"formBusyWheel\">\n <sp-entity-crud-preview-host\n [ngClass]=\"createEditViewActive() ? 'd-none' : 'd-inherit'\"\n [entityCrudComponentBase]=\"this\"\n [clientViewTemplate]=\"previewTemplate()!\"\n ></sp-entity-crud-preview-host>\n <!-- Create/Edit Entity -->\n <sp-create-edit-entity-host\n [ngClass]=\"createEditViewActive() ? 'd-inherit' : 'd-none'\"\n [itemLabel]=\"_itemLabel()\"\n [itemLabelPlural]=\"_itemLabelPlural()\"\n [entityCrudComponentBase]=\"this\"\n [clientViewTemplate]=\"createEditFormTemplate()\"\n ></sp-create-edit-entity-host>\n </div>\n </as-split-area>\n </as-split>\n `,\n styles: `\n .d-none {\n display: none;\n }\n .d-inherit {\n display: inherit;\n }\n .action-bar {\n display: flex;\n flex-direction: row;\n align-items: center;\n padding-bottom: 0.5em;\n }\n .action-bar-title {\n font-size: 1.5em;\n font-weight: 600;\n }\n .spacer {\n flex-grow: 1;\n }\n .action-bar-actions {\n text-align: end;\n }\n .active-row {\n font-weight: bold;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SPMatEntityCrudComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >\n extends SPMatEntityListComponent<TEntity, IdKey>\n implements SPMatEntityCrudComponentBase<TEntity>, AfterViewInit\n{\n // entityName = input.required<string>();\n // entityNamePlural = input<string>();\n\n itemLabel = input<string>();\n itemLabelPlural = input<string>();\n /**\n * Title string displayed above the component. If not specified, will use\n * itemLabelPlural() as the title.\n */\n title = input<string>();\n /**\n *\n */\n itemActions = input<SPContextMenuItem[]>([]);\n /**\n * Specify the list of router paths that will be set as the value for\n * [routerLink] for the 'New {{ item }}' button. If not specified,\n * if createEditTemplate is specified, it will be shown. If not, `action`\n * out event will be raised with `{ role: '_new_' }`.\n */\n newItemLink = input<string | string[]>();\n /**\n * If not specified, will use label from SPMatEntityCrudConfig.i18n.newItemLabel.\n */\n newItemLabel = input<string | string[]>();\n /**\n * Text for the Edit <item> pane title\n */\n editItemTitle = input<string>();\n /**\n * If you want \"New {{item}}\" button to support multiple entity types,\n * you can set this to `NewItemSubType[]`, where each element stands for for\n * a dropdown menu item. Refer to `NewItemSubType` for details on this\n * interface.\n */\n newItemSubTypes = input<NewItemSubType[]>();\n /**\n * If you want to take control of the network operations for the CRUD\n * operations (GET/CREATE/UPDATE/DELETE), provide a value for this property.\n */\n crudOpFn = input<CRUD_OP_FN<TEntity, IdKey>>();\n /**\n * Item preview template.\n */\n previewTemplate = input<TemplateRef<any>>();\n /**\n * Whether to allow a context menu action or not. Return false to disable\n * the action.\n */\n allowEntityActionFn = input<ALLOW_ITEM_ACTION_FN<TEntity>>();\n /**\n * A template that allows the header to be replaced. Usage:-\n *\n * ```\n * <sp-map-entity-crud\n * [headerTemplate]=\"myCrudViewHeader\"\n * ></sp-map-entity-crud>\n * <ng-template #myCrudViewHeader>...</ng-template>\n * ```\n */\n headerTemplate = input<TemplateRef<any>>();\n /**\n * Set this to the custom template identifier that will replace the\n * \"New {{Item}}\" button portion. This template will expand towards the\n * title which will be placed to its left (right in rtl).\n *\n * ```\n * <sp-map-entity-crud\n * [actionsTemplate]=\"myCrudActions\"\n * ></sp-map-entity-crud>\n * <ng-template #myCrudActions>...</ng-template>\n * ```\n */\n actionsTemplate = input<TemplateRef<any>>();\n\n /**\n * CRUD action response parser. This will be called with the response\n * from CREATE & UPDATE operations to parse the response JSON and return\n * the created/updated TEntity.\n */\n crudResponseParser = input<SPMatEntityCrudResponseParser>();\n /**\n * An ng-template name that contains the component which provides the\n * create/edit CRUD action.\n *\n * ```\n * <ng-template #createEdit let-data>\n * <app-create-edit-entity-demo [bridge]=\"data.bridge\" [entity]=\"data.entity\"></app-create-edit-entity-demo>\n * </ng-template>\n * ```\n * Note how [bridge] & [entity] properties are set deriving them from the\n * implicit template context. [entity] will be undefined for Create\n * opreation and will be the valid entity for an Update.\n * (app-create-edit-entity-demo here is the client code that implements the\n * Create/Edit form)\n */\n createEditFormTemplate = input<TemplateRef<any> | null>(null);\n /**\n * Disables the per item actions column, preventing 'Edit' & 'Delete'\n * (and other user defined) item operations.\n */\n disableItemActions = input<boolean>(false);\n /**\n * Disables the Create function.\n */\n disableCreate = input<boolean>(false);\n /**\n * View refresh policy after a CREATE/UPDATE operation. Values\n * 'none' - Objects are not refreshed after an edit operation. The return\n * value of the edit operation is used as the object to\n * add/update the component's internal store. This is the default.\n * 'object' - Refresh just the object that was returned from the\n * CREATE/UPDATE operation. Use this if the JSON object returned\n * after a successful CREATE/UPDATE op differs from the JSON\n * object returned for the GET request.\n * 'all' - Refresh the entire list after a CREATE/UPDATE operation. This\n * mimics the behaviour of legacy HTML apps with pure server\n * defined UI.\n */\n refreshAfterEdit = input<'none' | 'object' | 'all'>('none');\n /**\n * HttpContext for crud requests - list, create, retrieve, update & delete.\n * The value can be an object where the property names reflect the CRUD\n * methods with each of these keys taking\n * `[[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]` as its\n * value. This object has a special key 'crud', which if given a value for,\n * would be used for all CRUD requests (CREATE|READ|UPDATE|DELETE).\n *\n * Alternatively the property can be set a\n * `[[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]` as its\n * value, in which case the same context would be used for all HTTP requests.\n */\n crudHttpReqContext = input<\n | [[HttpContextToken<any>, any]]\n | [HttpContextToken<any>, any]\n | {\n // list?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any];\n // crud?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]; // common context for all crud operations\n create?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]; // CREATE\n retrieve?:\n | [[HttpContextToken<any>, any]]\n | [HttpContextToken<any>, any]; // RETRIEVE\n update?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]; // UPDATE\n delete?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]; // DELETE\n }\n >();\n /**\n * Width of the edit pane as a percentange of the overall <as-split> width.\n */\n editPaneWidth = input<number>(100);\n /**\n * Width of the preview pane as a percentange of the overall <as-split> width.\n */\n previewPaneWidth = input<number>(50);\n\n // INTERNAL PROPERTIES //\n // Derive a label from a camelCase source string. If the camelCase string\n // can be translated, it returns the translated string. If not, the function\n // converts the camelCase to 'Title Case' and returns it.\n private getLabel = (source: string) => {\n const label = this.ngxHelperConfig.i18nTranslate(source);\n if (label.localeCompare(source) !== 0) {\n // Successful translation, return it\n return label;\n }\n return startCase(source);\n };\n\n _itemLabel = computed<string>(() =>\n this.itemLabel()\n ? (this.itemLabel() as string)\n : this.getLabel(this.entityName())\n );\n _itemLabelPlural = computed<string>(() =>\n this.itemLabelPlural()\n ? (this.itemLabelPlural() as string)\n : this.getLabel(plural(this.entityName()))\n );\n // Computed title\n _title = computed(() =>\n this.title() ? this.title() : this._itemLabelPlural()\n );\n // endpoint with the QP string removed (if one was provided)\n _endpointSansParams = computed(() => this.endpoint().split('?')[0]);\n _endpointParams = computed(() => {});\n componentColumns = viewChildren(MatColumnDef);\n @ContentChildren(MatColumnDef) _clientColumnDefs!: QueryList<MatColumnDef>;\n\n /**\n * Event raised for user selecting an item action. It's also raised\n * for 'New <Item>' action, if 'newItemLink' property is not set.\n */\n @Output() action = new EventEmitter<{ role: string; entity?: TEntity }>();\n\n /**\n * Event raised when create Create/Edit pane is activated & deactivated.\n * Event contains two flags:-\n * activated - whether the createEdit form view was activated or\n * deactivated.\n * cancelled - whether the form view was cancelled by user. False for this\n * indicates that the form view was closed after a successful\n * edit operation.\n */\n @Output() entityViewPaneActivated = new EventEmitter<{\n activated: boolean;\n cancelled: boolean|undefined;\n mode: 'edit'|'preview';\n }>();\n\n busyWheelId = `entityCrudBusyWheel-${Date.now()}`;\n sub$ = new Subscription();\n spEntitiesList = viewChild(SPMatEntityListComponent<TEntity, IdKey>);\n crudConfig!: SPMatEntityCrudConfig;\n\n // This is the internal component that will host the createEditFormTemplate\n createEditHostComponent = viewChild(FormViewHostComponent);\n // A flag to toggle the viewport's contents between the mat-table\n // and the create/edit form template.\n createEditViewActive = signal<boolean>(false);\n\n // Whether it's okay to cancel the edit\n canCancelEditCallback!: () => boolean;\n\n // Preview host component\n previewHostComponent = viewChild(PreviewHostComponent);\n previewActive = computed(() => this.previewedEntity() !== undefined);\n previewedEntity = signal<TEntity | undefined>(undefined);\n\n // Whether the pane that hosts the preview/edit-entity template is active.\n // We call it entityPane as it's used to either render a selected entity\n // or to edit one.\n entityPaneActive = computed(() => !!this.previewedEntity() || this.createEditViewActive());\n // Effective width of the entity pane.\n entityPaneWidth = computed(() => !!this.previewedEntity() ? this.previewPaneWidth() : this.editPaneWidth());\n\n // Width of the pane showing the list of entities. Calculated as\n entitiesPaneWidth = computed(() => 100 - this.entityPaneWidth());\n entitiesPaneHidden = computed(() => this.entityPaneActive() && this.entityPaneWidth() === 100);\n\n defaultItemCrudActions = signal<SPContextMenuItem[]>([]);\n columnsWithAction = computed(() => {\n const cols: Array<SPEntityFieldSpec<TEntity, IdKey> | string> = JSON.parse(\n JSON.stringify(this.columns())\n );\n // JSON.parse(JSON.strigify()) does not clone function objects. So\n // explicitly copy these over. So this is really a shallow clone as\n // the cloned objects still refers to the function objects in the original\n // object.\n this.columns().forEach((col, index: number, orgColumns) => {\n const orgCol = orgColumns[index];\n if (typeof orgCol !== 'string') {\n const newColumn = cols[index] as SPEntityFieldSpec<TEntity, IdKey>;\n if (orgCol.valueFn) {\n newColumn.valueFn = orgCol.valueFn;\n }\n if (orgCol.valueOptions) {\n newColumn.valueOptions = orgCol.valueOptions;\n }\n }\n });\n const actionDefined =\n cols.find((c) =>\n typeof c === 'string' ? c === 'action' : c.name === 'action'\n ) !== undefined;\n if (!actionDefined && !this.disableItemActions()) {\n cols.push('action');\n }\n return cols;\n });\n // Use a custom computed() signal to derive the action items for each\n // entity so that we can run per item's allow item action function to\n // selectively disable one or more actions based on the item's state.\n _itemActions = computed(() => {\n const actions =\n this.itemActions() && this.itemActions().length\n ? this.itemActions()\n : this.defaultItemCrudActions();\n let actionsCopy: SPContextMenuItem[] = JSON.parse(JSON.stringify(actions));\n actionsCopy.forEach((action, index: number) => {\n const orgDisable = actions[index]?.disable;\n action.disable = (entity: TEntity) => {\n if (orgDisable) {\n return orgDisable(entity);\n }\n const allowItemActionFn = this.allowEntityActionFn();\n if (allowItemActionFn) {\n return !allowItemActionFn(entity, action.role ?? action.label);\n }\n return false;\n };\n });\n return actionsCopy;\n });\n // This uses the previewActive signal to compute the visible columns\n // when preview is activated. For now we just hide the 'action' column when\n // preview is active. We can further customize this logic by allowing the\n // client to specify the columns to display when preview is active thereby\n // reducing column clutter when the table width becomes narrower owing to\n // preview pane taking up screen space.\n visibleColumns = computed(() =>\n this.entityPaneActive()\n ? this.columnsWithAction()\n .map((col) => (typeof col === 'string' ? col : col.name))\n .filter((name) => name !== 'action')\n : []\n );\n\n constructor(\n http: HttpClient,\n private snackBar: MatSnackBar,\n sanitizer: DomSanitizer,\n injector: Injector,\n ) {\n super(http, sanitizer, injector);\n this.crudConfig = getEntityCrudConfig();\n if (this.crudConfig?.defaultItemActions) {\n this.defaultItemCrudActions.set(this.crudConfig?.defaultItemActions);\n } else {\n this.defaultItemCrudActions.set([\n { label: this.crudConfig.i18n.edit, role: '_update_' },\n { label: this.crudConfig.i18n.delete, role: '_delete_' },\n ]);\n }\n }\n\n override ngOnInit() {}\n\n override ngOnDestroy(): void {\n this.sub$.unsubscribe();\n }\n\n override ngAfterViewInit(): void {\n const spEntitiesList = this.spEntitiesList();\n if (spEntitiesList) {\n // Build contentColumnDefs using our component's content. Then add our own\n // 'action' column definition to it. Then set this as the value of\n // child SPMatEntityListComponent.contentColumnDef. This way we force\n // SPMatEntityListComponent to use our component's any project MatColumnDef\n // content in the final mat-table.\n const clientColumnDefs = this.clientColumnDefs;\n if (clientColumnDefs && spEntitiesList) {\n // Note that we process any content projected matColumnDef first and\n // our own internal content later. And when we process our own internal\n // columns (for now only 'action'), it's not added if a column with that\n // name has already been defined via content projection. This allows the\n // clients to override even internal columns with their column defintion.\n let contentColumnDefs = new Array<MatColumnDef>();\n clientColumnDefs.toArray().forEach((c) => contentColumnDefs.push(c));\n this.componentColumns().forEach((ic) => {\n if (!contentColumnDefs.find((c) => c.name === ic.name)) {\n contentColumnDefs.push(ic);\n }\n });\n spEntitiesList.contentColumnDefs = contentColumnDefs;\n }\n // This is a replication of SPMatEntityCrudList.ngAfterViewInit. That\n // code is skipped as we declare set the _deferViewInit=true in\n // sp-mat-entity-list declaration.\n spEntitiesList.buildColumns();\n spEntitiesList.setupSort();\n spEntitiesList.loadMoreEntities();\n }\n }\n\n /**\n * If the create/edit entity form is active, it calls its registered\n * canCancelEdit callback to determine if it's okay to cancel the edit.\n * You can use this method from the host component's router guard to\n * ensure that any changes made to the form are not accidentally lost by\n * navigating away from the CRUD page.\n *\n * If your CRUD page has multiple sp-mat-entity-crud components, you have to\n * implement the logic to call this method on the appropriate component.\n *\n * If the the create/edit form is not active, this method returns true.\n * @returns\n */\n canDeactivate() {\n if (this.createEditViewActive()) {\n return this.canCancelEdit();\n }\n return true;\n }\n\n override refresh() {\n this.spEntitiesList()?.refresh();\n }\n\n closeCreateEdit(cancelled: boolean) {\n this.createEditViewActive.set(false);\n this.entityViewPaneActivated.emit({ activated: false, cancelled: !!cancelled, mode: 'edit' });\n }\n\n canCancelEdit() {\n if (this.canCancelEditCallback) {\n return this.canCancelEditCallback();\n }\n return true;\n }\n\n registerCanCancelEditCallback(callback: () => boolean) {\n this.canCancelEditCallback = callback;\n }\n\n triggerEntityUpdate(entity: TEntity) {\n this.onUpdate(entity);\n }\n\n triggerEntityDelete(entity: TEntity) {\n this.onDelete(entity);\n }\n\n create(entityValue: any) {\n let obs!: Observable<TEntity | null>;\n const crudOpFn = this.crudOpFn();\n if (crudOpFn) {\n obs = crudOpFn('create', undefined, entityValue, this);\n } else {\n obs = this.http.post<TEntity>(this.getUrl(this.endpoint()), entityValue, {\n context: this.getCrudReqHttpContext('create'),\n });\n }\n\n return obs.pipe(\n showBusyWheelUntilComplete('formBusyWheel'),\n switchMap((resp) =>\n resp ? this.doRefreshAfterEdit(resp, 'create') : of(null)\n ),\n tap((entity) => {\n // If pagination is infinite or if the pagination if none or if the\n // count of items in the current page is less than pageSize()\n // wec an safely add the item to the list, which will cause the view\n // render the new item in the mat-table.\n if (entity) {\n this.spEntitiesList()?.addEntity(entity);\n this.snackBar.open(\n this.crudConfig.i18n.createdItemNotification(this._itemLabel())\n );\n }\n })\n );\n }\n\n update(id: TEntity[IdKey], entityValue: any) {\n let obs!: Observable<TEntity | null>;\n const crudOpFn = this.crudOpFn();\n if (crudOpFn) {\n obs = crudOpFn('update', id, entityValue, this);\n } else {\n obs = this.http.patch<TEntity>(this.getEntityUrl(id), entityValue, {\n context: this.getCrudReqHttpContext('update'),\n });\n }\n\n return obs.pipe(\n showBusyWheelUntilComplete('formBusyWheel'),\n switchMap((resp) =>\n resp ? this.doRefreshAfterEdit(resp, 'update') : of(null)\n ),\n tap((entity) => {\n if (entity) {\n this.spEntitiesList()?.updateEntity(id, entity);\n this.snackBar.open(\n this.crudConfig.i18n.updatedItemNotification(this._itemLabel())\n );\n }\n })\n );\n }\n\n /**\n * Refresh the entity list, after a CRUD CREATE or UPDATE operation.\n * @param resp This is the response from the CRUD operation (CREATE/UPDATE).\n * @param method The CRUD operation post which REFRESH is requested.\n * @returns Observable<TEntity|null>\n */\n doRefreshAfterEdit(resp: any, method: 'create' | 'update') {\n const refreshAfterEdit = this.refreshAfterEdit();\n const entity = this.getCrudOpResponseParser()(\n this.entityName(),\n this.idKey(),\n method,\n resp\n );\n if (refreshAfterEdit === 'object') {\n let obs!: Observable<TEntity>;\n const crudOpFn = this.crudOpFn();\n if (crudOpFn) {\n obs = crudOpFn(\n 'get',\n (entity as any)[this.idKey()],\n undefined,\n this\n ) as Observable<TEntity>;\n } else {\n obs = this.http.get<TEntity>(\n this.getEntityUrl((entity as any)[this.idKey()]),\n { context: this.getCrudReqHttpContext('retrieve') }\n );\n }\n return obs.pipe(\n map((entity) => {\n return this.getCrudOpResponseParser()(\n this.entityName(),\n this.idKey(),\n 'retrieve',\n entity\n );\n })\n );\n } else if (refreshAfterEdit === 'all') {\n this.spEntitiesList()?.refresh();\n return of(null);\n }\n\n return of(entity);\n }\n\n getCrudOpResponseParser(): SPMatEntityCrudResponseParser {\n if (this.crudResponseParser()) {\n // Without the `as SPMatEntityCrudResponseParser`, TSC will complain.\n return this.crudResponseParser() as SPMatEntityCrudResponseParser;\n }\n // crudConfig will have a parser as our default config provides one.\n return this.crudConfig\n .crudOpResponseParser as SPMatEntityCrudResponseParser;\n }\n\n // SPMatEntityCrudComponentBase interface method. Thunk to the implementation\n // method closePreviewImpl().\n closePreview() {\n this.closePreviewImpl(true);\n }\n\n private closePreviewImpl(toggleEntityListActiveEntity: boolean) {\n if (this.previewedEntity()) {\n if (toggleEntityListActiveEntity) {\n this.spEntitiesList()?.toggleActiveEntity(this.previewedEntity());\n }\n this.previewedEntity.set(undefined);\n this.entityViewPaneActivated.emit({ activated: false, cancelled: undefined, mode: 'preview' });\n }\n }\n\n onItemAction(role: string, entity: TEntity) {\n if (role === '_update_') {\n this.onUpdate(entity);\n } else if (role === '_delete_') {\n this.onDelete(entity);\n } else {\n this.action.emit({ role, entity });\n }\n }\n\n onCreate(event: Event) {\n // If newItemLink() has not been provided, check if createEditFormTemplate\n // is specified. If it is, load it and make that cover the entire viewport.\n // If that too is not specified, emit an action event with role='_new_'.\n if (!this.newItemLink() || this.newItemLink()?.length == 0) {\n event.preventDefault();\n event.stopImmediatePropagation();\n const params = {\n title: this.newItemLabel() ?? this.crudConfig.i18n.newItemLabel(this._itemLabel()),\n }\n this.showCreateEditView(undefined, params);\n // const tmpl = this.createEditFormTemplate();\n // if (tmpl) {\n // // If preview is active deactivate it\n // if (this.previewActive()) {\n // this.closePreview();\n // }\n // const createEditHost = this.createEditHostComponent();\n // createEditHost!.show(undefined);\n // this.createEditViewActive.set(true);\n // }\n }\n if (!this.createEditViewActive()) {\n this.action.emit({ role: '_new_' });\n }\n }\n\n onUpdate(entity: TEntity) {\n const params = {\n title: this.editItemTitle() ?? this.crudConfig.i18n.editItemLabel(this._itemLabel()),\n }\n this.showCreateEditView(entity, params);\n\n // const tmpl = this.createEditFormTemplate();\n // if (tmpl) {\n // // If preview is active deactivate it\n // if (this.previewActive()) {\n // this.closePreview();\n // }\n // const createEditHost = this.createEditHostComponent();\n // if (tmpl && createEditHost) {\n // createEditHost.show(entity);\n // this.createEditViewActive.set(true);\n // }\n // }\n if (!this.createEditViewActive()) {\n this.action.emit({ role: '_update_' });\n }\n }\n\n /**\n * Show the create/edit component. This is deliberately made public so as to\n * be callable from the client. This allows the client to dynamically\n * set the form edit template and then show the edit pane by calling this\n * method.\n * @param entity\n * @param params\n */\n showCreateEditView(entity?: TEntity | undefined, params?: any) {\n const tmpl = this.createEditFormTemplate();\n if (!this.createEditViewActive() && !this.previewActive() && tmpl) {\n // If preview is active deactivate it\n if (this.previewActive()) {\n this.closePreviewImpl(true);\n }\n const createEditHost = this.createEditHostComponent();\n createEditHost!.show(entity, params);\n this.createEditViewActive.set(true);\n this.entityViewPaneActivated.emit({ activated: true, cancelled: undefined, mode: 'edit' });\n }\n }\n\n showPreviewView(entity?: TEntity, params?: any) {\n const tmpl = this.previewTemplate();\n if (tmpl) {\n if (!this.createEditViewActive()) {\n const previewHost = this.previewHostComponent();\n this.previewedEntity.set(entity);\n previewHost?.show(entity, params);\n this.entityViewPaneActivated.emit({ activated: true, cancelled: undefined, mode: 'preview' });\n // this.previewActivated.emit({ entity, activated: true });\n }\n }\n }\n\n hidePreviewView() {\n if (this.previewActive()) {\n const previewHost = this.previewHostComponent();\n previewHost?.close();\n this.closePreviewImpl(false);\n }\n }\n\n async onDelete(entity: TEntity) {\n // Do the delete prompt asynchronously so that the context menu is\n // dismissed before the prompt is displayed.\n setTimeout(() => {\n const deletedItemPrompt = this.crudConfig.i18n.deleteItemMessage(\n this._itemLabel()\n );\n const yes = confirm(deletedItemPrompt);\n if (yes) {\n const entityId = (entity as any)[this.idKey()];\n\n // If preview is active deactivate it\n if (this.previewActive()) {\n this.closePreviewImpl(false);\n }\n\n let obs!: Observable<any>;\n const crudOpFn = this.crudOpFn();\n if (crudOpFn) {\n obs = crudOpFn('delete', entityId, undefined, this);\n } else {\n obs = this.http.delete<void>(this.getEntityUrl(entityId), {\n context: this.getCrudReqHttpContext('delete'),\n });\n }\n\n this.sub$.add(\n obs\n .pipe(\n // TODO: how to display a busy wheel?\n // showBusyWheelUntilComplete(this.busyWheelId),\n tap(() => {\n this.spEntitiesList()!.removeEntity(entityId);\n // TODO: customize by providing an interface via SPMatEntityCrudConfig?\n const deletedMessage =\n this.crudConfig.i18n.itemDeletedNotification(\n this._itemLabel()\n );\n this.snackBar.open(deletedMessage);\n })\n )\n .subscribe()\n );\n }\n });\n }\n\n override getUrl(endpoint: string) {\n return this.entityListConfig?.urlResolver\n ? this.entityListConfig?.urlResolver(endpoint)\n : endpoint;\n }\n\n getEntityUrl(entityId: TEntity[IdKey]) {\n const endpoint = this.endpoint();\n const endpointParts = endpoint.split('?');\n const entityEndpoint =\n (endpointParts[0].endsWith('/')\n ? endpointParts[0]\n : endpointParts[0] + '/') + `${String(entityId)}/`;\n if (endpointParts.length > 1) {\n return this.getUrl(entityEndpoint + `?${endpointParts[1]}`);\n }\n return this.getUrl(entityEndpoint);\n }\n\n handleSelectEntity(entity: TEntity|undefined) {\n if (!this.createEditViewActive()) {\n if (this.previewTemplate()) {\n entity ? this.showPreviewView(entity) : this.hidePreviewView();\n // this.previewedEntity.set(entity);\n } else {\n // If 'previewTemplate' is not set, propagate the event to client.\n this.selectEntity.emit(entity);\n }\n }\n }\n\n handleNewItemSubType(subtype: NewItemSubType) {\n // console.log(`handleNewItemSubType: ${subtype}`);\n if (subtype.role === '_new_') {\n this.showCreateEditView(undefined, subtype?.params);\n } else {\n this.action.emit({ role: subtype.role });\n }\n }\n\n private getCrudReqHttpContext(op: CrudOp) {\n const contextParamToHttpContext = (\n context: HttpContext,\n reqContext: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]\n ) => {\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\n let context = new HttpContext();\n const crudHttpReqContext = this.crudHttpReqContext();\n if (crudHttpReqContext) {\n if (Array.isArray(crudHttpReqContext)) {\n // Same HttpContext for all crud requests\n contextParamToHttpContext(context, crudHttpReqContext);\n } else if (\n typeof crudHttpReqContext === 'object' &&\n op &&\n crudHttpReqContext[op]\n ) {\n contextParamToHttpContext(context, crudHttpReqContext[op]!);\n // if (crudHttpReqContext[op]) {\n // context = contextParamToHttpContext(crudHttpReqContext[op] as any);\n // } else if (crudHttpReqContext['crud']) {\n // context = contextParamToHttpContext(crudHttpReqContext['crud'] as any);\n // }\n }\n // } else if (this.httpReqContext()) {\n // context = contextParamToHttpContext(this.httpReqContext()!);\n }\n\n context.set(SP_MAT_ENTITY_CRUD_HTTP_CONTEXT, {\n entityName: this.entityName(),\n entityNamePlural: this._entityNamePlural(),\n endpoint: this.endpoint(),\n op,\n });\n return context;\n // const httpReqContext = this.httpReqContext();\n // return httpReqContext\n // ? contextParamToHttpContext(httpReqContext)\n // : undefined;\n }\n}\n","import { ChangeDetectionStrategy, Component, Inject, input, OnDestroy, OnInit, Optional } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatToolbarModule } from '@angular/material/toolbar';\nimport { SPMatEntityCrudComponentBase } from './mat-entity-crud-internal-types';\nimport { SPMatEntityCrudConfig } from './mat-entity-crud-types';\nimport { SP_MAT_ENTITY_CRUD_CONFIG } from './providers';\nimport { getEntityCrudConfig } from './default-config';\n\n/**\n * A preview pane container to provide a consistent UX for all preview panes.\n * It consits of a toolbar on the top and a container div below that takes up\n * the rest of the preview pane area.\n */\n@Component({\n imports: [MatToolbarModule, MatButtonModule, MatIconModule],\n selector: 'sp-mat-entity-crud-preview-pane',\n template: `\n <div class=\"preview-wrapper\">\n <mat-toolbar>\n <mat-toolbar-row>\n @if (title()) {\n <h2>{{ title() }}</h2>&nbsp;\n }\n @if (!hideUpdate()) {\n <button mat-icon-button aria-label=\"Edit\" (click)=\"onEdit()\" [disabled]=\"disableUpdate()\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n @if (!hideDelete()) {\n <button mat-icon-button aria-label=\"Delete\" (click)=\"onDelete()\" [disabled]=\"disableDelete()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n <ng-content select=\"[previewToolbarContent]\"></ng-content>\n <span class=\"spacer\"></span>\n <button mat-icon-button aria-label=\"Close\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-toolbar-row>\n </mat-toolbar>\n <div [class]=\"'preview-content ' + (config.previewPaneContentClass ?? '')\">\n <ng-content select=\"[previewContent]\"></ng-content>\n </div>\n </div>\n `,\n styles: [`\n .preview-wrapper {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n .spacer {\n flex: 1 1 auto;\n }\n .preview-content {\n flex-grow: 1;\n overflow: scroll;\n }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SPMatEntityCrudPreviewPaneComponent<TEntity> implements OnInit, OnDestroy {\n\n entity = input.required<TEntity>();\n entityCrudComponent = input.required<SPMatEntityCrudComponentBase<TEntity>>();\n title = input<string>();\n disableUpdate = input<boolean>(false);\n hideUpdate = input<boolean>(false);\n disableDelete = input<boolean>(false);\n hideDelete = input<boolean>(false);\n config!: SPMatEntityCrudConfig;\n\n constructor() {\n this.config = getEntityCrudConfig();\n }\n\n ngOnInit() {\n }\n\n ngOnDestroy(): void {\n }\n\n onEdit() {\n this.entityCrudComponent().triggerEntityUpdate(this.entity());\n }\n\n onDelete() {\n this.entityCrudComponent().triggerEntityDelete(this.entity());\n }\n\n onClose() {\n this.entityCrudComponent().closePreview();\n }\n}\n","import { ChangeDetectorRef, Component, computed, inject, input, OnDestroy, OnInit, signal } from '@angular/core';\nimport { AbstractControl, UntypedFormGroup } from '@angular/forms';\nimport { setServerErrorsAsFormErrors } from '@smallpearl/ngx-helper/forms';\nimport { Subscription } from 'rxjs';\nimport { tap } from 'rxjs/operators';\nimport { getEntityCrudConfig } from './default-config';\nimport { SPMatEntityCrudCreateEditBridge } from './mat-entity-crud-types';\n\n/**\n * This is a convenience base class that clients can derive from to implement\n * their CRUD form component. Particularly this class registers the change\n * detection hook which will be called when the user attempts to close the\n * form's parent container pane via the Close button on the top right.\n *\n * This button behaves like a Cancel button in a desktop app and therefore if\n * the user has entered any data in the form's controls, (determined by\n * checking form.touched), then a 'Lose Changes' prompt is displayed allowing\n * the user to cancel the closure.\n *\n * The @Component is fake just to keep the VSCode angular linter quiet.\n *\n * To use this class:-\n *\n * 1. Declare a FormGroup<> type as\n *\n * ```\n * type MyForm = FormGroup<{\n * name: FormControl<string>;\n * type: FormControl<string>;\n * notes: FormControl<string>;\n * }>;\n * ```\n *\n * 2. Derive your form's component class from this and implement the\n * createForm() method returing the FormGroup<> instance that matches\n * the FormGroup concrete type above.\n *\n * ```\n * class MyFormComponent extends SPMatEntityCrudFormBase<MyForm, MyEntity> {\n * constructor() {\n * super()\n * }\n *\n * createForm() {\n * return new FormGroup([...])\n * }\n * }\n * ```\n *\n * 3. If you form's value requires manipulation before being sent to the\n * server, override getFormValue() method and do it there before returning\n * the modified values.\n *\n * 4. Wire up the form in the template as:\n *\n * ```\n * <form [formGroup]='form'.. (ngSubmit)=\"onSubmit()\">\n * <button type=\"submit\">Submit</button>\n * </form>\n * ```\n */\n@Component({\n selector: '_#_sp-mat-entity-crud-form-base_#_', template: ``,\n standalone: false\n})\nexport abstract class SPMatEntityCrudFormBase<\n TFormGroup extends AbstractControl,\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> implements OnInit, OnDestroy\n{\n _form = signal<TFormGroup|undefined>(undefined);\n entity = input.required<TEntity>();\n bridge = input.required<SPMatEntityCrudCreateEditBridge>();\n params = input<any>();\n sub$ = new Subscription();\n form = computed(() => this._form());\n\n crudConfig = getEntityCrudConfig();\n\n cdr = inject(ChangeDetectorRef);\n\n canCancelEdit = () => {\n return this._canCancelEdit();\n };\n\n _canCancelEdit() {\n const form = this._form();\n if (form && form.touched) {\n return window.confirm(this.crudConfig.i18n.loseChangesPrompt);\n }\n return true;\n }\n\n ngOnInit() {\n this._form.set(this.createForm(this.entity()));\n this.bridge()?.registerCanCancelEditCallback(this.canCancelEdit);\n }\n\n ngOnDestroy() {\n this.sub$.unsubscribe();\n }\n\n // get form(): TFormGroup|undefined {\n // return this._form();\n // }\n\n // set form(f: TFormGroup) {\n // this._form.set(f);\n // }\n\n /**\n * Create the TFormGroup FormGroup class that will be used for the reactive\n * form.\n * @param entity\n */\n abstract createForm(entity: TEntity | undefined): TFormGroup;\n\n /**\n * Override to customize the id key name if it's not 'id'\n * @returns The name of the unique identifier key that will be used to\n * extract the entity's id for UPDATE operation.\n */\n getIdKey() {\n return 'id';\n }\n\n /**\n * Return the form's value to be sent to server as Create/Update CRUD\n * operation data.\n * @returns\n */\n getFormValue() {\n const form = this.form()\n return form ? form.value : undefined;\n }\n\n onSubmit() {\n const value = this.getFormValue();\n const obs = !this.entity()\n ? this.bridge()?.create(value)\n : this.bridge()?.update((this.entity() as any)[this.getIdKey()], value);\n this.sub$.add(\n obs\n ?.pipe(\n setServerErrorsAsFormErrors(this._form as unknown as UntypedFormGroup, this.cdr),\n tap((res) => {\n if (res) {\n // this.bridge()?.close();\n }\n })\n )\n .subscribe()\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2","i3","tap"],"mappings":"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"}
1
+ {"version":3,"file":"smallpearl-ngx-helper-mat-entity-crud.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/mat-entity-crud-types.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/providers.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/default-config.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/form-view-host.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/preview-host.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/mat-entity-crud.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/preview-pane.component.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/src/mat-entity-crud-form-base.ts","../../../../projects/smallpearl/ngx-helper/mat-entity-crud/smallpearl-ngx-helper-mat-entity-crud.ts"],"sourcesContent":["import { HttpContextToken } from \"@angular/common/http\";\nimport { SPContextMenuItem } from \"@smallpearl/ngx-helper/mat-context-menu\";\nimport { Observable } from \"rxjs\";\n\n/**\n * Prototype of the function to parse the CRUD action response.\n */\nexport type SPMatEntityCrudResponseParser = (\n entityName: string,\n idKey: string,\n method: 'create' | 'retrieve' | 'update' | 'delete',\n resp: any\n) => any|undefined;\n\n\n/**\n * Global config for SPMatEntityList component.\n */\nexport interface SPMatEntityCrudConfig {\n i18n: {\n newItemLabel: (itemLabel: string) => string;\n editItemLabel: (itemLabel: string) => string;\n edit: string;\n delete: string;\n deleteItemHeader: (itemLabel: string) => string;\n deleteItemMessage: (itemLabel: string) => string;\n itemDeletedNotification: (itemLabel: string) => string;\n createdItemNotification: (itemLabel: string) => string;\n updatedItemNotification: (itemLabel: string) => string;\n loseChangesPrompt: string;\n }\n defaultItemActions?: SPContextMenuItem[];\n listPaneWrapperClass?: string;\n previewPaneWrapperClass?: string;\n previewPaneContentClass?: string;\n /**\n * Global crud response parser.\n */\n crudOpResponseParser?: SPMatEntityCrudResponseParser;\n}\n\n/**\n * This is the interface through which the client provided CRUD form component\n * interacts with the 'host' SPMatEntityCrudComponent. When the form wants to\n * submit an entity to the server (for create or update), it should call the\n * one of the create or update methods. The interface also other methods for\n * the form component to interact with SPMatEntityCrudComponent such as\n * refresh its entities list, close the form pane, etc.\n *\n * The interface name has a 'Bridge' as the interface acts as a bridge between\n * the client provided form handler component and the host\n * SPMatEntityCrudComponent.\n */\nexport interface SPMatEntityCrudCreateEditBridge {\n /**\n * Close the edit/update form pane. This WON'T call the 'cancelEditCallback'\n * even if one is registered.\n */\n close: (cancel: boolean) => void;\n /**\n * Client form view can register a callback that will be invoked by the\n * framework when user cancels the create/edit operation by clicking on the\n * close button on the top right.\n * @param callback\n * @returns None\n */\n registerCanCancelEditCallback: (callback: () => boolean) => void;\n // Parameters of type any are entity values are typically the output of\n // form.value and therefore their types would not necessarily match TEntity.\n // id can be typed as TEntity[Idkey], but TSC doesn't allow that yet.\n /**\n * Create a new instance of TEntity, by sending a POST request to remote.\n * @param entityValue This is the typically the output of Reactive form's\n * form.value. Since this value's shape may be different from TEntity and is\n * known only to client form, we use 'any'.\n * @returns None\n * @inner Implementation will show a busy wheel centered on the form\n * view while the async function to update the object remains active.\n */\n create: (entityValue: any) => Observable<any>;\n /**\n * Update the entity with id `id` with new values in entityValue.\n * @param id TEntity id\n * @param entityValue Entity values to be updated.\n * @returns None\n * @inner Implementation will show a busy wheel centered on the form\n * view while the async function to update the object remains active.\n */\n update: (id: any, entityValue: any) => Observable<any>;\n}\n\n/**\n * Prototype of the function that will be used instead of HttpClient for\n * CRUD operations.\n * @param op - the CRUD operation being requested\n * @param entityValue - The entity or entity value upon which the operation\n * is being requested. for 'create' & 'update' this will be the value\n * of the reactive form. This is typically form.value or the 2nd arg to create\n * & update methods of SPMatEntityCrudCreateEditBridge.\n */\nexport type CRUD_OP_FN<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> = (\n op: 'get' | 'create' | 'update' | 'delete',\n id: TEntity[IdKey] | undefined, // valid only for 'get', 'update' & 'delete'\n entityValue: any, // valid only for 'create' & 'update'\n entityCrudComponent: any,\n) => Observable<TEntity | null>;\n\n\nexport type ALLOW_ITEM_ACTION_FN<TEntity> = (entity: TEntity, action: string) => boolean;\n\n/**\n * This interface is used to define sub types for the \"New {{item}}\" button on\n * top of the CRUD UI. An array of these is provided as the value to the\n * component property 'newItemSubTypes'.\n */\nexport interface NewItemSubType {\n /**\n * A role string that will be passed as argument to the (action) event\n * handler. This string allows the event handler to distinguish the selected\n * sub-type.\n *\n * The special keyword '_new_' can be used to activate the\n * `createEditTemplate` template if one is provided. In this case the params\n * element value (see below) can be used in the template to distinguish\n * between different menu items.\n */\n role: string;\n /**\n * Label displayed in the menu representing this role.\n */\n label: string;\n /**\n * Arbitrary value that will be passed to the 'createEditTemplate' in the\n * $implicit template context as 'params'. You can access this in the\n * template like below (see `data.params`):-\n ```\n <ng-template #createEdit let-data>\n <app-create-edit-entity-demo\n [bridge]=\"data.bridge\"\n [entity]=\"data.entity\"\n [params]=\"data.params\"\n ></app-create-edit-entity-demo>\n </ng-template>\n ```\n\n If params is an object and it includes the key 'title', its value will be\n used as the title for the edit form.\n */\n params?: any;\n}\n\nexport type CrudOp = 'create'|'retrieve'|'update'|'delete'|undefined;\n\nexport interface SPMatEntityCrudHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n op: CrudOp;\n}\n\nexport const SP_MAT_ENTITY_CRUD_HTTP_CONTEXT =\n new HttpContextToken<SPMatEntityCrudHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n op: undefined,\n }));\n","import { InjectionToken } from '@angular/core';\nimport { SPMatEntityCrudConfig } from './mat-entity-crud-types';\n\nexport const SP_MAT_ENTITY_CRUD_CONFIG = new InjectionToken<SPMatEntityCrudConfig>('SPMatEntityCrudConfig');\n","import { inject } from \"@angular/core\";\nimport { SPMatEntityCrudConfig } from \"./mat-entity-crud-types\";\nimport { SP_MAT_ENTITY_CRUD_CONFIG } from \"./providers\";\n\nfunction defaultCrudResponseParser(\n entityName: string,\n idKey: string,\n method: 'create' | 'retrieve' | 'update' | 'delete',\n resp: any\n) {\n // If the response is an object with a property '<idKey>', return it as\n // TEntity.\n if (resp.hasOwnProperty(idKey)) {\n return resp;\n }\n // If the response has an object indexed at '<entityName>' and it has\n // the property '<idKey>', return it as TEntity.\n if (resp.hasOwnProperty(entityName)) {\n const obj = resp[entityName];\n if (obj.hasOwnProperty(idKey)) {\n return obj;\n }\n }\n // Return undefined, indicating that we could't parse the response.\n return undefined;\n}\n\nexport const DefaultSPMatEntityCrudConfig: SPMatEntityCrudConfig = {\n i18n: {\n newItemLabel: (itemLabel: string) => `New ${itemLabel}`,\n editItemLabel: (itemLabel: string) => `Edit ${itemLabel}`,\n edit: 'Edit',\n delete: 'Delete',\n deleteItemHeader: (itemLabel: string) => `Confirm Delete ${itemLabel}`,\n deleteItemMessage: (itemLabel: string) => `Are you sure you want to delete this ${itemLabel}`,\n itemDeletedNotification: (itemLabel: string) => `${itemLabel} deleted`,\n createdItemNotification: (itemLabel: string) => `${itemLabel} created.`,\n updatedItemNotification: (itemLabel: string) => `${ itemLabel } saved.`,\n loseChangesPrompt: 'OK to lose changes?'\n },\n crudOpResponseParser: defaultCrudResponseParser\n};\n\n/**\n * To be called from an object constructor as it internally calls Angular's\n * inject() API.\n * @param userConfig\n * @returns\n */\nexport function getEntityCrudConfig(): SPMatEntityCrudConfig {\n const userCrudConfig = inject(SP_MAT_ENTITY_CRUD_CONFIG, {\n optional: true,\n });\n return {\n ...DefaultSPMatEntityCrudConfig,\n ...(userCrudConfig ?? {}),\n };\n}\n","import { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n EmbeddedViewRef,\n input,\n OnDestroy,\n OnInit,\n signal,\n TemplateRef,\n viewChild,\n ViewContainerRef\n} from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { SPMatHostBusyWheelDirective } from '@smallpearl/ngx-helper/mat-busy-wheel';\nimport { Subscription, tap } from 'rxjs';\nimport { getEntityCrudConfig } from './default-config';\nimport { SPMatEntityCrudComponentBase } from './mat-entity-crud-internal-types';\nimport { SPMatEntityCrudConfig, SPMatEntityCrudCreateEditBridge } from './mat-entity-crud-types';\n\n@Component({\n imports: [CommonModule, MatButtonModule, MatIconModule, SPMatHostBusyWheelDirective],\n selector: 'sp-create-edit-entity-host',\n template: `\n <div spHostBusyWheel=\"formBusyWheel\">\n <div class=\"create-edit-topbar\">\n <div class=\"title\">\n {{ title() }}\n </div>\n <div class=\"spacer\"></div>\n <div class=\"close\">\n <button mat-icon-button (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n <ng-container #clientFormContainer></ng-container>\n </div>\n `,\n styles: `\n .create-edit-topbar {\n display: flex;\n flex-direction: row;\n align-items: center;\n min-height: 48px;\n }\n .create-edit-topbar .title {\n font-size: 1.5em;\n font-weight: 500;\n }\n .create-edit-topbar .spacer {\n flex-grow: 1;\n }\n .create-edit-topbar .close {\n\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class FormViewHostComponent<TEntity> implements SPMatEntityCrudCreateEditBridge, OnInit, OnDestroy\n{\n entityCrudComponentBase = input.required<SPMatEntityCrudComponentBase<TEntity>>();\n clientViewTemplate = input<TemplateRef<any> | null>(null);\n itemLabel = input.required<string>();\n itemLabelPlural = input.required<string>();\n\n entity = signal<TEntity|undefined>(undefined);\n title = signal<string>('');\n params = signal<any>(undefined);\n clientFormView!: EmbeddedViewRef<any> | null;\n vc = viewChild('clientFormContainer', { read: ViewContainerRef });\n config!: SPMatEntityCrudConfig;\n sub$ = new Subscription();\n\n constructor() {\n this.config = getEntityCrudConfig();\n }\n\n ngOnInit() {}\n\n ngOnDestroy(): void {\n this.sub$.unsubscribe();\n }\n\n show(entity: TEntity|undefined, params?: any) {\n this.entity.set(entity);\n if (params && params?.title) {\n this.title.set(params.title);\n } else {\n this.title.set(entity ? this.config.i18n.editItemLabel(this.itemLabel()) : this.config.i18n.newItemLabel(this.itemLabel()));\n }\n this.params.set(params);\n this.createClientView();\n }\n\n close(cancel: boolean) {\n this.entityCrudComponentBase().closeCreateEdit(cancel);\n // destroy the client's form component\n this.destroyClientView();\n }\n\n registerCanCancelEditCallback(callback: () => boolean) {\n this.entityCrudComponentBase().registerCanCancelEditCallback(callback);\n }\n\n create(entityValue: any) {\n // console.log(\n // `SPCreateEditEntityHostComponent.create - entity: ${JSON.stringify(\n // entityValue\n // )}`\n // );\n const crudComponent = this.entityCrudComponentBase();\n return crudComponent?.create(entityValue).pipe(\n tap(() => this.close(false)),\n );\n }\n\n update(id: any, entityValue: any) {\n // console.log(\n // `SPCreateEditEntityHostComponent.update - id: ${String(\n // id\n // )}, entity: ${entityValue}`\n // );\n const crudComponent = this.entityCrudComponentBase();\n return crudComponent?.update(id, entityValue).pipe(\n tap(() => this.close(false)),\n );\n }\n\n /**\n * Creates the client view provided via template\n */\n createClientView() {\n /** Render preview component if one was provided */\n const ft = this.clientViewTemplate();\n const vc = this.vc();\n if (ft && vc) {\n this.clientFormView = vc.createEmbeddedView(ft, {\n $implicit: {\n bridge: this,\n entity: this.entity(),\n params: this.params()\n },\n });\n this.clientFormView.detectChanges();\n }\n }\n\n destroyClientView() {\n if (this.clientFormView) {\n this.clientFormView.destroy();\n this.clientFormView = null;\n }\n }\n\n onClose() {\n // Can we give the client form component a chance to intercept this\n // and cancel the closure?\n if (this.entityCrudComponentBase().canCancelEdit()) {\n this.entityCrudComponentBase().closeCreateEdit(true);\n this.destroyClientView();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n EmbeddedViewRef,\n input,\n OnDestroy,\n OnInit,\n signal,\n TemplateRef,\n viewChild,\n ViewContainerRef\n} from '@angular/core';\nimport { SPMatEntityCrudComponentBase } from './mat-entity-crud-internal-types';\n\n@Component({\n imports: [],\n selector: 'sp-entity-crud-preview-host',\n template: ` <ng-container #previewComponent></ng-container> `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class PreviewHostComponent<TEntity> implements OnInit, OnDestroy {\n vc = viewChild('previewComponent', { read: ViewContainerRef });\n\n entityCrudComponentBase = input.required<SPMatEntityCrudComponentBase<TEntity>>();\n clientViewTemplate = input<TemplateRef<any> | null>(null);\n entity = signal<TEntity|undefined>(undefined);\n clientView!: EmbeddedViewRef<any> | null;\n\n constructor() {\n // effect(() => {\n // const tmpl = this.clientViewTemplate();\n // this.createClientView(tmpl);\n // });\n }\n\n ngOnInit(): void {}\n\n ngOnDestroy(): void {}\n\n show(entity: TEntity|undefined, params?: any) {\n this.entity.set(entity);\n // if (params && params?.title) {\n // this.title.set(params.title);\n // } else {\n // this.title.set(entity ? this.config.i18n.editItemLabel(this.itemLabel()) : this.config.i18n.newItemLabel(this.itemLabel()));\n // }\n // this.params.set(params);\n this.createClientView();\n }\n\n close() {\n // this.entityCrudComponentBase().closeCreateEdit(cancel);\n // destroy the client's form component\n this.destroyClientView();\n }\n\n private createClientView() {\n if (this.clientView) {\n // We have only one view in the ng-container. So we might as well\n // call clear() to remove all views contained in it.\n this.vc()!.clear();\n this.clientView.destroy();\n }\n /** Render preview component if one was provided */\n const ft = this.clientViewTemplate();\n const vc = this.vc();\n if (ft && vc) {\n this.clientView = this.vc()!.createEmbeddedView(\n ft,\n {\n $implicit: {\n entity: this.entity(),\n entityCrudComponent: this.entityCrudComponentBase(),\n },\n }\n );\n this.clientView.detectChanges();\n }\n }\n\n\n destroyClientView() {\n if (this.clientView) {\n this.clientView.destroy();\n this.clientView = null;\n }\n }\n\n // close() {\n // this.closePreview.emit();\n // }\n}\n","import { CommonModule } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ContentChildren,\n EventEmitter,\n Injector,\n input,\n Output,\n QueryList,\n signal,\n TemplateRef,\n viewChild,\n viewChildren\n} from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';\nimport { MatSortModule } from '@angular/material/sort';\nimport { MatColumnDef, MatTableModule } from '@angular/material/table';\nimport { RouterModule } from '@angular/router';\nimport {\n showBusyWheelUntilComplete,\n SPMatHostBusyWheelDirective\n} from '@smallpearl/ngx-helper/mat-busy-wheel';\nimport {\n SPContextMenuItem,\n SPMatContextMenuComponent,\n} from '@smallpearl/ngx-helper/mat-context-menu';\nimport { SPMatEntityListComponent } from '@smallpearl/ngx-helper/mat-entity-list';\n\nimport { MatMenuModule } from '@angular/material/menu';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { SPEntityFieldSpec } from '@smallpearl/ngx-helper/entity-field';\nimport { AngularSplitModule } from 'angular-split';\nimport { startCase } from 'lodash';\nimport { plural } from 'pluralize';\nimport { map, Observable, of, Subscription, switchMap, tap } from 'rxjs';\nimport { getEntityCrudConfig } from './default-config';\nimport { FormViewHostComponent } from './form-view-host.component';\nimport { SPMatEntityCrudComponentBase } from './mat-entity-crud-internal-types';\nimport {\n ALLOW_ITEM_ACTION_FN,\n CRUD_OP_FN,\n CrudOp,\n NewItemSubType,\n SP_MAT_ENTITY_CRUD_HTTP_CONTEXT,\n SPMatEntityCrudConfig,\n SPMatEntityCrudResponseParser,\n} from './mat-entity-crud-types';\nimport { PreviewHostComponent } from './preview-host.component';\n\n@Component({\n imports: [\n CommonModule,\n RouterModule,\n MatButtonModule,\n MatTableModule,\n MatSortModule,\n MatMenuModule,\n MatSnackBarModule,\n AngularSplitModule,\n SPMatEntityListComponent,\n SPMatContextMenuComponent,\n FormViewHostComponent,\n SPMatHostBusyWheelDirective,\n PreviewHostComponent,\n ],\n selector: 'sp-mat-entity-crud',\n template: `\n <as-split direction=\"horizontal\" [gutterSize]=\"6\">\n <as-split-area [size]=\"entitiesPaneWidth()\" [visible]=\"!entitiesPaneHidden()\">\n <div\n [class]=\"crudConfig.listPaneWrapperClass\"\n >\n <ng-content select=\"[breadCrumbs]\"></ng-content>\n\n <ng-template #defaultActionButtons>\n <div class=\"action-bar-actions\">\n @if (!disableCreate()) { @if (newItemSubTypes()) {\n <!-- New {{item}} displays a dropdown menu from which the subtype can be selected -->\n <button\n type=\"button\"\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"newSubTypesMenu\"\n >\n {{\n newItemLabel() ??\n crudConfig.i18n.newItemLabel(this._itemLabel())\n }}&nbsp;&#9660;\n <!-- down arrow-head -->\n </button>\n <mat-menu #newSubTypesMenu=\"matMenu\">\n @for (subtype of newItemSubTypes(); track $index) { @if\n (subtype.role) {\n <button mat-menu-item (click)=\"handleNewItemSubType(subtype)\">\n {{ subtype.label }}\n </button>\n } @else {\n <div style=\"padding: .2em 0.5em;\">\n <strong>{{ subtype.label }}</strong>\n </div>\n } }\n </mat-menu>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n (click)=\"onCreate($event)\"\n [routerLink]=\"newItemLink()\"\n >\n {{\n newItemLabel() ??\n crudConfig.i18n.newItemLabel(this._itemLabel())\n }}\n </button>\n } }\n </div>\n </ng-template>\n\n <ng-template #defaultHeaderTemplate>\n <div class=\"action-bar\">\n <div class=\"action-bar-title\">\n {{ _title() }}\n </div>\n <span class=\"spacer\"></span>\n <!-- Hide the action buttons when Preview/Edit pane is active -->\n @if (!entityPaneActive()) {\n <ng-container\n [ngTemplateOutlet]=\"actionsTemplate() || defaultActionButtons\"\n ></ng-container>\n }\n </div>\n </ng-template>\n <ng-container\n [ngTemplateOutlet]=\"headerTemplate() || defaultHeaderTemplate\"\n ></ng-container>\n <sp-mat-entity-list\n [entityName]=\"entityName()\"\n [entityNamePlural]=\"entityNamePlural()\"\n [_deferViewInit]=\"true\"\n [endpoint]=\"endpoint()\"\n [entityLoaderFn]=\"entityLoaderFn()\"\n [columns]=\"columnsWithAction()\"\n [displayedColumns]=\"visibleColumns()\"\n [idKey]=\"idKey()\"\n [pagination]=\"pagination()\"\n [paginator]=\"paginator()\"\n [pageSize]=\"pageSize()\"\n [sorter]=\"sorter()\"\n [disableSort]=\"disableSort()\"\n (selectEntity)=\"handleSelectEntity($event)\"\n [httpReqContext]=\"httpReqContext()\"\n >\n </sp-mat-entity-list>\n </div>\n\n <!--\n We'll be initializing the contentColumnDefs separately and not\n relying on <sp-mat-entity-list>'s internal @ContentChildre() querylist\n for building this. So we define this independenly and not as\n <sp-mat-entity-list> content.\n -->\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td\n mat-cell\n *matCellDef=\"let element\"\n (click)=\"$event.stopImmediatePropagation()\"\n >\n @if (_itemActions().length) {\n <sp-mat-context-menu\n [menuItems]=\"_itemActions()\"\n (selected)=\"onItemAction($event, element)\"\n [contextData]=\"element\"\n [hasBackdrop]=\"true\"\n ></sp-mat-context-menu>\n }\n </td>\n </ng-container>\n\n <!--\n <div\n [class]=\"crudConfig.listPaneWrapperClass\"\n [ngStyle]=\"{ display: createEditViewActive() ? 'inherit' : 'none' }\"\n spHostBusyWheel=\"formBusyWheel\"\n >\n <ng-content select=\"[breadCrumbs]\"></ng-content>\n <sp-create-edit-entity-host\n [itemLabel]=\"_itemLabel()\"\n [itemLabelPlural]=\"_itemLabelPlural()\"\n [entityCrudComponentBase]=\"this\"\n [clientViewTemplate]=\"createEditFormTemplate()\"\n ></sp-create-edit-entity-host>\n </div>\n -->\n </as-split-area>\n <as-split-area [size]=\"entityPaneWidth()\" [visible]=\"entityPaneActive()\">\n <div [class]=\"crudConfig.previewPaneWrapperClass\" spHostBusyWheel=\"formBusyWheel\">\n <sp-entity-crud-preview-host\n [ngClass]=\"createEditViewActive() ? 'd-none' : 'd-inherit'\"\n [entityCrudComponentBase]=\"this\"\n [clientViewTemplate]=\"previewTemplate()!\"\n ></sp-entity-crud-preview-host>\n <!-- Create/Edit Entity -->\n <sp-create-edit-entity-host\n [ngClass]=\"createEditViewActive() ? 'd-inherit' : 'd-none'\"\n [itemLabel]=\"_itemLabel()\"\n [itemLabelPlural]=\"_itemLabelPlural()\"\n [entityCrudComponentBase]=\"this\"\n [clientViewTemplate]=\"createEditFormTemplate()\"\n ></sp-create-edit-entity-host>\n </div>\n </as-split-area>\n </as-split>\n `,\n styles: `\n .d-none {\n display: none;\n }\n .d-inherit {\n display: inherit;\n }\n .action-bar {\n display: flex;\n flex-direction: row;\n align-items: center;\n padding-bottom: 0.5em;\n }\n .action-bar-title {\n font-size: 1.5em;\n font-weight: 600;\n }\n .spacer {\n flex-grow: 1;\n }\n .action-bar-actions {\n text-align: end;\n }\n .active-row {\n font-weight: bold;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SPMatEntityCrudComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >\n extends SPMatEntityListComponent<TEntity, IdKey>\n implements SPMatEntityCrudComponentBase<TEntity>, AfterViewInit\n{\n // entityName = input.required<string>();\n // entityNamePlural = input<string>();\n\n itemLabel = input<string>();\n itemLabelPlural = input<string>();\n /**\n * Title string displayed above the component. If not specified, will use\n * itemLabelPlural() as the title.\n */\n title = input<string>();\n /**\n *\n */\n itemActions = input<SPContextMenuItem[]>([]);\n /**\n * Specify the list of router paths that will be set as the value for\n * [routerLink] for the 'New {{ item }}' button. If not specified,\n * if createEditTemplate is specified, it will be shown. If not, `action`\n * out event will be raised with `{ role: '_new_' }`.\n */\n newItemLink = input<string | string[]>();\n /**\n * If not specified, will use label from SPMatEntityCrudConfig.i18n.newItemLabel.\n */\n newItemLabel = input<string | string[]>();\n /**\n * Text for the Edit <item> pane title\n */\n editItemTitle = input<string>();\n /**\n * If you want \"New {{item}}\" button to support multiple entity types,\n * you can set this to `NewItemSubType[]`, where each element stands for for\n * a dropdown menu item. Refer to `NewItemSubType` for details on this\n * interface.\n */\n newItemSubTypes = input<NewItemSubType[]>();\n /**\n * If you want to take control of the network operations for the CRUD\n * operations (GET/CREATE/UPDATE/DELETE), provide a value for this property.\n */\n crudOpFn = input<CRUD_OP_FN<TEntity, IdKey>>();\n /**\n * Item preview template.\n */\n previewTemplate = input<TemplateRef<any>>();\n /**\n * Whether to allow a context menu action or not. Return false to disable\n * the action.\n */\n allowEntityActionFn = input<ALLOW_ITEM_ACTION_FN<TEntity>>();\n /**\n * A template that allows the header to be replaced. Usage:-\n *\n * ```\n * <sp-map-entity-crud\n * [headerTemplate]=\"myCrudViewHeader\"\n * ></sp-map-entity-crud>\n * <ng-template #myCrudViewHeader>...</ng-template>\n * ```\n */\n headerTemplate = input<TemplateRef<any>>();\n /**\n * Set this to the custom template identifier that will replace the\n * \"New {{Item}}\" button portion. This template will expand towards the\n * title which will be placed to its left (right in rtl).\n *\n * ```\n * <sp-map-entity-crud\n * [actionsTemplate]=\"myCrudActions\"\n * ></sp-map-entity-crud>\n * <ng-template #myCrudActions>...</ng-template>\n * ```\n */\n actionsTemplate = input<TemplateRef<any>>();\n\n /**\n * CRUD action response parser. This will be called with the response\n * from CREATE & UPDATE operations to parse the response JSON and return\n * the created/updated TEntity.\n */\n crudResponseParser = input<SPMatEntityCrudResponseParser>();\n /**\n * An ng-template name that contains the component which provides the\n * create/edit CRUD action.\n *\n * ```\n * <ng-template #createEdit let-data>\n * <app-create-edit-entity-demo [bridge]=\"data.bridge\" [entity]=\"data.entity\"></app-create-edit-entity-demo>\n * </ng-template>\n * ```\n * Note how [bridge] & [entity] properties are set deriving them from the\n * implicit template context. [entity] will be undefined for Create\n * opreation and will be the valid entity for an Update.\n * (app-create-edit-entity-demo here is the client code that implements the\n * Create/Edit form)\n */\n createEditFormTemplate = input<TemplateRef<any> | null>(null);\n /**\n * Disables the per item actions column, preventing 'Edit' & 'Delete'\n * (and other user defined) item operations.\n */\n disableItemActions = input<boolean>(false);\n /**\n * Disables the Create function.\n */\n disableCreate = input<boolean>(false);\n /**\n * View refresh policy after a CREATE/UPDATE operation. Values\n * 'none' - Objects are not refreshed after an edit operation. The return\n * value of the edit operation is used as the object to\n * add/update the component's internal store. This is the default.\n * 'object' - Refresh just the object that was returned from the\n * CREATE/UPDATE operation. Use this if the JSON object returned\n * after a successful CREATE/UPDATE op differs from the JSON\n * object returned for the GET request.\n * 'all' - Refresh the entire list after a CREATE/UPDATE operation. This\n * mimics the behaviour of legacy HTML apps with pure server\n * defined UI.\n */\n refreshAfterEdit = input<'none' | 'object' | 'all'>('none');\n /**\n * HttpContext for crud requests - list, create, retrieve, update & delete.\n * The value can be an object where the property names reflect the CRUD\n * methods with each of these keys taking\n * `[[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]` as its\n * value. This object has a special key 'crud', which if given a value for,\n * would be used for all CRUD requests (CREATE|READ|UPDATE|DELETE).\n *\n * Alternatively the property can be set a\n * `[[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]` as its\n * value, in which case the same context would be used for all HTTP requests.\n */\n crudHttpReqContext = input<\n | [[HttpContextToken<any>, any]]\n | [HttpContextToken<any>, any]\n | {\n // list?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any];\n // crud?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]; // common context for all crud operations\n create?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]; // CREATE\n retrieve?:\n | [[HttpContextToken<any>, any]]\n | [HttpContextToken<any>, any]; // RETRIEVE\n update?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]; // UPDATE\n delete?: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]; // DELETE\n }\n >();\n /**\n * Width of the edit pane as a percentange of the overall <as-split> width.\n */\n editPaneWidth = input<number>(100);\n /**\n * Width of the preview pane as a percentange of the overall <as-split> width.\n */\n previewPaneWidth = input<number>(50);\n\n // INTERNAL PROPERTIES //\n // Derive a label from a camelCase source string. If the camelCase string\n // can be translated, it returns the translated string. If not, the function\n // converts the camelCase to 'Title Case' and returns it.\n private getLabel = (source: string) => {\n const label = this.ngxHelperConfig.i18nTranslate(source);\n if (label.localeCompare(source) !== 0) {\n // Successful translation, return it\n return label;\n }\n return startCase(source);\n };\n\n _itemLabel = computed<string>(() =>\n this.itemLabel()\n ? (this.itemLabel() as string)\n : this.getLabel(this.entityName())\n );\n _itemLabelPlural = computed<string>(() =>\n this.itemLabelPlural()\n ? (this.itemLabelPlural() as string)\n : this.getLabel(plural(this.entityName()))\n );\n // Computed title\n _title = computed(() =>\n this.title() ? this.title() : this._itemLabelPlural()\n );\n // endpoint with the QP string removed (if one was provided)\n _endpointSansParams = computed(() => this.endpoint().split('?')[0]);\n _endpointParams = computed(() => {});\n componentColumns = viewChildren(MatColumnDef);\n @ContentChildren(MatColumnDef) _clientColumnDefs!: QueryList<MatColumnDef>;\n\n /**\n * Event raised for user selecting an item action. It's also raised\n * for 'New <Item>' action, if 'newItemLink' property is not set.\n */\n @Output() action = new EventEmitter<{ role: string; entity?: TEntity }>();\n\n /**\n * Event raised when create Create/Edit pane is activated & deactivated.\n * Event contains two flags:-\n * activated - whether the createEdit form view was activated or\n * deactivated.\n * cancelled - whether the form view was cancelled by user. False for this\n * indicates that the form view was closed after a successful\n * edit operation.\n */\n @Output() entityViewPaneActivated = new EventEmitter<{\n activated: boolean;\n cancelled: boolean|undefined;\n mode: 'edit'|'preview';\n }>();\n\n busyWheelId = `entityCrudBusyWheel-${Date.now()}`;\n sub$ = new Subscription();\n spEntitiesList = viewChild(SPMatEntityListComponent<TEntity, IdKey>);\n crudConfig!: SPMatEntityCrudConfig;\n\n // This is the internal component that will host the createEditFormTemplate\n createEditHostComponent = viewChild(FormViewHostComponent);\n // A flag to toggle the viewport's contents between the mat-table\n // and the create/edit form template.\n createEditViewActive = signal<boolean>(false);\n\n // Whether it's okay to cancel the edit\n canCancelEditCallback!: () => boolean;\n\n // Preview host component\n previewHostComponent = viewChild(PreviewHostComponent);\n previewActive = computed(() => this.previewedEntity() !== undefined);\n previewedEntity = signal<TEntity | undefined>(undefined);\n\n // Whether the pane that hosts the preview/edit-entity template is active.\n // We call it entityPane as it's used to either render a selected entity\n // or to edit one.\n entityPaneActive = computed(() => !!this.previewedEntity() || this.createEditViewActive());\n // Effective width of the entity pane.\n entityPaneWidth = computed(() => !!this.previewedEntity() ? this.previewPaneWidth() : this.editPaneWidth());\n\n // Width of the pane showing the list of entities. Calculated as\n entitiesPaneWidth = computed(() => 100 - this.entityPaneWidth());\n entitiesPaneHidden = computed(() => this.entityPaneActive() && this.entityPaneWidth() === 100);\n\n defaultItemCrudActions = signal<SPContextMenuItem[]>([]);\n columnsWithAction = computed(() => {\n const cols: Array<SPEntityFieldSpec<TEntity, IdKey> | string> = JSON.parse(\n JSON.stringify(this.columns())\n );\n // JSON.parse(JSON.strigify()) does not clone function objects. So\n // explicitly copy these over. So this is really a shallow clone as\n // the cloned objects still refers to the function objects in the original\n // object.\n this.columns().forEach((col, index: number, orgColumns) => {\n const orgCol = orgColumns[index];\n if (typeof orgCol !== 'string') {\n const newColumn = cols[index] as SPEntityFieldSpec<TEntity, IdKey>;\n if (orgCol.valueFn) {\n newColumn.valueFn = orgCol.valueFn;\n }\n if (orgCol.valueOptions) {\n newColumn.valueOptions = orgCol.valueOptions;\n }\n }\n });\n const actionDefined =\n cols.find((c) =>\n typeof c === 'string' ? c === 'action' : c.name === 'action'\n ) !== undefined;\n if (!actionDefined && !this.disableItemActions()) {\n cols.push('action');\n }\n return cols;\n });\n // Use a custom computed() signal to derive the action items for each\n // entity so that we can run per item's allow item action function to\n // selectively disable one or more actions based on the item's state.\n _itemActions = computed(() => {\n const actions =\n this.itemActions() && this.itemActions().length\n ? this.itemActions()\n : this.defaultItemCrudActions();\n let actionsCopy: SPContextMenuItem[] = JSON.parse(JSON.stringify(actions));\n actionsCopy.forEach((action, index: number) => {\n const orgDisable = actions[index]?.disable;\n action.disable = (entity: TEntity) => {\n if (orgDisable) {\n return orgDisable(entity);\n }\n const allowItemActionFn = this.allowEntityActionFn();\n if (allowItemActionFn) {\n return !allowItemActionFn(entity, action.role ?? action.label);\n }\n return false;\n };\n });\n return actionsCopy;\n });\n // This uses the previewActive signal to compute the visible columns\n // when preview is activated. For now we just hide the 'action' column when\n // preview is active. We can further customize this logic by allowing the\n // client to specify the columns to display when preview is active thereby\n // reducing column clutter when the table width becomes narrower owing to\n // preview pane taking up screen space.\n visibleColumns = computed(() =>\n this.entityPaneActive()\n ? this.columnsWithAction()\n .map((col) => (typeof col === 'string' ? col : col.name))\n .filter((name) => name !== 'action')\n : []\n );\n\n constructor(\n http: HttpClient,\n private snackBar: MatSnackBar,\n sanitizer: DomSanitizer,\n injector: Injector,\n ) {\n super(http, sanitizer, injector);\n this.crudConfig = getEntityCrudConfig();\n if (this.crudConfig?.defaultItemActions) {\n this.defaultItemCrudActions.set(this.crudConfig?.defaultItemActions);\n } else {\n this.defaultItemCrudActions.set([\n { label: this.crudConfig.i18n.edit, role: '_update_' },\n { label: this.crudConfig.i18n.delete, role: '_delete_' },\n ]);\n }\n }\n\n override ngOnInit() {}\n\n override ngOnDestroy(): void {\n this.sub$.unsubscribe();\n }\n\n override ngAfterViewInit(): void {\n const spEntitiesList = this.spEntitiesList();\n if (spEntitiesList) {\n // Build contentColumnDefs using our component's content. Then add our own\n // 'action' column definition to it. Then set this as the value of\n // child SPMatEntityListComponent.contentColumnDef. This way we force\n // SPMatEntityListComponent to use our component's any project MatColumnDef\n // content in the final mat-table.\n const clientColumnDefs = this.clientColumnDefs;\n if (clientColumnDefs && spEntitiesList) {\n // Note that we process any content projected matColumnDef first and\n // our own internal content later. And when we process our own internal\n // columns (for now only 'action'), it's not added if a column with that\n // name has already been defined via content projection. This allows the\n // clients to override even internal columns with their column defintion.\n let contentColumnDefs = new Array<MatColumnDef>();\n clientColumnDefs.toArray().forEach((c) => contentColumnDefs.push(c));\n this.componentColumns().forEach((ic) => {\n if (!contentColumnDefs.find((c) => c.name === ic.name)) {\n contentColumnDefs.push(ic);\n }\n });\n spEntitiesList.contentColumnDefs = contentColumnDefs;\n }\n // This is a replication of SPMatEntityCrudList.ngAfterViewInit. That\n // code is skipped as we declare set the _deferViewInit=true in\n // sp-mat-entity-list declaration.\n spEntitiesList.buildColumns();\n spEntitiesList.setupSort();\n spEntitiesList.loadMoreEntities();\n }\n }\n\n /**\n * If the create/edit entity form is active, it calls its registered\n * canCancelEdit callback to determine if it's okay to cancel the edit.\n * You can use this method from the host component's router guard to\n * ensure that any changes made to the form are not accidentally lost by\n * navigating away from the CRUD page.\n *\n * If your CRUD page has multiple sp-mat-entity-crud components, you have to\n * implement the logic to call this method on the appropriate component.\n *\n * If the the create/edit form is not active, this method returns true.\n * @returns\n */\n canDeactivate() {\n if (this.createEditViewActive()) {\n return this.canCancelEdit();\n }\n return true;\n }\n\n override refresh(force = false) {\n this.spEntitiesList()?.refresh(force);\n }\n\n closeCreateEdit(cancelled: boolean) {\n this.createEditViewActive.set(false);\n this.entityViewPaneActivated.emit({ activated: false, cancelled: !!cancelled, mode: 'edit' });\n }\n\n canCancelEdit() {\n if (this.canCancelEditCallback) {\n return this.canCancelEditCallback();\n }\n return true;\n }\n\n registerCanCancelEditCallback(callback: () => boolean) {\n this.canCancelEditCallback = callback;\n }\n\n triggerEntityUpdate(entity: TEntity) {\n this.onUpdate(entity);\n }\n\n triggerEntityDelete(entity: TEntity) {\n this.onDelete(entity);\n }\n\n create(entityValue: any) {\n let obs!: Observable<TEntity | null>;\n const crudOpFn = this.crudOpFn();\n if (crudOpFn) {\n obs = crudOpFn('create', undefined, entityValue, this);\n } else {\n obs = this.http.post<TEntity>(this.getUrl(this.endpoint()), entityValue, {\n context: this.getCrudReqHttpContext('create'),\n });\n }\n\n return obs.pipe(\n showBusyWheelUntilComplete('formBusyWheel'),\n switchMap((resp) =>\n resp ? this.doRefreshAfterEdit(resp, 'create') : of(null)\n ),\n tap((entity) => {\n // If pagination is infinite or if the pagination if none or if the\n // count of items in the current page is less than pageSize()\n // wec an safely add the item to the list, which will cause the view\n // render the new item in the mat-table.\n if (entity) {\n this.spEntitiesList()?.addEntity(entity);\n this.snackBar.open(\n this.crudConfig.i18n.createdItemNotification(this._itemLabel())\n );\n }\n })\n );\n }\n\n update(id: TEntity[IdKey], entityValue: any) {\n let obs!: Observable<TEntity | null>;\n const crudOpFn = this.crudOpFn();\n if (crudOpFn) {\n obs = crudOpFn('update', id, entityValue, this);\n } else {\n obs = this.http.patch<TEntity>(this.getEntityUrl(id), entityValue, {\n context: this.getCrudReqHttpContext('update'),\n });\n }\n\n return obs.pipe(\n showBusyWheelUntilComplete('formBusyWheel'),\n switchMap((resp) =>\n resp ? this.doRefreshAfterEdit(resp, 'update') : of(null)\n ),\n tap((entity) => {\n if (entity) {\n this.spEntitiesList()?.updateEntity(id, entity);\n this.snackBar.open(\n this.crudConfig.i18n.updatedItemNotification(this._itemLabel())\n );\n }\n })\n );\n }\n\n /**\n * Refresh the entity list, after a CRUD CREATE or UPDATE operation.\n * @param resp This is the response from the CRUD operation (CREATE/UPDATE).\n * @param method The CRUD operation post which REFRESH is requested.\n * @returns Observable<TEntity|null>\n */\n doRefreshAfterEdit(resp: any, method: 'create' | 'update') {\n const refreshAfterEdit = this.refreshAfterEdit();\n const entity = this.getCrudOpResponseParser()(\n this.entityName(),\n this.idKey(),\n method,\n resp\n );\n if (refreshAfterEdit === 'object') {\n let obs!: Observable<TEntity>;\n const crudOpFn = this.crudOpFn();\n if (crudOpFn) {\n obs = crudOpFn(\n 'get',\n (entity as any)[this.idKey()],\n undefined,\n this\n ) as Observable<TEntity>;\n } else {\n obs = this.http.get<TEntity>(\n this.getEntityUrl((entity as any)[this.idKey()]),\n { context: this.getCrudReqHttpContext('retrieve') }\n );\n }\n return obs.pipe(\n map((entity) => {\n return this.getCrudOpResponseParser()(\n this.entityName(),\n this.idKey(),\n 'retrieve',\n entity\n );\n })\n );\n } else if (refreshAfterEdit === 'all') {\n this.refresh(true);\n return of(null);\n }\n\n return of(entity);\n }\n\n getCrudOpResponseParser(): SPMatEntityCrudResponseParser {\n if (this.crudResponseParser()) {\n // Without the `as SPMatEntityCrudResponseParser`, TSC will complain.\n return this.crudResponseParser() as SPMatEntityCrudResponseParser;\n }\n // crudConfig will have a parser as our default config provides one.\n return this.crudConfig\n .crudOpResponseParser as SPMatEntityCrudResponseParser;\n }\n\n // SPMatEntityCrudComponentBase interface method. Thunk to the implementation\n // method closePreviewImpl().\n closePreview() {\n this.closePreviewImpl(true);\n }\n\n private closePreviewImpl(toggleEntityListActiveEntity: boolean) {\n if (this.previewedEntity()) {\n if (toggleEntityListActiveEntity) {\n this.spEntitiesList()?.toggleActiveEntity(this.previewedEntity());\n }\n this.previewedEntity.set(undefined);\n this.entityViewPaneActivated.emit({ activated: false, cancelled: undefined, mode: 'preview' });\n }\n }\n\n onItemAction(role: string, entity: TEntity) {\n if (role === '_update_') {\n this.onUpdate(entity);\n } else if (role === '_delete_') {\n this.onDelete(entity);\n } else {\n this.action.emit({ role, entity });\n }\n }\n\n onCreate(event: Event) {\n // If newItemLink() has not been provided, check if createEditFormTemplate\n // is specified. If it is, load it and make that cover the entire viewport.\n // If that too is not specified, emit an action event with role='_new_'.\n if (!this.newItemLink() || this.newItemLink()?.length == 0) {\n event.preventDefault();\n event.stopImmediatePropagation();\n const params = {\n title: this.newItemLabel() ?? this.crudConfig.i18n.newItemLabel(this._itemLabel()),\n }\n this.showCreateEditView(undefined, params);\n // const tmpl = this.createEditFormTemplate();\n // if (tmpl) {\n // // If preview is active deactivate it\n // if (this.previewActive()) {\n // this.closePreview();\n // }\n // const createEditHost = this.createEditHostComponent();\n // createEditHost!.show(undefined);\n // this.createEditViewActive.set(true);\n // }\n }\n if (!this.createEditViewActive()) {\n this.action.emit({ role: '_new_' });\n }\n }\n\n onUpdate(entity: TEntity) {\n const params = {\n title: this.editItemTitle() ?? this.crudConfig.i18n.editItemLabel(this._itemLabel()),\n }\n this.showCreateEditView(entity, params);\n\n // const tmpl = this.createEditFormTemplate();\n // if (tmpl) {\n // // If preview is active deactivate it\n // if (this.previewActive()) {\n // this.closePreview();\n // }\n // const createEditHost = this.createEditHostComponent();\n // if (tmpl && createEditHost) {\n // createEditHost.show(entity);\n // this.createEditViewActive.set(true);\n // }\n // }\n if (!this.createEditViewActive()) {\n this.action.emit({ role: '_update_' });\n }\n }\n\n /**\n * Show the create/edit component. This is deliberately made public so as to\n * be callable from the client. This allows the client to dynamically\n * set the form edit template and then show the edit pane by calling this\n * method.\n * @param entity\n * @param params\n */\n showCreateEditView(entity?: TEntity | undefined, params?: any) {\n const tmpl = this.createEditFormTemplate();\n if (!this.createEditViewActive() && !this.previewActive() && tmpl) {\n // If preview is active deactivate it\n if (this.previewActive()) {\n this.closePreviewImpl(true);\n }\n const createEditHost = this.createEditHostComponent();\n createEditHost!.show(entity, params);\n this.createEditViewActive.set(true);\n this.entityViewPaneActivated.emit({ activated: true, cancelled: undefined, mode: 'edit' });\n }\n }\n\n showPreviewView(entity?: TEntity, params?: any) {\n const tmpl = this.previewTemplate();\n if (tmpl) {\n if (!this.createEditViewActive()) {\n const previewHost = this.previewHostComponent();\n this.previewedEntity.set(entity);\n previewHost?.show(entity, params);\n this.entityViewPaneActivated.emit({ activated: true, cancelled: undefined, mode: 'preview' });\n // this.previewActivated.emit({ entity, activated: true });\n }\n }\n }\n\n hidePreviewView() {\n if (this.previewActive()) {\n const previewHost = this.previewHostComponent();\n previewHost?.close();\n this.closePreviewImpl(false);\n }\n }\n\n async onDelete(entity: TEntity) {\n // Do the delete prompt asynchronously so that the context menu is\n // dismissed before the prompt is displayed.\n setTimeout(() => {\n const deletedItemPrompt = this.crudConfig.i18n.deleteItemMessage(\n this._itemLabel()\n );\n const yes = confirm(deletedItemPrompt);\n if (yes) {\n const entityId = (entity as any)[this.idKey()];\n\n // If preview is active deactivate it\n if (this.previewActive()) {\n this.closePreviewImpl(false);\n }\n\n let obs!: Observable<any>;\n const crudOpFn = this.crudOpFn();\n if (crudOpFn) {\n obs = crudOpFn('delete', entityId, undefined, this);\n } else {\n obs = this.http.delete<void>(this.getEntityUrl(entityId), {\n context: this.getCrudReqHttpContext('delete'),\n });\n }\n\n this.sub$.add(\n obs\n .pipe(\n // TODO: how to display a busy wheel?\n // showBusyWheelUntilComplete(this.busyWheelId),\n tap(() => {\n this.spEntitiesList()!.removeEntity(entityId);\n // TODO: customize by providing an interface via SPMatEntityCrudConfig?\n const deletedMessage =\n this.crudConfig.i18n.itemDeletedNotification(\n this._itemLabel()\n );\n this.snackBar.open(deletedMessage);\n })\n )\n .subscribe()\n );\n }\n });\n }\n\n override getUrl(endpoint: string) {\n return this.entityListConfig?.urlResolver\n ? this.entityListConfig?.urlResolver(endpoint)\n : endpoint;\n }\n\n getEntityUrl(entityId: TEntity[IdKey]) {\n const endpoint = this.endpoint();\n const endpointParts = endpoint.split('?');\n const entityEndpoint =\n (endpointParts[0].endsWith('/')\n ? endpointParts[0]\n : endpointParts[0] + '/') + `${String(entityId)}/`;\n if (endpointParts.length > 1) {\n return this.getUrl(entityEndpoint + `?${endpointParts[1]}`);\n }\n return this.getUrl(entityEndpoint);\n }\n\n handleSelectEntity(entity: TEntity|undefined) {\n if (!this.createEditViewActive()) {\n if (this.previewTemplate()) {\n entity ? this.showPreviewView(entity) : this.hidePreviewView();\n // this.previewedEntity.set(entity);\n } else {\n // If 'previewTemplate' is not set, propagate the event to client.\n this.selectEntity.emit(entity);\n }\n }\n }\n\n handleNewItemSubType(subtype: NewItemSubType) {\n // console.log(`handleNewItemSubType: ${subtype}`);\n if (subtype.role === '_new_') {\n this.showCreateEditView(undefined, subtype?.params);\n } else {\n this.action.emit({ role: subtype.role });\n }\n }\n\n private getCrudReqHttpContext(op: CrudOp) {\n const contextParamToHttpContext = (\n context: HttpContext,\n reqContext: [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any]\n ) => {\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\n let context = new HttpContext();\n const crudHttpReqContext = this.crudHttpReqContext();\n if (crudHttpReqContext) {\n if (Array.isArray(crudHttpReqContext)) {\n // Same HttpContext for all crud requests\n contextParamToHttpContext(context, crudHttpReqContext);\n } else if (\n typeof crudHttpReqContext === 'object' &&\n op &&\n crudHttpReqContext[op]\n ) {\n contextParamToHttpContext(context, crudHttpReqContext[op]!);\n // if (crudHttpReqContext[op]) {\n // context = contextParamToHttpContext(crudHttpReqContext[op] as any);\n // } else if (crudHttpReqContext['crud']) {\n // context = contextParamToHttpContext(crudHttpReqContext['crud'] as any);\n // }\n }\n // } else if (this.httpReqContext()) {\n // context = contextParamToHttpContext(this.httpReqContext()!);\n }\n\n context.set(SP_MAT_ENTITY_CRUD_HTTP_CONTEXT, {\n entityName: this.entityName(),\n entityNamePlural: this._entityNamePlural(),\n endpoint: this.endpoint(),\n op,\n });\n return context;\n // const httpReqContext = this.httpReqContext();\n // return httpReqContext\n // ? contextParamToHttpContext(httpReqContext)\n // : undefined;\n }\n}\n","import { ChangeDetectionStrategy, Component, Inject, input, OnDestroy, OnInit, Optional } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatToolbarModule } from '@angular/material/toolbar';\nimport { SPMatEntityCrudComponentBase } from './mat-entity-crud-internal-types';\nimport { SPMatEntityCrudConfig } from './mat-entity-crud-types';\nimport { SP_MAT_ENTITY_CRUD_CONFIG } from './providers';\nimport { getEntityCrudConfig } from './default-config';\n\n/**\n * A preview pane container to provide a consistent UX for all preview panes.\n * It consits of a toolbar on the top and a container div below that takes up\n * the rest of the preview pane area.\n */\n@Component({\n imports: [MatToolbarModule, MatButtonModule, MatIconModule],\n selector: 'sp-mat-entity-crud-preview-pane',\n template: `\n <div class=\"preview-wrapper\">\n <mat-toolbar>\n <mat-toolbar-row>\n @if (title()) {\n <h2>{{ title() }}</h2>&nbsp;\n }\n @if (!hideUpdate()) {\n <button mat-icon-button aria-label=\"Edit\" (click)=\"onEdit()\" [disabled]=\"disableUpdate()\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n @if (!hideDelete()) {\n <button mat-icon-button aria-label=\"Delete\" (click)=\"onDelete()\" [disabled]=\"disableDelete()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n <ng-content select=\"[previewToolbarContent]\"></ng-content>\n <span class=\"spacer\"></span>\n <button mat-icon-button aria-label=\"Close\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-toolbar-row>\n </mat-toolbar>\n <div [class]=\"'preview-content ' + (config.previewPaneContentClass ?? '')\">\n <ng-content select=\"[previewContent]\"></ng-content>\n </div>\n </div>\n `,\n styles: [`\n .preview-wrapper {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n .spacer {\n flex: 1 1 auto;\n }\n .preview-content {\n flex-grow: 1;\n overflow: scroll;\n }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SPMatEntityCrudPreviewPaneComponent<TEntity> implements OnInit, OnDestroy {\n\n entity = input.required<TEntity>();\n entityCrudComponent = input.required<SPMatEntityCrudComponentBase<TEntity>>();\n title = input<string>();\n disableUpdate = input<boolean>(false);\n hideUpdate = input<boolean>(false);\n disableDelete = input<boolean>(false);\n hideDelete = input<boolean>(false);\n config!: SPMatEntityCrudConfig;\n\n constructor() {\n this.config = getEntityCrudConfig();\n }\n\n ngOnInit() {\n }\n\n ngOnDestroy(): void {\n }\n\n onEdit() {\n this.entityCrudComponent().triggerEntityUpdate(this.entity());\n }\n\n onDelete() {\n this.entityCrudComponent().triggerEntityDelete(this.entity());\n }\n\n onClose() {\n this.entityCrudComponent().closePreview();\n }\n}\n","import { ChangeDetectorRef, Component, computed, inject, input, OnDestroy, OnInit, signal } from '@angular/core';\nimport { AbstractControl, UntypedFormGroup } from '@angular/forms';\nimport { setServerErrorsAsFormErrors } from '@smallpearl/ngx-helper/forms';\nimport { Subscription } from 'rxjs';\nimport { tap } from 'rxjs/operators';\nimport { getEntityCrudConfig } from './default-config';\nimport { SPMatEntityCrudCreateEditBridge } from './mat-entity-crud-types';\n\n/**\n * This is a convenience base class that clients can derive from to implement\n * their CRUD form component. Particularly this class registers the change\n * detection hook which will be called when the user attempts to close the\n * form's parent container pane via the Close button on the top right.\n *\n * This button behaves like a Cancel button in a desktop app and therefore if\n * the user has entered any data in the form's controls, (determined by\n * checking form.touched), then a 'Lose Changes' prompt is displayed allowing\n * the user to cancel the closure.\n *\n * The @Component is fake just to keep the VSCode angular linter quiet.\n *\n * To use this class:-\n *\n * 1. Declare a FormGroup<> type as\n *\n * ```\n * type MyForm = FormGroup<{\n * name: FormControl<string>;\n * type: FormControl<string>;\n * notes: FormControl<string>;\n * }>;\n * ```\n *\n * 2. Derive your form's component class from this and implement the\n * createForm() method returing the FormGroup<> instance that matches\n * the FormGroup concrete type above.\n *\n * ```\n * class MyFormComponent extends SPMatEntityCrudFormBase<MyForm, MyEntity> {\n * constructor() {\n * super()\n * }\n *\n * createForm() {\n * return new FormGroup([...])\n * }\n * }\n * ```\n *\n * 3. If you form's value requires manipulation before being sent to the\n * server, override getFormValue() method and do it there before returning\n * the modified values.\n *\n * 4. Wire up the form in the template as:\n *\n * ```\n * <form [formGroup]='form'.. (ngSubmit)=\"onSubmit()\">\n * <button type=\"submit\">Submit</button>\n * </form>\n * ```\n */\n@Component({\n selector: '_#_sp-mat-entity-crud-form-base_#_', template: ``,\n standalone: false\n})\nexport abstract class SPMatEntityCrudFormBase<\n TFormGroup extends AbstractControl,\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> implements OnInit, OnDestroy\n{\n _form = signal<TFormGroup|undefined>(undefined);\n entity = input.required<TEntity>();\n bridge = input.required<SPMatEntityCrudCreateEditBridge>();\n params = input<any>();\n sub$ = new Subscription();\n form = computed(() => this._form());\n\n crudConfig = getEntityCrudConfig();\n\n cdr = inject(ChangeDetectorRef);\n\n canCancelEdit = () => {\n return this._canCancelEdit();\n };\n\n _canCancelEdit() {\n const form = this._form();\n if (form && form.touched) {\n return window.confirm(this.crudConfig.i18n.loseChangesPrompt);\n }\n return true;\n }\n\n ngOnInit() {\n this._form.set(this.createForm(this.entity()));\n this.bridge()?.registerCanCancelEditCallback(this.canCancelEdit);\n }\n\n ngOnDestroy() {\n this.sub$.unsubscribe();\n }\n\n // get form(): TFormGroup|undefined {\n // return this._form();\n // }\n\n // set form(f: TFormGroup) {\n // this._form.set(f);\n // }\n\n /**\n * Create the TFormGroup FormGroup class that will be used for the reactive\n * form.\n * @param entity\n */\n abstract createForm(entity: TEntity | undefined): TFormGroup;\n\n /**\n * Override to customize the id key name if it's not 'id'\n * @returns The name of the unique identifier key that will be used to\n * extract the entity's id for UPDATE operation.\n */\n getIdKey() {\n return 'id';\n }\n\n /**\n * Return the form's value to be sent to server as Create/Update CRUD\n * operation data.\n * @returns\n */\n getFormValue() {\n const form = this.form()\n return form ? form.value : undefined;\n }\n\n onSubmit() {\n const value = this.getFormValue();\n const obs = !this.entity()\n ? this.bridge()?.create(value)\n : this.bridge()?.update((this.entity() as any)[this.getIdKey()], value);\n this.sub$.add(\n obs\n ?.pipe(\n setServerErrorsAsFormErrors(this._form as unknown as UntypedFormGroup, this.cdr),\n tap((res) => {\n if (res) {\n // this.bridge()?.close();\n }\n })\n )\n .subscribe()\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2","i3","tap"],"mappings":"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"}
@@ -23,7 +23,7 @@ import { getNgxHelperConfig } from '@smallpearl/ngx-helper/core';
23
23
  import { SPEntityField, SP_ENTITY_FIELD_CONFIG } from '@smallpearl/ngx-helper/entity-field';
24
24
  import { InfiniteScrollDirective } from 'ngx-infinite-scroll';
25
25
  import { plural } from 'pluralize';
26
- import { Subscription, tap, finalize } from 'rxjs';
26
+ import { Subscription, Subject, takeUntil, tap, filter, distinctUntilChanged, switchMap, finalize } from 'rxjs';
27
27
 
28
28
  const SP_MAT_ENTITY_LIST_HTTP_CONTEXT = new HttpContextToken(() => ({
29
29
  entityName: '',
@@ -80,6 +80,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
80
80
  standalone: true
81
81
  }]
82
82
  }], ctorParameters: () => [{ type: i0.ElementRef }] });
83
+ /**
84
+ * Represents a request to load entities from the remote. This is used to
85
+ * compare two requests to determine if they are equal. This is useful to
86
+ * prevent duplicate requests being sent to the remote.
87
+ */
88
+ class LoadRequest {
89
+ endpoint;
90
+ params;
91
+ force;
92
+ constructor(endpoint, params, force = false) {
93
+ this.endpoint = endpoint;
94
+ this.params = params;
95
+ this.force = force;
96
+ }
97
+ // Returns true if two LoadRequest objects are equal and this object's
98
+ // 'force' is not set to true.
99
+ isEqualToAndNotForced(prev) {
100
+ // console.log(
101
+ // `isEqualToAndNotForced - ${this.endpoint}, ${this.params.toString()} ${
102
+ // this.force
103
+ // }, other: ${prev.endpoint}, ${prev.params.toString()}, ${prev.force}`
104
+ // );
105
+ return this.force
106
+ ? false
107
+ : this.endpoint.localeCompare(prev.endpoint) === 0 &&
108
+ this.params.toString().localeCompare(prev.params.toString()) === 0;
109
+ }
110
+ }
83
111
  /**
84
112
  * A component to display a list of entities loaded from remote.
85
113
  */
@@ -215,6 +243,7 @@ class SPMatEntityListComponent {
215
243
  clientColumnDefs;
216
244
  contentColumnDefs = [];
217
245
  subs$ = new Subscription();
246
+ destroy$ = new Subject();
218
247
  // Pagination state
219
248
  entityCount = signal(0);
220
249
  pageIndex = signal(0);
@@ -299,9 +328,16 @@ class SPMatEntityListComponent {
299
328
  ngxHelperConfig = getNgxHelperConfig();
300
329
  fieldConfig = inject(SP_ENTITY_FIELD_CONFIG, { optional: true });
301
330
  entityListConfig = getEntityListConfig();
331
+ /**
332
+ * A signal that can be used to trigger loading of more entities from the
333
+ * remote. This can be visualized as the event loop of the entity list
334
+ * component.
335
+ */
336
+ loadRequest$ = new Subject();
302
337
  endpointChanged = effect(() => {
303
338
  runInInjectionContext(this.injector, () => {
304
339
  if (this.endpoint()) {
340
+ // console.log(`endpointChanged - ${this.endpoint()}`);
305
341
  setTimeout(() => { this.refresh(); });
306
342
  }
307
343
  });
@@ -323,32 +359,37 @@ class SPMatEntityListComponent {
323
359
  this._paginator = this.paginator()
324
360
  ? this.paginator()
325
361
  : this.entityListConfig?.paginator;
326
- this.subs$.add(this.entities$
327
- .pipe(tap((entities) => {
362
+ this.entities$
363
+ .pipe(takeUntil(this.destroy$), tap((entities) => {
328
364
  // .data is a setter property, which ought to trigger the necessary
329
365
  // signals resulting in mat-table picking up the changes without
330
366
  // requiring us to call cdr.detectChanges() explicitly.
331
367
  this.dataSource().data = entities;
332
368
  }))
333
- .subscribe());
369
+ .subscribe();
370
+ this.loadRequest$
371
+ .pipe(takeUntil(this.destroy$), filter((lr) => lr.endpoint !== '' || lr.force === true), distinctUntilChanged((prev, current) => current.isEqualToAndNotForced(prev)), switchMap((lr) => this.doActualLoad(lr)))
372
+ .subscribe();
334
373
  }
335
374
  ngOnDestroy() {
336
- this.subs$.unsubscribe();
375
+ this.destroy$.next();
376
+ this.destroy$.complete();
337
377
  }
338
378
  ngAfterViewInit() {
339
379
  if (!this._deferViewInit()) {
340
380
  this.buildContentColumnDefs();
341
381
  this.buildColumns();
342
382
  this.setupSort();
383
+ this.loadMoreEntities();
343
384
  }
344
385
  }
345
386
  /**
346
387
  * Clear all entities in store and reload them from endpoint as if
347
388
  * the entities are being loaded for the first time.
348
389
  */
349
- refresh() {
390
+ refresh(force = false) {
350
391
  this.pageIndex.set(0);
351
- this.loadMoreEntities();
392
+ this.loadMoreEntities(force);
352
393
  }
353
394
  addEntity(entity) {
354
395
  const pagination = this.pagination();
@@ -497,29 +538,67 @@ class SPMatEntityListComponent {
497
538
  this.loadMoreEntities();
498
539
  }
499
540
  }
500
- loadMoreEntities() {
541
+ loadMoreEntities(forceRefresh = false) {
542
+ this.loadRequest$.next(this.createNextLoadRequest(forceRefresh));
543
+ }
544
+ /**
545
+ * Creates a LoadRequest object for loading entities using the current state
546
+ * of the component. Therefore, if the request is for next page of entities,
547
+ * the LoadRequest object will have the updated page index. However, if
548
+ * pagination has been reset (refer to refresh()), the LoadRequest object
549
+ * will be for the first page of data. Note that when 'endpoint' value
550
+ * changes, the component's pagination state is reset causing a refresh()
551
+ * to be called, which in turn will create a new LoadRequest object for the
552
+ * first page of data.
553
+ * @returns LoadRequest object for the next load request.
554
+ */
555
+ createNextLoadRequest(forceRefresh) {
501
556
  let pageParams = {};
557
+ const parts = this.endpoint().split('?');
558
+ const endpoint = parts[0];
502
559
  if (this._paginator) {
503
- pageParams = this._paginator.getRequestPageParams(this.endpoint(), this.pageIndex(), this.pageSize());
560
+ pageParams = this._paginator.getRequestPageParams(endpoint, this.pageIndex(), this.pageSize());
504
561
  }
505
- const parts = this.endpoint().split('?');
506
- let params = new HttpParams(parts.length > 1 ? { fromString: parts[1] } : undefined);
562
+ const paramsSet = new Map();
507
563
  for (const key in pageParams) {
508
- params = params.append(key, pageParams[key]);
564
+ paramsSet.set(key, pageParams[key]);
509
565
  }
510
- // Inline check for input signal value before calling its value doesn't
511
- // seem to work as of now. So we assign the value to a const and check
512
- // it for undefined before calling it.
566
+ if (parts.length > 1) {
567
+ const embeddedParams = new HttpParams({ fromString: parts[1] });
568
+ embeddedParams.keys().forEach((key) => {
569
+ paramsSet.set(key, embeddedParams.get(key));
570
+ });
571
+ }
572
+ let params = new HttpParams();
573
+ paramsSet.forEach((value, key) => {
574
+ params = params.set(key, value ? value.toString() : '');
575
+ });
576
+ // let params = new HttpParams(parts.length > 1 ? { fromString: parts[1] } : undefined);
577
+ // for (const key in pageParams) {
578
+ // params = params.append(key, (pageParams as any)[key]);
579
+ // }
580
+ return new LoadRequest(endpoint, params, forceRefresh || !!this.entityLoaderFn());
581
+ }
582
+ /**
583
+ * Does the actual load of entities from the remote or via calling the
584
+ * entityLoaderFn. This method is the workhorse of the entity list
585
+ * 'loader-loop'.
586
+ * @param lr
587
+ * @returns Observable that emits the response from the remote or from
588
+ * entityLoaderFn().
589
+ */
590
+ doActualLoad(lr) {
591
+ // console.log(`doActualLoad - endpoint: ${lr.endpoint}, params: ${lr.params.toString()}`);
513
592
  const loaderFn = this.entityLoaderFn();
593
+ const params = lr.params;
514
594
  const obs = loaderFn !== undefined
515
595
  ? loaderFn({ params })
516
- : this.http.get(this.getUrl(parts[0]), {
596
+ : this.http.get(this.getUrl(lr.endpoint), {
517
597
  context: this._httpReqContext(),
518
598
  params,
519
599
  });
520
600
  this.loading.set(true);
521
- this.subs$.add(obs
522
- .pipe(tap((resp) => {
601
+ return obs.pipe(tap((resp) => {
523
602
  // TODO: defer this to a pagination provider so that we can support
524
603
  // many types of pagination. DRF itself has different schemes. And
525
604
  // express may have yet another pagination protocol.
@@ -527,7 +606,7 @@ class SPMatEntityListComponent {
527
606
  if (this._paginator) {
528
607
  // Convert HttpParams to JS object
529
608
  const paramsObj = {};
530
- params.keys().forEach(key => {
609
+ params.keys().forEach((key) => {
531
610
  paramsObj[key] = params.get(key);
532
611
  });
533
612
  const { entities, total } = this._paginator.parseRequestResponse(this.entityName(), this._entityNamePlural(), this.endpoint(), paramsObj, resp);
@@ -557,10 +636,7 @@ class SPMatEntityListComponent {
557
636
  else {
558
637
  this.store.update(upsertEntities(this.findArrayInResult(resp)));
559
638
  }
560
- }), finalize(() => {
561
- this.loading.set(false);
562
- }))
563
- .subscribe());
639
+ }), finalize(() => this.loading.set(false)));
564
640
  }
565
641
  findArrayInResult(res) {
566
642
  if (Array.isArray(res)) {
@@ -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 * These are global column value functions.\n *\n * If a value function for a column is not explicitly specified, this map is\n * looked up with the column name. If an entry exists in this table, it will\n * be used to render the column's value.\n *\n * This is useful for formatting certain column types which tends to have the\n * same name across the app. For instance columns such as 'amount', 'total'\n * or 'balance'. Or 'date', 'timestamp', etc. The return value from the\n * column value functions are deemed safe and therefore\n */\n // columnValueFns?: Map<string, COLUMN_VALUE_FN>;\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};\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 { getNgxHelperConfig } from '@smallpearl/ngx-helper/core';\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 { finalize, Observable, Subscription, tap } 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 * 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 [class]=\"column.class\" [headerAlignment]=\"column.options.alignment\" mat-header-cell *matHeaderCellDef>\n {{ column.label() }}\n </th>\n } @else {\n <th [class]=\"column.class\" [headerAlignment]=\"column.options.alignment\" mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.label() }}\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 {\n <span [innerHTML]=\"column.value(element)\"></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 .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 =\n input.required<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<[[HttpContextToken<any>, any]]|[HttpContextToken<any>, any]>();\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\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((colDef) => new SPEntityField<TEntity, IdKey>(colDef, this.ngxHelperConfig, this.fieldConfig))\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 ngxHelperConfig = getNgxHelperConfig();\n fieldConfig = inject(SP_ENTITY_FIELD_CONFIG, { optional: true })!;\n entityListConfig = getEntityListConfig();\n\n endpointChanged = effect(() => {\n runInInjectionContext(this.injector, () => {\n if (this.endpoint()) {\n setTimeout(() => { this.refresh(); });\n }\n });\n });\n\n constructor(\n protected http: HttpClient,\n private sanitizer: DomSanitizer,\n private injector: Injector,\n ) {\n // if (!this.config) {\n // this.config = new DefaultSPMatEntityListConfig();\n // }\n // this.fieldConfig = inject(SP_ENTITY_FIELD_CONFIG, { optional: true })!;\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.subs$.add(\n this.entities$\n .pipe(\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 }\n\n ngOnDestroy(): void {\n this.subs$.unsubscribe();\n }\n\n ngAfterViewInit(): void {\n if (!this._deferViewInit()) {\n this.buildContentColumnDefs();\n this.buildColumns();\n this.setupSort();\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() {\n this.pageIndex.set(0);\n this.loadMoreEntities();\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 // getColumnValue(\n // entity: TEntity,\n // column: SPEntityFieldSpec<TEntity>\n // ) {\n // let val = undefined;\n // if (!column.valueFn) {\n // if (\n // this.config?.columnValueFns &&\n // this.config.columnValueFns.has(column.name)\n // ) {\n // val = this.config.columnValueFns.get(column.name)!(entity, column.name);\n // } else {\n // val = (entity as any)[column.name];\n // }\n // } else {\n // val = column.valueFn(entity);\n // }\n // if (val instanceof Date) {\n // return spFormatDate(val);\n // } else if (typeof val === 'boolean') {\n // return val ? '✔' : '✖';\n // }\n // return val;\n // }\n\n // getColumnLabel(column: SPEntityFieldSpec<TEntity>) {\n // return this.config && this.config?.i18nTranslate\n // ? this.config.i18nTranslate(column?.label || column.name)\n // : column?.label || column.name;\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() {\n let pageParams = {};\n if (this._paginator) {\n pageParams = this._paginator.getRequestPageParams(\n this.endpoint(),\n this.pageIndex(),\n this.pageSize()\n );\n }\n const parts = this.endpoint().split('?');\n let params = new HttpParams(parts.length > 1 ? { fromString: parts[1] } : undefined);\n for (const key in pageParams) {\n params = params.append(key, (pageParams as any)[key]);\n }\n\n // Inline check for input signal value before calling its value doesn't\n // seem to work as of now. So we assign the value to a const and check\n // it for undefined before calling it.\n const loaderFn = this.entityLoaderFn();\n const obs =\n loaderFn !== undefined\n ? loaderFn({ params })\n : this.http.get<any>(this.getUrl(parts[0]), {\n context: this._httpReqContext(),\n params,\n });\n\n this.loading.set(true);\n this.subs$.add(\n obs\n .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\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(() => {\n this.loading.set(false);\n })\n )\n .subscribe()\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","/**\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 * These are global column value functions.\n *\n * If a value function for a column is not explicitly specified, this map is\n * looked up with the column name. If an entry exists in this table, it will\n * be used to render the column's value.\n *\n * This is useful for formatting certain column types which tends to have the\n * same name across the app. For instance columns such as 'amount', 'total'\n * or 'balance'. Or 'date', 'timestamp', etc. The return value from the\n * column value functions are deemed safe and therefore\n */\n // columnValueFns?: Map<string, COLUMN_VALUE_FN>;\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};\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 { getNgxHelperConfig } from '@smallpearl/ngx-helper/core';\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 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 [class]=\"column.class\" [headerAlignment]=\"column.options.alignment\" mat-header-cell *matHeaderCellDef>\n {{ column.label() }}\n </th>\n } @else {\n <th [class]=\"column.class\" [headerAlignment]=\"column.options.alignment\" mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.label() }}\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 {\n <span [innerHTML]=\"column.value(element)\"></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 .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 =\n input.required<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<[[HttpContextToken<any>, any]]|[HttpContextToken<any>, any]>();\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((colDef) => new SPEntityField<TEntity, IdKey>(colDef, this.ngxHelperConfig, this.fieldConfig))\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 ngxHelperConfig = getNgxHelperConfig();\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(() => { this.refresh(); });\n }\n });\n });\n\n constructor(\n protected http: HttpClient,\n private sanitizer: DomSanitizer,\n private injector: Injector,\n ) {\n // if (!this.config) {\n // this.config = new DefaultSPMatEntityListConfig();\n // }\n // this.fieldConfig = inject(SP_ENTITY_FIELD_CONFIG, { optional: true })!;\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) => current.isEqualToAndNotForced(prev)),\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 // getColumnValue(\n // entity: TEntity,\n // column: SPEntityFieldSpec<TEntity>\n // ) {\n // let val = undefined;\n // if (!column.valueFn) {\n // if (\n // this.config?.columnValueFns &&\n // this.config.columnValueFns.has(column.name)\n // ) {\n // val = this.config.columnValueFns.get(column.name)!(entity, column.name);\n // } else {\n // val = (entity as any)[column.name];\n // }\n // } else {\n // val = column.valueFn(entity);\n // }\n // if (val instanceof Date) {\n // return spFormatDate(val);\n // } else if (typeof val === 'boolean') {\n // return val ? '✔' : '✖';\n // }\n // return val;\n // }\n\n // getColumnLabel(column: SPEntityFieldSpec<TEntity>) {\n // return this.config && this.config?.i18nTranslate\n // ? this.config.i18nTranslate(column?.label || column.name)\n // : column?.label || column.name;\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 const paramsSet = new Map<string, string|number|boolean|null>();\n for (const key in pageParams) {\n paramsSet.set(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 paramsSet.set(key, embeddedParams.get(key));\n });\n }\n let params = new HttpParams();\n paramsSet.forEach((value, key) => {\n params = params.set(key, value ? value.toString() : '');\n });\n // let params = new HttpParams(parts.length > 1 ? { fromString: parts[1] } : undefined);\n // for (const key in pageParams) {\n // params = params.append(key, (pageParams as any)[key]);\n // }\n return new LoadRequest(endpoint, params, forceRefresh || !!this.entityLoaderFn());\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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -224,7 +224,7 @@ export declare class SPMatEntityCrudComponent<TEntity extends {
224
224
  * @returns
225
225
  */
226
226
  canDeactivate(): boolean;
227
- refresh(): void;
227
+ refresh(force?: boolean): void;
228
228
  closeCreateEdit(cancelled: boolean): void;
229
229
  canCancelEdit(): boolean;
230
230
  registerCanCancelEditCallback(callback: () => boolean): void;
@@ -1,11 +1,11 @@
1
- import { HttpClient, HttpContext, HttpContextToken } from '@angular/common/http';
1
+ import { HttpClient, HttpContext, HttpContextToken, HttpParams } from '@angular/common/http';
2
2
  import { AfterViewInit, ElementRef, EventEmitter, Injector, OnDestroy, OnInit, QueryList } from '@angular/core';
3
3
  import { PageEvent } from '@angular/material/paginator';
4
4
  import { MatSort } from '@angular/material/sort';
5
5
  import { MatColumnDef, MatTable, MatTableDataSource } from '@angular/material/table';
6
6
  import { DomSanitizer } from '@angular/platform-browser';
7
7
  import { SPEntityField, SPEntityFieldSpec } from '@smallpearl/ngx-helper/entity-field';
8
- import { Observable, Subscription } from 'rxjs';
8
+ import { Observable, Subject, Subscription } from 'rxjs';
9
9
  import { SPMatEntityListEntityLoaderFn, SPMatEntityListPaginator } from './mat-entity-list-types';
10
10
  import * as i0 from "@angular/core";
11
11
  export declare class HeaderAlignmentDirective implements AfterViewInit {
@@ -16,6 +16,18 @@ export declare class HeaderAlignmentDirective implements AfterViewInit {
16
16
  static ɵfac: i0.ɵɵFactoryDeclaration<HeaderAlignmentDirective, never>;
17
17
  static ɵdir: i0.ɵɵDirectiveDeclaration<HeaderAlignmentDirective, "[headerAlignment]", never, { "headerAlignment": { "alias": "headerAlignment"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
18
18
  }
19
+ /**
20
+ * Represents a request to load entities from the remote. This is used to
21
+ * compare two requests to determine if they are equal. This is useful to
22
+ * prevent duplicate requests being sent to the remote.
23
+ */
24
+ declare class LoadRequest {
25
+ endpoint: string;
26
+ params: HttpParams;
27
+ force: boolean;
28
+ constructor(endpoint: string, params: HttpParams, force?: boolean);
29
+ isEqualToAndNotForced(prev: LoadRequest): boolean;
30
+ }
19
31
  /**
20
32
  * A component to display a list of entities loaded from remote.
21
33
  */
@@ -122,6 +134,7 @@ export declare class SPMatEntityListComponent<TEntity extends {
122
134
  clientColumnDefs: QueryList<MatColumnDef>;
123
135
  contentColumnDefs: MatColumnDef[];
124
136
  subs$: Subscription;
137
+ destroy$: Subject<void>;
125
138
  entityCount: import("@angular/core").WritableSignal<number>;
126
139
  pageIndex: import("@angular/core").WritableSignal<number>;
127
140
  lastFetchedEntitiesCount: import("@angular/core").WritableSignal<number>;
@@ -153,6 +166,12 @@ export declare class SPMatEntityListComponent<TEntity extends {
153
166
  ngxHelperConfig: import("@smallpearl/ngx-helper/core").SPNgxHelperConfig;
154
167
  fieldConfig: import("@smallpearl/ngx-helper/entity-field").SPEntityFieldConfig;
155
168
  entityListConfig: import("./mat-entity-list-types").SPMatEntityListConfig;
169
+ /**
170
+ * A signal that can be used to trigger loading of more entities from the
171
+ * remote. This can be visualized as the event loop of the entity list
172
+ * component.
173
+ */
174
+ loadRequest$: Subject<LoadRequest>;
156
175
  endpointChanged: import("@angular/core").EffectRef;
157
176
  constructor(http: HttpClient, sanitizer: DomSanitizer, injector: Injector);
158
177
  ngOnInit(): void;
@@ -162,7 +181,7 @@ export declare class SPMatEntityListComponent<TEntity extends {
162
181
  * Clear all entities in store and reload them from endpoint as if
163
182
  * the entities are being loaded for the first time.
164
183
  */
165
- refresh(): void;
184
+ refresh(force?: boolean): void;
166
185
  addEntity(entity: TEntity): void;
167
186
  /**
168
187
  * Update an entity with a modified version. Can be used by CRUD UPDATE
@@ -199,7 +218,28 @@ export declare class SPMatEntityListComponent<TEntity extends {
199
218
  buildColumns(): void;
200
219
  setupSort(): void;
201
220
  infiniteScrollLoadNextPage(ev: any): void;
202
- loadMoreEntities(): void;
221
+ loadMoreEntities(forceRefresh?: boolean): void;
222
+ /**
223
+ * Creates a LoadRequest object for loading entities using the current state
224
+ * of the component. Therefore, if the request is for next page of entities,
225
+ * the LoadRequest object will have the updated page index. However, if
226
+ * pagination has been reset (refer to refresh()), the LoadRequest object
227
+ * will be for the first page of data. Note that when 'endpoint' value
228
+ * changes, the component's pagination state is reset causing a refresh()
229
+ * to be called, which in turn will create a new LoadRequest object for the
230
+ * first page of data.
231
+ * @returns LoadRequest object for the next load request.
232
+ */
233
+ private createNextLoadRequest;
234
+ /**
235
+ * Does the actual load of entities from the remote or via calling the
236
+ * entityLoaderFn. This method is the workhorse of the entity list
237
+ * 'loader-loop'.
238
+ * @param lr
239
+ * @returns Observable that emits the response from the remote or from
240
+ * entityLoaderFn().
241
+ */
242
+ private doActualLoad;
203
243
  private findArrayInResult;
204
244
  handlePageEvent(e: PageEvent): void;
205
245
  getUrl(endpoint: string): string;
@@ -207,3 +247,4 @@ export declare class SPMatEntityListComponent<TEntity extends {
207
247
  static ɵfac: i0.ɵɵFactoryDeclaration<SPMatEntityListComponent<any, any>, never>;
208
248
  static ɵcmp: i0.ɵɵComponentDeclaration<SPMatEntityListComponent<any, any>, "sp-mat-entity-list", never, { "entityName": { "alias": "entityName"; "required": true; "isSignal": true; }; "entityNamePlural": { "alias": "entityNamePlural"; "required": false; "isSignal": true; }; "endpoint": { "alias": "endpoint"; "required": false; "isSignal": true; }; "entityLoaderFn": { "alias": "entityLoaderFn"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "displayedColumns": { "alias": "displayedColumns"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "idKey": { "alias": "idKey"; "required": false; "isSignal": true; }; "pagination": { "alias": "pagination"; "required": false; "isSignal": true; }; "paginator": { "alias": "paginator"; "required": false; "isSignal": true; }; "sorter": { "alias": "sorter"; "required": false; "isSignal": true; }; "disableSort": { "alias": "disableSort"; "required": false; "isSignal": true; }; "infiniteScrollContainer": { "alias": "infiniteScrollContainer"; "required": false; "isSignal": true; }; "infiniteScrollDistance": { "alias": "infiniteScrollDistance"; "required": false; "isSignal": true; }; "infiniteScrollThrottle": { "alias": "infiniteScrollThrottle"; "required": false; "isSignal": true; }; "infiniteScrollWindow": { "alias": "infiniteScrollWindow"; "required": false; "isSignal": true; }; "httpReqContext": { "alias": "httpReqContext"; "required": false; "isSignal": true; }; "_deferViewInit": { "alias": "_deferViewInit"; "required": false; "isSignal": true; }; }, { "selectEntity": "selectEntity"; }, ["clientColumnDefs"], never, true, never>;
209
249
  }
250
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smallpearl/ngx-helper",
3
- "version": "0.29.23",
3
+ "version": "0.29.25",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.1.0",
6
6
  "@angular/core": "^19.1.0",
@@ -54,25 +54,25 @@
54
54
  "types": "./entity-field/index.d.ts",
55
55
  "default": "./fesm2022/smallpearl-ngx-helper-entity-field.mjs"
56
56
  },
57
- "./hover-dropdown": {
58
- "types": "./hover-dropdown/index.d.ts",
59
- "default": "./fesm2022/smallpearl-ngx-helper-hover-dropdown.mjs"
60
- },
61
57
  "./locale": {
62
58
  "types": "./locale/index.d.ts",
63
59
  "default": "./fesm2022/smallpearl-ngx-helper-locale.mjs"
64
60
  },
65
- "./mat-busy-wheel": {
66
- "types": "./mat-busy-wheel/index.d.ts",
67
- "default": "./fesm2022/smallpearl-ngx-helper-mat-busy-wheel.mjs"
61
+ "./hover-dropdown": {
62
+ "types": "./hover-dropdown/index.d.ts",
63
+ "default": "./fesm2022/smallpearl-ngx-helper-hover-dropdown.mjs"
64
+ },
65
+ "./forms": {
66
+ "types": "./forms/index.d.ts",
67
+ "default": "./fesm2022/smallpearl-ngx-helper-forms.mjs"
68
68
  },
69
69
  "./mat-context-menu": {
70
70
  "types": "./mat-context-menu/index.d.ts",
71
71
  "default": "./fesm2022/smallpearl-ngx-helper-mat-context-menu.mjs"
72
72
  },
73
- "./forms": {
74
- "types": "./forms/index.d.ts",
75
- "default": "./fesm2022/smallpearl-ngx-helper-forms.mjs"
73
+ "./mat-busy-wheel": {
74
+ "types": "./mat-busy-wheel/index.d.ts",
75
+ "default": "./fesm2022/smallpearl-ngx-helper-mat-busy-wheel.mjs"
76
76
  },
77
77
  "./mat-entity-crud": {
78
78
  "types": "./mat-entity-crud/index.d.ts",