@smallpearl/ngx-helper 0.32.8 → 0.32.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/i18n/sp-mat-select-entity/en.json +1 -1
- package/assets/i18n/sp-mat-select-entity/zh-hant.json +1 -1
- package/entities/index.d.ts +2 -0
- package/entities/src/paged-loader.d.ts +212 -0
- package/entities/src/paginator.d.ts +87 -0
- package/fesm2022/smallpearl-ngx-helper-entities.mjs +545 -0
- package/fesm2022/smallpearl-ngx-helper-entities.mjs.map +1 -0
- package/fesm2022/smallpearl-ngx-helper-mat-entity-list.mjs.map +1 -1
- package/fesm2022/smallpearl-ngx-helper-mat-select-entity.mjs +476 -471
- package/fesm2022/smallpearl-ngx-helper-mat-select-entity.mjs.map +1 -1
- package/fesm2022/smallpearl-ngx-helper-mat-select-infinite-scroll.mjs +138 -0
- package/fesm2022/smallpearl-ngx-helper-mat-select-infinite-scroll.mjs.map +1 -0
- package/mat-entity-list/src/mat-entity-list-types.d.ts +62 -0
- package/mat-select-entity/src/mat-select-entity.component.d.ts +71 -104
- package/mat-select-infinite-scroll/index.d.ts +2 -0
- package/mat-select-infinite-scroll/src/mat-select-infinite-scroll.directive.d.ts +19 -0
- package/mat-select-infinite-scroll/src/mat-select-infinite-scroll.service.d.ts +25 -0
- package/package.json +17 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smallpearl-ngx-helper-mat-select-entity.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/mat-select-entity.component.ts","../../../../projects/smallpearl/ngx-helper/mat-select-entity/smallpearl-ngx-helper-mat-select-entity.ts"],"sourcesContent":["import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule, NgTemplateOutlet } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken, HttpParams } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n HostBinding,\n inject,\n input,\n Input,\n OnDestroy,\n OnInit,\n Output,\n TemplateRef,\n ViewChild\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NgControl, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { MAT_FORM_FIELD, MatFormFieldControl } from '@angular/material/form-field';\nimport { MatSelect, MatSelectChange, MatSelectModule } from '@angular/material/select';\nimport { provideTranslocoScope, TranslocoModule, TranslocoService } from '@jsverse/transloco';\nimport { camelCase } from 'lodash';\nimport { NgxMatSelectSearchModule } from 'ngx-mat-select-search';\nimport { plural } from 'pluralize';\nimport {\n BehaviorSubject,\n combineLatest,\n debounceTime,\n Observable,\n of,\n Subject,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs';\n\nexport interface SPMatSelectEntityHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n}\n\nexport const SP_MAT_SELECT_ENTITY_HTTP_CONTEXT =\n new HttpContextToken<SPMatSelectEntityHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n }));\n\ntype EntityGroup<T> = {\n id?: PropertyKey;\n name?: string;\n label?: string;\n description?: string;\n items?: T[];\n __items__?: T[]; // for internal use\n};\n\nexport type SPMatSelectEntityResponseParser = <\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n>(\n response: any\n) => Array<TEntity>;\n\n/**\n * This is a generic component to display a <mat-select> for a FK field\n * where the select's options are dynamically loaded from the server using\n * the given url (or URL). The objects thus retrieved should have a\n * unique 'id' field that will be used as the value of each `option` element.\n * Therefore upon selection of an `option` element, the `select` value will\n * be set to the object's `id` property. By default 'id' is used as its id,\n * but this can be customized by specifying the `idKey' property value.\n */\n@Component({\n selector: 'sp-mat-select-entity',\n template: `\n <div\n *transloco=\"let t; scope: 'sp-mat-select-entity'\"\n (focusin)=\"onFocusIn($event)\"\n (focusout)=\"onFocusOut($event)\"\n role=\"group\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n >\n <mat-select\n [placeholder]=\"placeholder\"\n (opened)=\"onSelectOpened($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n [multiple]=\"multiple\"\n [(ngModel)]=\"selectValue\"\n >\n <mat-select-trigger>\n {{ selectTriggerValue }}\n @if (selectTriggerValueAsArray.length > 1) {\n <span class=\"addl-selection-count\">\n (+{{ selectTriggerValueAsArray.length - 1 }})\n </span>\n }\n </mat-select-trigger>\n\n <mat-option>\n <ngx-mat-select-search\n [(ngModel)]=\"filterStr\"\n (ngModelChange)=\"this.filter$.next($event)\"\n [placeholderLabel]=\"\n searchText() ? searchText() : t('spMatSelectEntity.search')\n \"\n [noEntriesFoundLabel]=\"\n notFoundText() ? notFoundText() : t('spMatSelectEntity.notFound')\n \"\n [searching]=\"searching\"\n >\n </ngx-mat-select-search>\n </mat-option>\n\n <ng-container *ngIf=\"!group; else groupedOptions\">\n <span *ngIf=\"filteredValues | async as entities\">\n <ng-template #defaultOptionLabelTemplate let-entity>\n {{ _entityLabelFn()(entity) }}\n </ng-template>\n @for (entity of entities; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n <ng-container\n *ngTemplateOutlet=\"\n optionLabelTemplate() || defaultOptionLabelTemplate;\n context: { $implicit: entity }\n \"\n ></ng-container>\n </mat-option>\n }\n\n <!-- <mat-option class=\"sel-entity-option\" *ngFor=\"let entity of entities\" [value]=\"entityId(entity)\">\n {{ _entityLabelFn()(entity) }}\n </mat-option> -->\n </span>\n </ng-container>\n <ng-template #groupedOptions>\n <span *ngIf=\"filteredGroupedValues | async as groups\">\n @for (group of groups; track groupLabel(group)) {\n <mat-optgroup [label]=\"groupLabel(group)\">\n @for (entity of group.__items__; track entityId(entity)) {\n\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n {{ _entityLabelFn()(entity) }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </span>\n </ng-template>\n\n <mat-option\n *ngIf=\"!multiple && inlineNew\"\n class=\"add-item-option\"\n value=\"0\"\n (click)=\"$event.stopPropagation()\"\n >⊕\n {{\n this.addItemText()\n ? this.addItemText()\n : t('spMatSelectEntity.addItem', { item: this.entityName })\n }}</mat-option\n >\n </mat-select>\n </div>\n `,\n styles: [\n `\n .add-item-option {\n padding-top: 2px;\n border-top: 1px solid gray;\n }\n .addl-selection-count {\n opacity: 0.75;\n font-size: 0.8em;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n NgTemplateOutlet,\n FormsModule,\n ReactiveFormsModule,\n MatSelectModule,\n TranslocoModule,\n NgxMatSelectSearchModule,\n ],\n providers: [\n provideTranslocoScope('sp-mat-select-entity'),\n { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },\n ],\n})\nexport class SPMatSelectEntityComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> implements\n OnInit,\n OnDestroy,\n AfterViewInit,\n ControlValueAccessor,\n MatFormFieldControl<string | number | string[] | number[]>\n{\n // We cache the entities that we fetch from remote here. Cache is indexed\n // by the endpoint. Each endpoint also keeps a refCount, which is incremented\n // for each instance of the component using the same endpoint. When this\n // refcount reaches 0, the endpoint is removed from the cache.\n //\n // This mechanism is to suppress multiple fetches from the remote from the\n // same endpoint as that can occur if a form has multiple instances of\n // this component, with the same endpoint.\n static _entitiesCache = new Map<\n string,\n { refCount: number; entities: Array<any> }\n >();\n\n @ViewChild(MatSelect) matSel!: MatSelect;\n\n // REQUIRED PROPERTIES //\n /**\n * Entity label function. Given an entity return its natural label\n * to display to the user.\n */\n @Input() entityLabelFn!: (entity: TEntity) => string;\n\n // OPTIONAL PROPERTIES //\n /**\n * Entity filter function - return a boolean if the entity is to be included\n * in the filtered entities list.\n * @param entity: TEntity object to test for 'search' string.\n * @param search - search string\n */\n @Input({ required: false }) entityFilterFn!: (\n entity: TEntity,\n search: string\n ) => boolean;\n /**\n * Entity idKey, if idKey is different from the default 'id'.\n */\n @Input({ required: false }) idKey = 'id';\n /**\n * URL of the remote from where entities are to be loaded.\n * This won't be used if `loadFromRemoteFn` is specified.\n */\n @Input({ required: false }) url!: string;\n /**\n * Parameters to be added to the HTTP request to retrieve data from\n * remote. This won't be used if `loadFromRemoteFn` is specified.\n */\n @Input({ required: false }) httpParams!: HttpParams;\n /**\n * Function to load entities from remote.\n */\n @Input({ required: false }) loadFromRemoteFn!: () => Observable<TEntity[]>;\n\n @Input({ required: false }) inlineNew: boolean = false;\n /**\n * Entity name, that is used to form the \"New { item }\" menu item if\n * inlineNew=true. This is also used as the key of the object in GET response\n * if the reponse JSON is not an array and rather an object, where the values\n * are stored indexed by the server model name. For eg:-\n *\n * {\n * 'customers': [\n * {...},\n * {...},\n * {...},\n * ]\n * }\n */\n @Input({ required: false }) entityName!: string;\n // Set to true to allow multiple option selection. The returned value\n // would be an array of entity ids.\n @Input({ required: false }) multiple = false;\n /*\n Whether to group options using <mat-optgroup></mat-optgroup>.\n If set to true, the response from the server should be an array of\n groups of TEntity objects, where each object is of the form:\n [\n {\n id: <id>,\n name|label: <>,\n items|<plural_entityName>|<custom_key>: [\n TEntity,\n ...\n ]\n },\n ...\n ]\n */\n @Input({ required: false }) group = false;\n /**\n * The group object key name under which options are stored. Defaults to\n * 'items' or pluralized 'entityName'. Ideally the client class should\n * explicitly set this property value.\n */\n @Input({ required: false }) groupOptionsKey!: string;\n /**\n * If groupOptions = true, specify this to provide accurate label for each\n * group. If not specified, group label will be determined by looking up one\n * of the standard fields - name, label or description - whichever comes\n * first.\n */\n @Input({ required: false }) groupLabelFn!: (group: any) => string;\n /**\n * Sideload data key name.\n */\n sideloadDataKey = input<string>();\n /**\n * Parser function to return the list of entities from the GET response.\n */\n responseParserFn = input<SPMatSelectEntityResponseParser>();\n\n @Output() selectionChange = new EventEmitter<TEntity | TEntity[]>();\n @Output() createNewItemSelected = new EventEmitter<void>();\n\n // allow per component customization\n readonly searchText = input<string>();\n readonly notFoundText = input<string>();\n readonly addItemText = input<string>();\n\n controlType = 'sp-mat-select-entity';\n\n /**\n * Template for the option label. If not provided, the default label\n * function will be used. Option label is what is placed inside the\n * <mat-option> tag. The template gets an implicit 'entity' variable\n * in the context, value for which is the entity object.\n *\n * For example:\n * ```\n * <sp-mat-select-entity\n * [url]=\"'/api/v1/customers/'\"\n * [entityLabelFn]=\"entity => entity.name\"\n * [optionLabelTemplate]=\"optionLabelTemplate\"\n * ></sp-mat-select-entity>\n * <ng-template #optionLabelTemplate let-entity>\n * {{ entity.name }} - {{ entity.description }}\n * </ng-template>\n * ```\n */\n optionLabelTemplate = input<TemplateRef<any>>();\n\n _entityLabelFn = computed<(entity: TEntity) => string>(() => {\n const fn = this.entityLabelFn;\n if (fn) {\n return fn;\n }\n return (entity: TEntity) => {\n return (\n (entity as any)['name'] ||\n (entity as any)['label'] ||\n String((entity as any)[this.idKey])\n );\n };\n });\n\n _sideloadDataKey = computed<string>(() => {\n if (this.sideloadDataKey()) {\n return this.sideloadDataKey() as string;\n }\n return this.entityName ? plural(camelCase(this.entityName)) : 'results';\n });\n\n private _entities = new Map<PropertyKey, TEntity>();\n private _groupedEntities = new Array<EntityGroup<TEntity>>();\n\n stateChanges = new Subject<void>();\n focused = false;\n touched = false;\n\n selectValue!: string | number | string[] | number[];\n // For storing last select value, which we use to restore the select's value\n // to when New Item is selected. This ensures that when New Item is selected,\n // the select's value remains the same. If the newly created item is to be\n // set as the select's value, the corresponding TEntity has to be added\n // to _entities (via addEntity()) and then selected by setting the\n // corresponding formControl's value to the entity's id.\n lastSelectValue!: string | number | string[] | number[];\n searching = false;\n filterStr: string = '';\n\n filter$ = new BehaviorSubject<string>('');\n // ControlValueAccessor callback\n onChanged = (_: any) => {};\n onTouched = () => {};\n @ViewChild(MatSelect) matSelect!: MatSelect;\n\n filteredValues = new Subject<TEntity[]>();\n filteredGroupedValues = new Subject<EntityGroup<TEntity>[]>();\n\n destroy = new Subject<void>();\n private loaded = false;\n private load$ = new BehaviorSubject<boolean>(false);\n\n static nextId = 0;\n @HostBinding() id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;\n private _placeholder!: string;\n protected http = inject(HttpClient);\n protected cdr = inject(ChangeDetectorRef);\n protected _elementRef = inject(ElementRef<HTMLElement>);\n protected _formField = inject(MAT_FORM_FIELD, { optional: true });\n public ngControl = inject(NgControl, { optional: true });\n transloco = inject(TranslocoService);\n\n constructor() {\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n ngOnInit() {\n combineLatest([this.filter$.pipe(debounceTime(400)), this.load$])\n .pipe(\n takeUntil(this.destroy),\n switchMap(([str, load]) => {\n if (load && !this.loaded) {\n this.searching = true;\n this.cdr.detectChanges();\n return this.loadFromRemote();\n } else {\n return of(this.entities ?? []);\n }\n }),\n tap(() => {\n if (this.group) {\n this.filterGroupedValues(this.filterStr);\n } else {\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n })\n )\n .subscribe();\n }\n ngOnDestroy(): void {\n this.destroy.next();\n this.removeFromCache();\n this.stateChanges.complete();\n }\n\n ngAfterViewInit(): void {\n // I'm not sure this is how this logic is right, but this seems to work.\n // if (this.ngControl && this.ngControl.control?.validator) {\n // const validator = this.ngControl.control.validator;\n // const res = validator(this.ngControl.control);\n // if (res && res['required']) {\n // this.required = true;\n // }\n // }\n }\n\n addEntity(entity: TEntity) {\n this._entities.set((entity as any)[this.idKey], entity);\n // So that the newly added entity will be added to the <mat-option> list.\n this.filterValues(this.filterStr);\n this.cdr.detectChanges();\n }\n\n get selectTriggerValue() {\n if (this.selectValue) {\n const firstSelected = Array.isArray(this.selectValue)\n ? this.selectValue[0]\n : this.selectValue;\n const selectedEntity = this._entities.get(firstSelected);\n return selectedEntity ? this._entityLabelFn()(selectedEntity) : '';\n }\n return '';\n }\n\n get selectTriggerValueAsArray() {\n return Array.isArray(this.selectValue)\n ? (this.selectValue as Array<string | number>)\n : [];\n }\n\n entityId(entity: TEntity) {\n return (entity as any)[this.idKey];\n }\n\n writeValue(entityId: string | number | string[] | number[]): void {\n if (Array.isArray(entityId)) {\n if (this.multiple) {\n const selectedValues: any[] = [];\n entityId.forEach((id) => {\n if (this._entities.has(id)) {\n selectedValues.push(id);\n }\n });\n this.selectValue = selectedValues;\n this.cdr.detectChanges();\n }\n } else {\n if (this._entities.has(entityId)) {\n this.selectValue = entityId;\n if (this.filterStr) {\n this.filterStr = '';\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n }\n }\n }\n registerOnChange(fn: any): void {\n this.onChanged = fn;\n }\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n @Input()\n get entities(): TEntity[] {\n return Array.from(this._entities.values());\n }\n\n set entities(items: TEntity[]) {\n if (!this.group) {\n items.forEach((item) => {\n this._entities.set((item as any)[this.idKey], item);\n });\n } else {\n this._groupedEntities = items as any as EntityGroup<TEntity>[];\n this._groupedEntities.forEach((group) => {\n const key = this.groupEntitiesKey();\n const groupEntities = (group as any)[key] as TEntity[];\n (group as any)['__items__'] = groupEntities;\n groupEntities.forEach((item) => {\n this._entities.set((item as any)[this.idKey], item);\n });\n });\n }\n }\n\n @Input()\n get value(): string | number | string[] | number[] {\n return this.selectValue;\n }\n set value(val: string | number | string[] | number[]) {\n this.selectValue = val;\n this.stateChanges.next();\n }\n get shouldLabelFloat() {\n return this.focused || !this.empty;\n }\n\n @Input('aria-describedby') userAriaDescribedBy!: string;\n\n @Input()\n get placeholder(): string {\n return this._placeholder;\n }\n set placeholder(value: string) {\n this._placeholder = value;\n this.stateChanges.next();\n }\n\n @Input()\n get required() {\n return (\n this._required ??\n this.ngControl?.control?.hasValidator(Validators.required)\n );\n }\n set required(req: boolean) {\n this._required = coerceBooleanProperty(req);\n this.stateChanges.next();\n }\n // Deliberately 'undefined' so that `get required()` will return the state\n // from ngControl's validators.\n private _required!: boolean;\n\n @Input()\n get disabled(): boolean {\n return this._disabled ?? this.ngControl?.control?.disabled;\n }\n set disabled(value: BooleanInput) {\n const disabled = coerceBooleanProperty(value);\n if (disabled !== this._disabled) {\n this.setDisabledState(disabled);\n this.stateChanges.next();\n }\n }\n // Same as `_required`, deliberately `undefined` by default.\n private _disabled!: boolean;\n\n get empty() {\n return !this.value;\n }\n\n get errorState(): boolean {\n return !!this.ngControl?.invalid && this.touched;\n }\n\n onFocusIn(event: FocusEvent) {\n if (!this.focused) {\n this.focused = true;\n this.stateChanges.next();\n }\n }\n\n onFocusOut(event: FocusEvent) {\n if (\n !this._elementRef.nativeElement.contains(event.relatedTarget as Element)\n ) {\n this.touched = true;\n this.focused = false;\n this.onTouched();\n this.stateChanges.next();\n }\n }\n\n setDescribedByIds(ids: string[]) {}\n\n onContainerClick(event: MouseEvent) {\n if ((event.target as Element).tagName.toLowerCase() != 'mat-select') {\n this._elementRef.nativeElement.querySelector('mat-select').focus();\n }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled = isDisabled;\n if (this.matSelect) {\n this.matSelect.setDisabledState(isDisabled);\n this.cdr.detectChanges();\n }\n }\n onSelectOpened(ev: any) {\n // Store the current select value so that we can restore it if user\n // eventually selects 'New Item' option.\n this.lastSelectValue = this.selectValue;\n // If values have not been loaded from remote, trigger a load.\n if (!this.loaded) {\n this.load$.next(true); // this will trigger the loadFromRemote() call.\n }\n }\n onSelectionChange(ev: MatSelectChange) {\n // console.log('SelectionChange - sel:', ev);\n if (Array.isArray(ev.value)) {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n const selectedEntities: TEntity[] = ev.value.map((id) =>\n this._entities.get(id)\n ) as TEntity[];\n this.selectionChange.emit(selectedEntities);\n } else {\n if (ev.value !== '0') {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n this.selectionChange.emit(this._entities.get(ev.value));\n } else {\n // New Item activated, return value to previous value. We track\n // previous value via 'lastSelectValue' member which is updated\n // whenever the select is opened.\n if (this.ngControl) {\n this.ngControl.control?.setValue(this.lastSelectValue);\n }\n ev.source.value = this.lastSelectValue;\n this.createNewItemSelected.emit();\n this.cdr.detectChanges();\n }\n }\n }\n\n filterValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const entities = this.entities;\n if (!entities) {\n return;\n }\n if (!search) {\n this.filteredValues.next(entities.slice());\n } else {\n this.filteredValues.next(\n entities.filter((member) => {\n if (this.entityFilterFn) {\n return this.entityFilterFn(member, search);\n }\n const labelFn = this._entityLabelFn();\n return labelFn(member).toLocaleLowerCase().includes(searchLwr);\n })\n );\n }\n }\n\n /**\n * Filtering grouped entities logic works like this. If the search string\n * matches a group label, the entire group is to be included in the results.\n * However, if the search string only matches certain entities, only those\n * groups are to be included and within those groups, only entities whose\n * label matches the search string are to be included in the result set.\n * @param search\n * @returns\n */\n filterGroupedValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const groups = this._groupedEntities;\n if (!groups) {\n return;\n }\n if (!search) {\n const groupsCopy = groups.slice();\n this.filteredGroupedValues.next(groupsCopy);\n } else {\n const groupEntitiesKey = this.groupEntitiesKey();\n const groups = this._groupedEntities.map((ge) => {\n const label = this.groupLabel(ge);\n if (label.toLocaleLowerCase().includes(searchLwr)) {\n return { ...ge } as EntityGroup<TEntity>;\n } else {\n const groupEntities = ge.__items__?.filter((e) =>\n this._entityLabelFn()(e).toLocaleLowerCase().includes(searchLwr)\n );\n const ret: any = {\n ...ge,\n };\n ret['__items__'] = groupEntities ?? [];\n return ret as EntityGroup<TEntity>;\n }\n });\n // filter out groups with no entities\n // console.log(`Groups: ${JSON.stringify(groups)}`);\n this.filteredGroupedValues.next(\n groups.filter(\n (group) =>\n Array.isArray((group as any)[groupEntitiesKey]) &&\n (group as any)['__items__'].length > 0\n )\n );\n }\n }\n\n loadFromRemote() {\n if (!this.url && !this.loadFromRemoteFn) {\n // If user had initialized entities, they will be dispalyed\n // in the options list. If not, options would be empty.\n return of(this.group ? this.groupEntities : this.entities);\n }\n let cacheKey!: string;\n let obs: Observable<TEntity[]>;\n if (this.loadFromRemoteFn) {\n obs = this.loadFromRemoteFn();\n } else {\n let params!: HttpParams;\n if (this.httpParams) {\n params = new HttpParams({\n fromString: this.httpParams.toString(),\n });\n } else {\n params = new HttpParams();\n }\n params = params.set('paginate', false);\n cacheKey = this.getCacheKey();\n if (this.existsInCache()) {\n obs = of(this.getFromCache());\n } else {\n obs = this.http.get<any>(this.url, {\n context: this.getHttpReqContext(),\n params,\n });\n }\n }\n return obs.pipe(\n tap((entities) => {\n this.searching = false; // remote loading done, will hide the loading wheel\n // Handle DRF paginated response\n const responseParserFn = this.responseParserFn();\n if (responseParserFn) {\n entities = responseParserFn(entities) as unknown as TEntity[];\n } else {\n if (\n !Array.isArray(entities) &&\n entities['results'] &&\n Array.isArray(entities['results'])\n ) {\n entities = entities['results'];\n } else if (\n // sideloaded response, where entities are usually provided in 'entityName'\n this._sideloadDataKey() &&\n !Array.isArray(entities) &&\n typeof entities === 'object' &&\n entities[this._sideloadDataKey()] &&\n Array.isArray(entities[this._sideloadDataKey()])\n ) {\n entities = entities[this._sideloadDataKey()];\n }\n }\n if (Array.isArray(entities)) {\n this.entities = entities;\n // if (this.group) {\n // this._groupedEntities = entities as EntityGroup<TEntity>[];\n // } else {\n // this.entities = entities;\n // }\n }\n this.loaded = true;\n this.addToCache(entities);\n this.cdr.detectChanges();\n })\n );\n }\n\n groupLabel(group: EntityGroup<TEntity>): string {\n if (this.groupLabelFn) {\n return this.groupLabelFn(group);\n }\n const standardLabelFields = ['name', 'label', 'desc', 'description'];\n for (let index = 0; index < standardLabelFields.length; index++) {\n const labelField = standardLabelFields[index];\n if ((group as any)[labelField]) {\n return (group as any)[labelField];\n }\n }\n return `Group ${String(group.id)}`;\n }\n\n groupEntities(group: EntityGroup<TEntity>): TEntity[] {\n const key = this.groupEntitiesKey();\n console.log(`groupEntities - group: ${JSON.stringify(group)}, key: ${key}`);\n return (group as any)[this.groupEntitiesKey()] ?? [];\n }\n\n groupEntitiesKey() {\n return this.groupOptionsKey\n ? this.groupOptionsKey\n : this.entityName\n ? plural(this.entityName.toLocaleLowerCase())\n : 'items';\n }\n\n private existsInCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n return SPMatSelectEntityComponent._entitiesCache.has(cacheKey);\n }\n return false;\n }\n\n private getCacheKey() {\n if (!this.loadFromRemoteFn) {\n let params!: HttpParams;\n if (this.httpParams) {\n params = new HttpParams({\n fromString: this.httpParams.toString(),\n });\n } else {\n params = new HttpParams();\n }\n // params = params.set('paginate', false)\n return `${this.url}?${params.toString()}`;\n }\n return ''; // empty string evalutes to boolean(false)\n }\n private getFromCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)\n ?.entities as TEntity[];\n }\n return [];\n }\n private addToCache(entities: TEntity[]) {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n if (!SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n SPMatSelectEntityComponent._entitiesCache.set(cacheKey, {\n refCount: 0,\n entities,\n });\n }\n const cacheEntry =\n SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n cacheEntry!.refCount += 1;\n }\n }\n private removeFromCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n const cacheEntry =\n SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n if (cacheEntry) {\n cacheEntry!.refCount -= 1;\n if (cacheEntry.refCount <= 0) {\n SPMatSelectEntityComponent._entitiesCache.delete(cacheKey);\n }\n }\n }\n }\n\n private getHttpReqContext() {\n const context = new HttpContext();\n const entityName = this.entityName;\n context.set(SP_MAT_SELECT_ENTITY_HTTP_CONTEXT, {\n entityName: this.entityName ?? '',\n entityNamePlural: this.entityName ? plural(this.entityName) : '',\n endpoint: this.url,\n });\n return context;\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-select-entity.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/mat-select-entity.component.ts","../../../../projects/smallpearl/ngx-helper/mat-select-entity/smallpearl-ngx-helper-mat-select-entity.ts"],"sourcesContent":["import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule, NgTemplateOutlet } from '@angular/common';\nimport {\n HttpContext,\n HttpContextToken\n} from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n HostBinding,\n inject,\n input,\n Input,\n OnDestroy,\n OnInit,\n Output,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormsModule,\n NgControl,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MAT_FORM_FIELD,\n MatFormFieldControl,\n} from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport {\n MatSelect,\n MatSelectChange,\n MatSelectModule,\n} from '@angular/material/select';\nimport {\n provideTranslocoScope,\n TranslocoModule,\n TranslocoService,\n} from '@jsverse/transloco';\nimport { getEntity, hasEntity, selectAllEntities, upsertEntities } from '@ngneat/elf-entities';\nimport {\n SPPagedEntityLoader\n} from '@smallpearl/ngx-helper/entities';\nimport {\n SPMatEntityListPaginator,\n SPPageParams,\n} from '@smallpearl/ngx-helper/mat-entity-list';\nimport { MatSelectInfiniteScrollDirective } from '@smallpearl/ngx-helper/mat-select-infinite-scroll';\nimport { NgxMatSelectSearchModule } from 'ngx-mat-select-search';\nimport {\n combineLatest,\n debounceTime,\n distinctUntilChanged,\n Observable,\n startWith,\n Subject,\n takeUntil,\n tap\n} from 'rxjs';\n\n\nexport interface SPMatSelectEntityHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n}\n\nexport const SP_MAT_SELECT_ENTITY_HTTP_CONTEXT =\n new HttpContextToken<SPMatSelectEntityHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n }));\n\n// Internal type to represent a group of entities. Used when grouping is enabled.\ntype EntityGroup<TEntity> = {\n label: string;\n entities: TEntity[];\n};\n\nexport type SPMatSelectEntityResponseParser = <\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n>(\n response: any\n) => Array<TEntity>;\n\n// Default paginator implementation. This can handle dynamic-rest and DRF\n// native pagination schemes. It also has a fallback to handle response conists\n// of an array of entities.\nclass DefaultPaginator implements SPMatEntityListPaginator {\n getRequestPageParams(\n endpoint: string,\n page: number,\n pageSize: number\n ): SPPageParams {\n return {\n page: page + 1,\n pageSize,\n };\n }\n\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 ) {\n if (Array.isArray(resp)) {\n return {\n total: resp.length,\n entities: resp,\n };\n }\n\n if (typeof resp === 'object') {\n const keys = Object.keys(resp);\n // Handle dynamic-rest sideloaded response\n // Rudimentary sideloaded response support. This should work for most\n // of the sideloaded responses where the main entities are stored\n // under the plural entity name key and resp['meta'] object contains\n // the total count.\n if (\n keys.includes(entityNamePlural) &&\n Array.isArray(resp[entityNamePlural])\n ) {\n let total = resp[entityNamePlural].length;\n if (\n keys.includes('meta') &&\n typeof resp['meta'] === 'object' &&\n typeof resp['meta']['total'] === 'number'\n ) {\n total = resp['meta']['total'];\n }\n return {\n total,\n entities: resp[entityNamePlural],\n };\n }\n\n // Handle django-rest-framework style response\n if (keys.includes('results') && Array.isArray(resp['results'])) {\n let total = resp['results'].length;\n if (keys.includes('count') && typeof resp['count'] === 'number') {\n total = resp['count'];\n }\n return {\n total,\n entities: resp['results'],\n };\n }\n\n // Finally, look for \"items\" key\n if (keys.includes('items') && Array.isArray(resp['items'])) {\n return {\n total: resp['items'].length,\n entities: resp['items'],\n };\n }\n }\n\n return {\n total: 0,\n entities: [],\n };\n }\n}\n\n/**\n * This is a generic component to display a <mat-select> for a FK field\n * where the select's options are dynamically loaded from the server using\n * the given url (or URL). The objects thus retrieved should have a\n * unique 'id' field that will be used as the value of each `option` element.\n * Therefore upon selection of an `option` element, the `select` value will\n * be set to the object's `id` property. By default 'id' is used as its id,\n * but this can be customized by specifying the `idKey' property value.\n */\n@Component({\n selector: 'sp-mat-select-entity',\n template: `\n <div\n *transloco=\"let t; scope: 'sp-mat-select-entity'\"\n (focusin)=\"onFocusIn($event)\"\n (focusout)=\"onFocusOut($event)\"\n role=\"group\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n >\n <mat-select\n [placeholder]=\"placeholder\"\n (opened)=\"onSelectOpened($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n [multiple]=\"multiple()\"\n [(ngModel)]=\"selectValue\"\n msInfiniteScroll\n (infiniteScroll)=\"onInfiniteScroll()\"\n >\n <mat-select-trigger>\n {{ selectTriggerValue }}\n @if (selectTriggerValueAsArray.length > 1) {\n <span class=\"addl-selection-count\">\n (+{{ selectTriggerValueAsArray.length - 1 }})\n </span>\n }\n </mat-select-trigger>\n\n <mat-option>\n <ngx-mat-select-search\n class=\"flex-grow-1\"\n [(ngModel)]=\"filterStr\"\n (ngModelChange)=\"this.filter$.next($event)\"\n [placeholderLabel]=\"\n searchText() ? searchText() : t('spMatSelectEntity.search')\n \"\n [noEntriesFoundLabel]=\"\n notFoundText() ? notFoundText() : t('spMatSelectEntity.notFound')\n \"\n [searching]=\"searching\"\n >\n </ngx-mat-select-search>\n </mat-option>\n\n <ng-template #defaultOptionLabelTemplate let-entity>\n {{ _entityLabelFn()(entity) }}\n </ng-template>\n @if (!_group()) { @if (filteredValues | async; as entities) { @for\n (entity of entities; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n <ng-container\n *ngTemplateOutlet=\"\n optionLabelTemplate() || defaultOptionLabelTemplate;\n context: { $implicit: entity }\n \"\n ></ng-container>\n </mat-option>\n } } } @else { @if (filteredGroupedValues | async; as groups) { @for\n (group of groups; track group.label) {\n <mat-optgroup [label]=\"group.label\">\n @for (entity of group.entities; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n <ng-container\n *ngTemplateOutlet=\"\n optionLabelTemplate() || defaultOptionLabelTemplate;\n context: { $implicit: entity }\n \"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n } } }\n\n <!--\n Create New option is displayed only if there is a filter string.\n The logic behind this behavior being that user searches for a matching\n item and when not finding one, would like to add a new one.\n -->\n @if (inlineNew() && filterStr.length > 0) {\n <mat-option\n class=\"add-item-option\"\n value=\"0\"\n (click)=\"$event.stopPropagation()\"\n >⊕\n {{\n this.createNewText()\n ? this.createNewText()\n : t('spMatSelectEntity.createNew', {\n item: this._capitalizedEntityName()\n })\n }}\n </mat-option>\n }\n </mat-select>\n </div>\n `,\n styles: [\n `\n .add-item-option {\n padding-top: 2px;\n border-top: 1px solid var(--mat-sys-outline);\n }\n .addl-selection-count {\n opacity: 0.75;\n font-size: 0.8em;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n NgTemplateOutlet,\n FormsModule,\n ReactiveFormsModule,\n MatSelectModule,\n MatButtonModule,\n MatIconModule,\n TranslocoModule,\n NgxMatSelectSearchModule,\n MatSelectInfiniteScrollDirective,\n ],\n providers: [\n provideTranslocoScope('sp-mat-select-entity'),\n { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },\n ],\n})\nexport class SPMatSelectEntityComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >\n extends SPPagedEntityLoader<TEntity, IdKey>\n implements\n OnInit,\n OnDestroy,\n AfterViewInit,\n ControlValueAccessor,\n MatFormFieldControl<string | number | string[] | number[]>\n{\n // We cache the entities that we fetch from remote here. Cache is indexed\n // by the endpoint. Each endpoint also keeps a refCount, which is incremented\n // for each instance of the component using the same endpoint. When this\n // refcount reaches 0, the endpoint is removed from the cache.\n //\n // This mechanism is to suppress multiple fetches from the remote from the\n // same endpoint as that can occur if a form has multiple instances of\n // this component with the same url.\n // static _entitiesCache = new Map<\n // string,\n // { refCount: number; entities: Array<any> }\n // >();\n\n //**** OPTIONAL ATTRIBUTES ****//\n\n // Entity label function - function that takes an entity object and returns\n // a string label for it. If not specified, a default label function is used\n // that returns the value of 'name' or 'label' or 'title' property. If\n // none of these properties are present, the entity's id is returned as\n // string.\n labelFn = input<(entity: TEntity) => string>();\n\n // Entity filter function - return a boolean if the entity is to be included\n // in the filtered entities list.\n filterFn = input<(entity: TEntity, search: string) => boolean>();\n\n // Set to true to show \"Add { item }\" option in the select dropdown.\n // Selecting this option, will emit `createNewItemSelected` event.\n inlineNew = input<boolean>(false);\n\n // Set to true to allow multiple option selection. The returned value\n // would be an array of entity ids.\n multiple = input<boolean>(false);\n\n /**\n * The entity key name that is used to classify entities into groups.\n * Entities with the same key value will be grouped together. If this is\n * specified, grouping will be enabled.\n * @see groupByFn\n */\n groupOptionsKey = input<string>();\n\n /**\n * A function that takes a TEntity and returns the group id (string)\n * that the entity belongs to. If this is specified, grouping of entities\n * in the select will be enabled. This takes precedence over\n * `groupOptionsKey`.\n * @see groupOptionsKey\n */\n groupByFn = input<(entity: TEntity) => string>();\n\n @Output() selectionChange = new EventEmitter<TEntity | TEntity[]>();\n @Output() createNewItemSelected = new EventEmitter<void>();\n\n // i18n localization support toallow per component customization of\n // some strings used.\n readonly searchText = input<string>();\n readonly notFoundText = input<string>();\n readonly createNewText = input<string>();\n\n controlType = 'sp-mat-select-entity';\n\n /**\n * Template for the option label. If not provided, the default label\n * function will be used. Option label is what is placed inside the\n * <mat-option> tag. The template gets an implicit 'entity' variable\n * in the context, value for which is the entity object.\n *\n * For example:\n * ```\n * <sp-mat-select-entity\n * [url]=\"'/api/v1/customers/'\"\n * [labelFn]=\"entity => entity.name\"\n * [optionLabelTemplate]=\"optionLabelTemplate\"\n * ></sp-mat-select-entity>\n * <ng-template #optionLabelTemplate let-entity>\n * {{ entity.name }} - {{ entity.description }}\n * </ng-template>\n * ```\n */\n optionLabelTemplate = input<TemplateRef<any>>();\n\n // a computed version of labelFn that provides a default implementation\n protected _entityLabelFn = computed<(entity: TEntity) => string>(() => {\n const fn = this.labelFn();\n if (fn) {\n return fn;\n }\n return (entity: TEntity) => {\n return (\n (entity as any)['name'] ||\n (entity as any)['label'] ||\n (entity as any)['title'] ||\n String((entity as any)[this.idKey()])\n );\n };\n });\n\n // Whether to group options. Grouping is enabled when either groupOptionsKey\n // or groupByFn is specified.\n protected _group = computed<boolean>(() => {\n return !!this.groupOptionsKey() || !!this.groupByFn();\n });\n\n protected _groupEntitiesKey = computed<string>(() => {\n const groupOptionsKey = this.groupOptionsKey();\n return groupOptionsKey\n ? groupOptionsKey\n : this.entityName()\n ? this._pluralEntityName()\n : 'items';\n });\n\n // For the global paginator. We'll abstract this into an independent\n // configuration that can be shared across both mat-entity-list and\n // mat-select-entity later.\n // entityListConfig = getEntityListConfig();\n\n // protected _paginator = computed<SPMatEntityListPaginator>(() => {\n // const paginator = this.paginator();\n // const entityListConfigPaginator = this.entityListConfig\n // ?.paginator as SPMatEntityListPaginator;\n // return paginator\n // ? paginator\n // : entityListConfigPaginator ?? new DefaultPaginator();\n // });\n\n stateChanges = new Subject<void>();\n focused = false;\n touched = false;\n\n selectValue!: string | number | string[] | number[];\n // For storing last select value, which we use to restore the select's value\n // to when New Item is selected. This ensures that when New Item is selected,\n // the select's value remains the same. If the newly created item is to be\n // set as the select's value, the corresponding TEntity has to be added\n // to _entities (via addEntity()) and then selected by setting the\n // corresponding formControl's value to the entity's id.\n lastSelectValue!: string | number | string[] | number[];\n searching = false;\n filterStr: string = '';\n\n filter$ = new Subject<string>();\n\n // ControlValueAccessor callbacks\n onChanged = (_: any) => {};\n onTouched = () => {};\n\n // @ViewChild(MatSelect) matSelect!: MatSelect;\n matSelect = viewChild(MatSelect);\n\n filteredValues = new Subject<TEntity[]>();\n filteredGroupedValues = new Subject<EntityGroup<TEntity>[]>();\n\n destroy = new Subject<void>();\n\n static nextId = 0;\n @HostBinding() id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;\n private _placeholder!: string;\n //protected http = inject(HttpClient);\n protected cdr = inject(ChangeDetectorRef);\n protected _elementRef = inject(ElementRef<HTMLElement>);\n protected _formField = inject(MAT_FORM_FIELD, { optional: true });\n public ngControl = inject(NgControl, { optional: true });\n transloco = inject(TranslocoService);\n\n // pagedEntityLoader!: SPPagedEntityLoader<TEntity, IdKey>;\n\n constructor() {\n super();\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n /**\n * Conditions for loading entities:\n *\n * 1. When the select is opened, if entities have not already been loaded.\n * 2. When the search string changes.\n * 3. When the scroll reaches the bottom and more entities are available\n * to be loaded.\n *\n * We need to create an 'observer-loop' that can handle the above.\n */\n\n ngOnInit() {\n // this.pagedEntityLoader = new SPPagedEntityLoader<TEntity, IdKey>(\n // this.entityName(),\n // this.url(),\n // this.http,\n // this.pageSize(),\n // this._paginator(),\n // this.searchParamName(),\n // this.idKey(),\n // this._pluralEntityName(),\n // undefined,\n // this.httpParams()\n // );\n this.startLoader();\n\n // A rudimentary mechanism to detect which of the two observables\n // emitted the latest value. We reset this array to 'false' after\n // processing every combined emission.\n const emittedObservable = [false, false];\n const store$ = this.store.pipe(selectAllEntities());\n const filter$ = this.filter$.pipe(\n startWith(''),\n distinctUntilChanged(),\n debounceTime(400)\n );\n\n const emittedStatusObservable = (obs: Observable<any>, index: number) =>\n obs.pipe(tap(() => (emittedObservable[index] = true)));\n\n // We need to determine if the emission is owing to a change in\n // filterStr or a change in the entities in pagedEntityLoader.store$.\n //\n // 1. If entities in pagedEntityLoader.store$ have changed, we just need\n // to filter the entities in local store using the current filterStr.\n // 2. If filterStr has changed, there are two cases to handle:-\n // a. If all entities have been loaded, we don't need to reload\n // entities. Instead we just have to filter the entities in\n // local store using the filterStr.\n // b. If all entities have not been loaded, we trigger a server\n // load with the new filterStr as the search param.\n //\n // The following logic implements the above.\n combineLatest([\n emittedStatusObservable(store$, 0),\n emittedStatusObservable(filter$, 1),\n ])\n .pipe(\n takeUntil(this.destroy),\n tap(([entities, filterStr]) => {\n if (emittedObservable.every((eo) => eo)) {\n // initial emission. This can be combined with the case immediately\n // below it. But we keep it separate for clarity.\n emittedObservable[0] = emittedObservable[1] = false;\n this.filterEntities(entities, filterStr);\n } else if (emittedObservable[0]) {\n emittedObservable[0] = false;\n this.filterEntities(entities, filterStr);\n } else {\n emittedObservable[1] = false;\n if (this.allEntitiesLoaded()) {\n this.filterEntities(entities, filterStr);\n } else {\n this.setSearchParamValue(filterStr);\n // This will cause an emission from store$ observable as the\n // 'forceRefresh=true' arg causes the store to be reset.\n this.loadNextPage(true);\n }\n }\n })\n )\n .subscribe();\n }\n\n ngOnDestroy(): void {\n this.destroy.next();\n this.destroy.complete();\n this.stopLoader();\n // this.removeFromCache();\n this.stateChanges.complete();\n }\n\n ngAfterViewInit(): void {\n // I'm not sure this is how this logic is right, but this seems to work.\n // if (this.ngControl && this.ngControl.control?.validator) {\n // const validator = this.ngControl.control.validator;\n // const res = validator(this.ngControl.control);\n // if (res && res['required']) {\n // this.required = true;\n // }\n // }\n // load first page\n // this.loadMoreEntities();\n }\n\n addEntity(entity: TEntity) {\n this.store.update(upsertEntities(entity));\n this.cdr.detectChanges();\n }\n\n get selectTriggerValue() {\n if (this.selectValue) {\n const firstSelected = Array.isArray(this.selectValue)\n ? this.selectValue[0]\n : this.selectValue;\n const selectedEntity = this.getEntity(\n firstSelected as TEntity[IdKey]\n );\n return selectedEntity ? this._entityLabelFn()(selectedEntity) : '';\n }\n return '';\n }\n\n get selectTriggerValueAsArray() {\n return Array.isArray(this.selectValue)\n ? (this.selectValue as Array<string | number>)\n : [];\n }\n\n entityId(entity: TEntity) {\n return (entity as any)[this.idKey()];\n }\n\n writeValue(entityId: string | number | string[] | number[]): void {\n const store = this.store;\n const entities = this.getEntities();\n if (Array.isArray(entityId)) {\n if (this.multiple()) {\n const selectedValues: any[] = [];\n entityId.forEach((id) => {\n if (store.query(hasEntity(id as TEntity[IdKey]))) {\n selectedValues.push(id);\n }\n });\n this.selectValue = selectedValues;\n this.cdr.detectChanges();\n }\n } else {\n if (store.query(hasEntity(entityId as TEntity[IdKey]))) {\n // if (this._entities.has(entityId)) {\n this.selectValue = entityId;\n if (this.filterStr) {\n this.filterStr = '';\n // this.filterNonGroupedEntities(entities, this.filterStr);\n }\n this.cdr.detectChanges();\n }\n }\n }\n\n registerOnChange(fn: any): void {\n this.onChanged = fn;\n }\n\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n @Input()\n get entities(): TEntity[] {\n return this.getEntities();\n }\n\n set entities(items: TEntity[]) {\n this.setEntities(items);\n }\n\n @Input()\n get value(): string | number | string[] | number[] {\n return this.selectValue;\n }\n set value(val: string | number | string[] | number[]) {\n this.selectValue = val;\n this.stateChanges.next();\n }\n get shouldLabelFloat() {\n return this.focused || !this.empty;\n }\n\n @Input('aria-describedby') userAriaDescribedBy!: string;\n\n @Input()\n get placeholder(): string {\n return this._placeholder;\n }\n set placeholder(value: string) {\n this._placeholder = value;\n this.stateChanges.next();\n }\n\n @Input()\n get required() {\n return (\n this._required ??\n this.ngControl?.control?.hasValidator(Validators.required)\n );\n }\n set required(req: boolean) {\n this._required = coerceBooleanProperty(req);\n this.stateChanges.next();\n }\n // Deliberately 'undefined' so that `get required()` will return the state\n // from ngControl's validators.\n private _required!: boolean;\n\n @Input()\n get disabled(): boolean {\n return this._disabled ?? this.ngControl?.control?.disabled;\n }\n set disabled(value: BooleanInput) {\n const disabled = coerceBooleanProperty(value);\n if (disabled !== this._disabled) {\n this.setDisabledState(disabled);\n this.stateChanges.next();\n }\n }\n // Same as `_required`, deliberately `undefined` by default.\n private _disabled!: boolean;\n\n get empty() {\n return !this.value;\n }\n\n get errorState(): boolean {\n return !!this.ngControl?.invalid && this.touched;\n }\n\n onFocusIn(event: FocusEvent) {\n if (!this.focused) {\n this.focused = true;\n this.stateChanges.next();\n }\n }\n\n onFocusOut(event: FocusEvent) {\n if (\n !this._elementRef.nativeElement.contains(event.relatedTarget as Element)\n ) {\n this.touched = true;\n this.focused = false;\n this.onTouched();\n this.stateChanges.next();\n }\n }\n\n setDescribedByIds(ids: string[]) {}\n\n onContainerClick(event: MouseEvent) {\n if ((event.target as Element).tagName.toLowerCase() != 'mat-select') {\n this._elementRef.nativeElement.querySelector('mat-select').focus();\n }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled = isDisabled;\n const matSelect = this.matSelect();\n if (matSelect) {\n matSelect.setDisabledState(isDisabled);\n this.cdr.detectChanges();\n }\n }\n\n onSelectOpened(ev: any) {\n // Store the current select value so that we can restore it if user\n // eventually selects 'New Item' option.\n this.lastSelectValue = this.selectValue;\n // If values have not been loaded from remote, trigger a load.\n if (this.totalEntitiesAtRemote() === 0) {\n // first load\n this.loadNextPage();\n }\n }\n\n onSelectionChange(ev: MatSelectChange) {\n // console.log('SelectionChange - sel:', ev);\n if (Array.isArray(ev.value)) {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n const selectedEntities: TEntity[] = ev.value.map((id) =>\n this.store.query(getEntity(id))\n ) as TEntity[];\n this.selectionChange.emit(selectedEntities);\n } else {\n if (ev.value !== '0') {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n this.selectionChange.emit(\n this.store.query(getEntity(ev.value))\n );\n } else {\n // New Item activated, return value to previous value. We track\n // previous value via 'lastSelectValue' member which is updated\n // whenever the select is opened.\n if (this.ngControl) {\n this.ngControl.control?.setValue(this.lastSelectValue);\n }\n ev.source.value = this.lastSelectValue;\n this.createNewItemSelected.emit();\n this.cdr.detectChanges();\n }\n }\n }\n\n /**\n * Wrapper to filter entities based on whether grouping is enabled or not.\n * Calls one of the two filtering methods -- filterGroupedEntities() or\n * filterNonGroupedEntities().\n * @param entities\n * @param filterStr\n * @returns\n */\n filterEntities(entities: TEntity[], filterStr: string) {\n this.searching = true;\n let retval: number | undefined;\n if (this._group()) {\n this.filterGroupedEntities(entities, filterStr);\n } else {\n this.filterNonGroupedEntities(entities, filterStr);\n }\n this.searching = false;\n }\n\n /**\n * Filters the entities based on the search string.\n * @param search The search string to filter entities.\n * @returns The number of entities in the filtered result set or undefined.\n */\n filterNonGroupedEntities(entities: TEntity[], search: string) {\n const searchLwr = search.toLocaleLowerCase();\n if (!search) {\n this.filteredValues.next(entities.slice());\n } else {\n const filteredEntities = entities.filter((member) => {\n const filterFn = this.filterFn();\n if (filterFn) {\n return filterFn(member, search);\n }\n const labelFn = this._entityLabelFn();\n return labelFn(member).toLocaleLowerCase().includes(searchLwr);\n });\n this.filteredValues.next(filteredEntities);\n }\n }\n\n /**\n * Filtering grouped entities logic works like this. If the search string\n * matches a group label, the entire group is to be included in the results.\n * However, if the search string only matches certain entities, only those\n * groups are to be included and within those groups, only entities whose\n * label matches the search string are to be included in the result set.\n * @param search\n * @returns number of groups in the filtered result set.\n */\n filterGroupedEntities(entities: TEntity[], search: string) {\n const searchLwr = search.toLocaleLowerCase();\n // First filter entities by the search string, if it's specified\n let filteredEntities: TEntity[];\n if (!search) {\n filteredEntities = entities;\n } else {\n filteredEntities = entities.filter((member) => {\n const filterFn = this.filterFn();\n if (filterFn) {\n return filterFn(member, search);\n }\n const labelFn = this._entityLabelFn();\n return labelFn(member).toLocaleLowerCase().includes(searchLwr);\n });\n }\n this.filteredGroupedValues.next(this.groupEntities(filteredEntities));\n }\n\n /**\n * Helper to arrange the given array of entities into groups based on the\n * groupByFn or groupOptionsKey. groupByFn takes precedence over\n * groupOptionsKey.\n * @param entities\n * @returns EntityGroup<TEntity>[]\n */\n protected groupEntities(entities: TEntity[]): EntityGroup<TEntity>[] {\n let groupByFn!: (entity: TEntity) => string;\n if (this.groupByFn()) {\n groupByFn = this.groupByFn()!;\n } else if (this.groupOptionsKey()) {\n groupByFn = (entity: TEntity) => {\n const key = this.groupOptionsKey()!;\n return (entity as any)[key] ?? '???';\n };\n }\n\n const groupedEntitiesMap = new Map<string | number, TEntity[]>();\n entities.forEach((entity) => {\n const groupId = groupByFn!(entity);\n if (!groupedEntitiesMap.has(groupId)) {\n groupedEntitiesMap.set(groupId, []);\n }\n groupedEntitiesMap.get(groupId)!.push(entity);\n });\n let entityGroups: EntityGroup<TEntity>[] = [];\n groupedEntitiesMap.forEach((entities, groupId) => {\n entityGroups.push({\n label: String(groupId),\n entities,\n });\n });\n return entityGroups;\n }\n\n // private existsInCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // return SPMatSelectEntityComponent._entitiesCache.has(cacheKey);\n // }\n // return false;\n // }\n\n // private getCacheKey() {\n // if (typeof this.url() !== 'function') {\n // let params!: HttpParams;\n // if (this.httpParams) {\n // params = new HttpParams({\n // fromString: this.httpParams.toString(),\n // });\n // } else {\n // params = new HttpParams();\n // }\n // // params = params.set('paginate', false)\n // return `${this.url}?${params.toString()}`;\n // }\n // return ''; // empty string evalutes to boolean(false)\n // }\n\n // private getFromCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n // return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)\n // ?.entities as TEntity[];\n // }\n // return [];\n // }\n\n // private addToCache(entities: TEntity[]) {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // if (!SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n // SPMatSelectEntityComponent._entitiesCache.set(cacheKey, {\n // refCount: 0,\n // entities,\n // });\n // }\n // const cacheEntry =\n // SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n // cacheEntry!.refCount += 1;\n // }\n // }\n\n // private removeFromCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // const cacheEntry =\n // SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n // if (cacheEntry) {\n // cacheEntry!.refCount -= 1;\n // if (cacheEntry.refCount <= 0) {\n // SPMatSelectEntityComponent._entitiesCache.delete(cacheKey);\n // }\n // }\n // }\n // }\n\n private getHttpReqContext() {\n const context = new HttpContext();\n const entityName = this.entityName;\n context.set(SP_MAT_SELECT_ENTITY_HTTP_CONTEXT, {\n entityName: this.entityName(),\n entityNamePlural: this._pluralEntityName(),\n endpoint: this.url() as string,\n });\n return context;\n }\n\n /**\n * If more entities are available, load the next page of entities.\n * This method is triggered when user scrolls to the bottom of the options\n * list. Well almost to the bottom of the options list. :)\n */\n onInfiniteScroll() {\n if (this.hasMore() && !this.loading()) {\n this.loadNextPage();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA2Ea,MAAA,iCAAiC,GAC5C,IAAI,gBAAgB,CAA+B,OAAO;AACxD,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,gBAAgB,EAAE,EAAE;AACpB,IAAA,QAAQ,EAAE,EAAE;AACb,CAAA,CAAC;AAeJ;AACA;AACA;AACA,MAAM,gBAAgB,CAAA;AACpB,IAAA,oBAAoB,CAClB,QAAgB,EAChB,IAAY,EACZ,QAAgB,EAAA;QAEhB,OAAO;YACL,IAAI,EAAE,IAAI,GAAG,CAAC;YACd,QAAQ;SACT;;IAGH,oBAAoB,CAIlB,UAAkB,EAClB,gBAAwB,EACxB,QAAgB,EAChB,MAAoB,EACpB,IAAS,EAAA;AAET,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACvB,OAAO;gBACL,KAAK,EAAE,IAAI,CAAC,MAAM;AAClB,gBAAA,QAAQ,EAAE,IAAI;aACf;;AAGH,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;AAM9B,YAAA,IACE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBAC/B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EACrC;gBACA,IAAI,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM;AACzC,gBAAA,IACE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;AACrB,oBAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ;oBAChC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,EACzC;oBACA,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;;gBAE/B,OAAO;oBACL,KAAK;AACL,oBAAA,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC;iBACjC;;;AAIH,YAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE;gBAC9D,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM;AAClC,gBAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE;AAC/D,oBAAA,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC;;gBAEvB,OAAO;oBACL,KAAK;AACL,oBAAA,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC;iBAC1B;;;AAIH,YAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE;gBAC1D,OAAO;AACL,oBAAA,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM;AAC3B,oBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC;iBACxB;;;QAIL,OAAO;AACL,YAAA,KAAK,EAAE,CAAC;AACR,YAAA,QAAQ,EAAE,EAAE;SACb;;AAEJ;AAED;;;;;;;;AAQG;AA+HG,MAAO,0BAIX,SAAQ,mBAAmC,CAAA;;;;;;;;;;;;;;;;;;;IA4B3C,OAAO,GAAG,KAAK,EAA+B;;;IAI9C,QAAQ,GAAG,KAAK,EAAgD;;;AAIhE,IAAA,SAAS,GAAG,KAAK,CAAU,KAAK,CAAC;;;AAIjC,IAAA,QAAQ,GAAG,KAAK,CAAU,KAAK,CAAC;AAEhC;;;;;AAKG;IACH,eAAe,GAAG,KAAK,EAAU;AAEjC;;;;;;AAMG;IACH,SAAS,GAAG,KAAK,EAA+B;AAEtC,IAAA,eAAe,GAAG,IAAI,YAAY,EAAuB;AACzD,IAAA,qBAAqB,GAAG,IAAI,YAAY,EAAQ;;;IAIjD,UAAU,GAAG,KAAK,EAAU;IAC5B,YAAY,GAAG,KAAK,EAAU;IAC9B,aAAa,GAAG,KAAK,EAAU;IAExC,WAAW,GAAG,sBAAsB;AAEpC;;;;;;;;;;;;;;;;;AAiBG;IACH,mBAAmB,GAAG,KAAK,EAAoB;;AAGrC,IAAA,cAAc,GAAG,QAAQ,CAA8B,MAAK;AACpE,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE;QACzB,IAAI,EAAE,EAAE;AACN,YAAA,OAAO,EAAE;;QAEX,OAAO,CAAC,MAAe,KAAI;AACzB,YAAA,QACG,MAAc,CAAC,MAAM,CAAC;gBACtB,MAAc,CAAC,OAAO,CAAC;gBACvB,MAAc,CAAC,OAAO,CAAC;gBACxB,MAAM,CAAE,MAAc,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AAEzC,SAAC;AACH,KAAC,CAAC;;;AAIQ,IAAA,MAAM,GAAG,QAAQ,CAAU,MAAK;AACxC,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE;AACvD,KAAC,CAAC;AAEQ,IAAA,iBAAiB,GAAG,QAAQ,CAAS,MAAK;AAClD,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE;AAC9C,QAAA,OAAO;AACL,cAAE;AACF,cAAE,IAAI,CAAC,UAAU;AACjB,kBAAE,IAAI,CAAC,iBAAiB;kBACtB,OAAO;AACb,KAAC,CAAC;;;;;;;;;;;;;AAgBF,IAAA,YAAY,GAAG,IAAI,OAAO,EAAQ;IAClC,OAAO,GAAG,KAAK;IACf,OAAO,GAAG,KAAK;AAEf,IAAA,WAAW;;;;;;;AAOX,IAAA,eAAe;IACf,SAAS,GAAG,KAAK;IACjB,SAAS,GAAW,EAAE;AAEtB,IAAA,OAAO,GAAG,IAAI,OAAO,EAAU;;AAG/B,IAAA,SAAS,GAAG,CAAC,CAAM,KAAI,GAAG;AAC1B,IAAA,SAAS,GAAG,MAAK,GAAG;;AAGpB,IAAA,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;AAEhC,IAAA,cAAc,GAAG,IAAI,OAAO,EAAa;AACzC,IAAA,qBAAqB,GAAG,IAAI,OAAO,EAA0B;AAE7D,IAAA,OAAO,GAAG,IAAI,OAAO,EAAQ;AAE7B,IAAA,OAAO,MAAM,GAAG,CAAC;AACF,IAAA,EAAE,GAAG,CAAoB,iBAAA,EAAA,0BAA0B,CAAC,MAAM,EAAE,EAAE;AACrE,IAAA,YAAY;;AAEV,IAAA,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAC/B,IAAA,WAAW,GAAG,MAAM,EAAC,UAAuB,EAAC;IAC7C,UAAU,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1D,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACxD,IAAA,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;;AAIpC,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AAC1B,YAAA,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI;;;AAIvC;;;;;;;;;AASG;IAEH,QAAQ,GAAA;;;;;;;;;;;;;QAaN,IAAI,CAAC,WAAW,EAAE;;;;AAKlB,QAAA,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAC/B,SAAS,CAAC,EAAE,CAAC,EACb,oBAAoB,EAAE,EACtB,YAAY,CAAC,GAAG,CAAC,CAClB;AAED,QAAA,MAAM,uBAAuB,GAAG,CAAC,GAAoB,EAAE,KAAa,KAClE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,iBAAiB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;;;;;;;;;;;;;;AAexD,QAAA,aAAa,CAAC;AACZ,YAAA,uBAAuB,CAAC,MAAM,EAAE,CAAC,CAAC;AAClC,YAAA,uBAAuB,CAAC,OAAO,EAAE,CAAC,CAAC;SACpC;AACE,aAAA,IAAI,CACH,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EACvB,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAI;AAC5B,YAAA,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;;;gBAGvC,iBAAiB,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK;AACnD,gBAAA,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC;;AACnC,iBAAA,IAAI,iBAAiB,CAAC,CAAC,CAAC,EAAE;AAC/B,gBAAA,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK;AAC5B,gBAAA,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC;;iBACnC;AACL,gBAAA,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK;AAC5B,gBAAA,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE;AAC5B,oBAAA,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC;;qBACnC;AACL,oBAAA,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC;;;AAGnC,oBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;;;AAG7B,SAAC,CAAC;AAEH,aAAA,SAAS,EAAE;;IAGhB,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACnB,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;QACvB,IAAI,CAAC,UAAU,EAAE;;AAEjB,QAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;;IAG9B,eAAe,GAAA;;;;;;;;;;;;AAaf,IAAA,SAAS,CAAC,MAAe,EAAA;QACvB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AACzC,QAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;AAG1B,IAAA,IAAI,kBAAkB,GAAA;AACpB,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW;AAClD,kBAAE,IAAI,CAAC,WAAW,CAAC,CAAC;AACpB,kBAAE,IAAI,CAAC,WAAW;YACpB,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CACnC,aAA+B,CAChC;AACD,YAAA,OAAO,cAAc,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE;;AAEpE,QAAA,OAAO,EAAE;;AAGX,IAAA,IAAI,yBAAyB,GAAA;AAC3B,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW;cAChC,IAAI,CAAC;cACN,EAAE;;AAGR,IAAA,QAAQ,CAAC,MAAe,EAAA;AACtB,QAAA,OAAQ,MAAc,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;;AAGtC,IAAA,UAAU,CAAC,QAA+C,EAAA;AACxD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;AACxB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;AACnC,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AAC3B,YAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;gBACnB,MAAM,cAAc,GAAU,EAAE;AAChC,gBAAA,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,KAAI;oBACtB,IAAI,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,EAAoB,CAAC,CAAC,EAAE;AAChD,wBAAA,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;;AAE3B,iBAAC,CAAC;AACF,gBAAA,IAAI,CAAC,WAAW,GAAG,cAAc;AACjC,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;aAErB;YACL,IAAI,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,QAA0B,CAAC,CAAC,EAAE;;AAEtD,gBAAA,IAAI,CAAC,WAAW,GAAG,QAAQ;AAC3B,gBAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,oBAAA,IAAI,CAAC,SAAS,GAAG,EAAE;;;AAGrB,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;;AAK9B,IAAA,gBAAgB,CAAC,EAAO,EAAA;AACtB,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;;AAGrB,IAAA,iBAAiB,CAAC,EAAO,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;;AAGrB,IAAA,IACI,QAAQ,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE;;IAG3B,IAAI,QAAQ,CAAC,KAAgB,EAAA;AAC3B,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;;AAGzB,IAAA,IACI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,WAAW;;IAEzB,IAAI,KAAK,CAAC,GAA0C,EAAA;AAClD,QAAA,IAAI,CAAC,WAAW,GAAG,GAAG;AACtB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;AAE1B,IAAA,IAAI,gBAAgB,GAAA;QAClB,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK;;AAGT,IAAA,mBAAmB;AAE9C,IAAA,IACI,WAAW,GAAA;QACb,OAAO,IAAI,CAAC,YAAY;;IAE1B,IAAI,WAAW,CAAC,KAAa,EAAA;AAC3B,QAAA,IAAI,CAAC,YAAY,GAAG,KAAK;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;AAG1B,IAAA,IACI,QAAQ,GAAA;QACV,QACE,IAAI,CAAC,SAAS;AACd,YAAA,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;;IAG9D,IAAI,QAAQ,CAAC,GAAY,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC,GAAG,CAAC;AAC3C,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;;AAIlB,IAAA,SAAS;AAEjB,IAAA,IACI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ;;IAE5D,IAAI,QAAQ,CAAC,KAAmB,EAAA;AAC9B,QAAA,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC;AAC7C,QAAA,IAAI,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;AAC/B,YAAA,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AAC/B,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;;AAIpB,IAAA,SAAS;AAEjB,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,CAAC,IAAI,CAAC,KAAK;;AAGpB,IAAA,IAAI,UAAU,GAAA;QACZ,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO;;AAGlD,IAAA,SAAS,CAAC,KAAiB,EAAA;AACzB,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;AAI5B,IAAA,UAAU,CAAC,KAAiB,EAAA;AAC1B,QAAA,IACE,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAwB,CAAC,EACxE;AACA,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,YAAA,IAAI,CAAC,OAAO,GAAG,KAAK;YACpB,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;IAI5B,iBAAiB,CAAC,GAAa,EAAA;AAE/B,IAAA,gBAAgB,CAAC,KAAiB,EAAA;QAChC,IAAK,KAAK,CAAC,MAAkB,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,YAAY,EAAE;AACnE,YAAA,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,KAAK,EAAE;;;AAItE,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,SAAS,GAAG,UAAU;AAC3B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;QAClC,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,gBAAgB,CAAC,UAAU,CAAC;AACtC,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;AAI5B,IAAA,cAAc,CAAC,EAAO,EAAA;;;AAGpB,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,WAAW;;AAEvC,QAAA,IAAI,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAC,EAAE;;YAEtC,IAAI,CAAC,YAAY,EAAE;;;AAIvB,IAAA,iBAAiB,CAAC,EAAmB,EAAA;;QAEnC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAC3B,YAAA,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,KAAK;YAC3B,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC;YACxB,MAAM,gBAAgB,GAAc,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,KAClD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CACnB;AACd,YAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC;;aACtC;AACL,YAAA,IAAI,EAAE,CAAC,KAAK,KAAK,GAAG,EAAE;AACpB,gBAAA,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,KAAK;gBAC3B,IAAI,CAAC,SAAS,EAAE;AAChB,gBAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC;AACxB,gBAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CACtC;;iBACI;;;;AAIL,gBAAA,IAAI,IAAI,CAAC,SAAS,EAAE;oBAClB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC;;gBAExD,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe;AACtC,gBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE;AACjC,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;;AAK9B;;;;;;;AAOG;IACH,cAAc,CAAC,QAAmB,EAAE,SAAiB,EAAA;AACnD,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,IAAI,MAA0B;AAC9B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;AACjB,YAAA,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC;;aAC1C;AACL,YAAA,IAAI,CAAC,wBAAwB,CAAC,QAAQ,EAAE,SAAS,CAAC;;AAEpD,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;;AAGxB;;;;AAIG;IACH,wBAAwB,CAAC,QAAmB,EAAE,MAAc,EAAA;AAC1D,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,EAAE;QAC5C,IAAI,CAAC,MAAM,EAAE;YACX,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;;aACrC;YACL,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,KAAI;AAClD,gBAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE;gBAChC,IAAI,QAAQ,EAAE;AACZ,oBAAA,OAAO,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;;AAEjC,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;AACrC,gBAAA,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;AAChE,aAAC,CAAC;AACF,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC;;;AAI9C;;;;;;;;AAQG;IACH,qBAAqB,CAAC,QAAmB,EAAE,MAAc,EAAA;AACvD,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,EAAE;;AAE5C,QAAA,IAAI,gBAA2B;QAC/B,IAAI,CAAC,MAAM,EAAE;YACX,gBAAgB,GAAG,QAAQ;;aACtB;YACL,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,KAAI;AAC5C,gBAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE;gBAChC,IAAI,QAAQ,EAAE;AACZ,oBAAA,OAAO,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;;AAEjC,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;AACrC,gBAAA,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;AAChE,aAAC,CAAC;;AAEJ,QAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;;AAGvE;;;;;;AAMG;AACO,IAAA,aAAa,CAAC,QAAmB,EAAA;AACzC,QAAA,IAAI,SAAuC;AAC3C,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;AACpB,YAAA,SAAS,GAAG,IAAI,CAAC,SAAS,EAAG;;AACxB,aAAA,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE;AACjC,YAAA,SAAS,GAAG,CAAC,MAAe,KAAI;AAC9B,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,EAAG;AACnC,gBAAA,OAAQ,MAAc,CAAC,GAAG,CAAC,IAAI,KAAK;AACtC,aAAC;;AAGH,QAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA8B;AAChE,QAAA,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,KAAI;AAC1B,YAAA,MAAM,OAAO,GAAG,SAAU,CAAC,MAAM,CAAC;YAClC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;AACpC,gBAAA,kBAAkB,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;;YAErC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AAC/C,SAAC,CAAC;QACF,IAAI,YAAY,GAA2B,EAAE;QAC7C,kBAAkB,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,OAAO,KAAI;YAC/C,YAAY,CAAC,IAAI,CAAC;AAChB,gBAAA,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC;gBACtB,QAAQ;AACT,aAAA,CAAC;AACJ,SAAC,CAAC;AACF,QAAA,OAAO,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiEb,iBAAiB,GAAA;AACvB,QAAA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE;AACjC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU;AAClC,QAAA,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE;AAC7C,YAAA,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;AAC7B,YAAA,gBAAgB,EAAE,IAAI,CAAC,iBAAiB,EAAE;AAC1C,YAAA,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAY;AAC/B,SAAA,CAAC;AACF,QAAA,OAAO,OAAO;;AAGhB;;;;AAIG;IACH,gBAAgB,GAAA;QACd,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE;YACrC,IAAI,CAAC,YAAY,EAAE;;;0HA/qBZ,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA1B,uBAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,0BAA0B,EAL1B,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,mBAAA,EAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,mBAAA,EAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,SAAA,EAAA,EAAA,EAAA,SAAA,EAAA;YACT,qBAAqB,CAAC,sBAAsB,CAAC;AAC7C,YAAA,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,0BAA0B,EAAE;AAC1E,SAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAmKqB,SAAS,EA7RrB,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6FT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,kIAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAeC,YAAY,EAEZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,IAAA,EAAA,OAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,WAAW,EACX,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,mBAAmB,8BACnB,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,eAAA,EAAA,UAAA,EAAA,8BAAA,EAAA,aAAA,EAAA,UAAA,EAAA,UAAA,EAAA,wBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,2BAAA,EAAA,gBAAA,EAAA,IAAA,EAAA,YAAA,EAAA,0BAAA,CAAA,EAAA,OAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,IAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,WAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACf,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACf,aAAa,EACb,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,EACf,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,wBAAwB,6oBACxB,gCAAgC,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,cAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAOvB,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBA9HtC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sBAAsB,EACtB,QAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FT,EAagB,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACtC,OAAA,EAAA;wBACP,YAAY;wBACZ,gBAAgB;wBAChB,WAAW;wBACX,mBAAmB;wBACnB,eAAe;wBACf,eAAe;wBACf,aAAa;wBACb,eAAe;wBACf,wBAAwB;wBACxB,gCAAgC;qBACjC,EACU,SAAA,EAAA;wBACT,qBAAqB,CAAC,sBAAsB,CAAC;AAC7C,wBAAA,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,4BAA4B,EAAE;AAC1E,qBAAA,EAAA,MAAA,EAAA,CAAA,kIAAA,CAAA,EAAA;wDAiES,eAAe,EAAA,CAAA;sBAAxB;gBACS,qBAAqB,EAAA,CAAA;sBAA9B;gBAyGc,EAAE,EAAA,CAAA;sBAAhB;gBA2LG,QAAQ,EAAA,CAAA;sBADX;gBAUG,KAAK,EAAA,CAAA;sBADR;gBAY0B,mBAAmB,EAAA,CAAA;sBAA7C,KAAK;uBAAC,kBAAkB;gBAGrB,WAAW,EAAA,CAAA;sBADd;gBAUG,QAAQ,EAAA,CAAA;sBADX;gBAgBG,QAAQ,EAAA,CAAA;sBADX;;;AC7sBH;;AAEG;;;;"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Injectable, EventEmitter, Directive, Input, Output } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/material/select';
|
|
4
|
+
import { Subject, fromEvent } from 'rxjs';
|
|
5
|
+
import { takeUntil, debounceTime, tap, delay } from 'rxjs/operators';
|
|
6
|
+
|
|
7
|
+
class MatSelectInfiniteScrollService {
|
|
8
|
+
ngZone;
|
|
9
|
+
threshold = '15%';
|
|
10
|
+
debounceTime = 150;
|
|
11
|
+
complete;
|
|
12
|
+
thrPx = 0;
|
|
13
|
+
thrPc = 0;
|
|
14
|
+
destroyed$ = new Subject();
|
|
15
|
+
selectItemHeightPx;
|
|
16
|
+
panel;
|
|
17
|
+
constructor(ngZone) {
|
|
18
|
+
this.ngZone = ngZone;
|
|
19
|
+
}
|
|
20
|
+
initialize(panel, selectItemHeightPx, config) {
|
|
21
|
+
this.threshold = config.threshold;
|
|
22
|
+
this.debounceTime = config.debounceTime;
|
|
23
|
+
this.complete = config.complete;
|
|
24
|
+
this.panel = panel;
|
|
25
|
+
this.selectItemHeightPx = selectItemHeightPx;
|
|
26
|
+
this.evaluateThreshold();
|
|
27
|
+
}
|
|
28
|
+
evaluateThreshold() {
|
|
29
|
+
if (this.threshold.lastIndexOf('%') > -1) {
|
|
30
|
+
this.thrPx = 0;
|
|
31
|
+
this.thrPc = parseFloat(this.threshold) / 100;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.thrPx = parseFloat(this.threshold);
|
|
35
|
+
this.thrPc = 0;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
registerScrollListener(infiniteScrollCallback) {
|
|
39
|
+
fromEvent(this.panel, 'scroll')
|
|
40
|
+
.pipe(takeUntil(this.destroyed$), debounceTime(this.debounceTime), tap((event) => {
|
|
41
|
+
this.handleScrollEvent(event, infiniteScrollCallback);
|
|
42
|
+
}))
|
|
43
|
+
.subscribe();
|
|
44
|
+
}
|
|
45
|
+
handleScrollEvent(event, infiniteScrollCallback) {
|
|
46
|
+
if (this.complete || !event.target) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.ngZone.runOutsideAngular(() => {
|
|
50
|
+
const countOfRenderedOptions = Math.round(this.panel.scrollHeight / this.selectItemHeightPx);
|
|
51
|
+
const infiniteScrollDistance = this.selectItemHeightPx * countOfRenderedOptions;
|
|
52
|
+
const threshold = this.thrPc !== 0 ? infiniteScrollDistance * this.thrPc : this.thrPx;
|
|
53
|
+
const scrolledDistance = this.panel.clientHeight + event.target.scrollTop;
|
|
54
|
+
if (scrolledDistance + threshold >= infiniteScrollDistance) {
|
|
55
|
+
this.ngZone.run(infiniteScrollCallback);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
destroy() {
|
|
60
|
+
this.destroyed$.next();
|
|
61
|
+
this.destroyed$.complete();
|
|
62
|
+
}
|
|
63
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: MatSelectInfiniteScrollService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
64
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: MatSelectInfiniteScrollService, providedIn: 'root' });
|
|
65
|
+
}
|
|
66
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: MatSelectInfiniteScrollService, decorators: [{
|
|
67
|
+
type: Injectable,
|
|
68
|
+
args: [{
|
|
69
|
+
providedIn: 'root',
|
|
70
|
+
}]
|
|
71
|
+
}], ctorParameters: () => [{ type: i0.NgZone }] });
|
|
72
|
+
|
|
73
|
+
/** The height of the select items in `em` units. */
|
|
74
|
+
const SELECT_ITEM_HEIGHT_EM = 3;
|
|
75
|
+
class MatSelectInfiniteScrollDirective {
|
|
76
|
+
matSelect;
|
|
77
|
+
infiniteScrollService;
|
|
78
|
+
threshold = '15%';
|
|
79
|
+
debounceTime = 150;
|
|
80
|
+
complete;
|
|
81
|
+
infiniteScroll = new EventEmitter();
|
|
82
|
+
destroyed$ = new Subject();
|
|
83
|
+
constructor(matSelect, infiniteScrollService) {
|
|
84
|
+
this.matSelect = matSelect;
|
|
85
|
+
this.infiniteScrollService = infiniteScrollService;
|
|
86
|
+
}
|
|
87
|
+
ngAfterViewInit() {
|
|
88
|
+
this.matSelect.openedChange
|
|
89
|
+
.pipe(
|
|
90
|
+
//Wait for the panel to be rendered (https://github.com/angular/components/issues/30596)
|
|
91
|
+
delay(0), takeUntil(this.destroyed$))
|
|
92
|
+
.subscribe((opened) => {
|
|
93
|
+
if (opened) {
|
|
94
|
+
const panel = this.matSelect.panel.nativeElement;
|
|
95
|
+
const selectItemHeightPx = this.getSelectItemHeightPx(panel);
|
|
96
|
+
this.infiniteScrollService.initialize(panel, selectItemHeightPx, {
|
|
97
|
+
threshold: this.threshold,
|
|
98
|
+
debounceTime: this.debounceTime,
|
|
99
|
+
complete: this.complete,
|
|
100
|
+
});
|
|
101
|
+
this.infiniteScrollService.registerScrollListener(() => this.infiniteScroll.emit());
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
getSelectItemHeightPx(panel) {
|
|
106
|
+
return parseFloat(getComputedStyle(panel).fontSize) * SELECT_ITEM_HEIGHT_EM;
|
|
107
|
+
}
|
|
108
|
+
ngOnDestroy() {
|
|
109
|
+
this.destroyed$.next(true);
|
|
110
|
+
this.destroyed$.complete();
|
|
111
|
+
this.infiniteScrollService.destroy();
|
|
112
|
+
}
|
|
113
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: MatSelectInfiniteScrollDirective, deps: [{ token: i1.MatSelect }, { token: MatSelectInfiniteScrollService }], target: i0.ɵɵFactoryTarget.Directive });
|
|
114
|
+
/** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.6", type: MatSelectInfiniteScrollDirective, isStandalone: true, selector: "[msInfiniteScroll]", inputs: { threshold: "threshold", debounceTime: "debounceTime", complete: "complete" }, outputs: { infiniteScroll: "infiniteScroll" }, providers: [MatSelectInfiniteScrollService], ngImport: i0 });
|
|
115
|
+
}
|
|
116
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: MatSelectInfiniteScrollDirective, decorators: [{
|
|
117
|
+
type: Directive,
|
|
118
|
+
args: [{
|
|
119
|
+
selector: '[msInfiniteScroll]',
|
|
120
|
+
providers: [MatSelectInfiniteScrollService],
|
|
121
|
+
standalone: true,
|
|
122
|
+
}]
|
|
123
|
+
}], ctorParameters: () => [{ type: i1.MatSelect }, { type: MatSelectInfiniteScrollService }], propDecorators: { threshold: [{
|
|
124
|
+
type: Input
|
|
125
|
+
}], debounceTime: [{
|
|
126
|
+
type: Input
|
|
127
|
+
}], complete: [{
|
|
128
|
+
type: Input
|
|
129
|
+
}], infiniteScroll: [{
|
|
130
|
+
type: Output
|
|
131
|
+
}] } });
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Generated bundle index. Do not edit.
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
export { MatSelectInfiniteScrollDirective, MatSelectInfiniteScrollService };
|
|
138
|
+
//# sourceMappingURL=smallpearl-ngx-helper-mat-select-infinite-scroll.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smallpearl-ngx-helper-mat-select-infinite-scroll.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-select-infinite-scroll/src/mat-select-infinite-scroll.service.ts","../../../../projects/smallpearl/ngx-helper/mat-select-infinite-scroll/src/mat-select-infinite-scroll.directive.ts","../../../../projects/smallpearl/ngx-helper/mat-select-infinite-scroll/smallpearl-ngx-helper-mat-select-infinite-scroll.ts"],"sourcesContent":["import { Injectable, NgZone } from '@angular/core';\nimport { fromEvent, Subject } from 'rxjs';\nimport { debounceTime, takeUntil, tap } from 'rxjs/operators';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class MatSelectInfiniteScrollService {\n private threshold = '15%';\n private debounceTime = 150;\n private complete!: boolean;\n private thrPx = 0;\n private thrPc = 0;\n private destroyed$ = new Subject<void>();\n private selectItemHeightPx!: number;\n private panel!: Element;\n\n constructor(private ngZone: NgZone) {}\n\n initialize(\n panel: Element,\n selectItemHeightPx: number,\n config: {\n threshold: string;\n debounceTime: number;\n complete: boolean;\n }\n ) {\n this.threshold = config.threshold;\n this.debounceTime = config.debounceTime;\n this.complete = config.complete;\n\n this.panel = panel;\n this.selectItemHeightPx = selectItemHeightPx;\n this.evaluateThreshold();\n }\n\n evaluateThreshold() {\n if (this.threshold.lastIndexOf('%') > -1) {\n this.thrPx = 0;\n this.thrPc = parseFloat(this.threshold) / 100;\n } else {\n this.thrPx = parseFloat(this.threshold);\n this.thrPc = 0;\n }\n }\n\n registerScrollListener(infiniteScrollCallback: () => void) {\n fromEvent(this.panel, 'scroll')\n .pipe(\n takeUntil(this.destroyed$),\n debounceTime(this.debounceTime),\n tap((event) => {\n this.handleScrollEvent(event, infiniteScrollCallback);\n })\n )\n .subscribe();\n }\n\n handleScrollEvent(event: Event, infiniteScrollCallback: () => void) {\n if (this.complete || !event.target) {\n return;\n }\n\n this.ngZone.runOutsideAngular(() => {\n const countOfRenderedOptions = Math.round(\n this.panel.scrollHeight / this.selectItemHeightPx\n );\n const infiniteScrollDistance =\n this.selectItemHeightPx * countOfRenderedOptions;\n const threshold =\n this.thrPc !== 0 ? infiniteScrollDistance * this.thrPc : this.thrPx;\n\n const scrolledDistance =\n this.panel.clientHeight + (event.target as HTMLElement).scrollTop;\n\n if (scrolledDistance + threshold >= infiniteScrollDistance) {\n this.ngZone.run(infiniteScrollCallback);\n }\n });\n }\n\n destroy() {\n this.destroyed$.next();\n this.destroyed$.complete();\n }\n}\n","import {\n AfterViewInit,\n Directive,\n EventEmitter,\n Input,\n OnDestroy,\n Output\n} from '@angular/core';\nimport { MatSelect } from '@angular/material/select';\nimport { Subject } from 'rxjs';\nimport { delay, takeUntil } from 'rxjs/operators';\nimport { MatSelectInfiniteScrollService } from './mat-select-infinite-scroll.service';\n\n/** The height of the select items in `em` units. */\nconst SELECT_ITEM_HEIGHT_EM = 3;\n\n@Directive({\n selector: '[msInfiniteScroll]',\n providers: [MatSelectInfiniteScrollService],\n standalone: true,\n})\nexport class MatSelectInfiniteScrollDirective\n implements OnDestroy, AfterViewInit\n{\n @Input() threshold = '15%';\n @Input() debounceTime = 150;\n @Input() complete!: boolean;\n @Output() infiniteScroll = new EventEmitter<void>();\n\n private destroyed$ = new Subject<boolean>();\n\n constructor(\n protected matSelect: MatSelect,\n private infiniteScrollService: MatSelectInfiniteScrollService\n ) {}\n\n ngAfterViewInit() {\n this.matSelect.openedChange\n .pipe(\n //Wait for the panel to be rendered (https://github.com/angular/components/issues/30596)\n delay(0),\n takeUntil(this.destroyed$)\n )\n .subscribe((opened) => {\n if (opened) {\n const panel = this.matSelect.panel.nativeElement;\n const selectItemHeightPx = this.getSelectItemHeightPx(panel);\n this.infiniteScrollService.initialize(panel, selectItemHeightPx, {\n threshold: this.threshold,\n debounceTime: this.debounceTime,\n complete: this.complete,\n });\n\n this.infiniteScrollService.registerScrollListener(() =>\n this.infiniteScroll.emit()\n );\n }\n });\n }\n\n getSelectItemHeightPx(panel: Element): number {\n return parseFloat(getComputedStyle(panel).fontSize) * SELECT_ITEM_HEIGHT_EM;\n }\n\n ngOnDestroy() {\n this.destroyed$.next(true);\n this.destroyed$.complete();\n\n this.infiniteScrollService.destroy();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i2.MatSelectInfiniteScrollService"],"mappings":";;;;;;MAOa,8BAA8B,CAAA;AAUrB,IAAA,MAAA;IATZ,SAAS,GAAG,KAAK;IACjB,YAAY,GAAG,GAAG;AAClB,IAAA,QAAQ;IACR,KAAK,GAAG,CAAC;IACT,KAAK,GAAG,CAAC;AACT,IAAA,UAAU,GAAG,IAAI,OAAO,EAAQ;AAChC,IAAA,kBAAkB;AAClB,IAAA,KAAK;AAEb,IAAA,WAAA,CAAoB,MAAc,EAAA;QAAd,IAAM,CAAA,MAAA,GAAN,MAAM;;AAE1B,IAAA,UAAU,CACR,KAAc,EACd,kBAA0B,EAC1B,MAIC,EAAA;AAED,QAAA,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS;AACjC,QAAA,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY;AACvC,QAAA,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ;AAE/B,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,kBAAkB,GAAG,kBAAkB;QAC5C,IAAI,CAAC,iBAAiB,EAAE;;IAG1B,iBAAiB,GAAA;AACf,QAAA,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;AACxC,YAAA,IAAI,CAAC,KAAK,GAAG,CAAC;YACd,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG;;aACxC;YACL,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;AACvC,YAAA,IAAI,CAAC,KAAK,GAAG,CAAC;;;AAIlB,IAAA,sBAAsB,CAAC,sBAAkC,EAAA;AACvD,QAAA,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ;aAC3B,IAAI,CACH,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,EAC1B,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,EAC/B,GAAG,CAAC,CAAC,KAAK,KAAI;AACZ,YAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,CAAC;AACvD,SAAC,CAAC;AAEH,aAAA,SAAS,EAAE;;IAGhB,iBAAiB,CAAC,KAAY,EAAE,sBAAkC,EAAA;QAChE,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAClC;;AAGF,QAAA,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAK;AACjC,YAAA,MAAM,sBAAsB,GAAG,IAAI,CAAC,KAAK,CACvC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAClD;AACD,YAAA,MAAM,sBAAsB,GAC1B,IAAI,CAAC,kBAAkB,GAAG,sBAAsB;YAClD,MAAM,SAAS,GACb,IAAI,CAAC,KAAK,KAAK,CAAC,GAAG,sBAAsB,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;AAErE,YAAA,MAAM,gBAAgB,GACpB,IAAI,CAAC,KAAK,CAAC,YAAY,GAAI,KAAK,CAAC,MAAsB,CAAC,SAAS;AAEnE,YAAA,IAAI,gBAAgB,GAAG,SAAS,IAAI,sBAAsB,EAAE;AAC1D,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC;;AAE3C,SAAC,CAAC;;IAGJ,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE;AACtB,QAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE;;0HA7EjB,8BAA8B,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,MAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAA9B,uBAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,8BAA8B,cAF7B,MAAM,EAAA,CAAA;;2FAEP,8BAA8B,EAAA,UAAA,EAAA,CAAA;kBAH1C,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACOD;AACA,MAAM,qBAAqB,GAAG,CAAC;MAOlB,gCAAgC,CAAA;AAW/B,IAAA,SAAA;AACF,IAAA,qBAAA;IATD,SAAS,GAAG,KAAK;IACjB,YAAY,GAAG,GAAG;AAClB,IAAA,QAAQ;AACP,IAAA,cAAc,GAAG,IAAI,YAAY,EAAQ;AAE3C,IAAA,UAAU,GAAG,IAAI,OAAO,EAAW;IAE3C,WACY,CAAA,SAAoB,EACtB,qBAAqD,EAAA;QADnD,IAAS,CAAA,SAAA,GAAT,SAAS;QACX,IAAqB,CAAA,qBAAA,GAArB,qBAAqB;;IAG/B,eAAe,GAAA;QACb,IAAI,CAAC,SAAS,CAAC;aACZ,IAAI;;QAEH,KAAK,CAAC,CAAC,CAAC,EACR,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;AAE3B,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;YACpB,IAAI,MAAM,EAAE;gBACV,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa;gBAChD,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC;gBAC5D,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,KAAK,EAAE,kBAAkB,EAAE;oBAC/D,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;AACxB,iBAAA,CAAC;AAEF,gBAAA,IAAI,CAAC,qBAAqB,CAAC,sBAAsB,CAAC,MAChD,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAC3B;;AAEL,SAAC,CAAC;;AAGN,IAAA,qBAAqB,CAAC,KAAc,EAAA;QAClC,OAAO,UAAU,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,qBAAqB;;IAG7E,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE;AAE1B,QAAA,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE;;0HA/C3B,gCAAgC,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,SAAA,EAAA,EAAA,EAAA,KAAA,EAAAA,8BAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;8GAAhC,gCAAgC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,YAAA,EAAA,cAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,EAAA,SAAA,EAHhC,CAAC,8BAA8B,CAAC,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAGhC,gCAAgC,EAAA,UAAA,EAAA,CAAA;kBAL5C,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;oBAC9B,SAAS,EAAE,CAAC,8BAA8B,CAAC;AAC3C,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;wHAIU,SAAS,EAAA,CAAA;sBAAjB;gBACQ,YAAY,EAAA,CAAA;sBAApB;gBACQ,QAAQ,EAAA,CAAA;sBAAhB;gBACS,cAAc,EAAA,CAAA;sBAAvB;;;AC3BH;;AAEG;;;;"}
|
|
@@ -23,7 +23,69 @@ export type SPPageParams = {
|
|
|
23
23
|
* SPMatEntityListPaginator class is provided to the component.
|
|
24
24
|
*/
|
|
25
25
|
export interface SPMatEntityListPaginator {
|
|
26
|
+
/**
|
|
27
|
+
* Return the HTTP request params for the given page index and page size as
|
|
28
|
+
* an object. For example, for a REST API that supports 'skip' and 'top' params,
|
|
29
|
+
* the implementation would be:
|
|
30
|
+
*
|
|
31
|
+
* ```typescript
|
|
32
|
+
* getRequestPageParams(endpoint: string, pageIndex: number, pageSize: number): SPPageParams {
|
|
33
|
+
* return {
|
|
34
|
+
* skip: pageIndex * pageSize,
|
|
35
|
+
* top: pageSize
|
|
36
|
+
* };
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
* @param endpoint
|
|
40
|
+
* @param pageIndex
|
|
41
|
+
* @param pageSize
|
|
42
|
+
* @returns
|
|
43
|
+
*/
|
|
26
44
|
getRequestPageParams: (endpoint: string, pageIndex: number, pageSize: number) => SPPageParams;
|
|
45
|
+
/**
|
|
46
|
+
* Parse the HTTP response received from the GET request and return an object
|
|
47
|
+
* containing the total number of entities available and the array of entities
|
|
48
|
+
* for the current page. For example, for the pure DRF paginated response
|
|
49
|
+
* like below:
|
|
50
|
+
* ```json
|
|
51
|
+
* {
|
|
52
|
+
* "count": 102,
|
|
53
|
+
* "next": "http://api.example.org/entities/?page=3",
|
|
54
|
+
* "previous": "http://api.example.org/entities/?page=1",
|
|
55
|
+
* "results": [
|
|
56
|
+
* {
|
|
57
|
+
* "id": 1,
|
|
58
|
+
* "name": "Entity 1"
|
|
59
|
+
* },
|
|
60
|
+
* {
|
|
61
|
+
* "id": 2,
|
|
62
|
+
* "name": "Entity 2"
|
|
63
|
+
* }
|
|
64
|
+
* ]
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
* The implementation would be:
|
|
68
|
+
* ```typescript
|
|
69
|
+
* parseRequestResponse<TEntity extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'>(
|
|
70
|
+
* entityName: string,
|
|
71
|
+
* entityNamePlural: string,
|
|
72
|
+
* endpoint: string,
|
|
73
|
+
* params: SPPageParams,
|
|
74
|
+
* resp: any
|
|
75
|
+
* ): { total: number; entities: TEntity[] } {
|
|
76
|
+
* return {
|
|
77
|
+
* total: resp.count,
|
|
78
|
+
* entities: resp.results
|
|
79
|
+
* };
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
* @param entityName
|
|
83
|
+
* @param entityNamePlural
|
|
84
|
+
* @param endpoint
|
|
85
|
+
* @param params
|
|
86
|
+
* @param resp
|
|
87
|
+
* @returns
|
|
88
|
+
*/
|
|
27
89
|
parseRequestResponse: <TEntity extends {
|
|
28
90
|
[P in IdKey]: PropertyKey;
|
|
29
91
|
}, IdKey extends string = 'id'>(entityName: string, entityNamePlural: string, endpoint: string, params: SPPageParams, resp: any) => {
|