@smallpearl/ngx-helper 0.33.26 → 0.33.28

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.
@@ -1,5 +1,5 @@
1
1
  import * as i1 from '@angular/common/http';
2
- import { HttpContextToken, HttpParams, HttpContext, HttpClient } from '@angular/common/http';
2
+ import { HttpContextToken, HttpContext, HttpParams, HttpClient } from '@angular/common/http';
3
3
  import * as i0 from '@angular/core';
4
4
  import { InjectionToken, inject, input, computed, signal, viewChild, ViewContainerRef, Component, ChangeDetectionStrategy, viewChildren, EventEmitter, effect, ContentChildren, Output, ChangeDetectorRef } from '@angular/core';
5
5
  import * as i4 from '@angular/common';
@@ -42,6 +42,31 @@ const SP_MAT_ENTITY_CRUD_HTTP_CONTEXT = new HttpContextToken(() => ({
42
42
 
43
43
  const SP_MAT_ENTITY_CRUD_CONFIG = new InjectionToken('SPMatEntityCrudConfig');
44
44
 
45
+ /**
46
+ * Converts array of HttpContextToken key, value pairs to HttpContext
47
+ * object in argument 'context'.
48
+ * @param context HTTP context to which the key, value pairs are added
49
+ * @param reqContext HttpContextToken key, value pairs array
50
+ * @returns HttpContext object, with the key, value pairs added. This is
51
+ * the same object as the 'context' argument.
52
+ */
53
+ function convertHttpContextInputToHttpContext(context, reqContext) {
54
+ if (reqContext instanceof HttpContext) {
55
+ // reqContext is already an HttpContext object.
56
+ for (const k of reqContext.keys()) {
57
+ context.set(k, reqContext.get(k));
58
+ }
59
+ }
60
+ else if (Array.isArray(reqContext) && reqContext.length == 2 && !Array.isArray(reqContext[0])) {
61
+ // one dimensional array of a key, value pair.
62
+ context.set(reqContext[0], reqContext[1]);
63
+ }
64
+ else {
65
+ reqContext.forEach(([k, v]) => context.set(k, v));
66
+ }
67
+ return context;
68
+ }
69
+
45
70
  function defaultCrudResponseParser(entityName, idKey, method, // 'create' | 'retrieve' | 'update' | 'delete',
46
71
  resp) {
47
72
  // If the response is an object with a property '<idKey>', return it as
@@ -1084,30 +1109,6 @@ class SPMatEntityCrudComponent extends SPMatEntityListComponent {
1084
1109
  }
1085
1110
  }
1086
1111
  getCrudReqHttpContext(op) {
1087
- /**
1088
- * Converts array of HttpContextToken key, value pairs to HttpContext
1089
- * object in argument 'context'.
1090
- * @param context HTTP context to which the key, value pairs are added
1091
- * @param reqContext HttpContextToken key, value pairs array
1092
- * @returns HttpContext object, with the key, value pairs added. This is
1093
- * the same object as the 'context' argument.
1094
- */
1095
- const contextParamToHttpContext = (context, reqContext) => {
1096
- if (reqContext instanceof HttpContext) {
1097
- // reqContext is already an HttpContext object.
1098
- for (const k of reqContext.keys()) {
1099
- context.set(k, reqContext.get(k));
1100
- }
1101
- }
1102
- else if (reqContext.length == 2 && !Array.isArray(reqContext[0])) {
1103
- // one dimensional array of a key, value pair.
1104
- context.set(reqContext[0], reqContext[1]);
1105
- }
1106
- else {
1107
- reqContext.forEach(([k, v]) => context.set(k, v));
1108
- }
1109
- return context;
1110
- };
1111
1112
  let context = new HttpContext();
1112
1113
  // HttpContext for crud operations are taken from either the global httpReqContext
1113
1114
  // or from the crudHttpReqContext, with the latter taking precedence.
@@ -1126,13 +1127,13 @@ class SPMatEntityCrudComponent extends SPMatEntityListComponent {
1126
1127
  if (Array.isArray(crudHttpReqContext)) {
1127
1128
  // Same HttpContext for all crud requests. Being an array, it must
1128
1129
  // be an array of HttpContextToken key, value pairs.
1129
- contextParamToHttpContext(context, crudHttpReqContext);
1130
+ convertHttpContextInputToHttpContext(context, crudHttpReqContext);
1130
1131
  }
1131
1132
  else if (typeof crudHttpReqContext === 'object' &&
1132
1133
  op &&
1133
1134
  Object.keys(crudHttpReqContext).find((k) => k === op)) {
1134
1135
  // HttpContext specific to this crud operation, 'create'|'retrieve'|'update'|'delete'
1135
- contextParamToHttpContext(context, crudHttpReqContext[op]);
1136
+ convertHttpContextInputToHttpContext(context, crudHttpReqContext[op]);
1136
1137
  }
1137
1138
  }
1138
1139
  }
@@ -1723,11 +1724,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
1723
1724
  * checking form.touched), then a 'Lose Changes' prompt is displayed allowing
1724
1725
  * the user to cancel the closure.
1725
1726
  *
1726
- * The @Component is fake just to keep the VSCode angular linter quiet.
1727
+ * The `@Component` decorator is fake to keep the VSCode angular linter quiet.
1727
1728
  *
1728
- * To use this class:-
1729
+ * This class can be used in two modes:
1729
1730
  *
1730
- * 1. Declare a FormGroup<> type as
1731
+ * I. SPMatEntityCrudComponent mode
1732
+ * This mode relies on a bridge interface that implements the
1733
+ * SPMatEntityCrudCreateEditBridge interface to perform the entity
1734
+ * load/create/update operations. This is the intended mode when the
1735
+ * component is used as a part of the SPMatEntityCrudComponent to
1736
+ * create/update an entity. This mode requires the following properties
1737
+ * to be set:
1738
+ * - entity: TEntity | TEntity[IdKey] | undefined (for create)
1739
+ * - bridge: SPMatEntityCrudCreateEditBridge
1740
+ *
1741
+ * II. Standalone mode
1742
+ * This mode does not rely on the bridge interface and the component
1743
+ * itself performs the entity load/create/update operations.
1744
+ * This mode requires the following properties to be set:
1745
+ * - entity: TEntity | TEntity[IdKey] | undefined (for create)
1746
+ * - baseUrl: string - Base URL for CRUD operations. This URL does not
1747
+ * include the entity id. The entity id will be appended to this URL
1748
+ * for entity load and update operations. For create operation, this
1749
+ * URL is used as is.
1750
+ * - entityName: string - Name of the entity, used to parse sideloaded
1751
+ * entity responses.
1752
+ * - httpReqContext?: HttpContextInput - Optional HTTP context to be
1753
+ * passed to the HTTP requests. For instance, if your app has a HTTP
1754
+ * interceptor that adds authentication tokens to the requests based
1755
+ * on a HttpContextToken, then you can pass that token here.
1756
+ *
1757
+ * I. SPMatEntityCrudComponent mode:
1758
+ *
1759
+ * 1. Declare a FormGroup<> type as
1731
1760
  *
1732
1761
  * ```
1733
1762
  * type MyForm = FormGroup<{
@@ -1737,64 +1766,101 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
1737
1766
  * }>;
1738
1767
  * ```
1739
1768
  *
1740
- * 2. Derive your form's component class from this and implement the
1769
+ * 2. Derive your form's component class from this and implement the
1741
1770
  * createForm() method returing the FormGroup<> instance that matches
1742
1771
  * the FormGroup concrete type above.
1743
1772
  *
1744
- * ```
1745
- * class MyFormComponent extends SPMatEntityCrudFormBase<MyForm, MyEntity> {
1746
- * constructor() {
1747
- * super()
1748
- * }
1749
- *
1750
- * createForm() {
1751
- * return new FormGroup([...])
1773
+ * ```
1774
+ * class MyFormComponent extends SPMatEntityCrudFormBase<MyForm, MyEntity> {
1775
+ * constructor() {
1776
+ * super()
1777
+ * }
1778
+ * createForm() {
1779
+ * return new FormGroup([...])
1780
+ * }
1752
1781
  * }
1753
- * }
1754
- * ```
1782
+ * ```
1755
1783
  *
1756
- * 3. If you form's value requires manipulation before being sent to the
1784
+ * 3. If your form's value requires manipulation before being sent to the
1757
1785
  * server, override `getFormValue()` method and do it there before returning
1758
1786
  * the modified values.
1759
1787
  *
1760
- * 4. Wire up the form in the template as:
1788
+ * 4. Wire up the form in the template as below
1789
+ *
1790
+ * ```html
1791
+ * @if (loadEntity$ | async) {
1792
+ * <form [formGroup]='form'.. (ngSubmit)="onSubmit()">
1793
+ * <button type="submit">Submit</button>
1794
+ * </form>
1795
+ * } @else {
1796
+ * <div>Loading...</div>
1797
+ * }
1798
+ * ```
1799
+ *
1800
+ * Here `loadEntity$` is an Observable<boolean> that upon emission of `true`
1801
+ * indicates that the entity has been loaded from server (in case of edit)
1802
+ * and the form is ready to be displayed. Note that if the full entity was
1803
+ * passed in the `entity` input property, then no server load is necessary
1804
+ * and the form will be created immediately.
1805
+ *
1806
+ * 5. In the parent component that hosts the SPMatEntityCrudComponent, set
1807
+ * the `entity` and `bridge` input properties of this component to
1808
+ * appropriate values. For instance, if your form component has the
1809
+ * selector `app-my-entity-form`, then the parent component's template
1810
+ * will have:
1811
+ *
1812
+ * ```html
1813
+ * <sp-mat-entity-crud
1814
+ * ...
1815
+ * createEditFormTemplate="entityFormTemplate"
1816
+ * ></sp-mat-entity-crud>
1817
+ * <ng-template #entityFormTemplate let-data="data">
1818
+ * <app-my-entity-form
1819
+ * [entity]="data.entity"
1820
+ * [bridge]="data.bridge"
1821
+ * ></app-my-entity-form>
1822
+ * </ng-template>
1823
+ * ```
1761
1824
  *
1762
- * ```
1763
- * @if (loadEntity$ | async) {
1764
- * <form [formGroup]='form'.. (ngSubmit)="onSubmit()">
1765
- * <button type="submit">Submit</button>
1766
- * </form>
1767
- * } @else {
1768
- * <div>Loading...</div>
1769
- * }
1770
- * ```
1771
- * Here `loadEntity$` is an Observable<boolean> that upon emission of `true`
1772
- * indicates that the entity has been loaded from server (in case of edit)
1773
- * and the form is ready to be displayed. Note that if the full entity was
1774
- * passed in the `entity` input property, then no server load is necessary
1775
- * and the form will be created immediately.
1825
+ * II. Standalone mode
1776
1826
  *
1777
- * 5. If the entity shape required by the form requires additional parameters
1778
- * to be loaded from server, initialize `entity` property with it's id.
1779
- * Then override the `getLoadEntityParams()` method to return the additional
1780
- * load parameters. The parameters returned by this method will be
1781
- * passed to the `loadEntity()` method of the bridge interface.
1827
+ * 1..4. Same as above, except set the required `bridge` input to `undefined`.
1828
+ * 5. Initialize the component's inputs `baseUrl` and `entityName` with the
1829
+ * appropriate values. If you would like to pass additional HTTP context to
1830
+ * the HTTP requests, then set the `httpReqContext` input as well.
1831
+ * If the entity uses an id key other than 'id', then set the `idKey` input
1832
+ * to the appropriate id key name.
1833
+ * 6. If you want to retrieve the created/updated entity after the create/update
1834
+ * operation, override the `onPostCreate()` and/or `onPostUpdate()` methods
1835
+ * respectively.
1782
1836
  */
1783
1837
  class SPMatEntityCrudFormBase {
1784
- _form = signal(undefined);
1785
1838
  entity = input.required();
1786
1839
  bridge = input.required();
1787
1840
  params = input();
1841
+ // --- BEGIN inputs used when `bridge` input is undefined
1842
+ // Entity name, which is used to parse sideloaded entity responses
1843
+ entityName = input();
1844
+ // Base CRUD URL, which is the GET-list-of-entities/POST-to-create
1845
+ // URL. Update URL will be derived from this ias `baseUrl()/${TEntity[IdKey]}`
1846
+ baseUrl = input();
1847
+ // Additional request context to be passed to the request
1848
+ httpReqContext = input();
1849
+ // ID key, defaults to 'id'
1850
+ idKey = input('id');
1851
+ // -- END inputs used when `bridge` input is undefined
1852
+ // IMPLEMENTATION
1788
1853
  loadEntity$;
1789
1854
  _entity = signal(undefined);
1790
1855
  sub$ = new Subscription();
1856
+ // Store for internal form signal. form() is computed from this.
1857
+ _form = signal(undefined);
1791
1858
  // Force typecast to TFormGroup so that we can use it in the template
1792
1859
  // without having to use the non-nullable operator ! with every reference
1793
1860
  // of form(). In any case the form() signal is always set in ngOnInit()
1794
1861
  // method after the form is created. And if form() is not set, then there
1795
1862
  // will be errors while loading the form in the template.
1796
1863
  form = computed(() => this._form());
1797
- // crudConfig = getEntityCrudConfig();
1798
1864
  transloco = inject(TranslocoService);
1799
1865
  cdr = inject(ChangeDetectorRef);
1800
1866
  http = inject(HttpClient);
@@ -1809,16 +1875,24 @@ class SPMatEntityCrudFormBase {
1809
1875
  return true;
1810
1876
  }
1811
1877
  ngOnInit() {
1878
+ // validate inputs. Either bridge or (baseUrl and entityName) must be
1879
+ // defined.
1880
+ if (!this.bridge() && (!this.baseUrl() || !this.entityName())) {
1881
+ throw new Error('SPMatEntityCrudFormBase: baseUrl and entityName inputs must be defined in standalone mode.');
1882
+ }
1812
1883
  this.loadEntity$ = (typeof this.entity() === 'object' || this.entity() === undefined
1813
1884
  ? new Observable((subscriber) => {
1814
1885
  subscriber.next(this.entity());
1815
1886
  subscriber.complete();
1816
1887
  })
1817
- : this.bridge()?.loadEntity(this.entity(), this.getLoadEntityParams())).pipe(map((resp) => {
1888
+ : this.load(this.entity())).pipe(map((resp) => {
1818
1889
  const compositeEntity = this.getEntityFromLoadResponse(resp);
1819
1890
  this._entity.set(compositeEntity);
1820
1891
  this._form.set(this.createForm(compositeEntity));
1821
- this.bridge()?.registerCanCancelEditCallback(this.canCancelEdit);
1892
+ const bridge = this.bridge();
1893
+ if (bridge && bridge.registerCanCancelEditCallback) {
1894
+ bridge.registerCanCancelEditCallback(this.canCancelEdit);
1895
+ }
1822
1896
  return true;
1823
1897
  }));
1824
1898
  }
@@ -1835,23 +1909,32 @@ class SPMatEntityCrudFormBase {
1835
1909
  }
1836
1910
  /**
1837
1911
  * Return the TEntity object from the response returned by the
1838
- * loadEntity() method of the bridge. Typically entity load return the actual
1912
+ * load() method. Typically entity load returns the actual
1839
1913
  * entity object itself. In some cases, where response is sideloaded, the
1840
1914
  * default implementation here uses the `sideloadToComposite()` utility to
1841
1915
  * extract the entity from the response after merging (inplace) the
1842
1916
  * sideloaded data into a composite.
1843
1917
  *
1844
- * If you have a different response shape, override this method to
1845
- * extract the TEntity object from the response.
1918
+ * If you have a different response shape, or if your sideloaded object
1919
+ * response requires custom custom `sideloadDataMap`, override this method
1920
+ * and implement your custom logic to extract the TEntity object from the
1921
+ * response.
1846
1922
  * @param resp
1847
1923
  * @returns
1848
1924
  */
1849
1925
  getEntityFromLoadResponse(resp) {
1850
- if (!resp) {
1926
+ if (!resp || typeof resp !== 'object') {
1851
1927
  return undefined;
1852
1928
  }
1853
- const sideloaded = sideloadToComposite(resp, this.bridge().getEntityName(), this.bridge().getIdKey());
1854
- return sideloaded;
1929
+ const entityName = this.entityName();
1930
+ if (resp.hasOwnProperty(this.getIdKey())) {
1931
+ return resp;
1932
+ }
1933
+ else if (entityName && resp.hasOwnProperty(entityName)) {
1934
+ // const sideloadDataMap = this.sideloadDataMap();
1935
+ return sideloadToComposite(resp, this.entityName(), this.getIdKey());
1936
+ }
1937
+ return undefined;
1855
1938
  }
1856
1939
  /**
1857
1940
  * Override to customize the id key name if it's not 'id'
@@ -1859,7 +1942,11 @@ class SPMatEntityCrudFormBase {
1859
1942
  * extract the entity's id for UPDATE operation.
1860
1943
  */
1861
1944
  getIdKey() {
1862
- return 'id';
1945
+ const bridge = this.bridge();
1946
+ if (bridge) {
1947
+ return bridge.getIdKey();
1948
+ }
1949
+ return this.idKey();
1863
1950
  }
1864
1951
  /**
1865
1952
  * Return the form's value to be sent to server as Create/Update CRUD
@@ -1872,15 +1959,117 @@ class SPMatEntityCrudFormBase {
1872
1959
  }
1873
1960
  onSubmit() {
1874
1961
  const value = this.getFormValue();
1875
- const obs = !this.entity()
1876
- ? this.bridge()?.create(value)
1877
- : this.bridge()?.update(this.entity()[this.getIdKey()], value);
1962
+ const obs = !this._entity()
1963
+ ? this.create(value)
1964
+ : this.update(this._entity()[this.getIdKey()], value);
1878
1965
  this.sub$.add(obs
1879
- ?.pipe(setServerErrorsAsFormErrors(this._form(), this.cdr))
1966
+ ?.pipe(tap(entity => this._entity() ? this.onPostUpdate(entity) : this.onPostCreate(entity)), setServerErrorsAsFormErrors(this._form(), this.cdr))
1880
1967
  .subscribe());
1881
1968
  }
1969
+ onPostCreate(entity) {
1970
+ /* empty */
1971
+ }
1972
+ onPostUpdate(entity) {
1973
+ /* empty */
1974
+ }
1975
+ /**
1976
+ * Loads the entity if `this.entity()` is of type TEntity[IdKey]. If `bridge`
1977
+ * input is defined, then it's `loadEntity()` method is used to load the
1978
+ * entity. Otherwise, then this method attempts to load the entity using
1979
+ * HTTP GET from the URL derived from `baseUrl` input.
1980
+ * @param entityId
1981
+ * @param params
1982
+ * @returns
1983
+ */
1984
+ load(entityId) {
1985
+ const bridge = this.bridge();
1986
+ const params = this.getLoadEntityParams();
1987
+ if (bridge) {
1988
+ return bridge.loadEntity(entityId, params);
1989
+ }
1990
+ // Try to load using baseUrl.
1991
+ if (!this.baseUrl()) {
1992
+ console.warn(`SPMatEntityCrudFormBase.load: No bridge defined, baseUrl input is undefined. Returning undefined.`);
1993
+ return new Observable((subscriber) => {
1994
+ subscriber.next(undefined);
1995
+ subscriber.complete();
1996
+ });
1997
+ }
1998
+ let context = new HttpContext();
1999
+ if (this.httpReqContext()) {
2000
+ context = convertHttpContextInputToHttpContext(context, this.httpReqContext());
2001
+ }
2002
+ const url = this.getEntityUrl(entityId);
2003
+ return this.http
2004
+ .get(this.getEntityUrl(entityId), {
2005
+ params: typeof params === 'string'
2006
+ ? new HttpParams({ fromString: params })
2007
+ : params,
2008
+ context: context,
2009
+ })
2010
+ .pipe(map((resp) => this.getEntityFromLoadResponse(resp)));
2011
+ }
2012
+ /**
2013
+ * Create a new entity using the bridge if defined, otherwise using HTTP
2014
+ * POST to the `baseUrl`.
2015
+ * @param values
2016
+ * @returns
2017
+ */
2018
+ create(values) {
2019
+ const bridge = this.bridge();
2020
+ if (bridge) {
2021
+ return bridge.create(values);
2022
+ }
2023
+ const url = this.baseUrl();
2024
+ if (!url) {
2025
+ console.warn('SPMatEntityCrudFormBase.create: Cannot create entity as neither bridge nor baseUrl inputs are provided.');
2026
+ return of(undefined);
2027
+ }
2028
+ const httpReqContext = this.httpReqContext();
2029
+ let context = new HttpContext();
2030
+ if (httpReqContext) {
2031
+ context = convertHttpContextInputToHttpContext(context, httpReqContext);
2032
+ }
2033
+ return this.http
2034
+ .post(url, values, { context: context })
2035
+ .pipe(map((resp) => this.getEntityFromLoadResponse(resp)));
2036
+ }
2037
+ /**
2038
+ * Update an existing entity using the bridge if defined, otherwise using HTTP
2039
+ * PATCH to the URL derived from `baseUrl` and the entity id.
2040
+ * @param id
2041
+ * @param values
2042
+ * @returns
2043
+ */
2044
+ update(id, values) {
2045
+ const bridge = this.bridge();
2046
+ if (bridge) {
2047
+ return bridge.update(id, values);
2048
+ }
2049
+ const url = this.baseUrl();
2050
+ if (!url) {
2051
+ console.warn('SPMatEntityCrudFormBase.update: Cannot update entity as neither bridge nor baseUrl inputs are provided.');
2052
+ return of(undefined);
2053
+ }
2054
+ return this.http
2055
+ .patch(this.getEntityUrl(id), values)
2056
+ .pipe(map((resp) => this.getEntityFromLoadResponse(resp)));
2057
+ }
2058
+ getEntityUrl(entityId) {
2059
+ const bridge = this.bridge();
2060
+ if (bridge) {
2061
+ return bridge.getEntityUrl(entityId);
2062
+ }
2063
+ const baseUrl = this.baseUrl();
2064
+ if (baseUrl) {
2065
+ const urlParts = baseUrl.split('?');
2066
+ return `${urlParts[0]}${String(entityId)}/${urlParts[1] ? '?' + urlParts[1] : ''}`;
2067
+ }
2068
+ console.warn('SPMatEntityCrudFormBase.getEntityUrl: Cannot determine entity URL as neither baseUrl nor bridge inputs are provided.');
2069
+ return '';
2070
+ }
1882
2071
  /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: SPMatEntityCrudFormBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
1883
- /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.6", type: SPMatEntityCrudFormBase, isStandalone: false, selector: "_#_sp-mat-entity-crud-form-base_#_", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, bridge: { classPropertyName: "bridge", publicName: "bridge", isSignal: true, isRequired: true, transformFunction: null }, params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: ``, isInline: true });
2072
+ /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.6", type: SPMatEntityCrudFormBase, isStandalone: false, selector: "_#_sp-mat-entity-crud-form-base_#_", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, bridge: { classPropertyName: "bridge", publicName: "bridge", isSignal: true, isRequired: true, transformFunction: null }, params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: false, transformFunction: null }, entityName: { classPropertyName: "entityName", publicName: "entityName", isSignal: true, isRequired: false, transformFunction: null }, baseUrl: { classPropertyName: "baseUrl", publicName: "baseUrl", isSignal: true, isRequired: false, transformFunction: null }, httpReqContext: { classPropertyName: "httpReqContext", publicName: "httpReqContext", isSignal: true, isRequired: false, transformFunction: null }, idKey: { classPropertyName: "idKey", publicName: "idKey", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: ``, isInline: true });
1884
2073
  }
1885
2074
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: SPMatEntityCrudFormBase, decorators: [{
1886
2075
  type: Component,