{"version":3,"file":"ngx-t-forms-document-picker.component-9clYsOcl.mjs","sources":["../../../projects/ngx-t-forms/src/lib/services/document-picker/document-filter.ts","../../../projects/ngx-t-forms/src/lib/services/document-picker/document-columns.ts","../../../projects/ngx-t-forms/src/lib/services/document-picker/document-query.store.ts","../../../projects/ngx-t-forms/src/lib/components/t-form-input/elements/document-picker/core/document-browser-dialog/document-browser-dialog.component.ts","../../../projects/ngx-t-forms/src/lib/components/t-form-input/elements/document-picker/core/document-browser-dialog/document-browser-dialog.component.html","../../../projects/ngx-t-forms/src/lib/components/t-form-input/elements/document-picker/core/document-picker-reactive-input/document-picker-reactive-input.component.ts","../../../projects/ngx-t-forms/src/lib/components/t-form-input/elements/document-picker/core/document-picker-reactive-input/document-picker-reactive-input.component.html","../../../projects/ngx-t-forms/src/lib/components/t-form-input/elements/document-picker/document-picker.component.ts","../../../projects/ngx-t-forms/src/lib/components/t-form-input/elements/document-picker/document-picker.component.html"],"sourcesContent":["import type {\r\n  DocumentPickerFilterValueType,\r\n  IDocumentPickerFilter,\r\n} from 'ngx-t-forms-types';\r\n\r\nimport { readDocumentIdentifier } from './document-reference';\r\n\r\n/** Inputs that together determine the filter sent with a document query. */\r\nexport interface DocumentFilterInput {\r\n  /** Administrator-configured clauses from the picker's builder config. */\r\n  readonly presetFilters?: readonly IDocumentPickerFilter[] | undefined;\r\n  /** Steps the picker is locked to, from the builder config. */\r\n  readonly lockedStepIds?: readonly string[] | undefined;\r\n  /** Step the user chose while browsing. Wins over {@link lockedStepIds}. */\r\n  readonly activeStepId?: string | null | undefined;\r\n  /** Current value of the parent form, keyed by input id, for `fromInputId` clauses. */\r\n  readonly formValue?: Readonly<Record<string, unknown>> | undefined;\r\n  /** Include archived transactions. Off by default. */\r\n  readonly includeArchived?: boolean | undefined;\r\n}\r\n\r\n/** `true` for values that mean \"the user has not chosen anything\". */\r\nfunction isEmptyValue(value: unknown): boolean {\r\n  if (value == null || value === '') return true;\r\n  return Array.isArray(value) && value.length === 0;\r\n}\r\n\r\n/** Escapes a string for safe literal use inside a regular expression. */\r\nfunction escapeRegExp(value: string): string {\r\n  return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n\r\n/** Applies the clause's declared value type to a single raw value. */\r\nfunction coerceValue(value: unknown, valueType: DocumentPickerFilterValueType | undefined): unknown {\r\n  if (value == null) return value;\r\n  if (valueType === 'number') {\r\n    const asNumber = Number(value);\r\n    return Number.isNaN(asNumber) ? value : asNumber;\r\n  }\r\n  if (valueType === 'boolean') {\r\n    if (typeof value === 'boolean') return value;\r\n    return String(value).trim().toLowerCase() === 'true';\r\n  }\r\n  return value;\r\n}\r\n\r\n/**\r\n * Resolves a clause's value list. `in` / `nin` accept an array as-is and split a\r\n * comma-separated string, so an administrator can type `draft, submitted` in the\r\n * builder without needing array syntax.\r\n */\r\nfunction coerceValueList(\r\n  value: unknown,\r\n  valueType: DocumentPickerFilterValueType | undefined,\r\n): unknown[] {\r\n  const raw = Array.isArray(value)\r\n    ? value\r\n    : String(value ?? '')\r\n        .split(',')\r\n        .map(part => part.trim())\r\n        .filter(part => part !== '');\r\n  return raw.map(entry => coerceValue(entry, valueType));\r\n}\r\n\r\n/**\r\n * Resolves which of the two mutually exclusive value sources a clause uses.\r\n *\r\n * An explicit `valueSource` always wins — that is the whole point of the switch:\r\n * an administrator who picked \"Fixed value\" gets the fixed value even if a stale\r\n * `fromInputId` is still sitting on the record. Only when `valueSource` is absent\r\n * — every filter saved before the switch existed — is the source inferred from\r\n * what was filled in, which is exactly the previous behaviour.\r\n */\r\nfunction isInputBound(preset: IDocumentPickerFilter): boolean {\r\n  if (preset.valueSource === 'input') return true;\r\n  if (preset.valueSource === 'fixed') return false;\r\n  return !!preset.fromInputId;\r\n}\r\n\r\n/**\r\n * Reads a clause's comparison value off the sibling input it is bound to.\r\n *\r\n * A sibling that is itself a document picker stores a whole reference object\r\n * (`{ id, workflowId, reference, label }`) for its chips, and that object is never a\r\n * valid comparison value: an `eq` clause becomes an exact-subdocument match against a\r\n * string field, `in` stringifies to `'[object Object]'`, `regex` escapes the same. All\r\n * three match nothing — and because `isEmptyValue` sees a populated object,\r\n * `omitWhenEmpty` does not drop the clause either, so the failure surfaces as an empty\r\n * browse dialog rather than an error. That is the whole point of narrowing here: it is\r\n * the difference between \"no transactions match\" and \"your filter is broken\".\r\n *\r\n * The test is structural because it has to be — the picker field holds only its own\r\n * config, so it cannot tell the builder that `fromInputId` names another picker. That\r\n * is safe at this call site specifically: a Mongo comparison value is always a scalar\r\n * or a scalar list, so a reference object here has no valid reading to protect.\r\n * Anything not recognisable as a stored link is passed through untouched.\r\n *\r\n * A multi-select source narrows to the identifier **list**, which is what the `in` /\r\n * `nin` operators want. Pair a multi-select picker with `eq` and the array reaches the\r\n * query as an array — a configuration mismatch this deliberately does not paper over\r\n * by rewriting the operator the administrator chose.\r\n *\r\n * @param formValue - Current value of the parent form, keyed by input id.\r\n * @param fromInputId - The sibling input the clause reads from.\r\n * @returns The comparison value, narrowed when it is a stored document link.\r\n */\r\nfunction readBoundValue(\r\n  formValue: Readonly<Record<string, unknown>> | undefined,\r\n  fromInputId: string | undefined,\r\n): unknown {\r\n  if (fromInputId === undefined) return undefined;\r\n  const stored = formValue?.[fromInputId];\r\n  return readDocumentIdentifier(stored) ?? stored;\r\n}\r\n\r\n/** Translates one resolved clause into its Mongo-style predicate. */\r\nfunction toPredicate(filter: IDocumentPickerFilter, value: unknown): unknown {\r\n  switch (filter.op ?? 'eq') {\r\n    case 'ne':\r\n      return { $ne: coerceValue(value, filter.valueType) };\r\n    case 'in':\r\n      return { $in: coerceValueList(value, filter.valueType) };\r\n    case 'nin':\r\n      return { $nin: coerceValueList(value, filter.valueType) };\r\n    case 'gt':\r\n      return { $gt: coerceValue(value, filter.valueType) };\r\n    case 'gte':\r\n      return { $gte: coerceValue(value, filter.valueType) };\r\n    case 'lt':\r\n      return { $lt: coerceValue(value, filter.valueType) };\r\n    case 'lte':\r\n      return { $lte: coerceValue(value, filter.valueType) };\r\n    case 'regex':\r\n      return { $regex: escapeRegExp(String(value ?? '')), $options: 'i' };\r\n    case 'exists':\r\n      return { $exists: coerceValue(value, 'boolean') !== false };\r\n    default:\r\n      return coerceValue(value, filter.valueType);\r\n  }\r\n}\r\n\r\n/**\r\n * Builds the filter object sent with a document query.\r\n *\r\n * Order is deliberate: the archive scope first, then the step restriction, then the\r\n * administrator's preset clauses. Presets are applied last so a picker can deliberately\r\n * widen the archive scope, and two presets on the same path resolve last-one-wins.\r\n *\r\n * Each preset takes its comparison value from exactly one source, chosen by its\r\n * `valueSource` and falling back to inference when that is absent (see\r\n * {@link isInputBound}). A clause bound to a sibling input with `omitWhenEmpty` is\r\n * dropped while that input is empty, rather than filtering on an empty value —\r\n * otherwise the picker would show an empty list before the user has filled in the\r\n * field it depends on. `omitWhenEmpty` is meaningless for a fixed value and is ignored\r\n * there. A clause bound to a sibling that is itself a document picker compares against\r\n * that picker's identifier, not its stored reference object — see {@link readBoundValue}.\r\n *\r\n * @param input - Builder configuration, the browsing step choice, and the parent form value.\r\n * @returns The filter for {@link IDocumentQueryRequest.filter}.\r\n */\r\nexport function buildDocumentFilter(input: DocumentFilterInput): Record<string, unknown> {\r\n  const filter: Record<string, unknown> = { archive: input.includeArchived === true };\r\n\r\n  const activeStepId = input.activeStepId ?? null;\r\n  const lockedStepIds = input.lockedStepIds ?? [];\r\n  if (activeStepId) {\r\n    filter['currentStep'] = activeStepId;\r\n  } else if (lockedStepIds.length === 1) {\r\n    filter['currentStep'] = lockedStepIds[0];\r\n  } else if (lockedStepIds.length > 1) {\r\n    filter['currentStep'] = { $in: [...lockedStepIds] };\r\n  }\r\n\r\n  for (const preset of input.presetFilters ?? []) {\r\n    if (!preset?.path) continue;\r\n    const boundToInput = isInputBound(preset);\r\n    const fromInputId = preset.fromInputId;\r\n    const rawValue = boundToInput\r\n      ? readBoundValue(input.formValue, fromInputId)\r\n      : preset.value;\r\n\r\n    if (boundToInput && preset.omitWhenEmpty && isEmptyValue(rawValue)) continue;\r\n\r\n    filter[preset.path] = toPredicate(preset, rawValue);\r\n  }\r\n\r\n  return filter;\r\n}\r\n\r\n/**\r\n * Builds the filter that hydrates an existing selection, whatever page — or step —\r\n * those documents currently sit on.\r\n *\r\n * @param ids - Selected document identifiers.\r\n * @param identifierPath - Path the ids were read from; `_id` unless the picker is\r\n *   configured with a different primary identifier key.\r\n * @returns A filter matching exactly those documents, or `undefined` when nothing is selected.\r\n */\r\nexport function buildSelectionFilter(\r\n  ids: readonly string[],\r\n  identifierPath: string,\r\n): Record<string, unknown> | undefined {\r\n  if (ids.length === 0) return undefined;\r\n  return { [identifierPath]: { $in: [...ids] } };\r\n}\r\n","import type { IWorkflowDocListCols } from 'ngx-t-forms-types';\r\nimport type { DocumentColumn } from '../../domain/document-picker/document-picker.model';\r\n\r\n/** Root-level document fields always present on a transaction, whatever the workflow. */\r\nconst REFERENCE_COLUMN: DocumentColumn = {\r\n  key: 'reference',\r\n  label: 'Reference',\r\n  path: 'reference',\r\n  type: undefined,\r\n  searchable: true,\r\n};\r\n\r\n/**\r\n * Column types that cannot back a free-text search, mapped to the type name the\r\n * search schema uses. Anything not listed is treated as text.\r\n */\r\nconst NON_TEXT_TYPES: ReadonlyArray<{ readonly match: string; readonly schemaType: string }> = [\r\n  { match: 'currency', schemaType: 'number' },\r\n  { match: 'number', schemaType: 'number' },\r\n  { match: 'daysago', schemaType: 'Date' },\r\n  { match: 'date', schemaType: 'Date' },\r\n  { match: 'bool', schemaType: 'boolean' },\r\n];\r\n\r\n/** Column type that is neither searchable nor a real form field. */\r\nconst SYSTEM_TYPE = 'systemreference';\r\n\r\n/**\r\n * Resolves a workflow's declared value type to the type name the search schema uses,\r\n * or `undefined` for columns that must be left out of the schema entirely.\r\n */\r\nfunction resolveSchemaType(type: IWorkflowDocListCols['type']): string | undefined {\r\n  const normalized = String(type ?? '').toLowerCase();\r\n  if (normalized === SYSTEM_TYPE) return undefined;\r\n  const nonText = NON_TEXT_TYPES.find(candidate => normalized.includes(candidate.match));\r\n  return nonText ? nonText.schemaType : 'string';\r\n}\r\n\r\n/**\r\n * Turns the workflow's raw list configuration into the columns the picker renders.\r\n *\r\n * Hidden columns are dropped, `reference` is prepended because every transaction has\r\n * one and it is what users actually recognise, and each column keeps the document\r\n * `path` so sorting and searching address the stored field rather than the bare\r\n * control name.\r\n *\r\n * @param cols - Column configuration as the host reports it.\r\n * @returns Display columns, `reference` first, in workflow order after that.\r\n */\r\nexport function resolveDocumentColumns(\r\n  cols: readonly IWorkflowDocListCols[] | undefined,\r\n): readonly DocumentColumn[] {\r\n  const resolved = (cols ?? [])\r\n    .filter(col => !col.hidden && col.formControlName !== REFERENCE_COLUMN.key)\r\n    .map<DocumentColumn>(col => ({\r\n      key: col.formControlName,\r\n      label: col.label || col.formControlName,\r\n      path: col.path,\r\n      type: col.type,\r\n      searchable: resolveSchemaType(col.type) === 'string',\r\n    }));\r\n  return [REFERENCE_COLUMN, ...resolved];\r\n}\r\n\r\n/**\r\n * Builds the path → type map that scopes a free-text search.\r\n *\r\n * This map is not optional decoration: a search term sent without it is silently\r\n * ignored by the server and an unfiltered page comes back, which reads to the user\r\n * as \"search is broken\" or, worse, as a filtered result set that is not filtered.\r\n *\r\n * @param columns - Resolved display columns.\r\n * @returns Path → type map covering every text column, always including `reference`.\r\n */\r\nexport function buildDocumentSearchSchema(\r\n  columns: readonly DocumentColumn[],\r\n): Record<string, string> {\r\n  const schema: Record<string, string> = { reference: 'string' };\r\n  for (const column of columns) {\r\n    const schemaType = resolveSchemaType(column.type);\r\n    if (!schemaType) continue;\r\n    schema[column.path] = schemaType;\r\n  }\r\n  return schema;\r\n}\r\n","import { DestroyRef, Injectable, computed, inject, signal } from '@angular/core';\r\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\r\nimport { catchError, distinctUntilChanged, forkJoin, map, of, switchMap, tap } from 'rxjs';\r\nimport type {\r\n  IDocumentPage,\r\n  IDocumentQueryRequest,\r\n  IWorkflowStepOption,\r\n} from 'ngx-t-forms-types';\r\nimport { DOCUMENT_REPOSITORY } from '../../tokens/document-repository.token';\r\nimport {\r\n  DEFAULT_DOCUMENT_PAGE_SIZE,\r\n  DEFAULT_DOCUMENT_SORT,\r\n  DocumentPickerConfigurationError,\r\n  type DocumentColumn,\r\n  type DocumentSort,\r\n} from '../../domain/document-picker/document-picker.model';\r\nimport { buildDocumentSearchSchema, resolveDocumentColumns } from './document-columns';\r\n\r\n/** Why the picker currently has nothing to show. */\r\nexport interface DocumentQueryError {\r\n  /**\r\n   * `configuration` means the picker can never work as set up — a missing host\r\n   * function or an unusable workflow — and retrying will not help. `query` means this\r\n   * particular request failed and retrying is worth offering.\r\n   */\r\n  readonly kind: 'configuration' | 'query';\r\n  readonly message: string;\r\n}\r\n\r\n/** Everything the picker needs to start querying a workflow. */\r\nexport interface DocumentQuerySetup {\r\n  readonly workflowId: string;\r\n  /** Step, preset and archive clauses, already resolved by the caller. */\r\n  readonly filter: Record<string, unknown>;\r\n  readonly pageSize?: number;\r\n}\r\n\r\n/** Snapshot compared to decide whether a new request is actually a new request. */\r\ninterface RequestKey {\r\n  readonly request: IDocumentQueryRequest | null;\r\n  readonly tick: number;\r\n}\r\n\r\n/**\r\n * Owns one document picker's query: which page, in what order, filtered how, matching\r\n * what search term.\r\n *\r\n * Every user action funnels into a single request, and that request is the only thing\r\n * that triggers a fetch — the picker never loads because a control gained focus or a\r\n * validator changed. Requests are switched, so a slow page can no longer overwrite the\r\n * page the user is actually looking at.\r\n *\r\n * Paging is keyset-based, so the cursor for page N is only known once page N-1 has been\r\n * read. The store keeps the cursors it has seen and moves one page at a time; anything\r\n * that invalidates them — a new sort, filter, search term or page size — resets paging\r\n * to the first page rather than sending a cursor the server would reject.\r\n *\r\n * @internal Provided per picker instance; not exported via public-api.ts.\r\n */\r\n@Injectable()\r\nexport class DocumentQueryStore {\r\n  readonly #repository = inject(DOCUMENT_REPOSITORY);\r\n  readonly #destroyRef = inject(DestroyRef);\r\n\r\n  readonly #workflowId = signal('');\r\n  readonly #filter = signal<Record<string, unknown>>({});\r\n  readonly #pageSize = signal(DEFAULT_DOCUMENT_PAGE_SIZE);\r\n  readonly #sort = signal<DocumentSort>(DEFAULT_DOCUMENT_SORT);\r\n  readonly #search = signal('');\r\n\r\n  /** Cursor for each page reached so far; index 0 is always the first page. */\r\n  readonly #cursors = signal<readonly (string | undefined)[]>([undefined]);\r\n  readonly #pageIndex = signal(0);\r\n  /** Bumped by {@link refresh} so an identical request is re-issued deliberately. */\r\n  readonly #tick = signal(0);\r\n\r\n  readonly #columns = signal<readonly DocumentColumn[]>([]);\r\n  readonly #columnsReady = signal(false);\r\n  readonly #steps = signal<readonly IWorkflowStepOption[]>([]);\r\n  readonly #rows = signal<readonly Record<string, unknown>[]>([]);\r\n  readonly #hasMore = signal(false);\r\n  readonly #totalItems = signal<number | undefined>(undefined);\r\n  readonly #totalPages = signal<number | undefined>(undefined);\r\n  readonly #loading = signal(false);\r\n  readonly #error = signal<DocumentQueryError | undefined>(undefined);\r\n\r\n  /** Documents on the current page, in server order. */\r\n  readonly rows = this.#rows.asReadonly();\r\n  /** Columns to render, resolved from the workflow's list configuration. */\r\n  readonly columns = this.#columns.asReadonly();\r\n  /** Workflow steps available to filter by. */\r\n  readonly steps = this.#steps.asReadonly();\r\n  /** `true` while a page or the workflow metadata is in flight. */\r\n  readonly loading = this.#loading.asReadonly();\r\n  /** Why nothing is shown, or `undefined` when the last request succeeded. */\r\n  readonly error = this.#error.asReadonly();\r\n  /** Active sort. */\r\n  readonly sort = this.#sort.asReadonly();\r\n  /** Active search term. */\r\n  readonly search = this.#search.asReadonly();\r\n  /** Page size in force. */\r\n  readonly pageSize = this.#pageSize.asReadonly();\r\n  /** Zero-based index of the page being shown. */\r\n  readonly pageIndex = this.#pageIndex.asReadonly();\r\n  /** Total matching records — known from the first page only, then remembered. */\r\n  readonly totalItems = this.#totalItems.asReadonly();\r\n  /** Total pages for the current query, when the source reports it. */\r\n  readonly totalPages = this.#totalPages.asReadonly();\r\n\r\n  /** `true` when a further page exists after the current one. */\r\n  readonly canGoNext = computed(() => this.#hasMore() && !this.#loading());\r\n  /** `true` when the current page is not the first. */\r\n  readonly canGoPrevious = computed(() => this.#pageIndex() > 0 && !this.#loading());\r\n  /** `true` when the query succeeded and matched nothing. */\r\n  readonly isEmpty = computed(\r\n    () => !this.#loading() && !this.#error() && this.#rows().length === 0,\r\n  );\r\n\r\n  /** The request for the current state, or `null` while the store is not ready to query. */\r\n  readonly #request = computed<IDocumentQueryRequest | null>(() => {\r\n    const workflowId = this.#workflowId();\r\n    if (!workflowId || !this.#columnsReady()) return null;\r\n\r\n    const sort = this.#sort();\r\n    const searchKey = this.#search().trim();\r\n    const cursor = this.#cursors()[this.#pageIndex()];\r\n\r\n    return {\r\n      workflowId,\r\n      itemsPerPage: this.#pageSize(),\r\n      ...(cursor === undefined ? {} : { cursor }),\r\n      sort: { [sort.path]: sort.direction },\r\n      filter: this.#filter(),\r\n      ...(searchKey === ''\r\n        ? {}\r\n        : { searchKey, schema: buildDocumentSearchSchema(this.#columns()) }),\r\n    };\r\n  });\r\n\r\n  constructor() {\r\n    this.#watchWorkflow();\r\n    this.#watchRequest();\r\n  }\r\n\r\n  /**\r\n   * Points the store at a workflow and its resolved filter. Safe to call on every\r\n   * change-detection pass: identical setup is ignored, and a genuinely new filter\r\n   * resets paging because outstanding cursors no longer describe the same result set.\r\n   *\r\n   * @param setup - Workflow, resolved filter clauses, and optional page size.\r\n   */\r\n  configure(setup: DocumentQuerySetup): void {\r\n    if (setup.pageSize && setup.pageSize !== this.#pageSize()) {\r\n      this.#pageSize.set(setup.pageSize);\r\n      this.#resetPaging();\r\n    }\r\n    if (!sameFilter(this.#filter(), setup.filter)) {\r\n      this.#filter.set({ ...setup.filter });\r\n      this.#resetPaging();\r\n    }\r\n    if (setup.workflowId !== this.#workflowId()) {\r\n      this.#workflowId.set(setup.workflowId);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Sorts by a document path. Re-selecting the active path flips its direction.\r\n   *\r\n   * @param path - Document path from a {@link DocumentColumn}, never a bare control name.\r\n   */\r\n  setSort(path: string): void {\r\n    if (!path) return;\r\n    const current = this.#sort();\r\n    const direction: DocumentSort['direction'] =\r\n      current.path === path && current.direction === -1 ? 1 : -1;\r\n    this.#sort.set({ path, direction });\r\n    this.#resetPaging();\r\n  }\r\n\r\n  /**\r\n   * Applies a search term. Callers debounce their input; the store issues one request\r\n   * per term it is given.\r\n   *\r\n   * @param term - Raw search text; blank clears the search.\r\n   */\r\n  setSearch(term: string): void {\r\n    const next = term ?? '';\r\n    if (next === this.#search()) return;\r\n    this.#search.set(next);\r\n    this.#resetPaging();\r\n  }\r\n\r\n  /** Changes the page size, returning to the first page. */\r\n  setPageSize(size: number): void {\r\n    if (size <= 0 || size === this.#pageSize()) return;\r\n    this.#pageSize.set(size);\r\n    this.#resetPaging();\r\n  }\r\n\r\n  /** Advances one page, if the last response reported another. */\r\n  nextPage(): void {\r\n    if (!this.canGoNext()) return;\r\n    this.#pageIndex.update(index => index + 1);\r\n  }\r\n\r\n  /** Steps back one page. */\r\n  previousPage(): void {\r\n    if (!this.canGoPrevious()) return;\r\n    this.#pageIndex.update(index => index - 1);\r\n  }\r\n\r\n  /** Returns to the first page without disturbing sort, filter or search. */\r\n  firstPage(): void {\r\n    if (this.#pageIndex() === 0) return;\r\n    this.#resetPaging();\r\n  }\r\n\r\n  /** Re-issues the current request, discarding any page cursors beyond the first. */\r\n  refresh(): void {\r\n    this.#resetPaging();\r\n    this.#tick.update(tick => tick + 1);\r\n  }\r\n\r\n  /** Drops every cursor and returns to the first page. */\r\n  #resetPaging(): void {\r\n    this.#cursors.set([undefined]);\r\n    this.#pageIndex.set(0);\r\n    this.#totalItems.set(undefined);\r\n    this.#totalPages.set(undefined);\r\n  }\r\n\r\n  /** Loads the workflow's columns and steps whenever the workflow changes. */\r\n  #watchWorkflow(): void {\r\n    toObservable(this.#workflowId)\r\n      .pipe(\r\n        distinctUntilChanged(),\r\n        tap(() => {\r\n          this.#columnsReady.set(false);\r\n          this.#columns.set([]);\r\n          this.#steps.set([]);\r\n          this.#rows.set([]);\r\n          this.#error.set(undefined);\r\n          this.#resetPaging();\r\n        }),\r\n        switchMap(workflowId => {\r\n          if (!workflowId) return of(null);\r\n          this.#loading.set(true);\r\n          return forkJoin({\r\n            columns: this.#repository.getColumns(workflowId),\r\n            steps: this.#repository.getSteps(workflowId),\r\n          }).pipe(\r\n            map(result => ({\r\n              columns: resolveDocumentColumns(result.columns),\r\n              steps: result.steps,\r\n            })),\r\n            catchError(error => {\r\n              this.#loading.set(false);\r\n              this.#error.set(toQueryError(error));\r\n              return of(null);\r\n            }),\r\n          );\r\n        }),\r\n        takeUntilDestroyed(this.#destroyRef),\r\n      )\r\n      .subscribe(result => {\r\n        if (!result) return;\r\n        this.#columns.set(result.columns);\r\n        this.#steps.set([...result.steps]);\r\n        this.#columnsReady.set(true);\r\n      });\r\n  }\r\n\r\n  /** Runs the current request, switching away from any request still in flight. */\r\n  #watchRequest(): void {\r\n    toObservable(\r\n      computed<RequestKey>(() => ({ request: this.#request(), tick: this.#tick() })),\r\n    )\r\n      .pipe(\r\n        distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),\r\n        switchMap(({ request }) => {\r\n          if (!request) {\r\n            this.#loading.set(false);\r\n            return of(null);\r\n          }\r\n          this.#loading.set(true);\r\n          this.#error.set(undefined);\r\n          return this.#repository.query(request).pipe(\r\n            catchError(error => {\r\n              this.#error.set(toQueryError(error));\r\n              return of(null);\r\n            }),\r\n          );\r\n        }),\r\n        takeUntilDestroyed(this.#destroyRef),\r\n      )\r\n      .subscribe(page => {\r\n        this.#loading.set(false);\r\n        if (!page) {\r\n          if (this.#error()) this.#rows.set([]);\r\n          return;\r\n        }\r\n        this.#applyPage(page);\r\n      });\r\n  }\r\n\r\n  /** Records a page and the cursor that reaches the page after it. */\r\n  #applyPage(page: IDocumentPage): void {\r\n    this.#rows.set(page.items ?? []);\r\n    this.#hasMore.set(page.hasMore === true);\r\n\r\n    // Totals come back on the first page only; hold on to them for later pages.\r\n    if (typeof page.totalItems === 'number') this.#totalItems.set(page.totalItems);\r\n    if (typeof page.totalPages === 'number') this.#totalPages.set(page.totalPages);\r\n\r\n    const nextIndex = this.#pageIndex() + 1;\r\n    const cursors = [...this.#cursors()];\r\n    if (page.hasMore && page.nextCursor) {\r\n      cursors[nextIndex] = page.nextCursor;\r\n    } else {\r\n      cursors.length = nextIndex;\r\n    }\r\n    this.#cursors.set(cursors);\r\n  }\r\n}\r\n\r\n/** Shallow-compares two filters by their serialized form. */\r\nfunction sameFilter(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\r\n  return JSON.stringify(a) === JSON.stringify(b);\r\n}\r\n\r\n/** Classifies a thrown value so the UI knows whether retrying can help. */\r\nfunction toQueryError(error: unknown): DocumentQueryError {\r\n  if (error instanceof DocumentPickerConfigurationError) {\r\n    return { kind: 'configuration', message: error.message };\r\n  }\r\n  const message =\r\n    (error as { error?: { message?: string } })?.error?.message ??\r\n    (error instanceof Error ? error.message : 'Could not load transactions.');\r\n  return { kind: 'query', message };\r\n}\r\n","import {\r\n  ChangeDetectionStrategy,\r\n  Component,\r\n  DestroyRef,\r\n  ViewEncapsulation,\r\n  computed,\r\n  inject,\r\n  signal,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\r\nimport { debounceTime, distinctUntilChanged, map } from 'rxjs';\r\n\r\nimport type { IDocumentReference, IWorkflowStepOption } from 'ngx-t-forms-types';\r\n\r\nimport type {\r\n  DocumentBrowserDialogData,\r\n  DocumentBrowserDialogResult,\r\n} from '../../../../../../domain/document-picker/document-browser-dialog.model';\r\nimport type { DocumentColumn } from '../../../../../../domain/document-picker/document-picker.model';\r\nimport { buildSelectionFilter } from '../../../../../../services/document-picker/document-filter';\r\nimport { readDocumentPath } from '../../../../../../services/document-picker/document-path';\r\nimport { DocumentQueryStore } from '../../../../../../services/document-picker/document-query.store';\r\nimport {\r\n  readDocumentId,\r\n  toDocumentReference,\r\n} from '../../../../../../services/document-picker/document-reference';\r\nimport { FormatDataPipe } from '../../../../../../shared/pipes/format-Data.pipe';\r\n\r\n/** How long the search box waits after the last keystroke before querying. */\r\nconst SEARCH_DEBOUNCE_MS = 350;\r\n\r\n/** Page sizes offered in the footer. The active size is merged in when it differs. */\r\nconst PAGE_SIZE_OPTIONS: readonly number[] = [5, 10, 25, 50];\r\n\r\n/**\r\n * Root-level field naming the workflow step a transaction currently sits on. It is a\r\n * root field, so the document path is the field name itself — nothing is nested.\r\n */\r\nconst CURRENT_STEP_PATH = 'currentStepID';\r\n\r\n/**\r\n * Number of colour slots in the step palette (see `--dbd-step-hue-0…7` in the\r\n * stylesheet). A step's slot is its process-tree index modulo this count, so the\r\n * palette must not shrink without re-checking that adjacent steps stay distinguishable.\r\n */\r\nconst STEP_HUE_COUNT = 8;\r\n\r\n/** Direction a header cell reports to assistive technology. */\r\ntype AriaSort = 'ascending' | 'descending' | 'none';\r\n\r\n/** What the Step column renders for one row. */\r\ninterface StepPill {\r\n  /** Text shown in the pill and repeated in its `title`. Never blank. */\r\n  readonly label: string;\r\n  /**\r\n   * Palette slot, or `undefined` when the step is unknown and the pill is neutral.\r\n   * Bound as `data-step-hue`, which the stylesheet turns into a tinted surface.\r\n   */\r\n  readonly hue: number | undefined;\r\n}\r\n\r\n/**\r\n * Modal browser for a workflow's transactions, opened by the document picker so the\r\n * user can find and link one — or several — cross-referenced documents.\r\n *\r\n * The dialog owns nothing but the user's in-progress selection: the query itself lives\r\n * in a per-instance {@link DocumentQueryStore}, so browsing (sorting, paging, searching,\r\n * step filtering) never touches the form control. The caller's value changes only when\r\n * the user confirms, and dismissing the dialog leaves it untouched.\r\n *\r\n * Selecting a row is deliberately inert: it mutates the local selection and nothing\r\n * else, so the list can never collapse or reload underneath the user mid-pick. To\r\n * review a selection spread across pages, the \"Selected\" toggle re-queries by\r\n * identifier instead.\r\n *\r\n * Opened with {@link DocumentBrowserDialogData} and closed with\r\n * {@link DocumentBrowserDialogResult}.\r\n *\r\n * @internal Opened by the document picker; not exported via public-api.ts.\r\n */\r\n@Component({\r\n  selector: 'lib-document-browser-dialog',\r\n  templateUrl: './document-browser-dialog.component.html',\r\n  styleUrl: './document-browser-dialog.component.css',\r\n  changeDetection: ChangeDetectionStrategy.OnPush,\r\n  encapsulation: ViewEncapsulation.Emulated,\r\n  host: { 'class': 'lib-document-browser-dialog' },\r\n  imports: [\r\n    MatDialogModule,\r\n    MatButtonModule,\r\n    MatIconModule,\r\n    MatProgressSpinnerModule,\r\n    FormatDataPipe,\r\n  ],\r\n  providers: [DocumentQueryStore],\r\n})\r\nexport class DocumentBrowserDialogComponent {\r\n  /** Query state for this dialog only — provided per instance, never shared. */\r\n  protected readonly store = inject(DocumentQueryStore);\r\n\r\n  readonly #data = inject<DocumentBrowserDialogData>(MAT_DIALOG_DATA);\r\n  readonly #dialogRef =\r\n    inject<MatDialogRef<DocumentBrowserDialogComponent, DocumentBrowserDialogResult>>(\r\n      MatDialogRef,\r\n    );\r\n  readonly #destroyRef = inject(DestroyRef);\r\n\r\n  /** Selection as the user has it right now; seeded from what is already linked. */\r\n  readonly #selection = signal<readonly IDocumentReference[]>([...this.#data.selection]);\r\n  /** Step the user chose to browse, or `undefined` for the picker's own step scope. */\r\n  readonly #activeStepId = signal<string | undefined>(undefined);\r\n  /** `true` while the list is filtered down to the selected documents. */\r\n  readonly #selectedOnly = signal(false);\r\n  /** Raw search box text, before debouncing. */\r\n  readonly #searchTerm = signal('');\r\n\r\n  /** Identifiers of the selected documents, for row-by-row comparison. */\r\n  readonly #selectedIds = computed<ReadonlySet<string>>(\r\n    () => new Set(this.#selection().map(entry => entry.id)),\r\n  );\r\n\r\n  /**\r\n   * Steps keyed by identifier, so a row resolves its step with one map lookup instead\r\n   * of scanning the step list on every change-detection pass.\r\n   */\r\n  readonly #stepsById = computed<ReadonlyMap<string, IWorkflowStepOption>>(\r\n    () => new Map(this.store.steps().map(step => [step.stepId, step])),\r\n  );\r\n\r\n  /**\r\n   * Column a reference is labelled by: the first searchable text column after\r\n   * `reference`, which is the one a user recognises a transaction from.\r\n   */\r\n  readonly #labelColumn = computed<DocumentColumn | undefined>(() =>\r\n    this.store.columns().find(column => column.searchable && column.path !== 'reference'),\r\n  );\r\n\r\n  /** Dialog heading — the picker's own label. */\r\n  protected readonly title: string = this.#data.title;\r\n\r\n  /** Whether more than one transaction may be linked. */\r\n  protected readonly allowMultiple: boolean = this.#data.allowMultiple;\r\n\r\n  /** Current search text, mirrored back into the input. */\r\n  protected readonly searchTerm = this.#searchTerm.asReadonly();\r\n\r\n  /** Step currently browsed, or `undefined` for \"Any step\". */\r\n  protected readonly activeStepId = this.#activeStepId.asReadonly();\r\n\r\n  /** `true` while the list shows only the selected documents. */\r\n  protected readonly selectedOnly = this.#selectedOnly.asReadonly();\r\n\r\n  /** Document path the Step column sorts on. */\r\n  protected readonly stepPath: string = CURRENT_STEP_PATH;\r\n\r\n  /**\r\n   * Whether to render the Step column at all. Without the workflow's steps every pill\r\n   * would read \"unknown\", which tells the user less than no column does — so when the\r\n   * host has not implemented `getWorkflowSteps` the column is dropped, header included.\r\n   */\r\n  protected readonly showStepColumn = computed<boolean>(() => this.store.steps().length > 0);\r\n\r\n  /** How many transactions are selected. */\r\n  protected readonly selectedCount = computed<number>(() => this.#selection().length);\r\n\r\n  /**\r\n   * Whether to offer the step chooser. A picker locked to exactly one step has no\r\n   * choice to make, so the control is not rendered at all.\r\n   */\r\n  protected readonly showStepChooser = computed<boolean>(\r\n    () => this.#data.lockedStepIds.length !== 1 && this.store.steps().length > 0,\r\n  );\r\n\r\n  /**\r\n   * Whether to offer the \"Selected\" filter. It stays visible while the filter is on\r\n   * even after the last row is deselected, so the user is never stranded in a\r\n   * filtered view with no way back.\r\n   */\r\n  protected readonly showSelectedFilter = computed<boolean>(\r\n    () => this.selectedCount() > 0 || this.#selectedOnly(),\r\n  );\r\n\r\n  /** Page sizes offered, always including whichever size is currently in force. */\r\n  protected readonly pageSizeOptions = computed<readonly number[]>(() =>\r\n    [...new Set([...PAGE_SIZE_OPTIONS, this.store.pageSize()])].sort((a, b) => a - b),\r\n  );\r\n\r\n  /**\r\n   * Position of the visible rows in the result set, e.g. `Showing 11–20 of 412`.\r\n   * Keyset paging cannot always know the total, in which case the total is omitted\r\n   * rather than guessed. Empty while there is nothing to place.\r\n   */\r\n  protected readonly positionLabel = computed<string>(() => {\r\n    const count = this.store.rows().length;\r\n    if (count === 0) return '';\r\n    const start = this.store.pageIndex() * this.store.pageSize() + 1;\r\n    const end = start + count - 1;\r\n    const total = this.store.totalItems();\r\n    return total === undefined\r\n      ? `Showing ${start}–${end}`\r\n      : `Showing ${start}–${end} of ${total}`;\r\n  });\r\n\r\n  constructor() {\r\n    this.store.configure({\r\n      workflowId: this.#data.workflowId,\r\n      filter: this.#browseFilter(),\r\n      pageSize: this.#data.pageSize,\r\n    });\r\n\r\n    // The store issues one request per term it is handed, so the debounce lives here.\r\n    toObservable(this.#searchTerm)\r\n      .pipe(\r\n        debounceTime(SEARCH_DEBOUNCE_MS),\r\n        map(term => term.trim()),\r\n        distinctUntilChanged(),\r\n        takeUntilDestroyed(this.#destroyRef),\r\n      )\r\n      .subscribe(term => this.store.setSearch(term));\r\n  }\r\n\r\n  /** Reads a cell's raw value from the stored document, which is never flattened. */\r\n  protected cell(row: Record<string, unknown>, column: DocumentColumn): unknown {\r\n    return readDocumentPath(row, column.path);\r\n  }\r\n\r\n  /** Stable identity for a row, falling back to its position when it carries no id. */\r\n  protected rowKey(row: Record<string, unknown>, index: number): string {\r\n    return readDocumentId(row, this.#data.identifierPath) ?? `row-${index}`;\r\n  }\r\n\r\n  /** `true` when a row is part of the current selection. */\r\n  protected isSelected(row: Record<string, unknown>): boolean {\r\n    const id = readDocumentId(row, this.#data.identifierPath);\r\n    return id !== undefined && this.#selectedIds().has(id);\r\n  }\r\n\r\n  /** Accessible name for a row's selection control. */\r\n  protected rowLabel(row: Record<string, unknown>): string {\r\n    const reference = readDocumentPath(row, 'reference');\r\n    const id = readDocumentId(row, this.#data.identifierPath);\r\n    const name = reference == null || reference === '' ? id : String(reference);\r\n    return name === undefined ? 'Select transaction' : `Select transaction ${name}`;\r\n  }\r\n\r\n  /**\r\n   * Resolves the Step pill for one row.\r\n   *\r\n   * The colour is the step's `index` — its position in the workflow's process tree —\r\n   * modulo {@link STEP_HUE_COUNT}. Tying it to the process tree, and never to the row's\r\n   * position on the current page, is what makes a step the same colour on every row, on\r\n   * every page and on every reopen: the same workflow always hands back the same index.\r\n   *\r\n   * Colour is only ever a second signal — the pill always carries the step's name.\r\n   */\r\n  protected stepPill(row: Record<string, unknown>): StepPill {\r\n    const raw = readDocumentPath(row, CURRENT_STEP_PATH);\r\n    const stepId =\r\n      typeof raw === 'string' ? raw.trim() : typeof raw === 'number' ? String(raw) : '';\r\n\r\n    const step = stepId === '' ? undefined : this.#stepsById().get(stepId);\r\n    if (step === undefined) {\r\n      // Say what is actually known: the raw id when the document carries one, and an\r\n      // honest \"unknown\" when it does not. Never an empty pill.\r\n      return { label: stepId === '' ? 'Unknown step' : stepId, hue: undefined };\r\n    }\r\n\r\n    // The contract types `label` as a string, but the host supplies it: a workflow with\r\n    // an unnamed step must still produce a pill, so fall back to the id rather than\r\n    // rendering nothing.\r\n    const label = typeof step.label === 'string' ? step.label.trim() : '';\r\n    return {\r\n      label: label === '' ? step.stepId : label,\r\n      hue: stepHue(step.index),\r\n    };\r\n  }\r\n\r\n  /**\r\n   * `true` when a document path is the one currently sorted on.\r\n   *\r\n   * Path-based rather than column-based because the Step column is not part of\r\n   * `store.columns()`; the column-facing helpers delegate here so both share one rule.\r\n   */\r\n  protected isSortedPath(path: string): boolean {\r\n    return this.store.sort().path === path;\r\n  }\r\n\r\n  /** `true` when a column is the one currently sorted on. */\r\n  protected isSorted(column: DocumentColumn): boolean {\r\n    return this.isSortedPath(column.path);\r\n  }\r\n\r\n  /** Sort state a header cell reports; only the active path reports a direction. */\r\n  protected ariaSortPath(path: string): AriaSort {\r\n    if (!this.isSortedPath(path)) return 'none';\r\n    return this.store.sort().direction === 1 ? 'ascending' : 'descending';\r\n  }\r\n\r\n  /** Sort state a column's header cell reports. */\r\n  protected ariaSort(column: DocumentColumn): AriaSort {\r\n    return this.ariaSortPath(column.path);\r\n  }\r\n\r\n  /** Glyph for the active sort direction. */\r\n  protected sortIcon(): string {\r\n    return this.store.sort().direction === 1 ? 'arrow_upward' : 'arrow_downward';\r\n  }\r\n\r\n  /** Sorts by a document path, flipping direction when it is already the active one. */\r\n  protected sortByPath(path: string): void {\r\n    this.store.setSort(path);\r\n  }\r\n\r\n  /** Sorts by a column, flipping direction when it is already the active one. */\r\n  protected sortBy(column: DocumentColumn): void {\r\n    this.sortByPath(column.path);\r\n  }\r\n\r\n  /**\r\n   * Adds or removes a row from the selection. Multi-select toggles; single-select\r\n   * replaces, because a radio cannot be unset by re-clicking it — \"Clear\" is how a\r\n   * single selection is undone.\r\n   */\r\n  protected toggleRow(row: Record<string, unknown>): void {\r\n    const reference = toDocumentReference(row, {\r\n      workflowId: this.#data.workflowId,\r\n      identifierPath: this.#data.identifierPath,\r\n      labelColumn: this.#labelColumn(),\r\n    });\r\n    if (!reference) return;\r\n\r\n    if (!this.#data.allowMultiple) {\r\n      this.#selection.set([reference]);\r\n      return;\r\n    }\r\n\r\n    this.#selection.update(current => {\r\n      const without = current.filter(entry => entry.id !== reference.id);\r\n      return without.length === current.length ? [...current, reference] : without;\r\n    });\r\n  }\r\n\r\n  /** Drops the whole selection without disturbing the list. */\r\n  protected clearSelection(): void {\r\n    this.#selection.set([]);\r\n  }\r\n\r\n  /**\r\n   * Switches between browsing and reviewing the selection. Reviewing queries by\r\n   * identifier over the picker's own filter, so a selected transaction is found\r\n   * whatever page — or step — it currently sits on.\r\n   */\r\n  protected toggleSelectedOnly(): void {\r\n    this.#selectedOnly.update(active => !active);\r\n    this.#applyFilter();\r\n  }\r\n\r\n  /** Records the search box's text; the query follows once typing settles. */\r\n  protected onSearch(event: Event): void {\r\n    this.#searchTerm.set((event.target as HTMLInputElement).value);\r\n  }\r\n\r\n  /** Clears the search box, restoring the unsearched list. */\r\n  protected clearSearch(): void {\r\n    this.#searchTerm.set('');\r\n  }\r\n\r\n  /** Restores the picker's own step scope after the user narrowed to one step. */\r\n  protected clearStep(): void {\r\n    if (this.#activeStepId() === undefined) return;\r\n    this.#activeStepId.set(undefined);\r\n    this.#applyFilter();\r\n  }\r\n\r\n  /** Narrows the browse to one step, or restores the picker's own step scope. */\r\n  protected onStepChange(event: Event): void {\r\n    const value = (event.target as HTMLSelectElement).value;\r\n    this.#activeStepId.set(value === '' ? undefined : value);\r\n    this.#applyFilter();\r\n  }\r\n\r\n  /** Changes how many rows a page holds, returning to the first page. */\r\n  protected onPageSizeChange(event: Event): void {\r\n    const size = Number((event.target as HTMLSelectElement).value);\r\n    if (Number.isFinite(size)) this.store.setPageSize(size);\r\n  }\r\n\r\n  /** Re-issues the failed request. Only offered for failures retrying can fix. */\r\n  protected retry(): void {\r\n    this.store.refresh();\r\n  }\r\n\r\n  /** Dismisses without touching the caller's value. */\r\n  protected cancel(): void {\r\n    this.#dialogRef.close(undefined);\r\n  }\r\n\r\n  /** Closes, handing the selection back to the picker. */\r\n  protected confirm(): void {\r\n    this.#dialogRef.close(this.#selection());\r\n  }\r\n\r\n  /** The picker's filter plus whichever step the user chose to browse. */\r\n  #browseFilter(): Record<string, unknown> {\r\n    const stepId = this.#activeStepId();\r\n    return stepId ? { ...this.#data.filter, currentStep: stepId } : { ...this.#data.filter };\r\n  }\r\n\r\n  /** The filter the list should currently run under. */\r\n  #currentFilter(): Record<string, unknown> {\r\n    if (this.#selectedOnly()) {\r\n      const ids = this.#selection().map(entry => entry.id);\r\n      const selectionFilter = buildSelectionFilter(ids, this.#data.identifierPath);\r\n      if (selectionFilter) return { ...this.#data.filter, ...selectionFilter };\r\n    }\r\n    return this.#browseFilter();\r\n  }\r\n\r\n  /** Re-points the store at the filter in force, keeping the user's page size. */\r\n  #applyFilter(): void {\r\n    this.store.configure({\r\n      workflowId: this.#data.workflowId,\r\n      filter: this.#currentFilter(),\r\n      pageSize: this.store.pageSize(),\r\n    });\r\n  }\r\n}\r\n\r\n/**\r\n * Maps a step's process-tree index onto a palette slot.\r\n *\r\n * The modulo is normalised so a negative or fractional index — which a malformed\r\n * workflow can produce — still lands on a real slot instead of yielding `NaN` or a\r\n * negative attribute value that no stylesheet rule would match.\r\n *\r\n * @param index - Zero-based position of the step in the workflow's process tree.\r\n * @returns A slot in `0…STEP_HUE_COUNT - 1`.\r\n */\r\nfunction stepHue(index: number): number {\r\n  const whole = Number.isFinite(index) ? Math.trunc(index) : 0;\r\n  return ((whole % STEP_HUE_COUNT) + STEP_HUE_COUNT) % STEP_HUE_COUNT;\r\n}\r\n","<div class=\"dbd__header\">\r\n  <span class=\"dbd__header-icon\" aria-hidden=\"true\">\r\n    <mat-icon>link</mat-icon>\r\n  </span>\r\n  <div class=\"dbd__heading\">\r\n    <h2 mat-dialog-title class=\"dbd__title\">{{ title }}</h2>\r\n    <p class=\"dbd__subtitle\">\r\n      @if (allowMultiple) {\r\n        Search the workflow and pick every transaction this form should reference.\r\n      } @else {\r\n        Search the workflow and pick the transaction this form should reference.\r\n      }\r\n    </p>\r\n  </div>\r\n</div>\r\n\r\n<mat-dialog-content class=\"dbd__content\">\r\n  <div class=\"dbd__controls\">\r\n    <label class=\"dbd-field dbd-field--grow\">\r\n      <span class=\"dbd-field__label\">Search</span>\r\n      <input\r\n        class=\"dbd-field__control\"\r\n        type=\"search\"\r\n        autocomplete=\"off\"\r\n        placeholder=\"Reference, description…\"\r\n        [value]=\"searchTerm()\"\r\n        (input)=\"onSearch($event)\" />\r\n    </label>\r\n\r\n    @if (showStepChooser()) {\r\n      <label class=\"dbd-field\">\r\n        <span class=\"dbd-field__label\">Step</span>\r\n        <select\r\n          class=\"dbd-field__control\"\r\n          [disabled]=\"selectedOnly()\"\r\n          (change)=\"onStepChange($event)\">\r\n          <option value=\"\" [selected]=\"activeStepId() === undefined\">Any step</option>\r\n          @for (step of store.steps(); track step.stepId) {\r\n            <option [value]=\"step.stepId\" [selected]=\"step.stepId === activeStepId()\">\r\n              {{ step.label }}\r\n            </option>\r\n          }\r\n        </select>\r\n      </label>\r\n    }\r\n  </div>\r\n\r\n  @if (showSelectedFilter()) {\r\n    <div class=\"dbd__selection\">\r\n      <button\r\n        type=\"button\"\r\n        class=\"dbd-toggle\"\r\n        [class.dbd-toggle--on]=\"selectedOnly()\"\r\n        [attr.aria-pressed]=\"selectedOnly()\"\r\n        (click)=\"toggleSelectedOnly()\">\r\n        <mat-icon class=\"dbd-toggle__icon\" aria-hidden=\"true\">\r\n          {{ selectedOnly() ? 'visibility' : 'filter_list' }}\r\n        </mat-icon>\r\n        <span>Selected ({{ selectedCount() }})</span>\r\n      </button>\r\n\r\n      @if (selectedCount() > 0) {\r\n        <button type=\"button\" class=\"dbd-clear\" (click)=\"clearSelection()\">Clear</button>\r\n      }\r\n\r\n      @if (selectedOnly()) {\r\n        <span class=\"dbd__selection-hint\">Showing only what you have picked.</span>\r\n      }\r\n    </div>\r\n  }\r\n\r\n  @if (store.error(); as error) {\r\n    <div class=\"dbd-alert\" role=\"alert\">\r\n      <mat-icon class=\"dbd-alert__icon\" aria-hidden=\"true\">error_outline</mat-icon>\r\n      <div class=\"dbd-alert__body\">\r\n        <p class=\"dbd-alert__message\">{{ error.message }}</p>\r\n        @if (error.kind === 'configuration') {\r\n          <p class=\"dbd-alert__hint\">\r\n            This picker cannot run as it is set up, so retrying will not help. A form\r\n            builder or the host application needs to correct it.\r\n          </p>\r\n        }\r\n      </div>\r\n      @if (error.kind === 'query') {\r\n        <button matButton=\"outlined\" type=\"button\" class=\"dbd-alert__retry\" (click)=\"retry()\">\r\n          Retry\r\n        </button>\r\n      }\r\n    </div>\r\n  }\r\n\r\n  <div class=\"dbd__table-wrap\">\r\n    <div class=\"dbd__table-scroll\">\r\n      <!-- role=\"table\", not \"grid\": grid promises two-dimensional arrow-key\r\n           navigation, which this list does not implement. Each row's own control\r\n           is focusable and every header is a real button, so the table stays fully\r\n           keyboard-operable under the simpler role. -->\r\n      <table role=\"table\" class=\"dbd-table\" [attr.aria-label]=\"title\">\r\n        <thead class=\"dbd-table__head\">\r\n          <tr role=\"row\">\r\n            <th role=\"columnheader\" scope=\"col\" class=\"dbd-table__pick\">\r\n              <span class=\"dbd-sr-only\">Select</span>\r\n            </th>\r\n            <!--\r\n              Step sits ahead of the workflow's own columns and is not one of them: it\r\n              reads the transaction's root `currentStepID`, so it is sorted by path\r\n              rather than by a DocumentColumn. Hidden entirely when the host cannot\r\n              supply the workflow's steps.\r\n            -->\r\n            @if (showStepColumn()) {\r\n              <th\r\n                role=\"columnheader\"\r\n                scope=\"col\"\r\n                class=\"dbd-table__step\"\r\n                [attr.aria-sort]=\"ariaSortPath(stepPath)\">\r\n                <button\r\n                  type=\"button\"\r\n                  class=\"dbd-sort\"\r\n                  [class.dbd-sort--active]=\"isSortedPath(stepPath)\"\r\n                  (click)=\"sortByPath(stepPath)\">\r\n                  <span class=\"dbd-sort__label\">Step</span>\r\n                  @if (isSortedPath(stepPath)) {\r\n                    <mat-icon class=\"dbd-sort__icon\" aria-hidden=\"true\">{{ sortIcon() }}</mat-icon>\r\n                  }\r\n                </button>\r\n              </th>\r\n            }\r\n            @for (column of store.columns(); track column.key) {\r\n              <th role=\"columnheader\" scope=\"col\" [attr.aria-sort]=\"ariaSort(column)\">\r\n                <button\r\n                  type=\"button\"\r\n                  class=\"dbd-sort\"\r\n                  [class.dbd-sort--active]=\"isSorted(column)\"\r\n                  (click)=\"sortBy(column)\">\r\n                  <span class=\"dbd-sort__label\">{{ column.label }}</span>\r\n                  @if (isSorted(column)) {\r\n                    <mat-icon class=\"dbd-sort__icon\" aria-hidden=\"true\">{{ sortIcon() }}</mat-icon>\r\n                  }\r\n                </button>\r\n              </th>\r\n            }\r\n          </tr>\r\n        </thead>\r\n\r\n        <tbody>\r\n          @for (row of store.rows(); track rowKey(row, $index)) {\r\n            <tr\r\n              role=\"row\"\r\n              class=\"dbd-row\"\r\n              [class.dbd-row--selected]=\"isSelected(row)\"\r\n              [attr.aria-selected]=\"isSelected(row)\"\r\n              (click)=\"toggleRow(row)\">\r\n              <td class=\"dbd-table__pick\">\r\n                @if (allowMultiple) {\r\n                  <input\r\n                    class=\"dbd-pick\"\r\n                    type=\"checkbox\"\r\n                    [checked]=\"isSelected(row)\"\r\n                    [attr.aria-label]=\"rowLabel(row)\"\r\n                    (click)=\"$event.stopPropagation()\"\r\n                    (change)=\"toggleRow(row)\" />\r\n                } @else {\r\n                  <input\r\n                    class=\"dbd-pick\"\r\n                    type=\"radio\"\r\n                    name=\"dbd-selection\"\r\n                    [checked]=\"isSelected(row)\"\r\n                    [attr.aria-label]=\"rowLabel(row)\"\r\n                    (click)=\"$event.stopPropagation()\"\r\n                    (change)=\"toggleRow(row)\" />\r\n                }\r\n              </td>\r\n              @if (showStepColumn()) {\r\n                @let pill = stepPill(row);\r\n                <td class=\"dbd-cell dbd-table__step\">\r\n                  <!--\r\n                    The step's name is always the pill's text: the tint is a scanning\r\n                    aid, never the only way to tell one step from another.\r\n                  -->\r\n                  <span\r\n                    class=\"dbd-pill\"\r\n                    [class.dbd-pill--unknown]=\"pill.hue === undefined\"\r\n                    [attr.data-step-hue]=\"pill.hue\"\r\n                    [title]=\"pill.label\"\r\n                    >{{ pill.label }}</span\r\n                  >\r\n                </td>\r\n              }\r\n              @for (column of store.columns(); track column.key) {\r\n                <td class=\"dbd-cell\">\r\n                  <span class=\"dbd-cell__text\">\r\n                    {{ cell(row, column) | formatData: column.type }}\r\n                  </span>\r\n                </td>\r\n              }\r\n            </tr>\r\n          }\r\n        </tbody>\r\n      </table>\r\n\r\n      @if (store.isEmpty()) {\r\n        <!--\r\n          Never a bare \"no results\": name why the list is empty and offer the\r\n          control that undoes it, so the user is not left guessing which of the\r\n          search, the step or the field's own filters excluded everything.\r\n        -->\r\n        <div class=\"dbd-empty\">\r\n          <mat-icon class=\"dbd-empty__icon\" aria-hidden=\"true\">search_off</mat-icon>\r\n\r\n          @if (selectedOnly()) {\r\n            <p class=\"dbd-empty__title\">Nothing picked yet</p>\r\n            <p class=\"dbd-empty__hint\">\r\n              Switch off <strong>Selected</strong> to browse the workflow and pick\r\n              {{ allowMultiple ? 'transactions' : 'a transaction' }}.\r\n            </p>\r\n          } @else if (searchTerm()) {\r\n            <p class=\"dbd-empty__title\">No transactions match “{{ searchTerm() }}”</p>\r\n            <p class=\"dbd-empty__hint\">\r\n              Search covers the reference and the columns shown above. Check the spelling,\r\n              or try a shorter term.\r\n            </p>\r\n          } @else if (activeStepId()) {\r\n            <p class=\"dbd-empty__title\">No transactions are at this step</p>\r\n            <p class=\"dbd-empty__hint\">\r\n              Every transaction has moved on, or none has reached it yet. Try another step.\r\n            </p>\r\n          } @else {\r\n            <p class=\"dbd-empty__title\">No transactions to show</p>\r\n            <p class=\"dbd-empty__hint\">\r\n              This workflow has no transactions yet, or this field is set up to show only\r\n              some of them. If you expected results here, ask an administrator to check the\r\n              field's filters.\r\n            </p>\r\n          }\r\n\r\n          <div class=\"dbd-empty__actions\">\r\n            @if (searchTerm()) {\r\n              <button type=\"button\" class=\"dbd-step\" (click)=\"clearSearch()\">Clear search</button>\r\n            }\r\n            @if (activeStepId()) {\r\n              <button type=\"button\" class=\"dbd-step\" (click)=\"clearStep()\">Show all steps</button>\r\n            }\r\n            @if (selectedOnly()) {\r\n              <button type=\"button\" class=\"dbd-step\" (click)=\"toggleSelectedOnly()\">\r\n                Back to browsing\r\n              </button>\r\n            }\r\n          </div>\r\n        </div>\r\n      }\r\n    </div>\r\n\r\n    @if (store.loading()) {\r\n      <div class=\"dbd__overlay\" role=\"status\" aria-live=\"polite\">\r\n        <mat-spinner [diameter]=\"32\" />\r\n        <span class=\"dbd-sr-only\">Loading transactions</span>\r\n      </div>\r\n    }\r\n  </div>\r\n</mat-dialog-content>\r\n\r\n<!--\r\n  Pinned footer. Paging and the confirm actions sit outside the scroll region so\r\n  they stay reachable however many rows are loaded.\r\n-->\r\n<div class=\"dbd__footer\">\r\n  <div class=\"dbd__paging\">\r\n    <p class=\"dbd__position\" aria-live=\"polite\">{{ positionLabel() }}</p>\r\n\r\n    <div class=\"dbd__paging-controls\">\r\n      <label class=\"dbd-field dbd-field--inline\">\r\n        <span class=\"dbd-field__label\">Rows</span>\r\n        <select\r\n          class=\"dbd-field__control dbd-field__control--compact\"\r\n          (change)=\"onPageSizeChange($event)\">\r\n          @for (size of pageSizeOptions(); track size) {\r\n            <option value=\"{{ size }}\" [selected]=\"size === store.pageSize()\">{{ size }}</option>\r\n          }\r\n        </select>\r\n      </label>\r\n\r\n      <button\r\n        type=\"button\"\r\n        class=\"dbd-step\"\r\n        [disabled]=\"!store.canGoPrevious()\"\r\n        (click)=\"store.previousPage()\">\r\n        <mat-icon class=\"dbd-step__icon\" aria-hidden=\"true\">chevron_left</mat-icon>\r\n        <span>Previous</span>\r\n      </button>\r\n\r\n      <button\r\n        type=\"button\"\r\n        class=\"dbd-step\"\r\n        [disabled]=\"!store.canGoNext()\"\r\n        (click)=\"store.nextPage()\">\r\n        <span>Next</span>\r\n        <mat-icon class=\"dbd-step__icon\" aria-hidden=\"true\">chevron_right</mat-icon>\r\n      </button>\r\n    </div>\r\n  </div>\r\n\r\n  <mat-dialog-actions class=\"dbd__actions\">\r\n    <button matButton type=\"button\" (click)=\"cancel()\">Cancel</button>\r\n    <button matButton=\"filled\" type=\"button\" (click)=\"confirm()\">Done</button>\r\n  </mat-dialog-actions>\r\n</div>\r\n","import {\r\n  ChangeDetectionStrategy,\r\n  Component,\r\n  DestroyRef,\r\n  ElementRef,\r\n  ViewEncapsulation,\r\n  computed,\r\n  inject,\r\n  input,\r\n  signal,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { NgControl } from '@angular/forms';\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { MatFormFieldControl } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { take } from 'rxjs';\r\n\r\nimport type { FormColumnInputs, IDocumentReference } from 'ngx-t-forms-types';\r\n\r\nimport type {\r\n  DocumentBrowserDialogData,\r\n  DocumentBrowserDialogResult,\r\n} from '../../../../../../domain/document-picker/document-browser-dialog.model';\r\nimport { DEFAULT_DOCUMENT_PAGE_SIZE } from '../../../../../../domain/document-picker/document-picker.model';\r\nimport { TFormEngine } from '../../../../../../services/core/t-form-engine/t-form-engine';\r\nimport {\r\n  BaseCustomInput,\r\n  BaseCustomInputConfig,\r\n} from '../../../../../../services/core/t-input-controller/functions/baseCustomInput';\r\nimport { buildDocumentFilter } from '../../../../../../services/document-picker/document-filter';\r\nimport {\r\n  readDocumentReferences,\r\n  resolveIdentifierPath,\r\n  writeDocumentValue,\r\n} from '../../../../../../services/document-picker/document-reference';\r\nimport { DocumentBrowserDialogComponent } from '../document-browser-dialog/document-browser-dialog.component';\r\n\r\n/**\r\n * The value a document-picker control holds: one reference when the input links a\r\n * single transaction, a list when it allows several. Exported because it appears in\r\n * this component's base-class type argument; it is not part of the library's\r\n * public API surface.\r\n */\r\nexport type DocumentPickerValue = IDocumentReference | readonly IDocumentReference[];\r\n\r\nconst customInputConfig: BaseCustomInputConfig = {\r\n  controlType: 'lib-document-picker-reactive-input',\r\n  nextId: 0,\r\n};\r\n\r\n/**\r\n * Compact summary of the transactions a form field links to: one chip per linked\r\n * transaction plus a button that opens the browse dialog.\r\n *\r\n * The field itself queries nothing. Every reference it renders comes from the form\r\n * control, and every change comes back from {@link DocumentBrowserDialogComponent},\r\n * which owns searching, paging and step filtering. Display state is derived from the\r\n * control value alone — deliberately never from `stateChanges`, which also fires on\r\n * focus, blur, touch and `disabled` and previously turned every focus change into a\r\n * fresh round of network requests.\r\n *\r\n * @example\r\n *   <lib-document-picker-reactive-input [inputConfig]=\"config\" [formControlName]=\"config.id\" />\r\n */\r\n@Component({\r\n  selector: 'lib-document-picker-reactive-input',\r\n  templateUrl: './document-picker-reactive-input.component.html',\r\n  styleUrl: './document-picker-reactive-input.component.css',\r\n  changeDetection: ChangeDetectionStrategy.OnPush,\r\n  encapsulation: ViewEncapsulation.Emulated,\r\n  imports: [MatIconModule],\r\n  host: {\r\n    'class': 'lib-document-picker-input',\r\n    '[class.floating]': 'shouldLabelFloat',\r\n    '[id]': 'id',\r\n    '(focusin)': 'onFocusIn($event)',\r\n    '(focusout)': 'onFocusOut($event)',\r\n  },\r\n  // `useExisting` is banned for the library's own DI (CLAUDE.md §3), but Material's\r\n  // form-field contract requires `MatFormFieldControl` to resolve to *this component\r\n  // instance*: `useClass` would construct a second, unbound control. Accepted\r\n  // exception, matching every other custom input in this library.\r\n  providers: [{ provide: MatFormFieldControl, useExisting: DocumentPickerReactiveInputComponent }],\r\n})\r\nexport class DocumentPickerReactiveInputComponent extends BaseCustomInput<DocumentPickerValue> {\r\n  /** Builder configuration for this field: workflow, filters and selection mode. */\r\n  readonly inputConfig = input<FormColumnInputs | undefined>(undefined);\r\n\r\n  /** Line shown while nothing is linked. */\r\n  readonly emptyMessage = input<string>('No transactions linked');\r\n\r\n  readonly #dialog = inject(MatDialog);\r\n  readonly #destroyRef = inject(DestroyRef);\r\n\r\n  /**\r\n   * The form engine this picker is rendered inside, when there is one.\r\n   *\r\n   * Optional by necessity: the picker also renders in the builder's element preview\r\n   * and in portal-hosted contexts, where no engine is provided. Those keep the\r\n   * form-group fallback in {@link DocumentPickerReactiveInputComponent.#dependencyValues}.\r\n   */\r\n  readonly #engine = inject(TFormEngine, { optional: true });\r\n\r\n  /**\r\n   * Signal mirror of the control value. `BaseCustomInput` keeps the value on a plain\r\n   * field, so both write paths are overridden to feed this: {@link writeValue}, which\r\n   * the form uses, and the `value` setter, which every user edit goes through. That\r\n   * keeps the template reactive under OnPush without observing `stateChanges` — which\r\n   * also fires on focus, blur and touch, and has no business redrawing this field.\r\n   */\r\n  readonly #value = signal<DocumentPickerValue | null>(null);\r\n\r\n  /** Disabled state pushed by the reactive form, e.g. `control.disable()`. */\r\n  readonly #formDisabled = signal<boolean>(false);\r\n\r\n  constructor() {\r\n    super(\r\n      inject(NgControl, { self: true, optional: true }) as NgControl,\r\n      inject<ElementRef<HTMLElement>>(ElementRef),\r\n      customInputConfig,\r\n    );\r\n  }\r\n\r\n  /** References parsed out of the stored value, with the count it could not read. */\r\n  readonly #readResult = computed(() => readDocumentReferences(this.#value()));\r\n\r\n  /** Transactions currently linked, in stored order. */\r\n  protected readonly references = computed<readonly IDocumentReference[]>(\r\n    () => this.#readResult().references,\r\n  );\r\n\r\n  /** Stored entries that are not readable as references — surfaced, never dropped. */\r\n  protected readonly unreadable = computed<number>(() => this.#readResult().unreadable);\r\n\r\n  /** Whether this field links more than one transaction. */\r\n  protected readonly allowMultiple = computed<boolean>(\r\n    () => this.inputConfig()?.allowMultipleSelection === true,\r\n  );\r\n\r\n  /** Workflow whose transactions this field browses; empty when unconfigured. */\r\n  readonly #workflowId = computed<string>(\r\n    () => this.inputConfig()?.workflowPickerConfig?.workflowId ?? '',\r\n  );\r\n\r\n  /** `true` when the field accepts no edits — disabled by the form or by configuration. */\r\n  protected readonly interactionLocked = computed<boolean>(() => {\r\n    const config = this.inputConfig();\r\n    return this.#formDisabled() || config?.disabled === true || config?.readonly === true;\r\n  });\r\n\r\n  /** `true` when the builder never chose a workflow, so there is nothing to browse. */\r\n  protected readonly unconfigured = computed<boolean>(() => this.#workflowId() === '');\r\n\r\n  /** `true` when the browse dialog can actually be opened. */\r\n  protected readonly canBrowse = computed<boolean>(\r\n    () => !this.interactionLocked() && !this.unconfigured(),\r\n  );\r\n\r\n  /** Browse-button wording: replacing a single link reads differently from adding one. */\r\n  protected readonly browseLabel = computed<string>(() =>\r\n    !this.allowMultiple() && this.references().length > 0 ? 'Change' : 'Browse transactions',\r\n  );\r\n\r\n  /**\r\n   * `true` when the empty field should spell out how to fill it.\r\n   *\r\n   * Withheld when the field is read-only or has no workflow configured: in both cases\r\n   * the reader cannot act on the instructions, and telling them to press a button that\r\n   * is absent or disabled is worse than saying nothing.\r\n   */\r\n  protected readonly showSteps = computed<boolean>(\r\n    () => !this.interactionLocked() && !this.unconfigured(),\r\n  );\r\n\r\n  /** Calm one-liner naming how many stored links could not be read. */\r\n  protected readonly unreadableMessage = computed<string>(() => {\r\n    const count = this.unreadable();\r\n    return `${count} saved ${count === 1 ? 'link' : 'links'} could not be read`;\r\n  });\r\n\r\n  /** Current control value. */\r\n  override get value(): DocumentPickerValue | null {\r\n    return super.value;\r\n  }\r\n\r\n  /**\r\n   * Sets the control value, keeping the signal mirror in step with it.\r\n   *\r\n   * The mirror is updated first so anything reacting to the base setter's\r\n   * `stateChanges` — `empty`, for one — already sees the new selection.\r\n   */\r\n  override set value(next: DocumentPickerValue | null) {\r\n    this.#value.set(next);\r\n    super.value = next;\r\n  }\r\n\r\n  /** `true` when no transaction is linked, so the Material label floats correctly. */\r\n  override get empty(): boolean {\r\n    return this.references().length === 0;\r\n  }\r\n\r\n  /** Always floats: the field renders chips, not text, so there is nothing to overlap. */\r\n  override get shouldLabelFloat(): boolean {\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Accepts a value from the form and mirrors it into the signal the template reads.\r\n   *\r\n   * @param value - Stored value; `null` whenever the control is reset.\r\n   */\r\n  override writeValue(value: DocumentPickerValue): void {\r\n    super.writeValue(value);\r\n    this.#value.set(value ?? null);\r\n  }\r\n\r\n  /**\r\n   * Records the form's disabled state so the template can react to it.\r\n   *\r\n   * @param isDisabled - `true` while the control is disabled.\r\n   */\r\n  override setDisabledState(isDisabled: boolean): void {\r\n    super.setDisabledState(isDisabled);\r\n    this.#formDisabled.set(isDisabled);\r\n  }\r\n\r\n  /**\r\n   * A chip's leading text: the human reference, else the descriptive label, else the\r\n   * raw id. The fallback order matters — a chip should only show an internal id when\r\n   * there is genuinely nothing human to show.\r\n   */\r\n  protected chipReference(reference: IDocumentReference): string {\r\n    return reference.reference || reference.label || reference.id;\r\n  }\r\n\r\n  /**\r\n   * A chip's trailing text — the descriptive label shown beside the reference, so a\r\n   * linked transaction reads as \"SDBIP-0197 · Machinery and Equipment\" rather than a\r\n   * bare code the user has to recognise from memory.\r\n   *\r\n   * Empty unless it adds something: when there is no `reference` the label is already\r\n   * the leading text ({@link chipReference}), and a label identical to the reference\r\n   * would just be printed twice.\r\n   */\r\n  protected chipDetail(reference: IDocumentReference): string {\r\n    const label = reference.label?.trim() ?? '';\r\n    if (!reference.reference || label === '' || label === reference.reference) return '';\r\n    return label;\r\n  }\r\n\r\n  /** The chip as one line of text — for the unlink button's accessible name. */\r\n  protected chipLabel(reference: IDocumentReference): string {\r\n    const detail = this.chipDetail(reference);\r\n    const lead = this.chipReference(reference);\r\n    return detail === '' ? lead : `${lead} — ${detail}`;\r\n  }\r\n\r\n  /**\r\n   * Unlinks one transaction.\r\n   *\r\n   * @param index - Position of the chip in {@link references}.\r\n   */\r\n  protected removeReference(index: number): void {\r\n    if (this.interactionLocked()) return;\r\n    this.commitSelection(this.references().filter((_, position) => position !== index));\r\n  }\r\n\r\n  /**\r\n   * Opens the browse dialog and applies whatever selection it comes back with.\r\n   * A dismissal returns `undefined` and leaves the stored links untouched.\r\n   */\r\n  protected openBrowser(): void {\r\n    if (!this.canBrowse()) return;\r\n    const data = this.#buildDialogData();\r\n    if (!data) return;\r\n\r\n    this.#dialog\r\n      .open<DocumentBrowserDialogComponent, DocumentBrowserDialogData, DocumentBrowserDialogResult>(\r\n        DocumentBrowserDialogComponent,\r\n        {\r\n          data,\r\n          autoFocus: false,\r\n          restoreFocus: true,\r\n          // An explicit height is load-bearing, not cosmetic: the dialog is a flex\r\n          // column whose table is the only scroll region, and that resolves only\r\n          // against a definite panel height. Without it the footer is pushed below\r\n          // the fold and the panel itself scrolls.\r\n          width: 'min(60rem, 94vw)',\r\n          maxWidth: '94vw',\r\n          height: 'min(42rem, 86vh)',\r\n        },\r\n      )\r\n      .afterClosed()\r\n      .pipe(take(1), takeUntilDestroyed(this.#destroyRef))\r\n      .subscribe((result) => {\r\n        if (result === undefined) return;\r\n        this.commitSelection(result);\r\n      });\r\n  }\r\n\r\n  /**\r\n   * Writes a new selection to the form control.\r\n   *\r\n   * Only one change notification is emitted: `BaseCustomInput`'s `value` setter\r\n   * already calls `onChange`, so this deliberately assigns through that setter\r\n   * instead of calling `onChange` a second time. `onTouched` is called explicitly —\r\n   * choosing (or clearing) a link is the interaction that makes the field touched.\r\n   *\r\n   * @param references - The selection as the user left it.\r\n   */\r\n  protected commitSelection(references: readonly IDocumentReference[]): void {\r\n    this.value = writeDocumentValue(references, this.allowMultiple());\r\n    this.onTouched();\r\n  }\r\n\r\n  /** Assembles everything the browse dialog needs, or nothing when unconfigured. */\r\n  #buildDialogData(): DocumentBrowserDialogData | undefined {\r\n    const config = this.inputConfig();\r\n    const pickerConfig = config?.workflowPickerConfig;\r\n    if (!config || !pickerConfig?.workflowId) return undefined;\r\n\r\n    const lockedStepIds = pickerConfig.stepFilter?.stepIds ?? [];\r\n    return {\r\n      workflowId: pickerConfig.workflowId,\r\n      title: config.label || 'Transactions',\r\n      filter: buildDocumentFilter({\r\n        presetFilters: pickerConfig.presetFilters,\r\n        lockedStepIds,\r\n        formValue: this.#dependencyValues(),\r\n      }),\r\n      lockedStepIds,\r\n      allowMultiple: this.allowMultiple(),\r\n      identifierPath: resolveIdentifierPath(pickerConfig.primaryIdentifierKey),\r\n      pageSize: DEFAULT_DOCUMENT_PAGE_SIZE,\r\n      selection: this.references(),\r\n    };\r\n  }\r\n\r\n  /**\r\n   * The values a preset filter bound to a sibling input reads from, keyed by input id.\r\n   *\r\n   * Sourced from the engine rather than the surrounding `FormGroup`, because the two\r\n   * disagree in three ways that all surface as the same silent bug — a browse dialog\r\n   * that opens empty because a clause matched nothing:\r\n   *\r\n   * - **Scope.** `formGenerator` nests the form as root → one group per section →\r\n   *   controls, so `control.parent` is this picker's OWN section. A filter bound to an\r\n   *   input on another slide read `undefined` forever, even though the builder's input\r\n   *   selector happily offers those inputs. The engine's value is flat and whole-form.\r\n   * - **Disabled controls.** `FormGroup.value` omits them (`getRawValue()` does not).\r\n   *   That silently excluded exactly the fields worth filtering by — calculated and\r\n   *   read-only ones. The engine's value never consulted the disabled flag.\r\n   * - **Derived values.** A calculated or API-fetched value lives in the engine's\r\n   *   `#derived` graph; so do MultipleInput sub-row and mSCOA inner-input values. The\r\n   *   section group exposes none of them usefully.\r\n   *\r\n   * Both sources key by input id, which is what `fromInputId` stores, so nothing is\r\n   * translated. Ids are unique per form — the engine's own flat maps already rely on\r\n   * that — so flattening across slides introduces no collision.\r\n   *\r\n   * The fallback is not dead code: with no engine in scope this reproduces the previous\r\n   * behaviour exactly, which is the right answer for a preview that has no live form.\r\n   */\r\n  #dependencyValues(): Record<string, unknown> | undefined {\r\n    const fromEngine = this.#engine?.getFormValue();\r\n    if (isValueRecord(fromEngine)) return fromEngine;\r\n    return isValueRecord(this.ngControl?.control?.parent?.value)\r\n      ? (this.ngControl?.control?.parent?.value as Record<string, unknown>)\r\n      : undefined;\r\n  }\r\n}\r\n\r\n/** `true` for a plain object usable as an inputId-keyed value map. */\r\nfunction isValueRecord(value: unknown): value is Record<string, unknown> {\r\n  return value != null && typeof value === 'object' && !Array.isArray(value);\r\n}\r\n","<!--\r\n  The `lib-document-picker-reactive-input` class is the element `BaseCustomInput`\r\n  looks up to apply `aria-describedby`, so it must stay on this container.\r\n-->\r\n<div class=\"lib-document-picker-reactive-input doc-link\">\r\n  @if (references().length > 0) {\r\n    <!-- Linked: chips and the browse action share one wrapping row. -->\r\n    <div class=\"doc-link__row\">\r\n      <ul class=\"doc-link__chips\">\r\n        @for (reference of references(); track $index) {\r\n          <li class=\"doc-link__chip\">\r\n            <mat-icon class=\"doc-link__chip-icon\" aria-hidden=\"true\">description</mat-icon>\r\n            <span class=\"doc-link__chip-label\">{{ chipReference(reference) }}</span>\r\n            @if (chipDetail(reference); as detail) {\r\n              <span class=\"doc-link__chip-detail\" [title]=\"detail\">{{ detail }}</span>\r\n            }\r\n            <button\r\n              type=\"button\"\r\n              class=\"doc-link__chip-remove\"\r\n              [disabled]=\"interactionLocked()\"\r\n              [attr.aria-label]=\"'Unlink ' + chipLabel(reference)\"\r\n              (click)=\"removeReference($index)\"\r\n            >\r\n              <mat-icon>close</mat-icon>\r\n            </button>\r\n          </li>\r\n        }\r\n      </ul>\r\n\r\n      @if (!interactionLocked()) {\r\n        <button\r\n          type=\"button\"\r\n          class=\"doc-link__browse\"\r\n          [disabled]=\"!canBrowse()\"\r\n          (click)=\"openBrowser()\"\r\n        >\r\n          <mat-icon class=\"doc-link__browse-icon\" aria-hidden=\"true\">search</mat-icon>\r\n          <span>{{ browseLabel() }}</span>\r\n        </button>\r\n      }\r\n    </div>\r\n  } @else {\r\n    <!--\r\n      Empty: say what this field is for and exactly how to fill it, rather than\r\n      leaving a bare \"nothing here\" the user has to interpret. The steps are\r\n      suppressed when the field is read-only or unconfigured, because there is\r\n      then no action for this user to take.\r\n    -->\r\n    <div class=\"doc-link__guide\" [class.doc-link__guide--muted]=\"interactionLocked()\">\r\n      <p class=\"doc-link__guide-head\">\r\n        <mat-icon class=\"doc-link__guide-icon\" aria-hidden=\"true\">link</mat-icon>\r\n        <span class=\"doc-link__empty\">{{ emptyMessage() }}</span>\r\n      </p>\r\n\r\n      @if (showSteps()) {\r\n        <ol class=\"doc-link__steps\">\r\n          <li>\r\n            Choose <strong>{{ browseLabel() }}</strong> below to open the transaction list.\r\n          </li>\r\n          <li>\r\n            Search by reference or any listed column, and narrow the list by workflow step.\r\n          </li>\r\n          <li>\r\n            @if (allowMultiple()) {\r\n              Tick every transaction this form relates to, then choose <strong>Done</strong>.\r\n            } @else {\r\n              Select the transaction this form relates to, then choose <strong>Done</strong>.\r\n            }\r\n          </li>\r\n        </ol>\r\n      }\r\n\r\n      @if (!interactionLocked()) {\r\n        <button\r\n          type=\"button\"\r\n          class=\"doc-link__browse\"\r\n          [disabled]=\"!canBrowse()\"\r\n          (click)=\"openBrowser()\"\r\n        >\r\n          <mat-icon class=\"doc-link__browse-icon\" aria-hidden=\"true\">search</mat-icon>\r\n          <span>{{ browseLabel() }}</span>\r\n        </button>\r\n      }\r\n    </div>\r\n  }\r\n\r\n  @if (unreadable() > 0) {\r\n    <p class=\"doc-link__notice doc-link__notice--warn\" role=\"status\">\r\n      <mat-icon class=\"doc-link__notice-icon\" aria-hidden=\"true\">report_problem</mat-icon>\r\n      <span>\r\n        <strong>{{ unreadableMessage() }}</strong> — they were saved in an older format.\r\n        Re-link them here to fix this field.\r\n      </span>\r\n    </p>\r\n  }\r\n\r\n  @if (unconfigured() && !interactionLocked()) {\r\n    <p class=\"doc-link__notice doc-link__notice--warn\" role=\"status\">\r\n      <mat-icon class=\"doc-link__notice-icon\" aria-hidden=\"true\">report_problem</mat-icon>\r\n      <span>\r\n        <strong>No workflow is configured for this field</strong> — nothing can be linked\r\n        until an administrator opens this form in the Form Builder and chooses the\r\n        workflow whose transactions this field should reference.\r\n      </span>\r\n    </p>\r\n  }\r\n</div>\r\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, computed, input } from '@angular/core';\r\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport type { FormBuilderFunctions, ITowerStepColumn } from 'ngx-t-forms-types';\r\nimport { TFormInputStatusComponent } from '../../../t-form-input-status/t-form-input-status.component';\r\nimport { DocumentPickerReactiveInputComponent } from './core/document-picker-reactive-input/document-picker-reactive-input.component';\r\nimport { getInputErrorMessage } from '../../../../services/core/t-input-controller/functions/inputErrorMessage';\r\n\r\n/**\r\n * Wraps a document-picker control inside a `mat-form-field`, contributing the\r\n * label, hint, errors and prefix/suffix affordances. The control itself owns the\r\n * linked-transaction chips and the browse dialog.\r\n */\r\n@Component({\r\n  selector: 'lib-document-picker',\r\n  templateUrl: './document-picker.component.html',\r\n  styleUrl: './document-picker.component.css',\r\n  changeDetection: ChangeDetectionStrategy.OnPush,\r\n  encapsulation: ViewEncapsulation.Emulated,\r\n  imports: [\r\n    ReactiveFormsModule,\r\n    MatFormFieldModule,\r\n    MatIconModule,\r\n    MatButtonModule,\r\n    MatTooltipModule,\r\n    DocumentPickerReactiveInputComponent,\r\n    TFormInputStatusComponent,\r\n  ],\r\n})\r\nexport class DocumentPickerComponent {\r\n  /** Builder configuration for the field being rendered. */\r\n  readonly inputConfig = input.required<ITowerStepColumn>();\r\n\r\n  /** Form group holding the control this field writes to. */\r\n  readonly formGroup = input.required<FormGroup>();\r\n\r\n  /**\r\n   * `true` while the field renders inside the form builder rather than a live form.\r\n   * Declared because the element registry marks this renderer builder-aware and\r\n   * forwards it; the picker's presentation does not currently differ.\r\n   */\r\n  readonly editorMode = input<boolean>(false);\r\n\r\n  /**\r\n   * Builder callbacks forwarded by the element registry to builder-aware\r\n   * renderers. The picker no longer loads its own data — the browse dialog queries\r\n   * through the document repository — so nothing here consumes them.\r\n   */\r\n  readonly formBuilderFunctions = input<FormBuilderFunctions | undefined>(undefined);\r\n\r\n  /** First validation message to show under the field, if any. */\r\n  protected readonly errorMessage = computed(() =>\r\n    getInputErrorMessage(this.inputConfig(), this.formGroup()),\r\n  );\r\n}\r\n","<form [formGroup]=\"formGroup()\">\r\n  @if (inputConfig(); as inputConfig) {\r\n    <mat-form-field [appearance]=\"inputConfig.appearance || 'fill'\" subscriptSizing=\"dynamic\">\r\n      <mat-label>\r\n        {{ inputConfig.label }}\r\n        <lib-t-form-input-status [inputConfig]=\"inputConfig\"></lib-t-form-input-status>\r\n      </mat-label>\r\n\r\n      <lib-document-picker-reactive-input\r\n        [disabled]=\"!!inputConfig.disabled\"\r\n        [inputConfig]=\"inputConfig\"\r\n        [required]=\"inputConfig.required\"\r\n        [formControlName]=\"inputConfig.id\"\r\n      ></lib-document-picker-reactive-input>\r\n\r\n      @if (inputConfig.hintLabel || inputConfig.temporaryHint) {\r\n        <mat-hint class=\"inputHint\">\r\n          {{ inputConfig.temporaryHint || inputConfig.hintLabel }}\r\n        </mat-hint>\r\n      }\r\n\r\n      @if (!!errorMessage()) {\r\n        <mat-error class=\"oneLineTextEllipsis\" matTooltipClass=\"errorToolTip\">{{ errorMessage() }}</mat-error>\r\n      }\r\n\r\n      @if (inputConfig.prefixIcon) {\r\n        <mat-icon matPrefix>{{ inputConfig.prefixIcon }}</mat-icon>\r\n      }\r\n\r\n      @if (inputConfig.canReload?.canReload) {\r\n        <button\r\n          mat-icon-button\r\n          matTooltip=\"Click to refresh this field.\"\r\n          class=\"input-sync-button\"\r\n          (click)=\"inputConfig.canReload.emit()\"\r\n          matSuffix\r\n        >\r\n          <mat-icon>sync</mat-icon>\r\n        </button>\r\n      }\r\n\r\n      @if (inputConfig.suffixIcon) {\r\n        <mat-icon matSuffix>{{ inputConfig.suffixIcon }}</mat-icon>\r\n      }\r\n\r\n      @if (inputConfig.prefixText) {\r\n        <span class=\"affix-text\" matPrefix>{{ inputConfig.prefixText }}</span>\r\n      }\r\n      @if (inputConfig.suffixText) {\r\n        <span class=\"affix-text affix-text--suffix\" matSuffix>{{ inputConfig.suffixText }}</span>\r\n      }\r\n    </mat-form-field>\r\n  }\r\n</form>\r\n"],"names":["i1","i2","i4"],"mappings":"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"}