@mintplayer/ng-spark 22.0.1 → 22.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-query-list.mjs","sources":["../../query-list/src/spark-query-list.component.ts","../../query-list/src/spark-query-list.component.html","../../query-list/mintplayer-ng-spark-query-list.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, input, output, signal, TemplateRef, Type } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Subscription } from 'rxjs';\nimport { CommonModule, NgTemplateOutlet, NgComponentOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { ActivatedRoute, Router, RouterModule } from '@angular/router';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsDatatableComponent, BsDatatableColumnDirective, BsRowTemplateDirective, DatatableSettings, type BsDatatableFetch } from '@mintplayer/ng-bootstrap/datatable';\nimport { BsFormComponent, BsFormControlDirective } from '@mintplayer/ng-bootstrap/form';\nimport { BsGridComponent, BsGridRowDirective, BsGridColumnDirective } from '@mintplayer/ng-bootstrap/grid';\nimport { BsInputGroupComponent } from '@mintplayer/ng-bootstrap/input-group';\nimport { BsPriorityNavComponent, BsPriorityNavItemDirective } from '@mintplayer/ng-bootstrap/priority-nav';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { SortColumn } from '@mintplayer/pagination';\nimport { SparkService, SparkStreamingService, SparkLanguageService } from '@mintplayer/ng-spark/services';\nimport {\n TranslateKeyPipe,\n ResolveTranslationPipe,\n AttributeValuePipe,\n} from '@mintplayer/ng-spark/pipes';\nimport { SparkIconComponent } from '@mintplayer/ng-spark/icon';\nimport { SPARK_ATTRIBUTE_RENDERERS } from '@mintplayer/ng-spark/renderers';\nimport {\n CustomActionDefinition,\n StreamingMessage,\n EntityType,\n EntityAttributeDefinition,\n LookupReference,\n PersistentObject,\n SparkQuery,\n ShowedOn,\n hasShowedOnFlag,\n} from '@mintplayer/ng-spark/models';\n\n@Component({\n selector: 'spark-query-list',\n imports: [CommonModule, NgTemplateOutlet, NgComponentOutlet, FormsModule, RouterModule, BsAlertComponent, BsDatatableComponent, BsDatatableColumnDirective, BsRowTemplateDirective, BsFormComponent, BsFormControlDirective, BsGridComponent, BsGridRowDirective, BsGridColumnDirective, BsInputGroupComponent, BsPriorityNavComponent, BsPriorityNavItemDirective, BsSpinnerComponent, SparkIconComponent, ResolveTranslationPipe, TranslateKeyPipe, AttributeValuePipe],\n templateUrl: './spark-query-list.component.html',\n styleUrl: './spark-query-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.virtual-scrolling]': 'isVirtualScrolling()'\n }\n})\nexport class SparkQueryListComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly sparkService = inject(SparkService);\n private readonly streamingService = inject(SparkStreamingService);\n protected readonly lang = inject(SparkLanguageService);\n private readonly rendererRegistry = inject(SPARK_ATTRIBUTE_RENDERERS);\n private readonly destroyRef = inject(DestroyRef);\n\n extraActionsTemplate = input<TemplateRef<void> | null>(null);\n showCustomActions = input(true);\n\n rowClicked = output<PersistentObject>();\n createClicked = output<void>();\n customActionExecuted = output<{ action: CustomActionDefinition }>();\n\n colors = Color;\n errorMessage = signal<string | null>(null);\n query = signal<SparkQuery | null>(null);\n entityType = signal<EntityType | null>(null);\n allEntityTypes = signal<EntityType[]>([]);\n lookupReferenceOptions = signal<Record<string, LookupReference>>({});\n resultCount = signal<number | null>(null);\n searchTerm: string = '';\n canRead = signal(false);\n canCreate = signal(false);\n customActions = signal<CustomActionDefinition[]>([]);\n isStreaming = signal(false);\n private streamingSub: Subscription | null = null;\n private allItems = signal<PersistentObject[]>([]);\n streamItems = signal<PersistentObject[]>([]);\n fetchFn = signal<BsDatatableFetch<PersistentObject> | null>(null);\n settings = signal(new DatatableSettings({\n perPage: { values: [10, 25, 50], selected: 10 },\n page: { values: [1], selected: 1 },\n sortColumns: []\n }));\n\n constructor() {\n this.route.paramMap.pipe(takeUntilDestroyed()).subscribe(params => this.onParamsChange(params));\n this.destroyRef.onDestroy(() => this.disconnectStreaming());\n }\n\n private async onParamsChange(params: any): Promise<void> {\n // Reset prior-route state so we render the spinner (not stale rows from\n // the previous query) while the new query/entityType resolve.\n this.entityType.set(null);\n this.fetchFn.set(null);\n this.resultCount.set(null);\n this.allItems.set([]);\n this.streamItems.set([]);\n this.disconnectStreaming();\n\n const queryId = params.get('queryId');\n const typeParam = params.get('type');\n\n let resolvedQuery: SparkQuery | null = null;\n let resolvedEntityType: EntityType | null = null;\n let resolvedEntityTypes: EntityType[] = [];\n\n if (queryId) {\n resolvedQuery = await this.sparkService.getQuery(queryId);\n if (resolvedQuery) {\n const result = await this.resolveEntityTypeForQuery(resolvedQuery);\n resolvedEntityType = result.entityType;\n resolvedEntityTypes = result.entityTypes;\n }\n } else if (typeParam) {\n resolvedEntityTypes = await this.sparkService.getEntityTypes();\n resolvedEntityType = resolvedEntityTypes.find(t =>\n t.id === typeParam || t.alias === typeParam\n ) || null;\n\n if (resolvedEntityType) {\n const queries = await this.sparkService.getQueries();\n const singularName = resolvedEntityType.name;\n resolvedQuery = queries.find(q => {\n // Match by explicit entityType\n if (q.entityType === singularName) return true;\n // Match by source name\n const sourceName = this.extractSourceName(q.source);\n const sourceSingular = this.singularize(sourceName);\n return sourceName === singularName ||\n sourceSingular === singularName ||\n sourceName === singularName + 's';\n }) || null;\n }\n }\n\n if (resolvedQuery) this.query.set(resolvedQuery);\n\n if (resolvedEntityType) {\n this.entityType.set(resolvedEntityType);\n this.allEntityTypes.set(resolvedEntityTypes);\n\n const initialSortColumns: SortColumn[] = (resolvedQuery?.sortColumns || []).map(sc => ({\n property: sc.property,\n direction: sc.direction === 'desc' ? 'descending' as const : 'ascending' as const\n }));\n\n this.settings.set(new DatatableSettings({\n perPage: { values: [10, 25, 50], selected: 10 },\n page: { values: [1], selected: 1 },\n sortColumns: initialSortColumns\n }));\n\n if (resolvedQuery?.isStreamingQuery) {\n // Streaming: WebSocket feeds allItems; the datatable binds [data]=\"streamItems()\".\n this.connectStreaming(resolvedQuery.id);\n } else if (resolvedQuery) {\n // Non-streaming: the datatable drives paging/sorting via [(settings)] and calls\n // fetchFn per page. Virtual scrolling is just the [virtualScroll] template flag —\n // the datatable front-loads all pages from fetchFn when virtual.\n this.fetchFn.set(this.makeFetch(resolvedQuery));\n }\n\n this.loadLookupReferenceOptions();\n const [permissions, actions] = await Promise.all([\n this.sparkService.getPermissions(resolvedEntityType.id),\n this.sparkService.getCustomActions(resolvedEntityType.id),\n ]);\n this.canRead.set(permissions.canRead);\n this.canCreate.set(permissions.canCreate);\n this.customActions.set(actions.filter(a => a.showedOn === 'list' || a.showedOn === 'both'));\n }\n }\n\n async onCustomAction(action: CustomActionDefinition): Promise<void> {\n if (action.confirmationMessageKey) {\n const message = this.lang.t(action.confirmationMessageKey) || 'Are you sure?';\n if (!confirm(message)) return;\n }\n try {\n await this.sparkService.executeCustomAction(this.entityType()!.id, action.name);\n this.customActionExecuted.emit({ action });\n if (action.refreshOnCompleted) {\n this.refresh();\n }\n } catch (e) {\n const err = e as HttpErrorResponse;\n this.errorMessage.set(err.error?.error || err.message || 'Action failed');\n }\n }\n\n private async resolveEntityTypeForQuery(query: SparkQuery): Promise<{ entityType: EntityType | null; entityTypes: EntityType[] }> {\n const entityTypes = await this.sparkService.getEntityTypes();\n\n // If entityType is explicitly set on the query, use it directly\n if (query.entityType) {\n const type = entityTypes.find(t =>\n t.name === query.entityType || t.alias === query.entityType?.toLowerCase()\n );\n return { entityType: type || null, entityTypes };\n }\n\n // For Database.X sources, extract the property name and try to match\n const sourceName = this.extractSourceName(query.source);\n const singularName = this.singularize(sourceName);\n const type = entityTypes.find(t =>\n t.name === sourceName ||\n t.name === singularName ||\n t.clrType.endsWith(singularName)\n );\n return { entityType: type || null, entityTypes };\n }\n\n private extractSourceName(source: string): string {\n const dotIndex = source.indexOf('.');\n return dotIndex >= 0 ? source.substring(dotIndex + 1) : source;\n }\n\n private singularize(plural: string): string {\n const irregulars: { [key: string]: string } = {\n 'People': 'Person',\n 'Children': 'Child',\n 'Men': 'Men',\n 'Women': 'Woman'\n };\n if (irregulars[plural]) return irregulars[plural];\n\n if (plural.endsWith('ies')) {\n return plural.slice(0, -3) + 'y';\n }\n if (plural.endsWith('es')) {\n return plural.slice(0, -2);\n }\n if (plural.endsWith('s')) {\n return plural.slice(0, -1);\n }\n return plural;\n }\n\n /**\n * Builds the server-side fetch callback the datatable invokes per page/sort.\n * Reads `searchTerm` live, so a settings change (or a new fetchFn identity)\n * refetches with the current search term.\n */\n private makeFetch(query: SparkQuery): BsDatatableFetch<PersistentObject> {\n return (req) => this.sparkService.executeQuery(query.id, {\n sortColumns: req.sortColumns,\n skip: (req.page - 1) * req.perPage,\n take: req.perPage,\n search: this.searchTerm || undefined,\n }).then(r => {\n this.errorMessage.set(null);\n this.resultCount.set(r.totalRecords);\n return {\n data: r.data,\n totalRecords: r.totalRecords,\n totalPages: Math.ceil(r.totalRecords / req.perPage) || 1,\n perPage: req.perPage,\n page: req.page,\n };\n }).catch((e: any) => {\n this.errorMessage.set(e.error?.error || e.message || 'An unexpected error occurred');\n this.resultCount.set(0);\n return { data: [], totalRecords: 0, totalPages: 1, perPage: req.perPage, page: req.page };\n });\n }\n\n /** Force a refetch (e.g. after a custom action) without changing page/sort. */\n private refresh(): void {\n if (this.isStreaming()) {\n this.applyFilter();\n return;\n }\n const q = this.query();\n if (q) this.fetchFn.set(this.makeFetch(q));\n }\n\n onSearchChange(): void {\n if (this.isStreaming()) {\n this.applyFilter();\n return;\n }\n // Reset to page 1 for the new search.\n const s = this.settings();\n this.settings.set(new DatatableSettings({\n perPage: { values: s.perPage.values, selected: s.perPage.selected },\n page: { values: [1], selected: 1 },\n sortColumns: s.sortColumns,\n }));\n // Re-assign the fetch callback so the datatable refetches even when\n // page/perPage/sort are unchanged. ng-bootstrap 22.4's web component dedupes\n // reloads by {sortColumns, perPage, page}; setting a new fetch identity resets\n // that key (set fetch → _lastReloadKey = null) and forces the reload. makeFetch\n // reads searchTerm live (mirrors refresh()).\n const q = this.query();\n if (q) this.fetchFn.set(this.makeFetch(q));\n }\n\n clearSearch(): void {\n this.searchTerm = '';\n this.onSearchChange();\n }\n\n isVirtualScrolling = computed(() => this.query()?.renderMode === 'VirtualScrolling');\n\n visibleAttributes = computed(() => {\n return this.entityType()?.attributes\n .filter(a => a.isVisible && hasShowedOnFlag(a.showedOn, ShowedOn.Query))\n .sort((a, b) => a.order - b.order) || [];\n });\n\n getColumnRendererComponent(attr: EntityAttributeDefinition): Type<any> | null {\n if (!attr.renderer) return null;\n return this.rendererRegistry.find(r => r.name === attr.renderer)?.columnComponent ?? null;\n }\n\n getColumnRendererInputs(item: PersistentObject, attr: EntityAttributeDefinition): Record<string, any> {\n const itemAttr = item.attributes.find(a => a.name === attr.name);\n return {\n value: itemAttr?.value,\n attribute: attr,\n options: attr.rendererOptions,\n };\n }\n\n private async loadLookupReferenceOptions(): Promise<void> {\n const lookupAttrs = this.visibleAttributes().filter(a => a.lookupReferenceType);\n if (lookupAttrs.length === 0) return;\n\n const lookupNames = [...new Set(lookupAttrs.map(a => a.lookupReferenceType!))];\n const entries = await Promise.all(\n lookupNames.map(async name => {\n const result = await this.sparkService.getLookupReference(name);\n return [name, result] as const;\n })\n );\n this.lookupReferenceOptions.set(entries.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {} as Record<string, LookupReference>));\n }\n\n onCreate(): void {\n this.createClicked.emit();\n const et = this.entityType();\n if (et) {\n this.router.navigate(['/po', et.alias || et.id, 'new']);\n }\n }\n\n private connectStreaming(queryId: string): void {\n this.disconnectStreaming();\n this.isStreaming.set(true);\n\n this.streamingSub = this.streamingService.connectToStreamingQuery(queryId).subscribe({\n next: (message) => this.handleStreamingMessage(message),\n error: (err) => {\n this.errorMessage.set(err?.message || 'Streaming connection failed');\n this.isStreaming.set(false);\n },\n complete: () => {\n this.isStreaming.set(false);\n }\n });\n }\n\n private disconnectStreaming(): void {\n if (this.streamingSub) {\n this.streamingSub.unsubscribe();\n this.streamingSub = null;\n }\n this.isStreaming.set(false);\n }\n\n private handleStreamingMessage(message: StreamingMessage): void {\n switch (message.type) {\n case 'snapshot':\n this.errorMessage.set(null);\n this.allItems.set(message.data);\n this.applyFilter();\n break;\n\n case 'patch':\n if (message.updated.length > 0) {\n const currentItems = this.allItems();\n const updatedItems = currentItems.map(item => {\n const patch = message.updated.find(u => u.id === item.id);\n if (!patch) return item;\n\n // Clone the item and update only changed attribute values\n const updatedAttributes = item.attributes.map(attr => {\n if (attr.name in patch.attributes) {\n return { ...attr, value: patch.attributes[attr.name] };\n }\n return attr;\n });\n\n return { ...item, attributes: updatedAttributes };\n });\n\n this.allItems.set(updatedItems);\n this.applyFilter();\n }\n break;\n\n case 'error':\n this.errorMessage.set(message.message);\n break;\n }\n }\n\n private applyFilter(): void {\n let items = this.allItems();\n\n // Apply search filter\n if (this.searchTerm) {\n const term = this.searchTerm.toLowerCase();\n items = items.filter(item =>\n item.attributes.some(a => String(a.value ?? '').toLowerCase().includes(term))\n );\n }\n\n // Apply sorting (client-side for the streaming snapshot; the datatable in\n // [data] mode also auto-sorts on header clicks).\n const sortCols = this.settings().sortColumns;\n if (sortCols.length > 0) {\n items = [...items].sort((a, b) => {\n for (const col of sortCols) {\n const aVal = a.attributes.find(attr => attr.name === col.property)?.value ?? '';\n const bVal = b.attributes.find(attr => attr.name === col.property)?.value ?? '';\n const cmp = String(aVal).localeCompare(String(bVal));\n if (cmp !== 0) return col.direction === 'descending' ? -cmp : cmp;\n }\n return 0;\n });\n }\n\n this.streamItems.set(items);\n this.resultCount.set(items.length);\n }\n}\n","<div class=\"d-flex flex-column h-100\">\n <div class=\"spark-actionbar py-2 flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\" [class.px-3]=\"!isVirtualScrolling()\">\n <bs-priority-nav [moreLabel]=\"lang.t('common.more')\" [collapseAt]=\"'sm'\">\n @if (canCreate()) {\n <button *bsPriorityNavItem=\"1\" class=\"btn btn-primary\" (click)=\"onCreate()\">\n <spark-icon name=\"plus-lg\" /> {{ 'common.new' | t }}\n </button>\n }\n @if (showCustomActions()) {\n @for (action of customActions(); track action.name) {\n <button *bsPriorityNavItem=\"10 + action.offset\" class=\"btn btn-outline-primary\" (click)=\"onCustomAction(action)\">\n {{ action.displayName | resolveTranslation }}\n </button>\n }\n }\n @if (extraActionsTemplate(); as extraActionsTpl) {\n <ng-container *bsPriorityNavItem=\"50\">\n <ng-container *ngTemplateOutlet=\"extraActionsTpl\"></ng-container>\n </ng-container>\n }\n </bs-priority-nav>\n </div>\n <h2 class=\"mb-4 flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n {{ (query()?.description | resolveTranslation) || query()?.name || ('common.loading' | t) }}\n @if (isStreaming()) {\n <span class=\"badge bg-success ms-2\" style=\"font-size: 0.5em; vertical-align: middle;\">LIVE</span>\n }\n </h2>\n\n @if (entityType()) {\n <!-- Search box -->\n <div class=\"flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n <bs-form>\n <bs-grid>\n <div bsRow class=\"mb-3\">\n <div [md]=\"4\">\n <bs-input-group>\n <span class=\"input-group-text\">\n <spark-icon name=\"search\" />\n </span>\n <input\n type=\"text\"\n [placeholder]=\"'common.search' | t\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange()\">\n @if (searchTerm) {\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"clearSearch()\">\n <spark-icon name=\"x-lg\" />\n </button>\n }\n </bs-input-group>\n </div>\n <div [md]=\"8\" class=\"text-end\">\n @if (searchTerm && resultCount() !== null) {\n <span class=\"text-muted\">\n {{ resultCount() }} {{ resultCount() === 1 ? ('common.resultFound' | t) : ('common.resultsFound' | t) }}\n </span>\n }\n </div>\n </div>\n </bs-grid>\n </bs-form>\n\n @if (errorMessage(); as err) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ err }}\n </bs-alert>\n }\n </div>\n\n @if (isStreaming()) {\n <bs-datatable class=\"flex-grow-1\"\n [virtualScroll]=\"isVirtualScrolling()\"\n [itemSize]=\"40\"\n [isResponsive]=\"isVirtualScrolling()\"\n [data]=\"streamItems()\"\n [(settings)]=\"settings\">\n @for (attr of visibleAttributes(); track attr.id) {\n <div *bsDatatableColumn=\"attr.name; sortable: true\">\n {{ (attr.label | resolveTranslation) || attr.name }}\n </div>\n }\n\n <ng-container *bsRowTemplate=\"let item\">\n @let row = $any(item);\n @for (attr of visibleAttributes(); track attr.id; let first = $first) {\n <td>\n @if (row) {\n @if (first && canRead()) {\n <a [routerLink]=\"['/po', entityType()!.alias || entityType()!.id, row.id]\" (click)=\"rowClicked.emit(row)\">\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: row, attr: attr }\"></ng-container>\n </a>\n } @else {\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: row, attr: attr }\"></ng-container>\n }\n } @else {\n &nbsp;\n }\n </td>\n }\n </ng-container>\n </bs-datatable>\n } @else {\n <bs-datatable class=\"flex-grow-1\"\n [virtualScroll]=\"isVirtualScrolling()\"\n [itemSize]=\"40\"\n [isResponsive]=\"isVirtualScrolling()\"\n [fetch]=\"fetchFn()\"\n [(settings)]=\"settings\">\n @for (attr of visibleAttributes(); track attr.id) {\n <div *bsDatatableColumn=\"attr.name; sortable: true\">\n {{ (attr.label | resolveTranslation) || attr.name }}\n </div>\n }\n\n <ng-container *bsRowTemplate=\"let item\">\n @let row = $any(item);\n @for (attr of visibleAttributes(); track attr.id; let first = $first) {\n <td>\n @if (row) {\n @if (first && canRead()) {\n <a [routerLink]=\"['/po', entityType()!.alias || entityType()!.id, row.id]\" (click)=\"rowClicked.emit(row)\">\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: row, attr: attr }\"></ng-container>\n </a>\n } @else {\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: row, attr: attr }\"></ng-container>\n }\n } @else {\n &nbsp;\n }\n </td>\n }\n </ng-container>\n </bs-datatable>\n }\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n\n<ng-template #cellContent let-item let-attr=\"attr\">\n @if (getColumnRendererComponent(attr); as rendererType) {\n <ng-container *ngComponentOutlet=\"rendererType; inputs: getColumnRendererInputs(item, attr)\"></ng-container>\n } @else if (attr.dataType === 'boolean') {\n <input type=\"checkbox\"\n [checked]=\"(attr.name | attributeValue:item:entityType():lookupReferenceOptions():allEntityTypes()) === true\"\n [indeterminate]=\"(attr.name | attributeValue:item:entityType():lookupReferenceOptions():allEntityTypes()) == null\"\n disabled\n onclick=\"return false;\">\n } @else if (attr.dataType === 'color') {\n @let colorVal = (attr.name | attributeValue:item:entityType():lookupReferenceOptions():allEntityTypes());\n @if (colorVal) {\n <span class=\"d-inline-block align-middle border rounded\" [style.background-color]=\"colorVal\" style=\"width: 1.5em; height: 1.5em;\"></span>\n }\n } @else {\n {{ (attr.name | attributeValue:item:entityType():lookupReferenceOptions():allEntityTypes()) }}\n }\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mintplayer-ng-spark-query-list.mjs","sources":["../../query-list/src/spark-query-list.component.ts","../../query-list/src/spark-query-list.component.html","../../query-list/mintplayer-ng-spark-query-list.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, input, output, signal, TemplateRef, Type } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Subscription } from 'rxjs';\nimport { CommonModule, NgTemplateOutlet, NgComponentOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { ActivatedRoute, Router, RouterModule } from '@angular/router';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsDatatableComponent, BsDatatableColumnDirective, BsRowTemplateDirective, DatatableSettings, type BsDatatableFetch } from '@mintplayer/ng-bootstrap/datatable';\nimport { BsFormComponent, BsFormControlDirective } from '@mintplayer/ng-bootstrap/form';\nimport { BsGridComponent, BsGridRowDirective, BsGridColumnDirective } from '@mintplayer/ng-bootstrap/grid';\nimport { BsInputGroupComponent } from '@mintplayer/ng-bootstrap/input-group';\nimport { BsPriorityNavComponent, BsPriorityNavItemDirective } from '@mintplayer/ng-bootstrap/priority-nav';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { SortColumn } from '@mintplayer/pagination';\nimport { SparkService, SparkStreamingService, SparkLanguageService } from '@mintplayer/ng-spark/services';\nimport {\n TranslateKeyPipe,\n ResolveTranslationPipe,\n AttributeValuePipe,\n ReferenceChipsPipe,\n} from '@mintplayer/ng-spark/pipes';\nimport { SparkIconComponent } from '@mintplayer/ng-spark/icon';\nimport { SPARK_ATTRIBUTE_RENDERERS } from '@mintplayer/ng-spark/renderers';\nimport {\n CustomActionDefinition,\n StreamingMessage,\n EntityType,\n EntityAttributeDefinition,\n LookupReference,\n PersistentObject,\n SparkQuery,\n ShowedOn,\n hasShowedOnFlag,\n} from '@mintplayer/ng-spark/models';\n\n@Component({\n selector: 'spark-query-list',\n imports: [CommonModule, NgTemplateOutlet, NgComponentOutlet, FormsModule, RouterModule, BsAlertComponent, BsDatatableComponent, BsDatatableColumnDirective, BsRowTemplateDirective, BsFormComponent, BsFormControlDirective, BsGridComponent, BsGridRowDirective, BsGridColumnDirective, BsInputGroupComponent, BsPriorityNavComponent, BsPriorityNavItemDirective, BsSpinnerComponent, SparkIconComponent, ResolveTranslationPipe, TranslateKeyPipe, AttributeValuePipe, ReferenceChipsPipe],\n templateUrl: './spark-query-list.component.html',\n styleUrl: './spark-query-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.virtual-scrolling]': 'isVirtualScrolling()'\n }\n})\nexport class SparkQueryListComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly sparkService = inject(SparkService);\n private readonly streamingService = inject(SparkStreamingService);\n protected readonly lang = inject(SparkLanguageService);\n private readonly rendererRegistry = inject(SPARK_ATTRIBUTE_RENDERERS);\n private readonly destroyRef = inject(DestroyRef);\n\n extraActionsTemplate = input<TemplateRef<void> | null>(null);\n showCustomActions = input(true);\n\n rowClicked = output<PersistentObject>();\n createClicked = output<void>();\n customActionExecuted = output<{ action: CustomActionDefinition }>();\n\n colors = Color;\n errorMessage = signal<string | null>(null);\n query = signal<SparkQuery | null>(null);\n entityType = signal<EntityType | null>(null);\n allEntityTypes = signal<EntityType[]>([]);\n lookupReferenceOptions = signal<Record<string, LookupReference>>({});\n resultCount = signal<number | null>(null);\n searchTerm: string = '';\n canRead = signal(false);\n canCreate = signal(false);\n customActions = signal<CustomActionDefinition[]>([]);\n isStreaming = signal(false);\n private streamingSub: Subscription | null = null;\n private allItems = signal<PersistentObject[]>([]);\n streamItems = signal<PersistentObject[]>([]);\n fetchFn = signal<BsDatatableFetch<PersistentObject> | null>(null);\n settings = signal(new DatatableSettings({\n perPage: { values: [10, 25, 50], selected: 10 },\n page: { values: [1], selected: 1 },\n sortColumns: []\n }));\n\n constructor() {\n this.route.paramMap.pipe(takeUntilDestroyed()).subscribe(params => this.onParamsChange(params));\n this.destroyRef.onDestroy(() => this.disconnectStreaming());\n }\n\n private async onParamsChange(params: any): Promise<void> {\n // Reset prior-route state so we render the spinner (not stale rows from\n // the previous query) while the new query/entityType resolve.\n this.entityType.set(null);\n this.fetchFn.set(null);\n this.resultCount.set(null);\n this.allItems.set([]);\n this.streamItems.set([]);\n this.disconnectStreaming();\n\n const queryId = params.get('queryId');\n const typeParam = params.get('type');\n\n let resolvedQuery: SparkQuery | null = null;\n let resolvedEntityType: EntityType | null = null;\n let resolvedEntityTypes: EntityType[] = [];\n\n if (queryId) {\n resolvedQuery = await this.sparkService.getQuery(queryId);\n if (resolvedQuery) {\n const result = await this.resolveEntityTypeForQuery(resolvedQuery);\n resolvedEntityType = result.entityType;\n resolvedEntityTypes = result.entityTypes;\n }\n } else if (typeParam) {\n resolvedEntityTypes = await this.sparkService.getEntityTypes();\n resolvedEntityType = resolvedEntityTypes.find(t =>\n t.id === typeParam || t.alias === typeParam\n ) || null;\n\n if (resolvedEntityType) {\n const queries = await this.sparkService.getQueries();\n const singularName = resolvedEntityType.name;\n resolvedQuery = queries.find(q => {\n // Match by explicit entityType\n if (q.entityType === singularName) return true;\n // Match by source name\n const sourceName = this.extractSourceName(q.source);\n const sourceSingular = this.singularize(sourceName);\n return sourceName === singularName ||\n sourceSingular === singularName ||\n sourceName === singularName + 's';\n }) || null;\n }\n }\n\n if (resolvedQuery) this.query.set(resolvedQuery);\n\n if (resolvedEntityType) {\n this.entityType.set(resolvedEntityType);\n this.allEntityTypes.set(resolvedEntityTypes);\n\n const initialSortColumns: SortColumn[] = (resolvedQuery?.sortColumns || []).map(sc => ({\n property: sc.property,\n direction: sc.direction === 'desc' ? 'descending' as const : 'ascending' as const\n }));\n\n this.settings.set(new DatatableSettings({\n perPage: { values: [10, 25, 50], selected: 10 },\n page: { values: [1], selected: 1 },\n sortColumns: initialSortColumns\n }));\n\n if (resolvedQuery?.isStreamingQuery) {\n // Streaming: WebSocket feeds allItems; the datatable binds [data]=\"streamItems()\".\n this.connectStreaming(resolvedQuery.id);\n } else if (resolvedQuery) {\n // Non-streaming: the datatable drives paging/sorting via [(settings)] and calls\n // fetchFn per page. Virtual scrolling is just the [virtualScroll] template flag —\n // the datatable front-loads all pages from fetchFn when virtual.\n this.fetchFn.set(this.makeFetch(resolvedQuery));\n }\n\n this.loadLookupReferenceOptions();\n const [permissions, actions] = await Promise.all([\n this.sparkService.getPermissions(resolvedEntityType.id),\n this.sparkService.getCustomActions(resolvedEntityType.id),\n ]);\n this.canRead.set(permissions.canRead);\n this.canCreate.set(permissions.canCreate);\n this.customActions.set(actions.filter(a => a.showedOn === 'list' || a.showedOn === 'both'));\n }\n }\n\n async onCustomAction(action: CustomActionDefinition): Promise<void> {\n if (action.confirmationMessageKey) {\n const message = this.lang.t(action.confirmationMessageKey) || 'Are you sure?';\n if (!confirm(message)) return;\n }\n try {\n await this.sparkService.executeCustomAction(this.entityType()!.id, action.name);\n this.customActionExecuted.emit({ action });\n if (action.refreshOnCompleted) {\n this.refresh();\n }\n } catch (e) {\n const err = e as HttpErrorResponse;\n this.errorMessage.set(err.error?.error || err.message || 'Action failed');\n }\n }\n\n private async resolveEntityTypeForQuery(query: SparkQuery): Promise<{ entityType: EntityType | null; entityTypes: EntityType[] }> {\n const entityTypes = await this.sparkService.getEntityTypes();\n\n // If entityType is explicitly set on the query, use it directly\n if (query.entityType) {\n const type = entityTypes.find(t =>\n t.name === query.entityType || t.alias === query.entityType?.toLowerCase()\n );\n return { entityType: type || null, entityTypes };\n }\n\n // For Database.X sources, extract the property name and try to match\n const sourceName = this.extractSourceName(query.source);\n const singularName = this.singularize(sourceName);\n const type = entityTypes.find(t =>\n t.name === sourceName ||\n t.name === singularName ||\n t.clrType.endsWith(singularName)\n );\n return { entityType: type || null, entityTypes };\n }\n\n private extractSourceName(source: string): string {\n const dotIndex = source.indexOf('.');\n return dotIndex >= 0 ? source.substring(dotIndex + 1) : source;\n }\n\n private singularize(plural: string): string {\n const irregulars: { [key: string]: string } = {\n 'People': 'Person',\n 'Children': 'Child',\n 'Men': 'Men',\n 'Women': 'Woman'\n };\n if (irregulars[plural]) return irregulars[plural];\n\n if (plural.endsWith('ies')) {\n return plural.slice(0, -3) + 'y';\n }\n if (plural.endsWith('es')) {\n return plural.slice(0, -2);\n }\n if (plural.endsWith('s')) {\n return plural.slice(0, -1);\n }\n return plural;\n }\n\n /**\n * Builds the server-side fetch callback the datatable invokes per page/sort.\n * Reads `searchTerm` live, so a settings change (or a new fetchFn identity)\n * refetches with the current search term.\n */\n private makeFetch(query: SparkQuery): BsDatatableFetch<PersistentObject> {\n return (req) => this.sparkService.executeQuery(query.id, {\n sortColumns: req.sortColumns,\n skip: (req.page - 1) * req.perPage,\n take: req.perPage,\n search: this.searchTerm || undefined,\n }).then(r => {\n this.errorMessage.set(null);\n this.resultCount.set(r.totalRecords);\n return {\n data: r.data,\n totalRecords: r.totalRecords,\n totalPages: Math.ceil(r.totalRecords / req.perPage) || 1,\n perPage: req.perPage,\n page: req.page,\n };\n }).catch((e: any) => {\n this.errorMessage.set(e.error?.error || e.message || 'An unexpected error occurred');\n this.resultCount.set(0);\n return { data: [], totalRecords: 0, totalPages: 1, perPage: req.perPage, page: req.page };\n });\n }\n\n /** Force a refetch (e.g. after a custom action) without changing page/sort. */\n private refresh(): void {\n if (this.isStreaming()) {\n this.applyFilter();\n return;\n }\n const q = this.query();\n if (q) this.fetchFn.set(this.makeFetch(q));\n }\n\n onSearchChange(): void {\n if (this.isStreaming()) {\n this.applyFilter();\n return;\n }\n // Reset to page 1 for the new search.\n const s = this.settings();\n this.settings.set(new DatatableSettings({\n perPage: { values: s.perPage.values, selected: s.perPage.selected },\n page: { values: [1], selected: 1 },\n sortColumns: s.sortColumns,\n }));\n // Re-assign the fetch callback so the datatable refetches even when\n // page/perPage/sort are unchanged. ng-bootstrap 22.4's web component dedupes\n // reloads by {sortColumns, perPage, page}; setting a new fetch identity resets\n // that key (set fetch → _lastReloadKey = null) and forces the reload. makeFetch\n // reads searchTerm live (mirrors refresh()).\n const q = this.query();\n if (q) this.fetchFn.set(this.makeFetch(q));\n }\n\n clearSearch(): void {\n this.searchTerm = '';\n this.onSearchChange();\n }\n\n isVirtualScrolling = computed(() => this.query()?.renderMode === 'VirtualScrolling');\n\n visibleAttributes = computed(() => {\n return this.entityType()?.attributes\n .filter(a => a.isVisible && hasShowedOnFlag(a.showedOn, ShowedOn.Query))\n .sort((a, b) => a.order - b.order) || [];\n });\n\n getColumnRendererComponent(attr: EntityAttributeDefinition): Type<any> | null {\n if (!attr.renderer) return null;\n return this.rendererRegistry.find(r => r.name === attr.renderer)?.columnComponent ?? null;\n }\n\n getColumnRendererInputs(item: PersistentObject, attr: EntityAttributeDefinition): Record<string, any> {\n const itemAttr = item.attributes.find(a => a.name === attr.name);\n return {\n value: itemAttr?.value,\n attribute: attr,\n options: attr.rendererOptions,\n };\n }\n\n private async loadLookupReferenceOptions(): Promise<void> {\n const lookupAttrs = this.visibleAttributes().filter(a => a.lookupReferenceType);\n if (lookupAttrs.length === 0) return;\n\n const lookupNames = [...new Set(lookupAttrs.map(a => a.lookupReferenceType!))];\n const entries = await Promise.all(\n lookupNames.map(async name => {\n const result = await this.sparkService.getLookupReference(name);\n return [name, result] as const;\n })\n );\n this.lookupReferenceOptions.set(entries.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {} as Record<string, LookupReference>));\n }\n\n onCreate(): void {\n this.createClicked.emit();\n const et = this.entityType();\n if (et) {\n this.router.navigate(['/po', et.alias || et.id, 'new']);\n }\n }\n\n private connectStreaming(queryId: string): void {\n this.disconnectStreaming();\n this.isStreaming.set(true);\n\n this.streamingSub = this.streamingService.connectToStreamingQuery(queryId).subscribe({\n next: (message) => this.handleStreamingMessage(message),\n error: (err) => {\n this.errorMessage.set(err?.message || 'Streaming connection failed');\n this.isStreaming.set(false);\n },\n complete: () => {\n this.isStreaming.set(false);\n }\n });\n }\n\n private disconnectStreaming(): void {\n if (this.streamingSub) {\n this.streamingSub.unsubscribe();\n this.streamingSub = null;\n }\n this.isStreaming.set(false);\n }\n\n private handleStreamingMessage(message: StreamingMessage): void {\n switch (message.type) {\n case 'snapshot':\n this.errorMessage.set(null);\n this.allItems.set(message.data);\n this.applyFilter();\n break;\n\n case 'patch':\n if (message.updated.length > 0) {\n const currentItems = this.allItems();\n const updatedItems = currentItems.map(item => {\n const patch = message.updated.find(u => u.id === item.id);\n if (!patch) return item;\n\n // Clone the item and update only changed attribute values\n const updatedAttributes = item.attributes.map(attr => {\n if (attr.name in patch.attributes) {\n return { ...attr, value: patch.attributes[attr.name] };\n }\n return attr;\n });\n\n return { ...item, attributes: updatedAttributes };\n });\n\n this.allItems.set(updatedItems);\n this.applyFilter();\n }\n break;\n\n case 'error':\n this.errorMessage.set(message.message);\n break;\n }\n }\n\n private applyFilter(): void {\n let items = this.allItems();\n\n // Apply search filter\n if (this.searchTerm) {\n const term = this.searchTerm.toLowerCase();\n items = items.filter(item =>\n item.attributes.some(a => String(a.value ?? '').toLowerCase().includes(term))\n );\n }\n\n // Apply sorting (client-side for the streaming snapshot; the datatable in\n // [data] mode also auto-sorts on header clicks).\n const sortCols = this.settings().sortColumns;\n if (sortCols.length > 0) {\n items = [...items].sort((a, b) => {\n for (const col of sortCols) {\n const aVal = a.attributes.find(attr => attr.name === col.property)?.value ?? '';\n const bVal = b.attributes.find(attr => attr.name === col.property)?.value ?? '';\n const cmp = String(aVal).localeCompare(String(bVal));\n if (cmp !== 0) return col.direction === 'descending' ? -cmp : cmp;\n }\n return 0;\n });\n }\n\n this.streamItems.set(items);\n this.resultCount.set(items.length);\n }\n}\n","<div class=\"d-flex flex-column h-100\">\n <div class=\"spark-actionbar py-2 flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\" [class.px-3]=\"!isVirtualScrolling()\">\n <bs-priority-nav [moreLabel]=\"lang.t('common.more')\" [collapseAt]=\"'sm'\">\n @if (canCreate()) {\n <button *bsPriorityNavItem=\"1\" class=\"btn btn-primary\" (click)=\"onCreate()\">\n <spark-icon name=\"plus-lg\" /> {{ 'common.new' | t }}\n </button>\n }\n @if (showCustomActions()) {\n @for (action of customActions(); track action.name) {\n <button *bsPriorityNavItem=\"10 + action.offset\" class=\"btn btn-outline-primary\" (click)=\"onCustomAction(action)\">\n {{ action.displayName | resolveTranslation }}\n </button>\n }\n }\n @if (extraActionsTemplate(); as extraActionsTpl) {\n <ng-container *bsPriorityNavItem=\"50\">\n <ng-container *ngTemplateOutlet=\"extraActionsTpl\"></ng-container>\n </ng-container>\n }\n </bs-priority-nav>\n </div>\n <h2 class=\"mb-4 flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n {{ (query()?.description | resolveTranslation) || query()?.name || ('common.loading' | t) }}\n @if (isStreaming()) {\n <span class=\"badge bg-success ms-2\" style=\"font-size: 0.5em; vertical-align: middle;\">LIVE</span>\n }\n </h2>\n\n @if (entityType()) {\n <!-- Search box -->\n <div class=\"flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n <bs-form>\n <bs-grid>\n <div bsRow class=\"mb-3\">\n <div [md]=\"4\">\n <bs-input-group>\n <span class=\"input-group-text\">\n <spark-icon name=\"search\" />\n </span>\n <input\n type=\"text\"\n [placeholder]=\"'common.search' | t\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange()\">\n @if (searchTerm) {\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"clearSearch()\">\n <spark-icon name=\"x-lg\" />\n </button>\n }\n </bs-input-group>\n </div>\n <div [md]=\"8\" class=\"text-end\">\n @if (searchTerm && resultCount() !== null) {\n <span class=\"text-muted\">\n {{ resultCount() }} {{ resultCount() === 1 ? ('common.resultFound' | t) : ('common.resultsFound' | t) }}\n </span>\n }\n </div>\n </div>\n </bs-grid>\n </bs-form>\n\n @if (errorMessage(); as err) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ err }}\n </bs-alert>\n }\n </div>\n\n @if (isStreaming()) {\n <bs-datatable class=\"flex-grow-1\"\n [virtualScroll]=\"isVirtualScrolling()\"\n [itemSize]=\"40\"\n [isResponsive]=\"isVirtualScrolling()\"\n [data]=\"streamItems()\"\n [(settings)]=\"settings\">\n @for (attr of visibleAttributes(); track attr.id) {\n <div *bsDatatableColumn=\"attr.name; sortable: true\">\n {{ (attr.label | resolveTranslation) || attr.name }}\n </div>\n }\n\n <ng-container *bsRowTemplate=\"let item\">\n @let row = $any(item);\n @for (attr of visibleAttributes(); track attr.id; let first = $first) {\n <td>\n @if (row) {\n @if (first && canRead()) {\n <a [routerLink]=\"['/po', entityType()!.alias || entityType()!.id, row.id]\" (click)=\"rowClicked.emit(row)\">\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: row, attr: attr }\"></ng-container>\n </a>\n } @else {\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: row, attr: attr }\"></ng-container>\n }\n } @else {\n &nbsp;\n }\n </td>\n }\n </ng-container>\n </bs-datatable>\n } @else {\n <bs-datatable class=\"flex-grow-1\"\n [virtualScroll]=\"isVirtualScrolling()\"\n [itemSize]=\"40\"\n [isResponsive]=\"isVirtualScrolling()\"\n [fetch]=\"fetchFn()\"\n [(settings)]=\"settings\">\n @for (attr of visibleAttributes(); track attr.id) {\n <div *bsDatatableColumn=\"attr.name; sortable: true\">\n {{ (attr.label | resolveTranslation) || attr.name }}\n </div>\n }\n\n <ng-container *bsRowTemplate=\"let item\">\n @let row = $any(item);\n @for (attr of visibleAttributes(); track attr.id; let first = $first) {\n <td>\n @if (row) {\n @if (first && canRead()) {\n <a [routerLink]=\"['/po', entityType()!.alias || entityType()!.id, row.id]\" (click)=\"rowClicked.emit(row)\">\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: row, attr: attr }\"></ng-container>\n </a>\n } @else {\n <ng-container *ngTemplateOutlet=\"cellContent; context: { $implicit: row, attr: attr }\"></ng-container>\n }\n } @else {\n &nbsp;\n }\n </td>\n }\n </ng-container>\n </bs-datatable>\n }\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n\n<ng-template #cellContent let-item let-attr=\"attr\">\n @if (getColumnRendererComponent(attr); as rendererType) {\n <ng-container *ngComponentOutlet=\"rendererType; inputs: getColumnRendererInputs(item, attr)\"></ng-container>\n } @else if (attr.dataType === 'boolean') {\n <input type=\"checkbox\"\n [checked]=\"(attr.name | attributeValue:item:entityType():lookupReferenceOptions():allEntityTypes()) === true\"\n [indeterminate]=\"(attr.name | attributeValue:item:entityType():lookupReferenceOptions():allEntityTypes()) == null\"\n disabled\n onclick=\"return false;\">\n } @else if (attr.dataType === 'color') {\n @let colorVal = (attr.name | attributeValue:item:entityType():lookupReferenceOptions():allEntityTypes());\n @if (colorVal) {\n <span class=\"d-inline-block align-middle border rounded\" [style.background-color]=\"colorVal\" style=\"width: 1.5em; height: 1.5em;\"></span>\n }\n } @else if (attr.dataType === 'Reference' && attr.isArray) {\n <span class=\"d-inline-flex flex-wrap gap-1\">\n @for (chip of (attr.name | referenceChips:item); track chip.id) {\n <span class=\"badge rounded-pill border bg-body-secondary text-body px-3 py-2\">{{ chip.label }}</span>\n }\n </span>\n } @else {\n {{ (attr.name | attributeValue:item:entityType():lookupReferenceOptions():allEntityTypes()) }}\n }\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mintplayer/ng-spark",
3
3
  "private": false,
4
- "version": "22.0.1",
4
+ "version": "22.0.2",
5
5
  "description": "Angular component library for MintPlayer.Spark CRUD applications",
6
6
  "repository": {
7
7
  "type": "git",
@@ -56,6 +56,12 @@ interface PersistentObjectAttribute {
56
56
  order: number;
57
57
  query?: string;
58
58
  breadcrumb?: string;
59
+ /**
60
+ * For `dataType === 'Reference'` with `isArray === true`: resolved display label per
61
+ * referenced id (id → breadcrumb), so the UI can render a chip per selected reference.
62
+ * The single-reference counterpart is `breadcrumb`.
63
+ */
64
+ breadcrumbs?: Record<string, string | null>;
59
65
  /**
60
66
  * Controls on which pages the attribute should be displayed.
61
67
  * Query = shown in list views, PersistentObject = shown in detail/edit views.
@@ -54,6 +54,23 @@ declare class ReferenceLinkRoutePipe implements PipeTransform {
54
54
  static ɵpipe: i0.ɵɵPipeDeclaration<ReferenceLinkRoutePipe, "referenceLinkRoute", true>;
55
55
  }
56
56
 
57
+ interface ReferenceChip {
58
+ id: string;
59
+ label: string;
60
+ }
61
+ /**
62
+ * Resolves a multi-reference attribute (`dataType === 'Reference'`, `isArray === true`)
63
+ * to a list of chips. The attribute's `value` carries the id array; `breadcrumbs` (a
64
+ * server-resolved id → label map) provides each chip's display label, falling back to
65
+ * the id when no breadcrumb is present. Mirrors the single-reference `breadcrumb`
66
+ * display, applied per id.
67
+ */
68
+ declare class ReferenceChipsPipe implements PipeTransform {
69
+ transform(attrName: string, item: PersistentObject | null): ReferenceChip[];
70
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReferenceChipsPipe, never>;
71
+ static ɵpipe: i0.ɵɵPipeDeclaration<ReferenceChipsPipe, "referenceChips", true>;
72
+ }
73
+
57
74
  declare class RouterLinkPipe implements PipeTransform {
58
75
  transform(unit: ProgramUnit): string[];
59
76
  static ɵfac: i0.ɵɵFactoryDeclaration<RouterLinkPipe, never>;
@@ -148,4 +165,5 @@ declare class ArrayValuePipe implements PipeTransform {
148
165
  static ɵpipe: i0.ɵɵPipeDeclaration<ArrayValuePipe, "arrayValue", true>;
149
166
  }
150
167
 
151
- export { ArrayValuePipe, AsDetailCellValuePipe, AsDetailColumnsPipe, AsDetailDisplayValuePipe, AsDetailTypePipe, AttributeValuePipe, CanCreateDetailRowPipe, CanDeleteDetailRowPipe, ErrorForAttributePipe, IconNamePipe, InlineRefOptionsPipe, InputTypePipe, LookupDisplayTypePipe, LookupDisplayValuePipe, LookupOptionsPipe, RawAttributeValuePipe, ReferenceAttrValuePipe, ReferenceDisplayValuePipe, ReferenceLinkRoutePipe, ResolveTranslationPipe, RouterLinkPipe, TranslateKeyPipe };
168
+ export { ArrayValuePipe, AsDetailCellValuePipe, AsDetailColumnsPipe, AsDetailDisplayValuePipe, AsDetailTypePipe, AttributeValuePipe, CanCreateDetailRowPipe, CanDeleteDetailRowPipe, ErrorForAttributePipe, IconNamePipe, InlineRefOptionsPipe, InputTypePipe, LookupDisplayTypePipe, LookupDisplayValuePipe, LookupOptionsPipe, RawAttributeValuePipe, ReferenceAttrValuePipe, ReferenceChipsPipe, ReferenceDisplayValuePipe, ReferenceLinkRoutePipe, ResolveTranslationPipe, RouterLinkPipe, TranslateKeyPipe };
169
+ export type { ReferenceChip };
@@ -1,6 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Type } from '@angular/core';
3
3
  import { Color } from '@mintplayer/ng-bootstrap';
4
+ import { InMemoryTreeSelectProvider, TreeNode } from '@mintplayer/ng-bootstrap/tree-select';
4
5
  import { DatatableSettings } from '@mintplayer/ng-bootstrap/datatable';
5
6
  import { PaginationResponse } from '@mintplayer/pagination';
6
7
  import { EntityType, ValidationError, PersistentObject, LookupReference, EntityAttributeDefinition, EntityPermissions, LookupReferenceValue, ELookupDisplayType, AttributeTab, AttributeGroup } from '@mintplayer/ng-spark/models';
@@ -20,6 +21,8 @@ declare class SparkPoFormComponent {
20
21
  cancel: _angular_core.OutputEmitterRef<void>;
21
22
  colors: typeof Color;
22
23
  referenceOptions: _angular_core.WritableSignal<Record<string, PersistentObject[]>>;
24
+ referenceProviders: _angular_core.WritableSignal<Record<string, InMemoryTreeSelectProvider>>;
25
+ referenceNodes: _angular_core.WritableSignal<Record<string, Record<string, TreeNode>>>;
23
26
  asDetailTypes: _angular_core.WritableSignal<Record<string, EntityType>>;
24
27
  lookupReferenceOptions: _angular_core.WritableSignal<Record<string, LookupReference>>;
25
28
  editingAsDetailAttr: _angular_core.WritableSignal<EntityAttributeDefinition | null>;
@@ -52,6 +55,15 @@ declare class SparkPoFormComponent {
52
55
  constructor();
53
56
  private toRecord;
54
57
  loadReferenceOptions(): Promise<void>;
58
+ /**
59
+ * Stable TreeNode[] value per multi-reference attribute, derived from the id array
60
+ * in formData and the resolved node map. Recomputes only when formData or the node
61
+ * map changes, so binding it into <bs-tree-select> doesn't churn on every CD pass.
62
+ * Ids without a resolved node fall back to a label of the id itself.
63
+ */
64
+ referenceTreeValues: _angular_core.Signal<Record<string, TreeNode[]>>;
65
+ getReferenceProvider(attr: EntityAttributeDefinition): InMemoryTreeSelectProvider | undefined;
66
+ onReferenceTreeChange(attr: EntityAttributeDefinition, value: TreeNode | TreeNode[] | null): void;
55
67
  loadAsDetailTypes(): Promise<void>;
56
68
  loadLookupReferenceOptions(): Promise<void>;
57
69
  getReferenceOptions(attr: EntityAttributeDefinition): PersistentObject[];