@solidev/data 1.1.0 → 1.1.1

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":"solidev-data.mjs","sources":["../../../projects/data/src/lib/data/data-parameters.ts","../../../projects/data/src/lib/data/field-values.ts","../../../projects/data/src/lib/data/fields/base.ts","../../../projects/data/src/lib/data/fields/primaryfield.ts","../../../projects/data/src/lib/data/data-model.ts","../../../projects/data/src/lib/data/data-query.ts","../../../projects/data/src/lib/data/data-collection.ts","../../../projects/data/src/lib/data/data-backend.ts","../../../projects/data/src/lib/modellist/model-list-fields/model-list-fields.ts","../../../projects/data/src/lib/modellist/model-list-paginator/model-list-paginator.ts","../../../projects/data/src/lib/modellist/model-list-sorter/model-list-sorter.ts","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters.ts","../../../projects/data/src/lib/auth/auth-interceptor.service.ts","../../../projects/data/src/lib/modellist/model-list.service.ts","../../../projects/data/src/lib/modellist/model-list-fields/model-list-fields-selector/model-list-fields-selector.component.ts","../../../projects/data/src/lib/modellist/model-list-fields/model-list-fields-selector/model-list-fields-selector.component.html","../../../projects/data/src/lib/modellist/model-list-sorter/model-list-sorter/model-list-sorter.component.ts","../../../projects/data/src/lib/modellist/model-list-sorter/model-list-sorter/model-list-sorter.component.html","../../../projects/data/src/lib/modellist/model-list-fields/model-list-field-header/model-list-field-header.component.ts","../../../projects/data/src/lib/modellist/model-list-fields/model-list-field-header/model-list-field-header.component.html","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters-select/model-list-filters-select.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters-select/model-list-filters-select.component.html","../../../projects/data/src/lib/utils/unique-id.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetime-range-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetime-range-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters/model-list-filters.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters/model-list-filters.component.html","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filter-group.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetimerange-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/adapters/ban.ts","../../../projects/data/src/lib/modellist/model-list-paginator/model-list-paginator/model-list-paginator.component.ts","../../../projects/data/src/lib/modellist/model-list-paginator/model-list-paginator/model-list-paginator.component.html","../../../projects/data/src/lib/dispedit/choice.pipe.ts","../../../projects/data/src/lib/dispedit/factor.pipe.ts","../../../projects/data/src/lib/dispedit/factorc.pipe.ts","../../../projects/data/src/lib/dispedit/fkselect/fkselect.component.ts","../../../projects/data/src/lib/dispedit/fkselect/fkselect.component.html","../../../projects/data/src/lib/messages/message.service.ts","../../../projects/data/src/lib/dispedit/m2mselect/m2mselect.component.ts","../../../projects/data/src/lib/dispedit/m2mselect/m2mselect.component.html","../../../projects/data/src/lib/dispedit/dispedit/dispedit.component.ts","../../../projects/data/src/lib/dispedit/dispedit/dispedit.component.html","../../../projects/data/src/lib/dispedit/flags/flags.component.ts","../../../projects/data/src/lib/dispedit/flags/flags.component.html","../../../projects/data/src/lib/dispedit/sdelete/sdelete.component.ts","../../../projects/data/src/lib/dispedit/sdelete/sdelete.component.html","../../../projects/data/src/lib/data/fields/stringfields.ts","../../../projects/data/src/lib/data/fields/datetime.ts","../../../projects/data/src/lib/data/fields/relations.ts","../../../projects/data/src/lib/data/fields/boolean.ts","../../../projects/data/src/lib/data/fields/numbers.ts","../../../projects/data/src/lib/data/fields/computed.ts","../../../projects/data/src/lib/data/fields/index.ts","../../../projects/data/src/lib/messages/message-zone/message-zone.component.ts","../../../projects/data/src/lib/messages/message-zone/message-zone.component.html","../../../projects/data/src/lib/data/data-query.mock.ts","../../../projects/data/src/lib/data/data-collection.mock.ts","../../../projects/data/src/lib/uploader/interfaces.ts","../../../projects/data/src/lib/uploader/ngx-uploader.class.ts","../../../projects/data/src/lib/uploader/ng-file-drop.directive.ts","../../../projects/data/src/lib/uploader/ng-file-select.directive.ts","../../../projects/data/src/lib/uploader/ngx-uploader.module.ts","../../../projects/data/src/lib/uploader/index.ts","../../../projects/data/src/lib/auth/jwt.ts","../../../projects/data/src/lib/auth/auth.service.ts","../../../projects/data/src/lib/routing/routing.ts","../../../projects/data/src/lib/routing/breadcrumb/breadcrumb.component.ts","../../../projects/data/src/lib/routing/breadcrumb/breadcrumb.component.html","../../../projects/data/src/lib/utils/tab-memory.service.ts","../../../projects/data/src/lib/utils/slugify.ts","../../../projects/data/src/lib/utils/editor-dom-shims.ts","../../../projects/data/src/lib/utils/template.ts","../../../projects/data/src/lib/updates/update.service.ts","../../../projects/data/src/lib/updates/update/update.component.ts","../../../projects/data/src/lib/updates/update/update.component.html","../../../projects/data/src/public-api.ts","../../../projects/data/src/solidev-data.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/**\n * Base URL of the REST API every {@link Collection} builds its endpoints on.\n *\n * This token is **required**: {@link DataBackend} injects it without `@Optional()`,\n * so an application that forgets to provide it fails at injection time rather than\n * at the first request. The value is prepended verbatim to each collection path\n * (`apiUrl + path`), so it must **not** carry a trailing slash — collection paths\n * are expected to start with one.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [{ provide: DATA_API_URL, useValue: 'https://api.example.com/v1' }],\n * });\n * // a Collection on '/path/to/things' then hits\n * // https://api.example.com/v1/path/to/things\n * ```\n */\nexport const DATA_API_URL = new InjectionToken<string>('data.api.url');\n/**\n * Time window, in milliseconds, during which {@link DataBackend} may answer GET\n * requests from Angular's `TransferState` instead of hitting the network.\n *\n * This token is **optional** and defaults to `0`, which disables TransferState\n * entirely — both the server-side write and the browser-side read are skipped.\n * Provide a positive value only in an SSR application that wants the server's\n * GET responses replayed on hydration.\n *\n * The window is measured from the moment the `DataBackend` instance was created,\n * not per cache entry: once more than this many milliseconds have elapsed since\n * bootstrap, every GET goes back to the network for the rest of the session.\n * A value slightly larger than the expected hydration time is the intent.\n *\n * Caching is additionally opt-out per collection via `Collection.useTransferState`.\n *\n * @example\n * ```ts\n * providers: [{ provide: DATA_MAX_TRANSFERSTATE_TIME, useValue: 10000 }]\n * ```\n */\nexport const DATA_MAX_TRANSFERSTATE_TIME = new InjectionToken<number>('data.max.transfer.state');\n\n/**\n * CSS class names and default modes the display/edit widgets apply to the inputs\n * they generate.\n *\n * The library renders form controls from field metadata, so it has to pick the\n * markup classes itself. Rather than hard-coding a CSS framework, it reads them\n * from here, which is what lets the same models render under Bootstrap, Tailwind\n * or a bespoke design system.\n *\n * Provide an implementation through {@link DATA_DISPLAY_CONFIG}; see\n * {@link BootstrapDataDisplayConfig} for a complete example.\n */\nexport interface DataDisplayConfig {\n dispEdit: {\n /**\n * Layout used by `dispedit` when a component does not request one explicitly:\n * `\"inline\"` renders the value in flow, `\"dd\"` renders it as a definition\n * list entry.\n */\n defaultMode: 'inline' | 'dd';\n /**\n * Class string per editor type, keyed by the editor names used in\n * `DISPEDIT_EDITOR_TYPES` (e.g. `\"input.text\"`, `\"select\"`). A missing key\n * simply yields no class.\n */\n inputClasses: Record<string, string>;\n };\n}\n\n/**\n * Bootstrap 5 flavour of {@link DataDisplayConfig}, and the fallback used when no\n * {@link DATA_DISPLAY_CONFIG} is provided.\n *\n * Useful as a starting point: spread it and override the entries you need rather\n * than restating the whole map.\n */\nexport const BootstrapDataDisplayConfig: DataDisplayConfig = {\n dispEdit: {\n defaultMode: 'dd',\n inputClasses: {\n 'input.text': 'form-control',\n 'input.email': 'form-control',\n 'input.datetime': 'form-control',\n 'input.date': 'form-control',\n 'input.number': 'form-control',\n 'input.decimal': 'form-control',\n 'input.checkbox': 'form-control',\n 'input.password': 'form-control',\n textarea: 'form-control',\n quill: '',\n fkselect: 'form-control',\n select: 'form-select',\n },\n },\n};\n\n/**\n * Styling contract for the generated display/edit widgets.\n *\n * This token is **optional**: consumers that do not provide it get\n * {@link BootstrapDataDisplayConfig} (Bootstrap 5 classes). Provide it once at\n * bootstrap to retarget every `dispedit`-family component at another CSS\n * framework without touching the components themselves.\n *\n * @example\n * ```ts\n * providers: [{\n * provide: DATA_DISPLAY_CONFIG,\n * useValue: {\n * dispEdit: {\n * defaultMode: 'inline',\n * inputClasses: { 'input.text': 'my-input', select: 'my-select' },\n * },\n * },\n * }]\n * ```\n */\nexport const DATA_DISPLAY_CONFIG = new InjectionToken<DataDisplayConfig>('data.display.config');\n","// Deliberately dependency-free: `fields/base.ts` needs this, and `data-model.ts`\n// imports from `fields/base.ts` -- putting it in either would close a cycle.\n\n/**\n * A model seen as the untyped property bag it also is.\n *\n * Fields are declared by decorators and reached by name at runtime — `dispedit`\n * reads `<field>_details`, filters read `filter.field` — so the data layer\n * constantly indexes models with a string the compiler cannot resolve. This is\n * the one sanctioned way to do it: it yields `unknown`, so the value has to be\n * narrowed where it is used instead of silently becoming `any` and disabling\n * type-checking for the rest of the expression.\n *\n * ```ts\n * const details = fieldValues(model)[`${field}_details`] as R[] | undefined;\n * fieldValues(model)[field] = event.id;\n * ```\n *\n * @param target model (or any object) to index by field name\n */\nexport function fieldValues(target: object): Record<string, unknown> {\n return target as Record<string, unknown>;\n}\n\n/**\n * Renders an unknown value as display text.\n *\n * `String(value)` is not enough here: values read through {@link fieldValues}\n * can be objects, and `String({})` yields `[object Object]`. Nullish becomes an\n * empty string, objects are JSON-encoded, everything else goes through\n * `String`.\n *\n * @param value value read off a model, a form or a payload\n */\nexport function asText(value: unknown): string {\n if (value === null || value === undefined) {\n return '';\n }\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n // Objects were handled above; what is left stringifies meaningfully.\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return String(value);\n}\n","import { FormControl, ValidatorFn, Validators } from '@angular/forms';\nimport { fieldValues } from '../field-values';\nimport { DataModel } from '../data-model';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\n\n/**\n * Symbol under which every field's metadata is stored, directly on the model\n * class prototype. The library deliberately does not depend on\n * `reflect-metadata`: a plain `Map` hung off this Symbol is the whole store.\n */\nexport const PROPERTY_METADATA_KEY = Symbol('ngxDataMetadata');\n\n/**\n * The per-prototype field store: `` `${__name}__${propertyKey}` `` → metadata.\n *\n * Stockage des métadonnées sur le prototype via Symbol, sans reflect-metadata.\n */\ntype MetadataMap = Map<string, IFieldStoredMetadata<unknown>>;\n\n/**\n * The metadata store hung off a prototype under {@link PROPERTY_METADATA_KEY}.\n * A symbol key, so this cannot go through `fieldValues()`.\n */\nfunction metadataStore(target: object): {\n [PROPERTY_METADATA_KEY]?: MetadataMap;\n} {\n return target;\n}\n\n/**\n * Returns the metadata map owned by `target`, creating it on first use.\n *\n * When a subclass prototype does not own a map yet, the inherited one is\n * copied rather than shared, so a subclass can declare its own fields without\n * leaking them back onto its parent.\n */\nfunction getOrCreateFieldsMap(target: object): MetadataMap {\n if (!Object.prototype.hasOwnProperty.call(target, PROPERTY_METADATA_KEY)) {\n const inherited = metadataStore(target)[PROPERTY_METADATA_KEY];\n const map: MetadataMap = inherited\n ? new Map<string, IFieldStoredMetadata<unknown>>(inherited)\n : new Map<string, IFieldStoredMetadata<unknown>>();\n Object.defineProperty(target, PROPERTY_METADATA_KEY, {\n value: map,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return map;\n }\n return metadataStore(target)[PROPERTY_METADATA_KEY]!;\n}\n\n/**\n * Reads the field metadata declared on a model, accepting either the class\n * itself or an instance/prototype. Returns `undefined` for a class that has no\n * decorated field anywhere in its chain.\n *\n * @param target model class, prototype or instance\n */\nexport function getFieldsMetadata(target: object): MetadataMap | undefined {\n const proto = typeof target === 'function' ? (target as { prototype: object }).prototype : target;\n return metadataStore(proto)[PROPERTY_METADATA_KEY];\n}\n\n/**\n * Options common to every field decorator. All are optional; each concrete\n * field type extends this with its own (`ICharFieldMetadata`, etc.).\n *\n * Whatever you pass to a decorator is copied verbatim onto the field's manager\n * instance, so these names double as the manager's public properties.\n *\n * @typeParam FT the JavaScript type the field holds on the model\n */\nexport interface IFieldMetadata<FT> {\n /**\n * Wire name of the field: the key used in the JSON payload. Defaults to the\n * decorated property name, so it only needs setting when the API name and\n * the TypeScript property name differ.\n */\n name?: string;\n /** Short hint shown next to the editor. Defaults to an empty string. */\n help?: string;\n /**\n * Human-readable label used for column titles, form labels and hover\n * details. Defaults to {@link IFieldMetadata.name} when omitted.\n */\n description?: string;\n /**\n * Marks the field as mandatory: adds `Validators.required` and forces a\n * value to be present on save.\n *\n * Beware: combining `required: true` with no `defaultValue` throws at class\n * definition time — see {@link BaseFieldManager.getDefaultValue}.\n */\n required?: boolean;\n /**\n * Field is display-only: it is excluded from generated form groups and never\n * pushed back to the API. Typical for server-maintained columns and for the\n * `*_details` half of a relation.\n */\n readonly?: boolean;\n /**\n * Value used when the model has no value for this field — either a constant\n * or a factory `(args) => FT` evaluated on each call, which is how you get a\n * fresh array/date per instance instead of a shared one.\n */\n defaultValue?: FT | ((args: FieldDefaultArgs) => FT) | null;\n /**\n * Display ordering weight: **higher is shown first**. `id` uses `1000`.\n *\n * `priority: -1` is the established idiom for \"deserialise this field but\n * never offer it in the UI\" — negative-priority fields are dropped from the\n * default column set. It is used for the id half of every relation, whose\n * `*_details` twin is what a human is meant to see.\n */\n priority?: number;\n}\n\n/**\n * Runtime behaviour of a single field: one manager instance is built per\n * decorated property, at class definition time, and cached in the prototype's\n * metadata map. Everything the library does with a field — serialise it,\n * validate it, build its form control, pick its widget — goes through here.\n *\n * Subclass it only to add a genuinely new field type; the shipped managers\n * (`CharFieldManager`, `ForeignKeyFieldManager`, ...) cover the usual cases.\n * Override `fromJson`/`toJson` to change the wire mapping and\n * `getValidators()` to add constraints.\n */\nexport class BaseFieldManager<FT> implements IFieldMetadata<FT> {\n /** Name is mandatory in a field manager. It is given by\n * field decorator if not directly given in field manager. */\n public name!: string;\n /** Human-readable label; falls back to {@link name} when not given. */\n public description!: string;\n /** Input hint; normalised to `''` when not given. */\n public help!: string;\n /** Whether a value must be present. Adds `Validators.required`. */\n public required = false;\n /** Whether the field is excluded from forms and never written back. */\n public readonly = false;\n /**\n * Set to `true` only by `ComputedFieldManager`. `DataModel.setFV` skips\n * assignment entirely for computed fields, making them permanently\n * read-only in the eyes of the model.\n */\n public computed = false;\n /** Display ordering weight; higher is shown first. See {@link IFieldMetadata.priority}. */\n public priority = 0;\n /** Constant or factory used when the model has no value. */\n public defaultValue?: FT | ((args: FieldDefaultArgs) => FT);\n\n /**\n * Which editor widget `dispedit` renders for this field in edit mode.\n *\n * This is the library's central idea: **declaring the model configures the\n * UI**. Managers set this themselves from what you declared — `charField`\n * flips to `'select'` as soon as `choices` is present, `foreignKeyField`\n * uses `'fkselect'`, `manyToManyField` `'m2mselect'` — so a correct model\n * yields the right editor with no per-template wiring.\n */\n public editorType: DISPEDIT_EDITOR_TYPES = 'input.text';\n /**\n * Which read-only renderer `dispedit` uses for this field. Chosen by the\n * manager the same way as {@link editorType} (`'fkdetails'` for a foreign\n * key, `'m2mdetails'` for a m2m, `'decimal'` for `decimalField`, ...).\n */\n public displayType: DISPEDIT_DISPLAY_TYPES = 'text';\n\n /**\n * Copies `params` onto the instance, fills in `name`/`description`/`help`\n * defaults, then eagerly resolves the default value — which means a\n * `required` field with no `defaultValue` throws here, at decoration time.\n *\n * @param params metadata as passed to the decorator\n */\n constructor(params: IFieldMetadata<FT>) {\n Object.assign(this, params);\n if (!this.name) {\n this.name = 'noname';\n }\n if (!this.description) {\n this.description = this.name;\n }\n if (!this.help) {\n this.help = '';\n }\n this.getDefaultValue();\n }\n\n /**\n * Angular validators for this field, rebuilt on each access. Subclasses\n * override this getter (not {@link getValidators}) to append their own —\n * `CharFieldManager` adds length/pattern, `IntegerFieldManager` min/max.\n */\n public get validators(): ValidatorFn[] {\n return this.getValidators();\n }\n\n /**\n * The bare property name, stripped of any `Model__` prefix: splits\n * {@link name} on `'__'` and returns the second segment, or the whole name\n * when there is no separator.\n */\n public get fname(): string {\n return this.name.split('__')[1] || this.name;\n }\n\n /**\n * Builds a typed `FormControl` for this field on a given model instance,\n * seeded with the instance's current value and falling back to the default\n * value, and wired with {@link validators}.\n *\n * Note the seed uses `||`, so falsy current values (`0`, `''`, `false`) fall\n * back to the default rather than being kept.\n *\n * @param instance model whose value seeds the control\n */\n public formControl(instance: DataModel): FormControl<FT | null> {\n return new FormControl<FT>(\n (fieldValues(instance)[this.fname] as FT) || (this.getDefaultValue() as FT),\n this.validators,\n );\n }\n\n /**\n * Converts a raw JSON value coming from the API into the model value.\n * The base implementation passes the data straight through; typed managers\n * override it to coerce (`boolean`), parse (`date`) or instantiate\n * (`details`).\n *\n * @param data raw value read from the JSON payload\n */\n public fromJson(data: unknown): FT {\n return data as FT;\n }\n\n /**\n * Converts the model value back into its JSON representation for save.\n * The base implementation passes the data straight through.\n *\n * @param data current model value\n */\n public toJson(data: FT): unknown {\n return data;\n }\n\n /**\n * Renders the value for display. The base implementation is plain string\n * interpolation.\n *\n * @param data value to render\n * @param _format reserved; ignored by the base implementation\n */\n public toString(data: FT, _format = 'default'): string {\n return String(data);\n }\n\n /**\n * Public accessor for this field's default value, invoking the\n * `defaultValue` factory with `args` when one was declared.\n *\n * @param args passed through to a `defaultValue` function\n */\n public default(args: FieldDefaultArgs = {}): FT | undefined {\n return this.getDefaultValue(args);\n }\n\n /**\n * Builds the base validator list: `Validators.required` when the field is\n * required, nothing otherwise. Subclasses call it and push their own.\n *\n * @protected\n */\n protected getValidators(): ValidatorFn[] {\n const v: ValidatorFn[] = [];\n if (this.required) {\n // eslint-disable-next-line @typescript-eslint/unbound-method -- Validators.* are static and `this`-free\n v.push(Validators.required);\n }\n return v;\n }\n\n /**\n * Resolves the default value: calls `defaultValue` when it is a function,\n * otherwise returns it as-is.\n *\n * **Throws** when the field is `required` and no `defaultValue` was given.\n * Because the constructor calls this, the error surfaces when the class is\n * defined (module evaluation), not when a model is instantiated — a\n * `required` field without a default breaks the app at import time.\n *\n * @param args passed through to a `defaultValue` function\n * @throws Error if `required` is set and `defaultValue` is `undefined`\n * @protected\n */\n protected getDefaultValue(args: FieldDefaultArgs = {}): FT | undefined {\n if (this.defaultValue instanceof Function) {\n return this.defaultValue(args);\n }\n if (this.required && this.defaultValue === undefined) {\n throw new Error(`Field ${this.name} : no default value for required field`);\n }\n return this.defaultValue;\n }\n}\n\n/**\n * What is actually kept in a model's metadata map: the options you passed to\n * the decorator, plus the four entries the decorator computes. This is the\n * shape returned by {@link getFieldsMetadata}.\n */\nexport interface IFieldStoredMetadata<FT> extends IFieldMetadata<FT> {\n /** Map key of this entry: `` `${__name}__${propertyKey}` ``. */\n self: string;\n /** Wire name; defaulted to the decorated property name. */\n name: string;\n /** Field type code, e.g. `'charField'`, `'foreignKeyField'`. */\n type: string;\n /** The live manager instance built for this field. */\n manager: BaseFieldManager<FT>;\n}\n\n/**\n * Arguments handed to a `defaultValue` factory. Free-form: callers pass\n * whatever the factory needs, and the factory knows what to expect.\n */\nexport type FieldDefaultArgs = Record<string, unknown>;\n\n/** Manager constructor\n * FT is js field type;\n * T is manager type\n * */\ntype BaseFieldManagerConstructor<MD, T> = new (params: MD) => T;\n\n/**\n * Shape of every field decorator returned by {@link genericDataField}: a plain\n * property decorator, applied for its side effect on the prototype's metadata\n * map.\n */\nexport type FieldDecoratorFn = (target: object, propertyKey: string | symbol) => void;\n\n/**\n * The factory behind every field decorator in the library — `charField`,\n * `foreignKeyField` and the rest are all one-line calls to it. Reach for it\n * only when adding a new field type of your own.\n *\n * The returned decorator registers the field on the class prototype under\n * `` `${__name}__${propertyKey}` ``, defaults `name` to the property name, and\n * instantiates `manager` immediately — so any error a manager raises in its\n * constructor (a `required` field with no default, for instance) is thrown\n * while the class is being defined.\n *\n * Every decorator except `primaryField` **throws** unless the decorated class\n * declares a `static __name`, since that string is half of the metadata key.\n *\n * @param meta field metadata, copied verbatim into the store and the manager\n * @param type field type code, e.g. `'charField'`\n * @param manager manager class to instantiate for this field\n * @throws Error if the class has no `static __name` (non-`primaryField` types)\n * @throws Error if the same field is declared twice\n */\nexport function genericDataField<FT, MD extends IFieldMetadata<FT>, MG extends BaseFieldManager<FT>>(\n meta: MD,\n type: string,\n manager: BaseFieldManagerConstructor<MD, MG>,\n): FieldDecoratorFn {\n return (target: object, propertyKey: string | symbol) => {\n // Utilisation du store symbolisé au lieu de Reflect\n const allMetadata = getOrCreateFieldsMap(target);\n const cname = `${String((target.constructor as { __name?: string }).__name)}`;\n if ((cname === `undefined` || cname === '') && type !== 'primaryField') {\n throw Error(\n `Decorator ${type} allowed only on classes with static __name ` +\n `field : \"${cname}\" found on field \"${String(propertyKey)}\"`,\n );\n }\n const pk = `${cname}__${String(propertyKey)}`;\n let cm = allMetadata.get(pk);\n /* istanbul ignore if */\n if (cm) {\n throw Error(`Field ${pk} already defined = ${JSON.stringify(cm)}`);\n }\n cm = { ...meta } as unknown as IFieldStoredMetadata<unknown>;\n if (meta.name === undefined) {\n cm.name = `${String(propertyKey)}`;\n }\n cm.type = type;\n cm.self = pk;\n // `cm` is `meta` plus the resolved name/type/self, so it is an `MD`;\n // the copy above loses that on the way through the stored shape.\n cm.manager = new manager(cm as unknown as MD);\n allMetadata.set(pk, cm);\n // Plus besoin de Reflect.defineMetadata : la Map est déjà stockée sur le prototype.\n };\n}\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\n\n/**\n * Options for {@link primaryField}.\n */\nexport interface IPrimaryFieldMetadata extends IFieldMetadata<number> {\n /** Increment hint for the identifier. Declarative only; unused at runtime. */\n step?: number;\n}\n\n/**\n * Manager for the model's primary key. It adds nothing to the base behaviour\n * beyond {@link IPrimaryFieldMetadata.step}: the id is carried as a plain\n * number, with the base pass-through serialisation.\n */\nexport class PrimaryFieldManager extends BaseFieldManager<number> implements IPrimaryFieldMetadata {\n /** Increment hint. Declarative only; nothing reads it. */\n public step = 1;\n}\n\n/**\n * Declares the model's primary key. `DataModel` already declares `id` with it\n * (`priority: 1000`, so it sorts first), so you rarely need this yourself —\n * only to give a model a differently-named identifier.\n *\n * Unlike every other field decorator, `primaryField` does **not** require the\n * class to declare a `static __name`; it is the one type exempted from that\n * check, which is what lets `DataModel` itself declare `id`.\n *\n * @param updates field options\n */\nexport const primaryField = (updates: IPrimaryFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'primaryField', PrimaryFieldManager);\n","import { BaseFieldManager, getFieldsMetadata, IFieldStoredMetadata } from './fields/base';\nimport { fieldValues } from './field-values';\nimport { primaryField } from './fields/primaryfield';\nimport { FormControl, FormGroup, ValidationErrors } from '@angular/forms';\nimport { Collection } from './data-collection';\nimport { Observable, throwError } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\n/**\n * Resolved field metadata of a model instance, keyed by field name.\n *\n * This is what {@link DataModel.F} exposes: the flattened result of walking the\n * class chain and collecting every decorated field. UI components (list headers,\n * filters, `dispedit`) read this map to render themselves without knowing the\n * concrete model.\n */\nexport type DataModelFields = Readonly<Map<string, IFieldStoredMetadata<unknown>>>;\n\n/**\n * The class a prototype-chain level belongs to, as the library sees it: a\n * constructor carrying the `__name` every model declares.\n */\nfunction modelClassOf(level: object): { name: string; __name?: string } {\n return (level as { constructor: { name: string; __name?: string } }).constructor;\n}\n\n/**\n * Base class for every model in the library: a plain class whose fields are\n * declared with field decorators, which turns it into something the rest of the\n * stack can introspect.\n *\n * Extending `DataModel` buys three things. Field metadata is collected at\n * construction and exposed via {@link F}/{@link FN}/{@link FM}, so generic UI can\n * render a model it has never seen. Serialization to and from the API's JSON is\n * handled by {@link fromJson}/{@link toJson} through each field's manager. And,\n * when the instance carries a {@link Collection} (which it does whenever it was\n * built by one), {@link save}/{@link update}/{@link action} give it CRUD against\n * the REST endpoint.\n *\n * **Every class in the chain must declare a unique `static override readonly\n * __name`.** The constructor matches metadata keys against\n * `constructor.__name + '__'` as it walks the prototype chain, so a class whose\n * `__name` is missing, empty, or duplicated from another class contributes *no\n * fields at all* — silently, with no error, and the model simply behaves as if\n * those fields were never declared. This is the single most common newcomer bug;\n * if a field mysteriously does not render or round-trip, check `__name` first.\n * The property exists because minifiers rewrite `constructor.name`, so the real\n * class name cannot be relied on at runtime.\n *\n * Fields are collected most-derived-first, so a subclass redeclaring a field name\n * overrides the parent's metadata for it.\n *\n * @example\n * ```ts\n * export class ThingBase extends DataModel {\n * static override readonly __name = 'ThingBase';\n *\n * @charField({ name: 'name', description: 'Name' })\n * public name!: string;\n * }\n *\n * export class Thing extends ThingBase {\n * static override readonly __name = 'Thing'; // unique, and required again here\n * }\n * ```\n */\nexport class DataModel {\n /**\n * Unique per-class identifier used to attribute decorated fields to the class\n * that declared them.\n *\n * Must be redeclared as `static override readonly __name = '<UniqueName>'` on\n * **every** subclass, including intermediate abstract-ish base classes, and\n * must be unique across the whole model set. It cannot be derived from\n * `constructor.name` because minification rewrites it. A missing or duplicated\n * value silently drops that class's fields — see the class-level docs.\n */\n protected static readonly __name: string = '';\n\n /**\n * Server-assigned primary key, and the flag the CRUD layer dispatches on:\n * `Collection.save()`/`update()` PATCH an existing record when `id` is defined\n * and POST a new one when it is `undefined`.\n *\n * Declared and decorated **once, here**, so every model inherits the metadata.\n * Consumers must **never** write `@primaryField() override id` on a subclass:\n * under `useDefineForClassFields: true` a redeclared field is re-initialized to\n * `undefined` at construction, shadowing the value the base class set and\n * making every save look like a create.\n */\n @primaryField({ name: 'id', description: 'ID', priority: 1000 })\n public id!: number;\n /** Backing store for {@link F}, computed once in the constructor. */\n private readonly _F: DataModelFields;\n\n /**\n * Resolves this instance's field metadata by walking its prototype chain.\n *\n * Field decorators record metadata under `'<__name>__<field>'` keys, so the\n * constructor climbs from the concrete class up to `Object`, and at each level\n * claims the keys prefixed with that class's `__name`. Because the walk is\n * most-derived-first and a name is only claimed once, a subclass redeclaring a\n * field wins over its parent. Classes whose `__name` matches nothing simply\n * contribute nothing — this is where a missing or duplicated `__name` silently\n * loses fields.\n *\n * @param _coll collection this instance belongs to; supplies the endpoint for\n * {@link save}, {@link update} and {@link action}. Instances built by hand\n * (`new Thing()`) have none, and those methods will error until one is set\n * via {@link _collection}.\n * @throws Error if no field metadata is reachable at all, which should be\n * impossible since `DataModel` itself declares `id`.\n */\n // `Collection<any>`, deliberately. `DataModelType<T>` is `new (_coll?:\n // Collection<T>) => T`, so a subclass has to stay assignable to a\n // constructor taking a collection *of itself*. Naming any concrete type\n // here -- `Collection<DataModel>` included -- closes that loop and makes\n // `new Collection(backend, url, MyModel)` stop type-checking for every\n // model in every consumer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(protected _coll?: Collection<any>) {\n // Remplacement de Reflect.getMetadata par getFieldsMetadata\n const md: Map<string, IFieldStoredMetadata<unknown>> | undefined = getFieldsMetadata(this);\n // istanbul ignore if\n if (!md) {\n // This should never occur as all datamodel have at least id field\n throw new Error('No property metadata found for this object; is there a property in current collection ?');\n }\n // Get all fields from current class and its parents\n const fields = new Map<string, IFieldStoredMetadata<unknown>>();\n let parent: object = Object.getPrototypeOf(this) as object;\n while (modelClassOf(parent).name !== 'Object') {\n for (const f of md.keys()) {\n const fieldName = f.split('__')[1];\n if (fields.has(fieldName)) {\n continue;\n }\n if (f.indexOf(`${modelClassOf(parent).__name}__`) === 0) {\n fields.set(fieldName, md.get(f)!);\n }\n }\n parent = Object.getPrototypeOf(parent) as object;\n }\n this._F = Object.freeze(fields);\n }\n\n /**\n * Collection backing this instance's CRUD calls.\n *\n * Set it on models you built by hand — `collection.create()`/`fromJson()` wire\n * it for you — otherwise {@link save}, {@link update} and {@link action} fail\n * with \"Missing collection\". The getter casts away the optional, so it lies\n * about `undefined` on an unattached model.\n */\n // `Collection<any>`, deliberately. `DataModelType<T>` is `new (_coll?:\n // Collection<T>) => T`, so a subclass has to stay assignable to a\n // constructor taking a collection *of itself*. Naming any concrete type\n // here -- `Collection<DataModel>` included -- closes that loop and makes\n // `new Collection(backend, url, MyModel)` stop type-checking for every\n // model in every consumer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public get _collection(): Collection<any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return this._coll as Collection<any>;\n }\n\n // `Collection<any>`, deliberately. `DataModelType<T>` is `new (_coll?:\n // Collection<T>) => T`, so a subclass has to stay assignable to a\n // constructor taking a collection *of itself*. Naming any concrete type\n // here -- `Collection<DataModel>` included -- closes that loop and makes\n // `new Collection(backend, url, MyModel)` stop type-checking for every\n // model in every consumer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public set _collection(coll: Collection<any>) {\n this._coll = coll;\n }\n\n /**\n * Field metadata for this instance, keyed by field name.\n *\n * The introspection entry point: generic components iterate this to discover\n * what a model has (type, label, priority, editor, validators) without any\n * compile-time knowledge of the class. Frozen and computed once at\n * construction.\n */\n public get F(): DataModelFields {\n // istanbul ignore if\n if (!this._F) {\n throw new Error('Invalid data model, fields metadata is missing');\n }\n return this._F;\n }\n\n /**\n * Names of every declared field, in declaration order (most-derived class\n * first). Handy shorthand for iterating a model generically; use\n * `Array.from(model.FN)` when you need a real array.\n */\n public get FN(): IterableIterator<string> {\n return this.F.keys();\n }\n\n /**\n * Populates this instance from an API JSON payload, running each value through\n * its field manager's deserializer (dates become `Date`s, nested details become\n * models, and so on).\n *\n * This is what `Collection.fromJson()` calls, and what you call yourself to\n * merge a server response back into an existing instance.\n *\n * @param data raw JSON object keyed by field name\n * @param partial when `true`, only fields actually present in `data` are\n * touched — use it for PATCH responses. When `false` (the default), *every*\n * declared field is assigned, so fields absent from `data` are reset to\n * whatever their manager makes of `undefined`.\n * @param check when `true`, each value is validated before assignment and a\n * failing field keeps its previous value\n * @returns `null` when everything was accepted, otherwise an object mapping the\n * offending field names to their `ValidationErrors`. Note that valid fields\n * are still applied even when others fail — this reports, it does not roll back.\n */\n public fromJson(\n data: object,\n { partial, check }: { partial?: boolean; check?: boolean } = {\n partial: false,\n check: false,\n },\n ): null | ValidationErrors {\n const errors: Record<string, null | ValidationErrors> = {};\n let haveError = false;\n for (const f of this.FN) {\n if (!partial || (partial && Object.keys(data).indexOf(f) !== -1)) {\n const ferr = this.setFV(f, this.FM(f).fromJson(fieldValues(data)[f]), check);\n if (ferr !== null) {\n errors[f] = ferr;\n haveError = true;\n }\n }\n }\n return haveError ? errors : null;\n }\n\n /**\n * Serializes this instance to a plain JSON object for the API, running each\n * value through its field manager's serializer.\n *\n * The two calling conventions differ in more than scope, and the difference\n * matters when writing:\n *\n * - `toJson()` — every field **except** those marked `readonly`. This is what\n * `Collection.save()` sends, so server-computed fields are never echoed back.\n * - `toJson(fields)` — only the named fields, and `readonly` is **not** applied.\n * This is what `Collection.update()` sends; naming a readonly field here will\n * put it in the payload.\n *\n * An empty array behaves like the no-argument form.\n *\n * @param fields single field name or list of names to restrict the output to\n */\n // The payload's shape is the model's own, which only the caller knows.\n // Narrowing this to `Record<string, unknown>` would force every consumer\n // reading a property off the result to cast, so it stays `any` until a major.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public toJson(fields?: string | string[]): any {\n if (fields && !Array.isArray(fields)) {\n fields = [fields];\n }\n const out: Record<string, unknown> = {};\n const fl = this.F;\n for (const f of this.FN) {\n const mgr = this.FM(f);\n if (!fields || fields.length === 0) {\n if (mgr.readonly) {\n continue;\n }\n out[f] = fl.get(f)!.manager.toJson(this.FV(f));\n } else {\n if (fields.indexOf(f) !== -1) {\n out[f] = fl.get(f)!.manager.toJson(this.FV(f));\n }\n }\n }\n return out;\n }\n\n /**\n * Calls a custom endpoint hanging off this record — the DRF `@action`\n * convention, i.e. `/path/to/things/<id>/<name>` — for the operations that are\n * not plain CRUD (`publish`, `duplicate`, `send`, ...).\n *\n * @param method HTTP method to use\n * @param name action name, appended to this record's detail URL\n * @param body JSON body to send\n * @param update when `true`, the response is fed back into this instance via\n * {@link fromJson}, so the model reflects whatever the action changed\n * @param updatePartial `partial` flag for that write-back; defaults to `true`,\n * which is what you want for the usual \"action returns the changed fields\"\n * response\n * @param updateCheck `check` flag for that write-back (validate before assigning)\n * @param params query parameters\n * @param headers extra headers\n * @returns an observable of the **raw response body**, not of this model, even\n * when `update` is `true`\n */\n // `T` is unused, but it comes first in the parameter list: removing it\n // would silently change what `action<A, B>()` call sites mean.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public action<T, RT extends object>(\n method: 'POST' | 'PATCH' | 'GET' | 'DELETE' | 'PUT',\n name: string,\n {\n body = undefined,\n update = false,\n updatePartial = true,\n updateCheck = false,\n // updateRaise = false,\n params = {},\n headers = {},\n }: {\n body?: object;\n update?: boolean;\n updatePartial?: boolean;\n updateCheck?: boolean;\n // updateRaise?: boolean;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {},\n ): Observable<RT> {\n if (this._coll === undefined) {\n return throwError(() => new Error('Missing collection'));\n }\n return this._coll\n .action<RT>(this, method, name, {\n body,\n params,\n headers,\n })\n .pipe(\n tap((result) => {\n if (update) {\n this.fromJson(result, {\n partial: updatePartial,\n check: updateCheck,\n });\n return this;\n }\n return result;\n }),\n );\n }\n\n /**\n * Returns a field's manager — the object holding its metadata and its\n * serialize/validate/render behaviour.\n *\n * The workhorse behind generic rendering: `FM(f).description` for a label,\n * `FM(f).readonly` to decide whether to offer an editor, `FM(f).toString(v)`\n * to display a value.\n *\n * @param field field name, as declared\n * @throws Error if the field is not declared on this model — which, for a field\n * you are sure you declared, usually means a missing or duplicated `__name`\n * on the declaring class rather than a typo here.\n */\n public FM<FT>(field: string): BaseFieldManager<FT> {\n if (this.F.has(field)) {\n // The map is keyed by name and holds managers of every field type; only\n // the caller knows which one this field is.\n return this.F.get(field)!.manager as BaseFieldManager<FT>;\n }\n throw new Error(\n `${field} not found in [${[...this.FN].join(',')}] ` +\n `on model ${(this.constructor as typeof DataModel).__name}`,\n );\n }\n\n /**\n * Reads a field's value by name, for code that only knows the field at runtime.\n *\n * The `FT` type parameter is an unchecked assertion, not a conversion: nothing\n * verifies the stored value matches. Prefer direct property access\n * (`thing.name`) wherever the field is statically known.\n *\n * @param field field name\n */\n public FV<FT>(field: string): FT {\n return fieldValues(this)[field] as FT;\n }\n\n /**\n * Writes a field's value by name, optionally validating it first.\n *\n * The counterpart to {@link FV} for generic editors, and the single write path\n * used by {@link fromJson}. Two behaviours are worth knowing: values for fields\n * whose manager is `computed` are **silently discarded** (they are derived\n * server-side and have no meaningful setter), and when validation fails the\n * field is **left untouched** rather than assigned the bad value.\n *\n * @param field field name\n * @param value new value, already deserialized\n * @param check run the field's validators first and refuse the write if any of\n * them rejects; off by default, since `fromJson` on trusted server data does\n * not need it\n * @returns `null` when the value was accepted (or ignored as computed),\n * otherwise the first validator's `ValidationErrors`\n */\n public setFV<FT>(field: string, value: FT, check = false): null | ValidationErrors {\n if (this.FM(field).computed) {\n return null;\n }\n if (check) {\n const fc = new FormControl(value);\n\n for (const v of this.FM(field).validators) {\n const val = v(fc);\n if (val !== null) {\n console.error(val);\n return val;\n }\n }\n }\n fieldValues(this)[field] = value;\n return null;\n }\n\n /**\n * Builds Angular reactive form controls from field metadata, wired with each\n * field's validators and current value.\n *\n * Saves hand-writing a `FormGroup` that duplicates what the model already\n * declares. The no-argument form is the common one and deliberately **excludes\n * `readonly` fields**, so the group matches what `save()` would actually send;\n * pass an explicit list when you want a subset, or a readonly field rendered\n * anyway.\n *\n * @param field one field name for a single `FormControl`, a list of names for a\n * `FormGroup` of exactly those, or nothing for a `FormGroup` of every\n * editable (non-readonly) field\n *\n * @example\n * ```ts\n * const form = thing.FC(); // FormGroup, editable fields only\n * const nameCtrl = thing.FC('name'); // FormControl\n * ```\n */\n public FC(): FormGroup;\n public FC(field: string): FormControl;\n public FC(field: string[]): FormGroup;\n public FC(field?: string | string[]): FormControl | FormGroup {\n if (field === undefined) {\n field = Array.from(this.FN).filter((n) => !this.FM(n).readonly);\n }\n if (Array.isArray(field)) {\n const fg: Record<string, FormControl> = {};\n for (const f of field) {\n fg[f] = this.FC(f);\n }\n return new FormGroup(fg);\n }\n return this.FM(field).formControl(this);\n }\n\n /**\n * Persists the whole record through its collection, creating or updating\n * depending on {@link id}: POST when `id` is `undefined`, PATCH when it is set.\n *\n * Sends every non-readonly field. Reach for {@link update} instead when you\n * want to write only some of them.\n *\n * @param updateModel refresh this instance from the server's response, so\n * server-assigned values (`id` on create, timestamps, computed fields) land\n * back on the model; on by default\n * @returns an observable that errors with \"Missing collection\" if this instance\n * was never attached to one\n */\n public save(\n { updateModel = true }: { updateModel?: boolean } = {\n updateModel: true,\n },\n ): Observable<this> {\n if (this._coll) {\n return this._coll.save(this, { updateModel }) as Observable<this>;\n }\n return throwError(() => new Error('Missing collection'));\n }\n\n /**\n * Persists only the named fields, which is what you want after an inline edit\n * of one value — it avoids clobbering fields another client may have changed\n * meanwhile.\n *\n * Dispatches on {@link id} exactly like {@link save} (POST when unset, PATCH\n * otherwise).\n *\n * @param fields field names to send; note that an empty list (the default)\n * falls back to sending every non-readonly field, i.e. it degrades to\n * {@link save}'s payload. Also note that naming a `readonly` field here does\n * include it in the payload — the readonly filter only applies to the\n * whole-record form.\n * @param updateModel refresh this instance from the server's response; on by default\n * @returns an observable that errors with \"Missing collection\" if this instance\n * was never attached to one\n *\n * @example\n * ```ts\n * thing.name = 'new name';\n * thing.update(['name']).subscribe();\n * ```\n */\n public update(\n fields: string[] = [],\n { updateModel = true }: { updateModel?: boolean } = {\n updateModel: true,\n },\n ): Observable<this> {\n if (this._coll) {\n return this._coll.update(this, fields, {\n updateModel,\n }) as Observable<this>;\n }\n return throwError(() => new Error('Missing collection'));\n }\n}\n\n//\n// export class TreeDataModel extends DataModel {\n// static override __name = 'TreeDataModel';\n// @detailsField({\n// model: this,\n// many: true,\n// description: 'Parents',\n// })\n// public parents_details?: this[];\n//\n// @foreignKeyField({\n// required: false,\n// description: 'Structure parente',\n// related: 'Structure',\n// })\n// public parent?: number;\n//\n// @integerField({\n// required: false,\n// readonly: true,\n// description: 'ID Tree',\n// })\n// public tree_id!: number;\n//\n// @integerField({\n// required: false,\n// readonly: true,\n// description: 'MPTT left',\n// })\n// public lft!: number;\n//\n// @integerField({\n// required: false,\n// readonly: true,\n// description: 'MPTT right',\n// })\n// public rght!: number;\n//\n// @integerField({\n// required: false,\n// readonly: true,\n// description: 'Niveau hiérarchique',\n// })\n// public level!: number;\n//\n// public get parent_details(): this | null {\n// if (this.parents_details) {\n// const out = this.parents_details[this.parents_details.length - 1];\n// out.parents_details = this.parents_details.slice(\n// 0,\n// this.parents_details.length - 1\n// );\n// return out;\n// }\n// return null;\n// }\n//\n// public set parent_details(d: this | null) {\n// console.log(d);\n// this.parents_details = d?.parents_details;\n// }\n//\n// public _display(): string {\n// const out: string[] = [];\n// if (this.parents_details) {\n// for (const p of this.parents_details) {\n// if ((p as any).code) {\n// out.push(`[${(p as any).code}] ${(p as any).name}`);\n// } else {\n// out.push((p as any).name);\n// }\n// }\n// }\n// if ((this as any).code) {\n// out.push(`[${(this as any).code}] ${(this as any).name}`);\n// } else {\n// out.push((this as any).name);\n// }\n//\n// return out.join(' : ');\n// }\n// }\n","import { Collection } from './data-collection';\nimport { DataModel } from './data-model';\nimport { combineLatest, Observable, ReplaySubject, share } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\nimport { ActivatedRoute, Router } from '@angular/router';\n\n/**\n * Filter criteria as authored by the caller, keyed by the query parameter the API\n * expects (`{ status: 'active', min_price: 10 }`).\n *\n * `undefined` and `null` are meaningful here: passing either for a key *removes*\n * that filter, which is what lets a form bind a cleared control straight to a\n * queryset filter.\n */\n/**\n * A value a filter can hold: whatever goes on the wire for that field. A scalar\n * for most filters, an array for the multi-valued ones, `null` for \"cleared\".\n */\nexport type FilterValue = string | number | boolean | null | undefined | (string | number)[];\n\nexport type FilterData = Record<string, string | number | boolean | undefined | null>;\n\n/**\n * Filter criteria flattened to strings, as they go on the wire. This is what\n * {@link Queryset.getQueryParams} produces.\n */\nexport type OutFilterData = Record<string, string>;\n\n/**\n * A single ordering term: a field name, optionally prefixed with `-` to reverse\n * it (`'name'`, `'-created'`) — the DRF `ordering` convention.\n */\nexport type SortData = string;\n\n/**\n * Construction options for a {@link Queryset}, passed through\n * `Collection.queryset()`.\n */\nexport interface IQuerysetOptions {\n /**\n * Whether the selected field list is sent to the API as a `fields` query\n * parameter, letting the server return only those columns. Defaults to `true`;\n * set it to `false` against an endpoint that does not understand `fields`.\n */\n emitFields?: boolean;\n /** Identifier for this queryset, used to tell several of them apart. */\n name?: string;\n /**\n * Intended to let the queryset sync its state with the URL. Currently inert —\n * nothing in the implementation reads it (the router code in `setPage` is\n * commented out).\n */\n route?: ActivatedRoute;\n /**\n * Intended to let the queryset push page changes into the URL. Currently inert\n * — see the commented-out block in `setPage`.\n */\n router?: Router;\n /**\n * Intended as the URL fragment identifying this queryset when several share a\n * page. Currently inert.\n */\n hash?: string;\n}\n\n/** Pagination request parameters: which page, and how many rows on it. */\nexport interface IQueryNav {\n page: number;\n page_size: number;\n}\n\n/**\n * Pagination state as reported by the API, and what a paginator component binds\n * to: total row count, current page, total pages, and the neighbouring page\n * numbers (`null` at either end).\n */\nexport interface IQueryMetaNav {\n /** Total number of rows matching the filters, across all pages. */\n count: number;\n /** Next page number, or `null` on the last page. */\n next: number | null;\n /** Current page number. */\n page: number;\n /** Total number of pages. */\n pages: number;\n /** Previous page number, or `null` on the first page. */\n prev: number | null;\n /** Rows per page. */\n size: number;\n}\n\n/**\n * Names the API uses for its pagination query parameters, echoed back so a client\n * can build page links without hard-coding them.\n */\nexport interface IQueryMetaNavParams {\n page: string;\n page_size: string;\n}\n\n/** Everything a list response says about itself apart from the rows. */\nexport interface IQueryMeta {\n nav: IQueryMetaNav;\n parameters: IQueryMetaNavParams;\n}\n\n/**\n * Full shape of a paginated list response: the rows under `results`, alongside\n * the {@link IQueryMeta} envelope. This is the contract {@link Queryset} expects\n * of every list endpoint it reads.\n */\nexport interface IQueryFullResponse<T> extends IQueryMeta {\n results: T[];\n}\n\n/**\n * A filtered, sorted, paginated view over a {@link Collection}, exposing its\n * results as observables ready to bind in a template.\n *\n * Obtained from `Collection.queryset()`. The mutators ({@link filter},\n * {@link sort}, {@link paginateBy}, {@link setPage}, {@link setFields}) are\n * chainable and only accumulate state locally — **nothing is requested until\n * {@link get} is called**, and calling `get()` again after changing filters is\n * what re-runs the query.\n *\n * Consumers normally subscribe to {@link results} (or {@link full}) once and keep\n * that subscription for the component's lifetime, then call `get()` on each\n * change: the observables are `ReplaySubject`-backed, so every new emission flows\n * to the existing subscribers and late subscribers immediately get the last value.\n *\n * @example\n * ```ts\n * const qs = things.queryset();\n * qs.results.subscribe((things) => (this.things = things));\n * qs.filter({ status: 'active' }).sort('-created').paginateBy(20).get().subscribe();\n * ```\n */\nexport class Queryset<T extends DataModel> {\n /** Filters currently staged, as last set by {@link filter}. */\n public filterData: FilterData = {};\n /** Ordering terms currently staged, as last set by {@link sort}. */\n public sortData: SortData[] = [];\n /**\n * Field names to request from the API, as last set by {@link setFields}. Only\n * sent when `options.emitFields` is on and the list is non-empty.\n */\n public fields: string[] = [];\n /**\n * Rows per page. Note the default is 500, not the API's own default: a queryset\n * you never call {@link paginateBy} on asks for a large page rather than a\n * small one.\n */\n public pageSize = 500;\n /** Page number to request, 1-based. */\n public page = 1;\n\n /** Options this queryset was built with, merged over the defaults. */\n public options: IQuerysetOptions;\n private _loading = new ReplaySubject<boolean>(1);\n /**\n * Emits `true` when a fetch starts and `false` when its results have been\n * processed — bind it to a spinner. Nothing is emitted before the first\n * {@link get}, and note that a failed request leaves this at `true`.\n */\n public loading = this._loading.asObservable().pipe(share());\n private _meta = new ReplaySubject<IQueryMeta>(1);\n /**\n * Emits the pagination envelope of each response — row count, page, total\n * pages. This is what a paginator component binds to, since {@link results}\n * only carries the current page's rows.\n */\n public meta = this._meta.asObservable().pipe(share());\n private _results = new ReplaySubject<T[]>(1);\n /**\n * Emits the current page's rows as model instances on every successful fetch.\n * The main output of a queryset. Being replayed, a late subscriber immediately\n * receives the most recent page rather than waiting for the next `get()`.\n */\n public results = this._results.asObservable().pipe(share());\n private _full: Observable<[T[], boolean, IQueryMeta]> = combineLatest([this.results, this.loading, this.meta]);\n /**\n * The three streams combined into `[results, loading, meta]`, for templates\n * that would otherwise need three `async` pipes.\n *\n * Being a `combineLatest`, it emits nothing until all three have produced a\n * value — i.e. not until the first fetch completes — and then emits once per\n * change of any of them, so a single fetch produces several tuples as loading\n * flips and results land.\n */\n public full = this._full.pipe(share());\n\n /**\n * @param _coll collection this queryset reads from\n * @param options queryset options, merged over the defaults (`emitFields: true`)\n */\n constructor(\n protected _coll: Collection<T>,\n options: IQuerysetOptions = {},\n ) {\n /** Default options */\n // console.log('@solidev/data: Creating collection', _coll);\n this.options = { emitFields: true };\n Object.assign(this.options, options);\n }\n\n private _pristine = true;\n\n /**\n * `true` until the first successful fetch, `false` forever after.\n *\n * Distinguishes \"no results yet\" from \"no results found\", which a bare empty\n * array cannot: use it to choose between a loading placeholder and an empty\n * state. It is also what makes `get(false)` decide whether it may serve the\n * cached results.\n */\n public get pristine(): boolean {\n return this._pristine;\n }\n\n /**\n * Stages the filters for the next {@link get}. Chainable; issues no request.\n *\n * @param params filter criteria. A key whose value is `null` or `undefined` is\n * *removed* rather than sent, so a cleared form control can be passed\n * straight through.\n * @param update when `true`, merge into the existing filters; when `false` (the\n * default), replace them wholesale\n *\n * @example\n * ```ts\n * qs.filter({ status: 'active' }); // replaces all filters\n * qs.filter({ q: search || null }, true); // merges; drops `q` when empty\n * ```\n */\n public filter(params: FilterData = {}, update = false): Queryset<T> {\n if (!update) {\n this.filterData = {};\n }\n for (const k of Object.keys(params)) {\n if (params[k] === undefined || params[k] === null) {\n delete this.filterData[k];\n } else {\n this.filterData[k] = params[k];\n }\n }\n return this;\n }\n\n /**\n * Stages the ordering for the next {@link get}. Chainable; issues no request.\n *\n * Terms are sent joined into a single `ordering` query parameter, in the order\n * given, so the first term is the primary sort key.\n *\n * @param sorting field names, `-` prefixed to reverse; replaces any previous\n * ordering, and calling with no arguments clears it\n *\n * @example\n * ```ts\n * qs.sort('-created', 'name').get().subscribe();\n * ```\n */\n public sort(...sorting: string[]): Queryset<T> {\n this.sortData = sorting;\n return this;\n }\n\n /**\n * Stages the page size for the next {@link get}. Chainable; issues no request.\n *\n * Does not reset {@link page}, so changing the size while on a high page number\n * can land past the end of the result set — call `setPage(1)` alongside it.\n *\n * @param pageSize rows per page; defaults to 20 when called with no argument,\n * which is *not* the queryset's own default of 500\n */\n public paginateBy(pageSize = 20): Queryset<T> {\n this.pageSize = pageSize;\n return this;\n }\n\n /**\n * Stages the page number for the next {@link get}. Chainable; issues no\n * request, so a paginator must call {@link get} afterwards.\n *\n * @param page 1-based page number\n * @param _fragment currently ignored; reserved for the URL-syncing behaviour\n * that is commented out in the implementation\n */\n public setPage(page = 1, _fragment?: string): Queryset<T> {\n if (page !== this.page) {\n this.page = page;\n // if (this.options.router) {\n // // TODO: check and fix usage of fragment/query params\n // const frag = fragment\n // ? fragment\n // : this.options.hash || this.options.name;\n // const _ = this.options.router.navigate([], {\n // queryParams: { page: page.toString() },\n // fragment: frag,\n // queryParamsHandling: 'merge',\n // });\n // }\n }\n return this;\n }\n\n /**\n * Stages which fields the API should return. Chainable; issues no request.\n *\n * Lets a list view ask only for the columns it actually shows, which matters on\n * wide models. Sent as a `fields` query parameter, and only when\n * `options.emitFields` is on — with it off, this is recorded but never\n * transmitted.\n *\n * @param fields field names to request; an empty array means \"no restriction\"\n */\n public setFields(fields: string[]): Queryset<T> {\n this.fields = fields;\n return this;\n }\n\n /**\n * Flattens the staged filter/sort/page/fields state into the query parameters\n * that will actually be sent.\n *\n * Exposed mainly for debugging and for building links that mirror the current\n * view; {@link get} calls it itself. Ordering goes out as `ordering`, paging as\n * `page`/`page_size`, and the field selection as `fields`.\n *\n * The `OutFilterData` return type is an assertion rather than a conversion —\n * numeric values such as `page` are still numbers at runtime, and are\n * stringified later by `HttpClient`.\n */\n public getQueryParams(): OutFilterData {\n const f: FilterData = {};\n Object.assign(f, this.filterData);\n if (this.sortData.length) {\n f['ordering'] = this.sortData.join(',');\n }\n f['page_size'] = this.pageSize;\n f['page'] = this.page;\n if (this.options.emitFields && this.fields.length) {\n f['fields'] = this.fields.join(',');\n }\n return f as OutFilterData;\n }\n\n /**\n * Runs the staged query and pushes the outcome through {@link results},\n * {@link meta} and {@link loading}.\n *\n * The one method that talks to the network. Call it after each change to the\n * filter/sort/page state; subscribers of `results` do not need to resubscribe,\n * they simply receive the new page. The returned observable is `results`\n * itself, so subscribing to the return value is a convenience, not a\n * requirement — though something must subscribe for the request to be sent.\n *\n * @param refresh when `false`, an already-fetched queryset (see\n * {@link pristine}) short-circuits and hands back the cached `results`\n * without any request. Use it where a component may be re-entered and should\n * reuse what is already loaded. A pristine queryset always fetches, whatever\n * this says.\n * @param sync adds `db=sync` to the query, asking the API to read from its\n * primary rather than a replica — for the read-after-write case where\n * replication lag would otherwise return stale rows\n *\n * @example\n * ```ts\n * qs.get().subscribe(); // always refetches\n * qs.get(false).subscribe(); // reuses results if already loaded once\n * ```\n */\n public get(refresh = true, sync = false): Observable<T[]> {\n if (!refresh && !this._pristine) {\n // console.log('@solidev/data: Get not refreshing, return current result observable');\n return this.results;\n }\n // console.log('@solidev/data: start get (query)');\n this._loading.next(true);\n const syncQp: Record<string, string> = {};\n if (sync) {\n syncQp['db'] = 'sync';\n }\n return this._coll\n .raw<IQueryFullResponse<T>>({\n method: 'GET',\n params: {\n ...this.getQueryParams(),\n ...syncQp,\n },\n })\n .pipe(\n switchMap((result) => {\n // Process results\n // console.log('@solidev/data: have meta');\n this._meta.next({ nav: result.nav, parameters: result.parameters });\n const out: T[] = [];\n for (const r of result.results) {\n const m = this._coll.fromJson(r);\n out.push(m);\n }\n this._pristine = false;\n // console.log('@solidev/data: have loading');\n this._loading.next(false);\n // console.log('@solidev/data: have result');\n this._results.next(out);\n // console.log('@solidev/data: done get');\n return this.results;\n }),\n );\n }\n}\n","import { DataModel } from './data-model';\nimport { fieldValues } from './field-values';\nimport { DataBackend } from './data-backend';\nimport { Observable } from 'rxjs';\nimport { FilterData, IQuerysetOptions, Queryset } from './data-query';\nimport { map, tap } from 'rxjs/operators';\n\n/** HTTP verbs this library issues. */\nexport type IHttpMethod = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH';\n\n/**\n * Per-request options shared by every {@link Collection} and {@link DataBackend}\n * call: body, headers and query parameters.\n *\n * All members are optional, so `{}` is a valid \"nothing special\" argument.\n */\nexport interface IActionParams {\n /** JSON body; ignored by GET/DELETE requests. */\n body?: unknown;\n /** Extra headers, merged on top of whatever the backend's `headers()` adds. */\n headers?: Record<string, string>;\n /** Query string parameters. */\n params?: Record<string, string>;\n /**\n * Expected response type. Note that the backend does not currently read this:\n * `DataBackend.action()` always parses JSON and `DataBackend.blob()` always\n * requests a blob. Use `Collection.blob()` to get binary data.\n */\n responseType?: 'json' | 'blob';\n}\n\n/**\n * Shape for describing per-collection cache tuning.\n *\n * Currently unused by the runtime — TransferState behaviour is driven by\n * `Collection.useTransferState` plus the `DATA_MAX_TRANSFERSTATE_TIME` token.\n */\nexport interface ICollectionCacheParams {\n transferState?: {\n enabled: boolean;\n maxTime: number;\n maxCount: number;\n };\n}\n\n/**\n * Constructor signature of a model class, letting a collection instantiate `T`\n * without knowing it — this is the `model` argument passed to\n * {@link Collection}'s constructor.\n */\nexport type DataModelType<T extends DataModel> = new (_coll?: Collection<T>) => T;\n\n/**\n * Binds a {@link DataModel} class to a REST endpoint and provides the CRUD\n * operations over it.\n *\n * A collection is the seam between models and HTTP: it knows the path, builds\n * URLs, hands raw JSON to the model for deserialization, and returns typed\n * instances that carry a back-reference to it (so `thing.save()` works). One\n * collection per endpoint, normally declared as a root-provided service.\n *\n * For anything involving filtering, sorting or pagination, go through\n * {@link queryset} rather than {@link list}.\n *\n * The endpoint is assumed to follow Django REST Framework conventions:\n * `/path` for the list, `/path/<id>` for a record, `/path/<id>/<action>` for\n * custom actions, and a *paginated* list response (see {@link list}).\n *\n * @example\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * export class ThingService extends Collection<Thing> {\n * constructor() {\n * super(inject(DataBackend), '/path/to/things', Thing);\n * }\n * }\n *\n * // then\n * things.fetch(1).subscribe((thing) => ...);\n * things.queryset().filter({ status: 'active' }).get().subscribe((list) => ...);\n * ```\n */\nexport class Collection<T extends DataModel> {\n /**\n * Whether GET responses for this collection may be served from / stored in\n * Angular's `TransferState` during SSR hydration.\n *\n * On by default, but only ever takes effect when `DATA_MAX_TRANSFERSTATE_TIME`\n * is provided and greater than zero. Set it to `false` on collections whose\n * data is user-specific or must not be embedded in the server-rendered HTML.\n */\n public useTransferState = true;\n\n /**\n * @param backend HTTP layer; supplies the API base URL and applies auth headers\n * @param path endpoint path appended to the backend's `apiUrl`, leading slash\n * included and trailing slash omitted (e.g. `'/path/to/things'`)\n * @param model model class this collection instantiates\n */\n constructor(\n protected backend: DataBackend,\n protected path: string,\n public model: DataModelType<T>,\n ) {}\n\n /**\n * Builds a new, unsaved model instance attached to this collection.\n *\n * Use it to back a creation form: the returned instance has no `id`, so the\n * first `save()` POSTs it. Values passed in `data` go through the field\n * managers' deserializers, exactly as if they had come from the API.\n *\n * @param data initial field values; omit for an empty instance\n *\n * @example\n * ```ts\n * const thing = things.create({ name: 'draft' });\n * thing.save().subscribe(); // POST /path/to/things\n * ```\n */\n public create(data?: Partial<T>): T {\n if (!data) {\n data = {};\n }\n return this.fromJson(data);\n }\n\n /**\n * Turns raw API JSON into model instances attached to this collection.\n *\n * Every read path funnels through here, and the attachment is the point: the\n * resulting instances can `save()`/`update()`/`action()` themselves. Call it\n * directly when you have JSON from somewhere other than this collection's own\n * requests (a websocket push, an embedded payload, a fixture).\n *\n * @param data one JSON object, or an array of them\n */\n fromJson(data: Partial<T>): T;\n fromJson(data: Partial<T>[]): T[];\n fromJson(data: Partial<T> | Partial<T>[]): T | T[] {\n if (data instanceof Array) {\n const out: T[] = [];\n for (const r of data) {\n const ri = new this.model(this);\n ri.fromJson(r);\n out.push(ri);\n }\n return out;\n }\n const m = new this.model(this);\n m.fromJson(data);\n return m;\n }\n\n /**\n * Opens a filterable, sortable, paginated view over this collection.\n *\n * The normal way to read lists: a {@link Queryset} accumulates query state and\n * exposes results/loading/meta as observables suitable for binding straight\n * into a template. Each call returns an independent queryset, so a component\n * showing two filtered lists of the same endpoint creates two.\n *\n * @param options queryset behaviour; see {@link IQuerysetOptions}\n */\n public queryset(options: IQuerysetOptions = {}): Queryset<T> {\n return new Queryset<T>(this, options);\n }\n\n /**\n * Retrieves a single record by primary key and returns it as a model.\n *\n * @param id primary key\n * @param prefix inserted between the collection path and the id, for endpoints\n * nested under a segment\n * @param suffix appended after the id, e.g. `'/detail'`\n * @param params query parameters\n * @param headers extra headers\n *\n * @example\n * ```ts\n * things.fetch(42).subscribe((thing) => ...); // GET /path/to/things/42\n * ```\n */\n public fetch(\n id: number,\n {\n prefix = '',\n suffix = '',\n params = {},\n headers = {},\n }: {\n prefix?: string;\n suffix?: string;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {},\n ): Observable<T> {\n return this.backend\n .get(this, this.getUrl(id, { prefix, suffix }), { headers, params })\n .pipe(map((result) => this.fromJson(result)));\n }\n\n /**\n * Calls a custom (non-CRUD) endpoint on this collection, either on one record\n * or on the collection as a whole, and returns the raw JSON response.\n *\n * This is the DRF `@action` convention. `DataModel.action()` delegates here;\n * call this directly for collection-level actions, which have no model.\n *\n * @param model record to act on, targeting `/path/to/things/<id>/<action>`, or\n * `null` for a collection-level action targeting `/path/to/things/<action>`\n * @param method HTTP method\n * @param action action name\n * @param body JSON body\n * @param params query parameters\n * @param headers extra headers\n */\n public action<RT>(\n model: T | null,\n method: IHttpMethod,\n action: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<RT> {\n return this.backend.action<T, RT>(\n this,\n method,\n this.getUrl(model ? model.id : null, {\n suffix: model ? '/' + action : action,\n }),\n { body, params, headers },\n );\n }\n\n /**\n * Writes a whole record: POST to the list URL when the model has no `id`,\n * PATCH to its detail URL when it does.\n *\n * Sends `model.toJson()`, i.e. every non-readonly field. Usually reached via\n * `model.save()` rather than called directly.\n *\n * @param model record to persist\n * @param updateModel feed the server's response back into `model` (defaults to\n * `true`), which is how a freshly created record gets its `id`. The returned\n * observable always emits a **separate** instance built from the response\n * either way.\n */\n public save(model: T, { updateModel = true }: { updateModel?: boolean } = {}): Observable<T> {\n const saveMethod =\n model.id !== undefined ? this.backend.patch.bind(this.backend) : this.backend.post.bind(this.backend);\n const url = model.id !== undefined ? this.getUrl(model.id) : this.getUrl();\n return saveMethod(this, url, { body: model.toJson() }).pipe(\n map((res) => this.fromJson(res)),\n tap((res) => {\n if (updateModel) {\n model.fromJson(fieldValues(res));\n }\n }),\n );\n }\n\n /**\n * Writes only the named fields of a record, dispatching POST/PATCH on `id`\n * exactly like {@link save}.\n *\n * Sends `model.toJson(fields)`, which restricts the payload to `fields` and\n * does **not** filter readonly ones. Usually reached via `model.update()`.\n *\n * @param model record to persist\n * @param fields field names to send; an empty list (the default) sends every\n * non-readonly field, making this equivalent to {@link save}\n * @param updateModel feed the server's response back into `model` (defaults to `true`)\n */\n public update(\n model: T,\n fields: string[] = [],\n { updateModel = true }: { updateModel?: boolean } = {},\n ): Observable<T> {\n const saveMethod =\n model.id !== undefined ? this.backend.patch.bind(this.backend) : this.backend.post.bind(this.backend);\n const url = model.id !== undefined ? this.getUrl(model.id) : this.getUrl();\n return saveMethod(this, url, { body: model.toJson(fields) }).pipe(\n map((res) => this.fromJson(res)),\n tap((res) => {\n if (updateModel) {\n model.fromJson(fieldValues(res));\n }\n }),\n );\n }\n\n /**\n * Deletes a record on the server. The local instance is left untouched — it is\n * the caller's job to drop it from whatever list holds it.\n *\n * @param model record to delete; its `id` builds the URL, so an unsaved model\n * would produce a request against the list URL\n * @param params query parameters\n * @param headers extra headers\n */\n public delete(model: T, { params = {}, headers = {} }: IActionParams = {}): Observable<unknown> {\n return this.backend.delete(this, this.getUrl(model.id), {\n params,\n headers,\n });\n }\n\n /**\n * Fetches a list of records in one shot, discarding pagination metadata.\n *\n * A shortcut for the simple cases (a dropdown's options, a small fixed set).\n * When you need paging, sorting, loading state or the result count, use\n * {@link queryset} instead.\n *\n * **The response must be paginated**: this reads `result.results` and returns\n * that array, so a DRF endpoint with pagination disabled — which answers with a\n * bare JSON array — yields an error rather than a list. The endpoint's page size\n * therefore also caps what you get back here; there is currently no way to point\n * this at a different response key (see the `FIXME` in the implementation).\n *\n * @param query filter parameters\n * @param prefix inserted before the suffix in the list URL\n * @param suffix appended to the list URL, for sub-endpoints\n * @param params extra query parameters, merged over `query`\n * @param headers extra headers\n */\n public list(\n query: FilterData = {},\n {\n prefix = '',\n suffix = '',\n params = {},\n headers = {},\n }: {\n prefix?: string;\n suffix?: string;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {},\n ): Observable<T[]> {\n const qry = Object.assign({}, query, params);\n return this.backend\n .list(\n this,\n this.getUrl(null, { suffix, prefix }),\n // SEE: forced typecast maybe bad\n { params: qry, headers },\n )\n .pipe(\n // FIXME: parametrize paginated results access\n map((result: { results: Partial<T>[] }) => this.fromJson(result.results)),\n );\n }\n\n /**\n * Calls a collection-level endpoint and returns the response body **unparsed**,\n * without turning it into models.\n *\n * The escape hatch for responses that are not a list of records: aggregates,\n * stats, export summaries. It is also what {@link Queryset} uses internally,\n * since a queryset needs the pagination envelope that {@link list} throws away.\n *\n * @param method HTTP method; defaults to GET\n * @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`\n * @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`\n * @param params query parameters\n * @param body accepted but **not currently sent** — the implementation does not\n * forward it to the backend, so non-GET calls needing a body must go through\n * {@link action}\n * @param headers extra headers\n */\n public raw<RT>({\n method = 'GET',\n prefix = '',\n suffix = '',\n params = {},\n body: _body = {},\n headers = {},\n }: {\n method?: IHttpMethod;\n prefix?: string;\n suffix?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {}): Observable<RT> {\n return this.backend.action(this, method, this.getUrl(null, { suffix, prefix }), {\n params,\n headers,\n });\n }\n\n /**\n * Calls a collection-level endpoint and returns the response as a `Blob`.\n *\n * Use it for binary or file downloads (CSV/XLSX/PDF exports) where the response\n * must not be parsed as JSON.\n *\n * @param method HTTP method; defaults to GET\n * @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`\n * @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`\n * @param params query parameters\n * @param body accepted but **not currently sent** — the implementation does not\n * forward it to the backend\n * @param headers extra headers\n */\n // `RT` is unused -- `blob()` always resolves to a Blob -- but dropping it\n // would be a breaking change for callers writing `blob<T>()`.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public blob<RT>({\n method = 'GET',\n prefix = '',\n suffix = '',\n params = {},\n body: _body = {},\n headers = {},\n }: {\n method?: IHttpMethod;\n prefix?: string;\n suffix?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {}): Observable<Blob> {\n return this.backend.blob(this, method, this.getUrl(null, { suffix, prefix }), {\n params,\n headers,\n });\n }\n\n /**\n * Builds the absolute URL for this collection or one of its records.\n *\n * Every request the collection makes goes through here, so overriding it is the\n * supported way to bend URL construction (versioned or nested endpoints).\n *\n * Layout is `apiUrl + path` for the list, `apiUrl + path + '/' + prefix + id +\n * suffix` for a record, and `apiUrl + path + '/' + prefix + suffix` for the list\n * with affixes. Note the separating slash is only emitted when there is\n * something after it, so a plain list URL has no trailing slash.\n *\n * @param id primary key for a detail URL; `undefined` or `null` yields the list URL\n * @param prefix inserted just before the id (or before the suffix)\n * @param suffix appended at the very end\n */\n public getUrl(id?: number | null, { prefix = '', suffix = '' }: { prefix?: string; suffix?: string } = {}): string {\n if (id === undefined || id === null) {\n if (prefix || suffix) {\n return `${this.backend.apiUrl}${this.path}/${prefix}${suffix}`;\n } else {\n return `${this.backend.apiUrl}${this.path}`;\n }\n }\n return `${this.backend.apiUrl}${this.path}/${prefix}${id}${suffix}`;\n }\n}\n","import { HttpClient } from '@angular/common/http';\n\nimport { Observable, of } from 'rxjs';\nimport { tap } from 'rxjs/operators';\nimport { Injectable, PLATFORM_ID, TransferState, inject, makeStateKey } from '@angular/core';\nimport { isPlatformServer } from '@angular/common';\nimport { Collection, IActionParams } from './data-collection';\nimport { DataModel } from './data-model';\nimport { DATA_API_URL, DATA_MAX_TRANSFERSTATE_TIME } from './data-parameters';\n\n/**\n * The HTTP layer every {@link Collection} sits on: it owns the API base URL,\n * decides the headers, and optionally serves GET responses out of Angular's\n * `TransferState` during SSR hydration.\n *\n * Collections never touch `HttpClient` directly, which makes this the one place\n * to hook cross-cutting request concerns. The usual reason to care about this\n * class is {@link headers}: subclass it, override that method to inject an auth\n * token, and provide the subclass in place of the default.\n *\n * Requires {@link DATA_API_URL}. TransferState caching applies to GET only, and\n * only when {@link DATA_MAX_TRANSFERSTATE_TIME} is provided and greater than\n * zero — see {@link _cachedGet} for the exact conditions.\n *\n * Dependencies are resolved with `inject()`, so a subclass declares **no\n * constructor**. To point one at a different API — a second backend alongside\n * the main one — override {@link apiUrl} rather than passing a URL through\n * `super()`; {@link maxTransferstateTime} is overridable the same way.\n *\n * @example\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * export class AuthBackend extends DataBackend {\n * protected override headers(headers: { [k: string]: string }) {\n * return { ...super.headers(headers), Authorization: `Bearer ${token}` };\n * }\n * }\n *\n * @Injectable({ providedIn: 'root' })\n * export class SupportBackend extends DataBackend {\n * public override get apiUrl(): string {\n * return 'https://support.example.com/api';\n * }\n * }\n *\n * providers: [\n * { provide: DATA_API_URL, useValue: 'https://api.example.com' },\n * { provide: DataBackend, useClass: AuthBackend },\n * ];\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DataBackend {\n /**\n * Instantiation timestamp, used as the origin of the TransferState validity\n * window (see {@link _cachedGet}) — the window runs from backend creation, not\n * from each entry's insertion.\n */\n private _created = new Date();\n\n private _http = inject(HttpClient);\n private _transferState = inject(TransferState);\n private _platform = inject<object>(PLATFORM_ID);\n private _apiUrl = inject(DATA_API_URL);\n private _maxTransferstateTime = inject(DATA_MAX_TRANSFERSTATE_TIME, { optional: true }) ?? 0;\n\n /**\n * Base URL every collection URL is built on, as provided via\n * {@link DATA_API_URL}. Read by `Collection.getUrl()`; exposed so custom\n * collections can build URLs the same way.\n */\n public get apiUrl(): string {\n return this._apiUrl;\n }\n\n /**\n * TransferState window in ms, from {@link DATA_MAX_TRANSFERSTATE_TIME}; `0`\n * disables the cache. Overridable for the same reason as {@link apiUrl}.\n */\n protected get maxTransferstateTime(): number {\n return this._maxTransferstateTime;\n }\n\n /**\n * Issues an arbitrary request and returns the parsed JSON body.\n *\n * The general-purpose entry point, used by `Collection.action()` and\n * `Collection.raw()`. GET requests are routed through {@link _cachedGet} and so\n * may be answered from TransferState; every other method goes straight to the\n * network and carries the body.\n *\n * @param collection collection the request belongs to; consulted for its\n * `useTransferState` flag\n * @param method HTTP method\n * @param url absolute URL, normally from `Collection.getUrl()`\n * @param body JSON body; ignored for GET\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n *\n * @return an observable of the response body\n */\n public action<T extends DataModel, RT>(\n collection: Collection<T>,\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<RT> {\n if (method === 'GET') {\n return this._cachedGet(collection, url, {\n headers: this.headers(headers),\n params,\n });\n } else {\n return this._http.request<RT>(method, url, {\n body,\n params,\n headers: this.headers(headers),\n });\n }\n }\n\n /**\n * Issues a request whose response is taken as binary rather than JSON.\n *\n * Backs `Collection.blob()`; use that instead of calling this directly. Never\n * cached through TransferState, whatever the method.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param method HTTP method\n * @param url absolute URL\n * @param body JSON body\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n *\n * @return an observable of the response as a `Blob`\n */\n public blob<T extends DataModel>(\n collection: Collection<T>,\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<Blob> {\n return this._http.request(method, url, {\n body,\n params,\n headers: this.headers(headers),\n responseType: 'blob',\n });\n }\n\n /**\n * Full-replacement write (HTTP PUT). Provided for completeness — the CRUD path\n * in `Collection` uses {@link post}/{@link patch} instead, so this is only\n * reached by callers that need PUT semantics explicitly.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param url absolute URL\n * @param body JSON body\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n */\n public put<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<T> {\n return this._http.put<T>(url, body, {\n params,\n headers: this.headers(headers),\n });\n }\n\n /**\n * Creates a record (HTTP POST). Chosen by `Collection.save()`/`update()` when\n * the model has no `id`.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param url absolute URL, normally the collection's list URL\n * @param body JSON body\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n * @returns the created record's JSON, expected to include the assigned `id`\n */\n public post<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<Partial<T>> {\n return this._http.post<Partial<T>>(url, body, {\n params,\n headers: this.headers(headers),\n });\n }\n\n /**\n * Partially updates a record (HTTP PATCH). Chosen by\n * `Collection.save()`/`update()` when the model already has an `id`.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param url absolute URL, normally the record's detail URL\n * @param body JSON body, holding only the fields to change\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n */\n public patch<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<Partial<T>> {\n return this._http.patch<Partial<T>>(url, body, {\n params,\n headers: this.headers(headers),\n });\n }\n\n /**\n * Deletes a record (HTTP DELETE). Backs `Collection.delete()`.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param url absolute URL of the record\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n */\n public delete<T extends DataModel, R>(\n collection: Collection<T>,\n url: string,\n { params = {}, headers = {} }: IActionParams = {},\n ): Observable<R> {\n return this._http.delete<R>(url, {\n params,\n headers: this.headers(headers),\n });\n }\n\n /**\n * Performs a GET, transparently replaying the server-rendered response from\n * `TransferState` when that is still allowed.\n *\n * This is what stops an SSR app from re-fetching, in the browser, everything it\n * already fetched on the server to render the page. Entries are keyed on URL +\n * params + resolved headers, so requests differing in any of those do not share\n * a slot.\n *\n * A cached value is **read** only when all of these hold: the collection has\n * `useTransferState`, {@link DATA_MAX_TRANSFERSTATE_TIME} is greater than zero,\n * the key is present, and less than that many milliseconds have passed since\n * *this backend instance was created*. That last condition makes the window a\n * one-shot hydration budget rather than a per-entry TTL: once it lapses, nothing\n * is served from TransferState again for the life of the backend.\n *\n * A value is **written** only when the collection has `useTransferState`, the\n * code is running on the server, and the window is greater than zero. So in the\n * browser this degrades to a plain, uncached `HttpClient.get`.\n *\n * @param collection collection the request belongs to; consulted for `useTransferState`\n * @param url absolute URL\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n */\n public _cachedGet<T extends DataModel, RT>(\n collection: Collection<T>,\n url: string,\n { params = {}, headers = {} }: IActionParams = {},\n ): Observable<RT> {\n const cur_headers = this.headers(headers);\n\n const key = makeStateKey<RT>(url + '|' + JSON.stringify(params) + '|' + JSON.stringify(cur_headers));\n if (\n collection.useTransferState &&\n this.maxTransferstateTime > 0 &&\n this._transferState.hasKey(key) &&\n new Date().getTime() - this._created.getTime() < this.maxTransferstateTime\n ) {\n return of(this._transferState.get<RT | null>(key, null) as RT);\n }\n return this._http.get<RT>(url, { headers: cur_headers, params }).pipe(\n tap((result) => {\n if (collection.useTransferState && isPlatformServer(this._platform) && this.maxTransferstateTime > 0) {\n this._transferState.set<RT>(key, result);\n }\n }),\n );\n }\n\n /**\n * Fetches a single record's JSON. Backs `Collection.fetch()`, and is\n * TransferState-cacheable via {@link _cachedGet}.\n *\n * @param collection collection the request belongs to\n * @param url absolute URL of the record\n * @param params query parameters\n * @param headers extra headers\n */\n public get<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { params = {}, headers = {} }: IActionParams = {},\n ): Observable<Partial<T>> {\n return this._cachedGet<T, Partial<T>>(collection, url, {\n headers: this.headers(headers),\n params,\n });\n }\n\n /**\n * Fetches a list endpoint's raw JSON — including the pagination envelope, which\n * `Collection.list()` then unwraps. Identical to {@link get} apart from the\n * declared return type; both funnel into {@link _cachedGet}.\n *\n * @param collection collection the request belongs to\n * @param url absolute URL of the list endpoint\n * @param params query parameters, typically the queryset's filters and paging\n * @param headers extra headers\n */\n public list<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { params = {}, headers = {} }: IActionParams = {},\n ): Observable<{ results: Partial<T>[] }> {\n return this._cachedGet<T, { results: Partial<T>[] }>(collection, url, {\n headers: this.headers(headers),\n params,\n });\n }\n\n /**\n * Resolves the headers actually sent with a request.\n *\n * **The designated extension point of this class.** The base implementation\n * just copies what it is given; subclasses override it to add headers that\n * every request needs — most often an `Authorization` token — and then get\n * provided in place of `DataBackend`. Doing it here rather than in an HTTP\n * interceptor keeps the headers part of the TransferState cache key, so\n * responses fetched under different credentials do not collide.\n *\n * Implementations should stay pure and synchronous: this is called once per\n * request, and for GETs its result feeds the cache key.\n *\n * @param headers per-request headers supplied by the caller\n * @returns the complete header set to send\n */\n protected headers(headers: Record<string, string>): Record<string, string> {\n return Object.assign({}, headers);\n }\n}\n","import { Observable, ReplaySubject } from 'rxjs';\nimport { DataModel } from '../../data/data-model';\nimport { Collection } from '../../data/data-collection';\nimport { FieldsParams } from '../model-list.service';\n\n/**\n * One column of a list: a model field (or a {@link CustomField}) together with\n * its display state.\n */\nexport interface ModelListField {\n /** Field name, as declared on the model, or the custom column's key. */\n name: string;\n /** Column title, taken from the field's `description` and falling back to `name`. */\n label: string;\n /** Currently displayed. */\n enabled: boolean;\n /** The user may enable it from the field selector. */\n allowed: boolean;\n /** The field's current value/manager, `null` for custom columns. */\n field: unknown;\n /** Sort key for display order, renumbered in steps of 10 on every change. */\n position: number;\n /** Ordering weight from the field metadata, higher first; `-1` means \"never shown by default\". */\n priority: number;\n}\n\n/**\n * The columns of a list: which exist, which are shown, and in what order.\n *\n * Built from the model's decorated fields plus any {@link FieldsParams.custom}\n * entries, then narrowed by `allowed`/`defaults`/`excluded`. Components mutate it\n * through {@link enable}/{@link disable}/{@link move}/{@link setPosition}; every\n * mutation renumbers positions and pushes the enabled field names on\n * {@link output}, which re-runs the list's query with the new `fields` param.\n */\nexport class ModelListFields<T extends DataModel> {\n private readonly __fields!: ModelListField[];\n\n /**\n * Resolve the column set once, from the model's fields and `params`.\n *\n * Fields are ordered by `priority` (higher first, ties broken by declaration\n * order), enabled fields are then laid out in `defaults` order, and anything\n * neither allowed nor enabled is dropped. An empty or absent `allowed` means\n * every field is allowed, and every field with `priority >= 0` is enabled.\n *\n * @param collection collection whose model provides the fields\n * @param params column selection, see {@link FieldsParams}\n */\n constructor(collection: Collection<T>, params?: FieldsParams) {\n // Get fields from model\n const m = collection.create();\n const tmp = [];\n for (const fn of m.FN) {\n tmp.push({\n name: fn,\n label: m.FM(fn).description || fn,\n allowed: false,\n enabled: false,\n field: m.FV(fn),\n position: tmp.length * 10,\n priority: m.FM(fn).priority || 0,\n });\n }\n // Add custom fields if provided\n const custom = params?.custom || [];\n for (const c of custom) {\n tmp.push({\n name: c.name,\n label: c.label,\n allowed: false,\n enabled: false,\n field: null,\n position: tmp.length * 10,\n priority: c.priority || 0,\n });\n }\n\n tmp.sort((b, a) => (a.priority === b.priority ? b.position - a.position : a.priority - b.priority));\n let pos = 0;\n for (const i of tmp) {\n i.position = pos;\n pos += 10;\n }\n\n // Prepare allowed fields (all fields if not set or empty)\n let allowed: string[];\n let ddefaults: string[];\n if (params?.allowed === undefined || params?.allowed.length === 0) {\n allowed = tmp.map((f) => f.name);\n ddefaults = tmp.filter((f) => f.priority >= 0).map((f) => f.name);\n } else {\n allowed = params.allowed;\n ddefaults = params.allowed;\n }\n\n // Prepare excluded fields\n const excluded: string[] = params?.excluded || [];\n\n // Process default fields\n // Use all allowed fields if empty of not set\n const defaults: string[] = params?.defaults || ddefaults;\n\n // Prepare fields status\n // Set allowed\n for (const fe of allowed) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.allowed = true;\n }\n }\n }\n // Set defaults\n for (const fe of defaults) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.enabled = true;\n f.allowed = true;\n }\n }\n }\n\n // remove excluded\n for (const fe of excluded) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.enabled = false;\n f.allowed = false;\n }\n }\n }\n const filtered = [];\n for (const f of tmp) {\n if (!(!f.enabled && !f.allowed)) {\n filtered.push(f);\n }\n }\n\n const ordered = [];\n const enabled = filtered.filter((f) => f.enabled);\n pos = 0;\n for (const fe of defaults) {\n for (const f of enabled) {\n if (f.name === fe) {\n f.position = pos;\n pos += 10;\n }\n }\n }\n enabled.sort((a, b) => a.position - b.position);\n const disabled = filtered.filter((f) => !f.enabled);\n let ei = 0;\n let di = 0;\n while (ei + di < filtered.length) {\n if (enabled[ei] && disabled[di]) {\n if (enabled[ei].priority > disabled[di].priority) {\n ordered.push(enabled[ei]);\n ei += 1;\n } else {\n ordered.push(disabled[di]);\n di += 1;\n }\n } else if (enabled[ei]) {\n ordered.push(enabled[ei]);\n ei += 1;\n } else {\n ordered.push(disabled[di]);\n di += 1;\n }\n }\n pos = 0;\n for (const f of ordered) {\n f.position = pos;\n pos += 10;\n }\n\n this.__fields = ordered;\n this._update();\n }\n\n private _fields = new ReplaySubject<ModelListField[]>(1);\n\n /**\n * Every column, enabled or not, in display order; re-emitted on each change.\n * This is what the field selector and the header menus render.\n */\n public get fields(): Observable<ModelListField[]> {\n return this._fields.asObservable();\n }\n\n private _enabled: string[] = [];\n\n /** Names of the currently displayed columns, in display order. */\n public get enabled(): string[] {\n return this._enabled;\n }\n\n private _output = new ReplaySubject<string[]>(1);\n\n /**\n * Enabled column names, re-emitted on each change. Consumed by\n * {@link ModelList.start} to set the query's `fields` parameter.\n */\n public get output(): Observable<string[]> {\n return this._output.asObservable();\n }\n\n /**\n * Enable a field by name. Position is optional.\n *\n * @param fname : name of field to be enabled\n * @param position : position (optional)\n * @returns current enabled fields\n */\n public enable(fname: string, position?: number): string[] {\n const f = this.get(fname);\n if (f) {\n f.enabled = true;\n if (position !== undefined) {\n f.position = position;\n }\n } else {\n console.error('Field not found', f);\n }\n this._update();\n return this._enabled;\n }\n\n /**\n * Disable a field by name.\n *\n * @param fname : name of field to be disabled\n * @returns current enabled fields\n */\n public disable(fname: string): string[] {\n const f = this.get(fname);\n if (f) {\n f.enabled = false;\n } else {\n console.error('Field not found', f);\n }\n this._update();\n return this._enabled;\n }\n\n /**\n * Move field `fname` before or after (depending on `position`) field `dest`.\n *\n * With `dest` omitted, the field swaps with its neighbour on that side among\n * the *enabled* fields, which is what the header's left/right arrows do; it is\n * a no-op at either end.\n *\n * @param fname field to move\n * @param position (\"before\" or \"after\")\n * @param dest reference field, defaults to `fname`'s neighbour\n * @returns current enabled fields\n */\n public move(fname: string, position: 'before' | 'after', dest = ''): string[] {\n const ftarget = this.get(fname);\n if (dest == '') {\n const pos = this._enabled.indexOf(fname);\n dest = this._enabled[pos + (position === 'before' ? -1 : +1)];\n if (dest === undefined) {\n return this._enabled;\n }\n }\n const fdest = this.get(dest);\n // istanbul ignore if\n if (!ftarget || !fdest) {\n console.error('Target / dest not found', fname, dest);\n return this._enabled;\n }\n if (fname == dest) {\n ftarget.position = fdest.position + (position === 'before' ? -15 : +15);\n } else {\n ftarget.position = fdest.position + (position === 'before' ? -5 : +5);\n }\n\n this._update();\n return this._enabled;\n }\n\n /**\n * Check if field with name `fname` is enabled.\n *\n * @param fname : name of field\n * @returns enabled (true) or disabled (false)\n */\n public isEnabled(fname: string): boolean {\n return this._enabled.indexOf(fname) !== -1;\n }\n\n /**\n * Get field by name\n * @param fname : name of field\n * @returns Model list field or null if not found\n */\n public get(fname: string): ModelListField | null {\n for (const f of this.__fields) {\n if (f.name === fname) {\n return f;\n }\n }\n return null;\n }\n\n /**\n * Get the field at index `pos` in display order.\n *\n * Note this is an array index (0, 1, 2...), *not* a {@link ModelListField.position}\n * value — those are renumbered in steps of 10.\n *\n * @param pos : index of field\n * @returns Model list field or null if not found\n */\n public getAtPos(pos: number): ModelListField | null {\n return this.__fields[pos] || null;\n }\n\n /**\n * Set a field's raw sort key, then reorder. Used by the field selector's\n * drag-and-drop, which computes a key that lands between two existing fields.\n *\n * @param fname name of field to move\n * @param position new sort key\n * @returns current enabled fields\n */\n setPosition(fname: string, position: number): string[] {\n const f = this.get(fname);\n if (f) {\n f.position = position;\n } else {\n console.error('Field not found', f);\n }\n this._update();\n return this._enabled;\n }\n\n private _update() {\n this.__fields.sort((a, b) => a.position - b.position);\n let i = 0;\n for (const f of this.__fields) {\n f.position = i * 10;\n i += 1;\n }\n const out: string[] = [];\n for (const f of this.__fields) {\n if (f.enabled) {\n out.push(f.name);\n }\n }\n this._enabled = out;\n this._output.next(this._enabled);\n this._fields.next(this.__fields);\n }\n}\n","import { IQueryNav } from '../../data/data-query';\nimport { Observable, ReplaySubject } from 'rxjs';\n\n/**\n * The current page and page size of a list.\n *\n * Note the two families of methods: `setPage`/`setPageSize` emit on\n * {@link output} and therefore re-run the list's query, while\n * `updatePage`/`updatePageSize` change the value silently. The silent ones exist\n * so the UI can absorb what the server actually returned — the API may clamp a\n * page or a size — without triggering a second query.\n */\nexport class ModelListPaginator {\n private _page_size!: number;\n private _page!: number;\n\n /**\n * @param defaults initial page and page size; defaults to page 1, 20 per page.\n */\n constructor(defaults?: IQueryNav) {\n if (!defaults) {\n defaults = { page_size: 20, page: 1 };\n }\n this._page_size = defaults.page_size || 20;\n this._page = defaults.page || 1;\n this._updateOutput('constructor');\n }\n\n private _output = new ReplaySubject<IQueryNav>(1);\n\n /**\n * Current page and page size, re-emitted whenever they are `set`.\n * Consumed by {@link ModelList.start} to paginate the query.\n */\n public get output(): Observable<IQueryNav> {\n return this._output.asObservable();\n }\n\n /** Go to `page`, re-running the query. No-op if already there. */\n public setPage(page: number): void {\n if (page !== this._page) {\n this._page = page;\n this._updateOutput('setPage');\n }\n }\n\n /** Record the page the server reported, without re-running the query. */\n public updatePage(page: number): void {\n if (page !== this._page) {\n this._page = page;\n }\n }\n\n /** Change the page size, re-running the query. No-op if unchanged. */\n public setPageSize(size: number): void {\n if (size !== this._page_size) {\n this._page_size = size;\n this._updateOutput('setPageSize');\n }\n }\n\n /** Record the page size the server reported, without re-running the query. */\n public updatePageSize(size: number): void {\n if (size !== this._page_size) {\n this._page_size = size;\n }\n }\n\n /** Current page size. */\n public getPageSize(): number {\n return this._page_size;\n }\n\n /** Current page number, 1-based. */\n public getPage(): number {\n return this._page;\n }\n\n private _updateOutput(_from = ''): void {\n this._output.next({ page: this._page, page_size: this._page_size });\n }\n}\n","import { Observable, ReplaySubject } from 'rxjs';\nimport { SorterDefaults } from '../model-list.service';\n\n// TODO: add an option to limit the number of ordering fields (eg. for tree queries)\n/** Direction of a sort key. */\nexport type SortDirection = 'asc' | 'desc';\n\n/** One sort key: a field and the direction it is sorted in. */\nexport interface FieldSortData {\n field: string;\n direction: SortDirection;\n}\n\n/** Ordered sort keys; earlier entries take precedence. */\nexport type SorterData = FieldSortData[];\n\n/**\n * The sort keys of a list, as an ordered multi-key set.\n *\n * Each {@link set} adds a key at the end or updates an existing one in place, so\n * clicking successive column headers refines the sort rather than replacing it,\n * and {@link getOrder} tells the UI where a column ranks. Every change emits on\n * {@link output} as the `+field`/`-field` strings the queryset wants, which\n * re-runs the list's query.\n */\nexport class ModelListSorter {\n private readonly _values: SorterData = [];\n\n /**\n * Create ModelListSorter instance, using defaults.\n * @param defaults defaults sort values, as a list of strings (+field, -field, field)\n */\n constructor(defaults: SorterDefaults = []) {\n this._output = new ReplaySubject(1);\n this._values = [];\n for (const d of defaults) {\n if (d.length < 1) {\n continue;\n }\n if (d[0] == '+') {\n this._values.push({ field: d.substring(1), direction: 'asc' });\n } else if (d[0] == '-') {\n this._values.push({ field: d.substring(1), direction: 'desc' });\n } else {\n this._values.push({ field: d, direction: 'asc' });\n }\n }\n this._updateOutput('constructor');\n }\n\n private _output: ReplaySubject<string[]>;\n\n /**\n * Returns a list of \"+/-field\" sort strings observable.\n * @returns sort strings observable\n */\n public get output(): Observable<string[]> {\n return this._output.asObservable();\n }\n\n /**\n * Set sorting for `name` key, in direction `direction`.\n * If sorting is already set for `name` key, updates direction without changing order.\n * If sorting isn't set for `name` key, adds it at the end of sorting directions.\n *\n * @param name field name\n * @param direction sort direction\n * @returns model list sorter\n */\n public set(name: string, direction: SortDirection): ModelListSorter {\n for (const v of this._values) {\n if (v.field === name) {\n v.direction = direction;\n this._updateOutput();\n return this;\n }\n }\n this._values.push({ field: name, direction });\n this._updateOutput('set');\n return this;\n }\n\n /**\n * Removes `name` sorting key from current keys.\n *\n * @param name sort key to be removed\n * @returns model list sorter\n */\n public unset(name: string): ModelListSorter {\n for (let i = 0; i < this._values.length; i++) {\n if (this._values[i].field === name) {\n this._values.splice(i, 1);\n break;\n }\n }\n this._updateOutput('unset');\n return this;\n }\n\n /**\n * Get sorting status for `field` argument.\n * If `field` is not found, returns null.\n *\n * @param field field name\n * @returns ordering direction / null\n */\n public get(field: string): FieldSortData | null {\n for (const v of this._values) {\n if (v.field === field) {\n return v;\n }\n }\n return null;\n }\n\n /**\n * Return all sorter data values.\n *\n * @returns all sorter data values.\n */\n public getAll(): SorterData {\n return this._values;\n }\n\n /**\n * Get the ordering position for `field` argument. If not found, returns -1.\n *\n * The rank is 1-based, so it can be shown as-is next to a column header when\n * several columns are sorted at once.\n *\n * @param field field name\n * @returns ordering position for field\n */\n public getOrder(field: string): number {\n for (let i = 0; i < this._values.length; i++) {\n if (this._values[i].field === field) {\n return i + 1;\n }\n }\n return -1;\n }\n\n private _updateOutput(_from = ''): void {\n const out: string[] = [];\n for (const v of this._values) {\n out.push(`${v.direction === 'asc' ? '' : '-'}${v.field}`);\n }\n this._output.next(out);\n }\n}\n","import { FilterData, FilterValue } from '../../data/data-query';\nimport { Observable, ReplaySubject } from 'rxjs';\nimport { FILTER_TYPE } from './filters/filtertypes';\nimport { IDispEditChoice } from '../../dispedit/dispedit/dispedit.constants';\nimport { ModelListFilterGroup } from './model-list-filter-group';\n\n/**\n * Construction parameters shared by every filter type.\n *\n * Every concrete filter (text, select, autocomplete, ...) extends this\n * interface with its own extra options.\n */\n\nexport interface ModelListFilterParams {\n /**\n * The filter's identity within its {@link ModelListFilters} set. This is the\n * string used by the `allowed`, `defaults` and `excluded` lists to designate\n * this filter; it is never sent to the server. It must be unique across the\n * list, even when several filters share the same {@link field}.\n */\n name: string;\n /**\n * The query parameter name sent to the server when the filter has a value.\n * This is usually identical to {@link name}, but the two are deliberately\n * separate: two filters may target the same `field` under different `name`s\n * and different fixed scopes, so that they appear as two independent widgets\n * while querying the same backend parameter.\n */\n field: string;\n /**\n * Label displayed above the filter widget and in the filter picker. Always\n * set it explicitly: when omitted, every filter subclass falls back to a\n * hardcoded French default (see the class documentation).\n */\n label?: string;\n /**\n * Help text, generally rendered as the widget's placeholder. As with\n * {@link label}, leaving it unset yields a hardcoded French default.\n */\n help?: string;\n /**\n * Not read by the constructor. {@link ModelListFilter} initialises its value\n * from {@link default} instead; see the `FIXME` in the constructor body.\n */\n value?: FilterValue;\n /**\n * Free-form description used as the `title` (native tooltip) of this filter's\n * entry in the `data-model-list-filters-select` picker. It has no effect on\n * the query.\n */\n desc?: string;\n /**\n * Initial value applied at construction time. Only some subclasses act on it\n * (text, select and select-multi); the others ignore it. Its expected shape\n * depends on the subclass.\n */\n default?: unknown;\n /**\n * CSS classes applied to the filter's container element, overriding the\n * `classes` input passed by the host component. Use it to give one filter a\n * different width or layout from its siblings.\n */\n displayClasses?: string[] | string;\n /**\n * Set automatically by {@link ModelListFilters} when the filter is declared\n * inside a {@link ModelListFilterGroup}. Do not set it by hand.\n */\n group?: ModelListFilterGroup;\n}\n\n/**\n * Base class for all model list filters.\n *\n * A filter holds one user-chosen value (or a set of values when {@link multi}\n * is `true`), exposes it as an observable, and contributes a query parameter to\n * the list's request through {@link updateFilter}. Concrete filters (\n * {@link ModelListTextFilter}, {@link ModelListSelectFilter}, ...) subclass it\n * to set their {@link type} and their own options; each `type` is paired with a\n * component that renders the widget.\n *\n * Filters are not used standalone: they are passed to {@link ModelListFilters}\n * through the `filters` parameter of a `ModelList`, which decides which ones are\n * allowed and which are enabled by default.\n *\n * ## `name` vs `field`\n *\n * `field` is the query parameter sent to the server; `name` is the filter's\n * identity, used by the `allowed`, `defaults` and `excluded` lists. They are\n * usually equal, but keeping them separate lets two filters share a single\n * `field` while remaining two distinct, independently selectable widgets.\n *\n * ## Always set `label` and `help`\n *\n * Every subclass substitutes a hardcoded **French** string for `label` and\n * `help` when you leave them empty (for instance `'Recherche par texte'`).\n * Unless your application is French, pass both explicitly on every filter you\n * create, otherwise French text leaks into the UI.\n *\n * ## Single vs multiple values\n *\n * When {@link multi} is `false` (the default) the filter holds one value and\n * sends it as-is. When `true`, it holds a set of values and sends them joined\n * by `,` in a single query parameter. Subclasses such as\n * {@link ModelListSelectMultiFilter} or {@link ModelListFlagsFilter} force\n * `multi` to `true`.\n */\nexport class ModelListFilter implements ModelListFilterParams {\n /** Filter identity, used by `allowed`/`defaults`/`excluded`. Never sent to the server. */\n public name: string;\n /** Query parameter name sent to the server. May be shared by several filters. */\n public field: string;\n /** Label shown above the widget. Defaults to a French string set by each subclass. */\n public label: string;\n /** Help/placeholder text. Defaults to a French string set by each subclass. */\n public help: string;\n /** Tooltip text for the filter picker entry; does not affect the query. */\n public desc?: string;\n /** Initial value, applied at construction by the subclasses that support it. */\n public default?: unknown;\n /** Discriminator telling {@link ModelListFiltersComponent} which widget to render. */\n public type: FILTER_TYPE;\n /**\n * Whether the user may turn this filter on. Computed by {@link ModelListFilters}\n * from the `allowed`/`defaults`/`excluded` lists; disallowed filters are absent\n * from the picker.\n */\n public allowed: boolean;\n /**\n * Whether the filter is currently active: enabled filters are rendered and\n * contribute to the query. Toggled by the picker, or preset via `defaults`.\n */\n public enabled: boolean;\n /** Per-filter CSS classes overriding the host component's `classes` input. */\n public displayClasses?: string[] | string;\n /** Declared and initialised to `true`, but never updated anywhere in the library. */\n public pristine = true;\n /**\n * When `true`, the filter accumulates several values and joins them with `,`\n * into a single query parameter. Subclasses set this; do not change it on an\n * existing instance.\n */\n public multi = false;\n /** The group this filter belongs to, wired up by {@link ModelListFilters}. */\n public group?: ModelListFilterGroup;\n\n /** Single current value */\n protected _value: IDispEditChoice | null = null;\n /** Multiple current value */\n protected _mvalue = new Map<string, string>();\n /** Single current value observable */\n protected _current = new ReplaySubject<IDispEditChoice | null>(1);\n /** Multiple current value observable */\n protected _mcurrent = new ReplaySubject<IDispEditChoice[]>(1);\n\n /**\n * Builds a bare filter. In practice you instantiate a subclass rather than\n * this class directly, since each subclass sets its own {@link type} and\n * validates the options its widget needs.\n *\n * Both `allowed` and `enabled` start out `false`: it is\n * {@link ModelListFilters} that turns them on according to its own\n * `allowed`/`defaults`/`excluded` parameters.\n */\n constructor(params: ModelListFilterParams) {\n this.name = params.name;\n this.field = params.field;\n this.label = params.label || '';\n this.help = params.help || '';\n this.desc = params.desc;\n this.displayClasses = params.displayClasses;\n this.allowed = false;\n this.enabled = false;\n this.type = 'text';\n this.default = params.default;\n // FIXME: add value init\n }\n\n /**\n * The current set of values, for multi-valued filters. Emits the full set on\n * every change. Meaningless on a single-valued filter, which never feeds it.\n */\n public get mcurrent$(): Observable<IDispEditChoice[]> {\n return this._mcurrent.asObservable();\n }\n\n /**\n * The current value, for single-valued filters, or `null` once cleared.\n * Meaningless on a multi-valued filter, which never feeds it.\n */\n public get current$(): Observable<IDispEditChoice | null> {\n return this._current.asObservable();\n }\n\n /**\n * The filter's value stream, picking the right source according to\n * {@link multi}. This is what widget components subscribe to in order to\n * reflect external changes back into their form control; prefer it over\n * {@link current$}/{@link mcurrent$} in code that must handle both kinds.\n */\n public get valueChanges(): Observable<IDispEditChoice | IDispEditChoice[] | null> {\n if (this.multi) {\n return this._mcurrent.asObservable();\n }\n return this._current.asObservable();\n }\n\n /**\n * A human-readable rendering of the current value, built from the\n * descriptions passed to {@link set}. Used by the filter picker in\n * `badge_summary` mode to show what each active filter is filtering on.\n */\n public get summary(): string {\n if (this.multi) {\n return Array.from(this._mvalue.values()).join(', ');\n } else {\n return this._value?.desc || '';\n }\n }\n\n /**\n * Contributes this filter's query parameter to `filter`, mutating it in\n * place. Called by {@link ModelListFilters.update} for every enabled filter.\n *\n * A multi-valued filter writes all its values joined by `,` under\n * {@link field}; a single-valued one writes its lone value. Nothing is\n * written when the filter has no value. Subclasses override this when they\n * need a different parameter name or encoding, as\n * {@link ModelListNumberFilter} does to append its comparison operator.\n */\n public updateFilter(filter: FilterData) {\n if (this.multi && this._mvalue.size > 0) {\n filter[this.field] = this.getMultiValue();\n } else if (!this.multi && this._value !== undefined && this._value !== null) {\n filter[this.field] = this.getValue();\n }\n }\n\n /**\n * Drops the filter's value (all of them when multi-valued), so that it stops\n * contributing a query parameter. Note that this does not disable the filter:\n * the widget stays on screen, simply empty.\n *\n * @param notify Whether to emit on the value stream. Pass `false` to update\n * the value silently, then call {@link ModelListFilters.update} yourself.\n */\n public clear(notify = true) {\n if (this.multi) {\n this._mvalue = new Map<string, string>();\n } else {\n this._value = null;\n }\n this.notify(notify);\n }\n\n /**\n * Sets `value` on the filter, adding it to the set when multi-valued or\n * replacing the current one otherwise. This is what widget components call\n * when the user picks something.\n *\n * @param value The raw value to send to the server.\n * @param desc Human-readable text for this value, surfaced through\n * {@link summary} and, for multi-valued filters, on the removable chips.\n * @param notify Whether to emit on the value stream.\n * @returns `true` when the value actually changed, `false` when it was\n * already set. Callers use this to avoid re-querying the list needlessly.\n */\n public set(value: FilterValue, desc: string, notify = true): boolean {\n if (this.multi) {\n return this.mset(value, desc, notify);\n }\n return this.sset(value, desc, notify);\n }\n\n /**\n * Removes `value` from the filter. On a multi-valued filter only that value\n * is dropped, which is what the chips' delete buttons call; on a\n * single-valued one the current value is cleared whatever `value` is.\n *\n * @param value The value to remove. Ignored by single-valued filters.\n * @param desc Unused; accepted so that both kinds share one signature.\n * @param notify Whether to emit on the value stream.\n * @returns `true` when something was actually removed.\n */\n public unset(value: FilterValue, desc: string, notify = true): boolean {\n if (this.multi) {\n return this.munset(value, desc, notify);\n }\n return this.sunset(value, desc, notify);\n }\n\n /**\n * Adds `value` if absent, removes it if present. Convenient for checkbox-like\n * widgets where the same gesture selects and deselects.\n *\n * @param value The value to toggle.\n * @param desc Human-readable text, used when the value is being added.\n * @param notify Whether to emit on the value stream.\n * @returns Always `true`.\n */\n public toggle(value: FilterValue, desc: string, notify = true): boolean {\n if (this.multi) {\n return this.mtoggle(value, desc, notify);\n }\n return this.stoggle(value, desc, notify);\n }\n\n /**\n * The current single value, stringified, as sent to the server. Only\n * meaningful for single-valued filters.\n */\n public getValue(): string | number {\n return String(this._value?.value);\n }\n\n /**\n * The current single value with its description, or `null` when unset. Used\n * by widgets that need to restore their state on init, such as the tree\n * filter rebuilding its hierarchy from a preselected node.\n */\n public get(): IDispEditChoice | null {\n return this._value;\n }\n\n private mtoggle(value: FilterValue, desc: string, notify = true): boolean {\n if (this._mvalue.has(String(value))) {\n this._mvalue.delete(String(value));\n } else {\n this._mvalue.set(String(value), desc);\n }\n this.notify(notify);\n return true;\n }\n\n private mset(value: FilterValue, desc: string, notify = true): boolean {\n if (!this._mvalue.has(String(value))) {\n this._mvalue.set(String(value), desc);\n this.notify(notify);\n return true;\n }\n return false;\n }\n\n private munset(value: FilterValue, desc: string, notify = true): boolean {\n if (this._mvalue.has(String(value))) {\n this._mvalue.delete(String(value));\n this.notify(notify);\n return true;\n }\n return false;\n }\n\n private stoggle(value: FilterValue, desc: string, notify = true): boolean {\n if (this._value !== null && this._value.value === value) {\n this._value = null;\n } else {\n this._value = { value, desc };\n }\n this.notify(notify);\n return true;\n }\n\n private sset(value: FilterValue, desc: string, notify = true): boolean {\n if (!(this._value !== null && this._value.value === value)) {\n this._value = { value, desc };\n this.notify(notify);\n return true;\n }\n return false;\n }\n\n private sunset(value: FilterValue, desc: string, notify = true): boolean {\n if (this._value !== null) {\n this._value = null;\n this.notify(notify);\n return true;\n }\n return false;\n }\n\n /** Joins the current multi values with `,` to form a single query parameter. */\n private getMultiValue(): string | number {\n return Array.from(this._mvalue.keys()).join(',');\n }\n\n /** Emits the current value on the stream matching {@link multi}, if `notify`. */\n private notify(notify = true) {\n if (notify) {\n if (this.multi) {\n this._mcurrent.next(\n Array.from(this._mvalue.entries()).map(([k, v]) => {\n return { desc: v, value: k };\n }),\n );\n } else {\n this._current.next(this._value);\n }\n }\n }\n}\n","import { FilterData } from '../../data/data-query';\nimport { Observable, ReplaySubject } from 'rxjs';\nimport { FiltersParams } from '../model-list.service';\nimport { ModelListFilter } from './model-list-filter';\nimport { ModelListFilterGroup } from './model-list-filter-group';\n\n/**\n * The filter set of a `ModelList`: it owns the individual filters, decides\n * which ones the user may pick and which are on by default, and aggregates\n * their values into the query sent to the server.\n *\n * You rarely build one directly — pass a `FiltersParams` object as the\n * `filters` option of a `ModelList` and it constructs this for you. Its\n * observables ({@link output}, {@link enabled}, {@link available},\n * {@link groups}) are what the `data-model-list-filters` and\n * `data-model-list-filters-select` components render from.\n *\n * ## Selecting filters\n *\n * The three name lists in `FiltersParams` all designate filters by\n * {@link ModelListFilter.name} (never by `field`, and never by group name):\n *\n * - `allowed` — the filters the user may enable from the picker. Empty or\n * omitted means all of them.\n * - `defaults` — the filters enabled from the start. Omitted means every\n * allowed filter. Listing a filter here also makes it allowed.\n * - `excluded` — filters forced off and hidden, applied last, so it overrides\n * both lists above.\n *\n * Filters declared inside a {@link ModelListFilterGroup} are flattened into the\n * same pool, so they are named individually in these lists just like ungrouped\n * ones.\n *\n * @example\n * ```typescript\n * const filters = new ModelListFilters({\n * filters: [\n * new ModelListTextFilter({ name: 'search', field: 'search', label: 'Search', help: 'Text to look for' }),\n * new ModelListSelectFilter<Category>({\n * name: 'category', field: 'category', label: 'Category', help: 'Pick a category',\n * choices: [{ value: 1, desc: 'First' }],\n * }),\n * ],\n * defaults: ['search'],\n * });\n * filters.output.subscribe((f) => console.log(f)); // e.g. { search: 'abc' }\n * ```\n */\nexport class ModelListFilters {\n private _enabled$ = new ReplaySubject<ModelListFilter[]>(1);\n private _filters: ModelListFilter[] = [];\n private _output$ = new ReplaySubject<FilterData>(1);\n private _available$ = new ReplaySubject<ModelListFilter[]>(1);\n private _groups$ = new ReplaySubject<ModelListFilterGroup[]>(1);\n\n /**\n * Flattens any groups, resolves the `allowed`/`defaults`/`excluded` lists\n * into per-filter flags, then emits an initial state. Passing no parameters\n * yields an empty, inert filter set.\n */\n constructor(params?: FiltersParams) {\n const fwgroups = Array.from(params?.filters || []);\n // Ungroup filters, keeping groups\n const tmp: ModelListFilter[] = [];\n const groups: ModelListFilterGroup[] = [];\n for (const f of fwgroups) {\n if (f instanceof ModelListFilter) {\n tmp.push(f);\n } else {\n groups.push(f);\n for (const ff of f.filters) {\n tmp.push(ff);\n ff.group = f;\n }\n }\n }\n\n // Prepare allowed filters (all filters if not set or empty)\n let allowed: string[] = [];\n if (params?.allowed === undefined || params?.allowed.length === 0) {\n for (const f of tmp) {\n allowed.push(f.name);\n }\n } else {\n allowed = params.allowed;\n }\n // Prepare excluded filters\n const excluded: string[] = params?.excluded || [];\n\n // Process default filters\n // Use all allowed filters if empty of not set\n const defaults: string[] = params?.defaults || allowed;\n\n // Prepare filters status\n // Set allowed\n for (const fe of allowed) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.allowed = true;\n }\n }\n }\n // Set defaults\n for (const fe of defaults) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.enabled = true;\n f.allowed = true;\n }\n }\n }\n // remove excluded\n for (const fe of excluded) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.enabled = false;\n f.allowed = false;\n }\n }\n }\n this._filters = tmp;\n this._groups = groups;\n this.update();\n }\n\n private _groups: ModelListFilterGroup[] = [];\n\n /**\n * The groups worth showing in the picker — those that are allowed and still\n * have a filter left to enable — sorted by\n * {@link ModelListFilterGroup.position}.\n */\n public get groups(): Observable<ModelListFilterGroup[]> {\n return this._groups$.asObservable();\n }\n\n private _enabled: ModelListFilter[] = [];\n\n /**\n * The currently active filters, i.e. the widgets to render. Re-emitted by\n * {@link update} whenever a filter is toggled.\n */\n public get enabled(): Observable<ModelListFilter[]> {\n return this._enabled$.asObservable();\n }\n\n private _available: ModelListFilter[] = [];\n\n /**\n * Every filter the user is allowed to enable, whether currently on or off.\n * This is the pool the filter picker offers.\n */\n public get available(): Observable<ModelListFilter[]> {\n return this._available$.asObservable();\n }\n\n /**\n * The aggregated query parameters contributed by all enabled filters. The\n * `ModelList` subscribes to this to re-run its query; emits on construction\n * and on every {@link update}.\n */\n public get output(): Observable<FilterData> {\n return this._output$.asObservable();\n }\n\n /**\n * Recomputes the whole filter state and emits on all four observables.\n *\n * Call this after mutating a filter's value or its `enabled` flag directly —\n * nothing else propagates such a change, and the filter widgets call it\n * themselves whenever the user interacts with them.\n */\n public update() {\n const filter: FilterData = {};\n for (const f of this._filters) {\n if (f.enabled) {\n f.updateFilter(filter);\n if (this._enabled.indexOf(f) === -1) {\n this._enabled.push(f);\n }\n } else {\n const i = this._enabled.indexOf(f);\n if (i !== -1) {\n this._enabled.splice(i, 1);\n }\n }\n if (f.allowed) {\n if (this._available.indexOf(f) === -1) {\n this._available.push(f);\n }\n } else {\n const i = this._available.indexOf(f);\n if (i !== -1) {\n this._available.splice(i, 1);\n }\n }\n }\n\n for (const g of this._groups) {\n g.enabled = false;\n g.allowed = false;\n for (const f of g.filters) {\n if (!f.enabled && f.allowed) {\n g.enabled = true;\n }\n if (f.allowed) {\n g.allowed = true;\n }\n }\n }\n\n this._output$.next(filter);\n this._enabled$.next(this._enabled);\n this._available$.next(this._available);\n this._groups$.next(this._groups.filter((g) => g.allowed && g.enabled).sort((a, b) => a.position - b.position));\n }\n}\n","import { inject, Injectable, InjectionToken } from '@angular/core';\nimport { HttpErrorResponse, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\nimport { AuthServiceBase } from './auth.service';\nimport { catchError, filter, switchMap, take, tap } from 'rxjs/operators';\nimport { BehaviorSubject, throwError } from 'rxjs';\nimport { IJwtRefreshResponseJson } from './jwt';\nimport { DATA_API_URL } from '../data/data-parameters';\n\n/**\n * The application's concrete {@link AuthServiceBase} subclass, as seen by the rest of\n * the library ({@link AuthInterceptor} and `ModelListService` both inject it).\n *\n * Wire it with **`useExisting`** against a class that is *also* provided in its own\n * right:\n *\n * ```ts\n * providers: [\n * AuthService,\n * { provide: DATA_AUTH_SERVICE, useExisting: AuthService },\n * ]\n * ```\n *\n * `useClass` here would construct a *second* auth service: components would hold one\n * instance while the interceptor and `ModelListService` hold another, so `logout$`\n * would never reach the list cache and stale data would survive a logout.\n */\n// The app that provides this token specialises all three parameters; naming\n// them here would force every consumer to cast on injection.\nexport const DATA_AUTH_SERVICE = new InjectionToken<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n AuthServiceBase<any, any, any>\n>('data.auth.service');\n\n/**\n * Extra origins, beyond `DATA_API_URL`, whose requests should carry the auth token.\n *\n * Optional; when absent only `DATA_API_URL` requests are authenticated. Entries are\n * matched with `String.startsWith`, so list full url prefixes and keep them narrow —\n * any request matching a prefix will have the bearer token attached to it.\n */\nexport const DATA_AUTH_URLS = new InjectionToken<string[]>('data.auth.urls');\n\n/**\n * Attaches the JWT access token to outgoing requests and transparently refreshes it\n * when the API rejects it.\n *\n * This is a **legacy class-based interceptor**, not a functional one, so it must be\n * registered through the `HTTP_INTERCEPTORS` multi-provider and `provideHttpClient`\n * must be given `withInterceptorsFromDi()`:\n *\n * ```ts\n * providers: [\n * provideHttpClient(withInterceptorsFromDi()),\n * { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },\n * ]\n * ```\n *\n * On a 401 it calls {@link AuthServiceBase.refresh} once and replays the failed\n * request with the new token; concurrent 401s wait for that single refresh rather than\n * each triggering their own.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class AuthInterceptor implements HttpInterceptor {\n private _isRefreshing = false;\n private _refreshTokenSubject = new BehaviorSubject<IJwtRefreshResponseJson | null>(null);\n\n private _auth = inject(DATA_AUTH_SERVICE);\n private _apiUrl = inject(DATA_API_URL);\n private _urls = inject(DATA_AUTH_URLS, { optional: true });\n\n /**\n * Adds `Authorization: Bearer <access token>` to a request, but only when **all** of\n * the following hold: a session is open (the auth service is not anonymous); the url\n * is neither the login nor the refresh endpoint (which must stay unauthenticated to\n * avoid a refresh loop); and the url starts with either `DATA_API_URL` or one of the\n * prefixes listed in {@link DATA_AUTH_URLS}.\n *\n * Requests failing any of these conditions are forwarded untouched — notably,\n * third-party urls never leak the token unless explicitly opted in via\n * {@link DATA_AUTH_URLS}. Authenticated requests additionally get 401 handling with\n * automatic token refresh and replay.\n */\n intercept(req: HttpRequest<unknown>, next: HttpHandler) {\n // If the user is anonymous, we don't add the token\n if (this._auth.isAnonymous) {\n return next.handle(req);\n }\n // If the request is refresh or login url, skip auth\n if (req.url.startsWith(this._auth.refreshUrl) || req.url.startsWith(this._auth.loginUrl)) {\n return next.handle(req);\n }\n // If the request is not for the api, and not for one of the urls specified in the\n // DATA_AUTH_URLS injection token, skip auth\n if (\n !req.url.startsWith(this._apiUrl) &&\n !(this._urls && this._urls.length > 0 && this._urls.some((url) => req.url.startsWith(url)))\n ) {\n return next.handle(req);\n }\n if (!this._auth.isAnonymous) {\n req = this._addToken(req, this._auth.accessToken as string);\n }\n return next.handle(req).pipe(\n catchError((error) => {\n console.log('Catched http error', error);\n if (error instanceof HttpErrorResponse && error.status === 401) {\n console.log('Passing to handle 401');\n return this._handle401Error(req, next);\n } else {\n console.log('throwing error');\n return throwError(error);\n }\n }),\n );\n }\n\n private _handle401Error(request: HttpRequest<unknown>, next: HttpHandler) {\n if (!this._isRefreshing) {\n this._isRefreshing = true;\n this._refreshTokenSubject.next(null);\n console.log('refreshing token');\n return this._auth.refresh().pipe(\n tap((token) => console.log('Refreshed token result', token)),\n switchMap((token) => {\n if (token === null) {\n this._isRefreshing = false;\n return throwError(\n () =>\n new HttpErrorResponse({\n error: 'Forbidden, please log in',\n status: 403,\n statusText: 'Warning',\n url: request.url,\n }),\n );\n } else {\n this._isRefreshing = false;\n this._refreshTokenSubject.next(token);\n return next.handle(this._addToken(request, token.access));\n }\n }),\n );\n } else {\n return this._refreshTokenSubject.pipe(\n filter((token) => token != null),\n take(1),\n switchMap((token) => next.handle(this._addToken(request, token.access))),\n );\n }\n }\n\n private _addToken(request: HttpRequest<unknown>, token: string) {\n const headers = request.headers.delete('Authorization').append('Authorization', `Bearer ${token}`);\n return request.clone({ headers });\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { combineLatest, NEVER, Observable, of, ReplaySubject, share, Subject, takeUntil } from 'rxjs';\nimport { DataModel } from '../data/data-model';\nimport { IQueryMeta, IQueryMetaNavParams, IQueryNav, Queryset } from '../data/data-query';\nimport { switchMap, tap, throttleTime } from 'rxjs/operators';\nimport { ModelListFields } from './model-list-fields/model-list-fields';\nimport { ModelListPaginator } from './model-list-paginator/model-list-paginator';\nimport { ModelListSorter } from './model-list-sorter/model-list-sorter';\nimport { ModelListFilters } from './model-list-filters/model-list-filters';\nimport { Collection } from '../data/data-collection';\nimport { ModelListFilter } from './model-list-filters/model-list-filter';\nimport { IFieldHeaderMessage } from './model-list-fields/model-list-field-header/messages';\nimport { AuthServiceBase } from '../auth/auth.service';\nimport { DATA_AUTH_SERVICE } from '../auth/auth-interceptor.service';\nimport { ModelListFilterGroup } from './model-list-filters/model-list-filter-group';\n\n/**\n * A synthetic column that does not exist on the model.\n *\n * Declared through {@link FieldsParams.custom}, it takes part in ordering and\n * shows up in the field selector exactly like a real field, but carries no\n * field manager and is never requested from the API. The typical use is an\n * \"actions\" column holding edit/delete buttons.\n */\nexport interface CustomField {\n /** Column key, used to address it in `defaults`/`allowed`/`excluded` and in templates. */\n name: string;\n /** Human readable column title. */\n label: string;\n /** Ordering weight, higher comes first. Use `-1` to keep it out of the default set. */\n priority?: number;\n}\n\n/**\n * A fixed query filter dict, force-ANDed into every request the list makes.\n *\n * This is scoping/context (the current tenant, the parent object of a nested\n * list), not user-facing filtering — see {@link ModelListParams.filter}.\n */\nexport type FilterDefaults = Record<string, string | number | undefined>;\n\n/**\n * Initial sort keys, as `field` / `+field` (ascending) or `-field` (descending).\n */\nexport type SorterDefaults = string[];\n\n/**\n * Which columns a list may show, which it shows by default, and in what order.\n *\n * The four lists are resolved once, in {@link ModelListFields}' constructor: the\n * model's own decorated fields are collected, `custom` entries are appended,\n * everything is ordered by `priority` (higher first), then `allowed`/`defaults`\n * select what the user can enable and what is enabled on load, and `excluded`\n * removes fields outright. Fields that end up neither allowed nor enabled are\n * dropped from the list entirely.\n */\nexport interface FieldsParams {\n /** Allowed fields, all model fields are allowed if empty */\n allowed?: string[];\n /**\n * Fields enabled on load, also fixing their left-to-right order.\n * Defaults to every field with a `priority >= 0` when `allowed` is empty.\n */\n defaults?: string[];\n /** Excluded fields */\n excluded?: string[];\n /** Extra non-model columns, e.g. an actions column. See {@link CustomField}. */\n custom?: CustomField[];\n}\n\n/**\n * Definitions of the user-facing filter widgets, and which of them are offered.\n *\n * `filters` holds the actual widget definitions; `allowed`/`defaults`/`excluded`\n * select among them by name, following the same resolution as\n * {@link FieldsParams}. Not to be confused with {@link ModelListParams.filter},\n * which is a fixed query dict rather than a set of widgets.\n */\nexport interface FiltersParams {\n /** Allowed filter names */\n allowed?: string[];\n /** Default active filter names */\n defaults?: string[];\n /** Excluded filter names */\n excluded?: string[];\n /** Filters definitions; groups are flattened, keeping the grouping for display. */\n filters?: (ModelListFilter | ModelListFilterGroup)[];\n}\n\n/**\n * @deprecated Unused by this module and mistyped for the job: it aliases the\n * string-valued nav params echoed back by the API, whereas\n * {@link ModelListParams.paginator} expects a numeric {@link IQueryNav}.\n */\nexport type PaginationParams = IQueryMetaNavParams;\n\n/**\n * A message pushed on {@link ModelList.messages$} to drive list UI from the\n * outside. Currently only header messages exist — see {@link IFieldHeaderMessage}.\n */\nexport type IModelListMessage = IFieldHeaderMessage;\n\n/**\n * Everything {@link ModelListService.get} needs to build a list: its columns,\n * its filters, its initial sort and page, plus the two subjects through which\n * the owning component drives and ends its lifecycle.\n *\n * **These are defaults, applied at creation time only.** When `get()` returns a\n * cached instance (see {@link keep}), every value here except `reload` and\n * `unsubscribe` is silently ignored — and those two only take effect if the\n * cached list is not currently started.\n *\n * @see {@link ModelListService.get} for the expected `ngOnInit` lifecycle.\n */\nexport interface ModelListParams {\n /** Column set and ordering. */\n fields?: FieldsParams;\n /**\n * Definitions of the user-facing filter widgets.\n * Not to be confused with {@link filter} — this is the widgets, that is the query.\n */\n filters?: FiltersParams;\n /**\n * A fixed filter dict force-ANDed into every query, or an observable of one.\n *\n * This is scoping/context — the parent object of a nested list, the current\n * tenant, a hardcoded `status` — not something the user sees or clears. It is\n * applied on top of the widget filters, so it always wins. Pass an observable\n * when the scope changes over the component's life; each emission re-runs the\n * query.\n */\n filter?: FilterDefaults | Observable<FilterDefaults>;\n /** Initial sort keys, e.g. `['-created', 'name']`. */\n sorter?: SorterDefaults;\n /** Initial page and page size. Defaults to page 1, 20 per page. */\n paginator?: IQueryNav;\n /**\n * Cache this list under {@link name} and reuse it on later `get()` calls.\n *\n * **Caching is keyed by `name` alone** — not by component, route or\n * collection — so any two lists sharing a name share one instance, and its\n * fields, filters, sort and page bleed between them. Names must be globally\n * unique across the whole app. Leave `false` (the default) for a private,\n * non-persisted list. See {@link ModelListService} for the full picture.\n */\n keep?: boolean;\n /**\n * A subject you own; `.next(true)` re-runs the query against the API with\n * `db=sync`, `.next()` re-runs it normally.\n *\n * Pass one whenever the list has row actions that mutate data, otherwise you\n * have no way to refresh it: if you omit it, `get()` creates its own subject\n * internally and you never get a reference to it.\n */\n reload?: Subject<void | boolean>;\n /**\n * A subject you own and must fire from `ngOnDestroy`; the library `takeUntil`s\n * it to tear the list's subscriptions down.\n *\n * The public API here is subject-based rather than `DestroyRef`-based, so this\n * cannot be inferred — omitting it means the query subscription lives as long\n * as the `ModelList` does.\n */\n unsubscribe?: Subject<void>;\n}\n\n/**\n * A live, self-refreshing list of models: the object a list component binds its\n * table, its paginator and its filter bar to.\n *\n * It owns a {@link Queryset} plus the four managers that feed it — {@link fields},\n * {@link filters}, {@link sorter}, {@link paginator} — and wires them together in\n * {@link start}, so that any change to any of them re-runs the query and pushes\n * new {@link results}. Components never build one directly: {@link ModelListService.get}\n * assembles and starts it.\n *\n * Read data through {@link results}/{@link meta}/{@link loading}/{@link full}\n * (shared, so subscribing several times does not multiply requests) and mutate\n * state through the managers.\n */\nexport class ModelList<T extends DataModel> {\n /** Cache key under which {@link ModelListService} may keep this list. */\n public name!: string;\n /** User-facing filter widgets and their current values. */\n public filters!: ModelListFilters;\n /** Current sort keys. */\n public sorter!: ModelListSorter;\n /** Current page and page size. */\n public paginator!: ModelListPaginator;\n /** The underlying query; reconfigured and re-run on every change. */\n public queryset!: Queryset<T>;\n /** Available/enabled columns and their order. */\n public fields!: ModelListFields<T>;\n /** Fire to re-run the query; `next(true)` forces a `db=sync` refresh. */\n public reload!: Subject<void | boolean>;\n /** Fired by the owning component to tear the list down. */\n public unsubscribe!: Subject<void>;\n /**\n * Out-of-band channel to drive list UI. Nothing in the library emits on it —\n * consumers push messages, and {@link ModelListFieldHeaderComponent} reacts.\n */\n public messages$ = new ReplaySubject<IModelListMessage>(1);\n /** True once {@link start} has run and the query subscription is alive. */\n public started = false;\n\n constructor(name: string, collection: Collection<T>) {\n this.name = name;\n this._collection = collection;\n }\n\n private _collection!: Collection<T>;\n\n /** The collection this list queries. */\n public get collection(): Collection<T> {\n return this._collection;\n }\n\n private _count: number | null = null;\n\n /**\n * Total number of matching rows, cached from the last `meta` received, or\n * `null` before the first one.\n *\n * It is the {@link meta} pipeline that refreshes this, so it stays `null`\n * unless something is subscribed to {@link meta} (or {@link full}).\n */\n public get count(): number | null {\n return this._count;\n }\n\n private _results?: Observable<T[]>;\n\n /**\n * The current page of models, re-emitted on every query.\n *\n * Created on first access and shared, so binding it from several places costs\n * one subscription to the queryset.\n */\n public get results(): Observable<T[]> {\n if (!this._results) {\n this._results = this.queryset.results.pipe(\n // tap(() => console.log('@solidev/data: modellist result')),\n share(),\n takeUntil(this.unsubscribe || NEVER),\n );\n }\n return this._results;\n }\n\n private _meta?: Observable<IQueryMeta>;\n\n /**\n * Pagination metadata (count, page, pages...) accompanying each response.\n * Subscribing to it is also what keeps {@link count} up to date.\n */\n public get meta(): Observable<IQueryMeta> {\n if (!this._meta) {\n this._meta = this.queryset.meta.pipe(\n // tap(() => console.log('@solidev/data: modellist meta')),\n tap((m) => (this._count = m.nav.count)),\n share(),\n takeUntil(this.unsubscribe || NEVER),\n );\n }\n return this._meta;\n }\n\n private _loading?: Observable<boolean>;\n\n /** True while a query is in flight; bind it to a spinner. */\n public get loading(): Observable<boolean> {\n if (!this._loading) {\n this._loading = this.queryset.loading.pipe(\n // tap(() => console.log('@solidev/data: modellist loading')),\n share(),\n takeUntil(this.unsubscribe || NEVER),\n );\n }\n return this._loading;\n }\n\n private _full?: Observable<[T[], boolean, IQueryMeta]>;\n\n /**\n * `[results, loading, meta]` combined, for templates that need all three\n * without nesting three async pipes.\n */\n public get full(): Observable<[T[], boolean, IQueryMeta]> {\n if (!this._full) {\n this._full = this.queryset.full.pipe(\n // tap(() => console.log('@solidev/data: modellist full')),\n share(),\n takeUntil(this.unsubscribe || NEVER),\n );\n }\n return this._full;\n }\n\n /**\n * Wire the managers to the queryset and fire the first query.\n *\n * Combines {@link reload}, the filter widgets' output, the fixed\n * {@link ModelListParams.filter}, the paginator, the sorter and the enabled\n * fields; any emission reconfigures the queryset and re-runs it, throttled to\n * one query per 200ms. A `reload.next(true)` seen since the last query makes\n * that query a `db=sync` one. Called by {@link ModelListService.get}; calling\n * it twice on the same list stacks a second subscription.\n */\n public start(params: ModelListParams) {\n let filter$: Observable<FilterDefaults>;\n let reloadFired = false;\n if (params.filter && !params.filter.subscribe) {\n filter$ = of(params.filter as FilterDefaults);\n } else if (params.filter && params.filter.subscribe) {\n filter$ = params.filter as Observable<FilterDefaults>;\n } else {\n filter$ = of({});\n }\n combineLatest([\n this.reload.pipe(tap((v) => (reloadFired = !!v))),\n this.filters.output,\n filter$,\n this.paginator.output,\n this.sorter.output,\n this.fields.output,\n ])\n .pipe(\n throttleTime(200),\n switchMap(([, filter, manualFilter, paginator, sorter, fields]) => {\n this.queryset\n .filter(filter)\n .filter(manualFilter || {}, true)\n .paginateBy(paginator.page_size)\n .setPage(paginator.page)\n .sort(...sorter)\n .setFields(fields);\n const dbSync = reloadFired;\n reloadFired = false;\n return this.queryset.get(true, dbSync);\n }),\n takeUntil(this.unsubscribe || NEVER),\n )\n .subscribe({\n next: (): void => {\n // console.log('@solidev/data: modellist:get results', this.name);\n },\n error: (error) => {\n console.error('@solidev/data: error while getting model list results : ', error);\n },\n complete: () => {\n // console.log('@solidev/data: modellist:completed', this.name);\n this.started = false;\n },\n });\n this.reload.next();\n this.started = true;\n }\n}\n\n/**\n * Builds {@link ModelList} instances — the entry point to this whole module.\n *\n * {@link get} composes a {@link Queryset} with a {@link ModelListFields},\n * {@link ModelListSorter}, {@link ModelListPaginator} and {@link ModelListFilters},\n * starts it, and hands back a live list. It can also cache lists so that a user\n * returning to a route finds their columns and filters as they left them.\n *\n * **Caching is keyed by name alone.** `_instances` is a `Map<string, ModelList>`\n * indexed by the `name` argument — not by component, route or collection. Two\n * `get()` calls passing the same name with `keep: true` therefore get *the same\n * list*, and its fields, filters, sort and page bleed across every route using\n * that name. Worse, when a cached instance is returned the `defaults` you passed\n * are silently ignored: different `fields` or `filters` for the same name have\n * no effect at all. Treat `name` as a globally unique identifier, and use\n * `keep: false` whenever you want a private, non-persisted list.\n *\n * All cached instances are unsubscribed and dropped when the user logs out, via\n * {@link AuthServiceBase.logout$}.\n *\n * **Recommended architecture:** do not call `get()` from each list component.\n * In a large consumer app this service is wrapped exactly once, in an abstract\n * base `@Directive` that every list component extends — around 150 of them —\n * which owns the `name`, `keep`, `reload` and `unsubscribe` plumbing and the\n * `ngOnInit` timing. Wrap it, then extend the wrapper.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class ModelListService {\n /** Kept lists, keyed by `name` only. See the class doc for what that implies. */\n private _instances = new Map<string, ModelList<DataModel>>();\n // Only `logout$` is used here, so the three type parameters are irrelevant.\n // See DATA_AUTH_SERVICE: the app specialises the three parameters.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _auth: AuthServiceBase<any, any, any> = inject(DATA_AUTH_SERVICE);\n\n constructor() {\n this._auth.logout$.pipe(takeUntilDestroyed()).subscribe(() => this.reset());\n }\n\n /**\n * Tear down and forget every cached list.\n *\n * Called automatically on logout, so that the next user does not inherit the\n * previous one's columns, filters and — through the queryset — their data.\n */\n public reset() {\n for (const i of this._instances.values()) {\n if (i.unsubscribe) {\n console.log('Clearing ', i);\n i.unsubscribe.next();\n }\n }\n this._instances.clear();\n }\n\n /**\n * Get a started {@link ModelList} for `collection`, either fresh or from cache.\n *\n * A fresh list is built whenever `name` is empty, `keep` is falsy, or nothing\n * is cached under `name`; otherwise the cached instance is returned as-is and\n * `defaults` is ignored — see the class doc, this is the main trap of this API.\n *\n * **Call this from `ngOnInit`, never from the constructor.** It consumes bound\n * inputs (`name`, `keep`, `filter`), which are not set yet at construction\n * time; called too early, `name` is undefined and you silently land in the\n * always-fresh branch, so `keep` never works.\n *\n * @param name globally unique list identifier, and the cache key when `keep` is set\n * @param collection the collection to query\n * @param defaults columns, filters, sort, page and lifecycle subjects\n *\n * @example\n * ```ts\n * export class ThingListComponent implements OnInit, OnDestroy {\n * private _lists = inject(ModelListService);\n * private _things = inject(ThingService);\n * public list!: ModelList<Thing>;\n * public reload = new Subject<void | boolean>();\n * public unsubscribe = new Subject<void>();\n *\n * public ngOnInit(): void {\n * this.list = this._lists.get('things', this._things, {\n * fields: { defaults: ['name', 'status'] },\n * sorter: ['-created'],\n * reload: this.reload,\n * unsubscribe: this.unsubscribe,\n * });\n * }\n *\n * public ngOnDestroy(): void {\n * this.unsubscribe.next();\n * }\n *\n * public onDeleted(): void {\n * this.reload.next(true);\n * }\n * }\n * ```\n */\n public get<T extends DataModel>(name: string, collection: Collection<T>, defaults: ModelListParams) {\n let ml: ModelList<T>;\n\n if (!name || !this._instances.has(name) || !defaults.keep) {\n ml = new ModelList<T>(name, collection);\n ml.queryset = collection.queryset();\n ml.fields = new ModelListFields(collection, defaults.fields);\n ml.sorter = new ModelListSorter(defaults.sorter || []);\n ml.paginator = new ModelListPaginator(defaults.paginator);\n ml.filters = new ModelListFilters(defaults.filters);\n if (defaults.keep) {\n this._instances.set(name, ml as unknown as ModelList<DataModel>);\n }\n } else {\n // The cache is keyed by name and holds lists of every model type.\n ml = this._instances.get(name)! as unknown as ModelList<T>;\n }\n if (!ml.started) {\n if (defaults.reload) {\n ml.reload = defaults.reload;\n } else {\n ml.reload = new Subject<void | boolean>();\n }\n if (defaults.unsubscribe) {\n ml.unsubscribe = defaults.unsubscribe;\n } else {\n ml.unsubscribe = new Subject<void>();\n }\n ml.start(defaults);\n }\n return ml;\n }\n}\n","import { Component, ElementRef, inject, input, OnInit, ViewChild } from '@angular/core';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelList } from '../../model-list.service';\nimport { CDK_DRAG_CONFIG, CdkDragDrop, DragDropModule } from '@angular/cdk/drag-drop';\nimport { AsyncPipe } from '@angular/common';\nimport { NgbOffcanvas, NgbOffcanvasModule } from '@ng-bootstrap/ng-bootstrap';\nimport { ModelListField } from '../model-list-fields';\nimport { CdkScrollableModule } from '@angular/cdk/scrolling';\n\nconst DragConfig = {\n dragStartThreshold: 5,\n pointerDirectionChangeThreshold: 10,\n zIndex: 10000,\n};\n\n@Component({\n selector: 'data-model-list-fields-selector',\n templateUrl: './model-list-fields-selector.component.html',\n styleUrls: ['./model-list-fields-selector.component.sass'],\n imports: [AsyncPipe, DragDropModule, CdkScrollableModule, NgbOffcanvasModule],\n providers: [{ provide: CDK_DRAG_CONFIG, useValue: DragConfig }],\n})\n/**\n * A button opening an offcanvas panel where the user picks which columns a list\n * shows and drags them into order.\n *\n * Drop it next to the table, bound to the same {@link ModelList}; it drives that\n * list's {@link ModelListFields} directly, so the table follows. Only columns\n * with `priority >= 0` are listed until the user asks for more.\n *\n * @example\n * ```html\n * <data-model-list-fields-selector [list]=\"list\"></data-model-list-fields-selector>\n * ```\n */\nexport class ModelListFieldsSelectorComponent<T extends DataModel> implements OnInit {\n /** The list whose columns are being edited. */\n public list = input.required<ModelList<T>>();\n @ViewChild('selector', { static: true })\n public ofctpl!: ElementRef<HTMLDivElement>;\n /** When true, also list the `priority < 0` columns normally kept out of the way. */\n public seeMore = false;\n private _ofc = inject(NgbOffcanvas);\n\n /** Fail fast if the list was not passed or has not been built by the service. */\n public ngOnInit() {\n if (!this.list() || !this.list().fields) {\n throw new Error('Missing list / fields');\n }\n }\n\n /** Open the field selector panel. */\n public open() {\n this._ofc.open(this.ofctpl);\n }\n\n /** Reorder the dropped column, placing it between its new neighbours. */\n drop($event: CdkDragDrop<T, T>) {\n let pos = $event.currentIndex * 10;\n if ($event.currentIndex > $event.previousIndex) {\n pos += 1;\n } else {\n pos -= 1;\n }\n this.list().fields.setPosition(String($event.item.data), pos);\n }\n\n /** Show or hide column `f`, depending on its current state. */\n public toggle(f: ModelListField) {\n if (f.enabled) {\n this.list().fields.disable(f.name);\n } else {\n this.list().fields.enable(f.name);\n }\n }\n}\n","<i\n class=\"bi bi-list-ul\"\n (click)=\"open()\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Choix des champs\"\n (keydown.enter)=\"open()\"\n (keydown.space)=\"$event.preventDefault(); open()\"\n></i>\n<ng-template #selector let-offcanvas>\n <div class=\"offcanvas-header\">\n <h4 class=\"offcanvas-title\">Choix des champs</h4>\n <button class=\"btn-close\" type=\"button\" aria-label=\"Close\" (click)=\"offcanvas.dismiss('x')\"></button>\n </div>\n <div class=\"offcanvas-body\" cdkScrollable>\n @if (list().fields.fields | async; as fields) {\n <div class=\"fields-list\" cdkDropList cdkDropListLockAxis=\"y\" (cdkDropListDropped)=\"drop($event)\">\n @for (f of fields; track f) {\n @if (seeMore || f.priority >= 0) {\n <div\n class=\"field-box\"\n cdkDrag\n (click)=\"toggle(f)\"\n (keydown.enter)=\"toggle(f)\"\n (keydown.space)=\"$event.preventDefault(); toggle(f)\"\n tabindex=\"0\"\n [cdkDragData]=\"f.name\"\n [class.enabled]=\"f.enabled\"\n [class.compact]=\"fields.length&gt;30\"\n [attr.arial-label]=\"f.label\"\n role=\"button\"\n >\n {{ f.label }}\n <span class=\"badge bg-info\">{{ f.priority }}</span>\n </div>\n }\n }\n </div>\n }\n <button class=\"btn btn-sm btn-link\" (click)=\"seeMore = !seeMore\">plus de champs</button>\n </div>\n</ng-template>\n","import { Component, input, signal } from '@angular/core';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelList } from '../../model-list.service';\n\n@Component({\n selector: 'data-model-list-sorter',\n templateUrl: './model-list-sorter.component.html',\n styleUrls: ['./model-list-sorter.component.sass'],\n imports: [],\n})\n/**\n * The pair of asc/desc arrows that sort a list on one field, plus a rank badge\n * and a clear button when several fields are sorted at once.\n *\n * Usually not placed by hand: {@link ModelListFieldHeaderComponent} renders it\n * for columns declared sortable. Use it directly to sort on a field that has no\n * column of its own. Any projected content is rendered after the arrows.\n *\n * Its displayed state is refreshed only by its own click handlers, so a sort\n * coming from anywhere else — the list's initial `sorter` defaults included — is\n * not reflected until the user touches it.\n */\nexport class ModelListSorterComponent<T extends DataModel = DataModel> {\n /**\n * ModelList reference.\n */\n public list = input.required<ModelList<T>>();\n /**\n * Sort field name.\n */\n public field = input.required<string>();\n /** Number of sorted fields, when this one is sorted; 0 otherwise. Drives the rank badge. */\n public getCount = signal<number>(0);\n /** This field's 1-based rank among the sort keys, -1 if unsorted. */\n public getOrder = signal<number>(0);\n /** This field is sorted ascending. */\n public isUp = signal<boolean>(false);\n /** This field is sorted descending. */\n public isDown = signal<boolean>(false);\n\n constructor() {\n // Dependencies are resolved with inject().\n }\n\n /** Sort ascending on this field. */\n public setUp(): void {\n this.list().sorter.set(this.field(), 'asc');\n this.update();\n }\n\n /** Re-read this field's sort state from the list's sorter into the signals. */\n public update() {\n this.getCount.set(this.list().sorter.get(this.field()) ? this.list().sorter.getAll().length : 0);\n this.getOrder.set(this.list().sorter.getOrder(this.field()));\n this.isDown.set(this.getIsDown());\n this.isUp.set(this.getIsUp());\n }\n\n /** Sort descending on this field. */\n public setDown(): void {\n this.list().sorter.set(this.field(), 'desc');\n this.update();\n }\n\n /** Stop sorting on this field, leaving the other sort keys in place. */\n public cancel(): void {\n this.list().sorter.unset(this.field());\n this.update();\n }\n\n private getIsDown(): boolean {\n const f = this.list().sorter.get(this.field());\n if (f) {\n return f.direction === 'desc';\n }\n return false;\n }\n\n private getIsUp(): boolean {\n const f = this.list().sorter.get(this.field());\n if (f) {\n return f.direction === 'asc';\n }\n return false;\n }\n}\n","<span class=\"dirs\">\n @if (getOrder() >= 0 || getCount() > 1) {\n <span\n (click)=\"cancel()\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Annuler le tri\"\n (keydown.enter)=\"cancel()\"\n (keydown.space)=\"$event.preventDefault(); cancel()\"\n >\n @if (getCount() > 1) {\n <span class=\"count\">{{ getOrder() }}</span>\n }\n <span class=\"bi bi-x\"></span>\n </span>\n }\n <span\n class=\"bi bi-sort-down-alt\"\n (click)=\"setUp()\"\n [class.active]=\"isUp()\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Trier par ordre croissant\"\n (keydown.enter)=\"setUp()\"\n (keydown.space)=\"$event.preventDefault(); setUp()\"\n ></span>\n <span\n class=\"bi bi-sort-down\"\n (click)=\"setDown()\"\n [class.active]=\"isDown()\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Trier par ordre décroissant\"\n (keydown.enter)=\"setDown()\"\n (keydown.space)=\"$event.preventDefault(); setDown()\"\n ></span>\n &nbsp;\n</span>\n<ng-content></ng-content>\n","import { Component, DestroyRef, inject, input, model, OnInit, signal, ViewChild } from '@angular/core';\nimport { ModelList } from '../../model-list.service';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelListField } from '../model-list-fields';\nimport { AsyncPipe, NgTemplateOutlet } from '@angular/common';\nimport { NgbDropdown, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';\nimport { ModelListSorterComponent } from '../../model-list-sorter/model-list-sorter/model-list-sorter.component';\nimport { filter } from 'rxjs/operators';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-model-list-field-header',\n templateUrl: './model-list-field-header.component.html',\n styleUrls: ['./model-list-field-header.component.sass'],\n imports: [AsyncPipe, NgTemplateOutlet, NgbDropdownModule, ModelListSorterComponent],\n})\n/**\n * A `<th>` for one column: its label, its sort control, and a menu to remove it\n * or insert another column after it.\n *\n * Put one per column in the table header, bound to the same {@link ModelList}.\n * The label comes from the field's metadata unless projected content is given.\n * It also listens on {@link ModelList.messages$} so the app can retune every\n * header at once — see {@link IFieldHeaderMessage}.\n *\n * @example\n * ```html\n * <th><data-model-list-field-header [list]=\"list\" field=\"name\" [sort]=\"true\">\n * </data-model-list-field-header></th>\n * ```\n */\nexport class ModelListFieldHeaderComponent<T extends DataModel> implements OnInit {\n /** The list this column belongs to. */\n public list = input.required<ModelList<T>>();\n /** Name of the column being headed. */\n public field = input.required<string>();\n /** Offer a sort control for this column. */\n public sort = input<boolean>(false);\n /** Field to sort on, when it differs from the displayed one (e.g. sort a label column on its id). */\n public sortField = input<string>();\n /** Where the column menu lives, or `'hide'` to drop it. */\n public menuMode = input<'hide' | 'side' | 'click'>('side');\n /** Where the sort control lives, or `'hide'` to drop it. */\n public sortMode = input<'hide' | 'side' | 'click'>('side');\n /** Two-way visibility flag, also settable from a header message. */\n public display = model<boolean>();\n\n @ViewChild('mnu', { static: false }) public mnu?: NgbDropdown;\n /** Effective menu mode: the message override if any, else {@link menuMode}. */\n public dispMenuMode = signal(this.menuMode());\n /** Effective sort mode: the message override if any, else {@link sortMode}. */\n public dispSortMode = signal(this.sortMode());\n private destroy$ = inject(DestroyRef);\n\n /** Subscribe to the list's header messages and apply them to the effective modes. */\n public ngOnInit() {\n this.list()\n .messages$.pipe(\n takeUntilDestroyed(this.destroy$),\n filter((m) => m.dest === 'header'),\n )\n .subscribe((m) => {\n this.dispMenuMode.set(m.menu && m.menu !== 'default' ? m.menu : this.menuMode());\n this.dispSortMode.set(m.sort && m.sort !== 'default' ? m.sort : this.sortMode());\n this.display.set(m.show !== undefined ? m.show : this.display());\n });\n }\n\n /** Remove this column from the table. */\n public disable() {\n this.list().fields.disable(this.field());\n }\n\n /** Insert column `f` immediately after this one and show it. */\n public enable(f: ModelListField) {\n this.list().fields.move(f.name, 'after', this.field());\n this.list().fields.enable(f.name);\n }\n}\n","<ng-template #label>\n <span #ref><ng-content></ng-content></span>\n @if (!ref.children.length) {\n <span>{{ list().fields.get(field())?.label || field() }}</span>\n }\n</ng-template>\n<div class=\"d-flex flex-row justify-content-between align-items-end slabel\">\n <div class=\"flex-grow-1\">\n @if (sort() && dispSortMode() === \"side\") {\n <data-model-list-sorter [list]=\"list()\" [field]=\"sortField() || field()\">\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n </data-model-list-sorter>\n }\n @if (!sort() || dispSortMode() === \"hide\") {\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n }\n </div>\n @if (dispMenuMode() === \"side\") {\n <div class=\"navicons d-flex flex-row\" [attr.aria-label]=\"'Gestion champs'\">\n <i\n class=\"bi bi-caret-left-fill\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Déplacer vers la gauche\"\n (click)=\"list().fields.move(field(), 'before')\"\n (keydown.enter)=\"list().fields.move(field(), 'before')\"\n (keydown.space)=\"$event.preventDefault(); list().fields.move(field(), 'before')\"\n ></i>\n <div ngbDropdown #mnu=\"ngbDropdown\" [container]=\"'body'\">\n <i class=\"bi bi-record\" ngbDropdownToggle aria-label=\"Ouvrir la boite de dialogue des champs\" role=\"button\"></i>\n <div ngbDropdownMenu>\n <button ngbDropdownItem (click)=\"disable()\">\n <i class=\"bi bi-trash me-2\"></i>\n Supprimer\n </button>\n <h6 class=\"dropdown-header\">Ajouter une colonne après</h6>\n @for (f of list().fields.fields | async; track f) {\n @if (f.allowed && !f.enabled) {\n <button ngbDropdownItem (click)=\"enable(f)\" [attr.aria-label]=\"f.label || f.name\">\n <i class=\"bi bi-plus-circle me-2\"></i>\n {{ f.label || f.name }}\n </button>\n }\n }\n </div>\n </div>\n <i\n class=\"bi bi-caret-right-fill\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Déplacer vers la droite\"\n (click)=\"list().fields.move(field(), 'after')\"\n (keydown.enter)=\"list().fields.move(field(), 'after')\"\n (keydown.space)=\"$event.preventDefault(); list().fields.move(field(), 'after')\"\n ></i>\n </div>\n }\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelList } from '../../model-list.service';\nimport { ModelListFilter } from '../model-list-filter';\nimport { AsyncPipe } from '@angular/common';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-model-list-filters-select',\n templateUrl: './model-list-filters-select.component.html',\n styleUrls: ['./model-list-filters-select.component.sass'],\n imports: [AsyncPipe, ReactiveFormsModule],\n})\n/**\n * The filter picker: lets the user turn a list's available filters on and off.\n *\n * It offers the filters the list marks as allowed, honouring their grouping,\n * and toggling one enables or disables its widget in\n * {@link ModelListFiltersComponent} — the two components are meant to sit side\n * by side.\n *\n * @example\n * ```html\n * <data-model-list-filters-select [list]=\"list\" mode=\"badge_summary\" />\n * <data-model-list-filters [list]=\"list\" />\n * ```\n */\nexport class ModelListFiltersSelectComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list whose filters can be toggled. Required. */\n public list = input.required<ModelList<T>>();\n /** CSS classes for the element wrapping the picker. */\n public containerClasses = input<string[] | string>('');\n /** CSS classes for an enabled filter's badge, in the badge modes. */\n public itemActiveClasses = input<string[] | string>('badge bg-success mx-1');\n /** CSS classes for a disabled filter's badge, in the badge modes. */\n public itemInactiveClasses = input<string[] | string>('badge bg-secondary mx-1');\n /**\n * How the picker presents itself: `badge` (the default) shows every available\n * filter as a clickable badge; `badge_summary` shows only the enabled ones,\n * each with its current value; `select` uses a dropdown instead, which suits\n * long filter lists.\n */\n public mode = input<'select' | 'badge' | 'badge_summary'>('badge');\n\n /** Backs the dropdown in `select` mode; unused in the badge modes. */\n public selectForm = new FormControl<ModelListFilter | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Flips a filter's enabled state and refreshes the list. Bound to the badges;\n * note that a filter disabled this way keeps its value.\n */\n public toggle(f: ModelListFilter) {\n f.enabled = !f.enabled;\n this.list().filters.update();\n }\n\n /**\n * In `select` mode only, wires the dropdown so that picking a filter toggles\n * it and resets the control, leaving the dropdown ready for the next pick.\n */\n public ngOnInit() {\n if (this.mode() === 'select') {\n this.selectForm.valueChanges.pipe(takeUntilDestroyed(this.destroy$)).subscribe((f) => {\n if (f) {\n f.enabled = !f.enabled;\n this.list().filters.update();\n this.selectForm.setValue(null, { emitEvent: false });\n }\n });\n }\n }\n}\n","@if (mode() === \"badge\") {\n @for (f of list().filters.available | async; track f) {\n <span\n (click)=\"toggle(f)\"\n [class]=\"containerClasses()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-pressed]=\"f.enabled\"\n [attr.aria-label]=\"f.label\"\n (keydown.enter)=\"toggle(f)\"\n (keydown.space)=\"$event.preventDefault(); toggle(f)\"\n >\n @if (f.enabled) {\n <span [class]=\"itemActiveClasses()\" [title]=\"f.desc\">\n <i class=\"bi bi-check2-square me-2\"></i>\n <span>{{ f.label }}</span>\n </span>\n }\n @if (!f.enabled) {\n <span [class]=\"itemInactiveClasses()\" [title]=\"f.desc\">\n <i class=\"bi bi-square me-2\"></i>\n <span>{{ f.label }}</span>\n </span>\n }\n </span>\n }\n}\n@if (mode() === \"badge_summary\") {\n @for (f of list().filters.available | async; track f) {\n <span\n (click)=\"toggle(f)\"\n [class]=\"containerClasses()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-pressed]=\"f.enabled\"\n [attr.aria-label]=\"f.label\"\n (keydown.enter)=\"toggle(f)\"\n (keydown.space)=\"$event.preventDefault(); toggle(f)\"\n >\n @if (f.enabled) {\n <span [class]=\"itemActiveClasses()\" [title]=\"f.desc\">\n <i class=\"bi bi-check2-square me-2\"></i>\n <span>{{ f.label }} : {{ f.summary || \"...\" }}</span>\n </span>\n }\n </span>\n }\n}\n@if (mode() === \"select\") {\n <select class=\"form-select\" [formControl]=\"selectForm\">\n <option [ngValue]=\"null\">-- Ajouter un filtre --</option>\n @for (f of list().filters.available | async; track f) {\n @if (!f.enabled && !f.group) {\n <option [ngValue]=\"f\">{{ f.label }}</option>\n }\n }\n @for (g of list().filters.groups | async; track g) {\n <optgroup [label]=\"g.label\">\n @for (f of g.filters; track f) {\n @if (!f.enabled && f.allowed) {\n <option [ngValue]=\"f\">{{ f.label }}</option>\n }\n }\n </optgroup>\n }\n </select>\n}\n","let _sequence = 0;\n\n/**\n * Returns a document-unique DOM id, as `<prefix>-<n>`.\n *\n * Used to wire a `<label [attr.for]>` to the control its template owns: the\n * widgets in this library are instantiated repeatedly on the same page, so a\n * hard-coded id would collide and silently break the association.\n *\n * The counter is module-level and starts at zero in each JS context, so a\n * server-rendered page and its client hydration agree as long as components are\n * created in the same order — which is what Angular does.\n *\n * @param prefix identifies the widget, e.g. `data-filter`\n */\nexport function uniqueId(prefix: string): string {\n _sequence += 1;\n return `${prefix}-${_sequence}`;\n}\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime } from 'rxjs';\nimport { ModelListTextFilter } from './model-list-text-filter';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\n\n@Component({\n selector: 'data-model-list-text-filter',\n templateUrl: './model-list-text-filter.component.html',\n styleUrls: ['./model-list-text-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListTextFilter}: a text input that pushes what the\n * user types into the filter, debounced by 250 ms so that a burst of keystrokes\n * triggers a single query. Instantiated by {@link ModelListFiltersComponent}\n * for filters of type `text`.\n */\nexport class ModelListTextFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the value changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListTextFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the text input. */\n public fc = new FormControl<string | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the input to the filter both ways: external value changes are\n * reflected back into the control without re-emitting, and the user's input\n * is debounced before updating the filter and refreshing the list.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n this.fc.setValue((val as IDispEditChoice).value as string | null, {\n emitEvent: false,\n });\n });\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (this.filter().set(val, val || '')) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input [attr.id]=\"inputId\" class=\"form-control\" type=\"text\" [formControl]=\"fc\" [placeholder]=\"filter().help\" />\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { fieldValues } from '../../../../data/field-values';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListAutocompleteFilter } from './model-list-autocomplete-filter';\nimport { TplFun } from '../../../../dispedit/fkselect/fkselect.component';\nimport { DataModel } from '../../../../data/data-model';\nimport { debounceTime, distinctUntilChanged, Observable } from 'rxjs';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\nimport { switchMap } from 'rxjs/operators';\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FilterData } from '../../../../data/data-query';\n\n@Component({\n selector: 'data-model-list-autocomplete-filter',\n templateUrl: './model-list-autocomplete-filter.component.html',\n styleUrls: ['./model-list-autocomplete-filter.component.sass'],\n imports: [NgbTypeaheadModule, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListAutocompleteFilter}: a typeahead input querying\n * the filter's collection as the user types. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `autocomplete`, and\n * subclassed by {@link ModelListAutocompleteMultiFilterComponent}.\n */\nexport class ModelListAutocompleteFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListAutocompleteFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the typeahead input; its value is the selected model, not a string. */\n public fc = new FormControl<T | null>(null);\n /** Bound search function handed to ngb-typeahead. */\n public search = this._search.bind(this);\n /** Bound formatter handed to ngb-typeahead for both the input and the results. */\n public display = this._display.bind(this);\n /**\n * Whether to clear the input after a selection. `false` here, since a single\n * selection should stay visible; the multi subclass overrides it to `true`.\n */\n protected _resetAfterSet = false;\n private _tpl!: TplFun<T>;\n private destroy$ = inject(DestroyRef);\n\n /**\n * Resolves how candidates are labelled, then stores each selected model's\n * `id` in the filter and refreshes the list.\n */\n public ngOnInit(): void {\n this._setDisplay();\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (val) {\n if (this.filter().set(val.id, this._display(val))) {\n this.list().filters.update();\n if (this._resetAfterSet) {\n this.fc.setValue(null);\n }\n }\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n\n /**\n * Keeps the highlighted result visible while arrowing through the dropdown.\n * Bound to the input's arrow-key events, and a no-op when the filter's\n * `scroll` option is off.\n */\n public scrollAction($event: Event) {\n if (!this.filter().scroll) {\n return;\n }\n const elem = ($event.currentTarget as HTMLElement).nextElementSibling?.getElementsByClassName('active')[0];\n elem?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n\n /**\n * Builds the labelling function from the filter's `display` option: a field\n * name becomes a property lookup, a function is used as-is. Without the\n * option, it falls back to the model's `_display`, then to `name`, `title`\n * and `id`.\n */\n private _setDisplay() {\n const display = this.filter().display;\n if (display) {\n if (typeof display === 'string') {\n this._tpl = (model: T) => String(fieldValues(model)[display]);\n } else if (typeof display === 'function') {\n this._tpl = display.bind(this);\n }\n } else {\n this._tpl = (model: T) => {\n const display = (model as { _display?: string })._display;\n if (display) {\n return display;\n } else {\n return String(fieldValues(model)['name'] ?? fieldValues(model)['title'] ?? fieldValues(model)['id']);\n }\n };\n }\n }\n\n /**\n * Labels one candidate for the dropdown, returning `''` for a null model so\n * that an empty input does not render `undefined`.\n */\n private _display(x: T | null | undefined): string {\n if (x) {\n return this._tpl(x);\n }\n return '';\n }\n\n /**\n * Queries the filter's queryset for candidates matching the typed text,\n * merging in the filter's static `filter` parameters and sending the term\n * under its `searchparam`. Debounced by 750 ms and deduplicated, to keep the\n * lookup endpoint from being hit on every keystroke.\n */\n private _search(text$: Observable<string>): Observable<T[]> {\n return text$.pipe(\n debounceTime(750),\n distinctUntilChanged(),\n switchMap((term) => {\n const f: FilterData = {};\n // Generate filter\n for (const k of Object.keys(this.filter().filter)) {\n if (this.filter().filter[k] !== null || this.filter().filter[k] !== undefined) {\n f[k] = this.filter().filter[k];\n }\n }\n // Add search param\n f[this.filter().searchparam] = term;\n // Update queryset filter\n this.filter().queryset?.filter(f);\n // Launch queryset\n return this.filter().queryset.get();\n }),\n takeUntilDestroyed(this.destroy$),\n );\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input\n [attr.id]=\"inputId\"\n class=\"form-control\"\n [formControl]=\"fc\"\n [ngbTypeahead]=\"search\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"display\"\n [resultFormatter]=\"display\"\n [placeholder]=\"filter().help\"\n (keyup.arrowDown)=\"scrollAction($event)\"\n (keyup.arrowUp)=\"scrollAction($event)\"\n #th=\"ngbTypeahead\"\n [class.tascroll]=\"filter().scroll\"\n />\n</div>\n","import { Component } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { ModelListAutocompleteFilterComponent } from '../model-list-autocomplete-filter/model-list-autocomplete-filter.component';\nimport { AsyncPipe } from '@angular/common';\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { FilterValue } from '../../../../data/data-query';\n\n@Component({\n selector: 'data-model-list-autocomplete-multi-filter',\n templateUrl: './model-list-autocomplete-multi-filter.component.html',\n styleUrls: ['./model-list-autocomplete-multi-filter.component.sass'],\n imports: [AsyncPipe, NgbTypeaheadModule, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListAutocompleteMultiFilter}: the same typeahead as\n * {@link ModelListAutocompleteFilterComponent}, extended to keep each pick as a\n * removable chip. Instantiated by {@link ModelListFiltersComponent} for filters\n * of type `autocompletemulti`.\n *\n * It inherits the search, labelling and binding logic wholesale, changing only\n * the reset behaviour and adding chip removal.\n */\nexport class ModelListAutocompleteMultiFilterComponent<\n T extends DataModel,\n> extends ModelListAutocompleteFilterComponent<T> {\n /** `true` here: the input clears after each pick, ready for the next one. */\n protected override _resetAfterSet = true;\n\n /**\n * Removes one selected value and refreshes the list. Bound to each chip's\n * delete icon.\n *\n * @param value The value to remove.\n * @param desc Its description, forwarded to the filter.\n */\n public unset(value: FilterValue, desc: string) {\n this.filter().unset(value, desc);\n this.list().filters.update();\n this.fc.setValue(null);\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input\n [attr.id]=\"inputId\"\n class=\"form-control\"\n [formControl]=\"fc\"\n [ngbTypeahead]=\"search\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"display\"\n [resultFormatter]=\"display\"\n [placeholder]=\"filter().help\"\n (keyup.arrowDown)=\"scrollAction($event)\"\n (keyup.arrowUp)=\"scrollAction($event)\"\n #th=\"ngbTypeahead\"\n [class.tascroll]=\"filter().scroll\"\n />\n <div class=\"enabled mt-1\">\n @for (e of filter().mcurrent$ | async; track e) {\n <div>\n <i\n class=\"bi bi-trash me-2\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer ' + e.desc\"\n (click)=\"unset(e.value, e.desc)\"\n (keydown.enter)=\"unset(e.value, e.desc)\"\n (keydown.space)=\"$event.preventDefault(); unset(e.value, e.desc)\"\n ></i>\n {{ e.desc }}\n </div>\n }\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListDatetimeFilter } from './model-list-datetime-filter';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\nimport { debounceTime } from 'rxjs';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\n@Component({\n selector: 'data-model-list-datetime-filter',\n templateUrl: './model-list-datetime-filter.component.html',\n styleUrls: ['./model-list-datetime-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListDatetimeFilter}: a native `datetime-local` input\n * bound to the filter. Instantiated by {@link ModelListFiltersComponent} for\n * filters of type `datetime`.\n */\nexport class ModelListDatetimeFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the date/time changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListDatetimeFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the date/time input. */\n public fc = new FormControl<string | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the input to the filter both ways, debouncing changes by 250 ms\n * before refreshing the list.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n this.fc.setValue((val as IDispEditChoice).value as string | null, {\n emitEvent: false,\n });\n });\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (this.filter().set(val, val ?? '')) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input\n [attr.id]=\"inputId\"\n class=\"form-control\"\n type=\"datetime-local\"\n [formControl]=\"fc\"\n [placeholder]=\"filter().help\"\n />\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListDatetimerangeFilter } from './model-list-datetimerange-filter';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { combineLatest } from 'rxjs';\n\n@Component({\n selector: 'data-model-list-datetime-range-filter',\n templateUrl: './model-list-datetime-range-filter.component.html',\n styleUrls: ['./model-list-datetime-range-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListDatetimerangeFilter}: two native `datetime-local`\n * inputs delimiting an interval. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `datetimerange`.\n */\nexport class ModelListDatetimeRangeFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when either bound changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListDatetimerangeFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the interval's start input. */\n public fc1 = new FormControl();\n /** Backs the interval's end input. */\n public fc2 = new FormControl();\n private destroy$ = inject(DestroyRef);\n\n /**\n * Joins both bounds with `--` into the filter's single value once they are\n * both filled in, and splits an incoming value back across the two inputs.\n */\n ngOnInit(): void {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n // If value is not an array, return\n if (val && !Array.isArray(val)) {\n const [v1, v2] = String(val.value).split('--');\n this.fc1.setValue(v1, { emitEvent: false });\n this.fc2.setValue(v2, { emitEvent: false });\n }\n });\n\n combineLatest([this.fc1.valueChanges, this.fc2.valueChanges])\n .pipe(takeUntilDestroyed(this.destroy$))\n .subscribe(([val1, val2]) => {\n if (val1 && val2) {\n if (this.filter().set(`${val1}--${val2}`, `${val1}--${val2}`)) {\n this.list().filters.update();\n }\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input\n [attr.id]=\"inputId\"\n class=\"form-control form-control-sm mb-1\"\n type=\"datetime-local\"\n [formControl]=\"fc1\"\n [placeholder]=\"filter().help\"\n />\n <input class=\"form-control form-control-sm\" type=\"datetime-local\" [formControl]=\"fc2\" [placeholder]=\"filter().help\" />\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { GetFlagsResult, ModelListFlagsFilter } from './model-list-flags-filter';\nimport { AsyncPipe } from '@angular/common';\nimport { DataModel } from '../../../../data/data-model';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime, Observable } from 'rxjs';\nimport { FilterValue } from '../../../../data/data-query';\n\n@Component({\n selector: 'data-model-list-flags-filter',\n templateUrl: './model-list-flags-filter.component.html',\n styleUrls: ['./model-list-flags-filter.component.sass'],\n imports: [AsyncPipe, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListFlagsFilter}: a dropdown of the flags fetched from\n * the collection, each pick becoming a removable chip. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `flags`.\n */\nexport class ModelListFlagsFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListFlagsFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the dropdown; reset to `null` after each pick. */\n public fc = new FormControl<string | null>(null);\n /** The available flags and their counts, fetched once on init. */\n public flags$!: Observable<GetFlagsResult>;\n private destroy$ = inject(DestroyRef);\n\n /**\n * Fetches the available flags through the filter's collection action, and\n * adds each picked flag to the filter before clearing the dropdown for the\n * next one.\n */\n public ngOnInit() {\n if (this.filter().collection && this.filter().action) {\n this.flags$ = this.filter().collection.action<GetFlagsResult>(null, 'GET', this.filter().action);\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (val !== null) {\n if (this.filter().set(val, val)) {\n this.list().filters.update();\n this.fc.setValue(null, { emitEvent: false });\n }\n }\n });\n }\n }\n\n /**\n * Removes one selected flag and refreshes the list. Bound to each chip's\n * delete icon.\n *\n * @param value The flag to remove.\n * @param desc Its description, forwarded to the filter.\n */\n public unset(value: FilterValue, desc: string) {\n this.fc.setValue(null);\n this.filter().unset(value, desc);\n this.list().filters.update();\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its values.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <select [attr.id]=\"inputId\" class=\"form-select\" [formControl]=\"fc\">\n <option [ngValue]=\"null\">-- {{ filter().help }} --</option>\n @for (c of flags$ | async; track c) {\n <option [ngValue]=\"c.flag\">{{ c.flag }} ({{ c.count }})</option>\n }\n </select>\n <div class=\"enabled mt-1\">\n @for (e of filter().mcurrent$ | async; track e) {\n <div>\n <i\n class=\"bi bi-trash me-2\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer ' + e.desc\"\n (click)=\"unset(e.value, e.desc)\"\n (keydown.enter)=\"unset(e.value, e.desc)\"\n (keydown.space)=\"$event.preventDefault(); unset(e.value, e.desc)\"\n ></i>\n {{ e.desc }}\n </div>\n }\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { GeoSearchResult, ModelListGeodistanceFilter } from './model-list-geodistance-filter';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { combineLatest, debounceTime, distinctUntilChanged, Observable } from 'rxjs';\nimport { filter, switchMap } from 'rxjs/operators';\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\n\n@Component({\n selector: 'data-model-list-geodistance-filter',\n templateUrl: './model-list-geodistance-filter.component.html',\n styleUrls: ['./model-list-geodistance-filter.component.sass'],\n imports: [NgbTypeaheadModule, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListGeodistanceFilter}: a distance dropdown next to a\n * typeahead that geocodes the typed text. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `geodistance`.\n *\n * The distance ladder (10 to 1000 km) is hardcoded in this component's\n * template, so it is not configurable through the filter.\n */\nexport class ModelListGeodistanceFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the place or distance changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListGeodistanceFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the place typeahead; its value is a {@link GeoSearchResult}. */\n public fc = new FormControl<GeoSearchResult | null>(null);\n /** Backs the distance dropdown; its value pairs an operator and a distance, e.g. `'lte,50'`. */\n public fd = new FormControl('');\n /** Bound search function handed to ngb-typeahead. */\n public search = this._search.bind(this);\n /** Bound formatter handed to ngb-typeahead for both the input and the results. */\n public display = this._display.bind(this);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Waits for both a place and a distance, then combines them into the filter's\n * single `<operator>,<distance>,<lng>,<lat>` value and refreshes the list.\n * Nothing is sent until both are set.\n */\n public ngOnInit(): void {\n const address = this.fc.valueChanges.pipe(\n debounceTime(250),\n filter((val) => !!val),\n );\n const distance = this.fd.valueChanges.pipe(filter((d) => !!d));\n combineLatest([address, distance])\n .pipe(takeUntilDestroyed(this.destroy$))\n .subscribe(([val, dist]) => {\n if (this.filter().set(`${String(dist)},${val.lng},${val.lat}`, val.label)) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n\n /** Labels a place in the dropdown, using the geocoder's own label. */\n private _display(x: GeoSearchResult): string {\n return `${x.label}`;\n }\n\n /**\n * Geocodes the typed text through the filter's `geolocator`. Debounced by\n * 750 ms and deduplicated, to limit calls to the geocoding service.\n */\n private _search(text$: Observable<string>): Observable<GeoSearchResult[]> {\n return text$.pipe(\n debounceTime(750),\n distinctUntilChanged(),\n switchMap((term) => this.filter().geolocator(term)),\n );\n }\n\n /**\n * Keeps the highlighted place visible while arrowing through the dropdown.\n * Bound to the input's arrow-key events, and a no-op when the filter's\n * `scroll` option is off.\n */\n public scrollAction($event: Event) {\n if (!this.filter().scroll) {\n return;\n }\n const elem = ($event.currentTarget as HTMLElement).nextElementSibling?.getElementsByClassName('active')[0];\n elem?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <div class=\"row g-1\">\n <div class=\"col-4\">\n <select [attr.id]=\"inputId\" class=\"form-select\" [formControl]=\"fd\">\n <option value=\"\">Distance</option>\n <option value=\"lte,10\">< 10 km</option>\n <option value=\"lte,20\">< 20 km</option>\n <option value=\"lte,30\">< 30 km</option>\n <option value=\"lte,50\">< 50 km</option>\n <option value=\"lte,80\">< 80 km</option>\n <option value=\"lte,100\">< 100 km</option>\n <option value=\"lte,150\">< 150 km</option>\n <option value=\"lte,200\">< 200 km</option>\n <option value=\"lte,250\">< 250 km</option>\n <option value=\"lte,300\">< 300 km</option>\n <option value=\"lte,500\">< 500 km</option>\n <option value=\"lte,1000\">< 1000 km</option>\n </select>\n </div>\n <div class=\"col-8\">\n <input\n class=\"form-control\"\n [formControl]=\"fc\"\n [ngbTypeahead]=\"search\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"display\"\n [resultFormatter]=\"display\"\n [placeholder]=\"filter().help\"\n (keyup.arrowDown)=\"scrollAction($event)\"\n (keyup.arrowUp)=\"scrollAction($event)\"\n #th=\"ngbTypeahead\"\n [class.tascroll]=\"filter().scroll\"\n />\n </div>\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListSelectFilter } from './model-list-select-filter';\nimport { combineLatest, debounceTime } from 'rxjs';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { DataModel } from '../../../../data/data-model';\nimport { AsyncPipe } from '@angular/common';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\n\n@Component({\n selector: 'data-model-list-select-filter',\n templateUrl: './model-list-select-filter.component.html',\n styleUrls: ['./model-list-select-filter.component.sass'],\n imports: [AsyncPipe, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListSelectFilter}: a dropdown of the filter's choices,\n * with an empty option that clears the filter. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `select`.\n */\nexport class ModelListSelectFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListSelectFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the dropdown; `null` means no selection. */\n public fc = new FormControl<string | number | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the dropdown to the filter both ways. Selections are matched against\n * the filter's choices to recover each value's description, which is why the\n * choices stream is combined in rather than merely rendered.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n this.fc.setValue(val ? ((val as IDispEditChoice).value as string | number | null) : null, { emitEvent: false });\n });\n\n combineLatest([this.filter().choices, this.fc.valueChanges.pipe(debounceTime(250))])\n .pipe(takeUntilDestroyed(this.destroy$))\n .subscribe(([choices, val]) => {\n if (val === null) {\n this.filter().clear();\n this.list().filters.update();\n } else {\n for (const ch of choices) {\n if (ch.value === val) {\n if (this.filter().set(ch.value, ch.desc)) {\n this.list().filters.update();\n break;\n }\n }\n }\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <select [attr.id]=\"inputId\" class=\"form-select\" [formControl]=\"fc\">\n <option [ngValue]=\"null\">-- {{ filter().help }} --</option>\n @for (c of filter().choices | async; track c) {\n <option [ngValue]=\"c.value\">{{ c.desc }}</option>\n }\n </select>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListSelectMultiFilter } from './model-list-select-multi-filter';\nimport { AsyncPipe } from '@angular/common';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { DataModel } from '../../../../data/data-model';\nimport { combineLatest, debounceTime } from 'rxjs';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\nimport { FilterValue } from '../../../../data/data-query';\n\n@Component({\n selector: 'data-model-list-select-multi-filter',\n templateUrl: './model-list-select-multi-filter.component.html',\n styleUrls: ['./model-list-select-multi-filter.component.sass'],\n imports: [AsyncPipe, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListSelectMultiFilter}: a dropdown that adds each pick\n * to a list of removable chips. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `selectmulti`.\n */\nexport class ModelListSelectMultiFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListSelectMultiFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the dropdown; reset to `null` after each pick so the same option can be re-picked. */\n public fc = new FormControl<IDispEditChoice | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Adds each picked choice to the filter, then clears the dropdown so it is\n * ready for the next selection. The choices stream is combined in to recover\n * the picked value's description for its chip.\n */\n public ngOnInit() {\n combineLatest([this.filter().choices, this.fc.valueChanges.pipe(debounceTime(250))])\n .pipe(takeUntilDestroyed(this.destroy$))\n .subscribe(([choices, val]) => {\n for (const ch of choices) {\n if (ch.value === val) {\n if (this.filter().set(ch.value, ch.desc)) {\n this.list().filters.update();\n break;\n }\n }\n }\n this.fc.setValue(null, { emitEvent: false });\n });\n }\n\n /**\n * Removes one selected value and refreshes the list. Bound to each chip's\n * delete icon.\n *\n * @param value The value to remove.\n * @param desc Its description, forwarded to the filter.\n */\n public unset(value: FilterValue, desc: string) {\n this.fc.setValue(null);\n this.filter().unset(value, desc);\n this.list().filters.update();\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its values.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <select [attr.id]=\"inputId\" class=\"form-select\" [formControl]=\"fc\">\n <option [ngValue]=\"null\">-- {{ filter().help }} --</option>\n @for (c of filter().choices | async; track c) {\n <option [ngValue]=\"c.value\">{{ c.desc }}</option>\n }\n </select>\n <div class=\"enabled mt-1\">\n @for (e of filter().mcurrent$ | async; track e) {\n <div>\n <i\n class=\"bi bi-trash me-2\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer ' + e.desc\"\n (click)=\"unset(e.value, e.desc)\"\n (keydown.enter)=\"unset(e.value, e.desc)\"\n (keydown.space)=\"$event.preventDefault(); unset(e.value, e.desc)\"\n ></i>\n {{ e.desc }}\n </div>\n }\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListTreeFilter } from './model-list-tree-filter';\nimport { DataModel } from '../../../../data/data-model';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime, firstValueFrom, Subject, Subscription } from 'rxjs';\nimport { FilterData, Queryset } from '../../../../data/data-query';\nimport { fieldValues } from '../../../../data/field-values';\nimport { TplFun } from '../../../../dispedit/fkselect/fkselect.component';\n\n/**\n * One dropdown in the tree filter's chain: the choices available at a given\n * depth, plus the node selected there. Internal to this component.\n */\nclass Level<T extends DataModel> {\n /** Zero-based depth, `0` being the roots. */\n public level: number;\n /** The tree this level belongs to, notified when the selection changes. */\n public tree: Tree<T>;\n /** The nodes offered at this depth, all children of the level above's selection. */\n public choices: { value: number; desc: string }[];\n /** Backs this level's dropdown. */\n public fc: FormControl;\n /** Id of the node selected here, if any. */\n public selected?: number;\n /** Subscription to the dropdown, torn down by {@link close}. */\n public subs: Subscription;\n\n constructor(tree: Tree<T>, level: number, choices: { value: number; desc: string }[]) {\n this.tree = tree;\n this.level = level;\n this.fc = new FormControl<string | null>('');\n this.choices = choices;\n this.subs = this.fc.valueChanges.subscribe((val) => {\n const selected = val ? Number(val) : undefined;\n if (this.selected !== selected) {\n this.selected = selected as number;\n this.tree.updated(this);\n }\n });\n }\n\n /** Unsubscribes from the dropdown; called when this level is discarded. */\n public close() {\n this.subs.unsubscribe();\n }\n}\n\n/**\n * The chain of dropdowns backing the tree filter: it fetches each level from\n * the server, drops the levels below whenever a selection changes, and reports\n * the current node. Internal to this component.\n */\nclass Tree<T extends DataModel> {\n /**\n * The levels currently displayed, from root to deepest.\n *\n * A signal because levels are appended asynchronously (after the queryset\n * resolves); under OnPush a plain array would leave the dropdowns unrendered.\n */\n readonly levels = signal<Level<T>[]>([]);\n /** Emits the selected node's id, or `null` once the selection is cleared. */\n changed: Subject<number | null> = new Subject<number | null>();\n\n /**\n * @param qs The queryset the nodes are fetched from.\n * @param maxLevel Depth cap, also bounding the walk back up to the root.\n * @param display Labels a node for its dropdown entry.\n * @param filter Extra query parameters merged into every level request.\n */\n constructor(\n private qs: Queryset<T>,\n private maxLevel: number,\n private display: string | TplFun<T> | undefined,\n private filter: FilterData,\n ) {}\n\n /**\n * Fetches the next level's nodes and appends it, if there is anything to\n * show. The first level asks for the roots (`parent=null`); deeper ones ask\n * for the children of the level above's selection, and are skipped when\n * nothing is selected there.\n *\n * @param fparent Overrides which parent's children to fetch, instead of using\n * the last level's selection.\n * @returns The new level, or `null` when the query came back empty — which is\n * how the chain stops at a leaf.\n */\n public async addLevel(fparent?: number): Promise<Level<T> | null> {\n let values: T[] = [];\n const levels = this.levels();\n if (levels.length === 0) {\n values = await firstValueFrom(this.qs.filter({ level: levels.length, parent: 'null', ...this.filter }).get());\n } else {\n const parent = fparent ? fparent : levels[levels.length - 1].selected;\n if (parent) {\n values = await firstValueFrom(\n this.qs\n .filter({\n level: levels.length,\n parent: levels[levels.length - 1].selected || 'null',\n ...this.filter,\n })\n .get(),\n );\n }\n }\n if (values.length > 0) {\n const level = new Level(this, levels.length, []);\n for (const v of values) {\n level.choices.push({ value: v.id, desc: this._label(v) });\n }\n this.levels.update((ls) => [...ls, level]);\n return level;\n }\n return null;\n }\n\n /**\n * Reacts to a selection at `level`: discards every deeper level, since they\n * described the previous branch, then appends the new level below and reports\n * the current node. Clearing a dropdown falls back to reporting the level\n * above's selection.\n */\n public updated(level: Level<T>) {\n const newLevels: Level<T>[] = [];\n for (const l of this.levels()) {\n if (l.level <= level.level) {\n newLevels.push(l);\n } else if (l.level > level.level) {\n l.close();\n }\n }\n this.levels.set(newLevels);\n void this.addLevel();\n if (level.selected) {\n this.changed.next(level.selected);\n } else {\n this.changed.next(this.levels()[level.level - 1]?.selected || null);\n }\n }\n\n /**\n * Rebuilds the whole chain of dropdowns around an already-selected node, so\n * that a filter restored from a saved state shows its full path rather than\n * an empty root dropdown.\n *\n * It walks from `value` up to the root by following each fetched record's\n * `parent` property, then replays the path downwards, preselecting each\n * level. Because it reads `parent` off the payload, the filter's `filter`\n * option must not trim that field away.\n *\n * @param value Id of the node to select.\n * @throws `Error('Max level error, could not find root')` when the walk\n * exceeds `maxLevel` without reaching a root, which signals either a cycle\n * or a `maxLevel` set too low.\n */\n /** Labels one node: `[display]` as a field name, as a function, or `id`. */\n private _label(node: T): string {\n if (typeof this.display === 'function') {\n return this.display(node);\n }\n if (typeof this.display === 'string') {\n return String(fieldValues(node)[this.display]);\n }\n return String(node.id);\n }\n\n public async prepare(value: number) {\n // console.log('prepare', value);\n const levels: T[] = [];\n let cur = (await firstValueFrom(this.qs.filter({ id: value, ...this.filter }).get()))[0];\n levels.push(cur);\n let nlev = 0;\n while (fieldValues(cur)['parent'] !== null) {\n cur = (\n await firstValueFrom(\n this.qs\n .filter({\n id: fieldValues(cur)['parent'] as number,\n ...this.filter,\n })\n .get(),\n )\n )[0];\n levels.push(cur);\n nlev++;\n if (nlev > this.maxLevel) {\n throw Error('Max level error, could not find root');\n }\n }\n for (let i = levels.length - 1; i >= 0; i--) {\n const lv = await this.addLevel();\n if (lv !== null) {\n lv.selected = levels[i].id;\n lv.fc.setValue(levels[i].id, { emitEvent: false });\n }\n }\n if (this.levels().length <= this.maxLevel) {\n await this.addLevel();\n }\n }\n\n /** Empty stub; does nothing. */\n public reset() {\n // Nothing to reset: the tree rebuilds itself from the filter value.\n }\n}\n\n@Component({\n selector: 'data-model-list-tree-filter',\n templateUrl: './model-list-tree-filter.component.html',\n styleUrls: ['./model-list-tree-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListTreeFilter}: a chain of dropdowns, one per level\n * of the hierarchy, each narrowing the one below. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `tree`.\n */\nexport class ModelListTreeFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListTreeFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** The dropdown chain rendered by the template; built on init. */\n public tree!: Tree<T>;\n private destroy$ = inject(DestroyRef);\n\n /**\n * Builds the dropdown chain, restoring the full path when the filter already\n * holds a value and otherwise starting at the roots, then pushes each\n * selection into the filter. Selections are debounced by 250 ms, since\n * changing one level cascades through the levels below it.\n */\n public async ngOnInit() {\n const filter = this.filter();\n this.tree = new Tree(filter.queryset, filter.maxLevel, filter.display, filter.filter);\n if (filter.get()) {\n await this.tree.prepare(filter.get()?.value as number);\n } else {\n await this.tree.addLevel();\n }\n\n this.tree.changed.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (val === null) {\n filter.clear();\n this.list().filters.update();\n } else {\n if (filter.set(val, '')) {\n this.list().filters.update();\n }\n }\n });\n\n // this.tree.changed.subscribe((selected) => {\n // console.log('tree changed', selected);\n // this.filter.set(selected, '');\n // });\n // if (this.filter.getValue()) {\n // console.log('filter value', this.filter.getValue());\n // await this.tree.prepare(this.filter.getValue() as number);\n // } else {\n // await this.tree.addLevel();\n // }\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n @for (l of tree.levels(); track l) {\n <div class=\"levelselect\">\n <select [attr.id]=\"$first ? inputId : null\" class=\"form-select form-select-sm\" [formControl]=\"l.fc\">\n <option value=\"\">{{ filter().help }}</option>\n @for (ch of l.choices; track ch) {\n <option [value]=\"ch.value\">{{ ch.desc }}</option>\n }\n </select>\n </div>\n }\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\nimport { debounceTime } from 'rxjs';\nimport { ModelListNumberFilter } from './model-list-number-filter';\nimport { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\n\n@Component({\n selector: 'data-model-list-number-filter',\n templateUrl: './model-list-number-filter.component.html',\n styleUrls: ['./model-list-number-filter.component.sass'],\n imports: [ReactiveFormsModule, NgbDropdownModule],\n})\n/**\n * Widget for {@link ModelListNumberFilter}: a number input alongside a dropdown\n * choosing the comparison operator. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `number`.\n */\nexport class ModelListNumberFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the value or operator changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListNumberFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the number input. */\n public fc = new FormControl<number | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the input to the filter both ways, debouncing the user's input by\n * 250 ms before updating the filter and refreshing the list.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n const value = (val as IDispEditChoice).value;\n this.fc.setValue(value === null ? null : Number(value), {\n emitEvent: false,\n });\n });\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (this.filter().set(val, val === null ? '' : String(val))) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n\n /**\n * Applies the comparison picked from the dropdown and re-runs the query,\n * since changing the operator changes the query parameter's name.\n *\n * @param eq The operator's suffix (`''`, `'_lt'`, ...), not its name.\n */\n selectOp(eq: string) {\n this.filter().setOperator(eq);\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <div class=\"bi bi-trash\"></div>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <div class=\"input-group\" ngbDropdown>\n <button class=\"btn btn-outline-secondary\" type=\"button\" ngbDropdownToggle>\n <span class=\"me-2\">{{ filter().operator.label }}</span>\n <div class=\"dropdown-menu\" ngbDropdownMenu>\n @for (op of filter().operations; track op) {\n <button\n ngbDropdownItem\n (click)=\"selectOp(op.operator)\"\n [class.text-primary]=\"op.operator === filter().operator.operator\"\n >\n {{ op.label }}\n </button>\n }\n </div>\n </button>\n <input [attr.id]=\"inputId\" class=\"form-control\" type=\"number\" [formControl]=\"fc\" [placeholder]=\"filter().help\" />\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListDateFilter } from './model-list-date-filter';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\nimport { debounceTime } from 'rxjs';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\n@Component({\n selector: 'data-model-list-date-filter',\n templateUrl: './model-list-date-filter.component.html',\n styleUrls: ['./model-list-date-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListDateFilter}: a native date input bound to the\n * filter. Instantiated by {@link ModelListFiltersComponent} for filters of type\n * `date`.\n */\nexport class ModelListDateFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the date changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListDateFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the date input. */\n public fc = new FormControl<string | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the input to the filter both ways, debouncing changes by 250 ms\n * before refreshing the list.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n this.fc.setValue((val as IDispEditChoice).value as string | null, {\n emitEvent: false,\n });\n });\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (this.filter().set(val, val ?? '')) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input [attr.id]=\"inputId\" class=\"form-control\" type=\"date\" [formControl]=\"fc\" [placeholder]=\"filter().help\" />\n</div>\n","import { Component, input } from '@angular/core';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelList } from '../../model-list.service';\nimport { AsyncPipe } from '@angular/common';\nimport { ModelListTextFilterComponent } from '../filters/model-list-text-filter/model-list-text-filter.component';\nimport { ModelListAutocompleteFilterComponent } from '../filters/model-list-autocomplete-filter/model-list-autocomplete-filter.component';\nimport { ModelListAutocompleteMultiFilterComponent } from '../filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.component';\nimport { ModelListDatetimeFilterComponent } from '../filters/model-list-datetime-filter/model-list-datetime-filter.component';\nimport { ModelListDatetimeRangeFilterComponent } from '../filters/model-list-datetimerange-filter/model-list-datetime-range-filter.component';\nimport { ModelListFlagsFilterComponent } from '../filters/model-list-flags-filter/model-list-flags-filter.component';\nimport { ModelListGeodistanceFilterComponent } from '../filters/model-list-geodistance-filter/model-list-geodistance-filter.component';\nimport { ModelListSelectFilterComponent } from '../filters/model-list-select-filter/model-list-select-filter.component';\nimport { ModelListSelectMultiFilterComponent } from '../filters/model-list-select-multi-filter/model-list-select-multi-filter.component';\nimport { ModelListTreeFilterComponent } from '../filters/model-list-tree-filter/model-list-tree-filter.component';\nimport { ModelListNumberFilterComponent } from '../filters/model-list-number-filter/model-list-number-filter.component';\nimport { ModelListDateFilterComponent } from '../filters/model-list-date-filter/model-list-date-filter.component';\n\n// SEE: register filter components and load them dynamically to allow user defined filters\n\n/**\n * Renders the widgets of a list's currently enabled filters.\n *\n * It subscribes to the list's enabled filters and, for each one, switches on\n * {@link ModelListFilter.type} to instantiate the matching filter component —\n * which is why every filter component is imported here. Pair it with\n * {@link ModelListFiltersSelectComponent}, which is how users turn filters on\n * and off; on its own this component only shows what is already enabled.\n *\n * @example\n * ```html\n * <data-model-list-filters [list]=\"list\" itemClasses=\"col-4\" />\n * ```\n */\n@Component({\n selector: 'data-model-list-filters',\n templateUrl: './model-list-filters.component.html',\n styleUrls: ['./model-list-filters.component.sass'],\n imports: [\n AsyncPipe,\n ModelListTextFilterComponent,\n ModelListNumberFilterComponent,\n ModelListAutocompleteFilterComponent,\n ModelListAutocompleteMultiFilterComponent,\n ModelListDatetimeFilterComponent,\n ModelListDateFilterComponent,\n ModelListDatetimeRangeFilterComponent,\n ModelListFlagsFilterComponent,\n ModelListGeodistanceFilterComponent,\n ModelListSelectFilterComponent,\n ModelListSelectMultiFilterComponent,\n ModelListTreeFilterComponent,\n ],\n})\nexport class ModelListFiltersComponent<T extends DataModel = DataModel> {\n /** The list whose filters are displayed. Required. */\n public list = input.required<ModelList<T>>();\n /** CSS classes for the element wrapping all the filter widgets. */\n public containerClasses = input<string[] | string>('');\n /**\n * CSS classes applied to each filter widget, typically grid columns. A filter\n * declaring `displayClasses` overrides this for itself.\n */\n public itemClasses = input<string[] | string>('');\n}\n","<div [class]=\"containerClasses()\">\n @for (f of list().filters.enabled | async; track f) {\n @switch (f.type) {\n @case (\"autocomplete\") {\n <data-model-list-autocomplete-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-autocomplete-filter>\n }\n @case (\"autocompletemulti\") {\n <data-model-list-autocomplete-multi-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-autocomplete-multi-filter>\n }\n @case (\"datetime\") {\n <data-model-list-datetime-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-datetime-filter>\n }\n @case (\"date\") {\n <data-model-list-date-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-date-filter>\n }\n @case (\"datetimerange\") {\n <data-model-list-datetime-range-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-datetime-range-filter>\n }\n @case (\"flags\") {\n <data-model-list-flags-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-flags-filter>\n }\n @case (\"geodistance\") {\n <data-model-list-geodistance-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-geodistance-filter>\n }\n @case (\"number\") {\n <data-model-list-number-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-number-filter>\n }\n @case (\"select\") {\n <data-model-list-select-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-select-filter>\n }\n @case (\"selectmulti\") {\n <data-model-list-select-multi-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-select-multi-filter>\n }\n @case (\"text\") {\n <data-model-list-text-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-text-filter>\n }\n @case (\"tree\") {\n <data-model-list-tree-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-tree-filter>\n }\n }\n }\n</div>\n","import { ModelListFilter } from './model-list-filter';\n\n/**\n * A named, presentation-only grouping of filters.\n *\n * A group exists purely to organise the UI: it gives a set of related filters a\n * shared heading and a position in the filter picker. It carries no filtering\n * logic of its own and never appears in a query.\n *\n * Groups are declared in the very same `filters` array as ungrouped filters —\n * the array is typed `(ModelListFilter | ModelListFilterGroup)[]` — and\n * {@link ModelListFilters} flattens them at construction, tagging each child\n * filter with its {@link ModelListFilter.group}. Because of that flattening,\n * the `allowed`, `defaults` and `excluded` lists always name **leaf filter\n * names**; naming a group there has no effect.\n *\n * {@link ModelListFilters.update} recomputes {@link allowed} and\n * {@link enabled} on every group from its children, so any value you pass for\n * those two is transient.\n *\n * @example\n * ```typescript\n * const filters = new ModelListFilters({\n * filters: [\n * new ModelListTextFilter({ name: 'search', field: 'search', label: 'Search', help: 'Text to look for' }),\n * new ModelListFilterGroup({\n * name: 'dates',\n * label: 'Dates',\n * position: 1,\n * filters: [\n * new ModelListDateFilter({ name: 'created', field: 'created', label: 'Created on', help: 'Creation date' }),\n * ],\n * }),\n * ],\n * // Leaf filter names, never 'dates'\n * defaults: ['search', 'created'],\n * });\n * ```\n */\nexport class ModelListFilterGroup {\n /** Group identity. Not usable in `allowed`/`defaults`/`excluded`, which take leaf filter names. */\n public name = '';\n /** Heading shown above the group in the filter picker. */\n public label = '';\n /** Longer description of the group's purpose. */\n public desc = '';\n /** Sort key: groups are displayed in ascending `position` order. */\n public position = 0;\n /**\n * Whether any child filter is allowed. Recomputed from the children by\n * {@link ModelListFilters.update}; only allowed groups are displayed.\n */\n public allowed = true;\n /**\n * Whether the group still has something to offer, i.e. at least one child\n * that is allowed but not yet enabled. Recomputed by\n * {@link ModelListFilters.update}; only such groups are displayed.\n */\n public enabled = true;\n /** The filters belonging to this group. */\n public filters: ModelListFilter[] = [];\n\n /**\n * Builds a group from a partial description; every field has a default.\n *\n * Note that `allowed: false` and `enabled: false` cannot be set through this\n * constructor — both options are read with `||`, so a `false` value falls\n * through to `true`. In practice this is harmless, since\n * {@link ModelListFilters.update} overwrites both from the group's children\n * before they are ever read.\n */\n constructor(params: Partial<ModelListFilterGroup>) {\n this.name = params.name || '';\n this.label = params.label || '';\n this.desc = params.desc || '';\n this.position = params.position || 0;\n this.allowed = params.allowed || true;\n this.enabled = params.enabled || true;\n this.filters = params.filters || [];\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { DataModel } from '../../../../data/data-model';\nimport { Collection } from '../../../../data/data-collection';\nimport { FilterData, Queryset } from '../../../../data/data-query';\nimport { TplFun } from '../../../../dispedit/fkselect/fkselect.component';\n\nexport interface ModelListAutocompleteParams<T extends DataModel> extends ModelListFilterParams {\n /**\n * The collection to look candidates up in. A queryset is derived from it, so\n * pass this unless you need a preconfigured {@link queryset}.\n */\n collection?: Collection<T>;\n /**\n * A ready-made queryset to search, used instead of deriving one from\n * {@link collection}. Takes precedence when both are given.\n */\n queryset?: Queryset<T>;\n /**\n * The query parameter carrying the user's search text to the lookup endpoint.\n * Defaults to `'search'`; override it when the endpoint expects another name.\n */\n searchparam?: string;\n /**\n * How to label a candidate: a model field name, or a function returning the\n * text. When omitted the filter falls back to the model's `_display`, then\n * `name`, `title` and `id`.\n */\n display?: string | TplFun<T>;\n /**\n * Extra query parameters merged into every lookup request, on top of the\n * search term. Beyond narrowing which records are proposed, this is the place\n * to trim the response: `filter: { fields: ['id', 'name'].join(',') }` asks\n * the server for just the columns the dropdown needs, which matters because\n * this endpoint is hit on every keystroke.\n */\n filter?: FilterData;\n /**\n * Whether arrow keys scroll the highlighted result into view. Defaults to\n * `true`; set `false` if the dropdown is short enough not to need it.\n */\n scroll?: boolean;\n}\n\n/**\n * Autocomplete filter: a typeahead input that searches a collection as the user\n * types (debounced) and sends the picked record's `id` under the filter's\n * `field`. The filter of choice for a foreign key onto a set too large for a\n * dropdown.\n *\n * The records to search come from either `collection` or `queryset`, and\n * passing neither throws. Use `filter` to both narrow the lookup and trim the\n * payload, and `display` to control how candidates are labelled.\n *\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par texte'` / `'Recherche par texte'`.\n *\n * @throws `'Missing related data (collection or queryset)'` (a string, not an\n * `Error`) when neither `collection` nor `queryset` is given.\n *\n * @example\n * ```typescript\n * new ModelListAutocompleteFilter<Category>({\n * name: 'category',\n * field: 'category',\n * label: 'Category',\n * help: 'Search for a category',\n * collection: categories,\n * display: 'name',\n * // Only fetch what the dropdown displays\n * filter: { fields: ['id', 'name'].join(',') },\n * });\n * ```\n */\nexport class ModelListAutocompleteFilter<T extends DataModel>\n extends ModelListFilter\n implements ModelListAutocompleteParams<T>\n{\n /** Field name or function labelling each candidate in the dropdown. */\n public display?: string | TplFun<T>;\n /** Query parameter carrying the search text; `'search'` unless overridden. */\n public searchparam!: string;\n /** The queryset searched on each keystroke, derived from `collection` if needed. */\n public queryset!: Queryset<T>;\n /** The collection the candidates come from, when one was given. */\n public collection?: Collection<T>;\n /** Extra query parameters merged into every lookup; `{}` when unset. */\n public filter!: FilterData;\n /** Whether arrow keys scroll the active result into view. */\n public scroll!: boolean;\n\n /**\n * Sets the filter type to `autocomplete` and resolves the queryset to search,\n * preferring an explicit `queryset` over one derived from `collection`.\n */\n constructor(params: ModelListAutocompleteParams<T>) {\n super(params);\n this.type = 'autocomplete';\n this.display = params.display;\n this.searchparam = params.searchparam ? params.searchparam : 'search';\n if (!params.collection && !params.queryset) {\n throw new Error('Missing related data (collection or queryset)');\n }\n this.collection = params.collection;\n if (params.collection && !params.queryset) {\n this.queryset = params.collection.queryset();\n } else {\n this.queryset = params.queryset as Queryset<T>;\n }\n this.scroll = params.scroll !== undefined ? params.scroll : true;\n this.filter = params.filter || {};\n\n if (this.label == '') {\n this.label = 'Sélectionnez par texte';\n }\n if (this.help == '') {\n this.help = 'Recherche par texte';\n }\n }\n}\n","import {\n ModelListAutocompleteFilter,\n ModelListAutocompleteParams,\n} from '../model-list-autocomplete-filter/model-list-autocomplete-filter';\nimport { DataModel } from '../../../../data/data-model';\n\n/**\n * Options for {@link ModelListAutocompleteMultiFilter}; identical to\n * {@link ModelListAutocompleteParams}, declared separately so the multi variant\n * can grow its own later.\n */\n// Kept as its own name so the multi variant can grow options later without a\n// breaking rename.\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ModelListAutocompleteMultiParams<T extends DataModel> extends ModelListAutocompleteParams<T> {}\n\n/**\n * Multi-valued autocomplete filter: same typeahead as\n * {@link ModelListAutocompleteFilter}, except each pick is kept as a removable\n * chip and the input resets for the next one. All picked ids are sent joined by\n * `,` in a single query parameter.\n *\n * Takes the same options and the same throw contract as its parent, including\n * the `filter: { fields: ... }` idiom worth applying here too.\n *\n * Always pass `label` and `help`: left empty they inherit the parent's French\n * `'Sélectionnez par texte'` / `'Recherche par texte'`.\n *\n * @throws `'Missing related data (collection or queryset)'` (a string, not an\n * `Error`) when neither `collection` nor `queryset` is given.\n *\n * @example\n * ```typescript\n * new ModelListAutocompleteMultiFilter<Category>({\n * name: 'categories',\n * field: 'categories',\n * label: 'Categories',\n * help: 'Search for categories',\n * collection: categories,\n * display: 'name',\n * filter: { fields: ['id', 'name'].join(',') },\n * });\n * ```\n */\nexport class ModelListAutocompleteMultiFilter<T extends DataModel> extends ModelListAutocompleteFilter<T> {\n /** Always `true`: this filter joins its values into one query parameter. */\n public override multi = true;\n\n /** Switches the filter type to `autocompletemulti`. */\n constructor(params: ModelListAutocompleteMultiParams<T>) {\n super(params);\n this.type = 'autocompletemulti';\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\n\n/**\n * Date and time filter: a single native `datetime-local` input whose value is\n * sent verbatim under the filter's `field`. Identical to\n * {@link ModelListDateFilter} but resolving to the minute.\n *\n * Takes no options beyond {@link ModelListFilterParams}, and ignores `default`.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par date/heure'` / `'Date/heure cible'`.\n *\n * @example\n * ```typescript\n * new ModelListDatetimeFilter({\n * name: 'created',\n * field: 'created',\n * label: 'Created at',\n * help: 'Creation date and time',\n * });\n * ```\n */\nexport class ModelListDatetimeFilter extends ModelListFilter {\n /** Sets the filter type to `datetime`. */\n constructor(params: ModelListFilterParams) {\n super(params);\n this.type = 'datetime';\n if (this.label == '') {\n this.label = 'Sélectionnez par date/heure';\n }\n if (this.help == '') {\n this.help = 'Date/heure cible';\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\n\n/**\n * Date filter: a single native date input whose value is sent verbatim under\n * the filter's `field`, in the browser's `yyyy-mm-dd` format. Matches on one\n * date; use {@link ModelListDatetimerangeFilter} for an interval.\n *\n * Takes no options beyond {@link ModelListFilterParams}, and ignores `default`.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par date'` / `'Date cible'`.\n *\n * @example\n * ```typescript\n * new ModelListDateFilter({\n * name: 'created',\n * field: 'created',\n * label: 'Created on',\n * help: 'Creation date',\n * });\n * ```\n */\nexport class ModelListDateFilter extends ModelListFilter {\n /** Sets the filter type to `date`. */\n constructor(params: ModelListFilterParams) {\n super(params);\n this.type = 'date';\n if (this.label == '') {\n this.label = 'Sélectionnez par date';\n }\n if (this.help == '') {\n this.help = 'Date cible';\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\n\n/**\n * Date/time interval filter: two native `datetime-local` inputs, sent as a\n * single query parameter holding both bounds joined by `--`, for example\n * `2026-01-01T00:00--2026-01-31T23:59`. The backend must parse that encoding.\n *\n * Nothing is sent until **both** bounds are filled in.\n *\n * Takes no options beyond {@link ModelListFilterParams}, and ignores `default`.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par intervalle de date/heure'` / `'Date/heure'`.\n *\n * @example\n * ```typescript\n * new ModelListDatetimerangeFilter({\n * name: 'created',\n * field: 'created',\n * label: 'Created between',\n * help: 'Start and end date',\n * });\n * ```\n */\nexport class ModelListDatetimerangeFilter extends ModelListFilter {\n /** Sets the filter type to `datetimerange`. */\n constructor(params: ModelListFilterParams) {\n super(params);\n this.type = 'datetimerange';\n if (this.label == '') {\n this.label = 'Sélectionnez par intervalle de date/heure';\n }\n if (this.help == '') {\n this.help = 'Date/heure';\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { Collection } from '../../../../data/data-collection';\nimport { DataModel } from '../../../../data/data-model';\n\nexport interface ModelListFlagsFilterParams<T extends DataModel> extends ModelListFilterParams {\n /**\n * The collection exposing the flags action. By convention this is the list's\n * own collection, so that the flags offered are those of the very records\n * being filtered. Required.\n */\n collection?: Collection<T>;\n /**\n * The collection action returning the available flags. Defaults to\n * `'get_flags'`; override it when the endpoint names it differently.\n */\n action?: string;\n}\n\n/**\n * The shape returned by the flags action: each available flag with how many\n * records carry it. The count is informational and shown next to the flag.\n */\nexport type GetFlagsResult = { flag: string; count: number }[];\n\n/**\n * Flags filter: a dropdown of the flags actually present in the data, picked\n * ones being kept as removable chips. Always multi-valued, so the selected\n * flags are sent joined by `,` in a single query parameter.\n *\n * The flag list is not declared here but fetched at runtime by calling a `GET`\n * action on `collection` — `'get_flags'` unless overridden — which must return\n * a {@link GetFlagsResult}. Pass the list's own collection so the offered flags\n * match the records being filtered.\n *\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par étiquette'` / `\"Nom de l'étiquette\"`.\n *\n * @throws `'Missing collection for flags filter'` (a string, not an `Error`)\n * when `collection` is not given.\n *\n * @example\n * ```typescript\n * new ModelListFlagsFilter<Thing>({\n * name: 'flags',\n * field: 'flags',\n * label: 'Flags',\n * help: 'Pick one or more flags',\n * // The list's own collection\n * collection: things,\n * });\n * ```\n */\nexport class ModelListFlagsFilter<T extends DataModel> extends ModelListFilter {\n /** The collection whose flags action feeds the dropdown. */\n public collection!: Collection<T>;\n /** Name of the `GET` collection action returning the available flags. */\n public action = 'get_flags';\n /** Always `true`: selected flags are joined into one query parameter. */\n public override multi = true;\n\n /**\n * Sets the filter type to `flags` and stores the collection and action used\n * to fetch the flag list.\n */\n constructor(params: ModelListFlagsFilterParams<T>) {\n super(params);\n this.type = 'flags';\n if (this.label == '') {\n this.label = 'Sélectionnez par étiquette';\n }\n if (this.help == '') {\n this.help = \"Nom de l'étiquette\";\n }\n if (!params.collection) {\n throw new Error('Missing collection for flags filter');\n }\n this.collection = params.collection;\n if (params.action) {\n this.action = params.action;\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { Observable } from 'rxjs';\n\n/**\n * One place proposed by a {@link ModelListGeodistanceFilterParams.geolocator},\n * normalised across geocoding services.\n */\nexport interface GeoSearchResult {\n /** Relevance as reported by the geocoder. Not used for sorting by the filter. */\n score: number;\n /** Human-readable place name, shown in the dropdown and kept as the value's description. */\n label: string;\n /** Latitude, in decimal degrees. */\n lat: number;\n /** Longitude, in decimal degrees. */\n lng: number;\n}\n\nexport interface ModelListGeodistanceFilterParams extends ModelListFilterParams {\n /**\n * Turns the user's text into candidate places. This is the filter's geocoding\n * back end and is required; {@link BanAdapter} is the implementation shipped\n * with the library, wired as `geolocator: (pos) => adapter.search(pos)`.\n */\n geolocator: (pos: string) => Observable<GeoSearchResult[]>;\n /** Declared but never read anywhere in the library; setting it has no effect. */\n geomap?: (pos: [number, number], dist: number) => string;\n /**\n * Whether arrow keys scroll the highlighted place into view. Defaults to\n * `true`.\n */\n scroll?: boolean;\n}\n\n/**\n * Geographic distance filter: a distance dropdown next to a typeahead that\n * geocodes the text the user types, matching records within the chosen radius\n * of the chosen place.\n *\n * ## Value encoding\n *\n * Both inputs are sent as one query parameter combining the distance option and\n * the resolved coordinates, comma-separated: `lte,50,2.3522,48.8566`, i.e.\n * `<operator>,<distance>,<lng>,<lat>` — note longitude first. The operator is\n * always `lte` and the distances are a fixed ladder from 10 to 1000, expressed\n * in kilometres and hardcoded in the component's template; neither is\n * configurable. The backend must parse this encoding. Nothing is sent until\n * both a distance and a place have been chosen.\n *\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `\"Par distance autour d'un point\"` / `'Ville & distance'`. The distance\n * dropdown's own options are French and cannot be overridden.\n *\n * @example\n * ```typescript\n * const adapter = new BanAdapter(http, 'https://api-adresse.data.gouv.fr/search/');\n * new ModelListGeodistanceFilter({\n * name: 'around',\n * field: 'around',\n * label: 'Distance',\n * help: 'Town & distance',\n * geolocator: (pos) => adapter.search(pos),\n * });\n * ```\n */\nexport class ModelListGeodistanceFilter extends ModelListFilter implements ModelListGeodistanceFilterParams {\n /** The geocoder resolving typed text into places. */\n public geolocator: (pos: string) => Observable<GeoSearchResult[]>;\n /** Whether arrow keys scroll the active result into view. */\n public scroll!: boolean;\n\n /** Sets the filter type to `geodistance` and stores the geolocator. */\n constructor(params: ModelListGeodistanceFilterParams) {\n super(params);\n\n this.type = 'geodistance';\n this.geolocator = params.geolocator;\n if (this.label == '') {\n this.label = \"Par distance autour d'un point\";\n }\n if (this.help == '') {\n this.help = 'Ville & distance';\n }\n this.scroll = params.scroll !== undefined ? params.scroll : true;\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { FilterData } from '../../../../data/data-query';\n\n/** One comparison operator offered by {@link ModelListNumberFilter}. */\ninterface OperationDescriptor {\n /** Short identifier, as used in the filter's `operations` option. */\n name: string;\n /** Label shown in the operator dropdown. */\n label: string;\n /** Suffix appended to the filter's `field` to build the query parameter. */\n operator: string;\n}\n\n/**\n * The comparison operators a {@link ModelListNumberFilter} can offer, in\n * display order. Each one queries `<field><operator>`, so `lt` on a `price`\n * field sends `price_lt`; equality sends the bare `price`. The backend must\n * understand these suffixes.\n */\nexport const ModelListNumberOperations: OperationDescriptor[] = [\n { name: 'eq', label: '= (égal)', operator: '' },\n { name: 'lt', label: '< (inférieur)', operator: '_lt' },\n { name: 'gt', label: '> (supérieur)', operator: '_gt' },\n { name: 'lte', label: '<= (inférieur ou égal)', operator: '_lte' },\n { name: 'gte', label: '>= (supérieur ou égal)', operator: '_gte' },\n];\n\nexport interface ModelListNumberFilterParams extends ModelListFilterParams {\n /**\n * Restricts the operator dropdown to these operators, by `name`, in the order\n * given; the first becomes the initial operator. Names that match nothing in\n * {@link ModelListNumberOperations} are ignored, and an empty or fully\n * unmatched list leaves all operators available.\n */\n operations?: string[];\n}\n\n/**\n * Numeric filter: a number input paired with a comparison operator dropdown\n * (`=`, `<`, `>`, `<=`, `>=`). Unlike other filters it does not query `field`\n * directly — it appends the operator's suffix, sending `price_lt` for \"less\n * than\" on a `price` field, so the backend must support those suffixed\n * parameters.\n *\n * Use `operations` to narrow the dropdown when only some comparisons make sense.\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Recherche par valeur'` / `'Valeur à rechercher'`. Note that the operator\n * labels themselves are French and cannot be overridden.\n *\n * @example\n * ```typescript\n * new ModelListNumberFilter({\n * name: 'price',\n * field: 'price',\n * label: 'Price',\n * help: 'Amount to compare',\n * operations: ['lte', 'gte'],\n * });\n * ```\n */\nexport class ModelListNumberFilter extends ModelListFilter {\n /** The comparison currently selected; drives the query parameter's suffix. */\n public operator = ModelListNumberOperations[0];\n /** The operators offered in the dropdown, narrowed by the `operations` option. */\n public operations = ModelListNumberOperations;\n\n /**\n * Sets the filter type to `number` and, when `operations` is given, restricts\n * the operator list to it and selects the first as the initial operator.\n */\n constructor(params: ModelListNumberFilterParams) {\n super(params);\n this.type = 'number';\n if (this.label == '') {\n this.label = 'Recherche par valeur';\n }\n if (this.help == '') {\n this.help = 'Valeur à rechercher';\n }\n const ops: OperationDescriptor[] = [];\n if (params.operations && params.operations.length > 0) {\n for (const op of params.operations) {\n for (const dop of this.operations) {\n if (op === dop.name) {\n ops.push(dop);\n }\n }\n }\n if (ops.length > 0) {\n this.operations = ops;\n this.operator = ops[0];\n }\n }\n }\n\n /**\n * Selects the comparison to apply, matching on the operator's **suffix**\n * (`'_lt'`, `''` for equality, ...) rather than its `name`. Unknown suffixes\n * leave the current operator untouched. Call\n * {@link ModelListFilters.update} afterwards to re-run the query.\n */\n public setOperator(op: string) {\n for (const o of this.operations) {\n if (op === o.operator) {\n this.operator = o;\n }\n }\n }\n\n /**\n * Writes the value under `field` suffixed with the current operator, so the\n * chosen comparison reaches the server as part of the parameter name.\n */\n public override updateFilter(filter: FilterData): void {\n if (this._value !== undefined && this._value !== null) {\n filter[`${this.field}${this.operator.operator}`] = this.getValue();\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { FilterValue } from '../../../../data/data-query';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\nimport { DataModel } from '../../../../data/data-model';\nimport { DataModelType } from '../../../../data/data-collection';\nimport { isObservable, Observable, of } from 'rxjs';\n\nexport interface ModelListSelectFilterParams<T extends DataModel> extends ModelListFilterParams {\n /**\n * The options to offer, either as a plain array or as an `Observable` for\n * choices resolved asynchronously. Required unless {@link model} is given.\n */\n choices?: IDispEditChoice[] | Observable<IDispEditChoice[]>;\n /**\n * A model class to read the choices from, instead of listing them by hand.\n * The filter instantiates it and reflects the `choices` declared on the\n * field's metadata, which keeps the dropdown in sync with the model.\n */\n model?: DataModelType<T>;\n /**\n * The model field to read the choices from, when it differs from\n * {@link ModelListFilterParams.field}. Only meaningful together with\n * {@link model}; defaults to `field`.\n */\n mfield?: string;\n}\n\n/**\n * Single-choice filter: a dropdown sending the selected option's value under\n * the filter's `field`. Clearing the dropdown clears the filter.\n *\n * The options come from either of two sources, and passing neither throws:\n *\n * - `choices` — an explicit array, or an `Observable` when they are loaded\n * asynchronously.\n * - `model` (plus optional `mfield`) — reflects the choices off the model\n * field's metadata, so a list of choices declared on the model is not\n * duplicated here. Throws if that field declares none.\n *\n * `default` is applied at construction on this class only; the multi variant\n * handles its own.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez un élément'` / `'Choix par liste déroulante'`.\n *\n * @throws `'Missing choices for select filter'` (a string, not an `Error`) when\n * neither `choices` nor `model` is given.\n * @throws `'No choices found for model/field'` (a string, not an `Error`) when\n * `model` is used but the target field declares no choices.\n *\n * @example\n * ```typescript\n * // Explicit choices\n * new ModelListSelectFilter<Thing>({\n * name: 'status',\n * field: 'status',\n * label: 'Status',\n * help: 'Pick a status',\n * choices: [{ value: 'ok', desc: 'Valid' }, { value: 'ko', desc: 'Invalid' }],\n * });\n *\n * // Reflected off the model field's metadata\n * new ModelListSelectFilter<Thing>({\n * name: 'status', field: 'status', label: 'Status', help: 'Pick a status',\n * model: Thing,\n * });\n * ```\n */\nexport class ModelListSelectFilter<T extends DataModel>\n extends ModelListFilter\n implements ModelListSelectFilterParams<T>\n{\n /**\n * The options offered by the dropdown, always an `Observable` whatever the\n * source they were built from.\n */\n public choices!: Observable<IDispEditChoice[]>;\n /** Declared to satisfy the params interface; the constructor never assigns it. */\n public model?: DataModelType<T>;\n /** Declared to satisfy the params interface; the constructor never assigns it. */\n public mfield?: string;\n\n /**\n * Resolves the choices from `choices` or `model`, sets the filter type to\n * `select`, and applies `default` when this instance really is a `select`\n * (the check keeps subclasses from applying it twice).\n */\n constructor(params: ModelListSelectFilterParams<T>) {\n super(params);\n this.type = 'select';\n if (this.label == '') {\n this.label = 'Sélectionnez un élément';\n }\n if (this.help == '') {\n this.help = 'Choix par liste déroulante';\n }\n if (!params.choices && !params.model) {\n throw new Error('Missing choices for select filter');\n }\n if (!params.choices && params.model) {\n const m = new params.model();\n const f = m.FM(params.mfield || params.field);\n const ch = (f as { choices?: IDispEditChoice[] }).choices;\n if (!ch) {\n throw new Error('No choices found for model/field');\n }\n this.choices = of(ch);\n } else {\n if (!isObservable(params.choices)) {\n this.choices = of(params.choices as IDispEditChoice[]);\n } else {\n this.choices = params.choices;\n }\n }\n // Set default only for cur type\n if (this.default && this.type == 'select') {\n this.set(this.default as FilterValue, '', true);\n }\n }\n\n /** Empty stub; the constructor applies `default` itself. Does nothing. */\n public setDefault() {\n // The choices carry their own default; nothing to seed here.\n }\n}\n","import {\n ModelListSelectFilter,\n ModelListSelectFilterParams,\n} from '../model-list-select-filter/model-list-select-filter';\nimport { DataModel } from '../../../../data/data-model';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\n\nexport interface ModelListMultiSelectFilterParams<T extends DataModel> extends ModelListSelectFilterParams<T> {\n /**\n * The options selected from the start, as full choice objects rather than\n * bare values: each `desc` is what labels the corresponding chip until the\n * user removes it.\n */\n default?: IDispEditChoice[];\n}\n\n/**\n * Multiple-choice filter: a dropdown that accumulates the picked options as\n * removable chips, sending all their values joined by `,` in a single query\n * parameter. Same choice sources as {@link ModelListSelectFilter} — `choices`\n * or `model` — and the same throw contract.\n *\n * `default` differs here: it takes an array of `IDispEditChoice` rather than a\n * lone value, since each preselected option needs its own label.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez un élément'` / `'Choix par liste déroulante (multiple)'`.\n *\n * @throws `'Missing choices for select filter'` (a string, not an `Error`) when\n * neither `choices` nor `model` is given.\n * @throws `'No choices found for model/field'` (a string, not an `Error`) when\n * `model` is used but the target field declares no choices.\n *\n * @example\n * ```typescript\n * new ModelListSelectMultiFilter<Thing>({\n * name: 'status',\n * field: 'status',\n * label: 'Status',\n * help: 'Pick one or more statuses',\n * choices: [{ value: 'ok', desc: 'Valid' }, { value: 'ko', desc: 'Invalid' }],\n * default: [{ value: 'ok', desc: 'Valid' }],\n * });\n * ```\n */\nexport class ModelListSelectMultiFilter<T extends DataModel> extends ModelListSelectFilter<T> {\n /** Always `true`: this filter joins its values into one query parameter. */\n public override multi = true;\n // `default` is inherited from ModelListFilter (typed `any`) and set by the\n // base constructor. We intentionally do NOT re-declare it here: under\n // useDefineForClassFields:true a field re-declaration without initializer\n // would clobber the base-constructor value back to undefined.\n\n /**\n * Switches the filter type to `selectmulti` and selects each `default`\n * choice. The parent constructor has already resolved the choices and\n * enforced the `choices`-or-`model` requirement.\n */\n /** The options selected from the start, as full choice objects. */\n declare public default?: IDispEditChoice[];\n\n constructor(params: ModelListMultiSelectFilterParams<T>) {\n super(params);\n\n this.type = 'selectmulti';\n if (this.label == '') {\n this.label = 'Sélectionnez un élément';\n }\n if (this.help == '') {\n this.help = 'Choix par liste déroulante (multiple)';\n }\n // Set default only for cur type\n if (this.default && this.type == 'selectmulti') {\n for (const f of this.default) {\n this.set(f.value, f.desc, true);\n }\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\n\n/**\n * Free-text filter: a single text input whose content is sent as-is under the\n * filter's `field`, debounced while the user types. The usual choice for a\n * list's main search box.\n *\n * Takes no options beyond {@link ModelListFilterParams}. `default` is applied\n * at construction, so the list starts out already filtered.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Recherche par texte'` / `'Texte à rechercher'`.\n *\n * @example\n * ```typescript\n * new ModelListTextFilter({\n * name: 'search',\n * field: 'search',\n * label: 'Search',\n * help: 'Text to look for',\n * });\n * ```\n */\nexport class ModelListTextFilter extends ModelListFilter {\n /**\n * Sets the filter type to `text` and applies `default` as the initial search\n * term when one is given.\n */\n constructor(params: ModelListFilterParams) {\n super(params);\n this.type = 'text';\n if (this.label == '') {\n this.label = 'Recherche par texte';\n }\n if (this.help == '') {\n this.help = 'Texte à rechercher';\n }\n if (this.default) {\n this.set(this.default as string, '', true);\n }\n }\n}\n","import { DataModel } from '../../../../data/data-model';\nimport {\n ModelListAutocompleteFilter,\n ModelListAutocompleteParams,\n} from '../model-list-autocomplete-filter/model-list-autocomplete-filter';\n\nexport interface ModelListTreeParams<T extends DataModel> extends ModelListAutocompleteParams<T> {\n /**\n * How deep the hierarchy may go, counted from the root. Defaults to `5`. It\n * caps how many dropdowns are offered, and bounds the walk back up to the\n * root when restoring a preselected node — that walk throws if it exceeds\n * this depth without reaching a root.\n */\n maxLevel?: number;\n}\n\n/**\n * Hierarchical filter: a chain of dropdowns, one per level, each populated from\n * the node selected in the one above. Picking a node sends its `id` under the\n * filter's `field`; a new dropdown appears as long as the selected node has\n * children and {@link maxLevel} is not reached.\n *\n * It extends {@link ModelListAutocompleteFilter}, so it needs `collection` or\n * `queryset` under the same throw contract, and it reuses that class's\n * `display` and `filter` options. It does not, however, present a typeahead.\n *\n * ## Backend contract\n *\n * Levels are fetched by querying the queryset with `level` and `parent`\n * parameters (`parent=null` for roots), so the endpoint must support both.\n * When the filter already has a value, it walks from that node up to the root\n * by following each record's `parent` property to rebuild the chain of\n * dropdowns.\n *\n * That walk reads `parent` off the fetched records, so if you use `filter` to\n * trim the payload it **must** keep the parent pointer:\n * `filter: { fields: ['id', 'name', 'parent'].join(',') }`. Omit it and\n * restoring a preselected node breaks.\n *\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez dans la hiérarchie'` / `'Texte à rechercher'`.\n *\n * @throws `'Missing related data (collection or queryset)'` (a string, not an\n * `Error`) when neither `collection` nor `queryset` is given.\n *\n * @example\n * ```typescript\n * new ModelListTreeFilter<Category>({\n * name: 'category',\n * field: 'category',\n * label: 'Category',\n * help: 'Pick a category',\n * collection: categories,\n * display: (c) => `${c.name}`,\n * maxLevel: 3,\n * // 'parent' is required to rebuild the hierarchy\n * filter: { fields: ['id', 'name', 'parent'].join(',') },\n * });\n * ```\n */\nexport class ModelListTreeFilter<T extends DataModel>\n extends ModelListAutocompleteFilter<T>\n implements ModelListTreeParams<T>\n{\n /** Maximum hierarchy depth; also bounds the walk back up to the root. */\n public maxLevel = 5;\n\n /**\n * Switches the filter type to `tree` and applies `maxLevel`. The parent\n * constructor has already enforced the `collection`-or-`queryset`\n * requirement.\n */\n constructor(params: ModelListTreeParams<T>) {\n super(params);\n this.type = 'tree';\n if (this.label == '') {\n this.label = 'Sélectionnez dans la hiérarchie';\n }\n if (this.help == '') {\n this.help = 'Texte à rechercher';\n }\n if (params.maxLevel) {\n this.maxLevel = params.maxLevel;\n }\n }\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { GeoSearchResult } from '../model-list-geodistance-filter';\n\n/**\n * The GeoJSON `FeatureCollection` returned by the BAN search endpoint. Only the\n * members {@link BanAdapter} reads are described precisely; the service returns\n * more.\n */\nexport interface BanResults {\n type: 'FeatureCollection';\n version: string;\n features: {\n type: 'Feature';\n geometry: {\n type: 'Point';\n coordinates: [number, number];\n };\n properties: {\n label: string;\n score: number;\n id: string;\n type: string;\n name: string;\n postcode: string;\n citycode: string;\n x: number;\n y: number;\n population: number;\n city: string;\n context: string;\n importance: number;\n };\n }[];\n}\n\n/**\n * Geocoder for {@link ModelListGeodistanceFilter} backed by the French *Base\n * Adresse Nationale* (BAN) address search API, whose GeoJSON responses it maps\n * to {@link GeoSearchResult}. This is the only adapter shipped with the\n * library; targeting another geocoder means writing an equivalent class, since\n * the filter only ever needs a `(text) => Observable<GeoSearchResult[]>`.\n *\n * Build it once — in a service, or wherever the filter is declared — and hand\n * its {@link search} to the filter's `geolocator`. Being a plain class it is\n * not injectable: pass an `HttpClient` in yourself.\n *\n * @example\n * ```typescript\n * const adapter = new BanAdapter(inject(HttpClient), 'https://api-adresse.data.gouv.fr/search/');\n * new ModelListGeodistanceFilter({\n * name: 'around', field: 'around', label: 'Distance', help: 'Town & distance',\n * geolocator: (pos) => adapter.search(pos),\n * });\n * ```\n */\nexport class BanAdapter {\n /**\n * @param _http The client issuing the search requests.\n * @param _baseUrl The BAN search endpoint, used as-is with the query added as\n * a `q` parameter (e.g. `https://api-adresse.data.gouv.fr/search/`).\n */\n constructor(\n private _http: HttpClient,\n private _baseUrl: string,\n ) {}\n\n /**\n * Geocodes `text` through the BAN endpoint, flattening each returned feature\n * into a {@link GeoSearchResult} whose `label` combines the address label and\n * its context (department and region), which disambiguates identically named\n * towns in the dropdown.\n *\n * Results come back in the service's own relevance order; no filtering on\n * `score` is applied.\n */\n public search(text: string): Observable<GeoSearchResult[]> {\n return this._http.get<BanResults>(`${this._baseUrl}`, { params: { q: text } }).pipe(\n map((r) => {\n const out: GeoSearchResult[] = [];\n for (const f of r.features) {\n out.push({\n score: f.properties.score,\n label: `${f.properties.label} (${f.properties.context})`,\n lat: f.geometry.coordinates[1],\n lng: f.geometry.coordinates[0],\n });\n }\n return out;\n }),\n );\n }\n}\n","import { Component, DestroyRef, inject, input, OnInit, signal } from '@angular/core';\nimport { ModelList } from '../../model-list.service';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime } from 'rxjs';\nimport { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';\n\nimport { DataModel } from '../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-model-list-paginator',\n templateUrl: './model-list-paginator.component.html',\n styleUrls: ['./model-list-paginator.component.sass'],\n imports: [ReactiveFormsModule, NgbPaginationModule],\n})\n/**\n * The pagination bar for a list: a page-size selector, page links, the total row\n * count and a \"go to page\" box.\n *\n * Place it under the table, bound to the same {@link ModelList}; it drives that\n * list's {@link ModelListPaginator} and follows the server's response, so no\n * wiring beyond the input is needed.\n *\n * @example\n * ```html\n * <data-model-list-paginator [list]=\"list\"></data-model-list-paginator>\n * ```\n */\nexport class ModelListPaginatorComponent<T extends DataModel> implements OnInit {\n /** The list being paginated. */\n public list = input.required<ModelList<T>>();\n /**\n * Largest page size offered in the selector — despite the name this caps rows\n * per page, not the number of pages. Options run 10 to 10000; each is shown\n * only if it is `<= maxPages`, so the default of 200 offers 10 through 200.\n */\n public maxPages = input<number>(200);\n /** Render nothing. */\n public hide = input<boolean>(false);\n\n /** Rows-per-page selector. */\n public perPageControl: FormControl = new FormControl<number>(10);\n /** Whether the \"go to page\" input is expanded. */\n public showDirectAccess = false;\n /** Direct page number entry, debounced 400ms before it moves the list. */\n public directAccess: FormControl = new FormControl<number>(0);\n /** Page currently shown, as reported by the last response. */\n public curPage = signal(1);\n /** Total number of matching rows. */\n public curCount = signal<number>(0);\n /** Rows per page currently in effect. */\n public pageSize = signal<number>(0);\n private destroy$ = inject(DestroyRef);\n\n /** Move the list to `page`. */\n public onPageChange(page: number): void {\n if (!page) {\n return;\n }\n this.list().paginator.setPage(page);\n }\n\n /**\n * Sync the controls with the list's paginator, follow the nav metadata of each\n * response, and push the user's page-size / direct-page changes back.\n */\n public ngOnInit(): void {\n const list = this.list();\n this.perPageControl.setValue(list.paginator.getPageSize(), {\n emitEvent: false,\n });\n list.meta.pipe(takeUntilDestroyed(this.destroy$)).subscribe((meta) => {\n if (meta.nav) {\n list.paginator.updatePage(meta.nav.page || 1);\n this.curPage.set(meta.nav.page || 1);\n this.curCount.set(meta.nav.count);\n list.paginator.updatePageSize(meta.nav.size);\n this.pageSize.set(list.paginator.getPageSize());\n this.perPageControl.setValue(this.pageSize(), { emitEvent: false });\n }\n });\n\n this.perPageControl.valueChanges.pipe(takeUntilDestroyed(this.destroy$)).subscribe((count) => {\n list.paginator.setPageSize(Number(count));\n });\n\n this.directAccess.valueChanges.pipe(takeUntilDestroyed(this.destroy$), debounceTime(400)).subscribe((count) => {\n list.paginator.setPage(+count);\n });\n }\n}\n","@if (!hide()) {\n <div class=\"row\">\n <div class=\"col-sm-4\">\n <select class=\"form-select perpage\" [formControl]=\"perPageControl\">\n @if (maxPages() >= 10) {\n <option value=\"10\">10 / page</option>\n }\n @if (maxPages() >= 20) {\n <option value=\"20\">20 / page</option>\n }\n @if (maxPages() >= 50) {\n <option value=\"50\">50 / page</option>\n }\n @if (maxPages() >= 100) {\n <option value=\"100\">100 / page</option>\n }\n @if (maxPages() >= 200) {\n <option value=\"200\">200 / page</option>\n }\n @if (maxPages() >= 500) {\n <option value=\"500\">500 / page</option>\n }\n @if (maxPages() >= 1000) {\n <option value=\"1000\">1000 / page</option>\n }\n @if (maxPages() >= 2000) {\n <option value=\"2000\">2000 / page</option>\n }\n @if (maxPages() >= 5000) {\n <option value=\"5000\">5000 / page</option>\n }\n @if (maxPages() >= 10000) {\n <option value=\"10000\">10000 / page</option>\n }\n </select>\n </div>\n @if (list()) {\n <div class=\"col-sm-5 pagination\">\n <div class=\"text-xs-center\">\n <ngb-pagination\n [pageSize]=\"pageSize()\"\n [collectionSize]=\"curCount()\"\n [page]=\"curPage()\"\n (pageChange)=\"onPageChange($event)\"\n [maxSize]=\"5\"\n [rotate]=\"true\"\n ></ngb-pagination>\n </div>\n </div>\n }\n <div class=\"col-sm-3 results\">\n <div>\n {{ curCount() }} résultats -\n <span\n (click)=\"showDirectAccess = !showDirectAccess\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"showDirectAccess\"\n (keydown.enter)=\"showDirectAccess = !showDirectAccess\"\n (keydown.space)=\"$event.preventDefault(); showDirectAccess = !showDirectAccess\"\n >\n acces direct\n </span>\n </div>\n @if (showDirectAccess) {\n <div>\n <input class=\"form-control\" [formControl]=\"directAccess\" type=\"number\" placeholder=\"Aller à la page\" />\n </div>\n }\n </div>\n </div>\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { fieldValues, asText } from '../data/field-values';\nimport { DataModel } from '../data/data-model';\nimport { IDispEditChoice } from './dispedit/dispedit.constants';\n\n/**\n * Resolves a model field's raw value to the label declared in its field\n * manager's `choices`.\n *\n * Saves repeating the code-to-label mapping in templates: the manager already\n * knows it, so `thing | choice: 'status'` prints `Active` where the model holds\n * `A`. Falls back to the raw value when the field declares no choices, and to\n * `[value] ??` when the value matches none of them — an unmatched value is\n * shown rather than hidden.\n *\n * @example\n * ```html\n * {{ thing | choice: 'status' }} <!-- Active -->\n * {{ thing | choice: 'status':'both' }} <!-- [A] Active -->\n * ```\n */\n@Pipe({\n name: 'choice',\n standalone: true,\n})\nexport class ChoicePipe<T extends DataModel> implements PipeTransform {\n /**\n * @param value model instance to read the field from; `-` if nullish.\n * @param field name of the field whose manager declares the choices.\n * @param mode `desc` for the label alone, `code` for the raw value alone\n * (no manager lookup), `both` for `[code] label`.\n */\n transform(value: T, field: string, mode: 'code' | 'desc' | 'both' = 'desc'): string {\n if (!value) {\n return '-';\n }\n const fvalue = fieldValues(value)[field];\n if (mode === 'code') {\n return asText(fvalue);\n }\n const manager = value.FM(field);\n const choices = (manager as { choices?: IDispEditChoice[] }).choices;\n if (!choices) {\n return asText(fvalue);\n }\n for (const ch of choices) {\n if (ch.value === fvalue) {\n if (mode === 'desc') {\n return ch.desc;\n } else {\n return `[${asText(fvalue)}] ${ch.desc}`;\n }\n }\n }\n return `[${asText(fvalue)}] ??`;\n }\n}\n\n/**\n * {@link ChoicePipe} for a value that is not on the model.\n *\n * Same resolution, but the value is piped in and the model is only used to find\n * the field manager holding the `choices`. Useful when the value comes from\n * elsewhere — an aggregate, a form control, a row of a related list — while the\n * choice mapping still lives on a model field.\n *\n * @example\n * ```html\n * {{ row.status | pchoice: thing: 'status' }}\n * ```\n */\n@Pipe({\n name: 'pchoice',\n standalone: true,\n})\nexport class PChoicePipe<T extends DataModel> implements PipeTransform {\n /**\n * @param value raw value to resolve; `-` if nullish.\n * @param model model instance used only to look up the field manager.\n * @param field name of the field whose manager declares the choices.\n * @param mode `desc` for the label alone, `code` for the raw value alone,\n * `both` for `[code] label`.\n */\n transform(value: unknown, model: T, field: string, mode: 'code' | 'desc' | 'both' = 'desc'): string {\n if (!model) {\n return '-';\n }\n if (!value) {\n return '-';\n }\n // Use value from input, not from field\n const fvalue = value; //- fieldValues(model)[field];\n if (mode === 'code') {\n return asText(fvalue);\n }\n const manager = model.FM(field);\n const choices = (manager as { choices?: IDispEditChoice[] }).choices;\n if (!choices) {\n return asText(fvalue);\n }\n for (const ch of choices) {\n if (ch.value === fvalue) {\n if (mode === 'desc') {\n return ch.desc;\n } else {\n return `[${asText(fvalue)}] ${ch.desc}`;\n }\n }\n }\n return `[${asText(fvalue)}] ??`;\n }\n}\n","import { inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core';\nimport { fieldValues } from '../data/field-values';\nimport { DataModel } from '../data/data-model';\nimport { formatNumber } from '@angular/common';\n\n/**\n * Whether a value is worth formatting: rejects null, undefined, empty string\n * and NaN (via the `value !== value` self-inequality check).\n */\nexport function isValue(value: number | string | null | undefined): value is number | string {\n return !(value == null || value === '' || value !== value);\n}\n\n/**\n * Coerce a numeric string to a number, passing numbers through.\n *\n * @param value value to coerce.\n * @throws Error if the value is neither a number nor a numeric string.\n */\nexport function strToNumber(value: number | string): number {\n // Convert strings to numbers\n if (typeof value === 'string' && !isNaN(Number(value) - parseFloat(value))) {\n return Number(value);\n }\n if (typeof value !== 'number') {\n throw new Error(`${value} is not a number`);\n }\n return value;\n}\n\n/**\n * Formats a scaled numeric model field as a human-readable number, dividing by\n * the field manager's `factor`.\n *\n * `decimalField.factor` is a wire-format concern, not a model one: the model\n * property holds the **raw** integer value, and the division happens at display\n * time — here, and in `<data-dispedit>`. With `factor: 100`, `thing.price` is\n * `1234` (cents) and this pipe prints `12.34`. Reading `thing.price` directly in\n * a template therefore shows the unscaled value; that mismatch is the trap this\n * pipe exists to avoid. Fields with no `factor` divide by 1 and are unaffected.\n *\n * @example\n * ```html\n * {{ thing | factor: 'price' }} <!-- 12.34 for a raw 1234 -->\n * {{ thing | factor: 'price':'1.2-2' }}\n * ```\n */\n@Pipe({\n name: 'factor',\n standalone: true,\n})\nexport class FactorPipe<T extends DataModel> implements PipeTransform {\n private _locale = inject(LOCALE_ID);\n\n /**\n * @param value model instance to read the field from; null if nullish.\n * @param field name of the field whose manager carries the `factor`.\n * @param digitsInfo digit format, as accepted by Angular's `number` pipe.\n * @param locale locale to format in; defaults to the ambient `LOCALE_ID`.\n */\n transform(value: T | null, field: string, digitsInfo?: string, locale?: string): string | null {\n if (!value) {\n return null;\n }\n locale = locale || this._locale;\n const fvalue = fieldValues(value)[field] as string | number | null | undefined;\n if (!isValue(fvalue)) return null;\n const manager = value.FM(field);\n let factor = (manager as { factor?: number }).factor;\n factor = factor || 1;\n const num = strToNumber(fvalue);\n return formatNumber(num / factor, locale, digitsInfo);\n }\n}\n\n/**\n * {@link FactorPipe} for a value that is not on the model.\n *\n * Same scaling, but the value is piped in and the model is only used to look up\n * the field manager's `factor`. Useful for computed totals or values from a\n * related payload that share a field's scale.\n *\n * @example\n * ```html\n * {{ total | pfactor: thing: 'price' }}\n * ```\n */\n@Pipe({\n name: 'pfactor',\n standalone: true,\n})\nexport class PFactorPipe<T extends DataModel> implements PipeTransform {\n private _locale = inject(LOCALE_ID);\n\n /**\n * @param value raw, unscaled value to format; null if falsy.\n * @param model model instance used only to look up the field manager.\n * @param field name of the field whose manager carries the `factor`.\n * @param digitsInfo digit format, as accepted by Angular's `number` pipe.\n * @param locale locale to format in; defaults to the ambient `LOCALE_ID`.\n */\n transform(\n value: number | string | null | undefined,\n model: T | null,\n field: string,\n digitsInfo?: string,\n locale?: string,\n ): string | null {\n if (!model) return null;\n if (!value) return null;\n\n locale = locale || this._locale;\n // Use value from input, not from model\n const fvalue = value; // fieldValues(model)[field];\n if (!isValue(fvalue)) return null;\n const manager = model.FM(field);\n let factor = (manager as { factor?: number }).factor;\n factor = factor || 1;\n const num = strToNumber(fvalue);\n return formatNumber(num / factor, locale, digitsInfo);\n }\n}\n","import { DEFAULT_CURRENCY_CODE, inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core';\nimport { fieldValues } from '../data/field-values';\nimport { DataModel } from '../data/data-model';\nimport { isValue, strToNumber } from './factor.pipe';\nimport { formatCurrency, getCurrencySymbol } from '@angular/common';\n\n/**\n * Currency counterpart of `factor`: divides a scaled numeric model field by its\n * field manager's `factor`, then formats the result as currency.\n *\n * The scaling caveat is the same. `decimalField.factor` is applied at display\n * time, not in the model: the property holds the raw integer, so `factor: 100`\n * means `thing.price` is `1234` and this pipe prints `12,34 €`. Fields with no\n * `factor` divide by 1.\n *\n * @example\n * ```html\n * {{ thing | factorc: 'price' }}\n * {{ thing | factorc: 'price':'USD':'symbol':'1.2-2' }}\n * ```\n */\n@Pipe({\n name: 'factorc',\n standalone: true,\n})\nexport class FactorcPipe<T extends DataModel> implements PipeTransform {\n private _locale = inject(LOCALE_ID);\n private _defaultCurrencyCode = inject(DEFAULT_CURRENCY_CODE);\n\n /**\n * @param value model instance to read the field from; null if nullish.\n * @param field name of the field whose manager carries the `factor`.\n * @param currencyCode ISO code; defaults to the ambient `DEFAULT_CURRENCY_CODE`.\n * @param display how to render the currency: `code`, `symbol` (the default),\n * `symbol-narrow`, or a literal string to use as-is.\n * @param digitsInfo digit format, as accepted by Angular's `currency` pipe.\n * @param locale locale to format in; defaults to the ambient `LOCALE_ID`.\n */\n transform(\n value: T | null,\n field: string,\n currencyCode?: string,\n display?: 'code' | 'symbol' | 'symbol-narrow' | (string & {}),\n digitsInfo?: string,\n locale?: string,\n ): string | null {\n if (!value) return null;\n const fvalue = fieldValues(value)[field] as string | number | null | undefined;\n if (!isValue(fvalue)) return null;\n locale = locale || this._locale;\n let currency: string = currencyCode || this._defaultCurrencyCode;\n if (!display) {\n display = 'symbol';\n }\n if (display !== 'code') {\n if (display === 'symbol' || display === 'symbol-narrow') {\n currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow', locale);\n } else {\n currency = display!;\n }\n }\n\n const manager = value.FM(field);\n const factor = (manager as { factor?: number }).factor || 1;\n const num = strToNumber(fvalue);\n return formatCurrency(num / factor, locale, currency, currencyCode, digitsInfo);\n }\n}\n\n/**\n * {@link FactorcPipe} for a value that is not on the model.\n *\n * Same scaling and currency formatting, but the value is piped in and the model\n * is only used to look up the field manager's `factor`. Useful for computed\n * totals that share a price field's scale.\n *\n * @example\n * ```html\n * {{ total | pfactorc: thing: 'price' }}\n * ```\n */\n@Pipe({\n name: 'pfactorc',\n standalone: true,\n})\nexport class PFactorcPipe<T extends DataModel> implements PipeTransform {\n private _locale = inject(LOCALE_ID);\n private _defaultCurrencyCode = inject(DEFAULT_CURRENCY_CODE);\n\n /**\n * @param value raw, unscaled value to format; null if falsy.\n * @param model model instance used only to look up the field manager.\n * @param field name of the field whose manager carries the `factor`.\n * @param currencyCode ISO code; defaults to the ambient `DEFAULT_CURRENCY_CODE`.\n * @param display how to render the currency: `code`, `symbol` (the default),\n * `symbol-narrow`, or a literal string to use as-is.\n * @param digitsInfo digit format, as accepted by Angular's `currency` pipe.\n * @param locale locale to format in; defaults to the ambient `LOCALE_ID`.\n */\n transform(\n value: number | string | undefined | null,\n model: T | null,\n field: string,\n currencyCode?: string,\n display?: 'code' | 'symbol' | 'symbol-narrow' | (string & {}),\n digitsInfo?: string,\n locale?: string,\n ): string | null {\n if (!model) return null;\n if (!value) return null;\n // Use value from input, not from model\n const fvalue = value; // fieldValues(model)[field];\n if (!isValue(fvalue)) {\n return null;\n }\n locale = locale || this._locale;\n let currency: string = currencyCode || this._defaultCurrencyCode;\n if (!display) {\n display = 'symbol';\n }\n if (display !== 'code') {\n if (display === 'symbol' || display === 'symbol-narrow') {\n currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow', locale);\n } else {\n currency = display!;\n }\n }\n\n const manager = model.FM(field);\n const factor = (manager as { factor?: number }).factor || 1;\n const num = strToNumber(fvalue);\n return formatCurrency(num / factor, locale, currency, currencyCode, digitsInfo);\n }\n}\n","import { Component, DestroyRef, inject, input, model, OnInit, output } from '@angular/core';\nimport { fieldValues } from '../../data/field-values';\nimport { DataModel } from '../../data/data-model';\nimport { uniqueId } from '../../utils/unique-id';\nimport { FilterData, Queryset } from '../../data/data-query';\nimport { Collection } from '../../data/data-collection';\nimport { debounceTime, distinctUntilChanged, Observable } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\n\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n/**\n * Renders a related instance as a label, for dropdown options and read-only\n * displays. Used as a fallback when the target model has no `_display`.\n */\nexport type TplFun<T extends DataModel> = (data: T) => string;\n\n@Component({\n selector: 'data-fkselect',\n templateUrl: './fkselect.component.html',\n styleUrls: ['./fkselect.component.sass'],\n imports: [ReactiveFormsModule, NgbTypeaheadModule],\n})\n/**\n * Typeahead for picking a single related instance (a foreign key target).\n *\n * Search terms are debounced (750ms) and sent to a queryset as a filter, so\n * candidates are queried from the API rather than held in memory. This is the\n * editor {@link DispeditComponent} renders for a `ForeignKeyFieldManager`; it\n * can also be used directly.\n *\n * The component only reports the selection through {@link selected} — it does\n * not write to the model or save. Used inside dispedit, that write (id to the\n * field, instance to `<field>_details`) and the save are dispedit's job.\n *\n * Options are labelled via the target's `_display`, accepted as either a getter\n * or a method; a model used as an FK target should define one. Failing that,\n * `[display]` is consulted, then `name` / `title` / `id`.\n */\nexport class FkselectComponent<T extends DataModel, R extends DataModel> implements OnInit {\n /**\n * Source model, used only to derive a queryset from its `_collection` when\n * neither `[queryset]` nor `[collection]` is given.\n */\n public model = input<T>();\n /** Field name on the source model. Informational; not read or written here. */\n public field = input<string>();\n /** Whether the control is in edit mode. */\n public edit = input<boolean>(false);\n /** Currently selected instance. */\n public value = input<R>();\n\n /**\n * Queryset searched for candidates. Derived on init from `[collection]`, or\n * from the model's `_collection`, when not supplied.\n */\n public queryset = model<Queryset<R>>();\n /** Collection the candidates are queried from. Writable so it can be derived. */\n public collection = model<Collection<R>>();\n /** Reserved flag; not currently read by the component. */\n public update = input<boolean>(false);\n /** Extra filter merged into every search request, to narrow the lookup. */\n public filter = input<FilterData>({});\n /** Presentation hint for the control. */\n public mode = input<'autocomplete' | 'select' | 'auto'>('auto');\n /** Option label: a property name, or a function. Only used without `_display`. */\n public display = input<string | TplFun<R>>();\n /** Query parameter name the search term is sent under. Defaults to `search`. */\n public search = input<string>('search');\n\n /** Label shown next to the control. */\n public label = input<string>('');\n /**\n * Id put on the search input, and pointed at by `[label]`'s `for`. Defaults\n * to a generated one; dispedit passes its own so its label drives this input.\n */\n public inputId = input<string>(uniqueId('data-fkselect'));\n /** Placeholder for the search input. */\n public placeholder = input<string>('');\n /** CSS classes applied to the search input. */\n public inputClasses = input<string[] | string>([]);\n\n /** Emits the instance the user picked from the dropdown. */\n public selected = output<R>();\n /** Emits when the user aborts editing (escape). */\n public cancelled = output<void>();\n /** Emits when the user clears the selection, via {@link clearAction}. */\n public cleared = output<void>();\n /** Form control backing the typeahead search input. */\n public fc!: FormControl<R | null>;\n /** Search callback handed to ng-bootstrap's typeahead. */\n public searchFn = this._search.bind(this);\n /** Option formatter handed to ng-bootstrap's typeahead. */\n public displayFn = this._display.bind(this);\n private _tpl!: TplFun<R>;\n private destroy$ = inject(DestroyRef);\n\n /**\n * Resolve the queryset (from the input, the collection, or the model's\n * collection), create the search control and subscribe to it, and build the\n * option display function.\n */\n public ngOnInit(): void {\n // Create queryset if not given\n // queryset is created through model\n const model = this.model();\n if (!this.queryset() && this.collection()) {\n this.queryset.set(this.collection()!.queryset());\n } else if (!this.queryset() && model && model._collection) {\n // Fallback: the source model's own collection, assumed to hold the\n // related instances. Nothing can check that assumption.\n const coll = model._collection as unknown as Collection<R>;\n this.collection.set(coll);\n this.queryset.set(coll.queryset());\n }\n this.fc = new FormControl<R | null>(null);\n this.fc.valueChanges.pipe(takeUntilDestroyed(this.destroy$), distinctUntilChanged()).subscribe((value) => {\n if (value) {\n this.selected.emit(value);\n }\n });\n const display = this.display();\n if (display) {\n if (typeof display === 'string') {\n this._tpl = (model: R) => String(fieldValues(model)[display]);\n } else if (typeof display === 'function') {\n this._tpl = display.bind(this);\n }\n } else {\n this._tpl = (model: R) =>\n String(fieldValues(model)['name'] ?? fieldValues(model)['title'] ?? fieldValues(model)['id']);\n }\n }\n\n /** Emit {@link cleared} so the parent can null the relation. */\n public clearAction(): void {\n this.cleared.emit();\n }\n\n /**\n * Label an instance: its `_display` (getter or method) if present, otherwise\n * the template function built from `[display]`.\n */\n private _display(x: R | null | undefined): string {\n if (x) {\n const display = (x as { _display?: string | (() => string) })._display;\n if (display) {\n return typeof display === 'function' ? display() : display;\n }\n if (this._tpl) {\n return this._tpl(x);\n }\n }\n return '';\n }\n\n /**\n * Debounce the typed term, merge it into `[filter]` under the `[search]`\n * parameter name, and query the queryset for candidates.\n *\n * @param text$ stream of search terms from the typeahead input.\n */\n private _search(text$: Observable<string>): Observable<R[]> {\n return text$.pipe(\n takeUntilDestroyed(this.destroy$),\n debounceTime(750),\n distinctUntilChanged(),\n switchMap((term) => {\n const f: FilterData = {};\n const filter = this.filter();\n for (const k of Object.keys(filter)) {\n if (filter[k] !== null || filter[k] !== undefined) {\n f[k] = filter[k];\n }\n }\n f[this.search()] = term;\n const qs = this.queryset()!;\n qs.filter(f, true);\n return qs.get();\n }),\n );\n }\n}\n","<div class=\"form-group\">\n @if (label()) {\n <label [attr.for]=\"inputId()\">{{ label() }}</label>\n }\n <div class=\"input-group\">\n <input\n [attr.id]=\"inputId()\"\n class=\"form-control\"\n [formControl]=\"fc\"\n [placeholder]=\"placeholder()\"\n [ngbTypeahead]=\"searchFn\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"displayFn\"\n [resultFormatter]=\"displayFn\"\n (keyup.escape)=\"cancelled.emit()\"\n />\n <div class=\"input-group-text\">\n <i\n class=\"bi bi-trash float-end pointer\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Vider la sélection\"\n (click)=\"clearAction()\"\n (keydown.enter)=\"clearAction()\"\n (keydown.space)=\"$event.preventDefault(); clearAction()\"\n ></i>\n </div>\n </div>\n</div>\n","import { inject, Injectable, InjectionToken, NgZone } from '@angular/core';\nimport { Observable, ReplaySubject, Subscription, timer } from 'rxjs';\n\n/** Severity of a {@link Message}; drives both the CSS classes and the default lifetime. */\nexport const enum TYPE {\n SUCCESS,\n INFO,\n WARNING,\n DANGER,\n}\n\n/** Default lifetime in milliseconds per severity: the more severe, the longer it stays on screen. */\nexport enum DEFAULT_TIMEOUTS {\n SUCCESS = 3000,\n INFO = 4000,\n WARNING = 10000,\n DANGER = 30000,\n}\n\n/** Lifecycle of a {@link Message}: never shown yet, currently shown, or dismissed by the user. */\nexport enum STATUS {\n UNDISP,\n DISP,\n ACK,\n}\n\nconst DEFAULT_MESSAGE_TIMEOUT = 5000;\n\n/**\n * Maps a sound key (`success`, `info`, `warning`, `error`, `notify`) to an audio file url.\n */\nexport type ISoundTypes = Record<string, string>;\n\n/**\n * Optional per-severity notification sounds ({@link ISoundTypes}) played by\n * {@link DataMessageService.play}.\n *\n * When not provided, messages are silent. Keys are the sound names the service uses:\n * `success`, `info`, `warning` and `error`.\n */\nexport const DATA_MESSAGE_SOUNDS = new InjectionToken<ISoundTypes>('data.message.sounds');\n\n/**\n * A single user-facing notification: a title, an optional body, an optional trace for\n * debugging, and a countdown.\n *\n * Instances are created by {@link DataMessageService}; application code normally reads\n * them from the message stream rather than constructing them. `ttl` is decremented in\n * place by the service, and the message is dropped once it reaches zero.\n */\nexport class Message {\n public status: string = STATUS[STATUS.UNDISP];\n public showTrace = false;\n\n constructor(\n public title: string,\n public type: TYPE = TYPE.INFO,\n public message = '',\n public trace: unknown = null,\n public ttl: number = DEFAULT_MESSAGE_TIMEOUT,\n ) {}\n\n /** Bootstrap alert classes matching this message's severity, bound by the message zone template. */\n public get style(): string {\n if (this.type === TYPE.DANGER) {\n return 'alert alert-dismissible alert-danger';\n }\n if (this.type === TYPE.INFO) {\n return 'alert alert-dismissible alert-info';\n }\n if (this.type === TYPE.WARNING) {\n return 'alert alert-dismissible alert-warning';\n }\n if (this.type === TYPE.SUCCESS) {\n return 'alert alert-dismissible alert-success';\n }\n return 'alert alert-dismissible alert-success';\n }\n\n /** Marks the message as dismissed so it is filtered out of the next emission. Prefer {@link DataMessageService.ack}, which also refreshes the stream. */\n public ack(): void {\n this.status = STATUS[STATUS.ACK];\n }\n}\n\n/**\n * The library's user-notification channel.\n *\n * Library components push through it — `dispedit` reports auto-save outcomes, `flags`\n * and `sdelete` report their results, and {@link AuthServiceBase} warns when a session\n * expires — and `<data-message-zone>` is what renders them. **The two go together: if\n * you use dispedit's auto-save (or anything else that reports through this service)\n * without placing a `<data-message-zone>` somewhere in the layout, errors are collected\n * and silently discarded, and users see failed saves as nothing at all.**\n *\n * Messages expire on their own via a 500 ms ticker that runs outside the Angular zone,\n * re-entering it only when something actually changes.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DataMessageService {\n public ngZone = inject(NgZone);\n public sounds = inject(DATA_MESSAGE_SOUNDS, { optional: true });\n public _messages$: ReplaySubject<Message[]> = new ReplaySubject<Message[]>(1);\n private _messages: Message[] = [];\n private _timer!: Observable<number>;\n private _subscription!: Subscription;\n\n constructor() {\n this.init();\n }\n\n /**\n * The live list of messages to display, re-emitted whenever one is added, dismissed\n * or expires. Subscribed to by {@link MessageZoneComponent}; replays the latest list\n * to late subscribers.\n */\n public get current(): Observable<Message[]> {\n return this._messages$.asObservable();\n }\n\n /**\n * Starts the expiry ticker. Called from the constructor and idempotent, so there is\n * normally no reason to call it — except to restart the service after {@link close}.\n */\n public init(): void {\n let changed = false;\n if (!this._timer) {\n this.ngZone.runOutsideAngular(() => {\n this._timer = timer(500, 500);\n this._subscription = this._timer.subscribe(() => {\n for (const m of this._messages) {\n m.ttl -= 500;\n if (m.ttl <= 0) {\n changed = true;\n }\n }\n if (changed) {\n this.ngZone.run(() => {\n const out: Message[] = [];\n for (const m of this._messages) {\n if (m.ttl >= 0) {\n out.push(m);\n }\n }\n this._messages = out;\n this._notify();\n });\n }\n });\n });\n }\n }\n\n /**\n * Stops the expiry ticker, freezing any displayed message in place. Mostly useful in\n * tests; the internal timer field is kept, so {@link init} will not restart it.\n */\n public close(): void {\n this._subscription.unsubscribe();\n }\n\n /** Reports a completed operation. Short-lived by default (3 s) and plays the `success` sound if configured. */\n public success(title: string, message = '', trace: unknown = null, timeout: number = DEFAULT_TIMEOUTS.SUCCESS): void {\n this._messages.push(new Message(title, TYPE.SUCCESS, message, trace, timeout));\n this.play('success');\n this._notify();\n }\n\n /** Reports neutral information the user does not have to act on. Defaults to a 4 s lifetime. */\n public info(title: string, message = '', trace: unknown = null, timeout: number = DEFAULT_TIMEOUTS.INFO): void {\n this._messages.push(new Message(title, TYPE.INFO, message, trace, timeout));\n this.play('info');\n this._notify();\n }\n\n /** Reports a problem the user should notice but that did not abort the operation. Stays 10 s by default. */\n public warning(title: string, message = '', trace: unknown = null, timeout: number = DEFAULT_TIMEOUTS.WARNING): void {\n this._messages.push(new Message(title, TYPE.WARNING, message, trace, timeout));\n this.play('warning');\n this._notify();\n }\n\n /**\n * Reports a failure, with the longest lifetime (30 s) and the `error` sound.\n *\n * Note that the `timeout` argument is currently ignored: the message is always created\n * with {@link DEFAULT_TIMEOUTS.DANGER}.\n */\n public danger(title: string, message = '', trace: unknown = null, timeout: number = DEFAULT_TIMEOUTS.DANGER): void {\n this._messages.push(new Message(title, TYPE.DANGER, message, trace, timeout));\n this.play('error');\n this._notify();\n }\n\n /** Alias for {@link danger}, for callers that think in terms of \"error\" rather than severity. */\n public error(title: string, message = '', trace: unknown = null): void {\n this.danger(title, message, trace);\n }\n\n /** Logs to the console only — nothing is shown to the user and no message is queued. */\n public debug(title: string, message = '', trace: unknown = null): void {\n console.log(title, message, trace);\n }\n\n /**\n * Dismisses a message on the user's behalf and immediately re-emits the list, so the\n * message zone drops it without waiting for its ttl. Bound to the close button of\n * `<data-message-zone>`.\n */\n public ack(message: Message): void {\n message.ack();\n this._notify();\n }\n\n /**\n * Plays the sound registered under `type` in {@link DATA_MESSAGE_SOUNDS}, and does\n * nothing when the token or the key is absent. Called automatically by the severity\n * methods; call it directly only for custom cues.\n */\n public play(type = 'notify') {\n if (this.sounds && this.sounds[type]) {\n const audio = new Audio(this.sounds[type]);\n // Rejects whenever the browser's autoplay policy blocks the sound\n // (no user gesture yet). A missing notification cue is not worth\n // surfacing, but the rejection must be handled all the same.\n audio.play().catch(() => undefined);\n }\n }\n\n private _notify(): void {\n const out: Message[] = [];\n for (const message of this._messages) {\n if (message.status === STATUS[STATUS.UNDISP] || message.status === STATUS[STATUS.DISP]) {\n message.status = STATUS[STATUS.DISP];\n out.push(message);\n }\n }\n this._messages$.next(out);\n }\n}\n","import { Component, DestroyRef, inject, input, model, OnInit, output } from '@angular/core';\nimport { fieldValues } from '../../data/field-values';\nimport { FilterData, Queryset } from '../../data/data-query';\nimport { Collection } from '../../data/data-collection';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule, UntypedFormControl } from '@angular/forms';\nimport { debounceTime, distinctUntilChanged, firstValueFrom, Observable } from 'rxjs';\nimport { TplFun } from '../fkselect/fkselect.component';\nimport { DataModel } from '../../data/data-model';\nimport { uniqueId } from '../../utils/unique-id';\nimport { switchMap } from 'rxjs/operators';\n\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-m2mselect',\n templateUrl: './m2mselect.component.html',\n styleUrls: ['./m2mselect.component.sass'],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: M2mselectComponent,\n },\n ],\n imports: [ReactiveFormsModule, NgbTypeaheadModule],\n})\n/**\n * Typeahead for picking several related instances (a many-to-many target).\n *\n * The FK counterpart of {@link FkselectComponent}, but implemented as a\n * `ControlValueAccessor`: its form value is the array of selected primary keys,\n * while the resolved instances are kept alongside for display. This is the\n * editor {@link DispeditComponent} renders for a `ManyToManyFieldManager`.\n *\n * On init, if no `[values]` are supplied, the initial selection is read from\n * the model's `<field>_details` sibling property (built by string\n * concatenation). When that property is missing the selection simply starts\n * empty — which is the normal case for an unsaved model, as rendered by a\n * creation form. On a model that has an `id`, a missing `_details` is instead a\n * configuration problem (field left out of the request's `fields=`, or a\n * misspelled `[field]`) and is reported with a `console.warn`. A queryset, on\n * the other hand, is mandatory — supplied directly, derived from\n * `[collection]`, or from the model's `_collection`.\n *\n * Options are labelled via each target's `_display` (getter or method), falling\n * back to `[display]`, then `name` / `title` / `id`.\n */\nexport class M2mselectComponent<T extends DataModel, R extends DataModel> implements OnInit, ControlValueAccessor {\n /** Source model. Provides the `<field>_details` seed and a fallback collection. */\n public model = input<T>();\n /** Field name on the source model, used to find `<field>_details`. */\n public field = input<string>();\n /** Whether the control is in edit mode. */\n public edit = input<boolean>(false);\n /** Currently selected instances, kept in sync with {@link pks}. */\n public values = model<R[]>();\n /** Primary keys of the selection; this is the control's form value. */\n public pks: number[] = [];\n /** Whether editing is blocked, set through `setDisabledState`. */\n public disabled = false;\n /**\n * Queryset searched for candidates. Derived on init from `[collection]` or\n * the model's `_collection`; the component throws if none can be resolved.\n */\n public queryset = model<Queryset<R>>();\n /**\n * Collection candidates are queried from, and used to fetch instances for\n * primary keys written in through `writeValue` that aren't already known.\n */\n public collection = model<Collection<R>>();\n /** Extra filter merged into every search request, to narrow the lookup. */\n public filter = input<FilterData>({});\n /** Presentation hint for the control. */\n public mode = input<'autocomplete' | 'select' | 'auto'>('auto');\n /** Option label: a property name, or a function. Only used without `_display`. */\n public display = input<string | TplFun<R>>();\n /** Query parameter name the search term is sent under. Defaults to `search`. */\n public search = input<string>('search');\n /** Label shown next to the control. */\n public label = input<string>('');\n /**\n * Id put on the search input, and pointed at by `[label]`'s `for`. Defaults\n * to a generated one; dispedit passes its own so its label drives this input.\n */\n public inputId = input<string>(uniqueId('data-m2mselect'));\n /** Placeholder for the search input. */\n public placeholder = input<string>('');\n /** Text shown when nothing is selected. */\n public emptyLabel = input<string>('');\n /** CSS classes applied to the search input. */\n public inputClasses = input<string[] | string>([]);\n /** Emits the instance just added to the selection. */\n public added = output<R>();\n /** Emits the instance just removed from the selection. */\n public removed = output<R>();\n /** Emits when the user aborts editing. */\n public cancelled = output<void>();\n /** Emits when the whole selection is cleared. */\n public cleared = output<void>();\n /** Emits the full list of selected instances whenever it changes. */\n public detailsChanged = output<R[]>();\n /** Emits the selected primary keys whenever they change. */\n public changed = output<number[]>();\n\n /** Form control backing the typeahead search input. */\n public fc!: UntypedFormControl;\n /** Search callback handed to ng-bootstrap's typeahead. */\n public searchFn = this._search.bind(this);\n /** Option formatter handed to ng-bootstrap's typeahead. */\n public displayFn = this._display.bind(this);\n private touched = false;\n private _tpl!: TplFun<R>;\n private destroy$ = inject(DestroyRef);\n /**\n * Control value accessor onChange dummy callback;\n * @param _fks\n */\n public onChange = (_fks: number[]) => {\n // Replaced by registerOnChange when used inside a form.\n };\n\n /**\n * Control value accessor onTouched dummy callback;\n */\n public onTouched = () => {\n // Replaced by registerOnTouched when used inside a form.\n };\n\n /**\n * OnChange register from controlValueAccessor\n * @param onChange callback\n */\n registerOnChange(onChange: (fks: number[]) => void) {\n this.onChange = onChange;\n }\n\n /**\n * OnTouched register from controlValueAccessor\n * @param onTouched callback\n */\n registerOnTouched(onTouched: () => void) {\n this.onTouched = onTouched;\n }\n\n /**\n * OnInit :\n * - ensures queryset is available\n * - creates form control for input\n * - creates display function\n * - ensure values are set from whichever source is available\n */\n public ngOnInit(): void {\n // Create queryset if not given\n // queryset is created through model\n const model = this.model();\n if (!this.queryset() && this.collection()) {\n this.queryset.set(this.collection()!.queryset());\n } else if (!this.queryset() && model && model._collection) {\n // Fallback: the source model's own collection, assumed to hold the\n // related instances. Nothing can check that assumption.\n const coll = model._collection as unknown as Collection<R>;\n this.collection.set(coll);\n this.queryset.set(coll.queryset());\n }\n if (!this.queryset()) {\n throw Error('queryset is mandatory for m2m select');\n }\n // Create form control for typeahead and subscribe for changes\n this.fc = new UntypedFormControl('');\n this.fc.valueChanges.pipe(takeUntilDestroyed(this.destroy$), distinctUntilChanged()).subscribe((value: R | '') => {\n if (value) {\n this.onAdd(value);\n }\n });\n // Set display function\n const display = this.display();\n if (display) {\n if (typeof display === 'string') {\n this._tpl = (m: R) => `${String(fieldValues(m)[display])}`;\n } else if (typeof display === 'function') {\n this._tpl = display.bind(this);\n }\n } else {\n this._tpl = (m: R) => {\n const v = fieldValues(m);\n return `${String(v['name'] ?? v['title'] ?? v['id'])}`;\n };\n }\n // Get values from model if not already given\n const field = this.field();\n if (this.values() === undefined && model && field) {\n const details = fieldValues(model)[`${field}_details`] as R[] | undefined;\n if (details === undefined && model.id !== undefined) {\n // The model comes from the API but carries no details for this\n // relation: either the field was left out of the request's `fields=`,\n // or `[field]` doesn't match the model's. Worth reporting, but not\n // worth breaking the display for — the selection just starts empty.\n console.warn(\n `m2mselect: no \"${field}_details\" on the model, starting with an ` +\n `empty selection. Check that \"${field}\" is requested in the ` +\n `fields= of the query, and that [field] is spelled correctly.`,\n model,\n );\n }\n this.values.set(details ?? []);\n }\n // No model or field given, or an unsaved model (creation form): the\n // details sibling cannot exist yet, an empty selection is expected.\n if (this.values() === undefined) {\n this.values.set([]);\n }\n }\n\n /**\n * Remove a value.\n * Emits detailsChanged, changed and removed signals.\n * @param i instance to be removed\n */\n public onRemove(i: R) {\n if (!this.disabled) {\n this.markAsTouched();\n const ps = this.pks.indexOf(i.id);\n this.pks.splice(ps, 1);\n this.values.set(this.values()!.filter((_, idx) => idx !== ps));\n this.detailsChanged.emit(this.values()!);\n this.changed.emit(this.pks);\n this.removed.emit(i);\n this.onChange(this.pks);\n }\n }\n\n /**\n * Add a value.\n * Emits detailsChanged, changed and added signals.\n * @param i instance to be added.\n */\n public onAdd(i: R) {\n if (!this.disabled) {\n this.markAsTouched();\n this.pks.push(i.id);\n this.values.set([...this.values()!, i]);\n this.detailsChanged.emit(this.values()!);\n this.changed.emit(this.pks);\n this.added.emit(i);\n this.onChange(this.pks);\n }\n }\n\n /**\n * Clear all values.\n * Emits detailsChanged, changed and cleared signals.\n */\n public onClear() {\n if (!this.disabled) {\n this.markAsTouched();\n this.pks = [];\n this.values.set([]);\n this.detailsChanged.emit(this.values()!);\n this.changed.emit(this.pks);\n this.cleared.emit();\n this.onChange(this.pks);\n }\n }\n\n /**\n * Write value from controlValueAccessor.\n * @param pks\n */\n async writeValue(pks: number[]) {\n this.pks = pks;\n await this._getDisplayValues(pks);\n }\n\n /**\n * Mark as touched.\n */\n public markAsTouched() {\n if (!this.touched) {\n this.onTouched();\n this.touched = true;\n }\n }\n\n /**\n * Mark as disabled.\n * @param disabled\n */\n setDisabledState(disabled: boolean) {\n this.disabled = disabled;\n }\n\n /**\n * Retrieve display values for current set of pks.\n * Eventually fetches items from collection.\n * Emits detailsChanged signal.\n * @param pks list of current pks.\n * @private\n */\n private async _getDisplayValues(pks: number[] = []) {\n const values: R[] = [];\n for (const k of pks) {\n let found = false;\n for (const v of this.values() ?? []) {\n if (v.id == k) {\n values.push(v);\n found = true;\n break;\n }\n }\n if (!found) {\n const collection = this.collection();\n if (collection) {\n values.push(await firstValueFrom(collection.fetch(k)));\n } else {\n values.push({ id: k, _display: 'Unknown' } as unknown as R);\n }\n }\n }\n this.values.set(values);\n this.detailsChanged.emit(values);\n }\n\n /**\n * Display function. Uses descfield or desc tpl (lodash template using model fields).\n */\n private _display(x: R | null | undefined): string {\n if (x) {\n const display = (x as { _display?: string | (() => string) })._display;\n if (display) {\n return typeof display === 'function' ? display() : display;\n }\n if (this._tpl) {\n return this._tpl(x);\n }\n }\n return '';\n }\n\n /**\n * Search function.\n * @param text$\n * @private\n */\n private _search(text$: Observable<string>): Observable<R[]> {\n return text$.pipe(\n takeUntilDestroyed(this.destroy$),\n debounceTime(750),\n distinctUntilChanged(),\n switchMap((term) => {\n const f: FilterData = {};\n const filter = this.filter();\n for (const k of Object.keys(filter)) {\n if (filter[k] !== null || filter[k] !== undefined) {\n f[k] = filter[k];\n }\n }\n f[this.search()] = term;\n const qs = this.queryset()!;\n qs.filter(f, true);\n return qs.get();\n }),\n );\n }\n}\n","<div class=\"form-group\">\n @if (label()) {\n <label [attr.for]=\"inputId()\">{{ label() }}</label>\n }\n <div class=\"input-group\">\n <input\n [attr.id]=\"inputId()\"\n class=\"form-control\"\n [formControl]=\"fc\"\n [placeholder]=\"placeholder()\"\n [ngbTypeahead]=\"searchFn\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"displayFn\"\n [resultFormatter]=\"displayFn\"\n (keyup.escape)=\"cancelled.emit()\"\n />\n <div class=\"input-group-text\">\n <i\n class=\"bi bi-trash float-end pointer\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Vider la sélection\"\n (click)=\"cleared.emit()\"\n (keydown.enter)=\"cleared.emit()\"\n (keydown.space)=\"$event.preventDefault(); cleared.emit()\"\n ></i>\n </div>\n </div>\n @for (i of values(); track i) {\n <div>\n <i\n class=\"bi bi-trash ms-2 float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer ' + displayFn(i)\"\n (click)=\"onRemove(i)\"\n (keydown.enter)=\"onRemove(i)\"\n (keydown.space)=\"$event.preventDefault(); onRemove(i)\"\n ></i>\n {{ displayFn(i) }}\n </div>\n }\n</div>\n","import { Component, DestroyRef, effect, inject, input, model, output, signal, untracked } from '@angular/core';\nimport { fieldValues, asText } from '../../data/field-values';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { DataModel } from '../../data/data-model';\nimport { uniqueId } from '../../utils/unique-id';\nimport { BaseFieldManager } from '../../data/fields/base';\nimport { ReactiveFormsModule, UntypedFormControl, UntypedFormGroup } from '@angular/forms';\nimport { firstValueFrom } from 'rxjs';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES, IDispEditChoice } from './dispedit.constants';\nimport { FilterData, Queryset } from '../../data/data-query';\nimport { Collection } from '../../data/data-collection';\nimport { FkselectComponent, TplFun } from '../fkselect/fkselect.component';\nimport { DecimalFieldManager } from '../../data/fields/numbers';\nimport { BootstrapDataDisplayConfig, DATA_DISPLAY_CONFIG, DataDisplayConfig } from '../../data/data-parameters';\nimport { DataMessageService } from '../../messages/message.service';\nimport { DatePipe, NgTemplateOutlet } from '@angular/common';\nimport { M2mselectComponent } from '../m2mselect/m2mselect.component';\n\n@Component({\n selector: 'data-dispedit',\n templateUrl: './dispedit.component.html',\n styleUrls: ['./dispedit.component.sass'],\n imports: [DatePipe, NgTemplateOutlet, ReactiveFormsModule, FkselectComponent, M2mselectComponent],\n})\n/**\n * Displays and edits a single model field, choosing its own widgets from the\n * model's field metadata.\n *\n * This is the library's flagship component. You do not tell it what to render:\n * it asks the model for the field's manager (`model.FM(field)`) and takes the\n * manager's `editorType` and `displayType`. A `ForeignKeyFieldManager` yields\n * `fkselect` / `fkdetails`, a `ManyToManyFieldManager` yields `m2mselect` /\n * `m2mdetails`, a `charField` declared with `choices` yields a `select`, a\n * `decimalField` yields `input.decimal` / `decimal`, and so on. Declare the\n * model well and the UI follows; `[editor]` and `[viewer]` are escape hatches\n * for the cases where it does not.\n *\n * ## Modes\n *\n * - `mode=\"dd\"` renders a `<dt>`/`<dd>` block that flips to an editor in place\n * when clicked and **saves to the API itself** on validation. This is the\n * workhorse and accounts for the vast majority of real usage.\n * - `mode=\"inline\"` / `mode=\"form\"` render a bare form control and **do not\n * save**. They expect an external `[form]` {@link UntypedFormGroup} and an\n * outer submit to persist the value. (`'inline'` is pending a rename to\n * `'form'`; both are currently accepted and differ only in whether the local\n * form group or the external one drives the template.)\n *\n * Note the input default is `'inline'`, so `mode=\"dd\"` must be set explicitly\n * to get the auto-saving dt/dd behaviour.\n *\n * ## The `<field>_details` contract\n *\n * For FK and M2M fields, the component reads and writes a sibling property\n * whose name is built by string concatenation: `` `${field()}_details` ``. A\n * `category` foreign key therefore **requires** a `category_details` property\n * on the model holding the resolved target instance (or, for M2M, the array of\n * instances). Nothing type-checks this: rename the FK without renaming the\n * sibling and both the display and the write-back break silently at runtime.\n *\n * ## Decimal factor\n *\n * `decimalField.factor` is applied *here*, not in the model. The model property\n * holds the raw wire value; this component divides by `factor` when loading it\n * into the editor and multiplies back (rounded) when saving. With\n * `factor: 100`, `model.price` is in cents and the user sees `12.34`.\n *\n * @example\n * ```html\n * <!-- Scalar field: click to edit, saves itself -->\n * <data-dispedit [model]=\"thing\" field=\"name\" mode=\"dd\">Name</data-dispedit>\n * ```\n *\n * @example\n * ```html\n * <!-- Foreign key: [collection] is what the dropdown queries.\n * Requires a `category_details` property on `thing`. -->\n * <data-dispedit\n * [model]=\"thing\"\n * field=\"category\"\n * mode=\"dd\"\n * [collection]=\"categories\"\n * [filter]=\"{fields: ['id', 'name'].join(',')}\"\n * >Category</data-dispedit>\n * ```\n */\nexport class DispeditComponent<FT, T extends DataModel, R extends DataModel> {\n /** Model instance holding the field. Mandatory. */\n public model = input.required<T>();\n /**\n * Name of the field to display / edit. Mandatory.\n *\n * Used to look up the field manager, to read and write the model property,\n * and to name the form control. For FK and M2M fields it also determines the\n * `<field>_details` sibling property the component reads the display value\n * from and writes the selected instance back to — that property must exist on\n * the model, and nothing checks it at compile time.\n */\n public field = input.required<string>();\n\n /** Id tying the label to whichever control the editor renders. */\n public readonly inputId = uniqueId('data-dispedit');\n /**\n * External form group, for `inline` / `form` modes.\n *\n * When provided, the component adds its control to this group instead of\n * creating a standalone one, and leaves persistence to the outer submit.\n */\n public form = input<UntypedFormGroup>();\n /**\n * Whether the editor is currently shown. Two-way bindable.\n *\n * Mutated internally by {@link toggleEdit}, {@link enableEditMode} and\n * {@link enableDisplayMode}. In `inline` mode with `editable` true, the\n * editor is always shown.\n */\n public edit = model<boolean>(false);\n /**\n * Whether the field can be switched to edit mode at all.\n *\n * When false, {@link enableEditMode} returns immediately and the field stays\n * read-only. Defaults to true.\n */\n public editable = input<boolean>(true);\n /**\n * Whether {@link update} persists to the API.\n *\n * This is **not** a template-bindable input — it is a plain class property,\n * so `[save]=\"false\"` will not compile against it. It is set internally\n * during recompute: true when `mode` is `dd`, false otherwise. Control saving\n * through {@link mode} instead.\n */\n public save?: boolean;\n /**\n * Layout and save behaviour.\n *\n * - `dd`: display / edit inside a `<dt>`/`<dd>` block, saving to the API on\n * validation.\n * - `inline` (to be renamed to `form`): an optional label plus a form\n * control, no saving.\n * - `form`: same, driven by the external `[form]` group.\n */\n public mode = input<'dd' | 'inline' | 'form'>('inline');\n /**\n * Explicit choices, overriding any declared on the field manager.\n *\n * As soon as any choices are resolved, the editor becomes `select` and the\n * display becomes `choice`, whatever the manager advertises.\n */\n public choices = input<IDispEditChoice[]>([]);\n /**\n * CSS classes applied to the editor input.\n *\n * Left unset, it is filled in from the display config's per-editor defaults\n * (bootstrap 5 by default). Writable so that fallback can be stored back.\n */\n public inputClasses = model<string[] | string>();\n /** Forces an editor widget, bypassing the field manager's `editorType`. */\n public editor = input<DISPEDIT_EDITOR_TYPES>();\n /**\n * Forces a display renderer, bypassing the field manager's `displayType`.\n *\n * Writable because setting `[editor]=\"'quill'\"` without a viewer makes the\n * component select the `quill` viewer for you.\n */\n public viewer = model<DISPEDIT_DISPLAY_TYPES>();\n /**\n * Value applied by {@link setDefault} when the user clears the field.\n *\n * The reset control only appears in edit mode when this is not undefined.\n */\n public default = input<unknown>();\n /** Input placeholder. Falls back to the field manager's `description`. */\n public placeholder = input<string>('');\n /** Help text shown under the editor. Falls back to the manager's `help`. */\n public help = input<string>('');\n /** Suppresses the `<dt>` / `<label>`, keeping only the value or control. */\n public hideLabel = input<boolean>(false);\n\n // FK fields\n // TODO: rename as fk_ or related_\n /**\n * Queryset used to search FK / M2M candidates.\n *\n * Usually left unset: passing `[collection]` is the normal route, and the\n * child select derives a queryset from it.\n */\n public queryset = input<Queryset<R>>();\n /**\n * Collection the FK / M2M dropdown queries for candidates.\n *\n * This is what makes an FK or M2M editor work at all — without it the\n * dropdown has nothing to search.\n */\n public collection = input<Collection<R>>();\n /**\n * How to label each FK / M2M option: a property name, or a function of the\n * target instance.\n *\n * Only consulted when the target has no `_display`. Models used as FK targets\n * should define `_display` (a getter or a method — both are accepted) and\n * then this input is unnecessary. Without either, the fallback tries `name`,\n * then `title`, then `id`.\n */\n public display = input<string | TplFun<R>>();\n /**\n * Filter narrowing the FK / M2M lookup.\n *\n * Merged into every search request. The idiom\n * `[filter]=\"{fields: ['id','name'].join(',')}\"` trims the response payload\n * to the fields actually needed to render the options.\n */\n public filter = input<FilterData>({});\n\n /** Emits the model after every successful save. */\n public changed = output<T>();\n\n /** Field manager resolved from the model for {@link field}. */\n public manager = signal<BaseFieldManager<FT> | undefined>(undefined);\n\n /** Rendered text for single-valued displays. */\n public txtValue = signal<string | undefined>(undefined);\n /** Rendered text, one entry per item, for `m2mdetails` displays. */\n public txtValues = signal<string[] | undefined>(undefined);\n\n /** Editor actually in use, after manager lookup and overrides. */\n public realEditor = signal<DISPEDIT_EDITOR_TYPES>('input.text');\n /** Display renderer actually in use, after manager lookup and overrides. */\n public realDisplay = signal<DISPEDIT_DISPLAY_TYPES>('text');\n /** Raw field value backing the current display, before formatting. */\n public dispValue = signal<unknown>(undefined);\n /** Choices actually in use, or undefined when the field has none. */\n public realChoices = signal<IDispEditChoice[] | undefined>([]);\n /** Help text actually shown, after the manager fallback. */\n public realHelp = signal<string>('');\n /** Placeholder actually shown, after the manager fallback. */\n public realPlaceholder = signal<string>('');\n /** Whether the manager declares the field required. */\n public required = signal<boolean>(false);\n /** Default value actually applied by {@link setDefault}. */\n public realDefault = signal<unknown>(undefined);\n\n /** Latest M2M instances reported by the child select, used for display. */\n public m2mValues?: DataModel[];\n\n /** Form group driving the editor: the external `[form]`, or a local one. */\n public fg = signal<UntypedFormGroup | undefined>(undefined);\n\n /** Resolved display function for FK / M2M options, built from `display`. */\n private _tpl!: TplFun<R>;\n\n private _destroyRef = inject(DestroyRef);\n\n /**\n * Display config, overridable via the DATA_DISPLAY_CONFIG injection token.\n * By default, bs5 config is used.\n */\n public dconf = inject<DataDisplayConfig>(DATA_DISPLAY_CONFIG, { optional: true }) ?? BootstrapDataDisplayConfig;\n private _msgs = inject(DataMessageService);\n\n /**\n * Recompute all derived values / edit mode on any (trigger) input change.\n *\n * Only the read-only inputs are tracked here: the internally-mutated\n * `edit` / `viewer` / `inputClasses` models and the computed display\n * signals are read/written inside the recompute (via `untracked`) so their\n * internal writes don't re-trigger this effect (which would recreate the\n * form control on every write).\n */\n private _recomputeEffect = effect(() => {\n // Trigger inputs (establish reactive dependencies)\n this.model();\n this.field();\n this.form();\n this.editable();\n this.mode();\n this.choices();\n this.editor();\n this.default();\n this.placeholder();\n this.help();\n this.queryset();\n this.collection();\n this.display();\n this.filter();\n untracked(() => this._recompute());\n });\n\n /**\n * Upgrade all values on any change.\n * - Sets display function\n * - Loads manager\n * - Runs misc checks on special values\n * - Gets help, placeholder strings\n * - Enables display or edit mode\n */\n private _recompute(): void {\n this._setDisplayFn();\n this.manager.set(this.model()?.FM(this.field()));\n this.required.set(this.manager()?.required || false);\n this._checks();\n this.realHelp.set(this.help() || this.manager()?.help || '');\n this.realPlaceholder.set(this.placeholder() || this.manager()?.description || '');\n this.realDefault.set(this.default());\n this.save = this.save === undefined ? this.mode() === 'dd' : this.save;\n if ((!this.edit() && this.mode() === 'dd') || (!this.editable() && this.mode() === 'inline')) {\n this.enableDisplayMode();\n } else {\n this.enableEditMode();\n }\n }\n\n /**\n * Set up display mode.\n * - get choices if available\n * - get display type\n * - process current value for display\n * - set display classes\n */\n public enableDisplayMode() {\n this._getChoices();\n this._getRealDisplay();\n this._getDisplayValue();\n this._setDisplayClasses();\n this.edit.set(false);\n }\n\n /**\n * Set up edit mode :\n * - get choices if available\n * - get editor type\n * - prepare form controle\n * - set form control value\n * - update form control classes\n */\n public enableEditMode() {\n if (!this.editable()) {\n return;\n }\n this._getChoices();\n this._getRealEditor();\n this._setFormControl();\n this._setFormControlValue();\n this._setEditorClasses();\n this.edit.set(true);\n }\n\n /**\n * Write the form control value back to the model field, then save if\n * {@link save} is true (i.e. in `dd` mode).\n *\n * Does nothing when the control is invalid. For `input.decimal` editors the\n * value is multiplied by the manager's `factor` and rounded, restoring the\n * raw wire representation the model property is expected to hold.\n */\n public async update(): Promise<void> {\n const model = this.model();\n const fg = this.fg();\n if (fg && model && fg.valid) {\n switch (this.realEditor()) {\n case 'input.decimal':\n fieldValues(model)[this.field()] = Math.round(\n (fg.value as Record<string, number>)[this.field()] *\n ((this.manager() as unknown as DecimalFieldManager).factor || 1),\n );\n break;\n default:\n fieldValues(model)[this.field()] = fieldValues(fg.value as object)[this.field()];\n }\n if (this.save === true) {\n return this._save();\n }\n }\n }\n\n /**\n * Leave edit mode and drop the local form group, in `dd` mode only.\n *\n * Bound to the escape key in the editor templates; in other modes the editor\n * is permanent and the call is a no-op.\n */\n unsetEdit() {\n if (this.mode() == 'dd' && this.edit()) {\n this.edit.set(false);\n this.fg.set(undefined);\n }\n }\n\n /** Switch between display and edit mode. Bound to the `<dt>` label click. */\n toggleEdit() {\n if (!this.edit()) {\n this.enableEditMode();\n } else {\n this.unsetEdit();\n this.enableDisplayMode();\n }\n }\n\n /**\n * Reset the field to {@link default}, updating both the model and the form\n * control, then run {@link update} (which saves in `dd` mode).\n *\n * Bound to the trash icon shown next to the label in edit mode.\n * TODO: check if edit mode needs to be changed / saved\n */\n public async setDefault(): Promise<void> {\n const model = this.model();\n if (model) {\n fieldValues(model)[this.field()] = this.realDefault();\n this.fg()!.controls[this.field()].setValue(this.realDefault(), {\n emitEvent: false,\n });\n }\n await this.update();\n }\n\n /**\n * Handle an FK pick from the child `<data-fkselect>`, then save immediately.\n *\n * Writes the id to the model field and the whole instance to the\n * `<field>_details` sibling property, so the display has something to render\n * without refetching. A null event (the clear action) nulls the field and\n * deletes the sibling. When an external `[form]` is bound it is patched and\n * marked touched/dirty too. Note this saves regardless of {@link save}.\n *\n * @param $event selected instance, or null when the selection was cleared.\n */\n public async selectedRefItem($event: R | null) {\n const model = this.model();\n const form = this.form();\n if (model) {\n if ($event !== null) {\n fieldValues(model)[this.field()] = $event.id;\n fieldValues(model)[`${this.field()}_details`] = $event;\n if (form) {\n const fv: Record<string, number | null> = {};\n fv[this.field()] = $event.id;\n form.patchValue(fv, { emitEvent: true });\n form.markAsTouched();\n form.markAsDirty();\n }\n } else {\n fieldValues(model)[this.field()] = null;\n delete fieldValues(model)[`${this.field()}_details`];\n if (form) {\n const fv: Record<string, number | null> = {};\n fv[this.field()] = null;\n form.patchValue(fv, { emitEvent: true });\n form.markAsTouched();\n form.markAsDirty();\n }\n }\n return this._save();\n }\n }\n\n /**\n * Cache the M2M instances reported by the child select.\n *\n * These take precedence over `<field>_details` when building the\n * `m2mdetails` display, so it reflects edits made in the current session.\n *\n * @param v current list of selected instances.\n */\n public onM2MValuesChanges(v: DataModel[]) {\n this.m2mValues = v;\n }\n\n /** Apply cross-input consistency rules (a quill editor implies a quill viewer). */\n private _checks() {\n if (this.editor() === 'quill' && !this.viewer()) {\n this.viewer.set('quill');\n }\n }\n\n /**\n * Save value to database, only if model have an id.\n * If mode is dd, toggle edit / display mode.\n * @private\n */\n private async _save(): Promise<void> {\n const model = this.model();\n if (model) {\n if (model.id) {\n try {\n await firstValueFrom(model.update([this.field()], { updateModel: true }));\n } catch (e) {\n console.error(e);\n let msg = '';\n const apiErrors = (e as { error?: Record<string, unknown> } | null)?.error;\n if (apiErrors?.[this.field()]) {\n msg = `${String(apiErrors[this.field()])}`;\n }\n this._msgs.error(\"Erreur lors de l'enregistrement\", msg, JSON.stringify(e));\n return;\n }\n }\n if (this.mode() === 'dd') {\n this.unsetEdit();\n this.enableDisplayMode();\n }\n this.changed.emit(model);\n }\n }\n\n private _display(x: unknown): string {\n if (x) {\n const display = (x as { _display?: string | (() => string) })._display;\n if (display) {\n return typeof display === 'function' ? display() : display;\n }\n if (this._tpl) {\n return this._tpl(x as R);\n }\n }\n return '';\n }\n\n private _setDisplayFn() {\n const display = this.display();\n if (display) {\n if (typeof display === 'string') {\n this._tpl = (model: R) => String(fieldValues(model)[display]);\n } else if (typeof display === 'function') {\n this._tpl = display.bind(this);\n }\n } else {\n this._tpl = (model: R) =>\n String(fieldValues(model)['name'] ?? fieldValues(model)['title'] ?? fieldValues(model)['id']);\n }\n }\n\n private _getChoices() {\n // Set display choices\n let choices: IDispEditChoice[] | undefined;\n const inputChoices = this.choices();\n if (inputChoices && inputChoices.length) {\n choices = inputChoices;\n } else {\n const managerChoices = (this.manager() as { choices?: IDispEditChoice[] } | undefined)?.choices;\n if (managerChoices) {\n choices = managerChoices;\n }\n }\n // Set display value\n if (choices && choices.length > 0) {\n this.realChoices.set(choices);\n } else {\n this.realChoices.set(undefined);\n }\n }\n\n private _getRealDisplay() {\n const viewer = this.viewer();\n const manager = this.manager();\n const realChoices = this.realChoices();\n this.realDisplay.set(viewer ? viewer : manager?.displayType ? manager.displayType : 'text');\n if (realChoices && realChoices.length) {\n this.realDisplay.set('choice');\n }\n }\n\n private _getRealEditor() {\n const editor = this.editor();\n const realChoices = this.realChoices();\n this.realEditor.set(editor ? editor : this.manager()?.editorType || 'input.text');\n if (realChoices && realChoices.length) {\n this.realEditor.set('select');\n }\n }\n\n private _setFormControl() {\n const model = this.model();\n const form = this.form();\n let fg: UntypedFormGroup;\n if (!form) {\n const fgc: Record<string, UntypedFormControl> = {};\n fgc[this.field()] = model.FC(this.field());\n fg = new UntypedFormGroup(fgc);\n } else {\n fg = form;\n fg.setControl(this.field(), model.FC(this.field()), {\n emitEvent: false,\n });\n }\n this.fg.set(fg);\n if (this.mode() === 'inline') {\n fg.valueChanges.pipe(takeUntilDestroyed(this._destroyRef)).subscribe(() => {\n void this.update();\n });\n }\n }\n\n private _setFormControlValue() {\n const model = this.model();\n const field = this.field();\n const fg = this.fg()!;\n switch (this.realEditor()) {\n case 'input.datetime': {\n const value = fieldValues(model)[field] as string | number | Date | null;\n const now = new Date();\n const localnow = new Date(now.getTime() - now.getTimezoneOffset() * 60000);\n if (value === null) {\n fg.controls[field].setValue(null, { emitEvent: true });\n } else {\n const time = value ? new Date(value) : new Date();\n const offset = time.getTimezoneOffset();\n const localtime = new Date(time.getTime() - offset * 60000);\n fg.controls[field].setValue(localtime.toISOString().substring(0, 16), { emitEvent: true });\n }\n this.realDefault.set(\n this.default() || this.manager()?.required ? localnow.toISOString().substring(0, 16) : null,\n );\n break;\n }\n case 'input.date': {\n const dt = fieldValues(model.toJson([field]) as object)[field];\n fg.controls[field].setValue(dt);\n break;\n }\n case 'input.decimal':\n fg.controls[field].setValue(\n (fieldValues(model)[field] as number) / ((this.manager() as unknown as DecimalFieldManager).factor || 1),\n );\n }\n }\n\n private _setEditorClasses() {\n // FIXME: use realEditorClasses\n if (!this.inputClasses()) {\n this.inputClasses.set(this.dconf.dispEdit.inputClasses[this.realEditor()] || '');\n }\n }\n\n private _getDisplayValue() {\n const model = this.model();\n const field = this.field();\n const value = fieldValues(model)[field];\n this.dispValue.set(value);\n const realChoices = this.realChoices();\n if (realChoices) {\n for (const c of realChoices) {\n if (c === value) {\n this.txtValue.set(String(c.desc ?? c.value));\n return;\n } else if (c.value !== undefined && c.value === value) {\n this.txtValue.set(c.desc);\n return;\n }\n }\n }\n // Set display text depending on value and realDisplay value\n if (value === true) {\n this.txtValue.set('OUI');\n } else if (value === false) {\n this.txtValue.set('NON');\n } else if (value === undefined || value === null) {\n this.txtValue.set('non défini');\n } else {\n switch (this.realDisplay()) {\n case 'fkdetails': {\n const details = fieldValues(model)[`${field}_details`];\n this.txtValue.set(this._display(details));\n break;\n }\n case 'm2mdetails': {\n const m2mDetails = this.m2mValues || (fieldValues(model)[`${field}_details`] as DataModel[]);\n const tv: string[] = [];\n for (const v of m2mDetails || []) {\n tv.push(this._display(v));\n }\n this.txtValues.set(tv);\n break;\n }\n case 'decimal':\n this.txtValue.set(`${(value as number) / ((this.manager() as unknown as DecimalFieldManager).factor || 1)}`);\n break;\n default:\n this.txtValue.set(asText(value));\n }\n }\n }\n\n private _setDisplayClasses() {\n // Reserved: display classes are currently applied in the template.\n }\n}\n","<ng-template #titleTpl>\n <ng-content></ng-content>\n</ng-template>\n\n<!-- TEMPLATE affichage -->\n<ng-template #dispTpl>\n @switch (realDisplay()) {\n @case (\"text\") {\n <span\n class=\"editable disp-text\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n {{ txtValue() }}\n </span>\n }\n @case (\"choice\") {\n <span\n class=\"editable disp-choice\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n {{ txtValue() }}\n </span>\n }\n @case (\"decimal\") {\n <span\n class=\"editable disp-decimal\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n {{ txtValue() }}\n </span>\n }\n @case (\"boolean\") {\n <span\n class=\"editable disp-boolean\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n {{ txtValue() }}\n </span>\n }\n @case (\"fkdetails\") {\n <span\n class=\"editable disp-fkdetails\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n <div class=\"fkitem\">{{ txtValue() }}</div>\n </span>\n }\n @case (\"m2mdetails\") {\n <span\n class=\"editable disp-m2mdetails\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n @for (v of txtValues(); track v) {\n <div class=\"m2mitem\">{{ v }}</div>\n }\n </span>\n }\n @case (\"datetime\") {\n <span\n class=\"editable disp-datetime\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n @if (dispValue()) {\n {{ txtValue() | date: \"short\" }}\n }\n @if (!dispValue()) {\n {{ txtValue() }}\n }\n </span>\n }\n @case (\"date\") {\n <span\n class=\"editable disp-datetime\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n @if (dispValue()) {\n {{ txtValue() | date: \"shortDate\" }}\n }\n @if (!dispValue()) {\n {{ txtValue() }}\n }\n </span>\n }\n }\n</ng-template>\n\n<!-- TEMPLATE édition -->\n<ng-template #editTpl let-form=\"form\">\n @switch (realEditor()) {\n @case (\"input.text\") {\n <input\n [attr.id]=\"inputId\"\n type=\"text\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minlength']\"\n >\n Trop court : {{ $any(manager()).minLength }} caractères minimum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxlength']\"\n >\n Trop long : {{ $any(manager()).maxLength }} caractères maximum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['pattern']\"\n >\n Format invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.email\") {\n <input\n [attr.id]=\"inputId\"\n type=\"email\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minlength']\"\n >\n Trop court : {{ $any(manager()).minLength }} caractères minimum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxlength']\"\n >\n Trop long : {{ $any(manager()).maxLength }} caractères maximum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['pattern']\"\n >\n Format invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['email']\"\n >\n Format d'email invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.password\") {\n <input\n [attr.id]=\"inputId\"\n type=\"password\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minlength']\"\n >\n Trop court : {{ $any(manager()).minLength }} caractères minimum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxlength']\"\n >\n Trop long : {{ $any(manager()).maxLength }} caractères maximum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['pattern']\"\n >\n Format invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.datetime\") {\n <input\n [attr.id]=\"inputId\"\n type=\"datetime-local\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n (keyup.enter)=\"update()\"\n />\n <div class=\"form-text\">{{ realHelp() }}</div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minDate']\"\n >\n Doit être postérieur à {{ $any(manager()).min | date: \"short\" }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxDate']\"\n >\n Doit être antérieur à {{ $any(manager()).max | date: \"short\" }}...\n </div>\n }\n @case (\"input.date\") {\n <input\n [attr.id]=\"inputId\"\n type=\"date\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n (keyup.enter)=\"update()\"\n />\n <div class=\"form-text\">{{ realHelp() }}</div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minDate']\"\n >\n Doit être postérieur à {{ $any(manager()).min | date: \"short\" }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxDate']\"\n >\n Doit être antérieur à {{ $any(manager()).max | date: \"short\" }}...\n </div>\n }\n @case (\"input.number\") {\n <input\n [attr.id]=\"inputId\"\n type=\"number\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['min']\"\n >\n Trop petit : minimum {{ $any(manager()).min }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['max']\"\n >\n Trop grand : maximum {{ $any(manager()).max }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.decimal\") {\n <input\n [attr.id]=\"inputId\"\n type=\"number\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['min']\"\n >\n Trop petit : minimum {{ $any(manager()).min }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['max']\"\n >\n Trop grand : maximum {{ $any(manager()).max }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.checkbox\") {\n @let v = $any(this.model())[this.field()];\n <div class=\"btn-group btn-group-sm\" role=\"group\">\n <button\n type=\"button\"\n [class]=\"v === true ? 'btn btn-primary' : 'btn btn-outline-primary'\"\n (click)=\"form.get(field())?.setValue(true); update()\"\n (keyup.escape)=\"unsetEdit()\"\n >\n Oui\n </button>\n <button\n type=\"button\"\n [class]=\"v === false ? 'btn btn-primary' : 'btn btn-outline-primary'\"\n (click)=\"form.get(field())?.setValue(false); update()\"\n (keyup.escape)=\"unsetEdit()\"\n >\n Non\n </button>\n </div>\n <div class=\"form-text\">{{ realHelp() }}</div>\n }\n @case (\"textarea\") {\n <textarea\n [attr.id]=\"inputId\"\n [formControl]=\"form.get(field())\"\n (keyup.escape)=\"unsetEdit()\"\n [class]=\"inputClasses()\"\n (keyup.control.enter)=\"update()\"\n [placeholder]=\"realPlaceholder()\"\n ></textarea>\n @if (mode() === \"dd\") {\n <button class=\"btn btn-sm btn-link w-100 dispedit-text-update-button\" (click)=\"update()\">\n <i class=\"bi bi-save\"></i>\n </button>\n }\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minlength']\"\n >\n Trop court : {{ $any(manager()).minLength }} caractères minimum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxlength']\"\n >\n Trop long : {{ $any(manager()).maxLength }} caractères maximum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['pattern']\"\n >\n Format invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"fkselect\") {\n <data-fkselect\n [inputId]=\"inputId\"\n [collection]=\"collection()\"\n [filter]=\"filter()\"\n [display]=\"display()\"\n (selected)=\"selectedRefItem($event)\"\n [placeholder]=\"placeholder()\"\n (cancelled)=\"unsetEdit()\"\n (cleared)=\"selectedRefItem(null)\"\n ></data-fkselect>\n }\n @case (\"m2mselect\") {\n <data-m2mselect\n [inputId]=\"inputId\"\n [collection]=\"collection()\"\n [filter]=\"filter()\"\n (changed)=\"update()\"\n [formControl]=\"form.get(field())\"\n (detailsChanged)=\"onM2MValuesChanges($event)\"\n [model]=\"model()\"\n [field]=\"field()\"\n [placeholder]=\"placeholder()\"\n ></data-m2mselect>\n }\n @case (\"select\") {\n <select\n [attr.id]=\"inputId\"\n [formControl]=\"form.get(field())\"\n (keyup.escape)=\"unsetEdit()\"\n (change)=\"update()\"\n [class]=\"inputClasses()\"\n >\n @for (c of realChoices(); track c) {\n <option [ngValue]=\"c.value !== undefined ? c.value : c\">\n {{ c.desc ? c.desc : c }}\n </option>\n }\n </select>\n <div class=\"form-text\">{{ realHelp() }}</div>\n }\n }\n</ng-template>\n<!-- Disp/edit toggler-->\n<ng-template #dispeditTpl>\n @if (!edit()) {\n <ng-container *ngTemplateOutlet=\"dispTpl\"></ng-container>\n }\n @if (edit()) {\n @if (fg(); as fg) {\n <form [formGroup]=\"fg\" (submit)=\"update()\">\n <ng-container *ngTemplateOutlet=\"editTpl; context: { form: fg }\"></ng-container>\n </form>\n }\n }\n</ng-template>\n<!-- DispEdit noform-->\n<ng-template #dispeditFormTpl>\n @if (!edit()) {\n <ng-container *ngTemplateOutlet=\"dispTpl\"></ng-container>\n }\n @if (edit()) {\n @if (form()) {\n <ng-container *ngTemplateOutlet=\"editTpl; context: { form: form() }\"></ng-container>\n }\n }\n</ng-template>\n<!-- Dd display-->\n@if (mode() === \"dd\") {\n @if (!hideLabel()) {\n <dt [class.required]=\"required()\">\n <span\n class=\"editable\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"toggleEdit()\"\n (keydown.enter)=\"toggleEdit()\"\n (keydown.space)=\"$event.preventDefault(); toggleEdit()\"\n >\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </span>\n @if (realDefault() !== undefined && edit()) {\n <span\n class=\"pointer float-end\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Rétablir la valeur par défaut\"\n (click)=\"setDefault()\"\n (keydown.enter)=\"setDefault()\"\n (keydown.space)=\"$event.preventDefault(); setDefault()\"\n >\n <i class=\"bi bi-trash ms-2\"></i>\n </span>\n }\n </dt>\n }\n <dd [class.mb-0]=\"hideLabel()\">\n <ng-container *ngTemplateOutlet=\"dispeditTpl\"></ng-container>\n </dd>\n}\n<!-- Inline display-->\n@if (mode() === \"inline\") {\n @if (!hideLabel()) {\n @if (realDefault() !== undefined && edit()) {\n <span\n class=\"pointer float-end\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Rétablir la valeur par défaut\"\n (click)=\"setDefault()\"\n (keydown.enter)=\"setDefault()\"\n (keydown.space)=\"$event.preventDefault(); setDefault()\"\n >\n <i class=\"bi bi-trash ms-2\"></i>\n </span>\n }\n <label [class.required]=\"required()\" [attr.for]=\"inputId\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </label>\n }\n <ng-container *ngTemplateOutlet=\"dispeditTpl\"></ng-container>\n}\n<!-- Form display-->\n@if (mode() === \"form\") {\n @if (!hideLabel()) {\n @if (realDefault() !== undefined && edit()) {\n <span\n class=\"pointer float-end\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Rétablir la valeur par défaut\"\n (click)=\"setDefault()\"\n (keydown.enter)=\"setDefault()\"\n (keydown.space)=\"$event.preventDefault(); setDefault()\"\n >\n <i class=\"bi bi-trash ms-2\"></i>\n </span>\n }\n <label [class.required]=\"required()\" [attr.for]=\"inputId\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </label>\n }\n <ng-container *ngTemplateOutlet=\"dispeditFormTpl\"></ng-container>\n}\n","import { Component, DestroyRef, inject, input, model, OnInit, signal } from '@angular/core';\nimport { fieldValues } from '../../data/field-values';\n\nimport { DataModel } from '../../data/data-model';\nimport { debounceTime, firstValueFrom, Observable } from 'rxjs';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { DataMessageService } from '../../messages/message.service';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n/**\n * One available flag, as returned by the collection's flags endpoint.\n */\nexport interface IFlagItem {\n /** The flag value itself, as stored in the model's flags array. */\n flag: string;\n /** How many instances currently carry the flag; shown next to the option. */\n count: number;\n}\n\n@Component({\n selector: 'data-flags',\n imports: [ReactiveFormsModule],\n templateUrl: './flags.component.html',\n styleUrls: ['./flags.component.sass'],\n})\n/**\n * Displays and edits a `string[]` flags field as a set of badges.\n *\n * The list of flags available for selection is discovered at runtime rather\n * than declared: on first entering edit mode the component calls a collection\n * action (`get_flags` by default) and populates its dropdown from the result,\n * counts included. Users can also type a new flag, unless `[create]` is false.\n *\n * There are two persistence strategies, chosen by `[action]`:\n * - default: the flags array is written back to the model field and saved with\n * an ordinary field update.\n * - `[action]=\"true\"`: each change POSTs to the model's `add_flag` /\n * `remove_flag` actions instead, leaving the field update to the server.\n *\n * Either way the local badge list is updated optimistically, before the request\n * resolves.\n *\n * @example\n * ```html\n * <data-flags [model]=\"thing\" field=\"flags\">Flags</data-flags>\n * ```\n */\nexport class FlagsComponent<T extends DataModel> implements OnInit {\n /** Model instance carrying the flags field. Mandatory. */\n public model = input.required<T>();\n /** Name of the `string[]` field to edit. Defaults to `flags`. */\n public field = input<string>('flags');\n // FIXME: make all flags endpoint as optional parameters\n /**\n * Collection action queried (GET) for the list of available flags.\n *\n * Only consulted when `[flags]` is not supplied. The `add_flag` /\n * `remove_flag` action names used by `[action]` mode are not configurable.\n */\n public get_flags_endpoint = input<string>('get_flags');\n /** Whether the editor is shown. Two-way bindable; toggled by {@link toggleEdit}. */\n public edit = model<boolean>(false);\n /** Whether the field can be edited at all. Defaults to true. */\n public editable = input<boolean>(true);\n /**\n * Source of available flags, overriding the endpoint call.\n *\n * Writable because the component fills it in from the model's collection when\n * left unset. It is subscribed lazily, on first entering edit mode.\n */\n public flags = model<Observable<IFlagItem[]>>();\n /**\n * Free-entry mode: offer only a text input, with no dropdown of known flags.\n */\n public free = input<boolean>(false);\n /** Whether a text input for adding new flags is shown alongside the dropdown. */\n public create = input<boolean>(true);\n /**\n * Persist through the model's `add_flag` / `remove_flag` actions rather than\n * by updating the field.\n */\n public action = input<boolean>(false);\n /** Control for the free-text \"new flag\" input. */\n public ft!: FormControl<string | null>;\n /** Control for the known-flags dropdown; selecting a value adds it. */\n public fs!: FormControl<string | null>;\n /** Flags currently on the model, rendered as badges. */\n public curflags = signal<string[]>([]);\n /** Unused; kept for backwards compatibility. */\n public txtflag = '';\n /** Unused; kept for backwards compatibility. */\n public selflag = '';\n /** Available flags, fetched on first entering edit mode. */\n public flaglist = signal<IFlagItem[]>([]);\n private destroy$ = inject(DestroyRef);\n private _msg = inject(DataMessageService);\n\n /**\n * Resolve the flags source from the model's collection, seed the badge list\n * from the model field, and wire the dropdown so that selecting a value adds\n * the flag (debounced 250ms).\n */\n public ngOnInit(): void {\n const model = this.model();\n if (!this.flags() && model._collection) {\n this.flags.set(model._collection.action(null, 'GET', this.get_flags_endpoint()));\n }\n const flags = model && this.field() && fieldValues(model)[this.field()];\n if (flags) {\n this.curflags.set(flags as string[]);\n } else {\n console.warn('Model or field problem in flagsfield component');\n this.curflags.set([]);\n }\n this.ft = new FormControl<string | null>('');\n this.fs = new FormControl<string | null>('');\n this.fs.valueChanges.pipe(takeUntilDestroyed(this.destroy$), debounceTime(250)).subscribe((value) => {\n if (value) {\n void this.addFlag(value);\n }\n });\n }\n\n /** Add the flag currently typed in the free-text input. */\n public async addFreeFlag(): Promise<void> {\n await this.addFlag(this.ft.value ?? '');\n }\n\n /**\n * Add a flag and persist, unless it is already present.\n *\n * Persists via the model's `add_flag` action when `[action]` is set, else by\n * saving the whole field through {@link update}.\n *\n * @param flag flag value to add.\n */\n public async addFlag(flag: string): Promise<void> {\n if (!this.flagPresent(flag)) {\n this.curflags.update((c) => [...c, flag]);\n if (this.action()) {\n try {\n await firstValueFrom(this.model().action('POST', 'add_flag', { body: { flag } }));\n this._msg.success('Flag enregistré avec succès');\n } catch (e) {\n this._msg.error('Erreur lors de la sauvegarde', String(e));\n }\n } else {\n await this.update();\n }\n }\n }\n\n /**\n * Write the current flags back to the model field and save it, then reset\n * both inputs. Reports success or failure through the message service.\n */\n public async update(): Promise<void> {\n fieldValues(this.model())[this.field()] = this.curflags();\n try {\n await firstValueFrom(this.model().update([this.field()]));\n this.fs.setValue('', { emitEvent: false });\n this.ft.setValue('', { emitEvent: false });\n this._msg.success('Flag enregistré avec succès');\n } catch (error) {\n this._msg.error(\n 'Erreur lors de la sauvegarde',\n `API Return : ${String(error)}`,\n (error as { _body?: string })._body,\n );\n }\n }\n\n /**\n * Whether the flag is already on the model.\n *\n * @param flag flag value to look for.\n */\n public flagPresent(flag: string): boolean {\n return this.curflags().findIndex((f) => flag === f) !== -1;\n }\n\n /**\n * Remove a flag and persist, via the model's `remove_flag` action when\n * `[action]` is set, else by saving the whole field through {@link update}.\n *\n * @param flag flag value to remove.\n */\n public async removeFlag(flag: string): Promise<void> {\n this.curflags.update((c) => c.filter((f) => f !== flag));\n if (this.action()) {\n try {\n await firstValueFrom(this.model().action('POST', 'remove_flag', { body: { flag } }));\n this._msg.success('Removed');\n } catch (e) {\n this._msg.error('Removing flag failed', String(e));\n }\n } else {\n await this.update();\n }\n }\n\n /**\n * Switch between badge display and the editor.\n *\n * Entering edit mode resolves the available flags list first, so the dropdown\n * is populated. Does nothing but force display mode when `[editable]` is\n * false.\n */\n public async toggleEdit() {\n if (this.editable()) {\n if (!this.edit()) {\n this.flaglist.set(await firstValueFrom(this.flags()!));\n this.edit.set(true);\n } else {\n this.edit.set(false);\n }\n } else {\n this.edit.set(false);\n }\n }\n}\n","<dt\n (click)=\"toggleEdit()\"\n role=\"button\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleEdit()\"\n (keydown.space)=\"$event.preventDefault(); toggleEdit()\"\n>\n <ng-content></ng-content>\n</dt>\n@if (!edit()) {\n <dd\n (click)=\"toggleEdit()\"\n role=\"button\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleEdit()\"\n (keydown.space)=\"$event.preventDefault(); toggleEdit()\"\n >\n @for (flag of curflags(); track flag) {\n <span class=\"badge bg-info me-1\">{{ flag }}</span>\n }\n </dd>\n}\n@if (edit()) {\n <dd>\n <div class=\"row\">\n @if (!free()) {\n <div class=\"col\">\n <select class=\"form-select form-select-sm\" [formControl]=\"fs\">\n @for (flag of flaglist(); track flag) {\n <option [value]=\"flag.flag\">\n {{ flag.flag }}\n @if (flag.count) {\n <span class=\"ms-1\">({{ flag.count }})</span>\n }\n </option>\n }\n </select>\n </div>\n @if (create()) {\n <div class=\"col\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Nouveau flag\"\n [formControl]=\"ft\"\n (keyup.enter)=\"addFreeFlag()\"\n />\n </div>\n }\n }\n @if (free()) {\n <div class=\"col-12\">\n <input\n class=\"form-control form-select-sm\"\n placeholder=\"Nouveau flag\"\n [formControl]=\"ft\"\n (keyup.enter)=\"addFreeFlag()\"\n (keyup.escape)=\"toggleEdit()\"\n />\n </div>\n }\n </div>\n <div class=\"row\">\n <div class=\"col-sm-12\">\n @for (flag of curflags(); track flag) {\n <span\n class=\"badge bg-info me-1\"\n (click)=\"removeFlag(flag)\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer le flag ' + flag\"\n (keydown.enter)=\"removeFlag(flag)\"\n (keydown.space)=\"$event.preventDefault(); removeFlag(flag)\"\n >\n <i class=\"bi bi-trash me-1\"></i>\n {{ flag }}\n </span>\n }\n <i\n class=\"bi bi-x-lg text-muted ms-2\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Fermer l'édition\"\n (click)=\"toggleEdit()\"\n (keydown.enter)=\"toggleEdit()\"\n (keydown.space)=\"$event.preventDefault(); toggleEdit()\"\n ></i>\n </div>\n </div>\n </dd>\n}\n","import { Component, ElementRef, inject, input, output, signal, ViewChild } from '@angular/core';\nimport { DataModel } from '../../data/data-model';\nimport { Collection } from '../../data/data-collection';\nimport { firstValueFrom } from 'rxjs';\nimport { NgbOffcanvas, NgbOffcanvasModule, NgbOffcanvasRef } from '@ng-bootstrap/ng-bootstrap';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { DataMessageService } from '../../messages/message.service';\n\n/** The two places an API error puts its human-readable message. */\ninterface IApiMessage {\n message?: string;\n error?: { message?: string };\n}\n\n/**\n * What a dry-run delete reports back: the blast radius of the real deletion.\n */\nexport interface FakeDeleteResult {\n /** Total number of database objects that would be removed. */\n count: number;\n /** Per-type breakdown, as `[object type name, count]` pairs. */\n details: [string, number][];\n}\n\n@Component({\n selector: 'data-safe-delete',\n templateUrl: './sdelete.component.html',\n styleUrls: ['./sdelete.component.sass'],\n imports: [NgTemplateOutlet, NgbOffcanvasModule],\n})\n/**\n * \"Safe delete\": a delete control that makes the user confirm what they are\n * about to destroy, cascade included.\n *\n * The flow is two round-trips. Clicking the control first sends a dry-run\n * delete (`doit: 'no'`), which the API answers with a {@link FakeDeleteResult}\n * counting everything that would be removed. That breakdown is shown in an\n * offcanvas panel, per object type, with `[checks]` translating database names\n * into human ones. Only if the user then confirms does a second, real delete go\n * out (`doit: 'really'`), and {@link deleted} fire.\n *\n * The dry run means the API must understand the `doit` parameter; `[actionFn]`\n * replaces the second step for models that delete differently.\n *\n * @example\n * ```html\n * <data-safe-delete [model]=\"thing\" (deleted)=\"reload()\">Delete</data-safe-delete>\n * ```\n */\nexport class SafeDeleteComponent<T extends DataModel> {\n /** Model instance to be deleted */\n public model = input.required<T>();\n /** Service to be used for deletion, taken from model if not provided */\n public service = input<Collection<T>>();\n /** Function to be called for deletion, overrides service deletion */\n public actionFn = input<(model: T) => Promise<{ success: boolean }>>();\n /** Translations of database objects names to human names */\n public checks = input<Record<string, string>>({});\n /** Messages to be displayed on success or error, default messages are used if not provided */\n public messages = input<{ success?: string; error?: string }>({});\n /** Event emitted on successful deletion */\n public deleted = output<FakeDeleteResult>();\n /** Display mode, default is button.\n *\n * - `fbutton`: floating button (small)\n * - `button`: button (small), with text taken from ng-content (no space around icon to allow empty buttons)\n * - `icon`: icon\n * - `custom`: custom : ng-content is surrounded by a clickable div\n * */\n public display = input<'fbutton' | 'button' | 'icon' | 'custom'>('button');\n\n /** Dry-run result driving the confirmation panel. */\n public result = signal<FakeDeleteResult | undefined>(undefined);\n @ViewChild('dialog', { static: true })\n private _dialogRef?: ElementRef<HTMLDivElement>;\n private ofc?: NgbOffcanvasRef;\n private _ofc = inject(NgbOffcanvas);\n private _msgs = inject(DataMessageService);\n\n /**\n * First step: run the dry-run delete and open the confirmation panel with its\n * result. Nothing is destroyed here.\n *\n * @param _model unused; the component always acts on its own `[model]` input.\n */\n public async checkDelete(_model: DataModel) {\n const service = this.service() || this.model()._collection;\n if (service) {\n try {\n this.result.set(\n (await firstValueFrom(service.delete(this.model(), { params: { doit: 'no' } }))) as FakeDeleteResult,\n );\n\n this.ofc = this._ofc.open(this._dialogRef, {\n position: 'end',\n });\n } catch (e) {\n console.error(e);\n if (this.messages().error) {\n this._msgs.error(\n this.messages().error!,\n (e as IApiMessage).error?.message || (e as IApiMessage).message || '',\n );\n }\n }\n }\n }\n\n /**\n * Second step: perform the actual deletion once the user has confirmed, then\n * close the panel and emit {@link deleted} with the dry-run result.\n *\n * Uses `[actionFn]` when provided, otherwise deletes through the service with\n * `doit: 'really'`. Nothing is emitted if the deletion fails.\n */\n public async reallyDelete() {\n const actionFn = this.actionFn();\n if (actionFn) {\n const res = await actionFn(this.model());\n if (res.success && this.messages().success) {\n this._msgs.success(this.messages().success!);\n } else if (!res.success && this.messages().error) {\n this._msgs.error(this.messages().error!);\n }\n this.ofc?.close();\n if (res.success) {\n this.deleted.emit(this.result()!);\n }\n } else {\n const service = this.service() || this.model()._collection;\n if (service) {\n try {\n this.result.set(\n (await firstValueFrom(service.delete(this.model(), { params: { doit: 'really' } }))) as FakeDeleteResult,\n );\n if (this.messages().success) {\n this._msgs.success(this.messages().success!);\n }\n this.ofc?.close();\n this.deleted.emit(this.result()!);\n } catch (e) {\n console.error(e);\n if (this.messages().error) {\n this._msgs.error(\n this.messages().error!,\n (e as IApiMessage).error?.message || (e as IApiMessage).message || '',\n );\n }\n }\n }\n }\n }\n}\n","<ng-template #dialog let-offcanvas>\n <div class=\"offcanvas-header\">\n <h2 class=\"offcanvas-title text-danger text-center\">\n <i class=\"bi bi-trash me-2\"></i>\n Supprimer réellement ??\n </h2>\n </div>\n @if (result(); as result) {\n <div class=\"offcanvas-body text-danger\">\n <div class=\"text-center my-4 fs-1\">\n <i class=\"bi bi-exclamation-diamond my-5\"></i>\n </div>\n <div class=\"fs-4\">\n <p>La suppression de cet élément supprimera {{ result.count }} éléments dans la base de données..</p>\n </div>\n <table class=\"table table-sm table-striped table-danger\">\n <thead>\n <tr>\n <th>Type d'élément</th>\n <th>Nombre</th>\n </tr>\n </thead>\n <tbody>\n @for (rl of result.details; track rl) {\n <tr>\n <td>{{ checks()[rl[0]] ? checks()[rl[0]] : rl[0] }}</td>\n <td>{{ rl[1] }}</td>\n </tr>\n }\n </tbody>\n </table>\n <button class=\"w-100 btn btn-lg btn-danger\" (click)=\"reallyDelete()\">\n <i class=\"bi bi-trash me-2\"></i>\n Je confirme la suppression\n </button>\n <button class=\"w-100 btn btn-outline-secondary my-3\" (click)=\"offcanvas.close()\">\n <i class=\"bi bi-door-open me-2\"></i>\n Je renonce à la suppression\n </button>\n </div>\n }\n</ng-template>\n<ng-template #contentTpl>\n <ng-content></ng-content>\n</ng-template>\n@if (display() === \"button\") {\n <button class=\"btn btn-sm btn-danger\" (click)=\"checkDelete(model())\">\n <i class=\"bi bi-trash\"></i>\n <ng-container *ngTemplateOutlet=\"contentTpl\"></ng-container>\n </button>\n}\n@if (display() === \"fbutton\") {\n <button class=\"btn btn-sm btn-outline-danger float-end\" (click)=\"checkDelete(model())\">\n <i class=\"bi bi-trash mx-2\"></i>\n </button>\n}\n@if (display() === \"icon\") {\n <i\n class=\"bi bi-trash mx-2\"\n (click)=\"checkDelete(model())\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Supprimer\"\n (keydown.enter)=\"checkDelete(model())\"\n (keydown.space)=\"$event.preventDefault(); checkDelete(model())\"\n ></i>\n}\n@if (display() === \"custom\") {\n <div\n (click)=\"checkDelete(model())\"\n role=\"button\"\n tabindex=\"0\"\n (keydown.enter)=\"checkDelete(model())\"\n (keydown.space)=\"$event.preventDefault(); checkDelete(model())\"\n >\n <ng-container *ngTemplateOutlet=\"contentTpl\"></ng-container>\n </div>\n}\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\nimport { ValidatorFn, Validators } from '@angular/forms';\nimport { DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\nimport { asText } from '../field-values';\n\n/**\n * A choice with a separate stored value and human label: `value` is what\n * travels to the API, `desc` is what the user sees.\n */\nexport interface ICharFieldDescChoice {\n /** The value stored on the model and sent to the API. */\n value: string;\n /** The human-readable label shown for that value. */\n desc: string;\n}\n\n/**\n * One entry of a `choices` list — either a `{value, desc}` pair, or a bare\n * string used as both the stored value and its own label.\n */\nexport type ICharFieldChoice = ICharFieldDescChoice | string;\n\n/**\n * Options for {@link charField} and, by extension, every other string field.\n */\nexport interface ICharFieldMetadata extends IFieldMetadata<string> {\n /** Minimum length; adds `Validators.minLength`. Ignored when `0`. */\n minLength?: number;\n /** Maximum length; adds `Validators.maxLength`. Ignored when `0`. */\n maxLength?: number;\n /** Regexp the value must match; adds `Validators.pattern`. */\n pattern?: RegExp | string;\n /**\n * Allowed values. Setting this switches the editor to a `'select'` dropdown.\n *\n * Note it is *not* enforced by a validator: choices shape the UI, they do\n * not currently reject an off-list value assigned in code.\n */\n choices?: ICharFieldChoice[];\n}\n\n/**\n * Options for {@link emailField}.\n */\nexport interface IEmailFieldMetadata extends ICharFieldMetadata {\n /** Apply `Validators.email`. Defaults to `true`. */\n validate?: boolean;\n}\n\n/**\n * Options for {@link passwordField}.\n */\nexport interface IPasswordFieldMetadata extends ICharFieldMetadata {\n /** Declarative only: `PasswordFieldManager` adds no validator of its own. */\n validate?: boolean;\n}\n\n/**\n * Options for {@link textField}.\n */\nexport interface ITextFieldMetadata extends ICharFieldMetadata {\n /**\n * Content syntax hint (e.g. markdown) for renderers. Carried as metadata;\n * the manager itself does not act on it.\n */\n syntax?: string;\n}\n\n/**\n * Manager for single-line string fields, and base for every other string\n * field type. Adds length and pattern validators, coerces incoming JSON to a\n * string, and switches {@link BaseFieldManager.editorType} to `'select'` when\n * `choices` is declared.\n */\nexport class CharFieldManager extends BaseFieldManager<string> {\n /** Minimum length; adds `Validators.minLength`. */\n declare public minLength?: number;\n /** Maximum length; adds `Validators.maxLength`. */\n declare public maxLength?: number;\n /** Allowed values; their presence switches the editor to a `'select'`. */\n declare public choices?: ICharFieldChoice[];\n /** Regexp the value must match; adds `Validators.pattern`. */\n declare public pattern?: RegExp | string;\n\n /**\n * Builds the manager and, when `choices` were declared, promotes the editor\n * from a free-text input to a dropdown.\n */\n constructor(params: ICharFieldMetadata) {\n super(params);\n if (this.choices) {\n this.editorType = 'select';\n }\n }\n\n /** Required, plus minLength / maxLength / pattern when declared. */\n public override get validators(): ValidatorFn[] {\n const v = super.getValidators();\n if (this.minLength) {\n v.push(Validators.minLength(this.minLength));\n }\n if (this.maxLength) {\n v.push(Validators.maxLength(this.maxLength));\n }\n if (this.pattern) {\n v.push(Validators.pattern(this.pattern));\n }\n // TODO: add choices validator ??\n return v;\n }\n\n /**\n * Coerces the incoming value to a string: `null` and `undefined` both yield\n * the field's default value, a string is kept as-is, and anything else is\n * interpolated (`42` → `'42'`).\n *\n * @param data raw value read from the JSON payload\n */\n public override fromJson(data: unknown): string {\n if (data === undefined) {\n return this.getDefaultValue()!;\n }\n if (data === null) {\n return this.getDefaultValue()!;\n }\n if (typeof data === 'string') {\n return data;\n }\n return asText(data);\n }\n}\n\n/**\n * Manager for email fields: renders an `input.email` editor and, unless\n * `validate: false`, applies `Validators.email`.\n *\n * Caveat, as currently implemented: its validator list is built from the\n * *base* manager, so it is `required` + `email` only. `minLength`,\n * `maxLength` and `pattern` declared on an `emailField` are **not** enforced,\n * even though the options are accepted.\n */\nexport class EmailFieldManager extends CharFieldManager implements ICharFieldMetadata {\n /** Whether `Validators.email` is applied. Defaults to `true`. */\n public validate = true;\n /** Renders an `input.email` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.email';\n\n /**\n * Builds the manager, defaulting {@link validate} to `true` when it was not\n * declared.\n */\n constructor(params: IEmailFieldMetadata) {\n super(params);\n if (this.validate === undefined) {\n this.validate = true;\n }\n }\n\n /**\n * `Validators.required` (when required) plus `Validators.email` (when\n * `validate`). Does not include the char-level length/pattern validators.\n */\n public override get validators(): ValidatorFn[] {\n const v = super.getValidators();\n if (this.validate) {\n // eslint-disable-next-line @typescript-eslint/unbound-method -- Validators.* are static and `this`-free\n v.push(Validators.email);\n }\n return v;\n }\n}\n\n/**\n * Manager for long-form text: a `CharFieldManager` rendered as a `textarea`.\n * Validation and serialisation are unchanged.\n */\nexport class TextFieldManager extends CharFieldManager {\n /** Content syntax hint (e.g. markdown) for renderers. */\n declare public syntax?: string;\n /** Renders a multi-line `textarea` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'textarea';\n}\n\n/**\n * Manager for password input: a `CharFieldManager` rendered as an\n * `input.password` (masked). It only changes the widget — the value is held\n * and transmitted as an ordinary string, with no hashing or extra validation.\n */\nexport class PasswordFieldManager extends CharFieldManager {\n /** Declarative only; unused by this manager. */\n declare public syntax?: string;\n /** Renders a masked `input.password` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.password';\n}\n\n/**\n * Declares a single-line string field — the default choice for any short text\n * value. Renders a text input, or a dropdown as soon as `choices` is given.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @charField({ description: 'Name', maxLength: 100 })\n * public name!: string;\n *\n * // `choices` alone switches the editor to a select\n * @charField({\n * description: 'Status',\n * defaultValue: 'draft',\n * choices: [\n * { value: 'draft', desc: 'Draft' },\n * { value: 'live', desc: 'Live' },\n * ],\n * })\n * public status!: string;\n * }\n */\nexport const charField = (updates: ICharFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'charField', CharFieldManager);\n\n/**\n * Declares an email field: a string rendered with an `input.email` editor and\n * validated with `Validators.email` unless `validate: false`.\n *\n * Note that `minLength`/`maxLength`/`pattern` are accepted but not enforced\n * here — see {@link EmailFieldManager}.\n *\n * @param updates field options\n */\nexport const emailField = (updates: IEmailFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'emailField', EmailFieldManager);\n\n/**\n * Declares a multi-line string field, rendered as a `textarea`. Reach for it\n * instead of {@link charField} for descriptions, notes and other long-form\n * content; behaviour is otherwise identical.\n *\n * @param updates field options\n */\nexport const textField = (updates: ITextFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'textField', TextFieldManager);\n\n/**\n * Declares a string field rendered with a masked `input.password` editor.\n * Masking is all it does: the value is stored and sent in clear, so treat it\n * as a UI affordance and not as a security measure.\n *\n * @param updates field options\n */\nexport const passwordField = (updates: IPasswordFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'passwordField', PasswordFieldManager);\n","import { BaseFieldManager, FieldDefaultArgs, genericDataField, IFieldMetadata } from './base';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\nimport { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\n/**\n * Options for {@link dateField}.\n */\nexport interface IDateFieldMetadata extends IFieldMetadata<Date | null> {\n /**\n * When no `defaultValue` is declared, use the current date as the default\n * instead of `null`. Note this only seeds the value on the client; it does\n * not re-stamp the field on every save.\n */\n autoNow?: boolean;\n /**\n * Same effect as {@link autoNow} in the current implementation: both flags\n * are tested together, so either one makes the default `new Date()`.\n */\n autoNowAdd?: boolean;\n /** Lower bound; adds {@link dateMinimum}. Exclusive — equal dates are rejected. */\n min?: Date;\n /** Upper bound; adds {@link dateMaximum}. Exclusive — equal dates are rejected. */\n max?: Date;\n}\n\n/**\n * Builds a validator rejecting any date that is not **strictly after** `date`.\n *\n * The bound is exclusive: the control is valid only when\n * `controlDate > date`, so a value exactly equal to `date` fails with a\n * `minDate` error. Empty controls (`null` / `undefined`) always pass —\n * emptiness is `required`'s business, not this validator's.\n *\n * @param date exclusive lower bound\n * @returns a `ValidatorFn` yielding `{minDate: {'date-minimum', actual}}` on failure\n */\nexport const dateMinimum = (date: Date): ValidatorFn => {\n return (control: AbstractControl): ValidationErrors | null => {\n if (control.value == null) {\n return null;\n }\n\n const controlDate = new Date(control.value as string | number | Date);\n\n const validationDate = date;\n\n return controlDate > validationDate\n ? null\n : {\n minDate: {\n 'date-minimum': validationDate,\n actual: controlDate,\n },\n };\n };\n};\n\n/**\n * Builds a validator rejecting any date that is not **strictly before**\n * `date`.\n *\n * As with {@link dateMinimum} the bound is exclusive: valid only when\n * `controlDate < date`, so a value exactly equal to `date` fails with a\n * `maxDate` error. Empty controls always pass.\n *\n * @param date exclusive upper bound\n * @returns a `ValidatorFn` yielding `{maxDate: {'date-maximum', actual}}` on failure\n */\nexport const dateMaximum = (date: Date): ValidatorFn => {\n return (control: AbstractControl): ValidationErrors | null => {\n if (control.value == null) {\n return null;\n }\n const controlDate = new Date(control.value as string | number | Date);\n const validationDate = date;\n\n return controlDate < validationDate\n ? null\n : {\n maxDate: {\n 'date-maximum': validationDate,\n actual: controlDate,\n },\n };\n };\n};\n\n/**\n * Options for {@link datetimeField}.\n */\nexport interface IDatetimeFieldMetadata extends IDateFieldMetadata {\n /**\n * How the wire format is interpreted and produced.\n *\n * - omitted / `null`: values are treated as **local time**. Any `Z` suffix\n * or `±HHMM` offset in the incoming string is stripped before parsing, and\n * `toJson` emits an offset-less ISO string shifted to local time.\n * - `'UTC'`: values are parsed as-is and serialised with `toISOString()`\n * (trailing `Z`).\n * - any other string: parsed as-is; on save the literal is appended to an\n * offset-less ISO string, so it must be a valid ISO offset like `'+0200'`.\n */\n timezone?: string | null;\n}\n\n/**\n * Manager for calendar dates (no time component). Parses anything the `Date`\n * constructor accepts, serialises back to a `YYYY-M-D` string built from\n * **UTC** parts, and adds exclusive `min`/`max` validators.\n *\n * It also overrides default-value resolution so that `autoNow`/`autoNowAdd`\n * yield the current date, and an undeclared default is `null` rather than\n * `undefined`.\n */\nexport class DateFieldManager extends BaseFieldManager<Date | null> implements IDateFieldMetadata {\n /** Default to the current date when no `defaultValue` is declared. */\n public autoNow = false;\n /** Equivalent to {@link autoNow}; both are tested together. */\n public autoNowAdd = false;\n /** Exclusive lower bound; adds {@link dateMinimum}. */\n declare public min?: Date;\n /** Exclusive upper bound; adds {@link dateMaximum}. */\n declare public max?: Date;\n /** Renders an `input.date` editor (no time component). */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.date';\n /** Rendered by the `date` display. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'date';\n\n /**\n * Builds the manager from the declared date options.\n *\n * @param params field options as passed to the decorator\n */\n constructor(params: IDateFieldMetadata) {\n super(params);\n }\n\n /** Required, plus {@link dateMinimum} / {@link dateMaximum} when declared. */\n public override get validators(): ValidatorFn[] {\n const v = super.validators;\n if (this.min) {\n v.push(dateMinimum(this.min));\n }\n if (this.max) {\n v.push(dateMaximum(this.max));\n }\n return v;\n }\n\n /**\n * Parses the incoming value with the `Date` constructor. `null`,\n * `undefined` and anything that parses to an invalid date all yield `null`,\n * so a malformed payload degrades to an empty field rather than throwing.\n *\n * @param data raw value read from the JSON payload\n */\n public override fromJson(data: unknown): Date | null {\n if (data === null || data === undefined) {\n return null;\n }\n const date = new Date(data as string | number | Date);\n if (date instanceof Date && !isNaN(date.getTime())) {\n return date;\n }\n return null;\n }\n\n /**\n * Serialises to a `YYYY-M-D` date string assembled from the **UTC** parts of\n * the value, dropping the time. Strings are re-parsed first; `null` and\n * `undefined` yield `null`.\n *\n * The parts are not zero-padded, so this emits `2024-1-5` rather than\n * `2024-01-05`.\n *\n * @param data current model value\n */\n public override toJson(data: Date | string | null): null | string {\n if (data === null || data === undefined) {\n return null;\n }\n if (typeof data === 'string') {\n const d = this.fromJson(data);\n if (d === null) {\n return null;\n }\n data = d;\n }\n return `${data.getUTCFullYear()}-${data.getUTCMonth() + 1}-${data.getUTCDate()}`;\n }\n\n /**\n * Resolves the default value, adding date-specific behaviour on top of the\n * base rules: a `defaultValue` function is called, a `required` field with\n * no default still throws, and an undeclared default resolves to\n * `new Date()` when `autoNow`/`autoNowAdd` is set, or `null` otherwise\n * (never `undefined`).\n *\n * @param args passed through to a `defaultValue` function\n * @throws Error if `required` is set and `defaultValue` is `undefined`\n * @protected\n */\n protected override getDefaultValue(args: FieldDefaultArgs = {}): Date | null | undefined {\n if (this.defaultValue instanceof Function) {\n return this.defaultValue(args);\n }\n if (this.required && this.defaultValue === undefined) {\n throw new Error(`Field ${this.name} : no default value for required field`);\n }\n if (this.defaultValue === undefined) {\n return this.autoNow || this.autoNowAdd ? new Date() : null;\n }\n return this.defaultValue;\n }\n}\n\n/**\n * Manager for date+time fields. Extends {@link DateFieldManager} with\n * timezone-aware (de)serialisation driven by\n * {@link IDatetimeFieldMetadata.timezone}, and switches to the\n * `input.datetime` / `datetime` widgets.\n *\n * Its default mode — no `timezone` — is deliberately *naive*: offsets are\n * stripped on read and never emitted on write, so wall-clock times round-trip\n * unshifted. Set `timezone: 'UTC'` when the instant matters more than the\n * wall-clock reading.\n */\nexport class DatetimeFieldManager extends DateFieldManager implements IDatetimeFieldMetadata {\n /** Wire timezone handling. See {@link IDatetimeFieldMetadata.timezone}. */\n declare public timezone?: string | null;\n /** Renders an `input.datetime` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.datetime';\n /** Rendered by the `datetime` display. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'datetime';\n\n /**\n * Builds the manager from the declared datetime options, `timezone`\n * included.\n *\n * @param params field options as passed to the decorator\n */\n constructor(params: IDatetimeFieldMetadata) {\n super(params);\n }\n\n /**\n * Serialises to an ISO 8601 string, shaped by `timezone`: naive local time\n * with no suffix when unset, `toISOString()` when `'UTC'`, or an\n * offset-less ISO string with the configured offset appended otherwise.\n * Strings are re-parsed first; `null`/`undefined` yield `null`.\n *\n * Never throws: a value that cannot be serialised is logged and `null` is\n * returned instead.\n *\n * @param data current model value\n */\n public override toJson(data: Date | string): string | null {\n if (data === null || data === undefined) {\n return null;\n }\n if (typeof data === 'string') {\n const d = this.fromJson(data);\n if (d === null) {\n return null;\n }\n data = d;\n }\n try {\n if (this.timezone === null || this.timezone === undefined) {\n const offset = data.getTimezoneOffset();\n const localDate = new Date(data.getTime() - offset * 60000);\n return localDate.toISOString().replace('Z', '');\n } else if (this.timezone === 'UTC') {\n return data.toISOString();\n } else {\n return data.toISOString().replace('Z', '') + this.timezone;\n }\n } catch (e) {\n console.error(e, data);\n return null;\n }\n }\n\n /**\n * Parses the incoming value into a `Date`, honouring `timezone`.\n *\n * With no `timezone` configured, incoming strings are read as local time:\n * a trailing `Z` or a `±HHMM` offset is stripped before parsing, so\n * `'2018-12-10T13:45:00Z'` yields 13:45 *local*, not 13:45 UTC. With a\n * `timezone` set, the string is handed to `Date` untouched. `null`,\n * `undefined` and unparseable values yield `null`.\n *\n * @param data raw value read from the JSON payload\n */\n public override fromJson(data: unknown): Date | null {\n if (data === null || data === undefined) {\n return null;\n }\n let date: Date;\n if (typeof data === 'string') {\n // If we don't have timezone info, we parse all dates as local\n if (this.timezone === null || this.timezone === undefined) {\n if (data.endsWith('Z')) {\n date = new Date(data.replace('Z', ''));\n } else if (data.match(/[-+]\\d{4}$/)) {\n date = new Date(data.replace(/[-+]\\d{4}$/, ''));\n } else {\n date = new Date(data);\n }\n } else {\n date = new Date(data);\n }\n } else {\n date = new Date(data as string | number | Date);\n }\n\n if (date instanceof Date && !isNaN(date.getTime())) {\n return date;\n }\n return null;\n }\n}\n\n/**\n * Declares a calendar-date field (no time of day) — birth dates, due dates,\n * anything where the time component would be noise. Held as a `Date`, sent as\n * a `YYYY-M-D` string built from UTC parts.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @dateField({ description: 'Due date', min: new Date('2024-01-01') })\n * public due!: Date | null;\n * }\n */\nexport const dateField = (updates: IDateFieldMetadata = {}) => genericDataField(updates, 'dateField', DateFieldManager);\n\n/**\n * Declares a date+time field. Defaults to naive local-time handling, which\n * round-trips wall-clock values unchanged; pass `timezone: 'UTC'` when the\n * field represents a true instant.\n *\n * The usual pairing for server-maintained stamps is\n * `{ readonly: true, priority: <low> }`, as `created`/`updated` are written by\n * the API and never by a form.\n *\n * @param updates field options\n */\nexport const datetimeField = (updates: IDatetimeFieldMetadata = {}) =>\n genericDataField(updates, 'datetimeField', DatetimeFieldManager);\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\nimport { DataModel } from '../data-model';\nimport { Collection, DataModelType } from '../data-collection';\nimport { fieldValues } from '../field-values';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\n\n/**\n * Options for {@link foreignKeyField}.\n */\nexport interface IForeignKeyFieldMetadata extends IFieldMetadata<number> {\n /**\n * Name of the target model, e.g. `'Category'`.\n *\n * **Inert.** Nothing in the library ever reads this string: it is not\n * resolved to a class, not validated, and not used to fetch anything. It is\n * a documentary annotation for humans and tooling, and a typo in it has no\n * runtime effect whatsoever.\n *\n * The actual link to the target model is `model:` on the paired\n * {@link detailsField}. If you set `related` and expect the relation to\n * work, it will not — add the `<field>_details` property.\n */\n related?: string;\n}\n\n/**\n * Options for {@link reverseForeignKeyField}.\n */\nexport interface IReverseForeignKeyFieldMetadata extends IFieldMetadata<number> {\n /**\n * Name of the model pointing back at this one.\n *\n * **Inert**, exactly as {@link IForeignKeyFieldMetadata.related}: required\n * by the type, but never read at runtime. Purely documentary; the real\n * deserialisation is done by the paired {@link detailsField}.\n */\n related: string;\n}\n\n/**\n * Options for {@link detailsField}.\n */\nexport interface IDetailsFieldMetadata<T> extends IFieldMetadata<T> {\n /** Name of the id field this details payload belongs to. Declarative only. */\n field?: string;\n /** Deserialise the payload as an array of `model` rather than a single one. */\n many?: boolean;\n /**\n * The target model **class** (a bare reference — not a string, not a\n * `forwardRef`, not a lambda). This is the real link of a relation: it is\n * what instantiates and populates the nested payload.\n */\n model?: DataModelType<DataModel>;\n /**\n * Custom deserialiser, taking precedence over `model`. Use it for payloads\n * that are not models — a plain shape, or a value needing transformation.\n */\n // A narrower parameter would not be assignable to one declared `unknown`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deserialize?: (data: any) => T;\n}\n\n/**\n * Options for {@link manyToManyField}.\n */\nexport interface IManyToManyFieldMetadata extends IFieldMetadata<number[]> {\n /**\n * Name of the target model.\n *\n * **Inert**, exactly as {@link IForeignKeyFieldMetadata.related}: required\n * by the type, but never read at runtime. The real link is `model:` on the\n * paired {@link detailsField}.\n */\n related: string;\n}\n\n/**\n * Manager for the id half of a foreign key. It carries a plain number with\n * pass-through serialisation; its real contribution is selecting the\n * `fkselect` editor and the `fkdetails` display, which are what make a bare\n * id render as a picker and as the related object's label.\n *\n * Both widgets read the sibling `<field>_details` property to do so — see\n * {@link DetailsFieldManager}.\n */\nexport class ForeignKeyFieldManager extends BaseFieldManager<number> implements IForeignKeyFieldMetadata {\n /** Target model name. Inert; see {@link IForeignKeyFieldMetadata.related}. */\n declare public related?: string;\n /** Renders an `fkselect` picker, populated from `<field>_details`. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'fkselect';\n /** Rendered by `fkdetails`, which reads `<field>_details`. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'fkdetails';\n}\n\n/**\n * Manager for the id half of a reverse foreign key. Unlike\n * {@link ForeignKeyFieldManager} it keeps the base text widgets, so it does\n * not render a picker: it marks the relation in metadata and leaves display to\n * the paired {@link detailsField}.\n */\nexport class ReverseForeignKeyFieldManager extends BaseFieldManager<number> implements IForeignKeyFieldMetadata {\n /** Source model name. Inert; see {@link IReverseForeignKeyFieldMetadata.related}. */\n declare public related?: string;\n}\n\n/**\n * Manager for the details half of a relation: it turns a nested JSON payload\n * into model instances (or whatever `deserialize` returns).\n *\n * **Naming is a runtime contract.** `dispedit` and `m2mselect` locate this\n * property by string concatenation, `` `${field}_details` ``, so the property\n * must be named exactly `<fkFieldName>_details` — `category` ⇒\n * `category_details`. The link is by name, never by type: rename one half\n * without the other and display and write-back break silently, with no\n * compile-time or runtime error.\n */\nexport class DetailsFieldManager<T> extends BaseFieldManager<T> implements IDetailsFieldMetadata<T> {\n /** Name of the id field this belongs to. Declarative only. */\n declare public field?: string;\n /** Deserialise an array rather than a single instance. */\n declare public many?: boolean;\n /** Target model class; the real link of the relation. */\n declare public model: DataModelType<DataModel>;\n /** Custom deserialiser, taking precedence over {@link model}. */\n // See IDetailsFieldMetadata.deserialize.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n declare public deserialize?: (data: any) => T;\n\n /**\n * Deserialises the nested payload, taking the first branch that applies:\n *\n * 1. `null` stays `null`, and `undefined` stays `undefined` — the two are\n * kept distinct, so an absent relation and an explicitly empty one remain\n * distinguishable.\n * 2. `deserialize` declared: the payload is handed to it and its result\n * returned as-is.\n * 3. `model` declared: a `new model(coll)` is built and populated via\n * `fromJson` — once, or once per element when `many: true`.\n * 4. Otherwise the raw JSON is passed **through untouched**. A bare\n * `detailsField()` with neither `model` nor `deserialize` is therefore a\n * legitimate way to hold server-computed payloads, string arrays and\n * other shapes that have no model of their own.\n *\n * @param data raw payload read from the JSON\n * @param coll collection handed to each constructed model instance\n */\n public override fromJson(data: unknown, coll?: Collection<DataModel>): T {\n if (data === null) {\n return data as T;\n }\n if (data === undefined) {\n return undefined as T;\n }\n if (this.deserialize) {\n return this.deserialize(data);\n }\n if (this.model) {\n if (!this.many) {\n const d = new this.model(coll);\n d.fromJson(fieldValues(data));\n return d as T;\n } else {\n const out: DataModel[] = [];\n for (const dt of data as unknown[]) {\n const d = new this.model(coll);\n d.fromJson(fieldValues(dt as object));\n out.push(d);\n }\n return out as T;\n }\n }\n return data as T;\n }\n}\n\n/**\n * Same as {@link IManyToManyFieldMetadata} but with `related` optional. It is\n * the interface {@link ManyToManyFieldManager} implements; the decorator's\n * public option type is `IManyToManyFieldMetadata`.\n */\nexport interface IManyToManyKeyFieldMetadata extends IFieldMetadata<number[]> {\n /** Target model name. Inert; see {@link IForeignKeyFieldMetadata.related}. */\n related?: string;\n}\n\n/**\n * Manager for the id half of a many-to-many relation: an array of numbers with\n * pass-through serialisation, rendered with the `m2mselect` editor and the\n * `m2mdetails` display.\n *\n * As with a foreign key, both widgets read the sibling `<field>_details`\n * property, which must be named accordingly.\n */\nexport class ManyToManyFieldManager extends BaseFieldManager<number[]> implements IManyToManyKeyFieldMetadata {\n /** Target model name. Inert; see {@link IManyToManyFieldMetadata.related}. */\n declare public related?: string;\n /** Renders an `m2mselect` multi-picker, populated from `<field>_details`. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'm2mselect';\n /** Rendered by `m2mdetails`, which reads `<field>_details`. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'm2mdetails';\n}\n\n/**\n * Declares the id half of a foreign key: the plain number the API stores.\n *\n * A relation is always **two fields**. This one holds the id; a companion\n * {@link detailsField} named `<thisField>_details` holds the nested object and\n * carries the `model:` that actually links the two. Declaring only the id\n * gives you a number and an empty picker.\n *\n * The id half conventionally takes `priority: -1` (\"load it, never show it\"),\n * since the details half is what a human should see. Its `related:` string is\n * documentation only — see {@link IForeignKeyFieldMetadata.related}.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * // id half — `related` is inert, `priority: -1` hides it from the UI\n * @foreignKeyField({ description: 'Category', related: 'Category', priority: -1 })\n * public category!: number;\n *\n * // details half — MUST be named `category_details`; `model` is the real link\n * @detailsField({ description: 'Category', model: Category, readonly: true, priority: 750 })\n * public category_details?: Category;\n * }\n */\nexport const foreignKeyField = (updates: IForeignKeyFieldMetadata): FieldDecoratorFn =>\n genericDataField(updates, 'foreignKeyField', ForeignKeyFieldManager);\n\n/**\n * Declares the id half of a reverse foreign key — the far side of a relation\n * another model owns. Unlike {@link foreignKeyField} it selects no relation\n * widget, so pair it with a {@link detailsField} for anything to be displayed.\n *\n * @param updates field options\n */\nexport const reverseForeignKeyField = (updates: IReverseForeignKeyFieldMetadata): FieldDecoratorFn =>\n genericDataField(updates, 'reverseForeignKeyField', ReverseForeignKeyFieldManager);\n\n/**\n * Declares the details half of a relation: the nested payload the API embeds\n * next to an id.\n *\n * **The property name is a runtime contract**: it must be exactly\n * `<idFieldName>_details`, because `dispedit` and `m2mselect` build the lookup\n * by concatenating `` `${field}_details` ``. Nothing checks it — get the name\n * wrong and display and write-back fail silently.\n *\n * Normally `readonly: true`: the nested object is rendered, but only the id\n * half is ever sent back. With neither `model` nor `deserialize` the raw JSON\n * is passed through, which is the idiomatic way to hold a server-computed\n * payload — see {@link DetailsFieldManager.fromJson}.\n *\n * @param meta field options\n * @example\n * // Pass-through: no model, so the raw JSON lands on the property as-is\n * @detailsField({ description: 'Labels', readonly: true })\n * public labels_details?: string[];\n */\nexport const detailsField = (meta: IDetailsFieldMetadata<unknown> = {}): FieldDecoratorFn =>\n genericDataField(meta, 'detailsField', DetailsFieldManager);\n\n/**\n * Declares the id half of a many-to-many relation: an array of ids, rendered\n * as a multi-select. Pairs with a `many: true` {@link detailsField} named\n * `<thisField>_details`, exactly as {@link foreignKeyField} does.\n *\n * Give it `defaultValue: []`. Without one the field deserialises to\n * `undefined` and the `m2mselect` editor has no array to work with.\n *\n * @param meta field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @manyToManyField({\n * description: 'Tags',\n * related: 'Tag', // inert: documentation only\n * defaultValue: [], // required in practice\n * priority: -1,\n * })\n * public tags!: number[];\n *\n * // `many: true` is what makes this deserialise an array of models\n * @detailsField({ description: 'Tags', model: Tag, many: true, readonly: true })\n * public tags_details?: Tag[];\n * }\n */\nexport const manyToManyField = (meta: IManyToManyFieldMetadata): FieldDecoratorFn =>\n genericDataField(meta, 'manyToManyField', ManyToManyFieldManager);\n","import { BaseFieldManager, genericDataField, IFieldMetadata } from './base';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\n\n/**\n * Options for {@link booleanField}. Adds nothing to the common metadata; the\n * value type is `boolean | null`, `null` standing for \"unset\".\n */\nexport type IBooleanFieldMetadata = IFieldMetadata<boolean | null>;\n\n/**\n * Manager for boolean fields. Renders a checkbox editor and a `boolean`\n * display, and — its real job — normalises the many shapes a truth value\n * arrives in over the wire (see {@link BooleanFieldManager.fromJson}).\n */\nexport class BooleanFieldManager extends BaseFieldManager<boolean | null> implements IBooleanFieldMetadata {\n /** Renders an `input.checkbox` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.checkbox';\n /** Rendered by the `boolean` display. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'boolean';\n\n /**\n * Coerces an incoming value to `boolean | null`, exactly as follows:\n *\n * - `null` / `undefined`: the default value when the field is `required`,\n * otherwise `null` — which is how a tri-state (true/false/unset) field is\n * modelled.\n * - a real boolean: returned unchanged.\n * - a string: `'true'`, `'1'`, `'ok'` and `'yes'` give `true`; `'false'`,\n * `'0'`, `'nok'` and `'no'` give `false`. **Any other string also gives\n * `true`**, including `''` and `'maybe'` — only the four listed spellings\n * are false. Matching is exact and case-sensitive, so `'True'` and `'YES'`\n * land in that catch-all and yield `true`.\n * - anything else: coerced with `!!data`.\n *\n * @param data raw value read from the JSON payload\n */\n public override fromJson(data: unknown): boolean | null {\n if (data === undefined) {\n if (this.required) {\n return this.getDefaultValue()!;\n } else {\n return null;\n }\n }\n if (data === null) {\n if (this.required) {\n return this.getDefaultValue()!;\n } else {\n return null;\n }\n }\n if (typeof data === 'boolean') {\n return data;\n }\n if (typeof data === 'string') {\n if (['true', '1', 'ok', 'yes'].indexOf(data) !== -1) {\n return true;\n }\n return ['false', '0', 'nok', 'no'].indexOf(data) === -1;\n }\n return !!data;\n }\n}\n\n/**\n * Declares a boolean field, rendered as a checkbox. Tolerant on input: string\n * spellings such as `'yes'` / `'0'` are coerced, so it copes with APIs that do\n * not send real JSON booleans.\n *\n * Left non-required, the field is tri-state — a missing or `null` payload\n * value stays `null` rather than becoming `false`. Set `required: true` with a\n * `defaultValue` to collapse it to a strict true/false.\n *\n * @param updates field options\n */\nexport const booleanField = (updates: IBooleanFieldMetadata = {}) =>\n genericDataField<boolean | null, IBooleanFieldMetadata, BooleanFieldManager>(\n updates,\n 'booleanField',\n BooleanFieldManager,\n );\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\nimport { ValidatorFn, Validators } from '@angular/forms';\n\n/**\n * Options for {@link integerField}.\n */\nexport interface IIntegerFieldMetadata extends IFieldMetadata<number> {\n /** Lower bound; adds `Validators.min`. */\n min?: number;\n /** Upper bound; adds `Validators.max`. */\n max?: number;\n}\n\n/**\n * Options for {@link floatField}.\n */\nexport interface IFloatFieldMetadata extends IFieldMetadata<number> {\n /** Lower bound; adds `Validators.min`. */\n min?: number;\n /** Upper bound; adds `Validators.max`. */\n max?: number;\n}\n\n/**\n * Options for {@link decimalField}.\n */\nexport interface IDecimalFieldMetadata extends IFieldMetadata<number> {\n /** Lower bound; adds `Validators.min`. Compared against the raw stored value. */\n min?: number;\n /** Upper bound; adds `Validators.max`. Compared against the raw stored value. */\n max?: number;\n /**\n * Scaling divisor used **for display only**.\n *\n * This is a trap worth reading twice: `factor` does not take part in\n * `fromJson`/`toJson`. The model property always holds the **raw wire\n * value**. The division happens exclusively in `dispedit` and in the\n * `factor`/`factorc` pipes (`value / factor`), and the editor multiplies\n * back by `factor` on save.\n *\n * So with `factor: 100`, `thing.price` is an integer number of cents:\n * `price === 1250` displays as `12.50`. `min`/`max` and any code reading the\n * property see cents too. Formatting a decimal field without the pipe shows\n * the unscaled value.\n */\n factor?: number;\n}\n\n/**\n * Manager for whole-number fields, and base for the other numeric managers.\n * Renders an `input.number` editor and adds `min`/`max` validators when\n * declared. Values are passed through unchanged by the base (de)serialisers —\n * nothing rounds or coerces to an integer at runtime.\n */\nexport class IntegerFieldManager extends BaseFieldManager<number> implements IIntegerFieldMetadata {\n /** Rendered as plain text. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'text';\n /** Renders an `input.number` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.number';\n\n /** Lower bound; adds `Validators.min`. */\n declare public min?: number;\n /** Upper bound; adds `Validators.max`. */\n declare public max?: number;\n\n /** Required, plus `Validators.min` / `Validators.max` when declared. */\n public override get validators(): ValidatorFn[] {\n const v = super.getValidators();\n if (this.min !== undefined) {\n v.push(Validators.min(this.min));\n }\n if (this.max !== undefined) {\n v.push(Validators.max(this.max));\n }\n return v;\n }\n}\n\n/**\n * Manager for real-number fields. Behaviourally identical to\n * {@link IntegerFieldManager} today — same widgets, same validators, same\n * pass-through serialisation — and exists to distinguish the two field types\n * in metadata.\n */\nexport class FloatFieldManager extends IntegerFieldManager implements IFloatFieldMetadata {\n /** Rendered as plain text. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'text';\n /** Renders an `input.number` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.number';\n}\n\n/**\n * Manager for fixed-point fields stored as scaled integers. It selects the\n * `decimal` / `input.decimal` widgets, which are the pieces that apply\n * {@link IDecimalFieldMetadata.factor}.\n *\n * The manager itself does **not** scale: `fromJson`/`toJson` are the\n * inherited pass-throughs, so the model property holds the raw wire value\n * (cents, with the usual `factor: 100`) and only the display layer divides.\n */\nexport class DecimalFieldManager extends IntegerFieldManager implements IDecimalFieldMetadata {\n /** Display-only scaling divisor. See {@link IDecimalFieldMetadata.factor}. */\n declare public factor?: number;\n /** Rendered by the `decimal` display, which divides by `factor`. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'decimal';\n /** Renders an `input.decimal` editor, which multiplies back by `factor` on save. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.decimal';\n}\n\n/**\n * Declares a whole-number field: counts, quantities, positions. Rendered as a\n * number input, with optional `min`/`max` validators.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @integerField({ description: 'Quantity', min: 0, defaultValue: 0 })\n * public quantity!: number;\n * }\n */\nexport const integerField = (updates: IIntegerFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'integerField', IntegerFieldManager);\n\n/**\n * Declares a real-number field, for values where a fractional part is\n * inherent (ratios, measurements, coordinates). Prefer {@link decimalField}\n * for money — floats are the wrong tool for exact amounts.\n *\n * @param updates field options\n */\nexport const floatField = (updates: IFloatFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'floatField', FloatFieldManager);\n\n/**\n * Declares a fixed-point field stored as a scaled integer — the right choice\n * for money and other amounts that must stay exact.\n *\n * The model property holds the **raw, unscaled** value; `factor` only divides\n * at display time and multiplies back on save. See\n * {@link IDecimalFieldMetadata.factor} before using it.\n *\n * Two sharp edges on `factor`. The `{ factor: 100 }` default applies only when\n * the decorator is called with **no argument at all** — passing any options\n * object replaces it wholesale, so `decimalField({ min: 0 })` leaves `factor`\n * undefined, which the display layer treats as `1` (no scaling). Spell\n * `factor` out whenever you pass options.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * // `price` holds cents: 1250 displays as 12.50\n * @decimalField({ description: 'Price', factor: 100, min: 0 })\n * public price!: number;\n * }\n */\nexport const decimalField = (updates: IDecimalFieldMetadata = { factor: 100 }): FieldDecoratorFn =>\n genericDataField(updates, 'decimalField', DecimalFieldManager);\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\nimport { DataModel } from '../data-model';\nimport { Collection } from '../data-collection';\nimport { ICharFieldChoice } from './stringfields';\n\n/**\n * Options for {@link computedField}.\n */\nexport interface IComputedFieldMetadata<T> extends IFieldMetadata<T> {\n /** Name of the source field this value is derived from. Declarative only. */\n field?: string;\n /**\n * Display scaling divisor, as on `decimalField`, for a computed value held\n * as a scaled integer. See `IDecimalFieldMetadata.factor`.\n */\n factor?: number;\n /**\n * Choice list used to render the value as a label rather than a raw code.\n * Note that, unlike `charField`, this does **not** switch the editor to a\n * select — a computed field has no editor.\n */\n choices?: ICharFieldChoice[];\n}\n\n/**\n * Manager for computed, display-only fields. It sets `computed = true`, which\n * makes `DataModel.setFV` skip assignment for the field entirely, and its\n * `fromJson` has an empty body — it always returns `undefined`.\n *\n * The combination means the model property is never populated by this manager:\n * the value is expected to come from a getter on the model itself, while the\n * field declaration exists to give that getter metadata (label, priority,\n * display type) so it can appear in generated lists and views.\n */\nexport class ComputedFieldManager<T> extends BaseFieldManager<T> implements IComputedFieldMetadata<T> {\n /** Source field name. Declarative only. */\n declare public field?: string;\n /** Always `true`, which is what makes `DataModel.setFV` skip this field. */\n public override computed = true;\n\n /**\n * Deserialises nothing: the body is empty, so the return is always\n * `undefined`. A computed field takes no value from the payload.\n *\n * @param _data ignored\n * @param _coll ignored\n */\n public override fromJson(_data: unknown, _coll?: Collection<DataModel>): T {\n // A computed field is derived on the client; the payload holds nothing.\n return undefined as T;\n }\n}\n\n/**\n * Declares a display-only field derived on the client, typically backed by a\n * getter on the model.\n *\n * It is **never written**: `fromJson` ignores the payload, and `DataModel.setFV`\n * refuses to assign to it. Reach for it to give a derived value the metadata\n * (label, priority, display type) it needs to show up in generated lists and\n * views, alongside real fields.\n *\n * @param meta field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @integerField({ description: 'Quantity' })\n * public quantity!: number;\n *\n * // Declared for display; the getter below is what produces the value\n * @computedField({ description: 'In stock', priority: 100 })\n * public get in_stock(): boolean {\n * return this.quantity > 0;\n * }\n * }\n */\nexport const computedField = (meta: IComputedFieldMetadata<unknown> = {}): FieldDecoratorFn =>\n genericDataField(meta, 'computedField', ComputedFieldManager);\n","/**\n * Public barrel for the field decorators — the library's primary API.\n *\n * Decorate a `DataModel` subclass (which must declare a `static __name`) with\n * these to describe each field once: the declaration then drives JSON\n * (de)serialisation, form controls and validators, and the widget `dispedit`\n * renders for the field.\n *\n * Only the decorators are re-exported here; the matching `*Manager` classes\n * and `I*Metadata` option interfaces are exported from their own modules.\n */\nexport { charField, emailField, textField, passwordField } from './stringfields';\nexport { primaryField } from './primaryfield';\nexport { dateField, datetimeField } from './datetime';\nexport { foreignKeyField, manyToManyField, reverseForeignKeyField, detailsField } from './relations';\nexport { booleanField } from './boolean';\nexport { decimalField, integerField, floatField } from './numbers';\nexport { computedField } from './computed';\n","import { Component, DestroyRef, inject, input, OnInit, signal } from '@angular/core';\nimport { DataMessageService, Message } from '../message.service';\n\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-message-zone',\n templateUrl: './message-zone.component.html',\n styleUrls: ['./message-zone.component.sass'],\n imports: [],\n})\n/**\n * Renders the notifications pushed through {@link DataMessageService} as dismissible\n * Bootstrap alerts.\n *\n * Place one instance in the application shell — typically next to the router outlet, so\n * it survives navigation. Without it, everything the library reports (dispedit save\n * errors, flag toggles, expired sessions) is queued and expires unseen. Each alert\n * carries a close button, and clicking the body toggles the stored trace, which is\n * useful for surfacing backend error details.\n */\nexport class MessageZoneComponent implements OnInit {\n /**\n * Currently unused: it is declared but never read, so it does not filter anything.\n */\n public filter = input<string>();\n /** Messages to render, mirrored from the service stream. */\n public current = signal<Message[]>([]);\n public messages = inject(DataMessageService);\n private destroy$ = inject(DestroyRef);\n\n public ngOnInit(): void {\n this.messages.current.pipe(takeUntilDestroyed(this.destroy$)).subscribe((messages) => {\n this.current.set(messages);\n });\n }\n}\n","<div class=\"messagezone\">\n @for (message of current(); track message) {\n <div\n class=\"alert\"\n animate.enter=\"fade-enter\"\n animate.leave=\"fade-leave\"\n [class]=\"message.style\"\n (click)=\"message.showTrace = !message.showTrace\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"message.showTrace\"\n aria-label=\"Afficher la trace\"\n (keydown.enter)=\"message.showTrace = !message.showTrace\"\n (keydown.space)=\"$event.preventDefault(); message.showTrace = !message.showTrace\"\n >\n <button class=\"btn-close\" type=\"button\" (click)=\"messages.ack(message)\" aria-label=\"Close\"></button>\n <strong>{{ message.title }}</strong>\n &nbsp; {{ message.message }}\n @if (message.showTrace) {\n <div class=\"pretrace\">{{ message.trace }}</div>\n }\n </div>\n }\n</div>\n","import { DataModel } from './data-model';\nimport { CollectionMock } from './data-collection.mock';\nimport { FilterData, IQueryMeta, IQuerysetOptions, SortData } from './data-query';\nimport { combineLatest, Observable, of } from 'rxjs';\n\n/**\n * Test double for {@link Queryset}, handed out by `CollectionMock.queryset()`.\n *\n * Lets you test list components — tables, paginators, filter bars — without HTTP:\n * set {@link mockData} and every read hands back exactly those rows, synchronously.\n *\n * The important caveat is that this double is **inert**. {@link filter},\n * {@link sort}, {@link paginateBy} and {@link setPage} accept their arguments,\n * discard them and return `this`, so chaining compiles and runs but changes\n * nothing: `mockData` comes back whatever you filtered by. That makes it right\n * for testing how a component *renders* rows and *reacts* to them, and wrong for\n * asserting that the component queried correctly — for the latter, spy on these\n * methods or use a real queryset against `HttpTestingController`.\n *\n * Reachable through `CollectionMock`, though not exported from the public API\n * under its own name.\n *\n * @example\n * ```ts\n * const things = new CollectionMock<Thing>(Thing);\n * const qs = things.queryset();\n * qs.mockData = things.fromJson([{ id: 1, name: 'a' }], true);\n * qs.get().subscribe((rows) => expect(rows.length).toBe(1));\n * ```\n */\nexport class QuerysetMock<T extends DataModel> {\n /**\n * Rows this queryset hands back. Falls through to the parent mock's\n * `mockValues` while left empty — but note the fallback is `||` on an array, so\n * the *default* `[]` is falsy-checked as an object and never triggers it: an\n * explicitly emptied `mockData` still shadows the collection's values.\n */\n public mockData: T[] = [];\n\n /** Present to match {@link Queryset}'s shape; never read or written by this mock. */\n public filterData: FilterData = {};\n /** Present to match {@link Queryset}'s shape; never read or written by this mock. */\n public sortData: SortData[] = [];\n /** Present to match {@link Queryset}'s shape; {@link paginateBy} does not update it. */\n public pageSize = 100;\n /** Present to match {@link Queryset}'s shape; {@link setPage} does not update it. */\n public page = 1;\n\n /**\n * Always `true` — unlike the real queryset, this is never flipped by\n * {@link get}. Components that branch on `pristine` to show an empty state\n * therefore behave as if no fetch had happened; set it yourself if that matters.\n */\n public pristine = true;\n /**\n * Always emits `false`, once. The mock resolves synchronously, so there is no\n * in-flight state to represent; components that gate rendering on `loading` see\n * a settled queryset from the start.\n */\n public loading = of(false);\n\n /**\n * @param _coll parent mock, used as the fallback source of rows\n * @param options recorded to match `Queryset`'s shape; no option is acted on\n */\n\n constructor(\n protected _coll: CollectionMock<T>,\n public options: IQuerysetOptions = {},\n ) {}\n\n /** Emits {@link mockData} (or the parent's `mockValues`) immediately, then completes. */\n public get results(): Observable<T[]> {\n return of(this.mockData || this._coll.mockValues);\n }\n\n /**\n * Emits a fixed, arbitrary pagination envelope (100 rows over 10 pages of 10) —\n * it bears no relation to {@link mockData}. Good enough to render a paginator,\n * useless for asserting counts; stub this getter when a test needs specific\n * numbers.\n */\n public get meta(): Observable<IQueryMeta> {\n return of({\n nav: { count: 100, next: 1, page: 1, pages: 10, prev: null, size: 10 },\n parameters: { page: 'page', page_size: 'page_size' },\n });\n }\n\n /** `[results, loading, meta]` combined, mirroring `Queryset.full`. */\n public get full(): Observable<[T[], boolean, IQueryMeta]> {\n return combineLatest([this.results, this.loading, this.meta]);\n }\n\n /** No-op returning `this`; the filter is discarded. See the class-level caveat. */\n public filter(_params: FilterData = {}): QuerysetMock<T> {\n return this;\n }\n\n /** No-op returning `this`; the ordering is discarded. See the class-level caveat. */\n public sort(..._sorting: string[]): QuerysetMock<T> {\n return this;\n }\n\n /** No-op returning `this`; {@link pageSize} is left untouched. */\n public paginateBy(_pageSize = 20): QuerysetMock<T> {\n return this;\n }\n\n /** No-op returning `this`; {@link page} is left untouched. */\n public setPage(_page: number): QuerysetMock<T> {\n return this;\n }\n\n /** Always returns `{}`, since no query state is retained. */\n public getQueryParams(): FilterData {\n return {};\n }\n\n /**\n * Emits the canned rows immediately. Takes no `refresh`/`sync` arguments, as\n * there is nothing to refresh; unlike the real `get()`, it leaves\n * {@link pristine} at `true`.\n */\n public get(): Observable<T[]> {\n return of(this.mockData || this._coll.mockValues);\n }\n}\n","import { DataModel } from './data-model';\nimport { Observable, of } from 'rxjs';\nimport { IQuerysetOptions } from './data-query';\nimport { QuerysetMock } from './data-query.mock';\nimport { Collection, IActionParams, IHttpMethod } from './data-collection';\n\n/**\n * Test double for {@link Collection}: same shape, no HTTP.\n *\n * This is how consumers test components that take a collection. Instead of\n * configuring `HttpClient`, `HttpTestingController` and a `DATA_API_URL`, you\n * hand the component a `CollectionMock`, set the canned values on it, and every\n * read resolves synchronously to those. {@link fromJson} is real, so the\n * instances handed out are genuine models with genuine field metadata — which is\n * what makes it a useful double for metadata-driven UI rather than a stub that\n * only returns plain objects.\n *\n * It deliberately does *not* extend `Collection` — it duplicates the read half of\n * the API structurally, so components typed against `Collection<T>` usually need\n * an `as any` at the injection point. The write half (`save`, `update`,\n * `delete`, `create`, `raw`, `blob`, `getUrl`) is **not implemented**; testing\n * those needs a real collection over `HttpTestingController`.\n *\n * See `projects/data/src/examples/catalog/catalog.spec.ts` for a worked example.\n *\n * @example\n * ```ts\n * const things = new CollectionMock<Thing>(Thing);\n * things.mockValues = things.fromJson([{ id: 1, name: 'a' }], true);\n * things.mockValue = things.fromJson({ id: 1, name: 'a' });\n *\n * TestBed.configureTestingModule({\n * providers: [{ provide: ThingService, useValue: things }],\n * });\n * ```\n */\nexport class CollectionMock<T extends DataModel> {\n /** Canned instance returned by every {@link fetch}, whatever the id. */\n public mockValue?: T;\n /**\n * Canned rows returned by {@link list}, and the fallback for\n * `QuerysetMock.get()` when the queryset has no `mockData` of its own.\n */\n public mockValues?: T[];\n /** Canned payload returned by every {@link action}, whatever the action name. */\n public actionValue: any;\n\n /**\n * @param model model class to instantiate in {@link fromJson}; pass the same\n * class the real collection is built on\n */\n constructor(protected model: new (coll: Collection<T>) => T) {}\n\n /**\n * Returns {@link mockValue}, ignoring the arguments entirely — including the\n * id, so a test that fetches two different ids gets the same instance back.\n * Reassign `mockValue` between calls if that matters.\n */\n public fetch(_id: number, _suffix = ''): Observable<T> {\n return of(this.mockValue as T);\n }\n\n /**\n * Returns {@link actionValue}, ignoring the arguments. Since it does not record\n * the call, assert on the effects rather than on the invocation, or spy on this\n * method when you need to check what was requested.\n */\n public action(_model: T | null, _method: IHttpMethod, _action: string, _params: IActionParams): Observable<any> {\n return of(this.actionValue);\n }\n\n /**\n * Opens a {@link QuerysetMock} backed by this mock, mirroring\n * `Collection.queryset()`. With no `mockData` set on it, the queryset falls\n * back to this mock's {@link mockValues}.\n */\n public queryset(options: IQuerysetOptions = {}): QuerysetMock<T> {\n return new QuerysetMock<T>(this, options);\n }\n\n /**\n * Returns `{ results: mockValues }` — the paginated envelope, matching what the\n * real `Collection.list()` unwraps. Arguments are ignored, so filters are not\n * applied; set {@link mockValues} to whatever the filtered result should be.\n */\n public list(_query: Record<string, string> = {}, _suffix = ''): Observable<any> {\n return of({ results: this.mockValues });\n }\n\n /**\n * Builds real model instances from JSON, exactly as a live collection would —\n * this is the method you use to prepare {@link mockValue}/{@link mockValues}.\n *\n * Two departures from `Collection.fromJson()` worth knowing when writing\n * fixtures. Arrays need `many: true` explicitly rather than being detected. And\n * a single object is only converted when it carries an `id`; anything else is\n * handed back **unchanged**, as a plain object rather than a model — so a\n * fixture for an unsaved record silently fails to become one.\n *\n * @param data JSON object or array of them\n * @param many set to `true` when `data` is an array\n */\n fromJson(data: any, many = false): any {\n if (data && data.id !== undefined) {\n const m = new this.model(this as any);\n m.fromJson(data);\n return m;\n } else {\n if (many && data && data.length) {\n const out: T[] = [];\n for (const r of data) {\n const ri = new this.model(this as any);\n ri.fromJson(r);\n out.push(ri);\n }\n return out;\n }\n return data;\n }\n }\n}\n","import { Subscription } from 'rxjs';\n\n/**\n * Limits applied to a queue, passed to the `options` input of the file select/drop\n * directives. Every field is a ceiling; omitted ones mean \"no limit\".\n */\nexport interface UploaderOptions {\n /** How many uploads may run at once. Use `Number.POSITIVE_INFINITY` for unbounded. */\n concurrency: number;\n /** Accepted MIME types; `['*']` (the default) accepts everything. Files failing this are emitted as `rejected`. */\n allowedContentTypes?: string[];\n /** Maximum number of files that may sit in the queue at once. */\n maxUploads?: number;\n /** Maximum accepted size per file, in bytes. */\n maxFileSize?: number;\n}\n\n/** A `Blob` that carries a filename, i.e. the shape of a `File` as the uploader sends it. */\nexport interface BlobFile extends Blob {\n name: string;\n}\n\n/** Where a queued file stands: waiting, in flight, finished, or aborted. */\nexport enum UploadStatus {\n Queue,\n Uploading,\n Done,\n Cancelled,\n}\n\n/**\n * Live progress of one file. `data` is present from the moment the file is queued, with\n * throughput and ETA figures filled in as the transfer advances.\n */\nexport interface UploadProgress {\n status: UploadStatus;\n data?: {\n percentage: number;\n speed: number;\n speedHuman: string;\n startTime: number | null;\n endTime: number | null;\n eta: number | null;\n etaHuman: string | null;\n };\n}\n\n/**\n * A file tracked by the uploader, from selection through to the server's response.\n *\n * The same object is mutated in place as the upload advances, so `progress` and the\n * `response*` fields change under you; `id` is what {@link UploadInput} commands refer to.\n */\nexport interface UploadFile {\n /** Random identifier generated on queueing; used to target this file in `cancel` and `remove` commands. */\n id: string;\n /** Position of the file within the batch it was added with, not within the queue. */\n fileIndex: number;\n lastModifiedDate: Date;\n name: string;\n size: number;\n /** MIME type as reported by the browser, matched against {@link UploaderOptions.allowedContentTypes}. */\n type: string;\n /** Multipart body sent for this file; extra `data` fields from the upload command are appended to it. */\n form: FormData;\n /** Live status and throughput figures, updated as the transfer progresses. */\n progress: UploadProgress;\n /** Response body, parsed as JSON when possible and left as raw text otherwise. Set once done. */\n response?: unknown;\n /** HTTP status code of the response. Set once done — note that a 4xx/5xx still completes as `done`. */\n responseStatus?: number;\n /** Subscription of the in-flight request, used to cancel it. */\n sub?: Subscription;\n /** The underlying browser `File`, i.e. what is actually transferred. */\n nativeFile?: File;\n /** Response headers, parsed into a plain object. Set once done. */\n responseHeaders?: Record<string, string>;\n}\n\n/**\n * An event emitted by the uploader on the `uploadOutput` output of the directives.\n *\n * Switch on `type` to drive your UI: `addedToQueue`/`allAddedToQueue` after selection,\n * `rejected` for files refused by the options, `start`/`uploading`/`done` over a\n * transfer's life, `cancelled`/`removed`/`removedAll` for queue edits, and\n * `dragOver`/`dragOut`/`drop` for drop-zone hover states.\n */\nexport interface UploadOutput {\n type:\n | 'addedToQueue'\n | 'allAddedToQueue'\n | 'uploading'\n | 'done'\n | 'start'\n | 'cancelled'\n | 'dragOver'\n | 'dragOut'\n | 'drop'\n | 'removed'\n | 'removedAll'\n | 'rejected';\n file?: UploadFile;\n nativeFile?: File;\n}\n\n/**\n * A command sent *to* the uploader by emitting it on the `EventEmitter` bound to the\n * directives' `uploadInput`.\n *\n * `uploadAll` and `uploadFile` carry the request details (url, method, headers, extra\n * data); the queue-management commands only need `type` and, where relevant, `id`.\n */\nexport interface UploadInput {\n type: 'uploadAll' | 'uploadFile' | 'cancel' | 'cancelAll' | 'remove' | 'removeAll';\n /** Target endpoint for `uploadAll`/`uploadFile`. Defaults to an empty string, which posts to the current url. */\n url?: string;\n /** HTTP method to use; defaults to `POST`. */\n method?: string;\n /** {@link UploadFile.id} to act on, required by `cancel` and `remove`. */\n id?: string;\n /** Multipart field name the file is sent under; defaults to `file`. */\n fieldName?: string;\n fileIndex?: number;\n /** The queued file to send with `uploadFile`; matched by identity against the queue. */\n file?: UploadFile;\n /** Extra form fields appended to the multipart body alongside the file. */\n data?: Record<string, string | Blob>;\n /** Extra request headers. Note the uploader uses `XMLHttpRequest` directly, so Angular HTTP interceptors — including the auth interceptor — do not apply; add any `Authorization` header here yourself. */\n headers?: Record<string, string>;\n includeWebKitFormBoundary?: boolean; // If false, only the file is send trough xhr.send (WebKitFormBoundary is omit)\n /** Sends credentials (cookies) cross-origin; defaults to `false`. */\n withCredentials?: boolean;\n}\n","import { EventEmitter } from '@angular/core';\nimport { Observable, Subject, Subscription } from 'rxjs';\nimport { finalize, mergeMap } from 'rxjs/operators';\nimport { BlobFile, UploadFile, UploadInput, UploadOutput, UploadStatus } from './interfaces';\n\n/**\n * Formats a byte count as a short human-readable string using binary (1024) steps, e.g.\n * `1.5 MB`. Used for the uploader's speed readouts, and generic enough for file sizes in\n * your own UI.\n */\nexport function humanizeBytes(bytes: number): string {\n if (bytes === 0) {\n return '0 Byte';\n }\n\n const k = 1024;\n const sizes: string[] = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];\n const i: number = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\n/**\n * The upload engine behind {@link NgFileSelectDirective} and {@link NgFileDropDirective}:\n * it owns the queue, enforces the option limits, and runs the transfers.\n *\n * Despite the name it is a plain class, not an Angular service — each directive news up\n * its own instance in `ngOnInit`, so a queue is scoped to one input or drop zone. Use the\n * directives rather than instantiating it directly unless you are building a custom host.\n *\n * Transfers go through `XMLHttpRequest` rather than `HttpClient`, in order to get upload\n * progress events; a consequence is that Angular's HTTP interceptors never see these\n * requests, so authentication headers must be passed explicitly on the\n * {@link UploadInput}.\n */\nexport class DataUploaderService {\n /** Files currently held, in insertion order. Mutated in place as files are added, cancelled or removed. */\n queue: UploadFile[];\n /** Stream of {@link UploadOutput} events; the directives forward it to their `uploadOutput` output. */\n serviceEvents: EventEmitter<UploadOutput>;\n /** Internal work queue; the `concurrency` limit is applied to it via `mergeMap`. */\n uploadScheduler: Subject<{ file: UploadFile; event: UploadInput }>;\n /** Per-file transfer subscriptions, kept so `cancel`/`cancelAll` can abort them. */\n subs: { id: string; sub: Subscription }[];\n contentTypes: string[];\n maxUploads: number;\n maxFileSize: number;\n\n /**\n * Builds a queue and starts its scheduler. All limits default to unbounded and all\n * content types are accepted.\n *\n * @param concurrency - how many transfers may run simultaneously.\n */\n constructor(\n concurrency: number = Number.POSITIVE_INFINITY,\n contentTypes: string[] = ['*'],\n maxUploads: number = Number.POSITIVE_INFINITY,\n maxFileSize: number = Number.POSITIVE_INFINITY,\n ) {\n this.queue = [];\n this.serviceEvents = new EventEmitter<UploadOutput>();\n this.uploadScheduler = new Subject();\n this.subs = [];\n this.contentTypes = contentTypes;\n this.maxUploads = maxUploads;\n this.maxFileSize = maxFileSize;\n\n this.uploadScheduler\n .pipe(mergeMap((upload) => this.startUpload(upload), concurrency))\n .subscribe((uploadOutput) => this.serviceEvents.emit(uploadOutput));\n }\n\n /**\n * Screens a batch of freshly selected or dropped files against the content type, queue\n * length and file size limits, queueing those that pass and emitting `rejected` for the\n * rest.\n *\n * Called by the directives on `change` and `drop`. Emits `addedToQueue` per accepted\n * file and a single `allAddedToQueue` at the end — the latter is the signal to act on if\n * you want to auto-start an upload.\n */\n handleFiles(incomingFiles: FileList): void {\n let acc: File[] = [];\n\n for (let i = 0; i < incomingFiles.length; i++) {\n const futureQueueLength = acc.length + this.queue.length + 1;\n const checkFile = incomingFiles[i];\n if (\n this.isContentTypeAllowed(checkFile.type) &&\n futureQueueLength <= this.maxUploads &&\n this.isFileSizeAllowed(checkFile.size)\n ) {\n acc = acc.concat(checkFile);\n } else {\n const rejectedFile: UploadFile = this.makeUploadFile(checkFile, i);\n this.serviceEvents.emit({ type: 'rejected', file: rejectedFile });\n }\n }\n for (let i = 0; i < acc.length; i++) {\n const file = acc[i];\n const uploadFile: UploadFile = this.makeUploadFile(file, i);\n this.serviceEvents.emit({ type: 'addedToQueue', file: uploadFile });\n this.queue.push(uploadFile);\n }\n this.serviceEvents.emit({ type: 'allAddedToQueue' });\n }\n\n /**\n * Wires an application-owned emitter as the command channel, so emitting an\n * {@link UploadInput} on it starts, cancels or clears uploads.\n *\n * The directives call this with whatever emitter is bound to their `uploadInput` and\n * unsubscribe on destroy.\n */\n initInputEvents(input: EventEmitter<UploadInput>): Subscription {\n return input.subscribe((event: UploadInput) => {\n switch (event.type) {\n case 'uploadFile': {\n const uploadFileIndex = this.queue.findIndex((file) => file === event.file);\n if (uploadFileIndex !== -1 && event.file) {\n this.uploadScheduler.next({\n file: this.queue[uploadFileIndex],\n event: event,\n });\n }\n break;\n }\n case 'uploadAll': {\n const files = this.queue.filter((file) => file.progress.status === UploadStatus.Queue);\n files.forEach((file) => this.uploadScheduler.next({ file: file, event: event }));\n break;\n }\n case 'cancel': {\n const id = event.id || null;\n if (!id) {\n return;\n }\n const subs = this.subs.filter((sub) => sub.id === id);\n subs.forEach((sub) => {\n if (sub.sub) {\n sub.sub.unsubscribe();\n const fileIndex = this.queue.findIndex((file) => file.id === id);\n if (fileIndex !== -1) {\n this.queue[fileIndex].progress.status = UploadStatus.Cancelled;\n this.serviceEvents.emit({\n type: 'cancelled',\n file: this.queue[fileIndex],\n });\n }\n }\n });\n break;\n }\n case 'cancelAll':\n this.subs.forEach((sub) => {\n if (sub.sub) {\n sub.sub.unsubscribe();\n }\n\n const file = this.queue.find((uploadFile) => uploadFile.id === sub.id);\n if (file) {\n file.progress.status = UploadStatus.Cancelled;\n this.serviceEvents.emit({ type: 'cancelled', file: file });\n }\n });\n break;\n case 'remove': {\n if (!event.id) {\n return;\n }\n\n const i = this.queue.findIndex((file) => file.id === event.id);\n if (i !== -1) {\n const file = this.queue[i];\n this.queue.splice(i, 1);\n this.serviceEvents.emit({ type: 'removed', file: file });\n }\n break;\n }\n case 'removeAll':\n if (this.queue.length) {\n this.queue = [];\n this.serviceEvents.emit({ type: 'removedAll' });\n }\n break;\n }\n });\n }\n\n /**\n * Wraps one {@link uploadFile} transfer so its subscription is registered for later\n * cancellation. Invoked by the scheduler under the concurrency limit rather than\n * directly.\n */\n startUpload(upload: { file: UploadFile; event: UploadInput }): Observable<UploadOutput> {\n return new Observable((observer) => {\n const sub = this.uploadFile(upload.file, upload.event)\n .pipe(\n finalize(() => {\n if (!observer.closed) {\n observer.complete();\n }\n }),\n )\n .subscribe({\n next: (output) => {\n observer.next(output);\n },\n error: (err) => {\n observer.error(err);\n observer.complete();\n },\n complete: () => {\n observer.complete();\n },\n });\n\n this.subs.push({ id: upload.file.id, sub: sub });\n });\n }\n\n /**\n * Performs the actual `XMLHttpRequest` transfer for one file, emitting `uploading` as\n * progress arrives and `done` when the request completes.\n *\n * Unsubscribing aborts the request. By default the file is sent as multipart form data\n * alongside `event.data`; set `includeWebKitFormBoundary: false` to send the raw file as\n * the body instead. Completion is reported for any HTTP status — inspect\n * {@link UploadFile.responseStatus} to tell success from a server-side error.\n */\n uploadFile(file: UploadFile, event: UploadInput): Observable<UploadOutput> {\n return new Observable((observer) => {\n const url = event.url || '';\n const method = event.method || 'POST';\n const data = event.data || {};\n const headers = event.headers || {};\n\n const xhr = new XMLHttpRequest();\n const time: number = new Date().getTime();\n let progressStartTime: number = (file.progress.data && file.progress.data.startTime) || time;\n let speed = 0;\n let eta: number | null = null;\n\n xhr.upload.addEventListener(\n 'progress',\n (e: ProgressEvent) => {\n if (e.lengthComputable) {\n const percentage = Math.round((e.loaded * 100) / e.total);\n const diff = new Date().getTime() - time;\n speed = Math.round((e.loaded / diff) * 1000);\n progressStartTime = (file.progress.data && file.progress.data.startTime) || new Date().getTime();\n eta = Math.ceil((e.total - e.loaded) / speed);\n\n file.progress = {\n status: UploadStatus.Uploading,\n data: {\n percentage: percentage,\n speed: speed,\n speedHuman: `${humanizeBytes(speed)}/s`,\n startTime: progressStartTime,\n endTime: null,\n eta: eta,\n etaHuman: this.secondsToHuman(eta),\n },\n };\n\n observer.next({ type: 'uploading', file: file });\n }\n },\n false,\n );\n\n xhr.upload.addEventListener('error', (e: Event) => {\n observer.error(e);\n observer.complete();\n });\n\n xhr.onreadystatechange = () => {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n const speedAverage = Math.round((file.size / (new Date().getTime() - progressStartTime)) * 1000);\n file.progress = {\n status: UploadStatus.Done,\n data: {\n percentage: 100,\n speed: speedAverage,\n speedHuman: `${humanizeBytes(speedAverage)}/s`,\n startTime: progressStartTime,\n endTime: new Date().getTime(),\n eta: eta,\n etaHuman: this.secondsToHuman(eta || 0),\n },\n };\n\n file.responseStatus = xhr.status;\n try {\n file.response = JSON.parse(xhr.response as string);\n } catch {\n file.response = xhr.response;\n }\n\n file.responseHeaders = this.parseResponseHeaders(xhr.getAllResponseHeaders());\n\n observer.next({ type: 'done', file: file });\n\n observer.complete();\n }\n };\n\n xhr.open(method, url, true);\n xhr.withCredentials = !!event.withCredentials;\n\n try {\n const uploadFile = file.nativeFile as BlobFile;\n const uploadIndex = this.queue.findIndex((outFile) => outFile.nativeFile === uploadFile);\n\n if (this.queue[uploadIndex].progress.status === UploadStatus.Cancelled) {\n observer.complete();\n }\n\n Object.keys(headers).forEach((key) => xhr.setRequestHeader(key, headers[key]));\n\n let bodyToSend: FormData | BlobFile;\n\n if (event.includeWebKitFormBoundary !== false) {\n Object.keys(data).forEach((key) => file.form.append(key, data[key]));\n file.form.append(event.fieldName || 'file', uploadFile, uploadFile.name);\n bodyToSend = file.form;\n } else {\n bodyToSend = uploadFile;\n }\n\n this.serviceEvents.emit({ type: 'start', file: file });\n xhr.send(bodyToSend);\n } catch {\n observer.complete();\n }\n\n return () => {\n xhr.abort();\n };\n });\n }\n\n /** Formats a number of seconds as `HH:MM:SS`, for the ETA readout. Values of a day or more wrap around. */\n secondsToHuman(sec: number): string {\n return new Date(sec * 1000).toISOString().substring(11, 11 + 8);\n }\n\n /** Generates the short random {@link UploadFile.id} given to each queued file. Random, not collision-proof. */\n generateId(): string {\n return Math.random().toString(36).substring(7);\n }\n\n /**\n * Replaces the accepted MIME types after construction, e.g. when the allowed types\n * depend on user input. A list containing `'*'`, or any non-array value, resets it to\n * \"accept everything\".\n */\n setContentTypes(contentTypes: string[]): void {\n if (typeof contentTypes !== 'undefined' && contentTypes instanceof Array) {\n if (contentTypes.find((type: string) => type === '*') !== undefined) {\n this.contentTypes = ['*'];\n } else {\n this.contentTypes = contentTypes;\n }\n return;\n }\n this.contentTypes = ['*'];\n }\n\n /** Whether the queue is in \"accept everything\" mode, i.e. `'*'` is among the content types. */\n allContentTypesAllowed(): boolean {\n return this.contentTypes.find((type: string) => type === '*') !== undefined;\n }\n\n /**\n * Whether a MIME type passes the filter. Matching is exact string equality, so wildcard\n * patterns such as `image/*` are not supported — only the bare `'*'` is.\n */\n isContentTypeAllowed(mimetype: string): boolean {\n if (this.allContentTypesAllowed()) {\n return true;\n }\n return this.contentTypes.find((type: string) => type === mimetype) !== undefined;\n }\n\n /** Whether a file is within {@link maxFileSize}. A falsy limit (including `0`) means no limit. */\n isFileSizeAllowed(fileSize: number): boolean {\n if (!this.maxFileSize) {\n return true;\n }\n return fileSize <= this.maxFileSize;\n }\n\n /**\n * Wraps a browser `File` into the {@link UploadFile} the queue works with, assigning it\n * an id and a zeroed progress record. Used for accepted and rejected files alike.\n */\n makeUploadFile(file: File, index: number): UploadFile {\n return {\n fileIndex: index,\n id: this.generateId(),\n name: file.name,\n size: file.size,\n type: file.type,\n form: new FormData(),\n progress: {\n status: UploadStatus.Queue,\n data: {\n percentage: 0,\n speed: 0,\n speedHuman: `${humanizeBytes(0)}/s`,\n startTime: null,\n endTime: null,\n eta: null,\n etaHuman: null,\n },\n },\n lastModifiedDate: new Date(file.lastModified),\n sub: undefined,\n nativeFile: file,\n };\n }\n\n private parseResponseHeaders(httpHeaders: string): Record<string, string> {\n if (!httpHeaders) {\n return {};\n }\n\n return httpHeaders\n .split('\\n')\n .map((x: string) => x.split(/: */, 2))\n .filter((x: string[]) => x[0])\n .reduce((acc: Record<string, string>, x: string[]) => {\n acc[x[0]] = x[1];\n return acc;\n }, {});\n }\n}\n","import { Directive, ElementRef, EventEmitter, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport { UploaderOptions, UploadInput, UploadOutput } from './interfaces';\nimport { DataUploaderService } from './ngx-uploader.class';\nimport { Subscription } from 'rxjs';\n\n@Directive({\n selector: '[dataFileDrop]',\n host: {\n '(drop)': 'onDrop($event)',\n '(dragover)': 'onDragOver($event)',\n '(dragleave)': 'onDragLeave($event)',\n },\n})\n/**\n * Turns any element into a drag-and-drop upload zone.\n *\n * Apply `dataFileDrop` to a container, bind `uploadOutput` to follow the queue and bind an\n * `EventEmitter<UploadInput>` to `uploadInput` to command it. Alongside the usual queue\n * events, it emits `dragOver`, `dragOut` and `drop`, which is what you hook to highlight\n * the zone while a file hovers over it. Drag events on the host are cancelled so the\n * browser does not navigate to the dropped file.\n *\n * The directive owns its own queue, so two drop zones do not share state.\n */\nexport class NgFileDropDirective implements OnInit, OnDestroy {\n /** Queue limits ({@link UploaderOptions}). Read once in `ngOnInit`; later changes have no effect. */\n public options = input<UploaderOptions>();\n /** Command channel: emit {@link UploadInput}s on it to start, cancel or clear uploads. */\n public uploadInput = input<EventEmitter<UploadInput>>();\n /** Queue and transfer events ({@link UploadOutput}), including the drag state events. */\n public uploadOutput = output<UploadOutput>();\n\n /** The queue backing this drop zone, created in `ngOnInit`. */\n public upload!: DataUploaderService;\n public el!: HTMLInputElement;\n public elementRef = inject(ElementRef);\n\n private _sub!: Subscription[];\n\n ngOnInit() {\n this._sub = [];\n const options = this.options();\n const concurrency = (options && options.concurrency) || Number.POSITIVE_INFINITY;\n const allowedContentTypes = (options && options.allowedContentTypes) || ['*'];\n const maxUploads = (options && options.maxUploads) || Number.POSITIVE_INFINITY;\n const maxFileSize = (options && options.maxFileSize) || Number.POSITIVE_INFINITY;\n this.upload = new DataUploaderService(concurrency, allowedContentTypes, maxUploads, maxFileSize);\n\n this.el = this.elementRef.nativeElement as HTMLInputElement;\n\n this._sub.push(\n this.upload.serviceEvents.subscribe((event: UploadOutput) => {\n this.uploadOutput.emit(event);\n }),\n );\n\n const uploadInput = this.uploadInput();\n if (uploadInput instanceof EventEmitter) {\n this._sub.push(this.upload.initInputEvents(uploadInput));\n }\n\n this.el.addEventListener('drop', this.stopEvent, false);\n this.el.addEventListener('dragenter', this.stopEvent, false);\n this.el.addEventListener('dragover', this.stopEvent, false);\n }\n\n ngOnDestroy() {\n if (this._sub) {\n this._sub.forEach((sub) => sub.unsubscribe());\n }\n }\n\n stopEvent = (e: Event) => {\n e.stopPropagation();\n e.preventDefault();\n };\n\n /** Handles a drop: emits `drop`, then screens and queues the dropped files. Bound to the host `drop` event. */\n public onDrop(e: DragEvent) {\n e.stopPropagation();\n e.preventDefault();\n\n const event: UploadOutput = { type: 'drop' };\n this.uploadOutput.emit(event);\n if (e.dataTransfer) {\n this.upload.handleFiles(e.dataTransfer.files);\n }\n }\n\n /** Emits `dragOver` while a drag hovers the zone, for highlighting it. Bound to the host `dragover` event. */\n public onDragOver(e: Event) {\n if (!e) {\n return;\n }\n\n const event: UploadOutput = { type: 'dragOver' };\n this.uploadOutput.emit(event);\n }\n\n /** Emits `dragOut` when a drag leaves the zone, to clear the highlight. Bound to the host `dragleave` event. */\n public onDragLeave(e: Event) {\n if (!e) {\n return;\n }\n\n const event: UploadOutput = { type: 'dragOut' };\n this.uploadOutput.emit(event);\n }\n}\n","import { Directive, ElementRef, EventEmitter, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport { UploaderOptions, UploadOutput } from './interfaces';\nimport { DataUploaderService } from './ngx-uploader.class';\nimport { Subscription } from 'rxjs';\nimport { UploadInput } from './interfaces';\n\n@Directive({\n selector: '[dataFileSelect]',\n})\n/**\n * Attaches an upload queue to an `<input type=\"file\">`.\n *\n * Apply `dataFileSelect` to the input, bind `uploadOutput` to follow the queue and bind an\n * `EventEmitter<UploadInput>` to `uploadInput` to command it. Files are queued whenever\n * the input's selection changes; nothing is sent until you emit an `uploadAll` or\n * `uploadFile` command carrying the target url.\n *\n * The directive owns its own queue, so several inputs do not share state. See\n * {@link NgFileDropDirective} for the drag-and-drop counterpart.\n */\nexport class NgFileSelectDirective implements OnInit, OnDestroy {\n /** Queue limits ({@link UploaderOptions}). Read once in `ngOnInit`; later changes have no effect. */\n public options = input<UploaderOptions>();\n /** Command channel: emit {@link UploadInput}s on it to start, cancel or clear uploads. */\n public uploadInput = input<EventEmitter<UploadInput>>();\n /** Queue and transfer events ({@link UploadOutput}) for this input. */\n public uploadOutput = output<UploadOutput>();\n\n /** The queue backing this input, created in `ngOnInit`. */\n public upload!: DataUploaderService;\n public el!: HTMLInputElement;\n public elementRef = inject(ElementRef);\n\n private _sub!: Subscription[];\n\n ngOnInit() {\n this._sub = [];\n const options = this.options();\n const concurrency = (options && options.concurrency) || Number.POSITIVE_INFINITY;\n const allowedContentTypes = (options && options.allowedContentTypes) || ['*'];\n const maxUploads = (options && options.maxUploads) || Number.POSITIVE_INFINITY;\n const maxFileSize = (options && options.maxFileSize) || Number.POSITIVE_INFINITY;\n this.upload = new DataUploaderService(concurrency, allowedContentTypes, maxUploads, maxFileSize);\n\n this.el = this.elementRef.nativeElement as HTMLInputElement;\n this.el.addEventListener('change', this.fileListener, false);\n\n this._sub.push(\n this.upload.serviceEvents.subscribe((event: UploadOutput) => {\n this.uploadOutput.emit(event);\n }),\n );\n\n const uploadInput = this.uploadInput();\n if (uploadInput instanceof EventEmitter) {\n this._sub.push(this.upload.initInputEvents(uploadInput));\n }\n }\n\n ngOnDestroy() {\n if (this.el) {\n this.el.removeEventListener('change', this.fileListener, false);\n this._sub.forEach((sub) => sub.unsubscribe());\n }\n }\n\n fileListener = () => {\n if (this.el.files) {\n this.upload.handleFiles(this.el.files);\n }\n };\n}\n","import { NgModule } from '@angular/core';\nimport { NgFileDropDirective } from './ng-file-drop.directive';\nimport { NgFileSelectDirective } from './ng-file-select.directive';\n\n/**\n * @deprecated `NgFileDropDirective` and `NgFileSelectDirective` are now standalone —\n * import them directly instead of importing `NgxUploaderModule`. This module is kept\n * as a thin compatibility shim and will be removed in a future major version.\n */\n@NgModule({\n imports: [NgFileDropDirective, NgFileSelectDirective],\n exports: [NgFileDropDirective, NgFileSelectDirective],\n})\nexport class NgxUploaderModule {}\n","/**\n * File upload primitives: a queue engine ({@link DataUploaderService}) plus two host\n * directives, {@link NgFileSelectDirective} for `<input type=\"file\">` and\n * {@link NgFileDropDirective} for drop zones.\n *\n * The API — the `UploadInput`/`UploadOutput` command and event pair, the directive\n * selectors, the `UploaderOptions` limits — follows that of the ngx-uploader project, from\n * which this module is adapted, as the retained file names indicate; it has since been\n * updated for standalone directives and the signal-based `input()`/`output()` APIs.\n *\n * Uploads bypass Angular's `HttpClient` (and therefore its interceptors) in order to\n * report progress, so authenticated uploads must set their headers on the\n * {@link UploadInput}.\n */\nexport * from './interfaces';\nexport * from './ng-file-drop.directive';\nexport * from './ng-file-select.directive';\nexport * from './ngx-uploader.class';\nexport * from './ngx-uploader.module';\n","import { jwtDecode } from 'jwt-decode';\n\n/**\n * Body returned by the token endpoint ({@link AuthParams.tokenUrl}): a full token pair.\n * Shaped after SimpleJWT's `TokenObtainPair` response.\n */\nexport interface IJwtResponseJson {\n access: string;\n refresh: string;\n}\n\n/**\n * Body returned by the refresh endpoint ({@link AuthParams.tokenRefreshUrl}), which\n * renews only the access token — the refresh token is kept by the client.\n */\nexport interface IJwtRefreshResponseJson {\n access: string;\n}\n\n/**\n * Minimal claims the library needs from a decoded access token.\n *\n * Extend it with your backend's own claims and pass the result as the `UserData`\n * parameter of {@link AuthServiceBase}. `user_id` is the one claim actually used: it\n * tells the auth service which user record to fetch.\n */\nexport interface IJwtBaseData {\n // FIXME: check minimal jwt data\n token_type: 'access' | 'refresh';\n user_id: number;\n // exp: number;\n // jti: string;\n}\n\n/**\n * Immutable holder for an access/refresh token pair and the claims decoded from the\n * access token.\n *\n * Decoding is done with the `jwt-decode` package, which only base64-decodes the\n * payload: **it does not verify the signature, the issuer or the expiry**. Treat the\n * claims as a convenience for client-side routing and user lookup only; every real\n * authorization decision belongs to the backend, which validates the token itself.\n *\n * Constructed with no argument it represents the anonymous state (no tokens, `data`\n * is `null`).\n *\n * @typeParam UserJwtData - the decoded payload shape, at least {@link IJwtBaseData}.\n */\nexport class Jwt<UserJwtData extends IJwtBaseData> {\n public readonly access?: string;\n public readonly refresh?: string;\n private readonly _data: UserJwtData | null = null;\n\n /**\n * Builds a token pair from a token endpoint response, decoding the access token\n * immediately; with no argument, builds the anonymous instance.\n *\n * Throws (via `jwt-decode`) if `response.access` is not a well-formed JWT, so callers\n * handing over externally-supplied tokens should be ready for that.\n */\n constructor(response?: IJwtResponseJson) {\n if (response) {\n this.access = response.access;\n this._data = Object.freeze(jwtDecode<UserJwtData>(response.access));\n this.refresh = response.refresh;\n } else {\n this._data = null;\n }\n }\n\n /**\n * Claims decoded from the access token, frozen at construction, or `null` when this\n * instance is anonymous. Unverified — see the class documentation.\n */\n public get data(): UserJwtData | null {\n return this._data;\n }\n\n /**\n * Serializes the token pair (without the decoded claims, which are recomputed on\n * construction). Used by {@link AuthServiceBase.saveAuth} to persist the session.\n */\n public toJson() {\n return { access: this.access, refresh: this.refresh };\n }\n}\n","import { Injectable, InjectionToken, inject } from '@angular/core';\nimport { IJwtBaseData, IJwtRefreshResponseJson, IJwtResponseJson, Jwt } from './jwt';\nimport { HttpClient } from '@angular/common/http';\nimport { catchError, map, switchMap, tap } from 'rxjs/operators';\nimport { Observable, of, ReplaySubject, Subject, throwError } from 'rxjs';\nimport { DataModel } from '../data/data-model';\nimport { Collection } from '../data/data-collection';\nimport { Router } from '@angular/router';\nimport { DataMessageService } from '../messages/message.service';\n\n/**\n * What this service reads off a failed HTTP call: DRF puts an application-level\n * code in the response body, and interceptors may put one on the error itself.\n */\ninterface IApiErrorResponse {\n code?: string;\n error?: { code?: string };\n}\n\n/**\n * Complete configuration surface of the authentication layer.\n *\n * Provided through the {@link DATA_AUTH_PARAMS} injection token and consumed by\n * {@link AuthServiceBase}. The URL fields are used verbatim as HTTP endpoints (no base\n * url is prepended), and the route fields are passed as-is to `Router.navigate`.\n * The optional reactivate/password-reset members are feature switches: when a url is\n * absent, the matching method short-circuits and returns `of(false)` without any request.\n */\nexport interface AuthParams {\n /** Endpoint posted to by `login()` to exchange credentials for an access/refresh token pair. */\n tokenUrl: string;\n /** Endpoint posted to by `refresh()` with `{refresh: <token>}` to obtain a fresh access token. */\n tokenRefreshUrl: string;\n /** Endpoint for `requestReactivate()`, which asks the backend to send a reactivation token. Omit to disable the feature. */\n requestReactivateUrl?: string;\n /** Endpoint for `processReactivate()`, which submits the received reactivation token. Omit to disable the feature. */\n processReactivateUrl?: string;\n /** Endpoint for `requestPwReset()`, which asks the backend to send a password reset token. Omit to disable the feature. */\n requestPwResetUrl?: string;\n /** Endpoint for `processPwReset()`, which submits the new password along with the reset token. Omit to disable the feature. */\n processPwResetUrl?: string;\n /** Name of the payload field carrying the user identifier; used by every credential post (login, reactivate, password reset). */\n loginField: string;\n /** Name of the payload field carrying the password, used by `login()` and `processPwReset()`. */\n passwordField: string;\n /** Name of the payload field carrying the one-shot token in `processReactivate()` and `processPwReset()`. */\n tokenField: string;\n /** Router commands to the login page. Navigated to automatically when a token refresh fails. */\n loginRoute: string[];\n /** Router commands to the logout page. Exposed via `logoutRoute` for consumers to link to; the library never navigates there itself. */\n logoutRoute: string[];\n /** Router commands to the password reset page, exposed via `pwresetRoute` for consumers to link to. */\n pwresetRoute?: string[];\n /** Router commands to the account reactivation page, exposed via `reactivateRoute` for consumers to link to. */\n reactivateRoute?: string[];\n /**\n * Field names requested when loading the current user after login or token decode.\n * Defaults to a Django-flavoured set (id, username, email, names, staff/superuser flags, ...).\n */\n userFetchFields?: string[];\n /**\n * How long a fetched user stays fresh before `currentUser$` re-fetches it from the API.\n * Defaults to 3600 seconds.\n */\n userFetchValiditySeconds?: number;\n}\n\n/**\n * Authentication configuration ({@link AuthParams}) for {@link AuthServiceBase}.\n *\n * Must be provided by the application; the library ships no default. Use `useValue`\n * with a plain object.\n */\nexport const DATA_AUTH_PARAMS = new InjectionToken<AuthParams>('data.auth.params');\n\n/**\n * The {@link Collection} used to load and instantiate the authenticated user model.\n *\n * Wire it with **`useExisting`** so it aliases the application's own singleton user\n * service rather than creating a second one:\n *\n * ```ts\n * providers: [\n * UserService,\n * { provide: DATA_AUTH_USER_SERVICE, useExisting: UserService },\n * ]\n * ```\n *\n * Using `useClass` here would give the auth layer a private instance whose cache and\n * state diverge from the one the rest of the application uses.\n */\nexport const DATA_AUTH_USER_SERVICE = new InjectionToken<Collection<DataModel>>('data.auth.user.service');\n\n/**\n * Generic JWT authentication service, meant to be **extended** by the application.\n *\n * It owns the token pair, the current user, and their persistence in `localStorage`\n * under the `auth` key. Subclass it with your own user model, user collection and JWT\n * payload shape, then provide the subclass both as itself and behind\n * {@link DATA_AUTH_SERVICE} (via `useExisting`) so that {@link AuthInterceptor} and\n * `ModelListService` observe the very same instance:\n *\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * export class AuthService extends AuthServiceBase<User, UserService, UserJwtData> {}\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideHttpClient(withInterceptorsFromDi()),\n * UserService,\n * AuthService,\n * { provide: DATA_AUTH_USER_SERVICE, useExisting: UserService },\n * { provide: DATA_AUTH_SERVICE, useExisting: AuthService },\n * { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },\n * {\n * provide: DATA_AUTH_PARAMS,\n * useValue: {\n * tokenUrl: '/path/to/token',\n * tokenRefreshUrl: '/path/to/token/refresh',\n * loginField: 'username',\n * passwordField: 'password',\n * tokenField: 'token',\n * loginRoute: ['/', 'auth', 'login'],\n * logoutRoute: ['/', 'auth', 'logout'],\n * } satisfies AuthParams,\n * },\n * ],\n * });\n * ```\n *\n * The constructor calls {@link autoLogin}, so a stored session is restored as soon as\n * the service is instantiated.\n *\n * @typeParam User - the application user model.\n * @typeParam UserService - the {@link Collection} able to fetch that model.\n * @typeParam UserData - the decoded JWT payload, at least an {@link IJwtBaseData}.\n */\n@Injectable()\nexport class AuthServiceBase<\n User extends DataModel,\n UserService extends Collection<User>,\n UserData extends IJwtBaseData,\n> {\n /**\n * Emits every time {@link logout} runs, whether triggered by the user, by a failed\n * token refresh, or by a login error.\n *\n * This is the library's session-teardown signal: `ModelListService` subscribes to it\n * and resets all of its cached model lists, so that data belonging to the previous\n * session is never served to the next one. Application code can subscribe for the\n * same purpose.\n */\n public logout$: Subject<void> = new Subject<void>();\n private _user!: User;\n private _user$ = new ReplaySubject<User | null>(1);\n private _token!: Jwt<UserData>;\n private _fetched?: number;\n\n /** Collection used to fetch the logged-in user, from {@link DATA_AUTH_USER_SERVICE}. */\n public userService = inject<UserService>(DATA_AUTH_USER_SERVICE);\n private _params = inject<AuthParams>(DATA_AUTH_PARAMS);\n private _router = inject(Router);\n private _http = inject(HttpClient);\n private _msgs = inject(DataMessageService);\n\n constructor() {\n this.autoLogin();\n }\n\n /** True when no access token is held, i.e. no session is active. Checked by {@link AuthInterceptor} before attaching a token. */\n public get isAnonymous(): boolean {\n return !this._token.access;\n }\n\n /** Current raw access token, or `null` when anonymous. Read by {@link AuthInterceptor} to build the `Authorization` header. */\n public get accessToken(): string | null {\n return this._token.access ? this._token.access : null;\n }\n\n /** Current raw refresh token, or `null` when anonymous. Posted to {@link AuthParams.tokenRefreshUrl} by {@link refresh}. */\n public get refreshToken(): string | null {\n return this._token.refresh ? this._token.refresh : null;\n }\n\n /**\n * Synchronous snapshot of the logged-in user, or `null` if there is none.\n * Returns the cached instance without triggering a fetch — use {@link currentUser$}\n * when freshness matters.\n */\n public get currentUser(): User | null {\n return this._user && this._user.id ? this._user : null;\n }\n\n /**\n * The logged-in user as a stream, emitting `null` when the session ends.\n *\n * Re-fetches the user from the API when the cached copy is older than\n * {@link AuthParams.userFetchValiditySeconds} (default 3600), so a long-lived session\n * eventually picks up server-side changes such as group membership.\n */\n public get currentUser$(): Observable<User | null> {\n // Needs refresh ?\n if (\n !this.isAnonymous &&\n (!this._fetched || Date.now() - this._fetched > (this._params.userFetchValiditySeconds || 3600) * 1000)\n ) {\n this._fetched = Date.now();\n return this._fetchUser().pipe(\n switchMap(() => {\n return this._user$.asObservable();\n }),\n );\n }\n return this._user$.asObservable();\n }\n\n /** Configured token refresh endpoint. Also read by {@link AuthInterceptor}, which never attaches a token to it. */\n public get refreshUrl(): string {\n return `${this._params.tokenRefreshUrl}`;\n }\n\n /** Configured token (login) endpoint. Also read by {@link AuthInterceptor}, which never attaches a token to it. */\n public get loginUrl(): string {\n return `${this._params.tokenUrl}`;\n }\n\n /** Router commands to the login page, for building links or redirects in the application. */\n public get loginRoute(): string[] {\n return this._params.loginRoute;\n }\n\n /** Router commands to the logout page, for building links in the application. */\n public get logoutRoute(): string[] {\n return this._params.logoutRoute;\n }\n\n /** Router commands to the password reset page, or `undefined` when the feature is not configured. */\n public get pwresetRoute(): string[] | undefined {\n return this._params.pwresetRoute;\n }\n\n /** Router commands to the account reactivation page, or `undefined` when the feature is not configured. */\n public get reactivateRoute(): string[] | undefined {\n return this._params.reactivateRoute;\n }\n\n /**\n * Ends the session: clears the stored `auth` entry, drops the token and user, emits\n * `null` on {@link currentUser$} and fires {@link logout$}.\n *\n * Purely local — no request is sent to the backend. It does not navigate either;\n * redirect using {@link logoutRoute} if needed.\n */\n public logout(): void {\n localStorage.removeItem('auth');\n\n this._token = new Jwt();\n this._user = this.userService.create();\n this._user$.next(null);\n this.logout$.next();\n }\n\n /**\n * Restores a session previously written to `localStorage` by {@link saveAuth}, and\n * falls back to {@link logout} when there is nothing stored.\n *\n * Called from the constructor, so consumers rarely need to invoke it themselves.\n * The restored token is trusted as-is; expiry is only discovered when the API first\n * answers 401 and {@link AuthInterceptor} triggers a refresh.\n */\n public autoLogin(): void {\n const localAuth = localStorage.getItem('auth');\n if (!localAuth) {\n return this.logout();\n }\n const { user, fetched, token } = JSON.parse(localAuth) as {\n user: Partial<User>;\n fetched: number;\n token: IJwtResponseJson;\n };\n this._token = new Jwt(token);\n this._user = this.userService.create(user);\n this._fetched = fetched;\n this._user$.next(this._user);\n }\n\n /**\n * Exchanges credentials for a token pair, loads the matching user and persists the\n * session.\n *\n * Never errors: on failure it logs out and emits the backend's error code (or\n * `'error'` when none is available), so callers can branch on the emitted string\n * rather than on an error callback.\n */\n public login(username: string, password: string): Observable<'success' | 'error' | 'invalid_token' | (string & {})> {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n payload[this._params.passwordField] = password;\n return this._http.post<IJwtResponseJson>(this.loginUrl, payload).pipe(\n tap((tok) => {\n this._token = new Jwt(tok);\n }),\n switchMap(() => {\n return this._fetchUser();\n }),\n map(() => 'success'),\n tap(() => this.saveAuth()),\n catchError((error: IApiErrorResponse) => {\n this.logout();\n const code = error.error?.code || error.code || 'error';\n console.error(code, error);\n return of(code);\n }),\n );\n }\n\n /**\n * Opens a session from an already-obtained token pair instead of credentials, for\n * flows where the tokens arrive out of band (SSO callback, impersonation, tests).\n *\n * Like {@link login}, it fetches the user, saves the session and reports failures as\n * an emitted code rather than an error.\n */\n public loginWithToken(\n accessToken: string,\n refreshToken: string,\n ): Observable<'success' | 'error' | 'invalid_token' | (string & {})> {\n this._token = new Jwt({\n access: accessToken,\n refresh: refreshToken,\n });\n return this._fetchUser().pipe(\n map(() => 'success'),\n tap(() => this.saveAuth()),\n catchError((error: IApiErrorResponse) => {\n this.logout();\n const code = error.error?.code || error.code || 'error';\n console.error(code, error);\n return of(code);\n }),\n );\n }\n\n /**\n * Asks the backend to send an account reactivation token to the given user.\n *\n * Emits `false` — without any request — when {@link AuthParams.requestReactivateUrl}\n * is not configured, and also when the request fails, so a failure and a disabled\n * feature are indistinguishable to the caller.\n */\n public requestReactivate(username: string): Observable<boolean> {\n if (this._params.requestReactivateUrl) {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n return this._http.post<unknown>(this._params.requestReactivateUrl, payload).pipe(\n map(() => true),\n catchError(() => of(false)),\n );\n }\n return of(false);\n }\n\n /**\n * Asks the backend to send a password reset token to the given user.\n *\n * Emits `false` when {@link AuthParams.requestPwResetUrl} is not configured or when\n * the request fails. Pair it with {@link processPwReset} to complete the flow.\n */\n public requestPwReset(username: string): Observable<boolean> {\n if (this._params.requestPwResetUrl) {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n return this._http.post<unknown>(this._params.requestPwResetUrl, payload).pipe(\n map(() => true),\n catchError(() => of(false)),\n );\n }\n return of(false);\n }\n\n /**\n * Completes the reactivation flow by submitting the token the user received.\n *\n * Emits `false` when {@link AuthParams.processReactivateUrl} is not configured or when\n * the token is rejected. Success does not open a session — call {@link login} afterwards.\n */\n public processReactivate(username: string, token: string): Observable<boolean> {\n if (this._params.processReactivateUrl) {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n payload[this._params.tokenField] = token;\n return this._http.post<unknown>(this._params.processReactivateUrl, payload).pipe(\n map(() => true),\n catchError(() => of(false)),\n );\n }\n return of(false);\n }\n\n /**\n * Completes the password reset flow by submitting the new password together with the\n * token the user received.\n *\n * Emits `false` when {@link AuthParams.processPwResetUrl} is not configured or when the\n * token is rejected. Success does not open a session — call {@link login} afterwards.\n */\n public processPwReset(username: string, password: string, token: string): Observable<boolean> {\n if (this._params.processPwResetUrl) {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n payload[this._params.passwordField] = password;\n payload[this._params.tokenField] = token;\n return this._http.post<unknown>(this._params.processPwResetUrl, payload).pipe(\n map(() => true),\n catchError(() => of(false)),\n );\n }\n return of(false);\n }\n\n /**\n * Persists the current user, token pair and fetch timestamp to `localStorage` under\n * the `auth` key, and pushes the user onto {@link currentUser$}.\n *\n * When anonymous it removes the entry instead. Called automatically after login, user\n * fetch and token refresh; call it manually only after mutating the cached user.\n */\n public saveAuth() {\n if (this.isAnonymous) {\n localStorage.removeItem('auth');\n this._user$.next(null);\n } else {\n localStorage.setItem(\n 'auth',\n JSON.stringify({\n user: this._user.toJson() as Record<string, unknown>,\n fetched: Date.now(),\n token: this._token.toJson(),\n }),\n );\n this._user$.next(this._user);\n }\n }\n\n /**\n * Trades the refresh token for a new access token and saves the session.\n *\n * Mainly driven by {@link AuthInterceptor} when the API answers 401. Emits `null` when\n * there is no refresh token or the backend refuses it; in that case it also logs out,\n * shows a warning through {@link DataMessageService} and navigates to\n * {@link AuthParams.loginRoute}.\n */\n public refresh(): Observable<IJwtRefreshResponseJson | null> {\n if (!this._token.refresh) {\n console.error('No refresh token available');\n this.logout();\n return of(null);\n }\n return this._http\n .post<IJwtRefreshResponseJson>(this.refreshUrl, {\n refresh: this._token.refresh,\n })\n .pipe(\n catchError((err, caught) => {\n console.error('Token refresh error', err, caught);\n this.logout();\n this._msgs.warning('Vous devez vous reconnecter');\n void this._router.navigate(this._params.loginRoute);\n return of(null);\n }),\n tap((tok) => {\n console.log('Token refresh response', tok);\n if (tok) {\n this._token = new Jwt({\n access: tok.access,\n refresh: this._token.refresh!,\n });\n this.saveAuth();\n }\n }),\n );\n }\n\n private _fetchUser(): Observable<User> {\n if (this._token.data && this._token.data.user_id) {\n // Fetch user data using token\n return this.userService\n .fetch(this._token.data.user_id, {\n params: {\n fields: (\n this._params.userFetchFields || [\n 'id',\n 'username',\n 'email',\n 'last_name',\n 'first_name',\n 'is_superuser',\n 'is_active',\n 'is_staff',\n 'last_login',\n 'current_groups_slugs',\n ]\n ).join(','),\n },\n })\n .pipe(\n tap((u) => {\n this._user = u;\n this.saveAuth();\n }),\n );\n } else {\n return throwError(() => {\n return { code: 'invalid_token' };\n });\n }\n }\n}\n","import { Route, Router } from '@angular/router';\nimport { fieldValues } from '../data/field-values';\n\n/**\n * Template function type.\n * Used for page title or other data to string operations.\n *\n * @param data: object\n * @param path: optional path (see: usage)\n */\nexport type TplFn<T> = (data: T, path?: string) => string;\n\n/**\n * Base route parameters interface.\n */\nexport interface BaseRouteParams {\n /** Skip route in breadcrumbs */\n skip?: boolean;\n /** Route title or title template */\n // Callers declare the data shape their template reads; `object` would\n // reject it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n title?: string | TplFn<any>;\n /** Route icon string */\n icon?: string;\n /** Route config item */\n route: RouteConfigItem;\n /** This route is a tree route */\n tree?: boolean;\n}\n\n/**\n * Route function type.\n * Takes parameters, return a route.\n *\n * The parameters are `any` on purpose: a route builder is written against the\n * models it links to (`(product: Product) => [...]`), and such a function is not\n * assignable to one declared over `unknown[]`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type RouteFn = (...args: any[]) => (string | number)[];\n\n/**\n * Route config item.\n * Stores route named parameters, route function and route name.\n */\nexport interface RouteConfigItem {\n params: string[];\n route: RouteFn;\n name: string;\n}\n\n/**\n * Identity helper that type-checks a route `data` literal against {@link BaseRouteParams}\n * while preserving its literal type.\n *\n * Use it when declaring routes so that mistakes in the `data` block are caught at\n * compile time instead of surfacing as a blank breadcrumb at runtime.\n */\nexport function RData<T extends BaseRouteParams>(value: T) {\n return value;\n}\n\n/**\n * A map of route names to their {@link RouteConfigItem}, keyed by a string-literal union\n * so that every name is known statically and typos are compile errors.\n */\nexport type RoutesConfig<T extends string> = Readonly<Record<T, RouteConfigItem>>;\n\n/** An Angular {@link Route} whose `data` is mandatory and typed as {@link BaseRouteParams}. */\nexport interface StrictRoutes extends Route {\n data: BaseRouteParams;\n}\n\n/** A route table built from {@link StrictRoutes}, i.e. where every route carries breadcrumb metadata. */\nexport type RoutesDefinition = StrictRoutes[];\n\ntype RouteArg<T> = Record<string, T>;\n\n/**\n * A bound, reusable reference to a route: it pairs a {@link RouteConfigItem} with a\n * context object from which the route's named parameters are read.\n *\n * The point is to build links without repeating parameter plumbing at each call site:\n * give it a context (a model instance, say) once, and {@link route} or {@link navigate}\n * will pull the declared parameters from it. Parameters can still be overridden per\n * call, and a missing one is reported on the console while yielding an empty route\n * rather than throwing.\n */\nexport class Link<T> {\n private _cargs: Record<string, unknown> = {};\n private _params: string[] = [];\n private _route: RouteFn;\n private _router?: Router;\n\n /**\n * Builds a link from a route config, optionally binding a context and a router.\n *\n * Passing a `router` here is what lets {@link navigate} be called without arguments\n * later. A missing `config` is tolerated (it warns and produces an inert link) so that\n * a partially-initialised template does not crash.\n */\n constructor(config?: RouteConfigItem, context?: object, router?: Router) {\n if (!config) {\n console.warn('Link created without config');\n }\n this._params = config?.params || [];\n this._route = config?.route || (() => []);\n this._router = router;\n this._name = config?.name || '';\n if (context) {\n this.context(context);\n }\n }\n\n private _name!: string;\n\n /** Name of the underlying route config item, or an empty string when the link was built without config. */\n public get name(): string {\n return this._name;\n }\n\n /**\n * Rebinds the object the route parameters are read from, replacing any previous\n * context. Only the parameters declared by the route config are picked up; those\n * missing from `ctx` are reset to `null`, not left over from the previous context.\n */\n public context(ctx: object): void {\n const values = fieldValues(ctx ?? {});\n for (const n of this._params) {\n if (values[n]) {\n this._cargs[n] = values[n];\n } else {\n this._cargs[n] = null;\n }\n }\n }\n\n /**\n * Builds the router commands array, resolving each declared parameter from `params`\n * first and falling back to the bound context.\n *\n * Suitable for `[routerLink]`. If a parameter cannot be resolved from either source it\n * logs an error and returns an empty array, which routerLink renders as a link to the\n * current url — so an empty result means a missing parameter, not a valid route.\n */\n public route(params?: Required<RouteArg<T>>): (string | number)[] {\n const rargs: unknown[] = [];\n for (const n of this._params) {\n if (params && params[n] !== undefined && params[n] !== null) {\n rargs.push(params[n]);\n } else if (this._cargs[n] !== undefined && this._cargs[n] !== null) {\n rargs.push(this._cargs[n]);\n } else {\n console.error('Missing route parameter', n);\n return [];\n }\n }\n // SEE: Check for undefined in rargs\n return this._route(...rargs);\n }\n\n /**\n * Resolves the route and navigates to it, using the router given here or the one bound\n * at construction.\n *\n * Resolves to `false` without navigating when no router is available from either\n * source; otherwise it resolves with the router's own result.\n */\n public async navigate(params?: Record<string, T>, router?: Router): Promise<boolean> {\n if (router) {\n return router.navigate(this.route(params));\n }\n if (this._router) {\n return this._router.navigate(this.route(params));\n }\n console.error('Router not provided, no navigation');\n return false;\n }\n}\n","import { Component, DestroyRef, inject, input, OnInit, signal } from '@angular/core';\nimport {\n ActivatedRoute,\n ActivatedRouteSnapshot,\n NavigationEnd,\n Router,\n RouterModule,\n RouterState,\n UrlSegment,\n} from '@angular/router';\nimport { filter } from 'rxjs/operators';\nimport { BaseRouteParams } from '../routing';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n/** One rendered breadcrumb entry: its absolute path, label, icon classes, and whether it is the active leaf. */\nexport interface IPathTreeItem {\n path: string;\n title: string;\n icon: string;\n current: boolean;\n}\n\n/**\n * Builds a breadcrumb for the active route from the {@link BaseRouteParams} declared in\n * each route's `data` block.\n *\n * It walks the router state from the root down to the leaf, and rebuilds itself on every\n * `NavigationEnd`, so a single instance in the layout keeps up with navigation. Each\n * route contributes an entry unless its config sets `skip`; routes marked `tree` emit one\n * entry per url segment, which is how a nested path renders as several crumbs.\n *\n * Route config data used here:\n * - `title`: a literal string, or a {@link TplFn} called with the route's `data` (and, for\n * `tree` routes, the current segment path) to compute the label.\n * - `icon`: icon classes, e.g. `fa fa-home` for Font Awesome.\n * - `skip`: exclude this route from the breadcrumb.\n * - `tree`: expand each url segment of this route into its own entry.\n *\n * Note that the icon and title are read from different sources: the icon comes from the\n * resolved route `data`, whereas the title comes from the static `routeConfig.data`.\n */\n@Component({\n selector: 'data-breadcrumb',\n templateUrl: './breadcrumb.component.html',\n styleUrls: ['./breadcrumb.component.css'],\n imports: [RouterModule],\n})\nexport class BreadcrumbComponent implements OnInit {\n /**\n * Additional data to be used in titleTemplate\n */\n public data = input<object>();\n /**\n * Do we display icons ?\n */\n public icons = input<boolean>(true);\n /** The computed breadcrumb entries, recomputed on every navigation and rendered by the template. */\n public tree = signal<IPathTreeItem[]>([]);\n public router = inject(Router);\n public route = inject(ActivatedRoute);\n private destroy$ = inject(DestroyRef);\n\n ngOnInit(): void {\n this.getRouteTree(this.router.routerState);\n this.router.events\n .pipe(\n takeUntilDestroyed(this.destroy$),\n filter((event) => event instanceof NavigationEnd),\n )\n .subscribe(() => {\n this.getRouteTree(this.router.routerState);\n });\n }\n\n /**\n * Walks the router state from root to leaf and rebuilds {@link tree}, accumulating url\n * segments so each entry gets an absolute path and flagging the last one as `current`.\n *\n * Called on init and on every `NavigationEnd`; public mainly so it can be driven\n * directly in tests.\n */\n public getRouteTree(current: RouterState): void {\n const tree: IPathTreeItem[] = [];\n const url: string[] = [];\n let p: ActivatedRouteSnapshot | null = current.root.snapshot;\n\n while (p != null) {\n let rdata: Partial<BaseRouteParams> = {\n tree: false,\n title: () => 'xxxx',\n icon: '',\n skip: true,\n };\n const data = p.data as BaseRouteParams;\n\n // Get route data\n if (p.routeConfig && p.routeConfig.data) {\n rdata = p.routeConfig.data;\n }\n\n if (rdata.tree) {\n // Get icon\n for (const u of p.url) {\n url.push(u.path);\n const rtd: IPathTreeItem = {\n icon: this.getIcon(rdata, data),\n title: this.getTitle(rdata, data, u),\n path: url.join('/'),\n current: false,\n };\n if (rtd.path.length > 0 && rtd.path[0] !== '/') {\n rtd.path = '/' + rtd.path;\n }\n if (!rdata.skip) {\n tree.push(rtd);\n }\n }\n } else {\n url.push(p.url.join('/'));\n const rtd: IPathTreeItem = {\n icon: this.getIcon(rdata, data),\n title: this.getTitle(rdata, data),\n path: url.join('/'),\n current: false,\n };\n if (rtd.path.length > 0 && rtd.path[0] !== '/') {\n rtd.path = '/' + rtd.path;\n }\n if (!rdata.skip) {\n tree.push(rtd);\n }\n }\n\n p = p.firstChild;\n }\n if (tree.length > 0) {\n tree[tree.length - 1].current = true;\n }\n this.tree.set(tree);\n }\n\n /**\n * Resolves one crumb's label: returns the configured string as-is, or invokes the\n * configured {@link TplFn} with the route data and, for `tree` routes, the segment path.\n *\n * Falls back to placeholder strings (`'xxx'`, or `'xx'` if a title template threw) so a\n * broken template degrades to visible filler rather than an exception.\n */\n public getTitle(rdata: Partial<BaseRouteParams>, data: BaseRouteParams, u?: UrlSegment): string {\n if (rdata['title']) {\n if (typeof rdata['title'] === 'function') {\n const tpl = rdata['title'];\n try {\n if (u) {\n return tpl(data, u.path);\n } else {\n return tpl(data);\n }\n } catch (e) {\n console.warn('Unable to process breadcrumb function', e);\n if (data.title != null) {\n return 'xx';\n }\n }\n } else {\n return rdata['title'];\n }\n }\n return 'xxx';\n }\n\n /**\n * Resolves one crumb's icon classes from the resolved route `data`, returning an empty\n * string when none is set. The `rdata` argument is accepted for symmetry with\n * {@link getTitle} but is not consulted.\n */\n public getIcon(rdata: Partial<BaseRouteParams>, data: BaseRouteParams): string {\n if (data.icon) {\n return data.icon;\n }\n return '';\n }\n}\n","<nav aria-label=\"breadcrumb\">\n <ol class=\"breadcrumb\">\n @for (p of tree(); track p) {\n @if (!p.current) {\n <li class=\"breadcrumb-item\">\n <a class=\"breadcrumb-item\" [routerLink]=\"p.path\">\n @if (icons() && p.icon) {\n <i class=\"me-2\" [class]=\"p.icon\"></i>\n {{ p.title }}\n }\n @if (!(icons() && p.icon)) {\n {{ p.title }}\n }\n </a>\n </li>\n }\n @if (p.current) {\n <li class=\"breadcrumb-item active\" aria-current=\"page\">\n @if (icons() && p.icon) {\n <i class=\"me-1\" [class]=\"p.icon\"></i>\n {{ p.title }}\n }\n @if (!(icons() && p.icon)) {\n {{ p.title }}\n }\n </li>\n }\n }\n </ol>\n</nav>\n","import { Injectable } from '@angular/core';\nimport { UrlSegment } from '@angular/router';\n\ninterface ITabStoredMem {\n name: string;\n value: string;\n}\n\n/**\n * Remembers the selected tab for one target route.\n *\n * Created and handed out by {@link TabMemoryService.memFor}; bind {@link current} to your\n * tab set to read and update the selection. When the driver was created with saving\n * enabled, assigning `current` writes the whole memory back to `localStorage`.\n */\nexport class NavDriver {\n private lastActive!: Date;\n\n /**\n * Seeds the selection with `defaults`, then overrides it with the persisted value when\n * `save` is set and one is stored. Instantiated by {@link TabMemoryService}; not meant\n * to be constructed directly.\n */\n constructor(\n private _parent: TabMemoryService,\n public name: string,\n public defaults: string,\n private save: boolean,\n ) {\n this._current = this.defaults;\n if (this.save) {\n const value = this._parent.load(this.name);\n if (value !== null) {\n this._current = value;\n }\n }\n }\n\n private _current: string;\n\n /** The remembered tab identifier for this route: the persisted value, or the default. */\n public get current(): string {\n return this._current;\n }\n\n /** Records the newly selected tab and, when saving is enabled, persists the memory immediately. */\n public set current(value: string) {\n this._current = value;\n this.lastActive = new Date();\n if (this.save) {\n this._parent.save();\n }\n }\n\n /** This driver's serializable form, used by {@link TabMemoryService.save}. */\n public get value(): ITabStoredMem {\n return { name: this.name, value: this._current };\n }\n}\n\n/**\n * Remembers which tab the user last opened on each route, so returning to a page restores\n * the tab they left it on instead of snapping back to the default.\n *\n * It keys memories by route target — the route commands joined into a `/a/b/c` string —\n * and hands out a {@link NavDriver} per key through {@link memFor}. The whole map is\n * persisted in `localStorage` under the single `tabmem` key, so it survives reloads and is\n * shared across tabs of the same browser; pass `save: false` for a memory that lasts only\n * for the current page session.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class TabMemoryService {\n private tabMem: Record<string, NavDriver> = {};\n\n private static targetToString(target: (string | number | UrlSegment)[]): string {\n let out = '';\n for (const t of target) {\n out += `/${String(t)}`;\n }\n return out;\n }\n\n /**\n * Returns the {@link NavDriver} for a route target, creating it on first use and\n * returning the same instance afterwards.\n *\n * Call it from a tabbed page's init with the route commands and the default tab. Pass\n * the current url `fragment` to let a deep link win over the remembered selection —\n * a non-empty fragment overwrites the memory.\n */\n public memFor(\n target: (string | number | UrlSegment)[],\n defaults: string,\n save = true,\n fragment?: string | null,\n ): NavDriver {\n const tname = TabMemoryService.targetToString(target);\n if (this.tabMem[tname] === undefined) {\n this.tabMem[tname] = new NavDriver(this, tname, defaults, save);\n }\n if (fragment) {\n this.tabMem[tname].current = fragment;\n }\n return this.tabMem[tname];\n }\n\n /**\n * Writes every known driver to the `tabmem` entry of `localStorage`, replacing whatever\n * was there. Called automatically when a saving driver's selection changes.\n */\n public save() {\n const tosave: Record<string, ITabStoredMem> = {};\n for (const tn of Object.keys(this.tabMem)) {\n tosave[tn] = this.tabMem[tn].value;\n }\n localStorage.setItem('tabmem', JSON.stringify(tosave));\n }\n\n /**\n * Reads back one stored selection by its target key, returning `null` when nothing is\n * stored for it. Used by {@link NavDriver} on construction.\n */\n public load(name: string): string | null {\n const tm = localStorage.getItem('tabmem');\n if (tm) {\n const tmd = JSON.parse(tm) as Record<string, { value?: string }>;\n const entry = tmd[name];\n if (entry?.value) {\n return entry.value;\n }\n }\n return null;\n }\n}\n","/**\n * Turns arbitrary text into a lowercase, dash-separated ASCII slug, suitable for urls,\n * anchors or generated identifiers.\n *\n * It trims, lowercases, folds a fixed set of Latin-1 accented characters onto their ASCII\n * equivalents, maps separator-ish characters (`·/_,:;`) to dashes, drops anything else\n * outside `[a-z0-9 -]`, and collapses runs of whitespace and dashes. Only the listed\n * accents are handled, so scripts outside that set (Cyrillic, Greek, CJK, and Latin\n * letters such as `ø` or `ß`) are stripped rather than transliterated, and text made\n * entirely of them yields an empty string.\n */\nexport const slugify = (str: string): string => {\n str = str.replace(/^\\s+|\\s+$/g, ''); // trim\n str = str.toLowerCase();\n\n // remove accents, swap ñ for n, etc\n const from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;';\n const to = 'aaaaeeeeiiiioooouuuunc------';\n for (let i = 0, l = from.length; i < l; i++) {\n str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));\n }\n\n str = str\n .replace(/[^a-z0-9 -]/g, '') // remove invalid chars\n .replace(/\\s+/g, '-') // collapse whitespace and replace by -\n .replace(/-+/g, '-'); // collapse dashes\n\n return str;\n};\n","/**\n * Teach jsdom the layout APIs CodeMirror and ProseMirror expect.\n *\n * Both editors measure the document to place the caret and decide what to\n * render, and jsdom has no layout engine: `getClientRects()` returns an empty\n * list and `elementFromPoint` does not exist at all. Zeroed rectangles are\n * enough — nothing in a spec depends on real geometry, it just has to not throw.\n *\n * Call it from `beforeEach` in any spec that instantiates an editor view. It is\n * idempotent, and only patches what is missing.\n */\nexport function installEditorDomShims(): void {\n const rect = () => new DOMRect(0, 0, 0, 0);\n const rectList = () => {\n const list = [rect()] as unknown as DOMRectList & { item: (index: number) => DOMRect | null };\n list.item = (index: number) => (index === 0 ? rect() : null);\n return list;\n };\n if (!Range.prototype.getClientRects) {\n Range.prototype.getClientRects = rectList;\n }\n if (!Range.prototype.getBoundingClientRect) {\n Range.prototype.getBoundingClientRect = rect;\n }\n if (!Element.prototype.getClientRects) {\n Element.prototype.getClientRects = rectList;\n }\n if (!document.elementFromPoint) {\n document.elementFromPoint = () => null;\n }\n if (!document.createRange().getClientRects) {\n // jsdom builds ranges from the prototype patched above; this is only a\n // guard for the case where an environment overrides createRange.\n Range.prototype.getClientRects = rectList;\n }\n}\n","// By default, Underscore uses ERB-style template delimiters, change the\n// following template settings to use alternative delimiters.\nconst settings = {\n evaluate: /<%([\\s\\S]+?)%>/g,\n interpolate: /<%=([\\s\\S]+?)%>/g,\n escape: /<%-([\\s\\S]+?)%>/g,\n variable: 'obj',\n};\n\n// When customizing `templateSettings`, if you don't want to define an\n// interpolation, evaluation or escaping regex, we need one that is\n// guaranteed not to match.\nconst noMatch = /.^/;\n\n// Certain characters need to be escaped so that they can be put into a\n// string literal.\nconst escapes: Record<string, string> = {\n '\\\\': '\\\\',\n \"'\": \"'\",\n r: '\\r',\n n: '\\n',\n t: '\\t',\n u2028: '\\u2028',\n u2029: '\\u2029',\n};\n\nfor (const p in escapes) {\n escapes[escapes[p]] = p;\n}\n\nconst escaper = /\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g;\n\n/**\n * Compiles (and optionally renders) an Underscore-style string template, using ERB\n * delimiters: `<%= expr %>` interpolates, `<% code %>` evaluates, and a `print()` helper\n * is available inside evaluated code.\n *\n * Called with `data`, it renders immediately and returns the resulting string; without\n * `data`, it returns a reusable render function carrying a `source` property with the\n * generated code. `objectName` renames the variable the data is exposed under — but note\n * it mutates module-level settings, so it persists for subsequent calls too.\n *\n * Within this library it backs route title templates (see {@link TplFn}). Two caveats:\n * compilation goes through `new Function`, so it will not run under a Content Security\n * Policy without `unsafe-eval`; and the escaping delimiter `<%- expr %>` is not usable,\n * as the code it emits calls `_.escape` while no `_` is in scope.\n */\n/**\n * A template compiled by {@link tmpl} but not yet rendered: call it with the\n * data. `source` carries the generated JS, which is handy when debugging.\n */\nexport type CompiledTemplate = ((data: object) => string) & { source?: string };\n\nexport function tmpl(text: string, data: object, objectName?: string): string;\nexport function tmpl(text: string, data?: undefined, objectName?: string): CompiledTemplate;\nexport function tmpl(text: string, data?: object, objectName?: string): string | CompiledTemplate {\n if (objectName) {\n settings.variable = objectName;\n }\n\n // Compile the template source, taking care to escape characters that\n // cannot be included in a string literal and then unescape them in code\n // blocks.\n let source =\n \"__p+='\" +\n text\n .replace(escaper, function (match) {\n return '\\\\' + escapes[match];\n })\n .replace(settings.escape || noMatch, function (match, code: string) {\n return \"'+\\n_.escape(\" + unescape(code) + \")+\\n'\";\n })\n .replace(settings.interpolate || noMatch, function (match, code: string) {\n return \"'+\\n(\" + unescape(code) + \")+\\n'\";\n })\n .replace(settings.evaluate || noMatch, function (match, code: string) {\n return \"';\\n\" + unescape(code) + \"\\n;__p+='\";\n }) +\n \"';\\n\";\n\n // If a variable is not specified, place data values in local scope.\n if (!settings.variable) {\n source = 'with(obj||{}){\\n' + source + '}\\n';\n }\n\n source =\n \"var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\\n\" + source + 'return __p;\\n';\n\n // The whole point of this module: `source` is the template compiled to JS.\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n const render = new Function(settings.variable || 'obj', source) as (data?: object) => string;\n\n if (data) {\n return render(data);\n }\n\n const template = ((data: object) => {\n return render(data);\n }) as CompiledTemplate;\n\n // Provide the compiled function source as a convenience for build time\n // precompilation.\n template.source = 'function(' + (settings.variable || 'obj') + '){\\n' + source + '}';\n\n return template;\n}\n","import { ApplicationRef, inject, Injectable } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { SwUpdate, VersionReadyEvent } from '@angular/service-worker';\nimport { filter, first, map, tap } from 'rxjs/operators';\nimport { merge, Observable, ReplaySubject, timer } from 'rxjs';\n\n/**\n * Watches the service worker for a newly deployed version and exposes it as a simple\n * \"an update is available\" flag.\n *\n * It polls `SwUpdate.checkForUpdate()` once the application first becomes stable and\n * then every 5 minutes, and flips {@link available$} to `true` when the service worker\n * reports a `VERSION_READY` event. Injecting it is enough to start the polling; render\n * {@link UpdateComponent} (or your own UI on `available$`) to let the user act on it.\n * Harmless without a service worker: the checks fail and are logged as warnings.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class UpdateService {\n private stable = false;\n\n private appRef = inject(ApplicationRef);\n private swUpdate = inject(SwUpdate);\n\n constructor() {\n this._available$ = new ReplaySubject<boolean>(1);\n this._available$.next(false);\n const appIsStable$ = this.appRef.isStable\n .pipe(first((isStable) => isStable))\n .pipe(tap(() => console.log('App is stable')));\n const checkInterval$ = timer(10 * 1000, 5 * 60 * 1000);\n const checkWhenStable$ = merge(appIsStable$, checkInterval$);\n const updatesAvailable = this.swUpdate.versionUpdates.pipe(\n tap((evt) => console.log('Version updates event', evt)),\n filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'),\n map((evt) => ({\n type: 'UPDATE_AVAILABLE',\n current: evt.currentVersion,\n available: evt.latestVersion,\n })),\n );\n updatesAvailable.pipe(takeUntilDestroyed()).subscribe(() => {\n this._available$.next(true);\n });\n checkWhenStable$.pipe(takeUntilDestroyed()).subscribe(() => {\n this.stable = true;\n void this._checkForUpdate();\n });\n }\n\n private _available$: ReplaySubject<boolean>;\n\n /**\n * Asks the service worker whether a new version is available. Swallows the\n * failure raised when no service worker is registered, which is the normal\n * case in development.\n */\n private async _checkForUpdate(): Promise<void> {\n try {\n console.log('Checking for update');\n const res = await this.swUpdate.checkForUpdate();\n console.log('Check for update result', res);\n } catch {\n console.warn('No service worker');\n }\n }\n\n /**\n * Whether a new version is ready to be activated. Starts at `false`, becomes `true` on\n * `VERSION_READY`, and returns to `false` once the user activates or dismisses it.\n */\n public get available$(): Observable<boolean> {\n return this._available$.asObservable();\n }\n\n /**\n * Applies the pending update by reloading the page, discarding any unsaved in-memory\n * state. Call it from a user-initiated action rather than automatically.\n */\n public activate(): void {\n this._available$.next(false);\n console.log('RELOADING FULL PAGE');\n document.location.reload();\n }\n\n /**\n * Hides the update prompt without reloading. The update stays pending and the prompt\n * reappears the next time the service worker signals a ready version.\n */\n public dismiss(): void {\n this._available$.next(false);\n }\n}\n","import { Component, inject } from '@angular/core';\nimport { UpdateService } from '../update.service';\nimport { AsyncPipe } from '@angular/common';\n\n@Component({\n selector: 'data-update',\n templateUrl: './update.component.html',\n styleUrls: ['./update.component.sass'],\n imports: [AsyncPipe],\n})\n/**\n * Snackbar prompting the user to reload when {@link UpdateService} reports a new\n * application version, with \"activate now\" and \"later\" actions.\n *\n * Place one instance in the application shell; it renders nothing until an update is\n * actually available. The prompt text is French and not translatable — supply your own\n * component bound to `UpdateService.available$` if that does not suit.\n */\nexport class UpdateComponent {\n /** The update service backing the prompt; also bound directly by the template. */\n public update = inject(UpdateService);\n}\n","@if (update.available$ | async) {\n <div class=\"snack\">\n <p>Une nouvelle version de l'application est disponible.</p>\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <button class=\"btn btn-primary btn-block w-100\" (click)=\"update.activate()\">L'ACTIVER MAINTENANT</button>\n </div>\n <div class=\"col-sm-6\">\n <button class=\"btn btn-warning btn-block w-100\" (click)=\"update.dismiss()\">Plus tard</button>\n </div>\n </div>\n </div>\n}\n","/*\n * Public API Surface of data\n */\n/// <reference types=\"@angular/localize\" />\n\nexport * from './lib/data/data-parameters';\nexport * from './lib/data/data-model';\nexport * from './lib/data/field-values';\nexport * from './lib/data/data-collection';\nexport * from './lib/data/data-backend';\nexport * from './lib/data/data-query';\n\nexport * from './lib/modellist/model-list.service';\nexport * from './lib/modellist/model-list-fields/model-list-fields-selector/model-list-fields-selector.component';\nexport * from './lib/modellist/model-list-fields/model-list-field-header/model-list-field-header.component';\nexport * from './lib/modellist/model-list-sorter/model-list-sorter/model-list-sorter.component';\nexport * from './lib/modellist/model-list-filters/model-list-filters-select/model-list-filters-select.component';\nexport * from './lib/modellist/model-list-filters/model-list-filters/model-list-filters.component';\nexport * from './lib/modellist/model-list-filters/model-list-filters';\nexport * from './lib/modellist/model-list-filters/model-list-filter';\nexport * from './lib/modellist/model-list-filters/model-list-filter-group';\n\nexport * from './lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetimerange-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter';\n\nexport * from './lib/modellist/model-list-filters/filters/model-list-geodistance-filter/adapters/ban';\n\nexport * from './lib/modellist/model-list-paginator/model-list-paginator/model-list-paginator.component';\n\nexport * from './lib/dispedit/choice.pipe';\nexport * from './lib/dispedit/factor.pipe';\nexport * from './lib/dispedit/factorc.pipe';\nexport * from './lib/dispedit/dispedit/dispedit.component';\nexport * from './lib/dispedit/fkselect/fkselect.component';\nexport * from './lib/dispedit/m2mselect/m2mselect.component';\nexport * from './lib/dispedit/flags/flags.component';\n\nexport * from './lib/dispedit/sdelete/sdelete.component';\nexport * from './lib/data/fields/index';\nexport { BaseFieldManager } from './lib/data/fields/base';\n\nexport * from './lib/messages/message.service';\nexport * from './lib/messages/message-zone/message-zone.component';\n\nexport * from './lib/data/data-collection.mock';\nexport * from './lib/uploader/index';\n\nexport * from './lib/auth/auth.service';\nexport * from './lib/auth/auth-interceptor.service';\nexport * from './lib/auth/jwt';\n\nexport * from './lib/routing/routing';\nexport * from './lib/routing/breadcrumb/breadcrumb.component';\n\nexport * from './lib/utils/tab-memory.service';\nexport * from './lib/utils/slugify';\nexport * from './lib/utils/unique-id';\nexport * from './lib/utils/editor-dom-shims';\nexport * from './lib/utils/template';\n\nexport * from './lib/updates/update.service';\nexport * from './lib/updates/update/update.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2"],"mappings":"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"}
1
+ {"version":3,"file":"solidev-data.mjs","sources":["../../../projects/data/src/lib/data/data-parameters.ts","../../../projects/data/src/lib/data/field-values.ts","../../../projects/data/src/lib/data/fields/base.ts","../../../projects/data/src/lib/data/fields/primaryfield.ts","../../../projects/data/src/lib/data/data-model.ts","../../../projects/data/src/lib/data/data-query.ts","../../../projects/data/src/lib/data/data-collection.ts","../../../projects/data/src/lib/data/data-backend.ts","../../../projects/data/src/lib/modellist/model-list-fields/model-list-fields.ts","../../../projects/data/src/lib/modellist/model-list-paginator/model-list-paginator.ts","../../../projects/data/src/lib/modellist/model-list-sorter/model-list-sorter.ts","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters.ts","../../../projects/data/src/lib/auth/auth-interceptor.service.ts","../../../projects/data/src/lib/modellist/model-list.service.ts","../../../projects/data/src/lib/modellist/model-list-fields/model-list-fields-selector/model-list-fields-selector.component.ts","../../../projects/data/src/lib/modellist/model-list-fields/model-list-fields-selector/model-list-fields-selector.component.html","../../../projects/data/src/lib/modellist/model-list-sorter/model-list-sorter/model-list-sorter.component.ts","../../../projects/data/src/lib/modellist/model-list-sorter/model-list-sorter/model-list-sorter.component.html","../../../projects/data/src/lib/modellist/model-list-fields/model-list-field-header/model-list-field-header.component.ts","../../../projects/data/src/lib/modellist/model-list-fields/model-list-field-header/model-list-field-header.component.html","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters-select/model-list-filters-select.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters-select/model-list-filters-select.component.html","../../../projects/data/src/lib/utils/unique-id.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetime-range-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetime-range-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter.component.html","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters/model-list-filters.component.ts","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filters/model-list-filters.component.html","../../../projects/data/src/lib/modellist/model-list-filters/model-list-filter-group.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetimerange-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter.ts","../../../projects/data/src/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/adapters/ban.ts","../../../projects/data/src/lib/modellist/model-list-paginator/model-list-paginator/model-list-paginator.component.ts","../../../projects/data/src/lib/modellist/model-list-paginator/model-list-paginator/model-list-paginator.component.html","../../../projects/data/src/lib/dispedit/choice.pipe.ts","../../../projects/data/src/lib/dispedit/factor.pipe.ts","../../../projects/data/src/lib/dispedit/factorc.pipe.ts","../../../projects/data/src/lib/dispedit/fkselect/fkselect.component.ts","../../../projects/data/src/lib/dispedit/fkselect/fkselect.component.html","../../../projects/data/src/lib/messages/message.service.ts","../../../projects/data/src/lib/editors/safe-html.pipe.ts","../../../projects/data/src/lib/dispedit/m2mselect/m2mselect.component.ts","../../../projects/data/src/lib/dispedit/m2mselect/m2mselect.component.html","../../../projects/data/src/lib/dispedit/dispedit/dispedit.component.ts","../../../projects/data/src/lib/dispedit/dispedit/dispedit.component.html","../../../projects/data/src/lib/dispedit/flags/flags.component.ts","../../../projects/data/src/lib/dispedit/flags/flags.component.html","../../../projects/data/src/lib/dispedit/sdelete/sdelete.component.ts","../../../projects/data/src/lib/dispedit/sdelete/sdelete.component.html","../../../projects/data/src/lib/data/fields/stringfields.ts","../../../projects/data/src/lib/data/fields/datetime.ts","../../../projects/data/src/lib/data/fields/relations.ts","../../../projects/data/src/lib/data/fields/boolean.ts","../../../projects/data/src/lib/data/fields/numbers.ts","../../../projects/data/src/lib/data/fields/computed.ts","../../../projects/data/src/lib/data/fields/index.ts","../../../projects/data/src/lib/messages/message-zone/message-zone.component.ts","../../../projects/data/src/lib/messages/message-zone/message-zone.component.html","../../../projects/data/src/lib/data/data-query.mock.ts","../../../projects/data/src/lib/data/data-collection.mock.ts","../../../projects/data/src/lib/uploader/interfaces.ts","../../../projects/data/src/lib/uploader/ngx-uploader.class.ts","../../../projects/data/src/lib/uploader/ng-file-drop.directive.ts","../../../projects/data/src/lib/uploader/ng-file-select.directive.ts","../../../projects/data/src/lib/uploader/ngx-uploader.module.ts","../../../projects/data/src/lib/uploader/index.ts","../../../projects/data/src/lib/auth/jwt.ts","../../../projects/data/src/lib/auth/auth.service.ts","../../../projects/data/src/lib/routing/routing.ts","../../../projects/data/src/lib/routing/breadcrumb/breadcrumb.component.ts","../../../projects/data/src/lib/routing/breadcrumb/breadcrumb.component.html","../../../projects/data/src/lib/utils/tab-memory.service.ts","../../../projects/data/src/lib/utils/slugify.ts","../../../projects/data/src/lib/utils/editor-dom-shims.ts","../../../projects/data/src/lib/editors/field-editor-base.ts","../../../projects/data/src/lib/utils/template.ts","../../../projects/data/src/lib/updates/update.service.ts","../../../projects/data/src/lib/updates/update/update.component.ts","../../../projects/data/src/lib/updates/update/update.component.html","../../../projects/data/src/public-api.ts","../../../projects/data/src/solidev-data.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/**\n * Base URL of the REST API every {@link Collection} builds its endpoints on.\n *\n * This token is **required**: {@link DataBackend} injects it without `@Optional()`,\n * so an application that forgets to provide it fails at injection time rather than\n * at the first request. The value is prepended verbatim to each collection path\n * (`apiUrl + path`), so it must **not** carry a trailing slash — collection paths\n * are expected to start with one.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [{ provide: DATA_API_URL, useValue: 'https://api.example.com/v1' }],\n * });\n * // a Collection on '/path/to/things' then hits\n * // https://api.example.com/v1/path/to/things\n * ```\n */\nexport const DATA_API_URL = new InjectionToken<string>('data.api.url');\n/**\n * Time window, in milliseconds, during which {@link DataBackend} may answer GET\n * requests from Angular's `TransferState` instead of hitting the network.\n *\n * This token is **optional** and defaults to `0`, which disables TransferState\n * entirely — both the server-side write and the browser-side read are skipped.\n * Provide a positive value only in an SSR application that wants the server's\n * GET responses replayed on hydration.\n *\n * The window is measured from the moment the `DataBackend` instance was created,\n * not per cache entry: once more than this many milliseconds have elapsed since\n * bootstrap, every GET goes back to the network for the rest of the session.\n * A value slightly larger than the expected hydration time is the intent.\n *\n * Caching is additionally opt-out per collection via `Collection.useTransferState`.\n *\n * @example\n * ```ts\n * providers: [{ provide: DATA_MAX_TRANSFERSTATE_TIME, useValue: 10000 }]\n * ```\n */\nexport const DATA_MAX_TRANSFERSTATE_TIME = new InjectionToken<number>('data.max.transfer.state');\n\n/**\n * CSS class names and default modes the display/edit widgets apply to the inputs\n * they generate.\n *\n * The library renders form controls from field metadata, so it has to pick the\n * markup classes itself. Rather than hard-coding a CSS framework, it reads them\n * from here, which is what lets the same models render under Bootstrap, Tailwind\n * or a bespoke design system.\n *\n * Provide an implementation through {@link DATA_DISPLAY_CONFIG}; see\n * {@link BootstrapDataDisplayConfig} for a complete example.\n */\nexport interface DataDisplayConfig {\n dispEdit: {\n /**\n * Layout used by `dispedit` when a component does not request one explicitly:\n * `\"inline\"` renders the value in flow, `\"dd\"` renders it as a definition\n * list entry.\n */\n defaultMode: 'inline' | 'dd';\n /**\n * Class string per editor type, keyed by the editor names used in\n * `DISPEDIT_EDITOR_TYPES` (e.g. `\"input.text\"`, `\"select\"`). A missing key\n * simply yields no class.\n */\n inputClasses: Record<string, string>;\n };\n}\n\n/**\n * Bootstrap 5 flavour of {@link DataDisplayConfig}, and the fallback used when no\n * {@link DATA_DISPLAY_CONFIG} is provided.\n *\n * Useful as a starting point: spread it and override the entries you need rather\n * than restating the whole map.\n */\nexport const BootstrapDataDisplayConfig: DataDisplayConfig = {\n dispEdit: {\n defaultMode: 'dd',\n inputClasses: {\n 'input.text': 'form-control',\n 'input.email': 'form-control',\n 'input.datetime': 'form-control',\n 'input.date': 'form-control',\n 'input.number': 'form-control',\n 'input.decimal': 'form-control',\n 'input.checkbox': 'form-control',\n 'input.password': 'form-control',\n textarea: 'form-control',\n fkselect: 'form-control',\n select: 'form-select',\n },\n },\n};\n\n/**\n * Styling contract for the generated display/edit widgets.\n *\n * This token is **optional**: consumers that do not provide it get\n * {@link BootstrapDataDisplayConfig} (Bootstrap 5 classes). Provide it once at\n * bootstrap to retarget every `dispedit`-family component at another CSS\n * framework without touching the components themselves.\n *\n * @example\n * ```ts\n * providers: [{\n * provide: DATA_DISPLAY_CONFIG,\n * useValue: {\n * dispEdit: {\n * defaultMode: 'inline',\n * inputClasses: { 'input.text': 'my-input', select: 'my-select' },\n * },\n * },\n * }]\n * ```\n */\nexport const DATA_DISPLAY_CONFIG = new InjectionToken<DataDisplayConfig>('data.display.config');\n","// Deliberately dependency-free: `fields/base.ts` needs this, and `data-model.ts`\n// imports from `fields/base.ts` -- putting it in either would close a cycle.\n\n/**\n * A model seen as the untyped property bag it also is.\n *\n * Fields are declared by decorators and reached by name at runtime — `dispedit`\n * reads `<field>_details`, filters read `filter.field` — so the data layer\n * constantly indexes models with a string the compiler cannot resolve. This is\n * the one sanctioned way to do it: it yields `unknown`, so the value has to be\n * narrowed where it is used instead of silently becoming `any` and disabling\n * type-checking for the rest of the expression.\n *\n * ```ts\n * const details = fieldValues(model)[`${field}_details`] as R[] | undefined;\n * fieldValues(model)[field] = event.id;\n * ```\n *\n * @param target model (or any object) to index by field name\n */\nexport function fieldValues(target: object): Record<string, unknown> {\n return target as Record<string, unknown>;\n}\n\n/**\n * Renders an unknown value as display text.\n *\n * `String(value)` is not enough here: values read through {@link fieldValues}\n * can be objects, and `String({})` yields `[object Object]`. Nullish becomes an\n * empty string, objects are JSON-encoded, everything else goes through\n * `String`.\n *\n * @param value value read off a model, a form or a payload\n */\nexport function asText(value: unknown): string {\n if (value === null || value === undefined) {\n return '';\n }\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n // Objects were handled above; what is left stringifies meaningfully.\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return String(value);\n}\n","import { FormControl, ValidatorFn, Validators } from '@angular/forms';\nimport { fieldValues } from '../field-values';\nimport { DataModel } from '../data-model';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\n\n/**\n * Symbol under which every field's metadata is stored, directly on the model\n * class prototype. The library deliberately does not depend on\n * `reflect-metadata`: a plain `Map` hung off this Symbol is the whole store.\n */\nexport const PROPERTY_METADATA_KEY = Symbol('ngxDataMetadata');\n\n/**\n * The per-prototype field store: `` `${__name}__${propertyKey}` `` → metadata.\n *\n * Stockage des métadonnées sur le prototype via Symbol, sans reflect-metadata.\n */\ntype MetadataMap = Map<string, IFieldStoredMetadata<unknown>>;\n\n/**\n * The metadata store hung off a prototype under {@link PROPERTY_METADATA_KEY}.\n * A symbol key, so this cannot go through `fieldValues()`.\n */\nfunction metadataStore(target: object): {\n [PROPERTY_METADATA_KEY]?: MetadataMap;\n} {\n return target;\n}\n\n/**\n * Returns the metadata map owned by `target`, creating it on first use.\n *\n * When a subclass prototype does not own a map yet, the inherited one is\n * copied rather than shared, so a subclass can declare its own fields without\n * leaking them back onto its parent.\n */\nfunction getOrCreateFieldsMap(target: object): MetadataMap {\n if (!Object.prototype.hasOwnProperty.call(target, PROPERTY_METADATA_KEY)) {\n const inherited = metadataStore(target)[PROPERTY_METADATA_KEY];\n const map: MetadataMap = inherited\n ? new Map<string, IFieldStoredMetadata<unknown>>(inherited)\n : new Map<string, IFieldStoredMetadata<unknown>>();\n Object.defineProperty(target, PROPERTY_METADATA_KEY, {\n value: map,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return map;\n }\n return metadataStore(target)[PROPERTY_METADATA_KEY]!;\n}\n\n/**\n * Reads the field metadata declared on a model, accepting either the class\n * itself or an instance/prototype. Returns `undefined` for a class that has no\n * decorated field anywhere in its chain.\n *\n * @param target model class, prototype or instance\n */\nexport function getFieldsMetadata(target: object): MetadataMap | undefined {\n const proto = typeof target === 'function' ? (target as { prototype: object }).prototype : target;\n return metadataStore(proto)[PROPERTY_METADATA_KEY];\n}\n\n/**\n * Options common to every field decorator. All are optional; each concrete\n * field type extends this with its own (`ICharFieldMetadata`, etc.).\n *\n * Whatever you pass to a decorator is copied verbatim onto the field's manager\n * instance, so these names double as the manager's public properties.\n *\n * @typeParam FT the JavaScript type the field holds on the model\n */\nexport interface IFieldMetadata<FT> {\n /**\n * Wire name of the field: the key used in the JSON payload. Defaults to the\n * decorated property name, so it only needs setting when the API name and\n * the TypeScript property name differ.\n */\n name?: string;\n /** Short hint shown next to the editor. Defaults to an empty string. */\n help?: string;\n /**\n * Human-readable label used for column titles, form labels and hover\n * details. Defaults to {@link IFieldMetadata.name} when omitted.\n */\n description?: string;\n /**\n * Marks the field as mandatory: adds `Validators.required` and forces a\n * value to be present on save.\n *\n * Beware: combining `required: true` with no `defaultValue` throws at class\n * definition time — see {@link BaseFieldManager.getDefaultValue}.\n */\n required?: boolean;\n /**\n * Field is display-only: it is excluded from generated form groups and never\n * pushed back to the API. Typical for server-maintained columns and for the\n * `*_details` half of a relation.\n */\n readonly?: boolean;\n /**\n * Value used when the model has no value for this field — either a constant\n * or a factory `(args) => FT` evaluated on each call, which is how you get a\n * fresh array/date per instance instead of a shared one.\n */\n defaultValue?: FT | ((args: FieldDefaultArgs) => FT) | null;\n /**\n * Display ordering weight: **higher is shown first**. `id` uses `1000`.\n *\n * `priority: -1` is the established idiom for \"deserialise this field but\n * never offer it in the UI\" — negative-priority fields are dropped from the\n * default column set. It is used for the id half of every relation, whose\n * `*_details` twin is what a human is meant to see.\n */\n priority?: number;\n}\n\n/**\n * Runtime behaviour of a single field: one manager instance is built per\n * decorated property, at class definition time, and cached in the prototype's\n * metadata map. Everything the library does with a field — serialise it,\n * validate it, build its form control, pick its widget — goes through here.\n *\n * Subclass it only to add a genuinely new field type; the shipped managers\n * (`CharFieldManager`, `ForeignKeyFieldManager`, ...) cover the usual cases.\n * Override `fromJson`/`toJson` to change the wire mapping and\n * `getValidators()` to add constraints.\n */\nexport class BaseFieldManager<FT> implements IFieldMetadata<FT> {\n /** Name is mandatory in a field manager. It is given by\n * field decorator if not directly given in field manager. */\n public name!: string;\n /** Human-readable label; falls back to {@link name} when not given. */\n public description!: string;\n /** Input hint; normalised to `''` when not given. */\n public help!: string;\n /** Whether a value must be present. Adds `Validators.required`. */\n public required = false;\n /** Whether the field is excluded from forms and never written back. */\n public readonly = false;\n /**\n * Set to `true` only by `ComputedFieldManager`. `DataModel.setFV` skips\n * assignment entirely for computed fields, making them permanently\n * read-only in the eyes of the model.\n */\n public computed = false;\n /** Display ordering weight; higher is shown first. See {@link IFieldMetadata.priority}. */\n public priority = 0;\n /** Constant or factory used when the model has no value. */\n public defaultValue?: FT | ((args: FieldDefaultArgs) => FT);\n\n /**\n * Which editor widget `dispedit` renders for this field in edit mode.\n *\n * This is the library's central idea: **declaring the model configures the\n * UI**. Managers set this themselves from what you declared — `charField`\n * flips to `'select'` as soon as `choices` is present, `foreignKeyField`\n * uses `'fkselect'`, `manyToManyField` `'m2mselect'` — so a correct model\n * yields the right editor with no per-template wiring.\n */\n public editorType: DISPEDIT_EDITOR_TYPES = 'input.text';\n /**\n * Which read-only renderer `dispedit` uses for this field. Chosen by the\n * manager the same way as {@link editorType} (`'fkdetails'` for a foreign\n * key, `'m2mdetails'` for a m2m, `'decimal'` for `decimalField`, ...).\n */\n public displayType: DISPEDIT_DISPLAY_TYPES = 'text';\n\n /**\n * Copies `params` onto the instance, fills in `name`/`description`/`help`\n * defaults, then eagerly resolves the default value — which means a\n * `required` field with no `defaultValue` throws here, at decoration time.\n *\n * @param params metadata as passed to the decorator\n */\n constructor(params: IFieldMetadata<FT>) {\n Object.assign(this, params);\n if (!this.name) {\n this.name = 'noname';\n }\n if (!this.description) {\n this.description = this.name;\n }\n if (!this.help) {\n this.help = '';\n }\n this.getDefaultValue();\n }\n\n /**\n * Angular validators for this field, rebuilt on each access. Subclasses\n * override this getter (not {@link getValidators}) to append their own —\n * `CharFieldManager` adds length/pattern, `IntegerFieldManager` min/max.\n */\n public get validators(): ValidatorFn[] {\n return this.getValidators();\n }\n\n /**\n * The bare property name, stripped of any `Model__` prefix: splits\n * {@link name} on `'__'` and returns the second segment, or the whole name\n * when there is no separator.\n */\n public get fname(): string {\n return this.name.split('__')[1] || this.name;\n }\n\n /**\n * Builds a typed `FormControl` for this field on a given model instance,\n * seeded with the instance's current value and falling back to the default\n * value, and wired with {@link validators}.\n *\n * Note the seed uses `||`, so falsy current values (`0`, `''`, `false`) fall\n * back to the default rather than being kept.\n *\n * @param instance model whose value seeds the control\n */\n public formControl(instance: DataModel): FormControl<FT | null> {\n return new FormControl<FT>(\n (fieldValues(instance)[this.fname] as FT) || (this.getDefaultValue() as FT),\n this.validators,\n );\n }\n\n /**\n * Converts a raw JSON value coming from the API into the model value.\n * The base implementation passes the data straight through; typed managers\n * override it to coerce (`boolean`), parse (`date`) or instantiate\n * (`details`).\n *\n * @param data raw value read from the JSON payload\n */\n public fromJson(data: unknown): FT {\n return data as FT;\n }\n\n /**\n * Converts the model value back into its JSON representation for save.\n * The base implementation passes the data straight through.\n *\n * @param data current model value\n */\n public toJson(data: FT): unknown {\n return data;\n }\n\n /**\n * Renders the value for display. The base implementation is plain string\n * interpolation.\n *\n * @param data value to render\n * @param _format reserved; ignored by the base implementation\n */\n public toString(data: FT, _format = 'default'): string {\n return String(data);\n }\n\n /**\n * Public accessor for this field's default value, invoking the\n * `defaultValue` factory with `args` when one was declared.\n *\n * @param args passed through to a `defaultValue` function\n */\n public default(args: FieldDefaultArgs = {}): FT | undefined {\n return this.getDefaultValue(args);\n }\n\n /**\n * Builds the base validator list: `Validators.required` when the field is\n * required, nothing otherwise. Subclasses call it and push their own.\n *\n * @protected\n */\n protected getValidators(): ValidatorFn[] {\n const v: ValidatorFn[] = [];\n if (this.required) {\n // eslint-disable-next-line @typescript-eslint/unbound-method -- Validators.* are static and `this`-free\n v.push(Validators.required);\n }\n return v;\n }\n\n /**\n * Resolves the default value: calls `defaultValue` when it is a function,\n * otherwise returns it as-is.\n *\n * **Throws** when the field is `required` and no `defaultValue` was given.\n * Because the constructor calls this, the error surfaces when the class is\n * defined (module evaluation), not when a model is instantiated — a\n * `required` field without a default breaks the app at import time.\n *\n * @param args passed through to a `defaultValue` function\n * @throws Error if `required` is set and `defaultValue` is `undefined`\n * @protected\n */\n protected getDefaultValue(args: FieldDefaultArgs = {}): FT | undefined {\n if (this.defaultValue instanceof Function) {\n return this.defaultValue(args);\n }\n if (this.required && this.defaultValue === undefined) {\n throw new Error(`Field ${this.name} : no default value for required field`);\n }\n return this.defaultValue;\n }\n}\n\n/**\n * What is actually kept in a model's metadata map: the options you passed to\n * the decorator, plus the four entries the decorator computes. This is the\n * shape returned by {@link getFieldsMetadata}.\n */\nexport interface IFieldStoredMetadata<FT> extends IFieldMetadata<FT> {\n /** Map key of this entry: `` `${__name}__${propertyKey}` ``. */\n self: string;\n /** Wire name; defaulted to the decorated property name. */\n name: string;\n /** Field type code, e.g. `'charField'`, `'foreignKeyField'`. */\n type: string;\n /** The live manager instance built for this field. */\n manager: BaseFieldManager<FT>;\n}\n\n/**\n * Arguments handed to a `defaultValue` factory. Free-form: callers pass\n * whatever the factory needs, and the factory knows what to expect.\n */\nexport type FieldDefaultArgs = Record<string, unknown>;\n\n/** Manager constructor\n * FT is js field type;\n * T is manager type\n * */\ntype BaseFieldManagerConstructor<MD, T> = new (params: MD) => T;\n\n/**\n * Shape of every field decorator returned by {@link genericDataField}: a plain\n * property decorator, applied for its side effect on the prototype's metadata\n * map.\n */\nexport type FieldDecoratorFn = (target: object, propertyKey: string | symbol) => void;\n\n/**\n * The factory behind every field decorator in the library — `charField`,\n * `foreignKeyField` and the rest are all one-line calls to it. Reach for it\n * only when adding a new field type of your own.\n *\n * The returned decorator registers the field on the class prototype under\n * `` `${__name}__${propertyKey}` ``, defaults `name` to the property name, and\n * instantiates `manager` immediately — so any error a manager raises in its\n * constructor (a `required` field with no default, for instance) is thrown\n * while the class is being defined.\n *\n * Every decorator except `primaryField` **throws** unless the decorated class\n * declares a `static __name`, since that string is half of the metadata key.\n *\n * @param meta field metadata, copied verbatim into the store and the manager\n * @param type field type code, e.g. `'charField'`\n * @param manager manager class to instantiate for this field\n * @throws Error if the class has no `static __name` (non-`primaryField` types)\n * @throws Error if the same field is declared twice\n */\nexport function genericDataField<FT, MD extends IFieldMetadata<FT>, MG extends BaseFieldManager<FT>>(\n meta: MD,\n type: string,\n manager: BaseFieldManagerConstructor<MD, MG>,\n): FieldDecoratorFn {\n return (target: object, propertyKey: string | symbol) => {\n // Utilisation du store symbolisé au lieu de Reflect\n const allMetadata = getOrCreateFieldsMap(target);\n const cname = `${String((target.constructor as { __name?: string }).__name)}`;\n if ((cname === `undefined` || cname === '') && type !== 'primaryField') {\n throw Error(\n `Decorator ${type} allowed only on classes with static __name ` +\n `field : \"${cname}\" found on field \"${String(propertyKey)}\"`,\n );\n }\n const pk = `${cname}__${String(propertyKey)}`;\n let cm = allMetadata.get(pk);\n /* istanbul ignore if */\n if (cm) {\n throw Error(`Field ${pk} already defined = ${JSON.stringify(cm)}`);\n }\n cm = { ...meta } as unknown as IFieldStoredMetadata<unknown>;\n if (meta.name === undefined) {\n cm.name = `${String(propertyKey)}`;\n }\n cm.type = type;\n cm.self = pk;\n // `cm` is `meta` plus the resolved name/type/self, so it is an `MD`;\n // the copy above loses that on the way through the stored shape.\n cm.manager = new manager(cm as unknown as MD);\n allMetadata.set(pk, cm);\n // Plus besoin de Reflect.defineMetadata : la Map est déjà stockée sur le prototype.\n };\n}\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\n\n/**\n * Options for {@link primaryField}.\n */\nexport interface IPrimaryFieldMetadata extends IFieldMetadata<number> {\n /** Increment hint for the identifier. Declarative only; unused at runtime. */\n step?: number;\n}\n\n/**\n * Manager for the model's primary key. It adds nothing to the base behaviour\n * beyond {@link IPrimaryFieldMetadata.step}: the id is carried as a plain\n * number, with the base pass-through serialisation.\n */\nexport class PrimaryFieldManager extends BaseFieldManager<number> implements IPrimaryFieldMetadata {\n /** Increment hint. Declarative only; nothing reads it. */\n public step = 1;\n}\n\n/**\n * Declares the model's primary key. `DataModel` already declares `id` with it\n * (`priority: 1000`, so it sorts first), so you rarely need this yourself —\n * only to give a model a differently-named identifier.\n *\n * Unlike every other field decorator, `primaryField` does **not** require the\n * class to declare a `static __name`; it is the one type exempted from that\n * check, which is what lets `DataModel` itself declare `id`.\n *\n * @param updates field options\n */\nexport const primaryField = (updates: IPrimaryFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'primaryField', PrimaryFieldManager);\n","import { BaseFieldManager, getFieldsMetadata, IFieldStoredMetadata } from './fields/base';\nimport { fieldValues } from './field-values';\nimport { primaryField } from './fields/primaryfield';\nimport { FormControl, FormGroup, ValidationErrors } from '@angular/forms';\nimport { Collection } from './data-collection';\nimport { Observable, throwError } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\n/**\n * Resolved field metadata of a model instance, keyed by field name.\n *\n * This is what {@link DataModel.F} exposes: the flattened result of walking the\n * class chain and collecting every decorated field. UI components (list headers,\n * filters, `dispedit`) read this map to render themselves without knowing the\n * concrete model.\n */\nexport type DataModelFields = Readonly<Map<string, IFieldStoredMetadata<unknown>>>;\n\n/**\n * The class a prototype-chain level belongs to, as the library sees it: a\n * constructor carrying the `__name` every model declares.\n */\nfunction modelClassOf(level: object): { name: string; __name?: string } {\n return (level as { constructor: { name: string; __name?: string } }).constructor;\n}\n\n/**\n * Base class for every model in the library: a plain class whose fields are\n * declared with field decorators, which turns it into something the rest of the\n * stack can introspect.\n *\n * Extending `DataModel` buys three things. Field metadata is collected at\n * construction and exposed via {@link F}/{@link FN}/{@link FM}, so generic UI can\n * render a model it has never seen. Serialization to and from the API's JSON is\n * handled by {@link fromJson}/{@link toJson} through each field's manager. And,\n * when the instance carries a {@link Collection} (which it does whenever it was\n * built by one), {@link save}/{@link update}/{@link action} give it CRUD against\n * the REST endpoint.\n *\n * **Every class in the chain must declare a unique `static override readonly\n * __name`.** The constructor matches metadata keys against\n * `constructor.__name + '__'` as it walks the prototype chain, so a class whose\n * `__name` is missing, empty, or duplicated from another class contributes *no\n * fields at all* — silently, with no error, and the model simply behaves as if\n * those fields were never declared. This is the single most common newcomer bug;\n * if a field mysteriously does not render or round-trip, check `__name` first.\n * The property exists because minifiers rewrite `constructor.name`, so the real\n * class name cannot be relied on at runtime.\n *\n * Fields are collected most-derived-first, so a subclass redeclaring a field name\n * overrides the parent's metadata for it.\n *\n * @example\n * ```ts\n * export class ThingBase extends DataModel {\n * static override readonly __name = 'ThingBase';\n *\n * @charField({ name: 'name', description: 'Name' })\n * public name!: string;\n * }\n *\n * export class Thing extends ThingBase {\n * static override readonly __name = 'Thing'; // unique, and required again here\n * }\n * ```\n */\nexport class DataModel {\n /**\n * Unique per-class identifier used to attribute decorated fields to the class\n * that declared them.\n *\n * Must be redeclared as `static override readonly __name = '<UniqueName>'` on\n * **every** subclass, including intermediate abstract-ish base classes, and\n * must be unique across the whole model set. It cannot be derived from\n * `constructor.name` because minification rewrites it. A missing or duplicated\n * value silently drops that class's fields — see the class-level docs.\n */\n protected static readonly __name: string = '';\n\n /**\n * Server-assigned primary key, and the flag the CRUD layer dispatches on:\n * `Collection.save()`/`update()` PATCH an existing record when `id` is defined\n * and POST a new one when it is `undefined`.\n *\n * Declared and decorated **once, here**, so every model inherits the metadata.\n * Consumers must **never** write `@primaryField() override id` on a subclass:\n * under `useDefineForClassFields: true` a redeclared field is re-initialized to\n * `undefined` at construction, shadowing the value the base class set and\n * making every save look like a create.\n */\n @primaryField({ name: 'id', description: 'ID', priority: 1000 })\n public id!: number;\n /** Backing store for {@link F}, computed once in the constructor. */\n private readonly _F: DataModelFields;\n\n /**\n * Resolves this instance's field metadata by walking its prototype chain.\n *\n * Field decorators record metadata under `'<__name>__<field>'` keys, so the\n * constructor climbs from the concrete class up to `Object`, and at each level\n * claims the keys prefixed with that class's `__name`. Because the walk is\n * most-derived-first and a name is only claimed once, a subclass redeclaring a\n * field wins over its parent. Classes whose `__name` matches nothing simply\n * contribute nothing — this is where a missing or duplicated `__name` silently\n * loses fields.\n *\n * @param _coll collection this instance belongs to; supplies the endpoint for\n * {@link save}, {@link update} and {@link action}. Instances built by hand\n * (`new Thing()`) have none, and those methods will error until one is set\n * via {@link _collection}.\n * @throws Error if no field metadata is reachable at all, which should be\n * impossible since `DataModel` itself declares `id`.\n */\n // `Collection<any>`, deliberately. `DataModelType<T>` is `new (_coll?:\n // Collection<T>) => T`, so a subclass has to stay assignable to a\n // constructor taking a collection *of itself*. Naming any concrete type\n // here -- `Collection<DataModel>` included -- closes that loop and makes\n // `new Collection(backend, url, MyModel)` stop type-checking for every\n // model in every consumer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(protected _coll?: Collection<any>) {\n // Remplacement de Reflect.getMetadata par getFieldsMetadata\n const md: Map<string, IFieldStoredMetadata<unknown>> | undefined = getFieldsMetadata(this);\n // istanbul ignore if\n if (!md) {\n // This should never occur as all datamodel have at least id field\n throw new Error('No property metadata found for this object; is there a property in current collection ?');\n }\n // Get all fields from current class and its parents\n const fields = new Map<string, IFieldStoredMetadata<unknown>>();\n let parent: object = Object.getPrototypeOf(this) as object;\n while (modelClassOf(parent).name !== 'Object') {\n for (const f of md.keys()) {\n const fieldName = f.split('__')[1];\n if (fields.has(fieldName)) {\n continue;\n }\n if (f.indexOf(`${modelClassOf(parent).__name}__`) === 0) {\n fields.set(fieldName, md.get(f)!);\n }\n }\n parent = Object.getPrototypeOf(parent) as object;\n }\n this._F = Object.freeze(fields);\n }\n\n /**\n * Collection backing this instance's CRUD calls.\n *\n * Set it on models you built by hand — `collection.create()`/`fromJson()` wire\n * it for you — otherwise {@link save}, {@link update} and {@link action} fail\n * with \"Missing collection\". The getter casts away the optional, so it lies\n * about `undefined` on an unattached model.\n */\n // `Collection<any>`, deliberately. `DataModelType<T>` is `new (_coll?:\n // Collection<T>) => T`, so a subclass has to stay assignable to a\n // constructor taking a collection *of itself*. Naming any concrete type\n // here -- `Collection<DataModel>` included -- closes that loop and makes\n // `new Collection(backend, url, MyModel)` stop type-checking for every\n // model in every consumer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public get _collection(): Collection<any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return this._coll as Collection<any>;\n }\n\n // `Collection<any>`, deliberately. `DataModelType<T>` is `new (_coll?:\n // Collection<T>) => T`, so a subclass has to stay assignable to a\n // constructor taking a collection *of itself*. Naming any concrete type\n // here -- `Collection<DataModel>` included -- closes that loop and makes\n // `new Collection(backend, url, MyModel)` stop type-checking for every\n // model in every consumer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public set _collection(coll: Collection<any>) {\n this._coll = coll;\n }\n\n /**\n * Field metadata for this instance, keyed by field name.\n *\n * The introspection entry point: generic components iterate this to discover\n * what a model has (type, label, priority, editor, validators) without any\n * compile-time knowledge of the class. Frozen and computed once at\n * construction.\n */\n public get F(): DataModelFields {\n // istanbul ignore if\n if (!this._F) {\n throw new Error('Invalid data model, fields metadata is missing');\n }\n return this._F;\n }\n\n /**\n * Names of every declared field, in declaration order (most-derived class\n * first). Handy shorthand for iterating a model generically; use\n * `Array.from(model.FN)` when you need a real array.\n */\n public get FN(): IterableIterator<string> {\n return this.F.keys();\n }\n\n /**\n * Populates this instance from an API JSON payload, running each value through\n * its field manager's deserializer (dates become `Date`s, nested details become\n * models, and so on).\n *\n * This is what `Collection.fromJson()` calls, and what you call yourself to\n * merge a server response back into an existing instance.\n *\n * @param data raw JSON object keyed by field name\n * @param partial when `true`, only fields actually present in `data` are\n * touched — use it for PATCH responses. When `false` (the default), *every*\n * declared field is assigned, so fields absent from `data` are reset to\n * whatever their manager makes of `undefined`.\n * @param check when `true`, each value is validated before assignment and a\n * failing field keeps its previous value\n * @returns `null` when everything was accepted, otherwise an object mapping the\n * offending field names to their `ValidationErrors`. Note that valid fields\n * are still applied even when others fail — this reports, it does not roll back.\n */\n public fromJson(\n data: object,\n { partial, check }: { partial?: boolean; check?: boolean } = {\n partial: false,\n check: false,\n },\n ): null | ValidationErrors {\n const errors: Record<string, null | ValidationErrors> = {};\n let haveError = false;\n for (const f of this.FN) {\n if (!partial || (partial && Object.keys(data).indexOf(f) !== -1)) {\n const ferr = this.setFV(f, this.FM(f).fromJson(fieldValues(data)[f]), check);\n if (ferr !== null) {\n errors[f] = ferr;\n haveError = true;\n }\n }\n }\n return haveError ? errors : null;\n }\n\n /**\n * Serializes this instance to a plain JSON object for the API, running each\n * value through its field manager's serializer.\n *\n * The two calling conventions differ in more than scope, and the difference\n * matters when writing:\n *\n * - `toJson()` — every field **except** those marked `readonly`. This is what\n * `Collection.save()` sends, so server-computed fields are never echoed back.\n * - `toJson(fields)` — only the named fields, and `readonly` is **not** applied.\n * This is what `Collection.update()` sends; naming a readonly field here will\n * put it in the payload.\n *\n * An empty array behaves like the no-argument form.\n *\n * @param fields single field name or list of names to restrict the output to\n */\n // The payload's shape is the model's own, which only the caller knows.\n // Narrowing this to `Record<string, unknown>` would force every consumer\n // reading a property off the result to cast, so it stays `any` until a major.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public toJson(fields?: string | string[]): any {\n if (fields && !Array.isArray(fields)) {\n fields = [fields];\n }\n const out: Record<string, unknown> = {};\n const fl = this.F;\n for (const f of this.FN) {\n const mgr = this.FM(f);\n if (!fields || fields.length === 0) {\n if (mgr.readonly) {\n continue;\n }\n out[f] = fl.get(f)!.manager.toJson(this.FV(f));\n } else {\n if (fields.indexOf(f) !== -1) {\n out[f] = fl.get(f)!.manager.toJson(this.FV(f));\n }\n }\n }\n return out;\n }\n\n /**\n * Calls a custom endpoint hanging off this record — the DRF `@action`\n * convention, i.e. `/path/to/things/<id>/<name>` — for the operations that are\n * not plain CRUD (`publish`, `duplicate`, `send`, ...).\n *\n * @param method HTTP method to use\n * @param name action name, appended to this record's detail URL\n * @param body JSON body to send\n * @param update when `true`, the response is fed back into this instance via\n * {@link fromJson}, so the model reflects whatever the action changed\n * @param updatePartial `partial` flag for that write-back; defaults to `true`,\n * which is what you want for the usual \"action returns the changed fields\"\n * response\n * @param updateCheck `check` flag for that write-back (validate before assigning)\n * @param params query parameters\n * @param headers extra headers\n * @returns an observable of the **raw response body**, not of this model, even\n * when `update` is `true`\n */\n // `T` is unused, but it comes first in the parameter list: removing it\n // would silently change what `action<A, B>()` call sites mean.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public action<T, RT extends object>(\n method: 'POST' | 'PATCH' | 'GET' | 'DELETE' | 'PUT',\n name: string,\n {\n body = undefined,\n update = false,\n updatePartial = true,\n updateCheck = false,\n // updateRaise = false,\n params = {},\n headers = {},\n }: {\n body?: object;\n update?: boolean;\n updatePartial?: boolean;\n updateCheck?: boolean;\n // updateRaise?: boolean;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {},\n ): Observable<RT> {\n if (this._coll === undefined) {\n return throwError(() => new Error('Missing collection'));\n }\n return this._coll\n .action<RT>(this, method, name, {\n body,\n params,\n headers,\n })\n .pipe(\n tap((result) => {\n if (update) {\n this.fromJson(result, {\n partial: updatePartial,\n check: updateCheck,\n });\n return this;\n }\n return result;\n }),\n );\n }\n\n /**\n * Returns a field's manager — the object holding its metadata and its\n * serialize/validate/render behaviour.\n *\n * The workhorse behind generic rendering: `FM(f).description` for a label,\n * `FM(f).readonly` to decide whether to offer an editor, `FM(f).toString(v)`\n * to display a value.\n *\n * @param field field name, as declared\n * @throws Error if the field is not declared on this model — which, for a field\n * you are sure you declared, usually means a missing or duplicated `__name`\n * on the declaring class rather than a typo here.\n */\n public FM<FT>(field: string): BaseFieldManager<FT> {\n if (this.F.has(field)) {\n // The map is keyed by name and holds managers of every field type; only\n // the caller knows which one this field is.\n return this.F.get(field)!.manager as BaseFieldManager<FT>;\n }\n throw new Error(\n `${field} not found in [${[...this.FN].join(',')}] ` +\n `on model ${(this.constructor as typeof DataModel).__name}`,\n );\n }\n\n /**\n * Reads a field's value by name, for code that only knows the field at runtime.\n *\n * The `FT` type parameter is an unchecked assertion, not a conversion: nothing\n * verifies the stored value matches. Prefer direct property access\n * (`thing.name`) wherever the field is statically known.\n *\n * @param field field name\n */\n public FV<FT>(field: string): FT {\n return fieldValues(this)[field] as FT;\n }\n\n /**\n * Writes a field's value by name, optionally validating it first.\n *\n * The counterpart to {@link FV} for generic editors, and the single write path\n * used by {@link fromJson}. Two behaviours are worth knowing: values for fields\n * whose manager is `computed` are **silently discarded** (they are derived\n * server-side and have no meaningful setter), and when validation fails the\n * field is **left untouched** rather than assigned the bad value.\n *\n * @param field field name\n * @param value new value, already deserialized\n * @param check run the field's validators first and refuse the write if any of\n * them rejects; off by default, since `fromJson` on trusted server data does\n * not need it\n * @returns `null` when the value was accepted (or ignored as computed),\n * otherwise the first validator's `ValidationErrors`\n */\n public setFV<FT>(field: string, value: FT, check = false): null | ValidationErrors {\n if (this.FM(field).computed) {\n return null;\n }\n if (check) {\n const fc = new FormControl(value);\n\n for (const v of this.FM(field).validators) {\n const val = v(fc);\n if (val !== null) {\n console.error(val);\n return val;\n }\n }\n }\n fieldValues(this)[field] = value;\n return null;\n }\n\n /**\n * Builds Angular reactive form controls from field metadata, wired with each\n * field's validators and current value.\n *\n * Saves hand-writing a `FormGroup` that duplicates what the model already\n * declares. The no-argument form is the common one and deliberately **excludes\n * `readonly` fields**, so the group matches what `save()` would actually send;\n * pass an explicit list when you want a subset, or a readonly field rendered\n * anyway.\n *\n * @param field one field name for a single `FormControl`, a list of names for a\n * `FormGroup` of exactly those, or nothing for a `FormGroup` of every\n * editable (non-readonly) field\n *\n * @example\n * ```ts\n * const form = thing.FC(); // FormGroup, editable fields only\n * const nameCtrl = thing.FC('name'); // FormControl\n * ```\n */\n public FC(): FormGroup;\n public FC(field: string): FormControl;\n public FC(field: string[]): FormGroup;\n public FC(field?: string | string[]): FormControl | FormGroup {\n if (field === undefined) {\n field = Array.from(this.FN).filter((n) => !this.FM(n).readonly);\n }\n if (Array.isArray(field)) {\n const fg: Record<string, FormControl> = {};\n for (const f of field) {\n fg[f] = this.FC(f);\n }\n return new FormGroup(fg);\n }\n return this.FM(field).formControl(this);\n }\n\n /**\n * Persists the whole record through its collection, creating or updating\n * depending on {@link id}: POST when `id` is `undefined`, PATCH when it is set.\n *\n * Sends every non-readonly field. Reach for {@link update} instead when you\n * want to write only some of them.\n *\n * @param updateModel refresh this instance from the server's response, so\n * server-assigned values (`id` on create, timestamps, computed fields) land\n * back on the model; on by default\n * @returns an observable that errors with \"Missing collection\" if this instance\n * was never attached to one\n */\n public save(\n { updateModel = true }: { updateModel?: boolean } = {\n updateModel: true,\n },\n ): Observable<this> {\n if (this._coll) {\n return this._coll.save(this, { updateModel }) as Observable<this>;\n }\n return throwError(() => new Error('Missing collection'));\n }\n\n /**\n * Persists only the named fields, which is what you want after an inline edit\n * of one value — it avoids clobbering fields another client may have changed\n * meanwhile.\n *\n * Dispatches on {@link id} exactly like {@link save} (POST when unset, PATCH\n * otherwise).\n *\n * @param fields field names to send; note that an empty list (the default)\n * falls back to sending every non-readonly field, i.e. it degrades to\n * {@link save}'s payload. Also note that naming a `readonly` field here does\n * include it in the payload — the readonly filter only applies to the\n * whole-record form.\n * @param updateModel refresh this instance from the server's response; on by default\n * @returns an observable that errors with \"Missing collection\" if this instance\n * was never attached to one\n *\n * @example\n * ```ts\n * thing.name = 'new name';\n * thing.update(['name']).subscribe();\n * ```\n */\n public update(\n fields: string[] = [],\n { updateModel = true }: { updateModel?: boolean } = {\n updateModel: true,\n },\n ): Observable<this> {\n if (this._coll) {\n return this._coll.update(this, fields, {\n updateModel,\n }) as Observable<this>;\n }\n return throwError(() => new Error('Missing collection'));\n }\n}\n\n//\n// export class TreeDataModel extends DataModel {\n// static override __name = 'TreeDataModel';\n// @detailsField({\n// model: this,\n// many: true,\n// description: 'Parents',\n// })\n// public parents_details?: this[];\n//\n// @foreignKeyField({\n// required: false,\n// description: 'Structure parente',\n// related: 'Structure',\n// })\n// public parent?: number;\n//\n// @integerField({\n// required: false,\n// readonly: true,\n// description: 'ID Tree',\n// })\n// public tree_id!: number;\n//\n// @integerField({\n// required: false,\n// readonly: true,\n// description: 'MPTT left',\n// })\n// public lft!: number;\n//\n// @integerField({\n// required: false,\n// readonly: true,\n// description: 'MPTT right',\n// })\n// public rght!: number;\n//\n// @integerField({\n// required: false,\n// readonly: true,\n// description: 'Niveau hiérarchique',\n// })\n// public level!: number;\n//\n// public get parent_details(): this | null {\n// if (this.parents_details) {\n// const out = this.parents_details[this.parents_details.length - 1];\n// out.parents_details = this.parents_details.slice(\n// 0,\n// this.parents_details.length - 1\n// );\n// return out;\n// }\n// return null;\n// }\n//\n// public set parent_details(d: this | null) {\n// console.log(d);\n// this.parents_details = d?.parents_details;\n// }\n//\n// public _display(): string {\n// const out: string[] = [];\n// if (this.parents_details) {\n// for (const p of this.parents_details) {\n// if ((p as any).code) {\n// out.push(`[${(p as any).code}] ${(p as any).name}`);\n// } else {\n// out.push((p as any).name);\n// }\n// }\n// }\n// if ((this as any).code) {\n// out.push(`[${(this as any).code}] ${(this as any).name}`);\n// } else {\n// out.push((this as any).name);\n// }\n//\n// return out.join(' : ');\n// }\n// }\n","import { Collection } from './data-collection';\nimport { DataModel } from './data-model';\nimport { combineLatest, Observable, ReplaySubject, share } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\nimport { ActivatedRoute, Router } from '@angular/router';\n\n/**\n * Filter criteria as authored by the caller, keyed by the query parameter the API\n * expects (`{ status: 'active', min_price: 10 }`).\n *\n * `undefined` and `null` are meaningful here: passing either for a key *removes*\n * that filter, which is what lets a form bind a cleared control straight to a\n * queryset filter.\n */\n/**\n * A value a filter can hold: whatever goes on the wire for that field. A scalar\n * for most filters, an array for the multi-valued ones, `null` for \"cleared\".\n */\nexport type FilterValue = string | number | boolean | null | undefined | (string | number)[];\n\nexport type FilterData = Record<string, string | number | boolean | undefined | null>;\n\n/**\n * Filter criteria flattened to strings, as they go on the wire. This is what\n * {@link Queryset.getQueryParams} produces.\n */\nexport type OutFilterData = Record<string, string>;\n\n/**\n * A single ordering term: a field name, optionally prefixed with `-` to reverse\n * it (`'name'`, `'-created'`) — the DRF `ordering` convention.\n */\nexport type SortData = string;\n\n/**\n * Construction options for a {@link Queryset}, passed through\n * `Collection.queryset()`.\n */\nexport interface IQuerysetOptions {\n /**\n * Whether the selected field list is sent to the API as a `fields` query\n * parameter, letting the server return only those columns. Defaults to `true`;\n * set it to `false` against an endpoint that does not understand `fields`.\n */\n emitFields?: boolean;\n /** Identifier for this queryset, used to tell several of them apart. */\n name?: string;\n /**\n * Intended to let the queryset sync its state with the URL. Currently inert —\n * nothing in the implementation reads it (the router code in `setPage` is\n * commented out).\n */\n route?: ActivatedRoute;\n /**\n * Intended to let the queryset push page changes into the URL. Currently inert\n * — see the commented-out block in `setPage`.\n */\n router?: Router;\n /**\n * Intended as the URL fragment identifying this queryset when several share a\n * page. Currently inert.\n */\n hash?: string;\n}\n\n/** Pagination request parameters: which page, and how many rows on it. */\nexport interface IQueryNav {\n page: number;\n page_size: number;\n}\n\n/**\n * Pagination state as reported by the API, and what a paginator component binds\n * to: total row count, current page, total pages, and the neighbouring page\n * numbers (`null` at either end).\n */\nexport interface IQueryMetaNav {\n /** Total number of rows matching the filters, across all pages. */\n count: number;\n /** Next page number, or `null` on the last page. */\n next: number | null;\n /** Current page number. */\n page: number;\n /** Total number of pages. */\n pages: number;\n /** Previous page number, or `null` on the first page. */\n prev: number | null;\n /** Rows per page. */\n size: number;\n}\n\n/**\n * Names the API uses for its pagination query parameters, echoed back so a client\n * can build page links without hard-coding them.\n */\nexport interface IQueryMetaNavParams {\n page: string;\n page_size: string;\n}\n\n/** Everything a list response says about itself apart from the rows. */\nexport interface IQueryMeta {\n nav: IQueryMetaNav;\n parameters: IQueryMetaNavParams;\n}\n\n/**\n * Full shape of a paginated list response: the rows under `results`, alongside\n * the {@link IQueryMeta} envelope. This is the contract {@link Queryset} expects\n * of every list endpoint it reads.\n */\nexport interface IQueryFullResponse<T> extends IQueryMeta {\n results: T[];\n}\n\n/**\n * A filtered, sorted, paginated view over a {@link Collection}, exposing its\n * results as observables ready to bind in a template.\n *\n * Obtained from `Collection.queryset()`. The mutators ({@link filter},\n * {@link sort}, {@link paginateBy}, {@link setPage}, {@link setFields}) are\n * chainable and only accumulate state locally — **nothing is requested until\n * {@link get} is called**, and calling `get()` again after changing filters is\n * what re-runs the query.\n *\n * Consumers normally subscribe to {@link results} (or {@link full}) once and keep\n * that subscription for the component's lifetime, then call `get()` on each\n * change: the observables are `ReplaySubject`-backed, so every new emission flows\n * to the existing subscribers and late subscribers immediately get the last value.\n *\n * @example\n * ```ts\n * const qs = things.queryset();\n * qs.results.subscribe((things) => (this.things = things));\n * qs.filter({ status: 'active' }).sort('-created').paginateBy(20).get().subscribe();\n * ```\n */\nexport class Queryset<T extends DataModel> {\n /** Filters currently staged, as last set by {@link filter}. */\n public filterData: FilterData = {};\n /** Ordering terms currently staged, as last set by {@link sort}. */\n public sortData: SortData[] = [];\n /**\n * Field names to request from the API, as last set by {@link setFields}. Only\n * sent when `options.emitFields` is on and the list is non-empty.\n */\n public fields: string[] = [];\n /**\n * Rows per page. Note the default is 500, not the API's own default: a queryset\n * you never call {@link paginateBy} on asks for a large page rather than a\n * small one.\n */\n public pageSize = 500;\n /** Page number to request, 1-based. */\n public page = 1;\n\n /** Options this queryset was built with, merged over the defaults. */\n public options: IQuerysetOptions;\n private _loading = new ReplaySubject<boolean>(1);\n /**\n * Emits `true` when a fetch starts and `false` when its results have been\n * processed — bind it to a spinner. Nothing is emitted before the first\n * {@link get}, and note that a failed request leaves this at `true`.\n */\n public loading = this._loading.asObservable().pipe(share());\n private _meta = new ReplaySubject<IQueryMeta>(1);\n /**\n * Emits the pagination envelope of each response — row count, page, total\n * pages. This is what a paginator component binds to, since {@link results}\n * only carries the current page's rows.\n */\n public meta = this._meta.asObservable().pipe(share());\n private _results = new ReplaySubject<T[]>(1);\n /**\n * Emits the current page's rows as model instances on every successful fetch.\n * The main output of a queryset. Being replayed, a late subscriber immediately\n * receives the most recent page rather than waiting for the next `get()`.\n */\n public results = this._results.asObservable().pipe(share());\n private _full: Observable<[T[], boolean, IQueryMeta]> = combineLatest([this.results, this.loading, this.meta]);\n /**\n * The three streams combined into `[results, loading, meta]`, for templates\n * that would otherwise need three `async` pipes.\n *\n * Being a `combineLatest`, it emits nothing until all three have produced a\n * value — i.e. not until the first fetch completes — and then emits once per\n * change of any of them, so a single fetch produces several tuples as loading\n * flips and results land.\n */\n public full = this._full.pipe(share());\n\n /**\n * @param _coll collection this queryset reads from\n * @param options queryset options, merged over the defaults (`emitFields: true`)\n */\n constructor(\n protected _coll: Collection<T>,\n options: IQuerysetOptions = {},\n ) {\n /** Default options */\n // console.log('@solidev/data: Creating collection', _coll);\n this.options = { emitFields: true };\n Object.assign(this.options, options);\n }\n\n private _pristine = true;\n\n /**\n * `true` until the first successful fetch, `false` forever after.\n *\n * Distinguishes \"no results yet\" from \"no results found\", which a bare empty\n * array cannot: use it to choose between a loading placeholder and an empty\n * state. It is also what makes `get(false)` decide whether it may serve the\n * cached results.\n */\n public get pristine(): boolean {\n return this._pristine;\n }\n\n /**\n * Stages the filters for the next {@link get}. Chainable; issues no request.\n *\n * @param params filter criteria. A key whose value is `null` or `undefined` is\n * *removed* rather than sent, so a cleared form control can be passed\n * straight through.\n * @param update when `true`, merge into the existing filters; when `false` (the\n * default), replace them wholesale\n *\n * @example\n * ```ts\n * qs.filter({ status: 'active' }); // replaces all filters\n * qs.filter({ q: search || null }, true); // merges; drops `q` when empty\n * ```\n */\n public filter(params: FilterData = {}, update = false): Queryset<T> {\n if (!update) {\n this.filterData = {};\n }\n for (const k of Object.keys(params)) {\n if (params[k] === undefined || params[k] === null) {\n delete this.filterData[k];\n } else {\n this.filterData[k] = params[k];\n }\n }\n return this;\n }\n\n /**\n * Stages the ordering for the next {@link get}. Chainable; issues no request.\n *\n * Terms are sent joined into a single `ordering` query parameter, in the order\n * given, so the first term is the primary sort key.\n *\n * @param sorting field names, `-` prefixed to reverse; replaces any previous\n * ordering, and calling with no arguments clears it\n *\n * @example\n * ```ts\n * qs.sort('-created', 'name').get().subscribe();\n * ```\n */\n public sort(...sorting: string[]): Queryset<T> {\n this.sortData = sorting;\n return this;\n }\n\n /**\n * Stages the page size for the next {@link get}. Chainable; issues no request.\n *\n * Does not reset {@link page}, so changing the size while on a high page number\n * can land past the end of the result set — call `setPage(1)` alongside it.\n *\n * @param pageSize rows per page; defaults to 20 when called with no argument,\n * which is *not* the queryset's own default of 500\n */\n public paginateBy(pageSize = 20): Queryset<T> {\n this.pageSize = pageSize;\n return this;\n }\n\n /**\n * Stages the page number for the next {@link get}. Chainable; issues no\n * request, so a paginator must call {@link get} afterwards.\n *\n * @param page 1-based page number\n * @param _fragment currently ignored; reserved for the URL-syncing behaviour\n * that is commented out in the implementation\n */\n public setPage(page = 1, _fragment?: string): Queryset<T> {\n if (page !== this.page) {\n this.page = page;\n // if (this.options.router) {\n // // TODO: check and fix usage of fragment/query params\n // const frag = fragment\n // ? fragment\n // : this.options.hash || this.options.name;\n // const _ = this.options.router.navigate([], {\n // queryParams: { page: page.toString() },\n // fragment: frag,\n // queryParamsHandling: 'merge',\n // });\n // }\n }\n return this;\n }\n\n /**\n * Stages which fields the API should return. Chainable; issues no request.\n *\n * Lets a list view ask only for the columns it actually shows, which matters on\n * wide models. Sent as a `fields` query parameter, and only when\n * `options.emitFields` is on — with it off, this is recorded but never\n * transmitted.\n *\n * @param fields field names to request; an empty array means \"no restriction\"\n */\n public setFields(fields: string[]): Queryset<T> {\n this.fields = fields;\n return this;\n }\n\n /**\n * Flattens the staged filter/sort/page/fields state into the query parameters\n * that will actually be sent.\n *\n * Exposed mainly for debugging and for building links that mirror the current\n * view; {@link get} calls it itself. Ordering goes out as `ordering`, paging as\n * `page`/`page_size`, and the field selection as `fields`.\n *\n * The `OutFilterData` return type is an assertion rather than a conversion —\n * numeric values such as `page` are still numbers at runtime, and are\n * stringified later by `HttpClient`.\n */\n public getQueryParams(): OutFilterData {\n const f: FilterData = {};\n Object.assign(f, this.filterData);\n if (this.sortData.length) {\n f['ordering'] = this.sortData.join(',');\n }\n f['page_size'] = this.pageSize;\n f['page'] = this.page;\n if (this.options.emitFields && this.fields.length) {\n f['fields'] = this.fields.join(',');\n }\n return f as OutFilterData;\n }\n\n /**\n * Runs the staged query and pushes the outcome through {@link results},\n * {@link meta} and {@link loading}.\n *\n * The one method that talks to the network. Call it after each change to the\n * filter/sort/page state; subscribers of `results` do not need to resubscribe,\n * they simply receive the new page. The returned observable is `results`\n * itself, so subscribing to the return value is a convenience, not a\n * requirement — though something must subscribe for the request to be sent.\n *\n * @param refresh when `false`, an already-fetched queryset (see\n * {@link pristine}) short-circuits and hands back the cached `results`\n * without any request. Use it where a component may be re-entered and should\n * reuse what is already loaded. A pristine queryset always fetches, whatever\n * this says.\n * @param sync adds `db=sync` to the query, asking the API to read from its\n * primary rather than a replica — for the read-after-write case where\n * replication lag would otherwise return stale rows\n *\n * @example\n * ```ts\n * qs.get().subscribe(); // always refetches\n * qs.get(false).subscribe(); // reuses results if already loaded once\n * ```\n */\n public get(refresh = true, sync = false): Observable<T[]> {\n if (!refresh && !this._pristine) {\n // console.log('@solidev/data: Get not refreshing, return current result observable');\n return this.results;\n }\n // console.log('@solidev/data: start get (query)');\n this._loading.next(true);\n const syncQp: Record<string, string> = {};\n if (sync) {\n syncQp['db'] = 'sync';\n }\n return this._coll\n .raw<IQueryFullResponse<T>>({\n method: 'GET',\n params: {\n ...this.getQueryParams(),\n ...syncQp,\n },\n })\n .pipe(\n switchMap((result) => {\n // Process results\n // console.log('@solidev/data: have meta');\n this._meta.next({ nav: result.nav, parameters: result.parameters });\n const out: T[] = [];\n for (const r of result.results) {\n const m = this._coll.fromJson(r);\n out.push(m);\n }\n this._pristine = false;\n // console.log('@solidev/data: have loading');\n this._loading.next(false);\n // console.log('@solidev/data: have result');\n this._results.next(out);\n // console.log('@solidev/data: done get');\n return this.results;\n }),\n );\n }\n}\n","import { DataModel } from './data-model';\nimport { fieldValues } from './field-values';\nimport { DataBackend } from './data-backend';\nimport { Observable } from 'rxjs';\nimport { FilterData, IQuerysetOptions, Queryset } from './data-query';\nimport { map, tap } from 'rxjs/operators';\n\n/** HTTP verbs this library issues. */\nexport type IHttpMethod = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH';\n\n/**\n * Per-request options shared by every {@link Collection} and {@link DataBackend}\n * call: body, headers and query parameters.\n *\n * All members are optional, so `{}` is a valid \"nothing special\" argument.\n */\nexport interface IActionParams {\n /** JSON body; ignored by GET/DELETE requests. */\n body?: unknown;\n /** Extra headers, merged on top of whatever the backend's `headers()` adds. */\n headers?: Record<string, string>;\n /** Query string parameters. */\n params?: Record<string, string>;\n /**\n * Expected response type. Note that the backend does not currently read this:\n * `DataBackend.action()` always parses JSON and `DataBackend.blob()` always\n * requests a blob. Use `Collection.blob()` to get binary data.\n */\n responseType?: 'json' | 'blob';\n}\n\n/**\n * Shape for describing per-collection cache tuning.\n *\n * Currently unused by the runtime — TransferState behaviour is driven by\n * `Collection.useTransferState` plus the `DATA_MAX_TRANSFERSTATE_TIME` token.\n */\nexport interface ICollectionCacheParams {\n transferState?: {\n enabled: boolean;\n maxTime: number;\n maxCount: number;\n };\n}\n\n/**\n * Constructor signature of a model class, letting a collection instantiate `T`\n * without knowing it — this is the `model` argument passed to\n * {@link Collection}'s constructor.\n */\nexport type DataModelType<T extends DataModel> = new (_coll?: Collection<T>) => T;\n\n/**\n * Binds a {@link DataModel} class to a REST endpoint and provides the CRUD\n * operations over it.\n *\n * A collection is the seam between models and HTTP: it knows the path, builds\n * URLs, hands raw JSON to the model for deserialization, and returns typed\n * instances that carry a back-reference to it (so `thing.save()` works). One\n * collection per endpoint, normally declared as a root-provided service.\n *\n * For anything involving filtering, sorting or pagination, go through\n * {@link queryset} rather than {@link list}.\n *\n * The endpoint is assumed to follow Django REST Framework conventions:\n * `/path` for the list, `/path/<id>` for a record, `/path/<id>/<action>` for\n * custom actions, and a *paginated* list response (see {@link list}).\n *\n * @example\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * export class ThingService extends Collection<Thing> {\n * constructor() {\n * super(inject(DataBackend), '/path/to/things', Thing);\n * }\n * }\n *\n * // then\n * things.fetch(1).subscribe((thing) => ...);\n * things.queryset().filter({ status: 'active' }).get().subscribe((list) => ...);\n * ```\n */\nexport class Collection<T extends DataModel> {\n /**\n * Whether GET responses for this collection may be served from / stored in\n * Angular's `TransferState` during SSR hydration.\n *\n * On by default, but only ever takes effect when `DATA_MAX_TRANSFERSTATE_TIME`\n * is provided and greater than zero. Set it to `false` on collections whose\n * data is user-specific or must not be embedded in the server-rendered HTML.\n */\n public useTransferState = true;\n\n /**\n * @param backend HTTP layer; supplies the API base URL and applies auth headers\n * @param path endpoint path appended to the backend's `apiUrl`, leading slash\n * included and trailing slash omitted (e.g. `'/path/to/things'`)\n * @param model model class this collection instantiates\n */\n constructor(\n protected backend: DataBackend,\n protected path: string,\n public model: DataModelType<T>,\n ) {}\n\n /**\n * Builds a new, unsaved model instance attached to this collection.\n *\n * Use it to back a creation form: the returned instance has no `id`, so the\n * first `save()` POSTs it. Values passed in `data` go through the field\n * managers' deserializers, exactly as if they had come from the API.\n *\n * @param data initial field values; omit for an empty instance\n *\n * @example\n * ```ts\n * const thing = things.create({ name: 'draft' });\n * thing.save().subscribe(); // POST /path/to/things\n * ```\n */\n public create(data?: Partial<T>): T {\n if (!data) {\n data = {};\n }\n return this.fromJson(data);\n }\n\n /**\n * Turns raw API JSON into model instances attached to this collection.\n *\n * Every read path funnels through here, and the attachment is the point: the\n * resulting instances can `save()`/`update()`/`action()` themselves. Call it\n * directly when you have JSON from somewhere other than this collection's own\n * requests (a websocket push, an embedded payload, a fixture).\n *\n * @param data one JSON object, or an array of them\n */\n fromJson(data: Partial<T>): T;\n fromJson(data: Partial<T>[]): T[];\n fromJson(data: Partial<T> | Partial<T>[]): T | T[] {\n if (data instanceof Array) {\n const out: T[] = [];\n for (const r of data) {\n const ri = new this.model(this);\n ri.fromJson(r);\n out.push(ri);\n }\n return out;\n }\n const m = new this.model(this);\n m.fromJson(data);\n return m;\n }\n\n /**\n * Opens a filterable, sortable, paginated view over this collection.\n *\n * The normal way to read lists: a {@link Queryset} accumulates query state and\n * exposes results/loading/meta as observables suitable for binding straight\n * into a template. Each call returns an independent queryset, so a component\n * showing two filtered lists of the same endpoint creates two.\n *\n * @param options queryset behaviour; see {@link IQuerysetOptions}\n */\n public queryset(options: IQuerysetOptions = {}): Queryset<T> {\n return new Queryset<T>(this, options);\n }\n\n /**\n * Retrieves a single record by primary key and returns it as a model.\n *\n * @param id primary key\n * @param prefix inserted between the collection path and the id, for endpoints\n * nested under a segment\n * @param suffix appended after the id, e.g. `'/detail'`\n * @param params query parameters\n * @param headers extra headers\n *\n * @example\n * ```ts\n * things.fetch(42).subscribe((thing) => ...); // GET /path/to/things/42\n * ```\n */\n public fetch(\n id: number,\n {\n prefix = '',\n suffix = '',\n params = {},\n headers = {},\n }: {\n prefix?: string;\n suffix?: string;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {},\n ): Observable<T> {\n return this.backend\n .get(this, this.getUrl(id, { prefix, suffix }), { headers, params })\n .pipe(map((result) => this.fromJson(result)));\n }\n\n /**\n * Calls a custom (non-CRUD) endpoint on this collection, either on one record\n * or on the collection as a whole, and returns the raw JSON response.\n *\n * This is the DRF `@action` convention. `DataModel.action()` delegates here;\n * call this directly for collection-level actions, which have no model.\n *\n * @param model record to act on, targeting `/path/to/things/<id>/<action>`, or\n * `null` for a collection-level action targeting `/path/to/things/<action>`\n * @param method HTTP method\n * @param action action name\n * @param body JSON body\n * @param params query parameters\n * @param headers extra headers\n */\n public action<RT>(\n model: T | null,\n method: IHttpMethod,\n action: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<RT> {\n return this.backend.action<T, RT>(\n this,\n method,\n this.getUrl(model ? model.id : null, {\n suffix: model ? '/' + action : action,\n }),\n { body, params, headers },\n );\n }\n\n /**\n * Writes a whole record: POST to the list URL when the model has no `id`,\n * PATCH to its detail URL when it does.\n *\n * Sends `model.toJson()`, i.e. every non-readonly field. Usually reached via\n * `model.save()` rather than called directly.\n *\n * @param model record to persist\n * @param updateModel feed the server's response back into `model` (defaults to\n * `true`), which is how a freshly created record gets its `id`. The returned\n * observable always emits a **separate** instance built from the response\n * either way.\n */\n public save(model: T, { updateModel = true }: { updateModel?: boolean } = {}): Observable<T> {\n const saveMethod =\n model.id !== undefined ? this.backend.patch.bind(this.backend) : this.backend.post.bind(this.backend);\n const url = model.id !== undefined ? this.getUrl(model.id) : this.getUrl();\n return saveMethod(this, url, { body: model.toJson() }).pipe(\n map((res) => this.fromJson(res)),\n tap((res) => {\n if (updateModel) {\n model.fromJson(fieldValues(res));\n }\n }),\n );\n }\n\n /**\n * Writes only the named fields of a record, dispatching POST/PATCH on `id`\n * exactly like {@link save}.\n *\n * Sends `model.toJson(fields)`, which restricts the payload to `fields` and\n * does **not** filter readonly ones. Usually reached via `model.update()`.\n *\n * @param model record to persist\n * @param fields field names to send; an empty list (the default) sends every\n * non-readonly field, making this equivalent to {@link save}\n * @param updateModel feed the server's response back into `model` (defaults to `true`)\n */\n public update(\n model: T,\n fields: string[] = [],\n { updateModel = true }: { updateModel?: boolean } = {},\n ): Observable<T> {\n const saveMethod =\n model.id !== undefined ? this.backend.patch.bind(this.backend) : this.backend.post.bind(this.backend);\n const url = model.id !== undefined ? this.getUrl(model.id) : this.getUrl();\n return saveMethod(this, url, { body: model.toJson(fields) }).pipe(\n map((res) => this.fromJson(res)),\n tap((res) => {\n if (updateModel) {\n model.fromJson(fieldValues(res));\n }\n }),\n );\n }\n\n /**\n * Deletes a record on the server. The local instance is left untouched — it is\n * the caller's job to drop it from whatever list holds it.\n *\n * @param model record to delete; its `id` builds the URL, so an unsaved model\n * would produce a request against the list URL\n * @param params query parameters\n * @param headers extra headers\n */\n public delete(model: T, { params = {}, headers = {} }: IActionParams = {}): Observable<unknown> {\n return this.backend.delete(this, this.getUrl(model.id), {\n params,\n headers,\n });\n }\n\n /**\n * Fetches a list of records in one shot, discarding pagination metadata.\n *\n * A shortcut for the simple cases (a dropdown's options, a small fixed set).\n * When you need paging, sorting, loading state or the result count, use\n * {@link queryset} instead.\n *\n * **The response must be paginated**: this reads `result.results` and returns\n * that array, so a DRF endpoint with pagination disabled — which answers with a\n * bare JSON array — yields an error rather than a list. The endpoint's page size\n * therefore also caps what you get back here; there is currently no way to point\n * this at a different response key (see the `FIXME` in the implementation).\n *\n * @param query filter parameters\n * @param prefix inserted before the suffix in the list URL\n * @param suffix appended to the list URL, for sub-endpoints\n * @param params extra query parameters, merged over `query`\n * @param headers extra headers\n */\n public list(\n query: FilterData = {},\n {\n prefix = '',\n suffix = '',\n params = {},\n headers = {},\n }: {\n prefix?: string;\n suffix?: string;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {},\n ): Observable<T[]> {\n const qry = Object.assign({}, query, params);\n return this.backend\n .list(\n this,\n this.getUrl(null, { suffix, prefix }),\n // SEE: forced typecast maybe bad\n { params: qry, headers },\n )\n .pipe(\n // FIXME: parametrize paginated results access\n map((result: { results: Partial<T>[] }) => this.fromJson(result.results)),\n );\n }\n\n /**\n * Calls a collection-level endpoint and returns the response body **unparsed**,\n * without turning it into models.\n *\n * The escape hatch for responses that are not a list of records: aggregates,\n * stats, export summaries. It is also what {@link Queryset} uses internally,\n * since a queryset needs the pagination envelope that {@link list} throws away.\n *\n * @param method HTTP method; defaults to GET\n * @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`\n * @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`\n * @param params query parameters\n * @param body accepted but **not currently sent** — the implementation does not\n * forward it to the backend, so non-GET calls needing a body must go through\n * {@link action}\n * @param headers extra headers\n */\n public raw<RT>({\n method = 'GET',\n prefix = '',\n suffix = '',\n params = {},\n body: _body = {},\n headers = {},\n }: {\n method?: IHttpMethod;\n prefix?: string;\n suffix?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {}): Observable<RT> {\n return this.backend.action(this, method, this.getUrl(null, { suffix, prefix }), {\n params,\n headers,\n });\n }\n\n /**\n * Calls a collection-level endpoint and returns the response as a `Blob`.\n *\n * Use it for binary or file downloads (CSV/XLSX/PDF exports) where the response\n * must not be parsed as JSON.\n *\n * @param method HTTP method; defaults to GET\n * @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`\n * @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`\n * @param params query parameters\n * @param body accepted but **not currently sent** — the implementation does not\n * forward it to the backend\n * @param headers extra headers\n */\n // `RT` is unused -- `blob()` always resolves to a Blob -- but dropping it\n // would be a breaking change for callers writing `blob<T>()`.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public blob<RT>({\n method = 'GET',\n prefix = '',\n suffix = '',\n params = {},\n body: _body = {},\n headers = {},\n }: {\n method?: IHttpMethod;\n prefix?: string;\n suffix?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n } = {}): Observable<Blob> {\n return this.backend.blob(this, method, this.getUrl(null, { suffix, prefix }), {\n params,\n headers,\n });\n }\n\n /**\n * Builds the absolute URL for this collection or one of its records.\n *\n * Every request the collection makes goes through here, so overriding it is the\n * supported way to bend URL construction (versioned or nested endpoints).\n *\n * Layout is `apiUrl + path` for the list, `apiUrl + path + '/' + prefix + id +\n * suffix` for a record, and `apiUrl + path + '/' + prefix + suffix` for the list\n * with affixes. Note the separating slash is only emitted when there is\n * something after it, so a plain list URL has no trailing slash.\n *\n * @param id primary key for a detail URL; `undefined` or `null` yields the list URL\n * @param prefix inserted just before the id (or before the suffix)\n * @param suffix appended at the very end\n */\n public getUrl(id?: number | null, { prefix = '', suffix = '' }: { prefix?: string; suffix?: string } = {}): string {\n if (id === undefined || id === null) {\n if (prefix || suffix) {\n return `${this.backend.apiUrl}${this.path}/${prefix}${suffix}`;\n } else {\n return `${this.backend.apiUrl}${this.path}`;\n }\n }\n return `${this.backend.apiUrl}${this.path}/${prefix}${id}${suffix}`;\n }\n}\n","import { HttpClient } from '@angular/common/http';\n\nimport { Observable, of } from 'rxjs';\nimport { tap } from 'rxjs/operators';\nimport { Injectable, PLATFORM_ID, TransferState, inject, makeStateKey } from '@angular/core';\nimport { isPlatformServer } from '@angular/common';\nimport { Collection, IActionParams } from './data-collection';\nimport { DataModel } from './data-model';\nimport { DATA_API_URL, DATA_MAX_TRANSFERSTATE_TIME } from './data-parameters';\n\n/**\n * The HTTP layer every {@link Collection} sits on: it owns the API base URL,\n * decides the headers, and optionally serves GET responses out of Angular's\n * `TransferState` during SSR hydration.\n *\n * Collections never touch `HttpClient` directly, which makes this the one place\n * to hook cross-cutting request concerns. The usual reason to care about this\n * class is {@link headers}: subclass it, override that method to inject an auth\n * token, and provide the subclass in place of the default.\n *\n * Requires {@link DATA_API_URL}. TransferState caching applies to GET only, and\n * only when {@link DATA_MAX_TRANSFERSTATE_TIME} is provided and greater than\n * zero — see {@link _cachedGet} for the exact conditions.\n *\n * Dependencies are resolved with `inject()`, so a subclass declares **no\n * constructor**. To point one at a different API — a second backend alongside\n * the main one — override {@link apiUrl} rather than passing a URL through\n * `super()`; {@link maxTransferstateTime} is overridable the same way.\n *\n * @example\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * export class AuthBackend extends DataBackend {\n * protected override headers(headers: { [k: string]: string }) {\n * return { ...super.headers(headers), Authorization: `Bearer ${token}` };\n * }\n * }\n *\n * @Injectable({ providedIn: 'root' })\n * export class SupportBackend extends DataBackend {\n * public override get apiUrl(): string {\n * return 'https://support.example.com/api';\n * }\n * }\n *\n * providers: [\n * { provide: DATA_API_URL, useValue: 'https://api.example.com' },\n * { provide: DataBackend, useClass: AuthBackend },\n * ];\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DataBackend {\n /**\n * Instantiation timestamp, used as the origin of the TransferState validity\n * window (see {@link _cachedGet}) — the window runs from backend creation, not\n * from each entry's insertion.\n */\n private _created = new Date();\n\n private _http = inject(HttpClient);\n private _transferState = inject(TransferState);\n private _platform = inject<object>(PLATFORM_ID);\n private _apiUrl = inject(DATA_API_URL);\n private _maxTransferstateTime = inject(DATA_MAX_TRANSFERSTATE_TIME, { optional: true }) ?? 0;\n\n /**\n * Base URL every collection URL is built on, as provided via\n * {@link DATA_API_URL}. Read by `Collection.getUrl()`; exposed so custom\n * collections can build URLs the same way.\n */\n public get apiUrl(): string {\n return this._apiUrl;\n }\n\n /**\n * TransferState window in ms, from {@link DATA_MAX_TRANSFERSTATE_TIME}; `0`\n * disables the cache. Overridable for the same reason as {@link apiUrl}.\n */\n protected get maxTransferstateTime(): number {\n return this._maxTransferstateTime;\n }\n\n /**\n * Issues an arbitrary request and returns the parsed JSON body.\n *\n * The general-purpose entry point, used by `Collection.action()` and\n * `Collection.raw()`. GET requests are routed through {@link _cachedGet} and so\n * may be answered from TransferState; every other method goes straight to the\n * network and carries the body.\n *\n * @param collection collection the request belongs to; consulted for its\n * `useTransferState` flag\n * @param method HTTP method\n * @param url absolute URL, normally from `Collection.getUrl()`\n * @param body JSON body; ignored for GET\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n *\n * @return an observable of the response body\n */\n public action<T extends DataModel, RT>(\n collection: Collection<T>,\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<RT> {\n if (method === 'GET') {\n return this._cachedGet(collection, url, {\n headers: this.headers(headers),\n params,\n });\n } else {\n return this._http.request<RT>(method, url, {\n body,\n params,\n headers: this.headers(headers),\n });\n }\n }\n\n /**\n * Issues a request whose response is taken as binary rather than JSON.\n *\n * Backs `Collection.blob()`; use that instead of calling this directly. Never\n * cached through TransferState, whatever the method.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param method HTTP method\n * @param url absolute URL\n * @param body JSON body\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n *\n * @return an observable of the response as a `Blob`\n */\n public blob<T extends DataModel>(\n collection: Collection<T>,\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<Blob> {\n return this._http.request(method, url, {\n body,\n params,\n headers: this.headers(headers),\n responseType: 'blob',\n });\n }\n\n /**\n * Full-replacement write (HTTP PUT). Provided for completeness — the CRUD path\n * in `Collection` uses {@link post}/{@link patch} instead, so this is only\n * reached by callers that need PUT semantics explicitly.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param url absolute URL\n * @param body JSON body\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n */\n public put<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<T> {\n return this._http.put<T>(url, body, {\n params,\n headers: this.headers(headers),\n });\n }\n\n /**\n * Creates a record (HTTP POST). Chosen by `Collection.save()`/`update()` when\n * the model has no `id`.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param url absolute URL, normally the collection's list URL\n * @param body JSON body\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n * @returns the created record's JSON, expected to include the assigned `id`\n */\n public post<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<Partial<T>> {\n return this._http.post<Partial<T>>(url, body, {\n params,\n headers: this.headers(headers),\n });\n }\n\n /**\n * Partially updates a record (HTTP PATCH). Chosen by\n * `Collection.save()`/`update()` when the model already has an `id`.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param url absolute URL, normally the record's detail URL\n * @param body JSON body, holding only the fields to change\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n */\n public patch<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { body = undefined, params = {}, headers = {} }: IActionParams = {},\n ): Observable<Partial<T>> {\n return this._http.patch<Partial<T>>(url, body, {\n params,\n headers: this.headers(headers),\n });\n }\n\n /**\n * Deletes a record (HTTP DELETE). Backs `Collection.delete()`.\n *\n * @param collection collection the request belongs to; not used by this method\n * @param url absolute URL of the record\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n */\n public delete<T extends DataModel, R>(\n collection: Collection<T>,\n url: string,\n { params = {}, headers = {} }: IActionParams = {},\n ): Observable<R> {\n return this._http.delete<R>(url, {\n params,\n headers: this.headers(headers),\n });\n }\n\n /**\n * Performs a GET, transparently replaying the server-rendered response from\n * `TransferState` when that is still allowed.\n *\n * This is what stops an SSR app from re-fetching, in the browser, everything it\n * already fetched on the server to render the page. Entries are keyed on URL +\n * params + resolved headers, so requests differing in any of those do not share\n * a slot.\n *\n * A cached value is **read** only when all of these hold: the collection has\n * `useTransferState`, {@link DATA_MAX_TRANSFERSTATE_TIME} is greater than zero,\n * the key is present, and less than that many milliseconds have passed since\n * *this backend instance was created*. That last condition makes the window a\n * one-shot hydration budget rather than a per-entry TTL: once it lapses, nothing\n * is served from TransferState again for the life of the backend.\n *\n * A value is **written** only when the collection has `useTransferState`, the\n * code is running on the server, and the window is greater than zero. So in the\n * browser this degrades to a plain, uncached `HttpClient.get`.\n *\n * @param collection collection the request belongs to; consulted for `useTransferState`\n * @param url absolute URL\n * @param params query parameters\n * @param headers extra headers, passed through {@link headers}\n */\n public _cachedGet<T extends DataModel, RT>(\n collection: Collection<T>,\n url: string,\n { params = {}, headers = {} }: IActionParams = {},\n ): Observable<RT> {\n const cur_headers = this.headers(headers);\n\n const key = makeStateKey<RT>(url + '|' + JSON.stringify(params) + '|' + JSON.stringify(cur_headers));\n if (\n collection.useTransferState &&\n this.maxTransferstateTime > 0 &&\n this._transferState.hasKey(key) &&\n new Date().getTime() - this._created.getTime() < this.maxTransferstateTime\n ) {\n return of(this._transferState.get<RT | null>(key, null) as RT);\n }\n return this._http.get<RT>(url, { headers: cur_headers, params }).pipe(\n tap((result) => {\n if (collection.useTransferState && isPlatformServer(this._platform) && this.maxTransferstateTime > 0) {\n this._transferState.set<RT>(key, result);\n }\n }),\n );\n }\n\n /**\n * Fetches a single record's JSON. Backs `Collection.fetch()`, and is\n * TransferState-cacheable via {@link _cachedGet}.\n *\n * @param collection collection the request belongs to\n * @param url absolute URL of the record\n * @param params query parameters\n * @param headers extra headers\n */\n public get<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { params = {}, headers = {} }: IActionParams = {},\n ): Observable<Partial<T>> {\n return this._cachedGet<T, Partial<T>>(collection, url, {\n headers: this.headers(headers),\n params,\n });\n }\n\n /**\n * Fetches a list endpoint's raw JSON — including the pagination envelope, which\n * `Collection.list()` then unwraps. Identical to {@link get} apart from the\n * declared return type; both funnel into {@link _cachedGet}.\n *\n * @param collection collection the request belongs to\n * @param url absolute URL of the list endpoint\n * @param params query parameters, typically the queryset's filters and paging\n * @param headers extra headers\n */\n public list<T extends DataModel>(\n collection: Collection<T>,\n url: string,\n { params = {}, headers = {} }: IActionParams = {},\n ): Observable<{ results: Partial<T>[] }> {\n return this._cachedGet<T, { results: Partial<T>[] }>(collection, url, {\n headers: this.headers(headers),\n params,\n });\n }\n\n /**\n * Resolves the headers actually sent with a request.\n *\n * **The designated extension point of this class.** The base implementation\n * just copies what it is given; subclasses override it to add headers that\n * every request needs — most often an `Authorization` token — and then get\n * provided in place of `DataBackend`. Doing it here rather than in an HTTP\n * interceptor keeps the headers part of the TransferState cache key, so\n * responses fetched under different credentials do not collide.\n *\n * Implementations should stay pure and synchronous: this is called once per\n * request, and for GETs its result feeds the cache key.\n *\n * @param headers per-request headers supplied by the caller\n * @returns the complete header set to send\n */\n protected headers(headers: Record<string, string>): Record<string, string> {\n return Object.assign({}, headers);\n }\n}\n","import { Observable, ReplaySubject } from 'rxjs';\nimport { DataModel } from '../../data/data-model';\nimport { Collection } from '../../data/data-collection';\nimport { FieldsParams } from '../model-list.service';\n\n/**\n * One column of a list: a model field (or a {@link CustomField}) together with\n * its display state.\n */\nexport interface ModelListField {\n /** Field name, as declared on the model, or the custom column's key. */\n name: string;\n /** Column title, taken from the field's `description` and falling back to `name`. */\n label: string;\n /** Currently displayed. */\n enabled: boolean;\n /** The user may enable it from the field selector. */\n allowed: boolean;\n /** The field's current value/manager, `null` for custom columns. */\n field: unknown;\n /** Sort key for display order, renumbered in steps of 10 on every change. */\n position: number;\n /** Ordering weight from the field metadata, higher first; `-1` means \"never shown by default\". */\n priority: number;\n}\n\n/**\n * The columns of a list: which exist, which are shown, and in what order.\n *\n * Built from the model's decorated fields plus any {@link FieldsParams.custom}\n * entries, then narrowed by `allowed`/`defaults`/`excluded`. Components mutate it\n * through {@link enable}/{@link disable}/{@link move}/{@link setPosition}; every\n * mutation renumbers positions and pushes the enabled field names on\n * {@link output}, which re-runs the list's query with the new `fields` param.\n */\nexport class ModelListFields<T extends DataModel> {\n private readonly __fields!: ModelListField[];\n\n /**\n * Resolve the column set once, from the model's fields and `params`.\n *\n * Fields are ordered by `priority` (higher first, ties broken by declaration\n * order), enabled fields are then laid out in `defaults` order, and anything\n * neither allowed nor enabled is dropped. An empty or absent `allowed` means\n * every field is allowed, and every field with `priority >= 0` is enabled.\n *\n * @param collection collection whose model provides the fields\n * @param params column selection, see {@link FieldsParams}\n */\n constructor(collection: Collection<T>, params?: FieldsParams) {\n // Get fields from model\n const m = collection.create();\n const tmp = [];\n for (const fn of m.FN) {\n tmp.push({\n name: fn,\n label: m.FM(fn).description || fn,\n allowed: false,\n enabled: false,\n field: m.FV(fn),\n position: tmp.length * 10,\n priority: m.FM(fn).priority || 0,\n });\n }\n // Add custom fields if provided\n const custom = params?.custom || [];\n for (const c of custom) {\n tmp.push({\n name: c.name,\n label: c.label,\n allowed: false,\n enabled: false,\n field: null,\n position: tmp.length * 10,\n priority: c.priority || 0,\n });\n }\n\n tmp.sort((b, a) => (a.priority === b.priority ? b.position - a.position : a.priority - b.priority));\n let pos = 0;\n for (const i of tmp) {\n i.position = pos;\n pos += 10;\n }\n\n // Prepare allowed fields (all fields if not set or empty)\n let allowed: string[];\n let ddefaults: string[];\n if (params?.allowed === undefined || params?.allowed.length === 0) {\n allowed = tmp.map((f) => f.name);\n ddefaults = tmp.filter((f) => f.priority >= 0).map((f) => f.name);\n } else {\n allowed = params.allowed;\n ddefaults = params.allowed;\n }\n\n // Prepare excluded fields\n const excluded: string[] = params?.excluded || [];\n\n // Process default fields\n // Use all allowed fields if empty of not set\n const defaults: string[] = params?.defaults || ddefaults;\n\n // Prepare fields status\n // Set allowed\n for (const fe of allowed) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.allowed = true;\n }\n }\n }\n // Set defaults\n for (const fe of defaults) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.enabled = true;\n f.allowed = true;\n }\n }\n }\n\n // remove excluded\n for (const fe of excluded) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.enabled = false;\n f.allowed = false;\n }\n }\n }\n const filtered = [];\n for (const f of tmp) {\n if (!(!f.enabled && !f.allowed)) {\n filtered.push(f);\n }\n }\n\n const ordered = [];\n const enabled = filtered.filter((f) => f.enabled);\n pos = 0;\n for (const fe of defaults) {\n for (const f of enabled) {\n if (f.name === fe) {\n f.position = pos;\n pos += 10;\n }\n }\n }\n enabled.sort((a, b) => a.position - b.position);\n const disabled = filtered.filter((f) => !f.enabled);\n let ei = 0;\n let di = 0;\n while (ei + di < filtered.length) {\n if (enabled[ei] && disabled[di]) {\n if (enabled[ei].priority > disabled[di].priority) {\n ordered.push(enabled[ei]);\n ei += 1;\n } else {\n ordered.push(disabled[di]);\n di += 1;\n }\n } else if (enabled[ei]) {\n ordered.push(enabled[ei]);\n ei += 1;\n } else {\n ordered.push(disabled[di]);\n di += 1;\n }\n }\n pos = 0;\n for (const f of ordered) {\n f.position = pos;\n pos += 10;\n }\n\n this.__fields = ordered;\n this._update();\n }\n\n private _fields = new ReplaySubject<ModelListField[]>(1);\n\n /**\n * Every column, enabled or not, in display order; re-emitted on each change.\n * This is what the field selector and the header menus render.\n */\n public get fields(): Observable<ModelListField[]> {\n return this._fields.asObservable();\n }\n\n private _enabled: string[] = [];\n\n /** Names of the currently displayed columns, in display order. */\n public get enabled(): string[] {\n return this._enabled;\n }\n\n private _output = new ReplaySubject<string[]>(1);\n\n /**\n * Enabled column names, re-emitted on each change. Consumed by\n * {@link ModelList.start} to set the query's `fields` parameter.\n */\n public get output(): Observable<string[]> {\n return this._output.asObservable();\n }\n\n /**\n * Enable a field by name. Position is optional.\n *\n * @param fname : name of field to be enabled\n * @param position : position (optional)\n * @returns current enabled fields\n */\n public enable(fname: string, position?: number): string[] {\n const f = this.get(fname);\n if (f) {\n f.enabled = true;\n if (position !== undefined) {\n f.position = position;\n }\n } else {\n console.error('Field not found', f);\n }\n this._update();\n return this._enabled;\n }\n\n /**\n * Disable a field by name.\n *\n * @param fname : name of field to be disabled\n * @returns current enabled fields\n */\n public disable(fname: string): string[] {\n const f = this.get(fname);\n if (f) {\n f.enabled = false;\n } else {\n console.error('Field not found', f);\n }\n this._update();\n return this._enabled;\n }\n\n /**\n * Move field `fname` before or after (depending on `position`) field `dest`.\n *\n * With `dest` omitted, the field swaps with its neighbour on that side among\n * the *enabled* fields, which is what the header's left/right arrows do; it is\n * a no-op at either end.\n *\n * @param fname field to move\n * @param position (\"before\" or \"after\")\n * @param dest reference field, defaults to `fname`'s neighbour\n * @returns current enabled fields\n */\n public move(fname: string, position: 'before' | 'after', dest = ''): string[] {\n const ftarget = this.get(fname);\n if (dest == '') {\n const pos = this._enabled.indexOf(fname);\n dest = this._enabled[pos + (position === 'before' ? -1 : +1)];\n if (dest === undefined) {\n return this._enabled;\n }\n }\n const fdest = this.get(dest);\n // istanbul ignore if\n if (!ftarget || !fdest) {\n console.error('Target / dest not found', fname, dest);\n return this._enabled;\n }\n if (fname == dest) {\n ftarget.position = fdest.position + (position === 'before' ? -15 : +15);\n } else {\n ftarget.position = fdest.position + (position === 'before' ? -5 : +5);\n }\n\n this._update();\n return this._enabled;\n }\n\n /**\n * Check if field with name `fname` is enabled.\n *\n * @param fname : name of field\n * @returns enabled (true) or disabled (false)\n */\n public isEnabled(fname: string): boolean {\n return this._enabled.indexOf(fname) !== -1;\n }\n\n /**\n * Get field by name\n * @param fname : name of field\n * @returns Model list field or null if not found\n */\n public get(fname: string): ModelListField | null {\n for (const f of this.__fields) {\n if (f.name === fname) {\n return f;\n }\n }\n return null;\n }\n\n /**\n * Get the field at index `pos` in display order.\n *\n * Note this is an array index (0, 1, 2...), *not* a {@link ModelListField.position}\n * value — those are renumbered in steps of 10.\n *\n * @param pos : index of field\n * @returns Model list field or null if not found\n */\n public getAtPos(pos: number): ModelListField | null {\n return this.__fields[pos] || null;\n }\n\n /**\n * Set a field's raw sort key, then reorder. Used by the field selector's\n * drag-and-drop, which computes a key that lands between two existing fields.\n *\n * @param fname name of field to move\n * @param position new sort key\n * @returns current enabled fields\n */\n setPosition(fname: string, position: number): string[] {\n const f = this.get(fname);\n if (f) {\n f.position = position;\n } else {\n console.error('Field not found', f);\n }\n this._update();\n return this._enabled;\n }\n\n private _update() {\n this.__fields.sort((a, b) => a.position - b.position);\n let i = 0;\n for (const f of this.__fields) {\n f.position = i * 10;\n i += 1;\n }\n const out: string[] = [];\n for (const f of this.__fields) {\n if (f.enabled) {\n out.push(f.name);\n }\n }\n this._enabled = out;\n this._output.next(this._enabled);\n this._fields.next(this.__fields);\n }\n}\n","import { IQueryNav } from '../../data/data-query';\nimport { Observable, ReplaySubject } from 'rxjs';\n\n/**\n * The current page and page size of a list.\n *\n * Note the two families of methods: `setPage`/`setPageSize` emit on\n * {@link output} and therefore re-run the list's query, while\n * `updatePage`/`updatePageSize` change the value silently. The silent ones exist\n * so the UI can absorb what the server actually returned — the API may clamp a\n * page or a size — without triggering a second query.\n */\nexport class ModelListPaginator {\n private _page_size!: number;\n private _page!: number;\n\n /**\n * @param defaults initial page and page size; defaults to page 1, 20 per page.\n */\n constructor(defaults?: IQueryNav) {\n if (!defaults) {\n defaults = { page_size: 20, page: 1 };\n }\n this._page_size = defaults.page_size || 20;\n this._page = defaults.page || 1;\n this._updateOutput('constructor');\n }\n\n private _output = new ReplaySubject<IQueryNav>(1);\n\n /**\n * Current page and page size, re-emitted whenever they are `set`.\n * Consumed by {@link ModelList.start} to paginate the query.\n */\n public get output(): Observable<IQueryNav> {\n return this._output.asObservable();\n }\n\n /** Go to `page`, re-running the query. No-op if already there. */\n public setPage(page: number): void {\n if (page !== this._page) {\n this._page = page;\n this._updateOutput('setPage');\n }\n }\n\n /** Record the page the server reported, without re-running the query. */\n public updatePage(page: number): void {\n if (page !== this._page) {\n this._page = page;\n }\n }\n\n /** Change the page size, re-running the query. No-op if unchanged. */\n public setPageSize(size: number): void {\n if (size !== this._page_size) {\n this._page_size = size;\n this._updateOutput('setPageSize');\n }\n }\n\n /** Record the page size the server reported, without re-running the query. */\n public updatePageSize(size: number): void {\n if (size !== this._page_size) {\n this._page_size = size;\n }\n }\n\n /** Current page size. */\n public getPageSize(): number {\n return this._page_size;\n }\n\n /** Current page number, 1-based. */\n public getPage(): number {\n return this._page;\n }\n\n private _updateOutput(_from = ''): void {\n this._output.next({ page: this._page, page_size: this._page_size });\n }\n}\n","import { Observable, ReplaySubject } from 'rxjs';\nimport { SorterDefaults } from '../model-list.service';\n\n// TODO: add an option to limit the number of ordering fields (eg. for tree queries)\n/** Direction of a sort key. */\nexport type SortDirection = 'asc' | 'desc';\n\n/** One sort key: a field and the direction it is sorted in. */\nexport interface FieldSortData {\n field: string;\n direction: SortDirection;\n}\n\n/** Ordered sort keys; earlier entries take precedence. */\nexport type SorterData = FieldSortData[];\n\n/**\n * The sort keys of a list, as an ordered multi-key set.\n *\n * Each {@link set} adds a key at the end or updates an existing one in place, so\n * clicking successive column headers refines the sort rather than replacing it,\n * and {@link getOrder} tells the UI where a column ranks. Every change emits on\n * {@link output} as the `+field`/`-field` strings the queryset wants, which\n * re-runs the list's query.\n */\nexport class ModelListSorter {\n private readonly _values: SorterData = [];\n\n /**\n * Create ModelListSorter instance, using defaults.\n * @param defaults defaults sort values, as a list of strings (+field, -field, field)\n */\n constructor(defaults: SorterDefaults = []) {\n this._output = new ReplaySubject(1);\n this._values = [];\n for (const d of defaults) {\n if (d.length < 1) {\n continue;\n }\n if (d[0] == '+') {\n this._values.push({ field: d.substring(1), direction: 'asc' });\n } else if (d[0] == '-') {\n this._values.push({ field: d.substring(1), direction: 'desc' });\n } else {\n this._values.push({ field: d, direction: 'asc' });\n }\n }\n this._updateOutput('constructor');\n }\n\n private _output: ReplaySubject<string[]>;\n\n /**\n * Returns a list of \"+/-field\" sort strings observable.\n * @returns sort strings observable\n */\n public get output(): Observable<string[]> {\n return this._output.asObservable();\n }\n\n /**\n * Set sorting for `name` key, in direction `direction`.\n * If sorting is already set for `name` key, updates direction without changing order.\n * If sorting isn't set for `name` key, adds it at the end of sorting directions.\n *\n * @param name field name\n * @param direction sort direction\n * @returns model list sorter\n */\n public set(name: string, direction: SortDirection): ModelListSorter {\n for (const v of this._values) {\n if (v.field === name) {\n v.direction = direction;\n this._updateOutput();\n return this;\n }\n }\n this._values.push({ field: name, direction });\n this._updateOutput('set');\n return this;\n }\n\n /**\n * Removes `name` sorting key from current keys.\n *\n * @param name sort key to be removed\n * @returns model list sorter\n */\n public unset(name: string): ModelListSorter {\n for (let i = 0; i < this._values.length; i++) {\n if (this._values[i].field === name) {\n this._values.splice(i, 1);\n break;\n }\n }\n this._updateOutput('unset');\n return this;\n }\n\n /**\n * Get sorting status for `field` argument.\n * If `field` is not found, returns null.\n *\n * @param field field name\n * @returns ordering direction / null\n */\n public get(field: string): FieldSortData | null {\n for (const v of this._values) {\n if (v.field === field) {\n return v;\n }\n }\n return null;\n }\n\n /**\n * Return all sorter data values.\n *\n * @returns all sorter data values.\n */\n public getAll(): SorterData {\n return this._values;\n }\n\n /**\n * Get the ordering position for `field` argument. If not found, returns -1.\n *\n * The rank is 1-based, so it can be shown as-is next to a column header when\n * several columns are sorted at once.\n *\n * @param field field name\n * @returns ordering position for field\n */\n public getOrder(field: string): number {\n for (let i = 0; i < this._values.length; i++) {\n if (this._values[i].field === field) {\n return i + 1;\n }\n }\n return -1;\n }\n\n private _updateOutput(_from = ''): void {\n const out: string[] = [];\n for (const v of this._values) {\n out.push(`${v.direction === 'asc' ? '' : '-'}${v.field}`);\n }\n this._output.next(out);\n }\n}\n","import { FilterData, FilterValue } from '../../data/data-query';\nimport { Observable, ReplaySubject } from 'rxjs';\nimport { FILTER_TYPE } from './filters/filtertypes';\nimport { IDispEditChoice } from '../../dispedit/dispedit/dispedit.constants';\nimport { ModelListFilterGroup } from './model-list-filter-group';\n\n/**\n * Construction parameters shared by every filter type.\n *\n * Every concrete filter (text, select, autocomplete, ...) extends this\n * interface with its own extra options.\n */\n\nexport interface ModelListFilterParams {\n /**\n * The filter's identity within its {@link ModelListFilters} set. This is the\n * string used by the `allowed`, `defaults` and `excluded` lists to designate\n * this filter; it is never sent to the server. It must be unique across the\n * list, even when several filters share the same {@link field}.\n */\n name: string;\n /**\n * The query parameter name sent to the server when the filter has a value.\n * This is usually identical to {@link name}, but the two are deliberately\n * separate: two filters may target the same `field` under different `name`s\n * and different fixed scopes, so that they appear as two independent widgets\n * while querying the same backend parameter.\n */\n field: string;\n /**\n * Label displayed above the filter widget and in the filter picker. Always\n * set it explicitly: when omitted, every filter subclass falls back to a\n * hardcoded French default (see the class documentation).\n */\n label?: string;\n /**\n * Help text, generally rendered as the widget's placeholder. As with\n * {@link label}, leaving it unset yields a hardcoded French default.\n */\n help?: string;\n /**\n * Not read by the constructor. {@link ModelListFilter} initialises its value\n * from {@link default} instead; see the `FIXME` in the constructor body.\n */\n value?: FilterValue;\n /**\n * Free-form description used as the `title` (native tooltip) of this filter's\n * entry in the `data-model-list-filters-select` picker. It has no effect on\n * the query.\n */\n desc?: string;\n /**\n * Initial value applied at construction time. Only some subclasses act on it\n * (text, select and select-multi); the others ignore it. Its expected shape\n * depends on the subclass.\n */\n default?: unknown;\n /**\n * CSS classes applied to the filter's container element, overriding the\n * `classes` input passed by the host component. Use it to give one filter a\n * different width or layout from its siblings.\n */\n displayClasses?: string[] | string;\n /**\n * Set automatically by {@link ModelListFilters} when the filter is declared\n * inside a {@link ModelListFilterGroup}. Do not set it by hand.\n */\n group?: ModelListFilterGroup;\n}\n\n/**\n * Base class for all model list filters.\n *\n * A filter holds one user-chosen value (or a set of values when {@link multi}\n * is `true`), exposes it as an observable, and contributes a query parameter to\n * the list's request through {@link updateFilter}. Concrete filters (\n * {@link ModelListTextFilter}, {@link ModelListSelectFilter}, ...) subclass it\n * to set their {@link type} and their own options; each `type` is paired with a\n * component that renders the widget.\n *\n * Filters are not used standalone: they are passed to {@link ModelListFilters}\n * through the `filters` parameter of a `ModelList`, which decides which ones are\n * allowed and which are enabled by default.\n *\n * ## `name` vs `field`\n *\n * `field` is the query parameter sent to the server; `name` is the filter's\n * identity, used by the `allowed`, `defaults` and `excluded` lists. They are\n * usually equal, but keeping them separate lets two filters share a single\n * `field` while remaining two distinct, independently selectable widgets.\n *\n * ## Always set `label` and `help`\n *\n * Every subclass substitutes a hardcoded **French** string for `label` and\n * `help` when you leave them empty (for instance `'Recherche par texte'`).\n * Unless your application is French, pass both explicitly on every filter you\n * create, otherwise French text leaks into the UI.\n *\n * ## Single vs multiple values\n *\n * When {@link multi} is `false` (the default) the filter holds one value and\n * sends it as-is. When `true`, it holds a set of values and sends them joined\n * by `,` in a single query parameter. Subclasses such as\n * {@link ModelListSelectMultiFilter} or {@link ModelListFlagsFilter} force\n * `multi` to `true`.\n */\nexport class ModelListFilter implements ModelListFilterParams {\n /** Filter identity, used by `allowed`/`defaults`/`excluded`. Never sent to the server. */\n public name: string;\n /** Query parameter name sent to the server. May be shared by several filters. */\n public field: string;\n /** Label shown above the widget. Defaults to a French string set by each subclass. */\n public label: string;\n /** Help/placeholder text. Defaults to a French string set by each subclass. */\n public help: string;\n /** Tooltip text for the filter picker entry; does not affect the query. */\n public desc?: string;\n /** Initial value, applied at construction by the subclasses that support it. */\n public default?: unknown;\n /** Discriminator telling {@link ModelListFiltersComponent} which widget to render. */\n public type: FILTER_TYPE;\n /**\n * Whether the user may turn this filter on. Computed by {@link ModelListFilters}\n * from the `allowed`/`defaults`/`excluded` lists; disallowed filters are absent\n * from the picker.\n */\n public allowed: boolean;\n /**\n * Whether the filter is currently active: enabled filters are rendered and\n * contribute to the query. Toggled by the picker, or preset via `defaults`.\n */\n public enabled: boolean;\n /** Per-filter CSS classes overriding the host component's `classes` input. */\n public displayClasses?: string[] | string;\n /** Declared and initialised to `true`, but never updated anywhere in the library. */\n public pristine = true;\n /**\n * When `true`, the filter accumulates several values and joins them with `,`\n * into a single query parameter. Subclasses set this; do not change it on an\n * existing instance.\n */\n public multi = false;\n /** The group this filter belongs to, wired up by {@link ModelListFilters}. */\n public group?: ModelListFilterGroup;\n\n /** Single current value */\n protected _value: IDispEditChoice | null = null;\n /** Multiple current value */\n protected _mvalue = new Map<string, string>();\n /** Single current value observable */\n protected _current = new ReplaySubject<IDispEditChoice | null>(1);\n /** Multiple current value observable */\n protected _mcurrent = new ReplaySubject<IDispEditChoice[]>(1);\n\n /**\n * Builds a bare filter. In practice you instantiate a subclass rather than\n * this class directly, since each subclass sets its own {@link type} and\n * validates the options its widget needs.\n *\n * Both `allowed` and `enabled` start out `false`: it is\n * {@link ModelListFilters} that turns them on according to its own\n * `allowed`/`defaults`/`excluded` parameters.\n */\n constructor(params: ModelListFilterParams) {\n this.name = params.name;\n this.field = params.field;\n this.label = params.label || '';\n this.help = params.help || '';\n this.desc = params.desc;\n this.displayClasses = params.displayClasses;\n this.allowed = false;\n this.enabled = false;\n this.type = 'text';\n this.default = params.default;\n // FIXME: add value init\n }\n\n /**\n * The current set of values, for multi-valued filters. Emits the full set on\n * every change. Meaningless on a single-valued filter, which never feeds it.\n */\n public get mcurrent$(): Observable<IDispEditChoice[]> {\n return this._mcurrent.asObservable();\n }\n\n /**\n * The current value, for single-valued filters, or `null` once cleared.\n * Meaningless on a multi-valued filter, which never feeds it.\n */\n public get current$(): Observable<IDispEditChoice | null> {\n return this._current.asObservable();\n }\n\n /**\n * The filter's value stream, picking the right source according to\n * {@link multi}. This is what widget components subscribe to in order to\n * reflect external changes back into their form control; prefer it over\n * {@link current$}/{@link mcurrent$} in code that must handle both kinds.\n */\n public get valueChanges(): Observable<IDispEditChoice | IDispEditChoice[] | null> {\n if (this.multi) {\n return this._mcurrent.asObservable();\n }\n return this._current.asObservable();\n }\n\n /**\n * A human-readable rendering of the current value, built from the\n * descriptions passed to {@link set}. Used by the filter picker in\n * `badge_summary` mode to show what each active filter is filtering on.\n */\n public get summary(): string {\n if (this.multi) {\n return Array.from(this._mvalue.values()).join(', ');\n } else {\n return this._value?.desc || '';\n }\n }\n\n /**\n * Contributes this filter's query parameter to `filter`, mutating it in\n * place. Called by {@link ModelListFilters.update} for every enabled filter.\n *\n * A multi-valued filter writes all its values joined by `,` under\n * {@link field}; a single-valued one writes its lone value. Nothing is\n * written when the filter has no value. Subclasses override this when they\n * need a different parameter name or encoding, as\n * {@link ModelListNumberFilter} does to append its comparison operator.\n */\n public updateFilter(filter: FilterData) {\n if (this.multi && this._mvalue.size > 0) {\n filter[this.field] = this.getMultiValue();\n } else if (!this.multi && this._value !== undefined && this._value !== null) {\n filter[this.field] = this.getValue();\n }\n }\n\n /**\n * Drops the filter's value (all of them when multi-valued), so that it stops\n * contributing a query parameter. Note that this does not disable the filter:\n * the widget stays on screen, simply empty.\n *\n * @param notify Whether to emit on the value stream. Pass `false` to update\n * the value silently, then call {@link ModelListFilters.update} yourself.\n */\n public clear(notify = true) {\n if (this.multi) {\n this._mvalue = new Map<string, string>();\n } else {\n this._value = null;\n }\n this.notify(notify);\n }\n\n /**\n * Sets `value` on the filter, adding it to the set when multi-valued or\n * replacing the current one otherwise. This is what widget components call\n * when the user picks something.\n *\n * @param value The raw value to send to the server.\n * @param desc Human-readable text for this value, surfaced through\n * {@link summary} and, for multi-valued filters, on the removable chips.\n * @param notify Whether to emit on the value stream.\n * @returns `true` when the value actually changed, `false` when it was\n * already set. Callers use this to avoid re-querying the list needlessly.\n */\n public set(value: FilterValue, desc: string, notify = true): boolean {\n if (this.multi) {\n return this.mset(value, desc, notify);\n }\n return this.sset(value, desc, notify);\n }\n\n /**\n * Removes `value` from the filter. On a multi-valued filter only that value\n * is dropped, which is what the chips' delete buttons call; on a\n * single-valued one the current value is cleared whatever `value` is.\n *\n * @param value The value to remove. Ignored by single-valued filters.\n * @param desc Unused; accepted so that both kinds share one signature.\n * @param notify Whether to emit on the value stream.\n * @returns `true` when something was actually removed.\n */\n public unset(value: FilterValue, desc: string, notify = true): boolean {\n if (this.multi) {\n return this.munset(value, desc, notify);\n }\n return this.sunset(value, desc, notify);\n }\n\n /**\n * Adds `value` if absent, removes it if present. Convenient for checkbox-like\n * widgets where the same gesture selects and deselects.\n *\n * @param value The value to toggle.\n * @param desc Human-readable text, used when the value is being added.\n * @param notify Whether to emit on the value stream.\n * @returns Always `true`.\n */\n public toggle(value: FilterValue, desc: string, notify = true): boolean {\n if (this.multi) {\n return this.mtoggle(value, desc, notify);\n }\n return this.stoggle(value, desc, notify);\n }\n\n /**\n * The current single value, stringified, as sent to the server. Only\n * meaningful for single-valued filters.\n */\n public getValue(): string | number {\n return String(this._value?.value);\n }\n\n /**\n * The current single value with its description, or `null` when unset. Used\n * by widgets that need to restore their state on init, such as the tree\n * filter rebuilding its hierarchy from a preselected node.\n */\n public get(): IDispEditChoice | null {\n return this._value;\n }\n\n private mtoggle(value: FilterValue, desc: string, notify = true): boolean {\n if (this._mvalue.has(String(value))) {\n this._mvalue.delete(String(value));\n } else {\n this._mvalue.set(String(value), desc);\n }\n this.notify(notify);\n return true;\n }\n\n private mset(value: FilterValue, desc: string, notify = true): boolean {\n if (!this._mvalue.has(String(value))) {\n this._mvalue.set(String(value), desc);\n this.notify(notify);\n return true;\n }\n return false;\n }\n\n private munset(value: FilterValue, desc: string, notify = true): boolean {\n if (this._mvalue.has(String(value))) {\n this._mvalue.delete(String(value));\n this.notify(notify);\n return true;\n }\n return false;\n }\n\n private stoggle(value: FilterValue, desc: string, notify = true): boolean {\n if (this._value !== null && this._value.value === value) {\n this._value = null;\n } else {\n this._value = { value, desc };\n }\n this.notify(notify);\n return true;\n }\n\n private sset(value: FilterValue, desc: string, notify = true): boolean {\n if (!(this._value !== null && this._value.value === value)) {\n this._value = { value, desc };\n this.notify(notify);\n return true;\n }\n return false;\n }\n\n private sunset(value: FilterValue, desc: string, notify = true): boolean {\n if (this._value !== null) {\n this._value = null;\n this.notify(notify);\n return true;\n }\n return false;\n }\n\n /** Joins the current multi values with `,` to form a single query parameter. */\n private getMultiValue(): string | number {\n return Array.from(this._mvalue.keys()).join(',');\n }\n\n /** Emits the current value on the stream matching {@link multi}, if `notify`. */\n private notify(notify = true) {\n if (notify) {\n if (this.multi) {\n this._mcurrent.next(\n Array.from(this._mvalue.entries()).map(([k, v]) => {\n return { desc: v, value: k };\n }),\n );\n } else {\n this._current.next(this._value);\n }\n }\n }\n}\n","import { FilterData } from '../../data/data-query';\nimport { Observable, ReplaySubject } from 'rxjs';\nimport { FiltersParams } from '../model-list.service';\nimport { ModelListFilter } from './model-list-filter';\nimport { ModelListFilterGroup } from './model-list-filter-group';\n\n/**\n * The filter set of a `ModelList`: it owns the individual filters, decides\n * which ones the user may pick and which are on by default, and aggregates\n * their values into the query sent to the server.\n *\n * You rarely build one directly — pass a `FiltersParams` object as the\n * `filters` option of a `ModelList` and it constructs this for you. Its\n * observables ({@link output}, {@link enabled}, {@link available},\n * {@link groups}) are what the `data-model-list-filters` and\n * `data-model-list-filters-select` components render from.\n *\n * ## Selecting filters\n *\n * The three name lists in `FiltersParams` all designate filters by\n * {@link ModelListFilter.name} (never by `field`, and never by group name):\n *\n * - `allowed` — the filters the user may enable from the picker. Empty or\n * omitted means all of them.\n * - `defaults` — the filters enabled from the start. Omitted means every\n * allowed filter. Listing a filter here also makes it allowed.\n * - `excluded` — filters forced off and hidden, applied last, so it overrides\n * both lists above.\n *\n * Filters declared inside a {@link ModelListFilterGroup} are flattened into the\n * same pool, so they are named individually in these lists just like ungrouped\n * ones.\n *\n * @example\n * ```typescript\n * const filters = new ModelListFilters({\n * filters: [\n * new ModelListTextFilter({ name: 'search', field: 'search', label: 'Search', help: 'Text to look for' }),\n * new ModelListSelectFilter<Category>({\n * name: 'category', field: 'category', label: 'Category', help: 'Pick a category',\n * choices: [{ value: 1, desc: 'First' }],\n * }),\n * ],\n * defaults: ['search'],\n * });\n * filters.output.subscribe((f) => console.log(f)); // e.g. { search: 'abc' }\n * ```\n */\nexport class ModelListFilters {\n private _enabled$ = new ReplaySubject<ModelListFilter[]>(1);\n private _filters: ModelListFilter[] = [];\n private _output$ = new ReplaySubject<FilterData>(1);\n private _available$ = new ReplaySubject<ModelListFilter[]>(1);\n private _groups$ = new ReplaySubject<ModelListFilterGroup[]>(1);\n\n /**\n * Flattens any groups, resolves the `allowed`/`defaults`/`excluded` lists\n * into per-filter flags, then emits an initial state. Passing no parameters\n * yields an empty, inert filter set.\n */\n constructor(params?: FiltersParams) {\n const fwgroups = Array.from(params?.filters || []);\n // Ungroup filters, keeping groups\n const tmp: ModelListFilter[] = [];\n const groups: ModelListFilterGroup[] = [];\n for (const f of fwgroups) {\n if (f instanceof ModelListFilter) {\n tmp.push(f);\n } else {\n groups.push(f);\n for (const ff of f.filters) {\n tmp.push(ff);\n ff.group = f;\n }\n }\n }\n\n // Prepare allowed filters (all filters if not set or empty)\n let allowed: string[] = [];\n if (params?.allowed === undefined || params?.allowed.length === 0) {\n for (const f of tmp) {\n allowed.push(f.name);\n }\n } else {\n allowed = params.allowed;\n }\n // Prepare excluded filters\n const excluded: string[] = params?.excluded || [];\n\n // Process default filters\n // Use all allowed filters if empty of not set\n const defaults: string[] = params?.defaults || allowed;\n\n // Prepare filters status\n // Set allowed\n for (const fe of allowed) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.allowed = true;\n }\n }\n }\n // Set defaults\n for (const fe of defaults) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.enabled = true;\n f.allowed = true;\n }\n }\n }\n // remove excluded\n for (const fe of excluded) {\n for (const f of tmp) {\n if (f.name === fe) {\n f.enabled = false;\n f.allowed = false;\n }\n }\n }\n this._filters = tmp;\n this._groups = groups;\n this.update();\n }\n\n private _groups: ModelListFilterGroup[] = [];\n\n /**\n * The groups worth showing in the picker — those that are allowed and still\n * have a filter left to enable — sorted by\n * {@link ModelListFilterGroup.position}.\n */\n public get groups(): Observable<ModelListFilterGroup[]> {\n return this._groups$.asObservable();\n }\n\n private _enabled: ModelListFilter[] = [];\n\n /**\n * The currently active filters, i.e. the widgets to render. Re-emitted by\n * {@link update} whenever a filter is toggled.\n */\n public get enabled(): Observable<ModelListFilter[]> {\n return this._enabled$.asObservable();\n }\n\n private _available: ModelListFilter[] = [];\n\n /**\n * Every filter the user is allowed to enable, whether currently on or off.\n * This is the pool the filter picker offers.\n */\n public get available(): Observable<ModelListFilter[]> {\n return this._available$.asObservable();\n }\n\n /**\n * The aggregated query parameters contributed by all enabled filters. The\n * `ModelList` subscribes to this to re-run its query; emits on construction\n * and on every {@link update}.\n */\n public get output(): Observable<FilterData> {\n return this._output$.asObservable();\n }\n\n /**\n * Recomputes the whole filter state and emits on all four observables.\n *\n * Call this after mutating a filter's value or its `enabled` flag directly —\n * nothing else propagates such a change, and the filter widgets call it\n * themselves whenever the user interacts with them.\n */\n public update() {\n const filter: FilterData = {};\n for (const f of this._filters) {\n if (f.enabled) {\n f.updateFilter(filter);\n if (this._enabled.indexOf(f) === -1) {\n this._enabled.push(f);\n }\n } else {\n const i = this._enabled.indexOf(f);\n if (i !== -1) {\n this._enabled.splice(i, 1);\n }\n }\n if (f.allowed) {\n if (this._available.indexOf(f) === -1) {\n this._available.push(f);\n }\n } else {\n const i = this._available.indexOf(f);\n if (i !== -1) {\n this._available.splice(i, 1);\n }\n }\n }\n\n for (const g of this._groups) {\n g.enabled = false;\n g.allowed = false;\n for (const f of g.filters) {\n if (!f.enabled && f.allowed) {\n g.enabled = true;\n }\n if (f.allowed) {\n g.allowed = true;\n }\n }\n }\n\n this._output$.next(filter);\n this._enabled$.next(this._enabled);\n this._available$.next(this._available);\n this._groups$.next(this._groups.filter((g) => g.allowed && g.enabled).sort((a, b) => a.position - b.position));\n }\n}\n","import { inject, Injectable, InjectionToken } from '@angular/core';\nimport { HttpErrorResponse, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\nimport { AuthServiceBase } from './auth.service';\nimport { catchError, filter, switchMap, take, tap } from 'rxjs/operators';\nimport { BehaviorSubject, throwError } from 'rxjs';\nimport { IJwtRefreshResponseJson } from './jwt';\nimport { DATA_API_URL } from '../data/data-parameters';\n\n/**\n * The application's concrete {@link AuthServiceBase} subclass, as seen by the rest of\n * the library ({@link AuthInterceptor} and `ModelListService` both inject it).\n *\n * Wire it with **`useExisting`** against a class that is *also* provided in its own\n * right:\n *\n * ```ts\n * providers: [\n * AuthService,\n * { provide: DATA_AUTH_SERVICE, useExisting: AuthService },\n * ]\n * ```\n *\n * `useClass` here would construct a *second* auth service: components would hold one\n * instance while the interceptor and `ModelListService` hold another, so `logout$`\n * would never reach the list cache and stale data would survive a logout.\n */\n// The app that provides this token specialises all three parameters; naming\n// them here would force every consumer to cast on injection.\nexport const DATA_AUTH_SERVICE = new InjectionToken<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n AuthServiceBase<any, any, any>\n>('data.auth.service');\n\n/**\n * Extra origins, beyond `DATA_API_URL`, whose requests should carry the auth token.\n *\n * Optional; when absent only `DATA_API_URL` requests are authenticated. Entries are\n * matched with `String.startsWith`, so list full url prefixes and keep them narrow —\n * any request matching a prefix will have the bearer token attached to it.\n */\nexport const DATA_AUTH_URLS = new InjectionToken<string[]>('data.auth.urls');\n\n/**\n * Attaches the JWT access token to outgoing requests and transparently refreshes it\n * when the API rejects it.\n *\n * This is a **legacy class-based interceptor**, not a functional one, so it must be\n * registered through the `HTTP_INTERCEPTORS` multi-provider and `provideHttpClient`\n * must be given `withInterceptorsFromDi()`:\n *\n * ```ts\n * providers: [\n * provideHttpClient(withInterceptorsFromDi()),\n * { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },\n * ]\n * ```\n *\n * On a 401 it calls {@link AuthServiceBase.refresh} once and replays the failed\n * request with the new token; concurrent 401s wait for that single refresh rather than\n * each triggering their own.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class AuthInterceptor implements HttpInterceptor {\n private _isRefreshing = false;\n private _refreshTokenSubject = new BehaviorSubject<IJwtRefreshResponseJson | null>(null);\n\n private _auth = inject(DATA_AUTH_SERVICE);\n private _apiUrl = inject(DATA_API_URL);\n private _urls = inject(DATA_AUTH_URLS, { optional: true });\n\n /**\n * Adds `Authorization: Bearer <access token>` to a request, but only when **all** of\n * the following hold: a session is open (the auth service is not anonymous); the url\n * is neither the login nor the refresh endpoint (which must stay unauthenticated to\n * avoid a refresh loop); and the url starts with either `DATA_API_URL` or one of the\n * prefixes listed in {@link DATA_AUTH_URLS}.\n *\n * Requests failing any of these conditions are forwarded untouched — notably,\n * third-party urls never leak the token unless explicitly opted in via\n * {@link DATA_AUTH_URLS}. Authenticated requests additionally get 401 handling with\n * automatic token refresh and replay.\n */\n intercept(req: HttpRequest<unknown>, next: HttpHandler) {\n // If the user is anonymous, we don't add the token\n if (this._auth.isAnonymous) {\n return next.handle(req);\n }\n // If the request is refresh or login url, skip auth\n if (req.url.startsWith(this._auth.refreshUrl) || req.url.startsWith(this._auth.loginUrl)) {\n return next.handle(req);\n }\n // If the request is not for the api, and not for one of the urls specified in the\n // DATA_AUTH_URLS injection token, skip auth\n if (\n !req.url.startsWith(this._apiUrl) &&\n !(this._urls && this._urls.length > 0 && this._urls.some((url) => req.url.startsWith(url)))\n ) {\n return next.handle(req);\n }\n if (!this._auth.isAnonymous) {\n req = this._addToken(req, this._auth.accessToken as string);\n }\n return next.handle(req).pipe(\n catchError((error) => {\n console.log('Catched http error', error);\n if (error instanceof HttpErrorResponse && error.status === 401) {\n console.log('Passing to handle 401');\n return this._handle401Error(req, next);\n } else {\n console.log('throwing error');\n return throwError(error);\n }\n }),\n );\n }\n\n private _handle401Error(request: HttpRequest<unknown>, next: HttpHandler) {\n if (!this._isRefreshing) {\n this._isRefreshing = true;\n this._refreshTokenSubject.next(null);\n console.log('refreshing token');\n return this._auth.refresh().pipe(\n tap((token) => console.log('Refreshed token result', token)),\n switchMap((token) => {\n if (token === null) {\n this._isRefreshing = false;\n return throwError(\n () =>\n new HttpErrorResponse({\n error: 'Forbidden, please log in',\n status: 403,\n statusText: 'Warning',\n url: request.url,\n }),\n );\n } else {\n this._isRefreshing = false;\n this._refreshTokenSubject.next(token);\n return next.handle(this._addToken(request, token.access));\n }\n }),\n );\n } else {\n return this._refreshTokenSubject.pipe(\n filter((token) => token != null),\n take(1),\n switchMap((token) => next.handle(this._addToken(request, token.access))),\n );\n }\n }\n\n private _addToken(request: HttpRequest<unknown>, token: string) {\n const headers = request.headers.delete('Authorization').append('Authorization', `Bearer ${token}`);\n return request.clone({ headers });\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { combineLatest, NEVER, Observable, of, ReplaySubject, share, Subject, takeUntil } from 'rxjs';\nimport { DataModel } from '../data/data-model';\nimport { IQueryMeta, IQueryMetaNavParams, IQueryNav, Queryset } from '../data/data-query';\nimport { switchMap, tap, throttleTime } from 'rxjs/operators';\nimport { ModelListFields } from './model-list-fields/model-list-fields';\nimport { ModelListPaginator } from './model-list-paginator/model-list-paginator';\nimport { ModelListSorter } from './model-list-sorter/model-list-sorter';\nimport { ModelListFilters } from './model-list-filters/model-list-filters';\nimport { Collection } from '../data/data-collection';\nimport { ModelListFilter } from './model-list-filters/model-list-filter';\nimport { IFieldHeaderMessage } from './model-list-fields/model-list-field-header/messages';\nimport { AuthServiceBase } from '../auth/auth.service';\nimport { DATA_AUTH_SERVICE } from '../auth/auth-interceptor.service';\nimport { ModelListFilterGroup } from './model-list-filters/model-list-filter-group';\n\n/**\n * A synthetic column that does not exist on the model.\n *\n * Declared through {@link FieldsParams.custom}, it takes part in ordering and\n * shows up in the field selector exactly like a real field, but carries no\n * field manager and is never requested from the API. The typical use is an\n * \"actions\" column holding edit/delete buttons.\n */\nexport interface CustomField {\n /** Column key, used to address it in `defaults`/`allowed`/`excluded` and in templates. */\n name: string;\n /** Human readable column title. */\n label: string;\n /** Ordering weight, higher comes first. Use `-1` to keep it out of the default set. */\n priority?: number;\n}\n\n/**\n * A fixed query filter dict, force-ANDed into every request the list makes.\n *\n * This is scoping/context (the current tenant, the parent object of a nested\n * list), not user-facing filtering — see {@link ModelListParams.filter}.\n */\nexport type FilterDefaults = Record<string, string | number | undefined>;\n\n/**\n * Initial sort keys, as `field` / `+field` (ascending) or `-field` (descending).\n */\nexport type SorterDefaults = string[];\n\n/**\n * Which columns a list may show, which it shows by default, and in what order.\n *\n * The four lists are resolved once, in {@link ModelListFields}' constructor: the\n * model's own decorated fields are collected, `custom` entries are appended,\n * everything is ordered by `priority` (higher first), then `allowed`/`defaults`\n * select what the user can enable and what is enabled on load, and `excluded`\n * removes fields outright. Fields that end up neither allowed nor enabled are\n * dropped from the list entirely.\n */\nexport interface FieldsParams {\n /** Allowed fields, all model fields are allowed if empty */\n allowed?: string[];\n /**\n * Fields enabled on load, also fixing their left-to-right order.\n * Defaults to every field with a `priority >= 0` when `allowed` is empty.\n */\n defaults?: string[];\n /** Excluded fields */\n excluded?: string[];\n /** Extra non-model columns, e.g. an actions column. See {@link CustomField}. */\n custom?: CustomField[];\n}\n\n/**\n * Definitions of the user-facing filter widgets, and which of them are offered.\n *\n * `filters` holds the actual widget definitions; `allowed`/`defaults`/`excluded`\n * select among them by name, following the same resolution as\n * {@link FieldsParams}. Not to be confused with {@link ModelListParams.filter},\n * which is a fixed query dict rather than a set of widgets.\n */\nexport interface FiltersParams {\n /** Allowed filter names */\n allowed?: string[];\n /** Default active filter names */\n defaults?: string[];\n /** Excluded filter names */\n excluded?: string[];\n /** Filters definitions; groups are flattened, keeping the grouping for display. */\n filters?: (ModelListFilter | ModelListFilterGroup)[];\n}\n\n/**\n * @deprecated Unused by this module and mistyped for the job: it aliases the\n * string-valued nav params echoed back by the API, whereas\n * {@link ModelListParams.paginator} expects a numeric {@link IQueryNav}.\n */\nexport type PaginationParams = IQueryMetaNavParams;\n\n/**\n * A message pushed on {@link ModelList.messages$} to drive list UI from the\n * outside. Currently only header messages exist — see {@link IFieldHeaderMessage}.\n */\nexport type IModelListMessage = IFieldHeaderMessage;\n\n/**\n * Everything {@link ModelListService.get} needs to build a list: its columns,\n * its filters, its initial sort and page, plus the two subjects through which\n * the owning component drives and ends its lifecycle.\n *\n * **These are defaults, applied at creation time only.** When `get()` returns a\n * cached instance (see {@link keep}), every value here except `reload` and\n * `unsubscribe` is silently ignored — and those two only take effect if the\n * cached list is not currently started.\n *\n * @see {@link ModelListService.get} for the expected `ngOnInit` lifecycle.\n */\nexport interface ModelListParams {\n /** Column set and ordering. */\n fields?: FieldsParams;\n /**\n * Definitions of the user-facing filter widgets.\n * Not to be confused with {@link filter} — this is the widgets, that is the query.\n */\n filters?: FiltersParams;\n /**\n * A fixed filter dict force-ANDed into every query, or an observable of one.\n *\n * This is scoping/context — the parent object of a nested list, the current\n * tenant, a hardcoded `status` — not something the user sees or clears. It is\n * applied on top of the widget filters, so it always wins. Pass an observable\n * when the scope changes over the component's life; each emission re-runs the\n * query.\n */\n filter?: FilterDefaults | Observable<FilterDefaults>;\n /** Initial sort keys, e.g. `['-created', 'name']`. */\n sorter?: SorterDefaults;\n /** Initial page and page size. Defaults to page 1, 20 per page. */\n paginator?: IQueryNav;\n /**\n * Cache this list under {@link name} and reuse it on later `get()` calls.\n *\n * **Caching is keyed by `name` alone** — not by component, route or\n * collection — so any two lists sharing a name share one instance, and its\n * fields, filters, sort and page bleed between them. Names must be globally\n * unique across the whole app. Leave `false` (the default) for a private,\n * non-persisted list. See {@link ModelListService} for the full picture.\n */\n keep?: boolean;\n /**\n * A subject you own; `.next(true)` re-runs the query against the API with\n * `db=sync`, `.next()` re-runs it normally.\n *\n * Pass one whenever the list has row actions that mutate data, otherwise you\n * have no way to refresh it: if you omit it, `get()` creates its own subject\n * internally and you never get a reference to it.\n */\n reload?: Subject<void | boolean>;\n /**\n * A subject you own and must fire from `ngOnDestroy`; the library `takeUntil`s\n * it to tear the list's subscriptions down.\n *\n * The public API here is subject-based rather than `DestroyRef`-based, so this\n * cannot be inferred — omitting it means the query subscription lives as long\n * as the `ModelList` does.\n */\n unsubscribe?: Subject<void>;\n}\n\n/**\n * A live, self-refreshing list of models: the object a list component binds its\n * table, its paginator and its filter bar to.\n *\n * It owns a {@link Queryset} plus the four managers that feed it — {@link fields},\n * {@link filters}, {@link sorter}, {@link paginator} — and wires them together in\n * {@link start}, so that any change to any of them re-runs the query and pushes\n * new {@link results}. Components never build one directly: {@link ModelListService.get}\n * assembles and starts it.\n *\n * Read data through {@link results}/{@link meta}/{@link loading}/{@link full}\n * (shared, so subscribing several times does not multiply requests) and mutate\n * state through the managers.\n */\nexport class ModelList<T extends DataModel> {\n /** Cache key under which {@link ModelListService} may keep this list. */\n public name!: string;\n /** User-facing filter widgets and their current values. */\n public filters!: ModelListFilters;\n /** Current sort keys. */\n public sorter!: ModelListSorter;\n /** Current page and page size. */\n public paginator!: ModelListPaginator;\n /** The underlying query; reconfigured and re-run on every change. */\n public queryset!: Queryset<T>;\n /** Available/enabled columns and their order. */\n public fields!: ModelListFields<T>;\n /** Fire to re-run the query; `next(true)` forces a `db=sync` refresh. */\n public reload!: Subject<void | boolean>;\n /** Fired by the owning component to tear the list down. */\n public unsubscribe!: Subject<void>;\n /**\n * Out-of-band channel to drive list UI. Nothing in the library emits on it —\n * consumers push messages, and {@link ModelListFieldHeaderComponent} reacts.\n */\n public messages$ = new ReplaySubject<IModelListMessage>(1);\n /** True once {@link start} has run and the query subscription is alive. */\n public started = false;\n\n constructor(name: string, collection: Collection<T>) {\n this.name = name;\n this._collection = collection;\n }\n\n private _collection!: Collection<T>;\n\n /** The collection this list queries. */\n public get collection(): Collection<T> {\n return this._collection;\n }\n\n private _count: number | null = null;\n\n /**\n * Total number of matching rows, cached from the last `meta` received, or\n * `null` before the first one.\n *\n * It is the {@link meta} pipeline that refreshes this, so it stays `null`\n * unless something is subscribed to {@link meta} (or {@link full}).\n */\n public get count(): number | null {\n return this._count;\n }\n\n private _results?: Observable<T[]>;\n\n /**\n * The current page of models, re-emitted on every query.\n *\n * Created on first access and shared, so binding it from several places costs\n * one subscription to the queryset.\n */\n public get results(): Observable<T[]> {\n if (!this._results) {\n this._results = this.queryset.results.pipe(\n // tap(() => console.log('@solidev/data: modellist result')),\n share(),\n takeUntil(this.unsubscribe || NEVER),\n );\n }\n return this._results;\n }\n\n private _meta?: Observable<IQueryMeta>;\n\n /**\n * Pagination metadata (count, page, pages...) accompanying each response.\n * Subscribing to it is also what keeps {@link count} up to date.\n */\n public get meta(): Observable<IQueryMeta> {\n if (!this._meta) {\n this._meta = this.queryset.meta.pipe(\n // tap(() => console.log('@solidev/data: modellist meta')),\n tap((m) => (this._count = m.nav.count)),\n share(),\n takeUntil(this.unsubscribe || NEVER),\n );\n }\n return this._meta;\n }\n\n private _loading?: Observable<boolean>;\n\n /** True while a query is in flight; bind it to a spinner. */\n public get loading(): Observable<boolean> {\n if (!this._loading) {\n this._loading = this.queryset.loading.pipe(\n // tap(() => console.log('@solidev/data: modellist loading')),\n share(),\n takeUntil(this.unsubscribe || NEVER),\n );\n }\n return this._loading;\n }\n\n private _full?: Observable<[T[], boolean, IQueryMeta]>;\n\n /**\n * `[results, loading, meta]` combined, for templates that need all three\n * without nesting three async pipes.\n */\n public get full(): Observable<[T[], boolean, IQueryMeta]> {\n if (!this._full) {\n this._full = this.queryset.full.pipe(\n // tap(() => console.log('@solidev/data: modellist full')),\n share(),\n takeUntil(this.unsubscribe || NEVER),\n );\n }\n return this._full;\n }\n\n /**\n * Wire the managers to the queryset and fire the first query.\n *\n * Combines {@link reload}, the filter widgets' output, the fixed\n * {@link ModelListParams.filter}, the paginator, the sorter and the enabled\n * fields; any emission reconfigures the queryset and re-runs it, throttled to\n * one query per 200ms. A `reload.next(true)` seen since the last query makes\n * that query a `db=sync` one. Called by {@link ModelListService.get}; calling\n * it twice on the same list stacks a second subscription.\n */\n public start(params: ModelListParams) {\n let filter$: Observable<FilterDefaults>;\n let reloadFired = false;\n if (params.filter && !params.filter.subscribe) {\n filter$ = of(params.filter as FilterDefaults);\n } else if (params.filter && params.filter.subscribe) {\n filter$ = params.filter as Observable<FilterDefaults>;\n } else {\n filter$ = of({});\n }\n combineLatest([\n this.reload.pipe(tap((v) => (reloadFired = !!v))),\n this.filters.output,\n filter$,\n this.paginator.output,\n this.sorter.output,\n this.fields.output,\n ])\n .pipe(\n throttleTime(200),\n switchMap(([, filter, manualFilter, paginator, sorter, fields]) => {\n this.queryset\n .filter(filter)\n .filter(manualFilter || {}, true)\n .paginateBy(paginator.page_size)\n .setPage(paginator.page)\n .sort(...sorter)\n .setFields(fields);\n const dbSync = reloadFired;\n reloadFired = false;\n return this.queryset.get(true, dbSync);\n }),\n takeUntil(this.unsubscribe || NEVER),\n )\n .subscribe({\n next: (): void => {\n // console.log('@solidev/data: modellist:get results', this.name);\n },\n error: (error) => {\n console.error('@solidev/data: error while getting model list results : ', error);\n },\n complete: () => {\n // console.log('@solidev/data: modellist:completed', this.name);\n this.started = false;\n },\n });\n this.reload.next();\n this.started = true;\n }\n}\n\n/**\n * Builds {@link ModelList} instances — the entry point to this whole module.\n *\n * {@link get} composes a {@link Queryset} with a {@link ModelListFields},\n * {@link ModelListSorter}, {@link ModelListPaginator} and {@link ModelListFilters},\n * starts it, and hands back a live list. It can also cache lists so that a user\n * returning to a route finds their columns and filters as they left them.\n *\n * **Caching is keyed by name alone.** `_instances` is a `Map<string, ModelList>`\n * indexed by the `name` argument — not by component, route or collection. Two\n * `get()` calls passing the same name with `keep: true` therefore get *the same\n * list*, and its fields, filters, sort and page bleed across every route using\n * that name. Worse, when a cached instance is returned the `defaults` you passed\n * are silently ignored: different `fields` or `filters` for the same name have\n * no effect at all. Treat `name` as a globally unique identifier, and use\n * `keep: false` whenever you want a private, non-persisted list.\n *\n * All cached instances are unsubscribed and dropped when the user logs out, via\n * {@link AuthServiceBase.logout$}.\n *\n * **Recommended architecture:** do not call `get()` from each list component.\n * In a large consumer app this service is wrapped exactly once, in an abstract\n * base `@Directive` that every list component extends — around 150 of them —\n * which owns the `name`, `keep`, `reload` and `unsubscribe` plumbing and the\n * `ngOnInit` timing. Wrap it, then extend the wrapper.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class ModelListService {\n /** Kept lists, keyed by `name` only. See the class doc for what that implies. */\n private _instances = new Map<string, ModelList<DataModel>>();\n // Only `logout$` is used here, so the three type parameters are irrelevant.\n // See DATA_AUTH_SERVICE: the app specialises the three parameters.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _auth: AuthServiceBase<any, any, any> = inject(DATA_AUTH_SERVICE);\n\n constructor() {\n this._auth.logout$.pipe(takeUntilDestroyed()).subscribe(() => this.reset());\n }\n\n /**\n * Tear down and forget every cached list.\n *\n * Called automatically on logout, so that the next user does not inherit the\n * previous one's columns, filters and — through the queryset — their data.\n */\n public reset() {\n for (const i of this._instances.values()) {\n if (i.unsubscribe) {\n console.log('Clearing ', i);\n i.unsubscribe.next();\n }\n }\n this._instances.clear();\n }\n\n /**\n * Get a started {@link ModelList} for `collection`, either fresh or from cache.\n *\n * A fresh list is built whenever `name` is empty, `keep` is falsy, or nothing\n * is cached under `name`; otherwise the cached instance is returned as-is and\n * `defaults` is ignored — see the class doc, this is the main trap of this API.\n *\n * **Call this from `ngOnInit`, never from the constructor.** It consumes bound\n * inputs (`name`, `keep`, `filter`), which are not set yet at construction\n * time; called too early, `name` is undefined and you silently land in the\n * always-fresh branch, so `keep` never works.\n *\n * @param name globally unique list identifier, and the cache key when `keep` is set\n * @param collection the collection to query\n * @param defaults columns, filters, sort, page and lifecycle subjects\n *\n * @example\n * ```ts\n * export class ThingListComponent implements OnInit, OnDestroy {\n * private _lists = inject(ModelListService);\n * private _things = inject(ThingService);\n * public list!: ModelList<Thing>;\n * public reload = new Subject<void | boolean>();\n * public unsubscribe = new Subject<void>();\n *\n * public ngOnInit(): void {\n * this.list = this._lists.get('things', this._things, {\n * fields: { defaults: ['name', 'status'] },\n * sorter: ['-created'],\n * reload: this.reload,\n * unsubscribe: this.unsubscribe,\n * });\n * }\n *\n * public ngOnDestroy(): void {\n * this.unsubscribe.next();\n * }\n *\n * public onDeleted(): void {\n * this.reload.next(true);\n * }\n * }\n * ```\n */\n public get<T extends DataModel>(name: string, collection: Collection<T>, defaults: ModelListParams) {\n let ml: ModelList<T>;\n\n if (!name || !this._instances.has(name) || !defaults.keep) {\n ml = new ModelList<T>(name, collection);\n ml.queryset = collection.queryset();\n ml.fields = new ModelListFields(collection, defaults.fields);\n ml.sorter = new ModelListSorter(defaults.sorter || []);\n ml.paginator = new ModelListPaginator(defaults.paginator);\n ml.filters = new ModelListFilters(defaults.filters);\n if (defaults.keep) {\n this._instances.set(name, ml as unknown as ModelList<DataModel>);\n }\n } else {\n // The cache is keyed by name and holds lists of every model type.\n ml = this._instances.get(name)! as unknown as ModelList<T>;\n }\n if (!ml.started) {\n if (defaults.reload) {\n ml.reload = defaults.reload;\n } else {\n ml.reload = new Subject<void | boolean>();\n }\n if (defaults.unsubscribe) {\n ml.unsubscribe = defaults.unsubscribe;\n } else {\n ml.unsubscribe = new Subject<void>();\n }\n ml.start(defaults);\n }\n return ml;\n }\n}\n","import { Component, ElementRef, inject, input, OnInit, ViewChild } from '@angular/core';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelList } from '../../model-list.service';\nimport { CDK_DRAG_CONFIG, CdkDragDrop, DragDropModule } from '@angular/cdk/drag-drop';\nimport { AsyncPipe } from '@angular/common';\nimport { NgbOffcanvas, NgbOffcanvasModule } from '@ng-bootstrap/ng-bootstrap';\nimport { ModelListField } from '../model-list-fields';\nimport { CdkScrollableModule } from '@angular/cdk/scrolling';\n\nconst DragConfig = {\n dragStartThreshold: 5,\n pointerDirectionChangeThreshold: 10,\n zIndex: 10000,\n};\n\n@Component({\n selector: 'data-model-list-fields-selector',\n templateUrl: './model-list-fields-selector.component.html',\n styleUrls: ['./model-list-fields-selector.component.sass'],\n imports: [AsyncPipe, DragDropModule, CdkScrollableModule, NgbOffcanvasModule],\n providers: [{ provide: CDK_DRAG_CONFIG, useValue: DragConfig }],\n})\n/**\n * A button opening an offcanvas panel where the user picks which columns a list\n * shows and drags them into order.\n *\n * Drop it next to the table, bound to the same {@link ModelList}; it drives that\n * list's {@link ModelListFields} directly, so the table follows. Only columns\n * with `priority >= 0` are listed until the user asks for more.\n *\n * @example\n * ```html\n * <data-model-list-fields-selector [list]=\"list\"></data-model-list-fields-selector>\n * ```\n */\nexport class ModelListFieldsSelectorComponent<T extends DataModel> implements OnInit {\n /** The list whose columns are being edited. */\n public list = input.required<ModelList<T>>();\n @ViewChild('selector', { static: true })\n public ofctpl!: ElementRef<HTMLDivElement>;\n /** When true, also list the `priority < 0` columns normally kept out of the way. */\n public seeMore = false;\n private _ofc = inject(NgbOffcanvas);\n\n /** Fail fast if the list was not passed or has not been built by the service. */\n public ngOnInit() {\n if (!this.list() || !this.list().fields) {\n throw new Error('Missing list / fields');\n }\n }\n\n /** Open the field selector panel. */\n public open() {\n this._ofc.open(this.ofctpl);\n }\n\n /** Reorder the dropped column, placing it between its new neighbours. */\n drop($event: CdkDragDrop<T, T>) {\n let pos = $event.currentIndex * 10;\n if ($event.currentIndex > $event.previousIndex) {\n pos += 1;\n } else {\n pos -= 1;\n }\n this.list().fields.setPosition(String($event.item.data), pos);\n }\n\n /** Show or hide column `f`, depending on its current state. */\n public toggle(f: ModelListField) {\n if (f.enabled) {\n this.list().fields.disable(f.name);\n } else {\n this.list().fields.enable(f.name);\n }\n }\n}\n","<i\n class=\"bi bi-list-ul\"\n (click)=\"open()\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Choix des champs\"\n (keydown.enter)=\"open()\"\n (keydown.space)=\"$event.preventDefault(); open()\"\n></i>\n<ng-template #selector let-offcanvas>\n <div class=\"offcanvas-header\">\n <h4 class=\"offcanvas-title\">Choix des champs</h4>\n <button class=\"btn-close\" type=\"button\" aria-label=\"Close\" (click)=\"offcanvas.dismiss('x')\"></button>\n </div>\n <div class=\"offcanvas-body\" cdkScrollable>\n @if (list().fields.fields | async; as fields) {\n <div class=\"fields-list\" cdkDropList cdkDropListLockAxis=\"y\" (cdkDropListDropped)=\"drop($event)\">\n @for (f of fields; track f) {\n @if (seeMore || f.priority >= 0) {\n <div\n class=\"field-box\"\n cdkDrag\n (click)=\"toggle(f)\"\n (keydown.enter)=\"toggle(f)\"\n (keydown.space)=\"$event.preventDefault(); toggle(f)\"\n tabindex=\"0\"\n [cdkDragData]=\"f.name\"\n [class.enabled]=\"f.enabled\"\n [class.compact]=\"fields.length&gt;30\"\n [attr.arial-label]=\"f.label\"\n role=\"button\"\n >\n {{ f.label }}\n <span class=\"badge bg-info\">{{ f.priority }}</span>\n </div>\n }\n }\n </div>\n }\n <button class=\"btn btn-sm btn-link\" (click)=\"seeMore = !seeMore\">plus de champs</button>\n </div>\n</ng-template>\n","import { Component, input, signal } from '@angular/core';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelList } from '../../model-list.service';\n\n@Component({\n selector: 'data-model-list-sorter',\n templateUrl: './model-list-sorter.component.html',\n styleUrls: ['./model-list-sorter.component.sass'],\n imports: [],\n})\n/**\n * The pair of asc/desc arrows that sort a list on one field, plus a rank badge\n * and a clear button when several fields are sorted at once.\n *\n * Usually not placed by hand: {@link ModelListFieldHeaderComponent} renders it\n * for columns declared sortable. Use it directly to sort on a field that has no\n * column of its own. Any projected content is rendered after the arrows.\n *\n * Its displayed state is refreshed only by its own click handlers, so a sort\n * coming from anywhere else — the list's initial `sorter` defaults included — is\n * not reflected until the user touches it.\n */\nexport class ModelListSorterComponent<T extends DataModel = DataModel> {\n /**\n * ModelList reference.\n */\n public list = input.required<ModelList<T>>();\n /**\n * Sort field name.\n */\n public field = input.required<string>();\n /** Number of sorted fields, when this one is sorted; 0 otherwise. Drives the rank badge. */\n public getCount = signal<number>(0);\n /** This field's 1-based rank among the sort keys, -1 if unsorted. */\n public getOrder = signal<number>(0);\n /** This field is sorted ascending. */\n public isUp = signal<boolean>(false);\n /** This field is sorted descending. */\n public isDown = signal<boolean>(false);\n\n constructor() {\n // Dependencies are resolved with inject().\n }\n\n /** Sort ascending on this field. */\n public setUp(): void {\n this.list().sorter.set(this.field(), 'asc');\n this.update();\n }\n\n /** Re-read this field's sort state from the list's sorter into the signals. */\n public update() {\n this.getCount.set(this.list().sorter.get(this.field()) ? this.list().sorter.getAll().length : 0);\n this.getOrder.set(this.list().sorter.getOrder(this.field()));\n this.isDown.set(this.getIsDown());\n this.isUp.set(this.getIsUp());\n }\n\n /** Sort descending on this field. */\n public setDown(): void {\n this.list().sorter.set(this.field(), 'desc');\n this.update();\n }\n\n /** Stop sorting on this field, leaving the other sort keys in place. */\n public cancel(): void {\n this.list().sorter.unset(this.field());\n this.update();\n }\n\n private getIsDown(): boolean {\n const f = this.list().sorter.get(this.field());\n if (f) {\n return f.direction === 'desc';\n }\n return false;\n }\n\n private getIsUp(): boolean {\n const f = this.list().sorter.get(this.field());\n if (f) {\n return f.direction === 'asc';\n }\n return false;\n }\n}\n","<span class=\"dirs\">\n @if (getOrder() >= 0 || getCount() > 1) {\n <span\n (click)=\"cancel()\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Annuler le tri\"\n (keydown.enter)=\"cancel()\"\n (keydown.space)=\"$event.preventDefault(); cancel()\"\n >\n @if (getCount() > 1) {\n <span class=\"count\">{{ getOrder() }}</span>\n }\n <span class=\"bi bi-x\"></span>\n </span>\n }\n <span\n class=\"bi bi-sort-down-alt\"\n (click)=\"setUp()\"\n [class.active]=\"isUp()\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Trier par ordre croissant\"\n (keydown.enter)=\"setUp()\"\n (keydown.space)=\"$event.preventDefault(); setUp()\"\n ></span>\n <span\n class=\"bi bi-sort-down\"\n (click)=\"setDown()\"\n [class.active]=\"isDown()\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Trier par ordre décroissant\"\n (keydown.enter)=\"setDown()\"\n (keydown.space)=\"$event.preventDefault(); setDown()\"\n ></span>\n &nbsp;\n</span>\n<ng-content></ng-content>\n","import { Component, DestroyRef, inject, input, model, OnInit, signal, ViewChild } from '@angular/core';\nimport { ModelList } from '../../model-list.service';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelListField } from '../model-list-fields';\nimport { AsyncPipe, NgTemplateOutlet } from '@angular/common';\nimport { NgbDropdown, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';\nimport { ModelListSorterComponent } from '../../model-list-sorter/model-list-sorter/model-list-sorter.component';\nimport { filter } from 'rxjs/operators';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-model-list-field-header',\n templateUrl: './model-list-field-header.component.html',\n styleUrls: ['./model-list-field-header.component.sass'],\n imports: [AsyncPipe, NgTemplateOutlet, NgbDropdownModule, ModelListSorterComponent],\n})\n/**\n * A `<th>` for one column: its label, its sort control, and a menu to remove it\n * or insert another column after it.\n *\n * Put one per column in the table header, bound to the same {@link ModelList}.\n * The label comes from the field's metadata unless projected content is given.\n * It also listens on {@link ModelList.messages$} so the app can retune every\n * header at once — see {@link IFieldHeaderMessage}.\n *\n * @example\n * ```html\n * <th><data-model-list-field-header [list]=\"list\" field=\"name\" [sort]=\"true\">\n * </data-model-list-field-header></th>\n * ```\n */\nexport class ModelListFieldHeaderComponent<T extends DataModel> implements OnInit {\n /** The list this column belongs to. */\n public list = input.required<ModelList<T>>();\n /** Name of the column being headed. */\n public field = input.required<string>();\n /** Offer a sort control for this column. */\n public sort = input<boolean>(false);\n /** Field to sort on, when it differs from the displayed one (e.g. sort a label column on its id). */\n public sortField = input<string>();\n /** Where the column menu lives, or `'hide'` to drop it. */\n public menuMode = input<'hide' | 'side' | 'click'>('side');\n /** Where the sort control lives, or `'hide'` to drop it. */\n public sortMode = input<'hide' | 'side' | 'click'>('side');\n /** Two-way visibility flag, also settable from a header message. */\n public display = model<boolean>();\n\n @ViewChild('mnu', { static: false }) public mnu?: NgbDropdown;\n /** Effective menu mode: the message override if any, else {@link menuMode}. */\n public dispMenuMode = signal(this.menuMode());\n /** Effective sort mode: the message override if any, else {@link sortMode}. */\n public dispSortMode = signal(this.sortMode());\n private destroy$ = inject(DestroyRef);\n\n /** Subscribe to the list's header messages and apply them to the effective modes. */\n public ngOnInit() {\n this.list()\n .messages$.pipe(\n takeUntilDestroyed(this.destroy$),\n filter((m) => m.dest === 'header'),\n )\n .subscribe((m) => {\n this.dispMenuMode.set(m.menu && m.menu !== 'default' ? m.menu : this.menuMode());\n this.dispSortMode.set(m.sort && m.sort !== 'default' ? m.sort : this.sortMode());\n this.display.set(m.show !== undefined ? m.show : this.display());\n });\n }\n\n /** Remove this column from the table. */\n public disable() {\n this.list().fields.disable(this.field());\n }\n\n /** Insert column `f` immediately after this one and show it. */\n public enable(f: ModelListField) {\n this.list().fields.move(f.name, 'after', this.field());\n this.list().fields.enable(f.name);\n }\n}\n","<ng-template #label>\n <span #ref><ng-content></ng-content></span>\n @if (!ref.children.length) {\n <span>{{ list().fields.get(field())?.label || field() }}</span>\n }\n</ng-template>\n<div class=\"d-flex flex-row justify-content-between align-items-end slabel\">\n <div class=\"flex-grow-1\">\n @if (sort() && dispSortMode() === \"side\") {\n <data-model-list-sorter [list]=\"list()\" [field]=\"sortField() || field()\">\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n </data-model-list-sorter>\n }\n @if (!sort() || dispSortMode() === \"hide\") {\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n }\n </div>\n @if (dispMenuMode() === \"side\") {\n <div class=\"navicons d-flex flex-row\" [attr.aria-label]=\"'Gestion champs'\">\n <i\n class=\"bi bi-caret-left-fill\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Déplacer vers la gauche\"\n (click)=\"list().fields.move(field(), 'before')\"\n (keydown.enter)=\"list().fields.move(field(), 'before')\"\n (keydown.space)=\"$event.preventDefault(); list().fields.move(field(), 'before')\"\n ></i>\n <div ngbDropdown #mnu=\"ngbDropdown\" [container]=\"'body'\">\n <i class=\"bi bi-record\" ngbDropdownToggle aria-label=\"Ouvrir la boite de dialogue des champs\" role=\"button\"></i>\n <div ngbDropdownMenu>\n <button ngbDropdownItem (click)=\"disable()\">\n <i class=\"bi bi-trash me-2\"></i>\n Supprimer\n </button>\n <h6 class=\"dropdown-header\">Ajouter une colonne après</h6>\n @for (f of list().fields.fields | async; track f) {\n @if (f.allowed && !f.enabled) {\n <button ngbDropdownItem (click)=\"enable(f)\" [attr.aria-label]=\"f.label || f.name\">\n <i class=\"bi bi-plus-circle me-2\"></i>\n {{ f.label || f.name }}\n </button>\n }\n }\n </div>\n </div>\n <i\n class=\"bi bi-caret-right-fill\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Déplacer vers la droite\"\n (click)=\"list().fields.move(field(), 'after')\"\n (keydown.enter)=\"list().fields.move(field(), 'after')\"\n (keydown.space)=\"$event.preventDefault(); list().fields.move(field(), 'after')\"\n ></i>\n </div>\n }\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelList } from '../../model-list.service';\nimport { ModelListFilter } from '../model-list-filter';\nimport { AsyncPipe } from '@angular/common';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-model-list-filters-select',\n templateUrl: './model-list-filters-select.component.html',\n styleUrls: ['./model-list-filters-select.component.sass'],\n imports: [AsyncPipe, ReactiveFormsModule],\n})\n/**\n * The filter picker: lets the user turn a list's available filters on and off.\n *\n * It offers the filters the list marks as allowed, honouring their grouping,\n * and toggling one enables or disables its widget in\n * {@link ModelListFiltersComponent} — the two components are meant to sit side\n * by side.\n *\n * @example\n * ```html\n * <data-model-list-filters-select [list]=\"list\" mode=\"badge_summary\" />\n * <data-model-list-filters [list]=\"list\" />\n * ```\n */\nexport class ModelListFiltersSelectComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list whose filters can be toggled. Required. */\n public list = input.required<ModelList<T>>();\n /** CSS classes for the element wrapping the picker. */\n public containerClasses = input<string[] | string>('');\n /** CSS classes for an enabled filter's badge, in the badge modes. */\n public itemActiveClasses = input<string[] | string>('badge bg-success mx-1');\n /** CSS classes for a disabled filter's badge, in the badge modes. */\n public itemInactiveClasses = input<string[] | string>('badge bg-secondary mx-1');\n /**\n * How the picker presents itself: `badge` (the default) shows every available\n * filter as a clickable badge; `badge_summary` shows only the enabled ones,\n * each with its current value; `select` uses a dropdown instead, which suits\n * long filter lists.\n */\n public mode = input<'select' | 'badge' | 'badge_summary'>('badge');\n\n /** Backs the dropdown in `select` mode; unused in the badge modes. */\n public selectForm = new FormControl<ModelListFilter | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Flips a filter's enabled state and refreshes the list. Bound to the badges;\n * note that a filter disabled this way keeps its value.\n */\n public toggle(f: ModelListFilter) {\n f.enabled = !f.enabled;\n this.list().filters.update();\n }\n\n /**\n * In `select` mode only, wires the dropdown so that picking a filter toggles\n * it and resets the control, leaving the dropdown ready for the next pick.\n */\n public ngOnInit() {\n if (this.mode() === 'select') {\n this.selectForm.valueChanges.pipe(takeUntilDestroyed(this.destroy$)).subscribe((f) => {\n if (f) {\n f.enabled = !f.enabled;\n this.list().filters.update();\n this.selectForm.setValue(null, { emitEvent: false });\n }\n });\n }\n }\n}\n","@if (mode() === \"badge\") {\n @for (f of list().filters.available | async; track f) {\n <span\n (click)=\"toggle(f)\"\n [class]=\"containerClasses()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-pressed]=\"f.enabled\"\n [attr.aria-label]=\"f.label\"\n (keydown.enter)=\"toggle(f)\"\n (keydown.space)=\"$event.preventDefault(); toggle(f)\"\n >\n @if (f.enabled) {\n <span [class]=\"itemActiveClasses()\" [title]=\"f.desc\">\n <i class=\"bi bi-check2-square me-2\"></i>\n <span>{{ f.label }}</span>\n </span>\n }\n @if (!f.enabled) {\n <span [class]=\"itemInactiveClasses()\" [title]=\"f.desc\">\n <i class=\"bi bi-square me-2\"></i>\n <span>{{ f.label }}</span>\n </span>\n }\n </span>\n }\n}\n@if (mode() === \"badge_summary\") {\n @for (f of list().filters.available | async; track f) {\n <span\n (click)=\"toggle(f)\"\n [class]=\"containerClasses()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-pressed]=\"f.enabled\"\n [attr.aria-label]=\"f.label\"\n (keydown.enter)=\"toggle(f)\"\n (keydown.space)=\"$event.preventDefault(); toggle(f)\"\n >\n @if (f.enabled) {\n <span [class]=\"itemActiveClasses()\" [title]=\"f.desc\">\n <i class=\"bi bi-check2-square me-2\"></i>\n <span>{{ f.label }} : {{ f.summary || \"...\" }}</span>\n </span>\n }\n </span>\n }\n}\n@if (mode() === \"select\") {\n <select class=\"form-select\" [formControl]=\"selectForm\">\n <option [ngValue]=\"null\">-- Ajouter un filtre --</option>\n @for (f of list().filters.available | async; track f) {\n @if (!f.enabled && !f.group) {\n <option [ngValue]=\"f\">{{ f.label }}</option>\n }\n }\n @for (g of list().filters.groups | async; track g) {\n <optgroup [label]=\"g.label\">\n @for (f of g.filters; track f) {\n @if (!f.enabled && f.allowed) {\n <option [ngValue]=\"f\">{{ f.label }}</option>\n }\n }\n </optgroup>\n }\n </select>\n}\n","let _sequence = 0;\n\n/**\n * Returns a document-unique DOM id, as `<prefix>-<n>`.\n *\n * Used to wire a `<label [attr.for]>` to the control its template owns: the\n * widgets in this library are instantiated repeatedly on the same page, so a\n * hard-coded id would collide and silently break the association.\n *\n * The counter is module-level and starts at zero in each JS context, so a\n * server-rendered page and its client hydration agree as long as components are\n * created in the same order — which is what Angular does.\n *\n * @param prefix identifies the widget, e.g. `data-filter`\n */\nexport function uniqueId(prefix: string): string {\n _sequence += 1;\n return `${prefix}-${_sequence}`;\n}\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime } from 'rxjs';\nimport { ModelListTextFilter } from './model-list-text-filter';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\n\n@Component({\n selector: 'data-model-list-text-filter',\n templateUrl: './model-list-text-filter.component.html',\n styleUrls: ['./model-list-text-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListTextFilter}: a text input that pushes what the\n * user types into the filter, debounced by 250 ms so that a burst of keystrokes\n * triggers a single query. Instantiated by {@link ModelListFiltersComponent}\n * for filters of type `text`.\n */\nexport class ModelListTextFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the value changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListTextFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the text input. */\n public fc = new FormControl<string | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the input to the filter both ways: external value changes are\n * reflected back into the control without re-emitting, and the user's input\n * is debounced before updating the filter and refreshing the list.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n this.fc.setValue((val as IDispEditChoice).value as string | null, {\n emitEvent: false,\n });\n });\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (this.filter().set(val, val || '')) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input [attr.id]=\"inputId\" class=\"form-control\" type=\"text\" [formControl]=\"fc\" [placeholder]=\"filter().help\" />\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { fieldValues } from '../../../../data/field-values';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListAutocompleteFilter } from './model-list-autocomplete-filter';\nimport { TplFun } from '../../../../dispedit/fkselect/fkselect.component';\nimport { DataModel } from '../../../../data/data-model';\nimport { debounceTime, distinctUntilChanged, Observable } from 'rxjs';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\nimport { switchMap } from 'rxjs/operators';\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FilterData } from '../../../../data/data-query';\n\n@Component({\n selector: 'data-model-list-autocomplete-filter',\n templateUrl: './model-list-autocomplete-filter.component.html',\n styleUrls: ['./model-list-autocomplete-filter.component.sass'],\n imports: [NgbTypeaheadModule, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListAutocompleteFilter}: a typeahead input querying\n * the filter's collection as the user types. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `autocomplete`, and\n * subclassed by {@link ModelListAutocompleteMultiFilterComponent}.\n */\nexport class ModelListAutocompleteFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListAutocompleteFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the typeahead input; its value is the selected model, not a string. */\n public fc = new FormControl<T | null>(null);\n /** Bound search function handed to ngb-typeahead. */\n public search = this._search.bind(this);\n /** Bound formatter handed to ngb-typeahead for both the input and the results. */\n public display = this._display.bind(this);\n /**\n * Whether to clear the input after a selection. `false` here, since a single\n * selection should stay visible; the multi subclass overrides it to `true`.\n */\n protected _resetAfterSet = false;\n private _tpl!: TplFun<T>;\n private destroy$ = inject(DestroyRef);\n\n /**\n * Resolves how candidates are labelled, then stores each selected model's\n * `id` in the filter and refreshes the list.\n */\n public ngOnInit(): void {\n this._setDisplay();\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (val) {\n if (this.filter().set(val.id, this._display(val))) {\n this.list().filters.update();\n if (this._resetAfterSet) {\n this.fc.setValue(null);\n }\n }\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n\n /**\n * Keeps the highlighted result visible while arrowing through the dropdown.\n * Bound to the input's arrow-key events, and a no-op when the filter's\n * `scroll` option is off.\n */\n public scrollAction($event: Event) {\n if (!this.filter().scroll) {\n return;\n }\n const elem = ($event.currentTarget as HTMLElement).nextElementSibling?.getElementsByClassName('active')[0];\n elem?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n\n /**\n * Builds the labelling function from the filter's `display` option: a field\n * name becomes a property lookup, a function is used as-is. Without the\n * option, it falls back to the model's `_display`, then to `name`, `title`\n * and `id`.\n */\n private _setDisplay() {\n const display = this.filter().display;\n if (display) {\n if (typeof display === 'string') {\n this._tpl = (model: T) => String(fieldValues(model)[display]);\n } else if (typeof display === 'function') {\n this._tpl = display.bind(this);\n }\n } else {\n this._tpl = (model: T) => {\n const display = (model as { _display?: string })._display;\n if (display) {\n return display;\n } else {\n return String(fieldValues(model)['name'] ?? fieldValues(model)['title'] ?? fieldValues(model)['id']);\n }\n };\n }\n }\n\n /**\n * Labels one candidate for the dropdown, returning `''` for a null model so\n * that an empty input does not render `undefined`.\n */\n private _display(x: T | null | undefined): string {\n if (x) {\n return this._tpl(x);\n }\n return '';\n }\n\n /**\n * Queries the filter's queryset for candidates matching the typed text,\n * merging in the filter's static `filter` parameters and sending the term\n * under its `searchparam`. Debounced by 750 ms and deduplicated, to keep the\n * lookup endpoint from being hit on every keystroke.\n */\n private _search(text$: Observable<string>): Observable<T[]> {\n return text$.pipe(\n debounceTime(750),\n distinctUntilChanged(),\n switchMap((term) => {\n const f: FilterData = {};\n // Generate filter\n for (const k of Object.keys(this.filter().filter)) {\n if (this.filter().filter[k] !== null || this.filter().filter[k] !== undefined) {\n f[k] = this.filter().filter[k];\n }\n }\n // Add search param\n f[this.filter().searchparam] = term;\n // Update queryset filter\n this.filter().queryset?.filter(f);\n // Launch queryset\n return this.filter().queryset.get();\n }),\n takeUntilDestroyed(this.destroy$),\n );\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input\n [attr.id]=\"inputId\"\n class=\"form-control\"\n [formControl]=\"fc\"\n [ngbTypeahead]=\"search\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"display\"\n [resultFormatter]=\"display\"\n [placeholder]=\"filter().help\"\n (keyup.arrowDown)=\"scrollAction($event)\"\n (keyup.arrowUp)=\"scrollAction($event)\"\n #th=\"ngbTypeahead\"\n [class.tascroll]=\"filter().scroll\"\n />\n</div>\n","import { Component } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { ModelListAutocompleteFilterComponent } from '../model-list-autocomplete-filter/model-list-autocomplete-filter.component';\nimport { AsyncPipe } from '@angular/common';\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { FilterValue } from '../../../../data/data-query';\n\n@Component({\n selector: 'data-model-list-autocomplete-multi-filter',\n templateUrl: './model-list-autocomplete-multi-filter.component.html',\n styleUrls: ['./model-list-autocomplete-multi-filter.component.sass'],\n imports: [AsyncPipe, NgbTypeaheadModule, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListAutocompleteMultiFilter}: the same typeahead as\n * {@link ModelListAutocompleteFilterComponent}, extended to keep each pick as a\n * removable chip. Instantiated by {@link ModelListFiltersComponent} for filters\n * of type `autocompletemulti`.\n *\n * It inherits the search, labelling and binding logic wholesale, changing only\n * the reset behaviour and adding chip removal.\n */\nexport class ModelListAutocompleteMultiFilterComponent<\n T extends DataModel,\n> extends ModelListAutocompleteFilterComponent<T> {\n /** `true` here: the input clears after each pick, ready for the next one. */\n protected override _resetAfterSet = true;\n\n /**\n * Removes one selected value and refreshes the list. Bound to each chip's\n * delete icon.\n *\n * @param value The value to remove.\n * @param desc Its description, forwarded to the filter.\n */\n public unset(value: FilterValue, desc: string) {\n this.filter().unset(value, desc);\n this.list().filters.update();\n this.fc.setValue(null);\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input\n [attr.id]=\"inputId\"\n class=\"form-control\"\n [formControl]=\"fc\"\n [ngbTypeahead]=\"search\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"display\"\n [resultFormatter]=\"display\"\n [placeholder]=\"filter().help\"\n (keyup.arrowDown)=\"scrollAction($event)\"\n (keyup.arrowUp)=\"scrollAction($event)\"\n #th=\"ngbTypeahead\"\n [class.tascroll]=\"filter().scroll\"\n />\n <div class=\"enabled mt-1\">\n @for (e of filter().mcurrent$ | async; track e) {\n <div>\n <i\n class=\"bi bi-trash me-2\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer ' + e.desc\"\n (click)=\"unset(e.value, e.desc)\"\n (keydown.enter)=\"unset(e.value, e.desc)\"\n (keydown.space)=\"$event.preventDefault(); unset(e.value, e.desc)\"\n ></i>\n {{ e.desc }}\n </div>\n }\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListDatetimeFilter } from './model-list-datetime-filter';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\nimport { debounceTime } from 'rxjs';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\n@Component({\n selector: 'data-model-list-datetime-filter',\n templateUrl: './model-list-datetime-filter.component.html',\n styleUrls: ['./model-list-datetime-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListDatetimeFilter}: a native `datetime-local` input\n * bound to the filter. Instantiated by {@link ModelListFiltersComponent} for\n * filters of type `datetime`.\n */\nexport class ModelListDatetimeFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the date/time changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListDatetimeFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the date/time input. */\n public fc = new FormControl<string | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the input to the filter both ways, debouncing changes by 250 ms\n * before refreshing the list.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n this.fc.setValue((val as IDispEditChoice).value as string | null, {\n emitEvent: false,\n });\n });\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (this.filter().set(val, val ?? '')) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input\n [attr.id]=\"inputId\"\n class=\"form-control\"\n type=\"datetime-local\"\n [formControl]=\"fc\"\n [placeholder]=\"filter().help\"\n />\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListDatetimerangeFilter } from './model-list-datetimerange-filter';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { combineLatest } from 'rxjs';\n\n@Component({\n selector: 'data-model-list-datetime-range-filter',\n templateUrl: './model-list-datetime-range-filter.component.html',\n styleUrls: ['./model-list-datetime-range-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListDatetimerangeFilter}: two native `datetime-local`\n * inputs delimiting an interval. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `datetimerange`.\n */\nexport class ModelListDatetimeRangeFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when either bound changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListDatetimerangeFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the interval's start input. */\n public fc1 = new FormControl();\n /** Backs the interval's end input. */\n public fc2 = new FormControl();\n private destroy$ = inject(DestroyRef);\n\n /**\n * Joins both bounds with `--` into the filter's single value once they are\n * both filled in, and splits an incoming value back across the two inputs.\n */\n ngOnInit(): void {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n // If value is not an array, return\n if (val && !Array.isArray(val)) {\n const [v1, v2] = String(val.value).split('--');\n this.fc1.setValue(v1, { emitEvent: false });\n this.fc2.setValue(v2, { emitEvent: false });\n }\n });\n\n combineLatest([this.fc1.valueChanges, this.fc2.valueChanges])\n .pipe(takeUntilDestroyed(this.destroy$))\n .subscribe(([val1, val2]) => {\n if (val1 && val2) {\n if (this.filter().set(`${val1}--${val2}`, `${val1}--${val2}`)) {\n this.list().filters.update();\n }\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input\n [attr.id]=\"inputId\"\n class=\"form-control form-control-sm mb-1\"\n type=\"datetime-local\"\n [formControl]=\"fc1\"\n [placeholder]=\"filter().help\"\n />\n <input class=\"form-control form-control-sm\" type=\"datetime-local\" [formControl]=\"fc2\" [placeholder]=\"filter().help\" />\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { GetFlagsResult, ModelListFlagsFilter } from './model-list-flags-filter';\nimport { AsyncPipe } from '@angular/common';\nimport { DataModel } from '../../../../data/data-model';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime, Observable } from 'rxjs';\nimport { FilterValue } from '../../../../data/data-query';\n\n@Component({\n selector: 'data-model-list-flags-filter',\n templateUrl: './model-list-flags-filter.component.html',\n styleUrls: ['./model-list-flags-filter.component.sass'],\n imports: [AsyncPipe, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListFlagsFilter}: a dropdown of the flags fetched from\n * the collection, each pick becoming a removable chip. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `flags`.\n */\nexport class ModelListFlagsFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListFlagsFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the dropdown; reset to `null` after each pick. */\n public fc = new FormControl<string | null>(null);\n /** The available flags and their counts, fetched once on init. */\n public flags$!: Observable<GetFlagsResult>;\n private destroy$ = inject(DestroyRef);\n\n /**\n * Fetches the available flags through the filter's collection action, and\n * adds each picked flag to the filter before clearing the dropdown for the\n * next one.\n */\n public ngOnInit() {\n if (this.filter().collection && this.filter().action) {\n this.flags$ = this.filter().collection.action<GetFlagsResult>(null, 'GET', this.filter().action);\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (val !== null) {\n if (this.filter().set(val, val)) {\n this.list().filters.update();\n this.fc.setValue(null, { emitEvent: false });\n }\n }\n });\n }\n }\n\n /**\n * Removes one selected flag and refreshes the list. Bound to each chip's\n * delete icon.\n *\n * @param value The flag to remove.\n * @param desc Its description, forwarded to the filter.\n */\n public unset(value: FilterValue, desc: string) {\n this.fc.setValue(null);\n this.filter().unset(value, desc);\n this.list().filters.update();\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its values.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <select [attr.id]=\"inputId\" class=\"form-select\" [formControl]=\"fc\">\n <option [ngValue]=\"null\">-- {{ filter().help }} --</option>\n @for (c of flags$ | async; track c) {\n <option [ngValue]=\"c.flag\">{{ c.flag }} ({{ c.count }})</option>\n }\n </select>\n <div class=\"enabled mt-1\">\n @for (e of filter().mcurrent$ | async; track e) {\n <div>\n <i\n class=\"bi bi-trash me-2\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer ' + e.desc\"\n (click)=\"unset(e.value, e.desc)\"\n (keydown.enter)=\"unset(e.value, e.desc)\"\n (keydown.space)=\"$event.preventDefault(); unset(e.value, e.desc)\"\n ></i>\n {{ e.desc }}\n </div>\n }\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { GeoSearchResult, ModelListGeodistanceFilter } from './model-list-geodistance-filter';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { combineLatest, debounceTime, distinctUntilChanged, Observable } from 'rxjs';\nimport { filter, switchMap } from 'rxjs/operators';\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\n\n@Component({\n selector: 'data-model-list-geodistance-filter',\n templateUrl: './model-list-geodistance-filter.component.html',\n styleUrls: ['./model-list-geodistance-filter.component.sass'],\n imports: [NgbTypeaheadModule, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListGeodistanceFilter}: a distance dropdown next to a\n * typeahead that geocodes the typed text. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `geodistance`.\n *\n * The distance ladder (10 to 1000 km) is hardcoded in this component's\n * template, so it is not configurable through the filter.\n */\nexport class ModelListGeodistanceFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the place or distance changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListGeodistanceFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the place typeahead; its value is a {@link GeoSearchResult}. */\n public fc = new FormControl<GeoSearchResult | null>(null);\n /** Backs the distance dropdown; its value pairs an operator and a distance, e.g. `'lte,50'`. */\n public fd = new FormControl('');\n /** Bound search function handed to ngb-typeahead. */\n public search = this._search.bind(this);\n /** Bound formatter handed to ngb-typeahead for both the input and the results. */\n public display = this._display.bind(this);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Waits for both a place and a distance, then combines them into the filter's\n * single `<operator>,<distance>,<lng>,<lat>` value and refreshes the list.\n * Nothing is sent until both are set.\n */\n public ngOnInit(): void {\n const address = this.fc.valueChanges.pipe(\n debounceTime(250),\n filter((val) => !!val),\n );\n const distance = this.fd.valueChanges.pipe(filter((d) => !!d));\n combineLatest([address, distance])\n .pipe(takeUntilDestroyed(this.destroy$))\n .subscribe(([val, dist]) => {\n if (this.filter().set(`${String(dist)},${val.lng},${val.lat}`, val.label)) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n\n /** Labels a place in the dropdown, using the geocoder's own label. */\n private _display(x: GeoSearchResult): string {\n return `${x.label}`;\n }\n\n /**\n * Geocodes the typed text through the filter's `geolocator`. Debounced by\n * 750 ms and deduplicated, to limit calls to the geocoding service.\n */\n private _search(text$: Observable<string>): Observable<GeoSearchResult[]> {\n return text$.pipe(\n debounceTime(750),\n distinctUntilChanged(),\n switchMap((term) => this.filter().geolocator(term)),\n );\n }\n\n /**\n * Keeps the highlighted place visible while arrowing through the dropdown.\n * Bound to the input's arrow-key events, and a no-op when the filter's\n * `scroll` option is off.\n */\n public scrollAction($event: Event) {\n if (!this.filter().scroll) {\n return;\n }\n const elem = ($event.currentTarget as HTMLElement).nextElementSibling?.getElementsByClassName('active')[0];\n elem?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <div class=\"row g-1\">\n <div class=\"col-4\">\n <select [attr.id]=\"inputId\" class=\"form-select\" [formControl]=\"fd\">\n <option value=\"\">Distance</option>\n <option value=\"lte,10\">< 10 km</option>\n <option value=\"lte,20\">< 20 km</option>\n <option value=\"lte,30\">< 30 km</option>\n <option value=\"lte,50\">< 50 km</option>\n <option value=\"lte,80\">< 80 km</option>\n <option value=\"lte,100\">< 100 km</option>\n <option value=\"lte,150\">< 150 km</option>\n <option value=\"lte,200\">< 200 km</option>\n <option value=\"lte,250\">< 250 km</option>\n <option value=\"lte,300\">< 300 km</option>\n <option value=\"lte,500\">< 500 km</option>\n <option value=\"lte,1000\">< 1000 km</option>\n </select>\n </div>\n <div class=\"col-8\">\n <input\n class=\"form-control\"\n [formControl]=\"fc\"\n [ngbTypeahead]=\"search\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"display\"\n [resultFormatter]=\"display\"\n [placeholder]=\"filter().help\"\n (keyup.arrowDown)=\"scrollAction($event)\"\n (keyup.arrowUp)=\"scrollAction($event)\"\n #th=\"ngbTypeahead\"\n [class.tascroll]=\"filter().scroll\"\n />\n </div>\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListSelectFilter } from './model-list-select-filter';\nimport { combineLatest, debounceTime } from 'rxjs';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { DataModel } from '../../../../data/data-model';\nimport { AsyncPipe } from '@angular/common';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\n\n@Component({\n selector: 'data-model-list-select-filter',\n templateUrl: './model-list-select-filter.component.html',\n styleUrls: ['./model-list-select-filter.component.sass'],\n imports: [AsyncPipe, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListSelectFilter}: a dropdown of the filter's choices,\n * with an empty option that clears the filter. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `select`.\n */\nexport class ModelListSelectFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListSelectFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the dropdown; `null` means no selection. */\n public fc = new FormControl<string | number | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the dropdown to the filter both ways. Selections are matched against\n * the filter's choices to recover each value's description, which is why the\n * choices stream is combined in rather than merely rendered.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n this.fc.setValue(val ? ((val as IDispEditChoice).value as string | number | null) : null, { emitEvent: false });\n });\n\n combineLatest([this.filter().choices, this.fc.valueChanges.pipe(debounceTime(250))])\n .pipe(takeUntilDestroyed(this.destroy$))\n .subscribe(([choices, val]) => {\n if (val === null) {\n this.filter().clear();\n this.list().filters.update();\n } else {\n for (const ch of choices) {\n if (ch.value === val) {\n if (this.filter().set(ch.value, ch.desc)) {\n this.list().filters.update();\n break;\n }\n }\n }\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <select [attr.id]=\"inputId\" class=\"form-select\" [formControl]=\"fc\">\n <option [ngValue]=\"null\">-- {{ filter().help }} --</option>\n @for (c of filter().choices | async; track c) {\n <option [ngValue]=\"c.value\">{{ c.desc }}</option>\n }\n </select>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListSelectMultiFilter } from './model-list-select-multi-filter';\nimport { AsyncPipe } from '@angular/common';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { DataModel } from '../../../../data/data-model';\nimport { combineLatest, debounceTime } from 'rxjs';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\nimport { FilterValue } from '../../../../data/data-query';\n\n@Component({\n selector: 'data-model-list-select-multi-filter',\n templateUrl: './model-list-select-multi-filter.component.html',\n styleUrls: ['./model-list-select-multi-filter.component.sass'],\n imports: [AsyncPipe, ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListSelectMultiFilter}: a dropdown that adds each pick\n * to a list of removable chips. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `selectmulti`.\n */\nexport class ModelListSelectMultiFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListSelectMultiFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the dropdown; reset to `null` after each pick so the same option can be re-picked. */\n public fc = new FormControl<IDispEditChoice | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Adds each picked choice to the filter, then clears the dropdown so it is\n * ready for the next selection. The choices stream is combined in to recover\n * the picked value's description for its chip.\n */\n public ngOnInit() {\n combineLatest([this.filter().choices, this.fc.valueChanges.pipe(debounceTime(250))])\n .pipe(takeUntilDestroyed(this.destroy$))\n .subscribe(([choices, val]) => {\n for (const ch of choices) {\n if (ch.value === val) {\n if (this.filter().set(ch.value, ch.desc)) {\n this.list().filters.update();\n break;\n }\n }\n }\n this.fc.setValue(null, { emitEvent: false });\n });\n }\n\n /**\n * Removes one selected value and refreshes the list. Bound to each chip's\n * delete icon.\n *\n * @param value The value to remove.\n * @param desc Its description, forwarded to the filter.\n */\n public unset(value: FilterValue, desc: string) {\n this.fc.setValue(null);\n this.filter().unset(value, desc);\n this.list().filters.update();\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its values.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <select [attr.id]=\"inputId\" class=\"form-select\" [formControl]=\"fc\">\n <option [ngValue]=\"null\">-- {{ filter().help }} --</option>\n @for (c of filter().choices | async; track c) {\n <option [ngValue]=\"c.value\">{{ c.desc }}</option>\n }\n </select>\n <div class=\"enabled mt-1\">\n @for (e of filter().mcurrent$ | async; track e) {\n <div>\n <i\n class=\"bi bi-trash me-2\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer ' + e.desc\"\n (click)=\"unset(e.value, e.desc)\"\n (keydown.enter)=\"unset(e.value, e.desc)\"\n (keydown.space)=\"$event.preventDefault(); unset(e.value, e.desc)\"\n ></i>\n {{ e.desc }}\n </div>\n }\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListTreeFilter } from './model-list-tree-filter';\nimport { DataModel } from '../../../../data/data-model';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime, firstValueFrom, Subject, Subscription } from 'rxjs';\nimport { FilterData, Queryset } from '../../../../data/data-query';\nimport { fieldValues } from '../../../../data/field-values';\nimport { TplFun } from '../../../../dispedit/fkselect/fkselect.component';\n\n/**\n * One dropdown in the tree filter's chain: the choices available at a given\n * depth, plus the node selected there. Internal to this component.\n */\nclass Level<T extends DataModel> {\n /** Zero-based depth, `0` being the roots. */\n public level: number;\n /** The tree this level belongs to, notified when the selection changes. */\n public tree: Tree<T>;\n /** The nodes offered at this depth, all children of the level above's selection. */\n public choices: { value: number; desc: string }[];\n /** Backs this level's dropdown. */\n public fc: FormControl;\n /** Id of the node selected here, if any. */\n public selected?: number;\n /** Subscription to the dropdown, torn down by {@link close}. */\n public subs: Subscription;\n\n constructor(tree: Tree<T>, level: number, choices: { value: number; desc: string }[]) {\n this.tree = tree;\n this.level = level;\n this.fc = new FormControl<string | null>('');\n this.choices = choices;\n this.subs = this.fc.valueChanges.subscribe((val) => {\n const selected = val ? Number(val) : undefined;\n if (this.selected !== selected) {\n this.selected = selected as number;\n this.tree.updated(this);\n }\n });\n }\n\n /** Unsubscribes from the dropdown; called when this level is discarded. */\n public close() {\n this.subs.unsubscribe();\n }\n}\n\n/**\n * The chain of dropdowns backing the tree filter: it fetches each level from\n * the server, drops the levels below whenever a selection changes, and reports\n * the current node. Internal to this component.\n */\nclass Tree<T extends DataModel> {\n /**\n * The levels currently displayed, from root to deepest.\n *\n * A signal because levels are appended asynchronously (after the queryset\n * resolves); under OnPush a plain array would leave the dropdowns unrendered.\n */\n readonly levels = signal<Level<T>[]>([]);\n /** Emits the selected node's id, or `null` once the selection is cleared. */\n changed: Subject<number | null> = new Subject<number | null>();\n\n /**\n * @param qs The queryset the nodes are fetched from.\n * @param maxLevel Depth cap, also bounding the walk back up to the root.\n * @param display Labels a node for its dropdown entry.\n * @param filter Extra query parameters merged into every level request.\n */\n constructor(\n private qs: Queryset<T>,\n private maxLevel: number,\n private display: string | TplFun<T> | undefined,\n private filter: FilterData,\n ) {}\n\n /**\n * Fetches the next level's nodes and appends it, if there is anything to\n * show. The first level asks for the roots (`parent=null`); deeper ones ask\n * for the children of the level above's selection, and are skipped when\n * nothing is selected there.\n *\n * @param fparent Overrides which parent's children to fetch, instead of using\n * the last level's selection.\n * @returns The new level, or `null` when the query came back empty — which is\n * how the chain stops at a leaf.\n */\n public async addLevel(fparent?: number): Promise<Level<T> | null> {\n let values: T[] = [];\n const levels = this.levels();\n if (levels.length === 0) {\n values = await firstValueFrom(this.qs.filter({ level: levels.length, parent: 'null', ...this.filter }).get());\n } else {\n const parent = fparent ? fparent : levels[levels.length - 1].selected;\n if (parent) {\n values = await firstValueFrom(\n this.qs\n .filter({\n level: levels.length,\n parent: levels[levels.length - 1].selected || 'null',\n ...this.filter,\n })\n .get(),\n );\n }\n }\n if (values.length > 0) {\n const level = new Level(this, levels.length, []);\n for (const v of values) {\n level.choices.push({ value: v.id, desc: this._label(v) });\n }\n this.levels.update((ls) => [...ls, level]);\n return level;\n }\n return null;\n }\n\n /**\n * Reacts to a selection at `level`: discards every deeper level, since they\n * described the previous branch, then appends the new level below and reports\n * the current node. Clearing a dropdown falls back to reporting the level\n * above's selection.\n */\n public updated(level: Level<T>) {\n const newLevels: Level<T>[] = [];\n for (const l of this.levels()) {\n if (l.level <= level.level) {\n newLevels.push(l);\n } else if (l.level > level.level) {\n l.close();\n }\n }\n this.levels.set(newLevels);\n void this.addLevel();\n if (level.selected) {\n this.changed.next(level.selected);\n } else {\n this.changed.next(this.levels()[level.level - 1]?.selected || null);\n }\n }\n\n /**\n * Rebuilds the whole chain of dropdowns around an already-selected node, so\n * that a filter restored from a saved state shows its full path rather than\n * an empty root dropdown.\n *\n * It walks from `value` up to the root by following each fetched record's\n * `parent` property, then replays the path downwards, preselecting each\n * level. Because it reads `parent` off the payload, the filter's `filter`\n * option must not trim that field away.\n *\n * @param value Id of the node to select.\n * @throws `Error('Max level error, could not find root')` when the walk\n * exceeds `maxLevel` without reaching a root, which signals either a cycle\n * or a `maxLevel` set too low.\n */\n /** Labels one node: `[display]` as a field name, as a function, or `id`. */\n private _label(node: T): string {\n if (typeof this.display === 'function') {\n return this.display(node);\n }\n if (typeof this.display === 'string') {\n return String(fieldValues(node)[this.display]);\n }\n return String(node.id);\n }\n\n public async prepare(value: number) {\n // console.log('prepare', value);\n const levels: T[] = [];\n let cur = (await firstValueFrom(this.qs.filter({ id: value, ...this.filter }).get()))[0];\n levels.push(cur);\n let nlev = 0;\n while (fieldValues(cur)['parent'] !== null) {\n cur = (\n await firstValueFrom(\n this.qs\n .filter({\n id: fieldValues(cur)['parent'] as number,\n ...this.filter,\n })\n .get(),\n )\n )[0];\n levels.push(cur);\n nlev++;\n if (nlev > this.maxLevel) {\n throw Error('Max level error, could not find root');\n }\n }\n for (let i = levels.length - 1; i >= 0; i--) {\n const lv = await this.addLevel();\n if (lv !== null) {\n lv.selected = levels[i].id;\n lv.fc.setValue(levels[i].id, { emitEvent: false });\n }\n }\n if (this.levels().length <= this.maxLevel) {\n await this.addLevel();\n }\n }\n\n /** Empty stub; does nothing. */\n public reset() {\n // Nothing to reset: the tree rebuilds itself from the filter value.\n }\n}\n\n@Component({\n selector: 'data-model-list-tree-filter',\n templateUrl: './model-list-tree-filter.component.html',\n styleUrls: ['./model-list-tree-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListTreeFilter}: a chain of dropdowns, one per level\n * of the hierarchy, each narrowing the one below. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `tree`.\n */\nexport class ModelListTreeFilterComponent<T extends DataModel> implements OnInit {\n /** The list to refresh when the selection changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListTreeFilter<T>>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** The dropdown chain rendered by the template; built on init. */\n public tree!: Tree<T>;\n private destroy$ = inject(DestroyRef);\n\n /**\n * Builds the dropdown chain, restoring the full path when the filter already\n * holds a value and otherwise starting at the roots, then pushes each\n * selection into the filter. Selections are debounced by 250 ms, since\n * changing one level cascades through the levels below it.\n */\n public async ngOnInit() {\n const filter = this.filter();\n this.tree = new Tree(filter.queryset, filter.maxLevel, filter.display, filter.filter);\n if (filter.get()) {\n await this.tree.prepare(filter.get()?.value as number);\n } else {\n await this.tree.addLevel();\n }\n\n this.tree.changed.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (val === null) {\n filter.clear();\n this.list().filters.update();\n } else {\n if (filter.set(val, '')) {\n this.list().filters.update();\n }\n }\n });\n\n // this.tree.changed.subscribe((selected) => {\n // console.log('tree changed', selected);\n // this.filter.set(selected, '');\n // });\n // if (this.filter.getValue()) {\n // console.log('filter value', this.filter.getValue());\n // await this.tree.prepare(this.filter.getValue() as number);\n // } else {\n // await this.tree.addLevel();\n // }\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n @for (l of tree.levels(); track l) {\n <div class=\"levelselect\">\n <select [attr.id]=\"$first ? inputId : null\" class=\"form-select form-select-sm\" [formControl]=\"l.fc\">\n <option value=\"\">{{ filter().help }}</option>\n @for (ch of l.choices; track ch) {\n <option [value]=\"ch.value\">{{ ch.desc }}</option>\n }\n </select>\n </div>\n }\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\nimport { debounceTime } from 'rxjs';\nimport { ModelListNumberFilter } from './model-list-number-filter';\nimport { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\n\n@Component({\n selector: 'data-model-list-number-filter',\n templateUrl: './model-list-number-filter.component.html',\n styleUrls: ['./model-list-number-filter.component.sass'],\n imports: [ReactiveFormsModule, NgbDropdownModule],\n})\n/**\n * Widget for {@link ModelListNumberFilter}: a number input alongside a dropdown\n * choosing the comparison operator. Instantiated by\n * {@link ModelListFiltersComponent} for filters of type `number`.\n */\nexport class ModelListNumberFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the value or operator changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListNumberFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the number input. */\n public fc = new FormControl<number | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the input to the filter both ways, debouncing the user's input by\n * 250 ms before updating the filter and refreshing the list.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n const value = (val as IDispEditChoice).value;\n this.fc.setValue(value === null ? null : Number(value), {\n emitEvent: false,\n });\n });\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (this.filter().set(val, val === null ? '' : String(val))) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n\n /**\n * Applies the comparison picked from the dropdown and re-runs the query,\n * since changing the operator changes the query parameter's name.\n *\n * @param eq The operator's suffix (`''`, `'_lt'`, ...), not its name.\n */\n selectOp(eq: string) {\n this.filter().setOperator(eq);\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <div class=\"bi bi-trash\"></div>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <div class=\"input-group\" ngbDropdown>\n <button class=\"btn btn-outline-secondary\" type=\"button\" ngbDropdownToggle>\n <span class=\"me-2\">{{ filter().operator.label }}</span>\n <div class=\"dropdown-menu\" ngbDropdownMenu>\n @for (op of filter().operations; track op) {\n <button\n ngbDropdownItem\n (click)=\"selectOp(op.operator)\"\n [class.text-primary]=\"op.operator === filter().operator.operator\"\n >\n {{ op.label }}\n </button>\n }\n </div>\n </button>\n <input [attr.id]=\"inputId\" class=\"form-control\" type=\"number\" [formControl]=\"fc\" [placeholder]=\"filter().help\" />\n </div>\n</div>\n","import { Component, DestroyRef, inject, input, OnInit } from '@angular/core';\nimport { DataModel } from '../../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { uniqueId } from '../../../../utils/unique-id';\nimport { ModelList } from '../../../model-list.service';\nimport { ModelListDateFilter } from './model-list-date-filter';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\nimport { debounceTime } from 'rxjs';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\n@Component({\n selector: 'data-model-list-date-filter',\n templateUrl: './model-list-date-filter.component.html',\n styleUrls: ['./model-list-date-filter.component.sass'],\n imports: [ReactiveFormsModule],\n})\n/**\n * Widget for {@link ModelListDateFilter}: a native date input bound to the\n * filter. Instantiated by {@link ModelListFiltersComponent} for filters of type\n * `date`.\n */\nexport class ModelListDateFilterComponent<T extends DataModel = DataModel> implements OnInit {\n /** The list to refresh when the date changes. Required. */\n public list = input.required<ModelList<T>>();\n /** The filter this widget edits. Required. */\n public filter = input.required<ModelListDateFilter>();\n /** CSS classes for the widget's container, overridden by the filter's `displayClasses`. */\n public classes = input<string[] | string>('');\n /** Id shared by the label and its control, so clicking the label focuses it. */\n public readonly inputId = uniqueId('data-filter');\n /** Backs the date input. */\n public fc = new FormControl<string | null>(null);\n private destroy$ = inject(DestroyRef);\n\n /**\n * Binds the input to the filter both ways, debouncing changes by 250 ms\n * before refreshing the list.\n */\n public ngOnInit() {\n this.filter()\n .valueChanges.pipe(takeUntilDestroyed(this.destroy$))\n .subscribe((val) => {\n this.fc.setValue((val as IDispEditChoice).value as string | null, {\n emitEvent: false,\n });\n });\n this.fc.valueChanges.pipe(debounceTime(250), takeUntilDestroyed(this.destroy$)).subscribe((val) => {\n if (this.filter().set(val, val ?? '')) {\n this.list().filters.update();\n }\n });\n }\n\n /**\n * Turns the filter off and refreshes the list, removing this widget from the\n * screen. Bound to the widget's trash icon. The filter keeps its value.\n */\n public disable() {\n this.filter().enabled = false;\n this.list().filters.update();\n }\n}\n","<div class=\"filteritem\" [class]=\"filter().displayClasses || classes()\">\n <div\n class=\"trash float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Désactiver le filtre ' + filter().label\"\n (click)=\"disable()\"\n (keydown.enter)=\"disable()\"\n (keydown.space)=\"$event.preventDefault(); disable()\"\n >\n <i class=\"bi bi-trash\"></i>\n </div>\n <label [attr.for]=\"inputId\">{{ filter().label }}</label>\n <input [attr.id]=\"inputId\" class=\"form-control\" type=\"date\" [formControl]=\"fc\" [placeholder]=\"filter().help\" />\n</div>\n","import { Component, input } from '@angular/core';\nimport { DataModel } from '../../../data/data-model';\nimport { ModelList } from '../../model-list.service';\nimport { AsyncPipe } from '@angular/common';\nimport { ModelListTextFilterComponent } from '../filters/model-list-text-filter/model-list-text-filter.component';\nimport { ModelListAutocompleteFilterComponent } from '../filters/model-list-autocomplete-filter/model-list-autocomplete-filter.component';\nimport { ModelListAutocompleteMultiFilterComponent } from '../filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.component';\nimport { ModelListDatetimeFilterComponent } from '../filters/model-list-datetime-filter/model-list-datetime-filter.component';\nimport { ModelListDatetimeRangeFilterComponent } from '../filters/model-list-datetimerange-filter/model-list-datetime-range-filter.component';\nimport { ModelListFlagsFilterComponent } from '../filters/model-list-flags-filter/model-list-flags-filter.component';\nimport { ModelListGeodistanceFilterComponent } from '../filters/model-list-geodistance-filter/model-list-geodistance-filter.component';\nimport { ModelListSelectFilterComponent } from '../filters/model-list-select-filter/model-list-select-filter.component';\nimport { ModelListSelectMultiFilterComponent } from '../filters/model-list-select-multi-filter/model-list-select-multi-filter.component';\nimport { ModelListTreeFilterComponent } from '../filters/model-list-tree-filter/model-list-tree-filter.component';\nimport { ModelListNumberFilterComponent } from '../filters/model-list-number-filter/model-list-number-filter.component';\nimport { ModelListDateFilterComponent } from '../filters/model-list-date-filter/model-list-date-filter.component';\n\n// SEE: register filter components and load them dynamically to allow user defined filters\n\n/**\n * Renders the widgets of a list's currently enabled filters.\n *\n * It subscribes to the list's enabled filters and, for each one, switches on\n * {@link ModelListFilter.type} to instantiate the matching filter component —\n * which is why every filter component is imported here. Pair it with\n * {@link ModelListFiltersSelectComponent}, which is how users turn filters on\n * and off; on its own this component only shows what is already enabled.\n *\n * @example\n * ```html\n * <data-model-list-filters [list]=\"list\" itemClasses=\"col-4\" />\n * ```\n */\n@Component({\n selector: 'data-model-list-filters',\n templateUrl: './model-list-filters.component.html',\n styleUrls: ['./model-list-filters.component.sass'],\n imports: [\n AsyncPipe,\n ModelListTextFilterComponent,\n ModelListNumberFilterComponent,\n ModelListAutocompleteFilterComponent,\n ModelListAutocompleteMultiFilterComponent,\n ModelListDatetimeFilterComponent,\n ModelListDateFilterComponent,\n ModelListDatetimeRangeFilterComponent,\n ModelListFlagsFilterComponent,\n ModelListGeodistanceFilterComponent,\n ModelListSelectFilterComponent,\n ModelListSelectMultiFilterComponent,\n ModelListTreeFilterComponent,\n ],\n})\nexport class ModelListFiltersComponent<T extends DataModel = DataModel> {\n /** The list whose filters are displayed. Required. */\n public list = input.required<ModelList<T>>();\n /** CSS classes for the element wrapping all the filter widgets. */\n public containerClasses = input<string[] | string>('');\n /**\n * CSS classes applied to each filter widget, typically grid columns. A filter\n * declaring `displayClasses` overrides this for itself.\n */\n public itemClasses = input<string[] | string>('');\n}\n","<div [class]=\"containerClasses()\">\n @for (f of list().filters.enabled | async; track f) {\n @switch (f.type) {\n @case (\"autocomplete\") {\n <data-model-list-autocomplete-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-autocomplete-filter>\n }\n @case (\"autocompletemulti\") {\n <data-model-list-autocomplete-multi-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-autocomplete-multi-filter>\n }\n @case (\"datetime\") {\n <data-model-list-datetime-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-datetime-filter>\n }\n @case (\"date\") {\n <data-model-list-date-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-date-filter>\n }\n @case (\"datetimerange\") {\n <data-model-list-datetime-range-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-datetime-range-filter>\n }\n @case (\"flags\") {\n <data-model-list-flags-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-flags-filter>\n }\n @case (\"geodistance\") {\n <data-model-list-geodistance-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-geodistance-filter>\n }\n @case (\"number\") {\n <data-model-list-number-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-number-filter>\n }\n @case (\"select\") {\n <data-model-list-select-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-select-filter>\n }\n @case (\"selectmulti\") {\n <data-model-list-select-multi-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-select-multi-filter>\n }\n @case (\"text\") {\n <data-model-list-text-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-text-filter>\n }\n @case (\"tree\") {\n <data-model-list-tree-filter\n [filter]=\"$any(f)\"\n [list]=\"list()\"\n [class]=\"itemClasses()\"\n ></data-model-list-tree-filter>\n }\n }\n }\n</div>\n","import { ModelListFilter } from './model-list-filter';\n\n/**\n * A named, presentation-only grouping of filters.\n *\n * A group exists purely to organise the UI: it gives a set of related filters a\n * shared heading and a position in the filter picker. It carries no filtering\n * logic of its own and never appears in a query.\n *\n * Groups are declared in the very same `filters` array as ungrouped filters —\n * the array is typed `(ModelListFilter | ModelListFilterGroup)[]` — and\n * {@link ModelListFilters} flattens them at construction, tagging each child\n * filter with its {@link ModelListFilter.group}. Because of that flattening,\n * the `allowed`, `defaults` and `excluded` lists always name **leaf filter\n * names**; naming a group there has no effect.\n *\n * {@link ModelListFilters.update} recomputes {@link allowed} and\n * {@link enabled} on every group from its children, so any value you pass for\n * those two is transient.\n *\n * @example\n * ```typescript\n * const filters = new ModelListFilters({\n * filters: [\n * new ModelListTextFilter({ name: 'search', field: 'search', label: 'Search', help: 'Text to look for' }),\n * new ModelListFilterGroup({\n * name: 'dates',\n * label: 'Dates',\n * position: 1,\n * filters: [\n * new ModelListDateFilter({ name: 'created', field: 'created', label: 'Created on', help: 'Creation date' }),\n * ],\n * }),\n * ],\n * // Leaf filter names, never 'dates'\n * defaults: ['search', 'created'],\n * });\n * ```\n */\nexport class ModelListFilterGroup {\n /** Group identity. Not usable in `allowed`/`defaults`/`excluded`, which take leaf filter names. */\n public name = '';\n /** Heading shown above the group in the filter picker. */\n public label = '';\n /** Longer description of the group's purpose. */\n public desc = '';\n /** Sort key: groups are displayed in ascending `position` order. */\n public position = 0;\n /**\n * Whether any child filter is allowed. Recomputed from the children by\n * {@link ModelListFilters.update}; only allowed groups are displayed.\n */\n public allowed = true;\n /**\n * Whether the group still has something to offer, i.e. at least one child\n * that is allowed but not yet enabled. Recomputed by\n * {@link ModelListFilters.update}; only such groups are displayed.\n */\n public enabled = true;\n /** The filters belonging to this group. */\n public filters: ModelListFilter[] = [];\n\n /**\n * Builds a group from a partial description; every field has a default.\n *\n * Note that `allowed: false` and `enabled: false` cannot be set through this\n * constructor — both options are read with `||`, so a `false` value falls\n * through to `true`. In practice this is harmless, since\n * {@link ModelListFilters.update} overwrites both from the group's children\n * before they are ever read.\n */\n constructor(params: Partial<ModelListFilterGroup>) {\n this.name = params.name || '';\n this.label = params.label || '';\n this.desc = params.desc || '';\n this.position = params.position || 0;\n this.allowed = params.allowed || true;\n this.enabled = params.enabled || true;\n this.filters = params.filters || [];\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { DataModel } from '../../../../data/data-model';\nimport { Collection } from '../../../../data/data-collection';\nimport { FilterData, Queryset } from '../../../../data/data-query';\nimport { TplFun } from '../../../../dispedit/fkselect/fkselect.component';\n\nexport interface ModelListAutocompleteParams<T extends DataModel> extends ModelListFilterParams {\n /**\n * The collection to look candidates up in. A queryset is derived from it, so\n * pass this unless you need a preconfigured {@link queryset}.\n */\n collection?: Collection<T>;\n /**\n * A ready-made queryset to search, used instead of deriving one from\n * {@link collection}. Takes precedence when both are given.\n */\n queryset?: Queryset<T>;\n /**\n * The query parameter carrying the user's search text to the lookup endpoint.\n * Defaults to `'search'`; override it when the endpoint expects another name.\n */\n searchparam?: string;\n /**\n * How to label a candidate: a model field name, or a function returning the\n * text. When omitted the filter falls back to the model's `_display`, then\n * `name`, `title` and `id`.\n */\n display?: string | TplFun<T>;\n /**\n * Extra query parameters merged into every lookup request, on top of the\n * search term. Beyond narrowing which records are proposed, this is the place\n * to trim the response: `filter: { fields: ['id', 'name'].join(',') }` asks\n * the server for just the columns the dropdown needs, which matters because\n * this endpoint is hit on every keystroke.\n */\n filter?: FilterData;\n /**\n * Whether arrow keys scroll the highlighted result into view. Defaults to\n * `true`; set `false` if the dropdown is short enough not to need it.\n */\n scroll?: boolean;\n}\n\n/**\n * Autocomplete filter: a typeahead input that searches a collection as the user\n * types (debounced) and sends the picked record's `id` under the filter's\n * `field`. The filter of choice for a foreign key onto a set too large for a\n * dropdown.\n *\n * The records to search come from either `collection` or `queryset`, and\n * passing neither throws. Use `filter` to both narrow the lookup and trim the\n * payload, and `display` to control how candidates are labelled.\n *\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par texte'` / `'Recherche par texte'`.\n *\n * @throws `'Missing related data (collection or queryset)'` (a string, not an\n * `Error`) when neither `collection` nor `queryset` is given.\n *\n * @example\n * ```typescript\n * new ModelListAutocompleteFilter<Category>({\n * name: 'category',\n * field: 'category',\n * label: 'Category',\n * help: 'Search for a category',\n * collection: categories,\n * display: 'name',\n * // Only fetch what the dropdown displays\n * filter: { fields: ['id', 'name'].join(',') },\n * });\n * ```\n */\nexport class ModelListAutocompleteFilter<T extends DataModel>\n extends ModelListFilter\n implements ModelListAutocompleteParams<T>\n{\n /** Field name or function labelling each candidate in the dropdown. */\n public display?: string | TplFun<T>;\n /** Query parameter carrying the search text; `'search'` unless overridden. */\n public searchparam!: string;\n /** The queryset searched on each keystroke, derived from `collection` if needed. */\n public queryset!: Queryset<T>;\n /** The collection the candidates come from, when one was given. */\n public collection?: Collection<T>;\n /** Extra query parameters merged into every lookup; `{}` when unset. */\n public filter!: FilterData;\n /** Whether arrow keys scroll the active result into view. */\n public scroll!: boolean;\n\n /**\n * Sets the filter type to `autocomplete` and resolves the queryset to search,\n * preferring an explicit `queryset` over one derived from `collection`.\n */\n constructor(params: ModelListAutocompleteParams<T>) {\n super(params);\n this.type = 'autocomplete';\n this.display = params.display;\n this.searchparam = params.searchparam ? params.searchparam : 'search';\n if (!params.collection && !params.queryset) {\n throw new Error('Missing related data (collection or queryset)');\n }\n this.collection = params.collection;\n if (params.collection && !params.queryset) {\n this.queryset = params.collection.queryset();\n } else {\n this.queryset = params.queryset as Queryset<T>;\n }\n this.scroll = params.scroll !== undefined ? params.scroll : true;\n this.filter = params.filter || {};\n\n if (this.label == '') {\n this.label = 'Sélectionnez par texte';\n }\n if (this.help == '') {\n this.help = 'Recherche par texte';\n }\n }\n}\n","import {\n ModelListAutocompleteFilter,\n ModelListAutocompleteParams,\n} from '../model-list-autocomplete-filter/model-list-autocomplete-filter';\nimport { DataModel } from '../../../../data/data-model';\n\n/**\n * Options for {@link ModelListAutocompleteMultiFilter}; identical to\n * {@link ModelListAutocompleteParams}, declared separately so the multi variant\n * can grow its own later.\n */\n// Kept as its own name so the multi variant can grow options later without a\n// breaking rename.\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ModelListAutocompleteMultiParams<T extends DataModel> extends ModelListAutocompleteParams<T> {}\n\n/**\n * Multi-valued autocomplete filter: same typeahead as\n * {@link ModelListAutocompleteFilter}, except each pick is kept as a removable\n * chip and the input resets for the next one. All picked ids are sent joined by\n * `,` in a single query parameter.\n *\n * Takes the same options and the same throw contract as its parent, including\n * the `filter: { fields: ... }` idiom worth applying here too.\n *\n * Always pass `label` and `help`: left empty they inherit the parent's French\n * `'Sélectionnez par texte'` / `'Recherche par texte'`.\n *\n * @throws `'Missing related data (collection or queryset)'` (a string, not an\n * `Error`) when neither `collection` nor `queryset` is given.\n *\n * @example\n * ```typescript\n * new ModelListAutocompleteMultiFilter<Category>({\n * name: 'categories',\n * field: 'categories',\n * label: 'Categories',\n * help: 'Search for categories',\n * collection: categories,\n * display: 'name',\n * filter: { fields: ['id', 'name'].join(',') },\n * });\n * ```\n */\nexport class ModelListAutocompleteMultiFilter<T extends DataModel> extends ModelListAutocompleteFilter<T> {\n /** Always `true`: this filter joins its values into one query parameter. */\n public override multi = true;\n\n /** Switches the filter type to `autocompletemulti`. */\n constructor(params: ModelListAutocompleteMultiParams<T>) {\n super(params);\n this.type = 'autocompletemulti';\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\n\n/**\n * Date and time filter: a single native `datetime-local` input whose value is\n * sent verbatim under the filter's `field`. Identical to\n * {@link ModelListDateFilter} but resolving to the minute.\n *\n * Takes no options beyond {@link ModelListFilterParams}, and ignores `default`.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par date/heure'` / `'Date/heure cible'`.\n *\n * @example\n * ```typescript\n * new ModelListDatetimeFilter({\n * name: 'created',\n * field: 'created',\n * label: 'Created at',\n * help: 'Creation date and time',\n * });\n * ```\n */\nexport class ModelListDatetimeFilter extends ModelListFilter {\n /** Sets the filter type to `datetime`. */\n constructor(params: ModelListFilterParams) {\n super(params);\n this.type = 'datetime';\n if (this.label == '') {\n this.label = 'Sélectionnez par date/heure';\n }\n if (this.help == '') {\n this.help = 'Date/heure cible';\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\n\n/**\n * Date filter: a single native date input whose value is sent verbatim under\n * the filter's `field`, in the browser's `yyyy-mm-dd` format. Matches on one\n * date; use {@link ModelListDatetimerangeFilter} for an interval.\n *\n * Takes no options beyond {@link ModelListFilterParams}, and ignores `default`.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par date'` / `'Date cible'`.\n *\n * @example\n * ```typescript\n * new ModelListDateFilter({\n * name: 'created',\n * field: 'created',\n * label: 'Created on',\n * help: 'Creation date',\n * });\n * ```\n */\nexport class ModelListDateFilter extends ModelListFilter {\n /** Sets the filter type to `date`. */\n constructor(params: ModelListFilterParams) {\n super(params);\n this.type = 'date';\n if (this.label == '') {\n this.label = 'Sélectionnez par date';\n }\n if (this.help == '') {\n this.help = 'Date cible';\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\n\n/**\n * Date/time interval filter: two native `datetime-local` inputs, sent as a\n * single query parameter holding both bounds joined by `--`, for example\n * `2026-01-01T00:00--2026-01-31T23:59`. The backend must parse that encoding.\n *\n * Nothing is sent until **both** bounds are filled in.\n *\n * Takes no options beyond {@link ModelListFilterParams}, and ignores `default`.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par intervalle de date/heure'` / `'Date/heure'`.\n *\n * @example\n * ```typescript\n * new ModelListDatetimerangeFilter({\n * name: 'created',\n * field: 'created',\n * label: 'Created between',\n * help: 'Start and end date',\n * });\n * ```\n */\nexport class ModelListDatetimerangeFilter extends ModelListFilter {\n /** Sets the filter type to `datetimerange`. */\n constructor(params: ModelListFilterParams) {\n super(params);\n this.type = 'datetimerange';\n if (this.label == '') {\n this.label = 'Sélectionnez par intervalle de date/heure';\n }\n if (this.help == '') {\n this.help = 'Date/heure';\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { Collection } from '../../../../data/data-collection';\nimport { DataModel } from '../../../../data/data-model';\n\nexport interface ModelListFlagsFilterParams<T extends DataModel> extends ModelListFilterParams {\n /**\n * The collection exposing the flags action. By convention this is the list's\n * own collection, so that the flags offered are those of the very records\n * being filtered. Required.\n */\n collection?: Collection<T>;\n /**\n * The collection action returning the available flags. Defaults to\n * `'get_flags'`; override it when the endpoint names it differently.\n */\n action?: string;\n}\n\n/**\n * The shape returned by the flags action: each available flag with how many\n * records carry it. The count is informational and shown next to the flag.\n */\nexport type GetFlagsResult = { flag: string; count: number }[];\n\n/**\n * Flags filter: a dropdown of the flags actually present in the data, picked\n * ones being kept as removable chips. Always multi-valued, so the selected\n * flags are sent joined by `,` in a single query parameter.\n *\n * The flag list is not declared here but fetched at runtime by calling a `GET`\n * action on `collection` — `'get_flags'` unless overridden — which must return\n * a {@link GetFlagsResult}. Pass the list's own collection so the offered flags\n * match the records being filtered.\n *\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez par étiquette'` / `\"Nom de l'étiquette\"`.\n *\n * @throws `'Missing collection for flags filter'` (a string, not an `Error`)\n * when `collection` is not given.\n *\n * @example\n * ```typescript\n * new ModelListFlagsFilter<Thing>({\n * name: 'flags',\n * field: 'flags',\n * label: 'Flags',\n * help: 'Pick one or more flags',\n * // The list's own collection\n * collection: things,\n * });\n * ```\n */\nexport class ModelListFlagsFilter<T extends DataModel> extends ModelListFilter {\n /** The collection whose flags action feeds the dropdown. */\n public collection!: Collection<T>;\n /** Name of the `GET` collection action returning the available flags. */\n public action = 'get_flags';\n /** Always `true`: selected flags are joined into one query parameter. */\n public override multi = true;\n\n /**\n * Sets the filter type to `flags` and stores the collection and action used\n * to fetch the flag list.\n */\n constructor(params: ModelListFlagsFilterParams<T>) {\n super(params);\n this.type = 'flags';\n if (this.label == '') {\n this.label = 'Sélectionnez par étiquette';\n }\n if (this.help == '') {\n this.help = \"Nom de l'étiquette\";\n }\n if (!params.collection) {\n throw new Error('Missing collection for flags filter');\n }\n this.collection = params.collection;\n if (params.action) {\n this.action = params.action;\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { Observable } from 'rxjs';\n\n/**\n * One place proposed by a {@link ModelListGeodistanceFilterParams.geolocator},\n * normalised across geocoding services.\n */\nexport interface GeoSearchResult {\n /** Relevance as reported by the geocoder. Not used for sorting by the filter. */\n score: number;\n /** Human-readable place name, shown in the dropdown and kept as the value's description. */\n label: string;\n /** Latitude, in decimal degrees. */\n lat: number;\n /** Longitude, in decimal degrees. */\n lng: number;\n}\n\nexport interface ModelListGeodistanceFilterParams extends ModelListFilterParams {\n /**\n * Turns the user's text into candidate places. This is the filter's geocoding\n * back end and is required; {@link BanAdapter} is the implementation shipped\n * with the library, wired as `geolocator: (pos) => adapter.search(pos)`.\n */\n geolocator: (pos: string) => Observable<GeoSearchResult[]>;\n /** Declared but never read anywhere in the library; setting it has no effect. */\n geomap?: (pos: [number, number], dist: number) => string;\n /**\n * Whether arrow keys scroll the highlighted place into view. Defaults to\n * `true`.\n */\n scroll?: boolean;\n}\n\n/**\n * Geographic distance filter: a distance dropdown next to a typeahead that\n * geocodes the text the user types, matching records within the chosen radius\n * of the chosen place.\n *\n * ## Value encoding\n *\n * Both inputs are sent as one query parameter combining the distance option and\n * the resolved coordinates, comma-separated: `lte,50,2.3522,48.8566`, i.e.\n * `<operator>,<distance>,<lng>,<lat>` — note longitude first. The operator is\n * always `lte` and the distances are a fixed ladder from 10 to 1000, expressed\n * in kilometres and hardcoded in the component's template; neither is\n * configurable. The backend must parse this encoding. Nothing is sent until\n * both a distance and a place have been chosen.\n *\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `\"Par distance autour d'un point\"` / `'Ville & distance'`. The distance\n * dropdown's own options are French and cannot be overridden.\n *\n * @example\n * ```typescript\n * const adapter = new BanAdapter(http, 'https://api-adresse.data.gouv.fr/search/');\n * new ModelListGeodistanceFilter({\n * name: 'around',\n * field: 'around',\n * label: 'Distance',\n * help: 'Town & distance',\n * geolocator: (pos) => adapter.search(pos),\n * });\n * ```\n */\nexport class ModelListGeodistanceFilter extends ModelListFilter implements ModelListGeodistanceFilterParams {\n /** The geocoder resolving typed text into places. */\n public geolocator: (pos: string) => Observable<GeoSearchResult[]>;\n /** Whether arrow keys scroll the active result into view. */\n public scroll!: boolean;\n\n /** Sets the filter type to `geodistance` and stores the geolocator. */\n constructor(params: ModelListGeodistanceFilterParams) {\n super(params);\n\n this.type = 'geodistance';\n this.geolocator = params.geolocator;\n if (this.label == '') {\n this.label = \"Par distance autour d'un point\";\n }\n if (this.help == '') {\n this.help = 'Ville & distance';\n }\n this.scroll = params.scroll !== undefined ? params.scroll : true;\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { FilterData } from '../../../../data/data-query';\n\n/** One comparison operator offered by {@link ModelListNumberFilter}. */\ninterface OperationDescriptor {\n /** Short identifier, as used in the filter's `operations` option. */\n name: string;\n /** Label shown in the operator dropdown. */\n label: string;\n /** Suffix appended to the filter's `field` to build the query parameter. */\n operator: string;\n}\n\n/**\n * The comparison operators a {@link ModelListNumberFilter} can offer, in\n * display order. Each one queries `<field><operator>`, so `lt` on a `price`\n * field sends `price_lt`; equality sends the bare `price`. The backend must\n * understand these suffixes.\n */\nexport const ModelListNumberOperations: OperationDescriptor[] = [\n { name: 'eq', label: '= (égal)', operator: '' },\n { name: 'lt', label: '< (inférieur)', operator: '_lt' },\n { name: 'gt', label: '> (supérieur)', operator: '_gt' },\n { name: 'lte', label: '<= (inférieur ou égal)', operator: '_lte' },\n { name: 'gte', label: '>= (supérieur ou égal)', operator: '_gte' },\n];\n\nexport interface ModelListNumberFilterParams extends ModelListFilterParams {\n /**\n * Restricts the operator dropdown to these operators, by `name`, in the order\n * given; the first becomes the initial operator. Names that match nothing in\n * {@link ModelListNumberOperations} are ignored, and an empty or fully\n * unmatched list leaves all operators available.\n */\n operations?: string[];\n}\n\n/**\n * Numeric filter: a number input paired with a comparison operator dropdown\n * (`=`, `<`, `>`, `<=`, `>=`). Unlike other filters it does not query `field`\n * directly — it appends the operator's suffix, sending `price_lt` for \"less\n * than\" on a `price` field, so the backend must support those suffixed\n * parameters.\n *\n * Use `operations` to narrow the dropdown when only some comparisons make sense.\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Recherche par valeur'` / `'Valeur à rechercher'`. Note that the operator\n * labels themselves are French and cannot be overridden.\n *\n * @example\n * ```typescript\n * new ModelListNumberFilter({\n * name: 'price',\n * field: 'price',\n * label: 'Price',\n * help: 'Amount to compare',\n * operations: ['lte', 'gte'],\n * });\n * ```\n */\nexport class ModelListNumberFilter extends ModelListFilter {\n /** The comparison currently selected; drives the query parameter's suffix. */\n public operator = ModelListNumberOperations[0];\n /** The operators offered in the dropdown, narrowed by the `operations` option. */\n public operations = ModelListNumberOperations;\n\n /**\n * Sets the filter type to `number` and, when `operations` is given, restricts\n * the operator list to it and selects the first as the initial operator.\n */\n constructor(params: ModelListNumberFilterParams) {\n super(params);\n this.type = 'number';\n if (this.label == '') {\n this.label = 'Recherche par valeur';\n }\n if (this.help == '') {\n this.help = 'Valeur à rechercher';\n }\n const ops: OperationDescriptor[] = [];\n if (params.operations && params.operations.length > 0) {\n for (const op of params.operations) {\n for (const dop of this.operations) {\n if (op === dop.name) {\n ops.push(dop);\n }\n }\n }\n if (ops.length > 0) {\n this.operations = ops;\n this.operator = ops[0];\n }\n }\n }\n\n /**\n * Selects the comparison to apply, matching on the operator's **suffix**\n * (`'_lt'`, `''` for equality, ...) rather than its `name`. Unknown suffixes\n * leave the current operator untouched. Call\n * {@link ModelListFilters.update} afterwards to re-run the query.\n */\n public setOperator(op: string) {\n for (const o of this.operations) {\n if (op === o.operator) {\n this.operator = o;\n }\n }\n }\n\n /**\n * Writes the value under `field` suffixed with the current operator, so the\n * chosen comparison reaches the server as part of the parameter name.\n */\n public override updateFilter(filter: FilterData): void {\n if (this._value !== undefined && this._value !== null) {\n filter[`${this.field}${this.operator.operator}`] = this.getValue();\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\nimport { FilterValue } from '../../../../data/data-query';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\nimport { DataModel } from '../../../../data/data-model';\nimport { DataModelType } from '../../../../data/data-collection';\nimport { isObservable, Observable, of } from 'rxjs';\n\nexport interface ModelListSelectFilterParams<T extends DataModel> extends ModelListFilterParams {\n /**\n * The options to offer, either as a plain array or as an `Observable` for\n * choices resolved asynchronously. Required unless {@link model} is given.\n */\n choices?: IDispEditChoice[] | Observable<IDispEditChoice[]>;\n /**\n * A model class to read the choices from, instead of listing them by hand.\n * The filter instantiates it and reflects the `choices` declared on the\n * field's metadata, which keeps the dropdown in sync with the model.\n */\n model?: DataModelType<T>;\n /**\n * The model field to read the choices from, when it differs from\n * {@link ModelListFilterParams.field}. Only meaningful together with\n * {@link model}; defaults to `field`.\n */\n mfield?: string;\n}\n\n/**\n * Single-choice filter: a dropdown sending the selected option's value under\n * the filter's `field`. Clearing the dropdown clears the filter.\n *\n * The options come from either of two sources, and passing neither throws:\n *\n * - `choices` — an explicit array, or an `Observable` when they are loaded\n * asynchronously.\n * - `model` (plus optional `mfield`) — reflects the choices off the model\n * field's metadata, so a list of choices declared on the model is not\n * duplicated here. Throws if that field declares none.\n *\n * `default` is applied at construction on this class only; the multi variant\n * handles its own.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez un élément'` / `'Choix par liste déroulante'`.\n *\n * @throws `'Missing choices for select filter'` (a string, not an `Error`) when\n * neither `choices` nor `model` is given.\n * @throws `'No choices found for model/field'` (a string, not an `Error`) when\n * `model` is used but the target field declares no choices.\n *\n * @example\n * ```typescript\n * // Explicit choices\n * new ModelListSelectFilter<Thing>({\n * name: 'status',\n * field: 'status',\n * label: 'Status',\n * help: 'Pick a status',\n * choices: [{ value: 'ok', desc: 'Valid' }, { value: 'ko', desc: 'Invalid' }],\n * });\n *\n * // Reflected off the model field's metadata\n * new ModelListSelectFilter<Thing>({\n * name: 'status', field: 'status', label: 'Status', help: 'Pick a status',\n * model: Thing,\n * });\n * ```\n */\nexport class ModelListSelectFilter<T extends DataModel>\n extends ModelListFilter\n implements ModelListSelectFilterParams<T>\n{\n /**\n * The options offered by the dropdown, always an `Observable` whatever the\n * source they were built from.\n */\n public choices!: Observable<IDispEditChoice[]>;\n /** Declared to satisfy the params interface; the constructor never assigns it. */\n public model?: DataModelType<T>;\n /** Declared to satisfy the params interface; the constructor never assigns it. */\n public mfield?: string;\n\n /**\n * Resolves the choices from `choices` or `model`, sets the filter type to\n * `select`, and applies `default` when this instance really is a `select`\n * (the check keeps subclasses from applying it twice).\n */\n constructor(params: ModelListSelectFilterParams<T>) {\n super(params);\n this.type = 'select';\n if (this.label == '') {\n this.label = 'Sélectionnez un élément';\n }\n if (this.help == '') {\n this.help = 'Choix par liste déroulante';\n }\n if (!params.choices && !params.model) {\n throw new Error('Missing choices for select filter');\n }\n if (!params.choices && params.model) {\n const m = new params.model();\n const f = m.FM(params.mfield || params.field);\n const ch = (f as { choices?: IDispEditChoice[] }).choices;\n if (!ch) {\n throw new Error('No choices found for model/field');\n }\n this.choices = of(ch);\n } else {\n if (!isObservable(params.choices)) {\n this.choices = of(params.choices as IDispEditChoice[]);\n } else {\n this.choices = params.choices;\n }\n }\n // Set default only for cur type\n if (this.default && this.type == 'select') {\n this.set(this.default as FilterValue, '', true);\n }\n }\n\n /** Empty stub; the constructor applies `default` itself. Does nothing. */\n public setDefault() {\n // The choices carry their own default; nothing to seed here.\n }\n}\n","import {\n ModelListSelectFilter,\n ModelListSelectFilterParams,\n} from '../model-list-select-filter/model-list-select-filter';\nimport { DataModel } from '../../../../data/data-model';\nimport { IDispEditChoice } from '../../../../dispedit/dispedit/dispedit.constants';\n\nexport interface ModelListMultiSelectFilterParams<T extends DataModel> extends ModelListSelectFilterParams<T> {\n /**\n * The options selected from the start, as full choice objects rather than\n * bare values: each `desc` is what labels the corresponding chip until the\n * user removes it.\n */\n default?: IDispEditChoice[];\n}\n\n/**\n * Multiple-choice filter: a dropdown that accumulates the picked options as\n * removable chips, sending all their values joined by `,` in a single query\n * parameter. Same choice sources as {@link ModelListSelectFilter} — `choices`\n * or `model` — and the same throw contract.\n *\n * `default` differs here: it takes an array of `IDispEditChoice` rather than a\n * lone value, since each preselected option needs its own label.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez un élément'` / `'Choix par liste déroulante (multiple)'`.\n *\n * @throws `'Missing choices for select filter'` (a string, not an `Error`) when\n * neither `choices` nor `model` is given.\n * @throws `'No choices found for model/field'` (a string, not an `Error`) when\n * `model` is used but the target field declares no choices.\n *\n * @example\n * ```typescript\n * new ModelListSelectMultiFilter<Thing>({\n * name: 'status',\n * field: 'status',\n * label: 'Status',\n * help: 'Pick one or more statuses',\n * choices: [{ value: 'ok', desc: 'Valid' }, { value: 'ko', desc: 'Invalid' }],\n * default: [{ value: 'ok', desc: 'Valid' }],\n * });\n * ```\n */\nexport class ModelListSelectMultiFilter<T extends DataModel> extends ModelListSelectFilter<T> {\n /** Always `true`: this filter joins its values into one query parameter. */\n public override multi = true;\n // `default` is inherited from ModelListFilter (typed `any`) and set by the\n // base constructor. We intentionally do NOT re-declare it here: under\n // useDefineForClassFields:true a field re-declaration without initializer\n // would clobber the base-constructor value back to undefined.\n\n /**\n * Switches the filter type to `selectmulti` and selects each `default`\n * choice. The parent constructor has already resolved the choices and\n * enforced the `choices`-or-`model` requirement.\n */\n /** The options selected from the start, as full choice objects. */\n declare public default?: IDispEditChoice[];\n\n constructor(params: ModelListMultiSelectFilterParams<T>) {\n super(params);\n\n this.type = 'selectmulti';\n if (this.label == '') {\n this.label = 'Sélectionnez un élément';\n }\n if (this.help == '') {\n this.help = 'Choix par liste déroulante (multiple)';\n }\n // Set default only for cur type\n if (this.default && this.type == 'selectmulti') {\n for (const f of this.default) {\n this.set(f.value, f.desc, true);\n }\n }\n }\n}\n","import { ModelListFilter, ModelListFilterParams } from '../../model-list-filter';\n\n/**\n * Free-text filter: a single text input whose content is sent as-is under the\n * filter's `field`, debounced while the user types. The usual choice for a\n * list's main search box.\n *\n * Takes no options beyond {@link ModelListFilterParams}. `default` is applied\n * at construction, so the list starts out already filtered.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Recherche par texte'` / `'Texte à rechercher'`.\n *\n * @example\n * ```typescript\n * new ModelListTextFilter({\n * name: 'search',\n * field: 'search',\n * label: 'Search',\n * help: 'Text to look for',\n * });\n * ```\n */\nexport class ModelListTextFilter extends ModelListFilter {\n /**\n * Sets the filter type to `text` and applies `default` as the initial search\n * term when one is given.\n */\n constructor(params: ModelListFilterParams) {\n super(params);\n this.type = 'text';\n if (this.label == '') {\n this.label = 'Recherche par texte';\n }\n if (this.help == '') {\n this.help = 'Texte à rechercher';\n }\n if (this.default) {\n this.set(this.default as string, '', true);\n }\n }\n}\n","import { DataModel } from '../../../../data/data-model';\nimport {\n ModelListAutocompleteFilter,\n ModelListAutocompleteParams,\n} from '../model-list-autocomplete-filter/model-list-autocomplete-filter';\n\nexport interface ModelListTreeParams<T extends DataModel> extends ModelListAutocompleteParams<T> {\n /**\n * How deep the hierarchy may go, counted from the root. Defaults to `5`. It\n * caps how many dropdowns are offered, and bounds the walk back up to the\n * root when restoring a preselected node — that walk throws if it exceeds\n * this depth without reaching a root.\n */\n maxLevel?: number;\n}\n\n/**\n * Hierarchical filter: a chain of dropdowns, one per level, each populated from\n * the node selected in the one above. Picking a node sends its `id` under the\n * filter's `field`; a new dropdown appears as long as the selected node has\n * children and {@link maxLevel} is not reached.\n *\n * It extends {@link ModelListAutocompleteFilter}, so it needs `collection` or\n * `queryset` under the same throw contract, and it reuses that class's\n * `display` and `filter` options. It does not, however, present a typeahead.\n *\n * ## Backend contract\n *\n * Levels are fetched by querying the queryset with `level` and `parent`\n * parameters (`parent=null` for roots), so the endpoint must support both.\n * When the filter already has a value, it walks from that node up to the root\n * by following each record's `parent` property to rebuild the chain of\n * dropdowns.\n *\n * That walk reads `parent` off the fetched records, so if you use `filter` to\n * trim the payload it **must** keep the parent pointer:\n * `filter: { fields: ['id', 'name', 'parent'].join(',') }`. Omit it and\n * restoring a preselected node breaks.\n *\n * `default` is not applied by this filter.\n *\n * Always pass `label` and `help`: left empty they fall back to the French\n * `'Sélectionnez dans la hiérarchie'` / `'Texte à rechercher'`.\n *\n * @throws `'Missing related data (collection or queryset)'` (a string, not an\n * `Error`) when neither `collection` nor `queryset` is given.\n *\n * @example\n * ```typescript\n * new ModelListTreeFilter<Category>({\n * name: 'category',\n * field: 'category',\n * label: 'Category',\n * help: 'Pick a category',\n * collection: categories,\n * display: (c) => `${c.name}`,\n * maxLevel: 3,\n * // 'parent' is required to rebuild the hierarchy\n * filter: { fields: ['id', 'name', 'parent'].join(',') },\n * });\n * ```\n */\nexport class ModelListTreeFilter<T extends DataModel>\n extends ModelListAutocompleteFilter<T>\n implements ModelListTreeParams<T>\n{\n /** Maximum hierarchy depth; also bounds the walk back up to the root. */\n public maxLevel = 5;\n\n /**\n * Switches the filter type to `tree` and applies `maxLevel`. The parent\n * constructor has already enforced the `collection`-or-`queryset`\n * requirement.\n */\n constructor(params: ModelListTreeParams<T>) {\n super(params);\n this.type = 'tree';\n if (this.label == '') {\n this.label = 'Sélectionnez dans la hiérarchie';\n }\n if (this.help == '') {\n this.help = 'Texte à rechercher';\n }\n if (params.maxLevel) {\n this.maxLevel = params.maxLevel;\n }\n }\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { GeoSearchResult } from '../model-list-geodistance-filter';\n\n/**\n * The GeoJSON `FeatureCollection` returned by the BAN search endpoint. Only the\n * members {@link BanAdapter} reads are described precisely; the service returns\n * more.\n */\nexport interface BanResults {\n type: 'FeatureCollection';\n version: string;\n features: {\n type: 'Feature';\n geometry: {\n type: 'Point';\n coordinates: [number, number];\n };\n properties: {\n label: string;\n score: number;\n id: string;\n type: string;\n name: string;\n postcode: string;\n citycode: string;\n x: number;\n y: number;\n population: number;\n city: string;\n context: string;\n importance: number;\n };\n }[];\n}\n\n/**\n * Geocoder for {@link ModelListGeodistanceFilter} backed by the French *Base\n * Adresse Nationale* (BAN) address search API, whose GeoJSON responses it maps\n * to {@link GeoSearchResult}. This is the only adapter shipped with the\n * library; targeting another geocoder means writing an equivalent class, since\n * the filter only ever needs a `(text) => Observable<GeoSearchResult[]>`.\n *\n * Build it once — in a service, or wherever the filter is declared — and hand\n * its {@link search} to the filter's `geolocator`. Being a plain class it is\n * not injectable: pass an `HttpClient` in yourself.\n *\n * @example\n * ```typescript\n * const adapter = new BanAdapter(inject(HttpClient), 'https://api-adresse.data.gouv.fr/search/');\n * new ModelListGeodistanceFilter({\n * name: 'around', field: 'around', label: 'Distance', help: 'Town & distance',\n * geolocator: (pos) => adapter.search(pos),\n * });\n * ```\n */\nexport class BanAdapter {\n /**\n * @param _http The client issuing the search requests.\n * @param _baseUrl The BAN search endpoint, used as-is with the query added as\n * a `q` parameter (e.g. `https://api-adresse.data.gouv.fr/search/`).\n */\n constructor(\n private _http: HttpClient,\n private _baseUrl: string,\n ) {}\n\n /**\n * Geocodes `text` through the BAN endpoint, flattening each returned feature\n * into a {@link GeoSearchResult} whose `label` combines the address label and\n * its context (department and region), which disambiguates identically named\n * towns in the dropdown.\n *\n * Results come back in the service's own relevance order; no filtering on\n * `score` is applied.\n */\n public search(text: string): Observable<GeoSearchResult[]> {\n return this._http.get<BanResults>(`${this._baseUrl}`, { params: { q: text } }).pipe(\n map((r) => {\n const out: GeoSearchResult[] = [];\n for (const f of r.features) {\n out.push({\n score: f.properties.score,\n label: `${f.properties.label} (${f.properties.context})`,\n lat: f.geometry.coordinates[1],\n lng: f.geometry.coordinates[0],\n });\n }\n return out;\n }),\n );\n }\n}\n","import { Component, DestroyRef, inject, input, OnInit, signal } from '@angular/core';\nimport { ModelList } from '../../model-list.service';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime } from 'rxjs';\nimport { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';\n\nimport { DataModel } from '../../../data/data-model';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-model-list-paginator',\n templateUrl: './model-list-paginator.component.html',\n styleUrls: ['./model-list-paginator.component.sass'],\n imports: [ReactiveFormsModule, NgbPaginationModule],\n})\n/**\n * The pagination bar for a list: a page-size selector, page links, the total row\n * count and a \"go to page\" box.\n *\n * Place it under the table, bound to the same {@link ModelList}; it drives that\n * list's {@link ModelListPaginator} and follows the server's response, so no\n * wiring beyond the input is needed.\n *\n * @example\n * ```html\n * <data-model-list-paginator [list]=\"list\"></data-model-list-paginator>\n * ```\n */\nexport class ModelListPaginatorComponent<T extends DataModel> implements OnInit {\n /** The list being paginated. */\n public list = input.required<ModelList<T>>();\n /**\n * Largest page size offered in the selector — despite the name this caps rows\n * per page, not the number of pages. Options run 10 to 10000; each is shown\n * only if it is `<= maxPages`, so the default of 200 offers 10 through 200.\n */\n public maxPages = input<number>(200);\n /** Render nothing. */\n public hide = input<boolean>(false);\n\n /** Rows-per-page selector. */\n public perPageControl: FormControl = new FormControl<number>(10);\n /** Whether the \"go to page\" input is expanded. */\n public showDirectAccess = false;\n /** Direct page number entry, debounced 400ms before it moves the list. */\n public directAccess: FormControl = new FormControl<number>(0);\n /** Page currently shown, as reported by the last response. */\n public curPage = signal(1);\n /** Total number of matching rows. */\n public curCount = signal<number>(0);\n /** Rows per page currently in effect. */\n public pageSize = signal<number>(0);\n private destroy$ = inject(DestroyRef);\n\n /** Move the list to `page`. */\n public onPageChange(page: number): void {\n if (!page) {\n return;\n }\n this.list().paginator.setPage(page);\n }\n\n /**\n * Sync the controls with the list's paginator, follow the nav metadata of each\n * response, and push the user's page-size / direct-page changes back.\n */\n public ngOnInit(): void {\n const list = this.list();\n this.perPageControl.setValue(list.paginator.getPageSize(), {\n emitEvent: false,\n });\n list.meta.pipe(takeUntilDestroyed(this.destroy$)).subscribe((meta) => {\n if (meta.nav) {\n list.paginator.updatePage(meta.nav.page || 1);\n this.curPage.set(meta.nav.page || 1);\n this.curCount.set(meta.nav.count);\n list.paginator.updatePageSize(meta.nav.size);\n this.pageSize.set(list.paginator.getPageSize());\n this.perPageControl.setValue(this.pageSize(), { emitEvent: false });\n }\n });\n\n this.perPageControl.valueChanges.pipe(takeUntilDestroyed(this.destroy$)).subscribe((count) => {\n list.paginator.setPageSize(Number(count));\n });\n\n this.directAccess.valueChanges.pipe(takeUntilDestroyed(this.destroy$), debounceTime(400)).subscribe((count) => {\n list.paginator.setPage(+count);\n });\n }\n}\n","@if (!hide()) {\n <div class=\"row\">\n <div class=\"col-sm-4\">\n <select class=\"form-select perpage\" [formControl]=\"perPageControl\">\n @if (maxPages() >= 10) {\n <option value=\"10\">10 / page</option>\n }\n @if (maxPages() >= 20) {\n <option value=\"20\">20 / page</option>\n }\n @if (maxPages() >= 50) {\n <option value=\"50\">50 / page</option>\n }\n @if (maxPages() >= 100) {\n <option value=\"100\">100 / page</option>\n }\n @if (maxPages() >= 200) {\n <option value=\"200\">200 / page</option>\n }\n @if (maxPages() >= 500) {\n <option value=\"500\">500 / page</option>\n }\n @if (maxPages() >= 1000) {\n <option value=\"1000\">1000 / page</option>\n }\n @if (maxPages() >= 2000) {\n <option value=\"2000\">2000 / page</option>\n }\n @if (maxPages() >= 5000) {\n <option value=\"5000\">5000 / page</option>\n }\n @if (maxPages() >= 10000) {\n <option value=\"10000\">10000 / page</option>\n }\n </select>\n </div>\n @if (list()) {\n <div class=\"col-sm-5 pagination\">\n <div class=\"text-xs-center\">\n <ngb-pagination\n [pageSize]=\"pageSize()\"\n [collectionSize]=\"curCount()\"\n [page]=\"curPage()\"\n (pageChange)=\"onPageChange($event)\"\n [maxSize]=\"5\"\n [rotate]=\"true\"\n ></ngb-pagination>\n </div>\n </div>\n }\n <div class=\"col-sm-3 results\">\n <div>\n {{ curCount() }} résultats -\n <span\n (click)=\"showDirectAccess = !showDirectAccess\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"showDirectAccess\"\n (keydown.enter)=\"showDirectAccess = !showDirectAccess\"\n (keydown.space)=\"$event.preventDefault(); showDirectAccess = !showDirectAccess\"\n >\n acces direct\n </span>\n </div>\n @if (showDirectAccess) {\n <div>\n <input class=\"form-control\" [formControl]=\"directAccess\" type=\"number\" placeholder=\"Aller à la page\" />\n </div>\n }\n </div>\n </div>\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { fieldValues, asText } from '../data/field-values';\nimport { DataModel } from '../data/data-model';\nimport { IDispEditChoice } from './dispedit/dispedit.constants';\n\n/**\n * Resolves a model field's raw value to the label declared in its field\n * manager's `choices`.\n *\n * Saves repeating the code-to-label mapping in templates: the manager already\n * knows it, so `thing | choice: 'status'` prints `Active` where the model holds\n * `A`. Falls back to the raw value when the field declares no choices, and to\n * `[value] ??` when the value matches none of them — an unmatched value is\n * shown rather than hidden.\n *\n * @example\n * ```html\n * {{ thing | choice: 'status' }} <!-- Active -->\n * {{ thing | choice: 'status':'both' }} <!-- [A] Active -->\n * ```\n */\n@Pipe({\n name: 'choice',\n standalone: true,\n})\nexport class ChoicePipe<T extends DataModel> implements PipeTransform {\n /**\n * @param value model instance to read the field from; `-` if nullish.\n * @param field name of the field whose manager declares the choices.\n * @param mode `desc` for the label alone, `code` for the raw value alone\n * (no manager lookup), `both` for `[code] label`.\n */\n transform(value: T, field: string, mode: 'code' | 'desc' | 'both' = 'desc'): string {\n if (!value) {\n return '-';\n }\n const fvalue = fieldValues(value)[field];\n if (mode === 'code') {\n return asText(fvalue);\n }\n const manager = value.FM(field);\n const choices = (manager as { choices?: IDispEditChoice[] }).choices;\n if (!choices) {\n return asText(fvalue);\n }\n for (const ch of choices) {\n if (ch.value === fvalue) {\n if (mode === 'desc') {\n return ch.desc;\n } else {\n return `[${asText(fvalue)}] ${ch.desc}`;\n }\n }\n }\n return `[${asText(fvalue)}] ??`;\n }\n}\n\n/**\n * {@link ChoicePipe} for a value that is not on the model.\n *\n * Same resolution, but the value is piped in and the model is only used to find\n * the field manager holding the `choices`. Useful when the value comes from\n * elsewhere — an aggregate, a form control, a row of a related list — while the\n * choice mapping still lives on a model field.\n *\n * @example\n * ```html\n * {{ row.status | pchoice: thing: 'status' }}\n * ```\n */\n@Pipe({\n name: 'pchoice',\n standalone: true,\n})\nexport class PChoicePipe<T extends DataModel> implements PipeTransform {\n /**\n * @param value raw value to resolve; `-` if nullish.\n * @param model model instance used only to look up the field manager.\n * @param field name of the field whose manager declares the choices.\n * @param mode `desc` for the label alone, `code` for the raw value alone,\n * `both` for `[code] label`.\n */\n transform(value: unknown, model: T, field: string, mode: 'code' | 'desc' | 'both' = 'desc'): string {\n if (!model) {\n return '-';\n }\n if (!value) {\n return '-';\n }\n // Use value from input, not from field\n const fvalue = value; //- fieldValues(model)[field];\n if (mode === 'code') {\n return asText(fvalue);\n }\n const manager = model.FM(field);\n const choices = (manager as { choices?: IDispEditChoice[] }).choices;\n if (!choices) {\n return asText(fvalue);\n }\n for (const ch of choices) {\n if (ch.value === fvalue) {\n if (mode === 'desc') {\n return ch.desc;\n } else {\n return `[${asText(fvalue)}] ${ch.desc}`;\n }\n }\n }\n return `[${asText(fvalue)}] ??`;\n }\n}\n","import { inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core';\nimport { fieldValues } from '../data/field-values';\nimport { DataModel } from '../data/data-model';\nimport { formatNumber } from '@angular/common';\n\n/**\n * Whether a value is worth formatting: rejects null, undefined, empty string\n * and NaN (via the `value !== value` self-inequality check).\n */\nexport function isValue(value: number | string | null | undefined): value is number | string {\n return !(value == null || value === '' || value !== value);\n}\n\n/**\n * Coerce a numeric string to a number, passing numbers through.\n *\n * @param value value to coerce.\n * @throws Error if the value is neither a number nor a numeric string.\n */\nexport function strToNumber(value: number | string): number {\n // Convert strings to numbers\n if (typeof value === 'string' && !isNaN(Number(value) - parseFloat(value))) {\n return Number(value);\n }\n if (typeof value !== 'number') {\n throw new Error(`${value} is not a number`);\n }\n return value;\n}\n\n/**\n * Formats a scaled numeric model field as a human-readable number, dividing by\n * the field manager's `factor`.\n *\n * `decimalField.factor` is a wire-format concern, not a model one: the model\n * property holds the **raw** integer value, and the division happens at display\n * time — here, and in `<data-dispedit>`. With `factor: 100`, `thing.price` is\n * `1234` (cents) and this pipe prints `12.34`. Reading `thing.price` directly in\n * a template therefore shows the unscaled value; that mismatch is the trap this\n * pipe exists to avoid. Fields with no `factor` divide by 1 and are unaffected.\n *\n * @example\n * ```html\n * {{ thing | factor: 'price' }} <!-- 12.34 for a raw 1234 -->\n * {{ thing | factor: 'price':'1.2-2' }}\n * ```\n */\n@Pipe({\n name: 'factor',\n standalone: true,\n})\nexport class FactorPipe<T extends DataModel> implements PipeTransform {\n private _locale = inject(LOCALE_ID);\n\n /**\n * @param value model instance to read the field from; null if nullish.\n * @param field name of the field whose manager carries the `factor`.\n * @param digitsInfo digit format, as accepted by Angular's `number` pipe.\n * @param locale locale to format in; defaults to the ambient `LOCALE_ID`.\n */\n transform(value: T | null, field: string, digitsInfo?: string, locale?: string): string | null {\n if (!value) {\n return null;\n }\n locale = locale || this._locale;\n const fvalue = fieldValues(value)[field] as string | number | null | undefined;\n if (!isValue(fvalue)) return null;\n const manager = value.FM(field);\n let factor = (manager as { factor?: number }).factor;\n factor = factor || 1;\n const num = strToNumber(fvalue);\n return formatNumber(num / factor, locale, digitsInfo);\n }\n}\n\n/**\n * {@link FactorPipe} for a value that is not on the model.\n *\n * Same scaling, but the value is piped in and the model is only used to look up\n * the field manager's `factor`. Useful for computed totals or values from a\n * related payload that share a field's scale.\n *\n * @example\n * ```html\n * {{ total | pfactor: thing: 'price' }}\n * ```\n */\n@Pipe({\n name: 'pfactor',\n standalone: true,\n})\nexport class PFactorPipe<T extends DataModel> implements PipeTransform {\n private _locale = inject(LOCALE_ID);\n\n /**\n * @param value raw, unscaled value to format; null if falsy.\n * @param model model instance used only to look up the field manager.\n * @param field name of the field whose manager carries the `factor`.\n * @param digitsInfo digit format, as accepted by Angular's `number` pipe.\n * @param locale locale to format in; defaults to the ambient `LOCALE_ID`.\n */\n transform(\n value: number | string | null | undefined,\n model: T | null,\n field: string,\n digitsInfo?: string,\n locale?: string,\n ): string | null {\n if (!model) return null;\n if (!value) return null;\n\n locale = locale || this._locale;\n // Use value from input, not from model\n const fvalue = value; // fieldValues(model)[field];\n if (!isValue(fvalue)) return null;\n const manager = model.FM(field);\n let factor = (manager as { factor?: number }).factor;\n factor = factor || 1;\n const num = strToNumber(fvalue);\n return formatNumber(num / factor, locale, digitsInfo);\n }\n}\n","import { DEFAULT_CURRENCY_CODE, inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core';\nimport { fieldValues } from '../data/field-values';\nimport { DataModel } from '../data/data-model';\nimport { isValue, strToNumber } from './factor.pipe';\nimport { formatCurrency, getCurrencySymbol } from '@angular/common';\n\n/**\n * Currency counterpart of `factor`: divides a scaled numeric model field by its\n * field manager's `factor`, then formats the result as currency.\n *\n * The scaling caveat is the same. `decimalField.factor` is applied at display\n * time, not in the model: the property holds the raw integer, so `factor: 100`\n * means `thing.price` is `1234` and this pipe prints `12,34 €`. Fields with no\n * `factor` divide by 1.\n *\n * @example\n * ```html\n * {{ thing | factorc: 'price' }}\n * {{ thing | factorc: 'price':'USD':'symbol':'1.2-2' }}\n * ```\n */\n@Pipe({\n name: 'factorc',\n standalone: true,\n})\nexport class FactorcPipe<T extends DataModel> implements PipeTransform {\n private _locale = inject(LOCALE_ID);\n private _defaultCurrencyCode = inject(DEFAULT_CURRENCY_CODE);\n\n /**\n * @param value model instance to read the field from; null if nullish.\n * @param field name of the field whose manager carries the `factor`.\n * @param currencyCode ISO code; defaults to the ambient `DEFAULT_CURRENCY_CODE`.\n * @param display how to render the currency: `code`, `symbol` (the default),\n * `symbol-narrow`, or a literal string to use as-is.\n * @param digitsInfo digit format, as accepted by Angular's `currency` pipe.\n * @param locale locale to format in; defaults to the ambient `LOCALE_ID`.\n */\n transform(\n value: T | null,\n field: string,\n currencyCode?: string,\n display?: 'code' | 'symbol' | 'symbol-narrow' | (string & {}),\n digitsInfo?: string,\n locale?: string,\n ): string | null {\n if (!value) return null;\n const fvalue = fieldValues(value)[field] as string | number | null | undefined;\n if (!isValue(fvalue)) return null;\n locale = locale || this._locale;\n let currency: string = currencyCode || this._defaultCurrencyCode;\n if (!display) {\n display = 'symbol';\n }\n if (display !== 'code') {\n if (display === 'symbol' || display === 'symbol-narrow') {\n currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow', locale);\n } else {\n currency = display!;\n }\n }\n\n const manager = value.FM(field);\n const factor = (manager as { factor?: number }).factor || 1;\n const num = strToNumber(fvalue);\n return formatCurrency(num / factor, locale, currency, currencyCode, digitsInfo);\n }\n}\n\n/**\n * {@link FactorcPipe} for a value that is not on the model.\n *\n * Same scaling and currency formatting, but the value is piped in and the model\n * is only used to look up the field manager's `factor`. Useful for computed\n * totals that share a price field's scale.\n *\n * @example\n * ```html\n * {{ total | pfactorc: thing: 'price' }}\n * ```\n */\n@Pipe({\n name: 'pfactorc',\n standalone: true,\n})\nexport class PFactorcPipe<T extends DataModel> implements PipeTransform {\n private _locale = inject(LOCALE_ID);\n private _defaultCurrencyCode = inject(DEFAULT_CURRENCY_CODE);\n\n /**\n * @param value raw, unscaled value to format; null if falsy.\n * @param model model instance used only to look up the field manager.\n * @param field name of the field whose manager carries the `factor`.\n * @param currencyCode ISO code; defaults to the ambient `DEFAULT_CURRENCY_CODE`.\n * @param display how to render the currency: `code`, `symbol` (the default),\n * `symbol-narrow`, or a literal string to use as-is.\n * @param digitsInfo digit format, as accepted by Angular's `currency` pipe.\n * @param locale locale to format in; defaults to the ambient `LOCALE_ID`.\n */\n transform(\n value: number | string | undefined | null,\n model: T | null,\n field: string,\n currencyCode?: string,\n display?: 'code' | 'symbol' | 'symbol-narrow' | (string & {}),\n digitsInfo?: string,\n locale?: string,\n ): string | null {\n if (!model) return null;\n if (!value) return null;\n // Use value from input, not from model\n const fvalue = value; // fieldValues(model)[field];\n if (!isValue(fvalue)) {\n return null;\n }\n locale = locale || this._locale;\n let currency: string = currencyCode || this._defaultCurrencyCode;\n if (!display) {\n display = 'symbol';\n }\n if (display !== 'code') {\n if (display === 'symbol' || display === 'symbol-narrow') {\n currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow', locale);\n } else {\n currency = display!;\n }\n }\n\n const manager = model.FM(field);\n const factor = (manager as { factor?: number }).factor || 1;\n const num = strToNumber(fvalue);\n return formatCurrency(num / factor, locale, currency, currencyCode, digitsInfo);\n }\n}\n","import { Component, DestroyRef, inject, input, model, OnInit, output } from '@angular/core';\nimport { fieldValues } from '../../data/field-values';\nimport { DataModel } from '../../data/data-model';\nimport { uniqueId } from '../../utils/unique-id';\nimport { FilterData, Queryset } from '../../data/data-query';\nimport { Collection } from '../../data/data-collection';\nimport { debounceTime, distinctUntilChanged, Observable } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\n\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n/**\n * Renders a related instance as a label, for dropdown options and read-only\n * displays. Used as a fallback when the target model has no `_display`.\n */\nexport type TplFun<T extends DataModel> = (data: T) => string;\n\n@Component({\n selector: 'data-fkselect',\n templateUrl: './fkselect.component.html',\n styleUrls: ['./fkselect.component.sass'],\n imports: [ReactiveFormsModule, NgbTypeaheadModule],\n})\n/**\n * Typeahead for picking a single related instance (a foreign key target).\n *\n * Search terms are debounced (750ms) and sent to a queryset as a filter, so\n * candidates are queried from the API rather than held in memory. This is the\n * editor {@link DispeditComponent} renders for a `ForeignKeyFieldManager`; it\n * can also be used directly.\n *\n * The component only reports the selection through {@link selected} — it does\n * not write to the model or save. Used inside dispedit, that write (id to the\n * field, instance to `<field>_details`) and the save are dispedit's job.\n *\n * Options are labelled via the target's `_display`, accepted as either a getter\n * or a method; a model used as an FK target should define one. Failing that,\n * `[display]` is consulted, then `name` / `title` / `id`.\n */\nexport class FkselectComponent<T extends DataModel, R extends DataModel> implements OnInit {\n /**\n * Source model, used only to derive a queryset from its `_collection` when\n * neither `[queryset]` nor `[collection]` is given.\n */\n public model = input<T>();\n /** Field name on the source model. Informational; not read or written here. */\n public field = input<string>();\n /** Whether the control is in edit mode. */\n public edit = input<boolean>(false);\n /** Currently selected instance. */\n public value = input<R>();\n\n /**\n * Queryset searched for candidates. Derived on init from `[collection]`, or\n * from the model's `_collection`, when not supplied.\n */\n public queryset = model<Queryset<R>>();\n /** Collection the candidates are queried from. Writable so it can be derived. */\n public collection = model<Collection<R>>();\n /** Reserved flag; not currently read by the component. */\n public update = input<boolean>(false);\n /** Extra filter merged into every search request, to narrow the lookup. */\n public filter = input<FilterData>({});\n /** Presentation hint for the control. */\n public mode = input<'autocomplete' | 'select' | 'auto'>('auto');\n /** Option label: a property name, or a function. Only used without `_display`. */\n public display = input<string | TplFun<R>>();\n /** Query parameter name the search term is sent under. Defaults to `search`. */\n public search = input<string>('search');\n\n /** Label shown next to the control. */\n public label = input<string>('');\n /**\n * Id put on the search input, and pointed at by `[label]`'s `for`. Defaults\n * to a generated one; dispedit passes its own so its label drives this input.\n */\n public inputId = input<string>(uniqueId('data-fkselect'));\n /** Placeholder for the search input. */\n public placeholder = input<string>('');\n /** CSS classes applied to the search input. */\n public inputClasses = input<string[] | string>([]);\n\n /** Emits the instance the user picked from the dropdown. */\n public selected = output<R>();\n /** Emits when the user aborts editing (escape). */\n public cancelled = output<void>();\n /** Emits when the user clears the selection, via {@link clearAction}. */\n public cleared = output<void>();\n /** Form control backing the typeahead search input. */\n public fc!: FormControl<R | null>;\n /** Search callback handed to ng-bootstrap's typeahead. */\n public searchFn = this._search.bind(this);\n /** Option formatter handed to ng-bootstrap's typeahead. */\n public displayFn = this._display.bind(this);\n private _tpl!: TplFun<R>;\n private destroy$ = inject(DestroyRef);\n\n /**\n * Resolve the queryset (from the input, the collection, or the model's\n * collection), create the search control and subscribe to it, and build the\n * option display function.\n */\n public ngOnInit(): void {\n // Create queryset if not given\n // queryset is created through model\n const model = this.model();\n if (!this.queryset() && this.collection()) {\n this.queryset.set(this.collection()!.queryset());\n } else if (!this.queryset() && model && model._collection) {\n // Fallback: the source model's own collection, assumed to hold the\n // related instances. Nothing can check that assumption.\n const coll = model._collection as unknown as Collection<R>;\n this.collection.set(coll);\n this.queryset.set(coll.queryset());\n }\n this.fc = new FormControl<R | null>(null);\n this.fc.valueChanges.pipe(takeUntilDestroyed(this.destroy$), distinctUntilChanged()).subscribe((value) => {\n if (value) {\n this.selected.emit(value);\n }\n });\n const display = this.display();\n if (display) {\n if (typeof display === 'string') {\n this._tpl = (model: R) => String(fieldValues(model)[display]);\n } else if (typeof display === 'function') {\n this._tpl = display.bind(this);\n }\n } else {\n this._tpl = (model: R) =>\n String(fieldValues(model)['name'] ?? fieldValues(model)['title'] ?? fieldValues(model)['id']);\n }\n }\n\n /** Emit {@link cleared} so the parent can null the relation. */\n public clearAction(): void {\n this.cleared.emit();\n }\n\n /**\n * Label an instance: its `_display` (getter or method) if present, otherwise\n * the template function built from `[display]`.\n */\n private _display(x: R | null | undefined): string {\n if (x) {\n const display = (x as { _display?: string | (() => string) })._display;\n if (display) {\n return typeof display === 'function' ? display() : display;\n }\n if (this._tpl) {\n return this._tpl(x);\n }\n }\n return '';\n }\n\n /**\n * Debounce the typed term, merge it into `[filter]` under the `[search]`\n * parameter name, and query the queryset for candidates.\n *\n * @param text$ stream of search terms from the typeahead input.\n */\n private _search(text$: Observable<string>): Observable<R[]> {\n return text$.pipe(\n takeUntilDestroyed(this.destroy$),\n debounceTime(750),\n distinctUntilChanged(),\n switchMap((term) => {\n const f: FilterData = {};\n const filter = this.filter();\n for (const k of Object.keys(filter)) {\n if (filter[k] !== null || filter[k] !== undefined) {\n f[k] = filter[k];\n }\n }\n f[this.search()] = term;\n const qs = this.queryset()!;\n qs.filter(f, true);\n return qs.get();\n }),\n );\n }\n}\n","<div class=\"form-group\">\n @if (label()) {\n <label [attr.for]=\"inputId()\">{{ label() }}</label>\n }\n <div class=\"input-group\">\n <input\n [attr.id]=\"inputId()\"\n class=\"form-control\"\n [formControl]=\"fc\"\n [placeholder]=\"placeholder()\"\n [ngbTypeahead]=\"searchFn\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"displayFn\"\n [resultFormatter]=\"displayFn\"\n (keyup.escape)=\"cancelled.emit()\"\n />\n <div class=\"input-group-text\">\n <i\n class=\"bi bi-trash float-end pointer\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Vider la sélection\"\n (click)=\"clearAction()\"\n (keydown.enter)=\"clearAction()\"\n (keydown.space)=\"$event.preventDefault(); clearAction()\"\n ></i>\n </div>\n </div>\n</div>\n","import { inject, Injectable, InjectionToken, NgZone } from '@angular/core';\nimport { Observable, ReplaySubject, Subscription, timer } from 'rxjs';\n\n/** Severity of a {@link Message}; drives both the CSS classes and the default lifetime. */\nexport const enum TYPE {\n SUCCESS,\n INFO,\n WARNING,\n DANGER,\n}\n\n/** Default lifetime in milliseconds per severity: the more severe, the longer it stays on screen. */\nexport enum DEFAULT_TIMEOUTS {\n SUCCESS = 3000,\n INFO = 4000,\n WARNING = 10000,\n DANGER = 30000,\n}\n\n/** Lifecycle of a {@link Message}: never shown yet, currently shown, or dismissed by the user. */\nexport enum STATUS {\n UNDISP,\n DISP,\n ACK,\n}\n\nconst DEFAULT_MESSAGE_TIMEOUT = 5000;\n\n/**\n * Maps a sound key (`success`, `info`, `warning`, `error`, `notify`) to an audio file url.\n */\nexport type ISoundTypes = Record<string, string>;\n\n/**\n * Optional per-severity notification sounds ({@link ISoundTypes}) played by\n * {@link DataMessageService.play}.\n *\n * When not provided, messages are silent. Keys are the sound names the service uses:\n * `success`, `info`, `warning` and `error`.\n */\nexport const DATA_MESSAGE_SOUNDS = new InjectionToken<ISoundTypes>('data.message.sounds');\n\n/**\n * A single user-facing notification: a title, an optional body, an optional trace for\n * debugging, and a countdown.\n *\n * Instances are created by {@link DataMessageService}; application code normally reads\n * them from the message stream rather than constructing them. `ttl` is decremented in\n * place by the service, and the message is dropped once it reaches zero.\n */\nexport class Message {\n public status: string = STATUS[STATUS.UNDISP];\n public showTrace = false;\n\n constructor(\n public title: string,\n public type: TYPE = TYPE.INFO,\n public message = '',\n public trace: unknown = null,\n public ttl: number = DEFAULT_MESSAGE_TIMEOUT,\n ) {}\n\n /** Bootstrap alert classes matching this message's severity, bound by the message zone template. */\n public get style(): string {\n if (this.type === TYPE.DANGER) {\n return 'alert alert-dismissible alert-danger';\n }\n if (this.type === TYPE.INFO) {\n return 'alert alert-dismissible alert-info';\n }\n if (this.type === TYPE.WARNING) {\n return 'alert alert-dismissible alert-warning';\n }\n if (this.type === TYPE.SUCCESS) {\n return 'alert alert-dismissible alert-success';\n }\n return 'alert alert-dismissible alert-success';\n }\n\n /** Marks the message as dismissed so it is filtered out of the next emission. Prefer {@link DataMessageService.ack}, which also refreshes the stream. */\n public ack(): void {\n this.status = STATUS[STATUS.ACK];\n }\n}\n\n/**\n * The library's user-notification channel.\n *\n * Library components push through it — `dispedit` reports auto-save outcomes, `flags`\n * and `sdelete` report their results, and {@link AuthServiceBase} warns when a session\n * expires — and `<data-message-zone>` is what renders them. **The two go together: if\n * you use dispedit's auto-save (or anything else that reports through this service)\n * without placing a `<data-message-zone>` somewhere in the layout, errors are collected\n * and silently discarded, and users see failed saves as nothing at all.**\n *\n * Messages expire on their own via a 500 ms ticker that runs outside the Angular zone,\n * re-entering it only when something actually changes.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DataMessageService {\n public ngZone = inject(NgZone);\n public sounds = inject(DATA_MESSAGE_SOUNDS, { optional: true });\n public _messages$: ReplaySubject<Message[]> = new ReplaySubject<Message[]>(1);\n private _messages: Message[] = [];\n private _timer!: Observable<number>;\n private _subscription!: Subscription;\n\n constructor() {\n this.init();\n }\n\n /**\n * The live list of messages to display, re-emitted whenever one is added, dismissed\n * or expires. Subscribed to by {@link MessageZoneComponent}; replays the latest list\n * to late subscribers.\n */\n public get current(): Observable<Message[]> {\n return this._messages$.asObservable();\n }\n\n /**\n * Starts the expiry ticker. Called from the constructor and idempotent, so there is\n * normally no reason to call it — except to restart the service after {@link close}.\n */\n public init(): void {\n let changed = false;\n if (!this._timer) {\n this.ngZone.runOutsideAngular(() => {\n this._timer = timer(500, 500);\n this._subscription = this._timer.subscribe(() => {\n for (const m of this._messages) {\n m.ttl -= 500;\n if (m.ttl <= 0) {\n changed = true;\n }\n }\n if (changed) {\n this.ngZone.run(() => {\n const out: Message[] = [];\n for (const m of this._messages) {\n if (m.ttl >= 0) {\n out.push(m);\n }\n }\n this._messages = out;\n this._notify();\n });\n }\n });\n });\n }\n }\n\n /**\n * Stops the expiry ticker, freezing any displayed message in place. Mostly useful in\n * tests; the internal timer field is kept, so {@link init} will not restart it.\n */\n public close(): void {\n this._subscription.unsubscribe();\n }\n\n /** Reports a completed operation. Short-lived by default (3 s) and plays the `success` sound if configured. */\n public success(title: string, message = '', trace: unknown = null, timeout: number = DEFAULT_TIMEOUTS.SUCCESS): void {\n this._messages.push(new Message(title, TYPE.SUCCESS, message, trace, timeout));\n this.play('success');\n this._notify();\n }\n\n /** Reports neutral information the user does not have to act on. Defaults to a 4 s lifetime. */\n public info(title: string, message = '', trace: unknown = null, timeout: number = DEFAULT_TIMEOUTS.INFO): void {\n this._messages.push(new Message(title, TYPE.INFO, message, trace, timeout));\n this.play('info');\n this._notify();\n }\n\n /** Reports a problem the user should notice but that did not abort the operation. Stays 10 s by default. */\n public warning(title: string, message = '', trace: unknown = null, timeout: number = DEFAULT_TIMEOUTS.WARNING): void {\n this._messages.push(new Message(title, TYPE.WARNING, message, trace, timeout));\n this.play('warning');\n this._notify();\n }\n\n /**\n * Reports a failure, with the longest lifetime (30 s) and the `error` sound.\n *\n * Note that the `timeout` argument is currently ignored: the message is always created\n * with {@link DEFAULT_TIMEOUTS.DANGER}.\n */\n public danger(title: string, message = '', trace: unknown = null, timeout: number = DEFAULT_TIMEOUTS.DANGER): void {\n this._messages.push(new Message(title, TYPE.DANGER, message, trace, timeout));\n this.play('error');\n this._notify();\n }\n\n /** Alias for {@link danger}, for callers that think in terms of \"error\" rather than severity. */\n public error(title: string, message = '', trace: unknown = null): void {\n this.danger(title, message, trace);\n }\n\n /** Logs to the console only — nothing is shown to the user and no message is queued. */\n public debug(title: string, message = '', trace: unknown = null): void {\n console.log(title, message, trace);\n }\n\n /**\n * Dismisses a message on the user's behalf and immediately re-emits the list, so the\n * message zone drops it without waiting for its ttl. Bound to the close button of\n * `<data-message-zone>`.\n */\n public ack(message: Message): void {\n message.ack();\n this._notify();\n }\n\n /**\n * Plays the sound registered under `type` in {@link DATA_MESSAGE_SOUNDS}, and does\n * nothing when the token or the key is absent. Called automatically by the severity\n * methods; call it directly only for custom cues.\n */\n public play(type = 'notify') {\n if (this.sounds && this.sounds[type]) {\n const audio = new Audio(this.sounds[type]);\n // Rejects whenever the browser's autoplay policy blocks the sound\n // (no user gesture yet). A missing notification cue is not worth\n // surfacing, but the rejection must be handled all the same.\n audio.play().catch(() => undefined);\n }\n }\n\n private _notify(): void {\n const out: Message[] = [];\n for (const message of this._messages) {\n if (message.status === STATUS[STATUS.UNDISP] || message.status === STATUS[STATUS.DISP]) {\n message.status = STATUS[STATUS.DISP];\n out.push(message);\n }\n }\n this._messages$.next(out);\n }\n}\n","import { inject, Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\n/**\n * Marks HTML as trusted, so `[innerHTML]` renders it as-is.\n *\n * Meant for the rendered half of a rich text field — the `<field>_html` column\n * the server produces from the markdown or HTML source. Angular's sanitizer\n * builds its allow-list from `URI_ATTRS + HTML_ATTRS + ARIA_ATTRS`, and `style`\n * is in none of them, so a plain `[innerHTML]` silently drops every\n * `text-align` and every colour `<data-richedit>` writes: read-only mode ends\n * up looking nothing like the editor.\n *\n * **Only use it on HTML the server produced.** The value is inserted without\n * any filtering, and trusted HTML executes scripts — pointing this at a string\n * a user of another system can influence is an XSS vector.\n *\n * @example\n * ```html\n * <div [innerHTML]=\"product.description_html | safeHtml\"></div>\n * ```\n */\n@Pipe({\n name: 'safeHtml',\n})\nexport class SafeHtmlPipe implements PipeTransform {\n private _sanitizer = inject(DomSanitizer);\n\n /**\n * @param value HTML to trust; null for a nullish or empty input, which\n * `[innerHTML]` renders as nothing.\n */\n transform(value: string | null | undefined): SafeHtml | null {\n if (!value) {\n return null;\n }\n return this._sanitizer.bypassSecurityTrustHtml(value);\n }\n}\n","import { Component, DestroyRef, inject, input, model, OnInit, output } from '@angular/core';\nimport { fieldValues } from '../../data/field-values';\nimport { FilterData, Queryset } from '../../data/data-query';\nimport { Collection } from '../../data/data-collection';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule, UntypedFormControl } from '@angular/forms';\nimport { debounceTime, distinctUntilChanged, firstValueFrom, Observable } from 'rxjs';\nimport { TplFun } from '../fkselect/fkselect.component';\nimport { DataModel } from '../../data/data-model';\nimport { uniqueId } from '../../utils/unique-id';\nimport { switchMap } from 'rxjs/operators';\n\nimport { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-m2mselect',\n templateUrl: './m2mselect.component.html',\n styleUrls: ['./m2mselect.component.sass'],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: M2mselectComponent,\n },\n ],\n imports: [ReactiveFormsModule, NgbTypeaheadModule],\n})\n/**\n * Typeahead for picking several related instances (a many-to-many target).\n *\n * The FK counterpart of {@link FkselectComponent}, but implemented as a\n * `ControlValueAccessor`: its form value is the array of selected primary keys,\n * while the resolved instances are kept alongside for display. This is the\n * editor {@link DispeditComponent} renders for a `ManyToManyFieldManager`.\n *\n * On init, if no `[values]` are supplied, the initial selection is read from\n * the model's `<field>_details` sibling property (built by string\n * concatenation). When that property is missing the selection simply starts\n * empty — which is the normal case for an unsaved model, as rendered by a\n * creation form. On a model that has an `id`, a missing `_details` is instead a\n * configuration problem (field left out of the request's `fields=`, or a\n * misspelled `[field]`) and is reported with a `console.warn`. A queryset, on\n * the other hand, is mandatory — supplied directly, derived from\n * `[collection]`, or from the model's `_collection`.\n *\n * Options are labelled via each target's `_display` (getter or method), falling\n * back to `[display]`, then `name` / `title` / `id`.\n */\nexport class M2mselectComponent<T extends DataModel, R extends DataModel> implements OnInit, ControlValueAccessor {\n /** Source model. Provides the `<field>_details` seed and a fallback collection. */\n public model = input<T>();\n /** Field name on the source model, used to find `<field>_details`. */\n public field = input<string>();\n /** Whether the control is in edit mode. */\n public edit = input<boolean>(false);\n /** Currently selected instances, kept in sync with {@link pks}. */\n public values = model<R[]>();\n /** Primary keys of the selection; this is the control's form value. */\n public pks: number[] = [];\n /** Whether editing is blocked, set through `setDisabledState`. */\n public disabled = false;\n /**\n * Queryset searched for candidates. Derived on init from `[collection]` or\n * the model's `_collection`; the component throws if none can be resolved.\n */\n public queryset = model<Queryset<R>>();\n /**\n * Collection candidates are queried from, and used to fetch instances for\n * primary keys written in through `writeValue` that aren't already known.\n */\n public collection = model<Collection<R>>();\n /** Extra filter merged into every search request, to narrow the lookup. */\n public filter = input<FilterData>({});\n /** Presentation hint for the control. */\n public mode = input<'autocomplete' | 'select' | 'auto'>('auto');\n /** Option label: a property name, or a function. Only used without `_display`. */\n public display = input<string | TplFun<R>>();\n /** Query parameter name the search term is sent under. Defaults to `search`. */\n public search = input<string>('search');\n /** Label shown next to the control. */\n public label = input<string>('');\n /**\n * Id put on the search input, and pointed at by `[label]`'s `for`. Defaults\n * to a generated one; dispedit passes its own so its label drives this input.\n */\n public inputId = input<string>(uniqueId('data-m2mselect'));\n /** Placeholder for the search input. */\n public placeholder = input<string>('');\n /** Text shown when nothing is selected. */\n public emptyLabel = input<string>('');\n /** CSS classes applied to the search input. */\n public inputClasses = input<string[] | string>([]);\n /** Emits the instance just added to the selection. */\n public added = output<R>();\n /** Emits the instance just removed from the selection. */\n public removed = output<R>();\n /** Emits when the user aborts editing. */\n public cancelled = output<void>();\n /** Emits when the whole selection is cleared. */\n public cleared = output<void>();\n /** Emits the full list of selected instances whenever it changes. */\n public detailsChanged = output<R[]>();\n /** Emits the selected primary keys whenever they change. */\n public changed = output<number[]>();\n\n /** Form control backing the typeahead search input. */\n public fc!: UntypedFormControl;\n /** Search callback handed to ng-bootstrap's typeahead. */\n public searchFn = this._search.bind(this);\n /** Option formatter handed to ng-bootstrap's typeahead. */\n public displayFn = this._display.bind(this);\n private touched = false;\n private _tpl!: TplFun<R>;\n private destroy$ = inject(DestroyRef);\n /**\n * Control value accessor onChange dummy callback;\n * @param _fks\n */\n public onChange = (_fks: number[]) => {\n // Replaced by registerOnChange when used inside a form.\n };\n\n /**\n * Control value accessor onTouched dummy callback;\n */\n public onTouched = () => {\n // Replaced by registerOnTouched when used inside a form.\n };\n\n /**\n * OnChange register from controlValueAccessor\n * @param onChange callback\n */\n registerOnChange(onChange: (fks: number[]) => void) {\n this.onChange = onChange;\n }\n\n /**\n * OnTouched register from controlValueAccessor\n * @param onTouched callback\n */\n registerOnTouched(onTouched: () => void) {\n this.onTouched = onTouched;\n }\n\n /**\n * OnInit :\n * - ensures queryset is available\n * - creates form control for input\n * - creates display function\n * - ensure values are set from whichever source is available\n */\n public ngOnInit(): void {\n // Create queryset if not given\n // queryset is created through model\n const model = this.model();\n if (!this.queryset() && this.collection()) {\n this.queryset.set(this.collection()!.queryset());\n } else if (!this.queryset() && model && model._collection) {\n // Fallback: the source model's own collection, assumed to hold the\n // related instances. Nothing can check that assumption.\n const coll = model._collection as unknown as Collection<R>;\n this.collection.set(coll);\n this.queryset.set(coll.queryset());\n }\n if (!this.queryset()) {\n throw Error('queryset is mandatory for m2m select');\n }\n // Create form control for typeahead and subscribe for changes\n this.fc = new UntypedFormControl('');\n this.fc.valueChanges.pipe(takeUntilDestroyed(this.destroy$), distinctUntilChanged()).subscribe((value: R | '') => {\n if (value) {\n this.onAdd(value);\n }\n });\n // Set display function\n const display = this.display();\n if (display) {\n if (typeof display === 'string') {\n this._tpl = (m: R) => `${String(fieldValues(m)[display])}`;\n } else if (typeof display === 'function') {\n this._tpl = display.bind(this);\n }\n } else {\n this._tpl = (m: R) => {\n const v = fieldValues(m);\n return `${String(v['name'] ?? v['title'] ?? v['id'])}`;\n };\n }\n // Get values from model if not already given\n const field = this.field();\n if (this.values() === undefined && model && field) {\n const details = fieldValues(model)[`${field}_details`] as R[] | undefined;\n if (details === undefined && model.id !== undefined) {\n // The model comes from the API but carries no details for this\n // relation: either the field was left out of the request's `fields=`,\n // or `[field]` doesn't match the model's. Worth reporting, but not\n // worth breaking the display for — the selection just starts empty.\n console.warn(\n `m2mselect: no \"${field}_details\" on the model, starting with an ` +\n `empty selection. Check that \"${field}\" is requested in the ` +\n `fields= of the query, and that [field] is spelled correctly.`,\n model,\n );\n }\n this.values.set(details ?? []);\n }\n // No model or field given, or an unsaved model (creation form): the\n // details sibling cannot exist yet, an empty selection is expected.\n if (this.values() === undefined) {\n this.values.set([]);\n }\n }\n\n /**\n * Remove a value.\n * Emits detailsChanged, changed and removed signals.\n * @param i instance to be removed\n */\n public onRemove(i: R) {\n if (!this.disabled) {\n this.markAsTouched();\n const ps = this.pks.indexOf(i.id);\n this.pks.splice(ps, 1);\n this.values.set(this.values()!.filter((_, idx) => idx !== ps));\n this.detailsChanged.emit(this.values()!);\n this.changed.emit(this.pks);\n this.removed.emit(i);\n this.onChange(this.pks);\n }\n }\n\n /**\n * Add a value.\n * Emits detailsChanged, changed and added signals.\n * @param i instance to be added.\n */\n public onAdd(i: R) {\n if (!this.disabled) {\n this.markAsTouched();\n this.pks.push(i.id);\n this.values.set([...this.values()!, i]);\n this.detailsChanged.emit(this.values()!);\n this.changed.emit(this.pks);\n this.added.emit(i);\n this.onChange(this.pks);\n }\n }\n\n /**\n * Clear all values.\n * Emits detailsChanged, changed and cleared signals.\n */\n public onClear() {\n if (!this.disabled) {\n this.markAsTouched();\n this.pks = [];\n this.values.set([]);\n this.detailsChanged.emit(this.values()!);\n this.changed.emit(this.pks);\n this.cleared.emit();\n this.onChange(this.pks);\n }\n }\n\n /**\n * Write value from controlValueAccessor.\n * @param pks\n */\n async writeValue(pks: number[]) {\n this.pks = pks;\n await this._getDisplayValues(pks);\n }\n\n /**\n * Mark as touched.\n */\n public markAsTouched() {\n if (!this.touched) {\n this.onTouched();\n this.touched = true;\n }\n }\n\n /**\n * Mark as disabled.\n * @param disabled\n */\n setDisabledState(disabled: boolean) {\n this.disabled = disabled;\n }\n\n /**\n * Retrieve display values for current set of pks.\n * Eventually fetches items from collection.\n * Emits detailsChanged signal.\n * @param pks list of current pks.\n * @private\n */\n private async _getDisplayValues(pks: number[] = []) {\n const values: R[] = [];\n for (const k of pks) {\n let found = false;\n for (const v of this.values() ?? []) {\n if (v.id == k) {\n values.push(v);\n found = true;\n break;\n }\n }\n if (!found) {\n const collection = this.collection();\n if (collection) {\n values.push(await firstValueFrom(collection.fetch(k)));\n } else {\n values.push({ id: k, _display: 'Unknown' } as unknown as R);\n }\n }\n }\n this.values.set(values);\n this.detailsChanged.emit(values);\n }\n\n /**\n * Display function. Uses descfield or desc tpl (lodash template using model fields).\n */\n private _display(x: R | null | undefined): string {\n if (x) {\n const display = (x as { _display?: string | (() => string) })._display;\n if (display) {\n return typeof display === 'function' ? display() : display;\n }\n if (this._tpl) {\n return this._tpl(x);\n }\n }\n return '';\n }\n\n /**\n * Search function.\n * @param text$\n * @private\n */\n private _search(text$: Observable<string>): Observable<R[]> {\n return text$.pipe(\n takeUntilDestroyed(this.destroy$),\n debounceTime(750),\n distinctUntilChanged(),\n switchMap((term) => {\n const f: FilterData = {};\n const filter = this.filter();\n for (const k of Object.keys(filter)) {\n if (filter[k] !== null || filter[k] !== undefined) {\n f[k] = filter[k];\n }\n }\n f[this.search()] = term;\n const qs = this.queryset()!;\n qs.filter(f, true);\n return qs.get();\n }),\n );\n }\n}\n","<div class=\"form-group\">\n @if (label()) {\n <label [attr.for]=\"inputId()\">{{ label() }}</label>\n }\n <div class=\"input-group\">\n <input\n [attr.id]=\"inputId()\"\n class=\"form-control\"\n [formControl]=\"fc\"\n [placeholder]=\"placeholder()\"\n [ngbTypeahead]=\"searchFn\"\n [editable]=\"false\"\n [focusFirst]=\"true\"\n [inputFormatter]=\"displayFn\"\n [resultFormatter]=\"displayFn\"\n (keyup.escape)=\"cancelled.emit()\"\n />\n <div class=\"input-group-text\">\n <i\n class=\"bi bi-trash float-end pointer\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Vider la sélection\"\n (click)=\"cleared.emit()\"\n (keydown.enter)=\"cleared.emit()\"\n (keydown.space)=\"$event.preventDefault(); cleared.emit()\"\n ></i>\n </div>\n </div>\n @for (i of values(); track i) {\n <div>\n <i\n class=\"bi bi-trash ms-2 float-end\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer ' + displayFn(i)\"\n (click)=\"onRemove(i)\"\n (keydown.enter)=\"onRemove(i)\"\n (keydown.space)=\"$event.preventDefault(); onRemove(i)\"\n ></i>\n {{ displayFn(i) }}\n </div>\n }\n</div>\n","import { Component, DestroyRef, effect, inject, input, model, output, signal, untracked } from '@angular/core';\nimport { fieldValues, asText } from '../../data/field-values';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { DataModel } from '../../data/data-model';\nimport { uniqueId } from '../../utils/unique-id';\nimport { BaseFieldManager } from '../../data/fields/base';\nimport { ReactiveFormsModule, UntypedFormControl, UntypedFormGroup } from '@angular/forms';\nimport { firstValueFrom } from 'rxjs';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES, IDispEditChoice } from './dispedit.constants';\nimport { FilterData, Queryset } from '../../data/data-query';\nimport { Collection } from '../../data/data-collection';\nimport { FkselectComponent, TplFun } from '../fkselect/fkselect.component';\nimport { DecimalFieldManager } from '../../data/fields/numbers';\nimport { BootstrapDataDisplayConfig, DATA_DISPLAY_CONFIG, DataDisplayConfig } from '../../data/data-parameters';\nimport { DataMessageService } from '../../messages/message.service';\nimport { DatePipe, NgTemplateOutlet } from '@angular/common';\nimport { SafeHtmlPipe } from '../../editors/safe-html.pipe';\nimport { M2mselectComponent } from '../m2mselect/m2mselect.component';\n\n@Component({\n selector: 'data-dispedit',\n templateUrl: './dispedit.component.html',\n styleUrls: ['./dispedit.component.sass'],\n imports: [DatePipe, NgTemplateOutlet, ReactiveFormsModule, FkselectComponent, M2mselectComponent, SafeHtmlPipe],\n})\n/**\n * Displays and edits a single model field, choosing its own widgets from the\n * model's field metadata.\n *\n * This is the library's flagship component. You do not tell it what to render:\n * it asks the model for the field's manager (`model.FM(field)`) and takes the\n * manager's `editorType` and `displayType`. A `ForeignKeyFieldManager` yields\n * `fkselect` / `fkdetails`, a `ManyToManyFieldManager` yields `m2mselect` /\n * `m2mdetails`, a `charField` declared with `choices` yields a `select`, a\n * `decimalField` yields `input.decimal` / `decimal`, and so on. Declare the\n * model well and the UI follows; `[editor]` and `[viewer]` are escape hatches\n * for the cases where it does not.\n *\n * ## Modes\n *\n * - `mode=\"dd\"` renders a `<dt>`/`<dd>` block that flips to an editor in place\n * when clicked and **saves to the API itself** on validation. This is the\n * workhorse and accounts for the vast majority of real usage.\n * - `mode=\"inline\"` / `mode=\"form\"` render a bare form control and **do not\n * save**. They expect an external `[form]` {@link UntypedFormGroup} and an\n * outer submit to persist the value. (`'inline'` is pending a rename to\n * `'form'`; both are currently accepted and differ only in whether the local\n * form group or the external one drives the template.)\n *\n * Note the input default is `'inline'`, so `mode=\"dd\"` must be set explicitly\n * to get the auto-saving dt/dd behaviour.\n *\n * ## The `<field>_details` contract\n *\n * For FK and M2M fields, the component reads and writes a sibling property\n * whose name is built by string concatenation: `` `${field()}_details` ``. A\n * `category` foreign key therefore **requires** a `category_details` property\n * on the model holding the resolved target instance (or, for M2M, the array of\n * instances). Nothing type-checks this: rename the FK without renaming the\n * sibling and both the display and the write-back break silently at runtime.\n *\n * ## Decimal factor\n *\n * `decimalField.factor` is applied *here*, not in the model. The model property\n * holds the raw wire value; this component divides by `factor` when loading it\n * into the editor and multiplies back (rounded) when saving. With\n * `factor: 100`, `model.price` is in cents and the user sees `12.34`.\n *\n * @example\n * ```html\n * <!-- Scalar field: click to edit, saves itself -->\n * <data-dispedit [model]=\"thing\" field=\"name\" mode=\"dd\">Name</data-dispedit>\n * ```\n *\n * @example\n * ```html\n * <!-- Foreign key: [collection] is what the dropdown queries.\n * Requires a `category_details` property on `thing`. -->\n * <data-dispedit\n * [model]=\"thing\"\n * field=\"category\"\n * mode=\"dd\"\n * [collection]=\"categories\"\n * [filter]=\"{fields: ['id', 'name'].join(',')}\"\n * >Category</data-dispedit>\n * ```\n */\nexport class DispeditComponent<FT, T extends DataModel, R extends DataModel> {\n /** Model instance holding the field. Mandatory. */\n public model = input.required<T>();\n /**\n * Name of the field to display / edit. Mandatory.\n *\n * Used to look up the field manager, to read and write the model property,\n * and to name the form control. For FK and M2M fields it also determines the\n * `<field>_details` sibling property the component reads the display value\n * from and writes the selected instance back to — that property must exist on\n * the model, and nothing checks it at compile time.\n */\n public field = input.required<string>();\n\n /** Id tying the label to whichever control the editor renders. */\n public readonly inputId = uniqueId('data-dispedit');\n /**\n * External form group, for `inline` / `form` modes.\n *\n * When provided, the component adds its control to this group instead of\n * creating a standalone one, and leaves persistence to the outer submit.\n */\n public form = input<UntypedFormGroup>();\n /**\n * Whether the editor is currently shown. Two-way bindable.\n *\n * Mutated internally by {@link toggleEdit}, {@link enableEditMode} and\n * {@link enableDisplayMode}. In `inline` mode with `editable` true, the\n * editor is always shown.\n */\n public edit = model<boolean>(false);\n /**\n * Whether the field can be switched to edit mode at all.\n *\n * When false, {@link enableEditMode} returns immediately and the field stays\n * read-only. Defaults to true.\n */\n public editable = input<boolean>(true);\n /**\n * Whether {@link update} persists to the API.\n *\n * This is **not** a template-bindable input — it is a plain class property,\n * so `[save]=\"false\"` will not compile against it. It is set internally\n * during recompute: true when `mode` is `dd`, false otherwise. Control saving\n * through {@link mode} instead.\n */\n public save?: boolean;\n /**\n * Layout and save behaviour.\n *\n * - `dd`: display / edit inside a `<dt>`/`<dd>` block, saving to the API on\n * validation.\n * - `inline` (to be renamed to `form`): an optional label plus a form\n * control, no saving.\n * - `form`: same, driven by the external `[form]` group.\n */\n public mode = input<'dd' | 'inline' | 'form'>('inline');\n /**\n * Explicit choices, overriding any declared on the field manager.\n *\n * As soon as any choices are resolved, the editor becomes `select` and the\n * display becomes `choice`, whatever the manager advertises.\n */\n public choices = input<IDispEditChoice[]>([]);\n /**\n * CSS classes applied to the editor input.\n *\n * Left unset, it is filled in from the display config's per-editor defaults\n * (bootstrap 5 by default). Writable so that fallback can be stored back.\n */\n public inputClasses = model<string[] | string>();\n /** Forces an editor widget, bypassing the field manager's `editorType`. */\n public editor = input<DISPEDIT_EDITOR_TYPES>();\n /**\n * Forces a display renderer, bypassing the field manager's `displayType`.\n *\n * Writable so that cross-input consistency rules can settle on a renderer;\n * see {@link _checks}.\n */\n public viewer = model<DISPEDIT_DISPLAY_TYPES>();\n /**\n * Value applied by {@link setDefault} when the user clears the field.\n *\n * The reset control only appears in edit mode when this is not undefined.\n */\n public default = input<unknown>();\n /** Input placeholder. Falls back to the field manager's `description`. */\n public placeholder = input<string>('');\n /** Help text shown under the editor. Falls back to the manager's `help`. */\n public help = input<string>('');\n /** Suppresses the `<dt>` / `<label>`, keeping only the value or control. */\n public hideLabel = input<boolean>(false);\n\n // FK fields\n // TODO: rename as fk_ or related_\n /**\n * Queryset used to search FK / M2M candidates.\n *\n * Usually left unset: passing `[collection]` is the normal route, and the\n * child select derives a queryset from it.\n */\n public queryset = input<Queryset<R>>();\n /**\n * Collection the FK / M2M dropdown queries for candidates.\n *\n * This is what makes an FK or M2M editor work at all — without it the\n * dropdown has nothing to search.\n */\n public collection = input<Collection<R>>();\n /**\n * How to label each FK / M2M option: a property name, or a function of the\n * target instance.\n *\n * Only consulted when the target has no `_display`. Models used as FK targets\n * should define `_display` (a getter or a method — both are accepted) and\n * then this input is unnecessary. Without either, the fallback tries `name`,\n * then `title`, then `id`.\n */\n public display = input<string | TplFun<R>>();\n /**\n * Filter narrowing the FK / M2M lookup.\n *\n * Merged into every search request. The idiom\n * `[filter]=\"{fields: ['id','name'].join(',')}\"` trims the response payload\n * to the fields actually needed to render the options.\n */\n public filter = input<FilterData>({});\n\n /** Emits the model after every successful save. */\n public changed = output<T>();\n\n /** Field manager resolved from the model for {@link field}. */\n public manager = signal<BaseFieldManager<FT> | undefined>(undefined);\n\n /** Rendered text for single-valued displays. */\n public txtValue = signal<string | undefined>(undefined);\n /** Rendered text, one entry per item, for `m2mdetails` displays. */\n public txtValues = signal<string[] | undefined>(undefined);\n\n /** Editor actually in use, after manager lookup and overrides. */\n public realEditor = signal<DISPEDIT_EDITOR_TYPES>('input.text');\n /** Display renderer actually in use, after manager lookup and overrides. */\n public realDisplay = signal<DISPEDIT_DISPLAY_TYPES>('text');\n /** Raw field value backing the current display, before formatting. */\n public dispValue = signal<unknown>(undefined);\n /** Choices actually in use, or undefined when the field has none. */\n public realChoices = signal<IDispEditChoice[] | undefined>([]);\n /** Help text actually shown, after the manager fallback. */\n public realHelp = signal<string>('');\n /** Placeholder actually shown, after the manager fallback. */\n public realPlaceholder = signal<string>('');\n /** Whether the manager declares the field required. */\n public required = signal<boolean>(false);\n /** Default value actually applied by {@link setDefault}. */\n public realDefault = signal<unknown>(undefined);\n\n /** Latest M2M instances reported by the child select, used for display. */\n public m2mValues?: DataModel[];\n\n /** Form group driving the editor: the external `[form]`, or a local one. */\n public fg = signal<UntypedFormGroup | undefined>(undefined);\n\n /** Resolved display function for FK / M2M options, built from `display`. */\n private _tpl!: TplFun<R>;\n\n private _destroyRef = inject(DestroyRef);\n\n /**\n * Display config, overridable via the DATA_DISPLAY_CONFIG injection token.\n * By default, bs5 config is used.\n */\n public dconf = inject<DataDisplayConfig>(DATA_DISPLAY_CONFIG, { optional: true }) ?? BootstrapDataDisplayConfig;\n private _msgs = inject(DataMessageService);\n\n /**\n * Recompute all derived values / edit mode on any (trigger) input change.\n *\n * Only the read-only inputs are tracked here: the internally-mutated\n * `edit` / `viewer` / `inputClasses` models and the computed display\n * signals are read/written inside the recompute (via `untracked`) so their\n * internal writes don't re-trigger this effect (which would recreate the\n * form control on every write).\n */\n private _recomputeEffect = effect(() => {\n // Trigger inputs (establish reactive dependencies)\n this.model();\n this.field();\n this.form();\n this.editable();\n this.mode();\n this.choices();\n this.editor();\n this.default();\n this.placeholder();\n this.help();\n this.queryset();\n this.collection();\n this.display();\n this.filter();\n untracked(() => this._recompute());\n });\n\n /**\n * Upgrade all values on any change.\n * - Sets display function\n * - Loads manager\n * - Runs misc checks on special values\n * - Gets help, placeholder strings\n * - Enables display or edit mode\n */\n private _recompute(): void {\n this._setDisplayFn();\n this.manager.set(this.model()?.FM(this.field()));\n this.required.set(this.manager()?.required || false);\n this._checks();\n this.realHelp.set(this.help() || this.manager()?.help || '');\n this.realPlaceholder.set(this.placeholder() || this.manager()?.description || '');\n this.realDefault.set(this.default());\n this.save = this.save === undefined ? this.mode() === 'dd' : this.save;\n if ((!this.edit() && this.mode() === 'dd') || (!this.editable() && this.mode() === 'inline')) {\n this.enableDisplayMode();\n } else {\n this.enableEditMode();\n }\n }\n\n /**\n * Set up display mode.\n * - get choices if available\n * - get display type\n * - process current value for display\n * - set display classes\n */\n public enableDisplayMode() {\n this._getChoices();\n this._getRealDisplay();\n this._getDisplayValue();\n this._setDisplayClasses();\n this.edit.set(false);\n }\n\n /**\n * Set up edit mode :\n * - get choices if available\n * - get editor type\n * - prepare form controle\n * - set form control value\n * - update form control classes\n */\n public enableEditMode() {\n if (!this.editable()) {\n return;\n }\n this._getChoices();\n this._getRealEditor();\n this._setFormControl();\n this._setFormControlValue();\n this._setEditorClasses();\n this.edit.set(true);\n }\n\n /**\n * Write the form control value back to the model field, then save if\n * {@link save} is true (i.e. in `dd` mode).\n *\n * Does nothing when the control is invalid. For `input.decimal` editors the\n * value is multiplied by the manager's `factor` and rounded, restoring the\n * raw wire representation the model property is expected to hold.\n */\n public async update(): Promise<void> {\n const model = this.model();\n const fg = this.fg();\n if (fg && model && fg.valid) {\n switch (this.realEditor()) {\n case 'input.decimal':\n fieldValues(model)[this.field()] = Math.round(\n (fg.value as Record<string, number>)[this.field()] *\n ((this.manager() as unknown as DecimalFieldManager).factor || 1),\n );\n break;\n default:\n fieldValues(model)[this.field()] = fieldValues(fg.value as object)[this.field()];\n }\n if (this.save === true) {\n return this._save();\n }\n }\n }\n\n /**\n * Leave edit mode and drop the local form group, in `dd` mode only.\n *\n * Bound to the escape key in the editor templates; in other modes the editor\n * is permanent and the call is a no-op.\n */\n unsetEdit() {\n if (this.mode() == 'dd' && this.edit()) {\n this.edit.set(false);\n this.fg.set(undefined);\n }\n }\n\n /** Switch between display and edit mode. Bound to the `<dt>` label click. */\n toggleEdit() {\n if (!this.edit()) {\n this.enableEditMode();\n } else {\n this.unsetEdit();\n this.enableDisplayMode();\n }\n }\n\n /**\n * Reset the field to {@link default}, updating both the model and the form\n * control, then run {@link update} (which saves in `dd` mode).\n *\n * Bound to the trash icon shown next to the label in edit mode.\n * TODO: check if edit mode needs to be changed / saved\n */\n public async setDefault(): Promise<void> {\n const model = this.model();\n if (model) {\n fieldValues(model)[this.field()] = this.realDefault();\n this.fg()!.controls[this.field()].setValue(this.realDefault(), {\n emitEvent: false,\n });\n }\n await this.update();\n }\n\n /**\n * Handle an FK pick from the child `<data-fkselect>`, then save immediately.\n *\n * Writes the id to the model field and the whole instance to the\n * `<field>_details` sibling property, so the display has something to render\n * without refetching. A null event (the clear action) nulls the field and\n * deletes the sibling. When an external `[form]` is bound it is patched and\n * marked touched/dirty too. Note this saves regardless of {@link save}.\n *\n * @param $event selected instance, or null when the selection was cleared.\n */\n public async selectedRefItem($event: R | null) {\n const model = this.model();\n const form = this.form();\n if (model) {\n if ($event !== null) {\n fieldValues(model)[this.field()] = $event.id;\n fieldValues(model)[`${this.field()}_details`] = $event;\n if (form) {\n const fv: Record<string, number | null> = {};\n fv[this.field()] = $event.id;\n form.patchValue(fv, { emitEvent: true });\n form.markAsTouched();\n form.markAsDirty();\n }\n } else {\n fieldValues(model)[this.field()] = null;\n delete fieldValues(model)[`${this.field()}_details`];\n if (form) {\n const fv: Record<string, number | null> = {};\n fv[this.field()] = null;\n form.patchValue(fv, { emitEvent: true });\n form.markAsTouched();\n form.markAsDirty();\n }\n }\n return this._save();\n }\n }\n\n /**\n * Cache the M2M instances reported by the child select.\n *\n * These take precedence over `<field>_details` when building the\n * `m2mdetails` display, so it reflects edits made in the current session.\n *\n * @param v current list of selected instances.\n */\n public onM2MValuesChanges(v: DataModel[]) {\n this.m2mValues = v;\n }\n\n /**\n * Apply cross-input consistency rules.\n *\n * Nothing to reconcile at the moment: the one rule that lived here paired the\n * `quill` editor with the `quill` viewer, and neither exists any more. Kept\n * as the place such rules belong, since `_init` already calls it.\n */\n private _checks() {\n // No rules currently.\n }\n\n /**\n * Save value to database, only if model have an id.\n * If mode is dd, toggle edit / display mode.\n * @private\n */\n private async _save(): Promise<void> {\n const model = this.model();\n if (model) {\n if (model.id) {\n try {\n await firstValueFrom(model.update([this.field()], { updateModel: true }));\n } catch (e) {\n console.error(e);\n let msg = '';\n const apiErrors = (e as { error?: Record<string, unknown> } | null)?.error;\n if (apiErrors?.[this.field()]) {\n msg = `${String(apiErrors[this.field()])}`;\n }\n this._msgs.error(\"Erreur lors de l'enregistrement\", msg, JSON.stringify(e));\n return;\n }\n }\n if (this.mode() === 'dd') {\n this.unsetEdit();\n this.enableDisplayMode();\n }\n this.changed.emit(model);\n }\n }\n\n private _display(x: unknown): string {\n if (x) {\n const display = (x as { _display?: string | (() => string) })._display;\n if (display) {\n return typeof display === 'function' ? display() : display;\n }\n if (this._tpl) {\n return this._tpl(x as R);\n }\n }\n return '';\n }\n\n private _setDisplayFn() {\n const display = this.display();\n if (display) {\n if (typeof display === 'string') {\n this._tpl = (model: R) => String(fieldValues(model)[display]);\n } else if (typeof display === 'function') {\n this._tpl = display.bind(this);\n }\n } else {\n this._tpl = (model: R) =>\n String(fieldValues(model)['name'] ?? fieldValues(model)['title'] ?? fieldValues(model)['id']);\n }\n }\n\n private _getChoices() {\n // Set display choices\n let choices: IDispEditChoice[] | undefined;\n const inputChoices = this.choices();\n if (inputChoices && inputChoices.length) {\n choices = inputChoices;\n } else {\n const managerChoices = (this.manager() as { choices?: IDispEditChoice[] } | undefined)?.choices;\n if (managerChoices) {\n choices = managerChoices;\n }\n }\n // Set display value\n if (choices && choices.length > 0) {\n this.realChoices.set(choices);\n } else {\n this.realChoices.set(undefined);\n }\n }\n\n private _getRealDisplay() {\n const viewer = this.viewer();\n const manager = this.manager();\n const realChoices = this.realChoices();\n this.realDisplay.set(viewer ? viewer : manager?.displayType ? manager.displayType : 'text');\n if (realChoices && realChoices.length) {\n this.realDisplay.set('choice');\n }\n }\n\n private _getRealEditor() {\n const editor = this.editor();\n const realChoices = this.realChoices();\n this.realEditor.set(editor ? editor : this.manager()?.editorType || 'input.text');\n if (realChoices && realChoices.length) {\n this.realEditor.set('select');\n }\n }\n\n private _setFormControl() {\n const model = this.model();\n const form = this.form();\n let fg: UntypedFormGroup;\n if (!form) {\n const fgc: Record<string, UntypedFormControl> = {};\n fgc[this.field()] = model.FC(this.field());\n fg = new UntypedFormGroup(fgc);\n } else {\n fg = form;\n fg.setControl(this.field(), model.FC(this.field()), {\n emitEvent: false,\n });\n }\n this.fg.set(fg);\n if (this.mode() === 'inline') {\n fg.valueChanges.pipe(takeUntilDestroyed(this._destroyRef)).subscribe(() => {\n void this.update();\n });\n }\n }\n\n private _setFormControlValue() {\n const model = this.model();\n const field = this.field();\n const fg = this.fg()!;\n switch (this.realEditor()) {\n case 'input.datetime': {\n const value = fieldValues(model)[field] as string | number | Date | null;\n const now = new Date();\n const localnow = new Date(now.getTime() - now.getTimezoneOffset() * 60000);\n if (value === null) {\n fg.controls[field].setValue(null, { emitEvent: true });\n } else {\n const time = value ? new Date(value) : new Date();\n const offset = time.getTimezoneOffset();\n const localtime = new Date(time.getTime() - offset * 60000);\n fg.controls[field].setValue(localtime.toISOString().substring(0, 16), { emitEvent: true });\n }\n this.realDefault.set(\n this.default() || this.manager()?.required ? localnow.toISOString().substring(0, 16) : null,\n );\n break;\n }\n case 'input.date': {\n const dt = fieldValues(model.toJson([field]) as object)[field];\n fg.controls[field].setValue(dt);\n break;\n }\n case 'input.decimal':\n fg.controls[field].setValue(\n (fieldValues(model)[field] as number) / ((this.manager() as unknown as DecimalFieldManager).factor || 1),\n );\n }\n }\n\n private _setEditorClasses() {\n // FIXME: use realEditorClasses\n if (!this.inputClasses()) {\n this.inputClasses.set(this.dconf.dispEdit.inputClasses[this.realEditor()] || '');\n }\n }\n\n private _getDisplayValue() {\n const model = this.model();\n const field = this.field();\n const value = fieldValues(model)[field];\n this.dispValue.set(value);\n const realChoices = this.realChoices();\n if (realChoices) {\n for (const c of realChoices) {\n if (c === value) {\n this.txtValue.set(String(c.desc ?? c.value));\n return;\n } else if (c.value !== undefined && c.value === value) {\n this.txtValue.set(c.desc);\n return;\n }\n }\n }\n // Set display text depending on value and realDisplay value\n if (value === true) {\n this.txtValue.set('OUI');\n } else if (value === false) {\n this.txtValue.set('NON');\n } else if (value === undefined || value === null) {\n this.txtValue.set('non défini');\n } else {\n switch (this.realDisplay()) {\n case 'fkdetails': {\n const details = fieldValues(model)[`${field}_details`];\n this.txtValue.set(this._display(details));\n break;\n }\n case 'm2mdetails': {\n const m2mDetails = this.m2mValues || (fieldValues(model)[`${field}_details`] as DataModel[]);\n const tv: string[] = [];\n for (const v of m2mDetails || []) {\n tv.push(this._display(v));\n }\n this.txtValues.set(tv);\n break;\n }\n case 'decimal':\n this.txtValue.set(`${(value as number) / ((this.manager() as unknown as DecimalFieldManager).factor || 1)}`);\n break;\n default:\n this.txtValue.set(asText(value));\n }\n }\n }\n\n private _setDisplayClasses() {\n // Reserved: display classes are currently applied in the template.\n }\n}\n","<ng-template #titleTpl>\n <ng-content></ng-content>\n</ng-template>\n\n<!-- TEMPLATE affichage -->\n<ng-template #dispTpl>\n @switch (realDisplay()) {\n @case (\"text\") {\n <span\n class=\"editable disp-text\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n {{ txtValue() }}\n </span>\n }\n @case (\"html\") {\n <!--\n Trusted, not sanitized: Angular's sanitizer strips the inline styles\n richedit writes. See SafeHtmlPipe.\n -->\n <div\n class=\"editable disp-html\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n [innerHTML]=\"txtValue() | safeHtml\"\n ></div>\n }\n @case (\"choice\") {\n <span\n class=\"editable disp-choice\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n {{ txtValue() }}\n </span>\n }\n @case (\"decimal\") {\n <span\n class=\"editable disp-decimal\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n {{ txtValue() }}\n </span>\n }\n @case (\"boolean\") {\n <span\n class=\"editable disp-boolean\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n {{ txtValue() }}\n </span>\n }\n @case (\"fkdetails\") {\n <span\n class=\"editable disp-fkdetails\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n <div class=\"fkitem\">{{ txtValue() }}</div>\n </span>\n }\n @case (\"m2mdetails\") {\n <span\n class=\"editable disp-m2mdetails\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n @for (v of txtValues(); track v) {\n <div class=\"m2mitem\">{{ v }}</div>\n }\n </span>\n }\n @case (\"datetime\") {\n <span\n class=\"editable disp-datetime\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n @if (dispValue()) {\n {{ txtValue() | date: \"short\" }}\n }\n @if (!dispValue()) {\n {{ txtValue() }}\n }\n </span>\n }\n @case (\"date\") {\n <span\n class=\"editable disp-datetime\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"enableEditMode()\"\n (keydown.enter)=\"enableEditMode()\"\n (keydown.space)=\"$event.preventDefault(); enableEditMode()\"\n >\n @if (dispValue()) {\n {{ txtValue() | date: \"shortDate\" }}\n }\n @if (!dispValue()) {\n {{ txtValue() }}\n }\n </span>\n }\n }\n</ng-template>\n\n<!-- TEMPLATE édition -->\n<ng-template #editTpl let-form=\"form\">\n @switch (realEditor()) {\n @case (\"input.text\") {\n <input\n [attr.id]=\"inputId\"\n type=\"text\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minlength']\"\n >\n Trop court : {{ $any(manager()).minLength }} caractères minimum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxlength']\"\n >\n Trop long : {{ $any(manager()).maxLength }} caractères maximum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['pattern']\"\n >\n Format invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.email\") {\n <input\n [attr.id]=\"inputId\"\n type=\"email\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minlength']\"\n >\n Trop court : {{ $any(manager()).minLength }} caractères minimum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxlength']\"\n >\n Trop long : {{ $any(manager()).maxLength }} caractères maximum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['pattern']\"\n >\n Format invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['email']\"\n >\n Format d'email invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.password\") {\n <input\n [attr.id]=\"inputId\"\n type=\"password\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minlength']\"\n >\n Trop court : {{ $any(manager()).minLength }} caractères minimum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxlength']\"\n >\n Trop long : {{ $any(manager()).maxLength }} caractères maximum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['pattern']\"\n >\n Format invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.datetime\") {\n <input\n [attr.id]=\"inputId\"\n type=\"datetime-local\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n (keyup.enter)=\"update()\"\n />\n <div class=\"form-text\">{{ realHelp() }}</div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minDate']\"\n >\n Doit être postérieur à {{ $any(manager()).min | date: \"short\" }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxDate']\"\n >\n Doit être antérieur à {{ $any(manager()).max | date: \"short\" }}...\n </div>\n }\n @case (\"input.date\") {\n <input\n [attr.id]=\"inputId\"\n type=\"date\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n (keyup.enter)=\"update()\"\n />\n <div class=\"form-text\">{{ realHelp() }}</div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minDate']\"\n >\n Doit être postérieur à {{ $any(manager()).min | date: \"short\" }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxDate']\"\n >\n Doit être antérieur à {{ $any(manager()).max | date: \"short\" }}...\n </div>\n }\n @case (\"input.number\") {\n <input\n [attr.id]=\"inputId\"\n type=\"number\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['min']\"\n >\n Trop petit : minimum {{ $any(manager()).min }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['max']\"\n >\n Trop grand : maximum {{ $any(manager()).max }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.decimal\") {\n <input\n [attr.id]=\"inputId\"\n type=\"number\"\n [formControl]=\"form.get(field())\"\n [class]=\"inputClasses()\"\n (keyup.escape)=\"unsetEdit()\"\n [placeholder]=\"realPlaceholder()\"\n />\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['min']\"\n >\n Trop petit : minimum {{ $any(manager()).min }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['max']\"\n >\n Trop grand : maximum {{ $any(manager()).max }}...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"input.checkbox\") {\n @let v = $any(this.model())[this.field()];\n <div class=\"btn-group btn-group-sm\" role=\"group\">\n <button\n type=\"button\"\n [class]=\"v === true ? 'btn btn-primary' : 'btn btn-outline-primary'\"\n (click)=\"form.get(field())?.setValue(true); update()\"\n (keyup.escape)=\"unsetEdit()\"\n >\n Oui\n </button>\n <button\n type=\"button\"\n [class]=\"v === false ? 'btn btn-primary' : 'btn btn-outline-primary'\"\n (click)=\"form.get(field())?.setValue(false); update()\"\n (keyup.escape)=\"unsetEdit()\"\n >\n Non\n </button>\n </div>\n <div class=\"form-text\">{{ realHelp() }}</div>\n }\n @case (\"textarea\") {\n <textarea\n [attr.id]=\"inputId\"\n [formControl]=\"form.get(field())\"\n (keyup.escape)=\"unsetEdit()\"\n [class]=\"inputClasses()\"\n (keyup.control.enter)=\"update()\"\n [placeholder]=\"realPlaceholder()\"\n ></textarea>\n @if (mode() === \"dd\") {\n <button class=\"btn btn-sm btn-link w-100 dispedit-text-update-button\" (click)=\"update()\">\n <i class=\"bi bi-save\"></i>\n </button>\n }\n @if (realHelp()) {\n <div class=\"form-text\">\n {{ realHelp() }}\n @if (required()) {\n <span class=\"ms-1\">(requis)</span>\n }\n </div>\n }\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['minlength']\"\n >\n Trop court : {{ $any(manager()).minLength }} caractères minimum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['maxlength']\"\n >\n Trop long : {{ $any(manager()).maxLength }} caractères maximum...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['pattern']\"\n >\n Format invalide...\n </div>\n <div\n class=\"invalid-feedback mt-0\"\n [class.d-block]=\"form &amp;&amp; !form.controls[field()].pristine &amp;&amp; form.controls[field()].errors?.['required']\"\n >\n Ce champ est requis...\n </div>\n }\n @case (\"fkselect\") {\n <data-fkselect\n [inputId]=\"inputId\"\n [collection]=\"collection()\"\n [filter]=\"filter()\"\n [display]=\"display()\"\n (selected)=\"selectedRefItem($event)\"\n [placeholder]=\"placeholder()\"\n (cancelled)=\"unsetEdit()\"\n (cleared)=\"selectedRefItem(null)\"\n ></data-fkselect>\n }\n @case (\"m2mselect\") {\n <data-m2mselect\n [inputId]=\"inputId\"\n [collection]=\"collection()\"\n [filter]=\"filter()\"\n (changed)=\"update()\"\n [formControl]=\"form.get(field())\"\n (detailsChanged)=\"onM2MValuesChanges($event)\"\n [model]=\"model()\"\n [field]=\"field()\"\n [placeholder]=\"placeholder()\"\n ></data-m2mselect>\n }\n @case (\"select\") {\n <select\n [attr.id]=\"inputId\"\n [formControl]=\"form.get(field())\"\n (keyup.escape)=\"unsetEdit()\"\n (change)=\"update()\"\n [class]=\"inputClasses()\"\n >\n @for (c of realChoices(); track c) {\n <option [ngValue]=\"c.value !== undefined ? c.value : c\">\n {{ c.desc ? c.desc : c }}\n </option>\n }\n </select>\n <div class=\"form-text\">{{ realHelp() }}</div>\n }\n }\n</ng-template>\n<!-- Disp/edit toggler-->\n<ng-template #dispeditTpl>\n @if (!edit()) {\n <ng-container *ngTemplateOutlet=\"dispTpl\"></ng-container>\n }\n @if (edit()) {\n @if (fg(); as fg) {\n <form [formGroup]=\"fg\" (submit)=\"update()\">\n <ng-container *ngTemplateOutlet=\"editTpl; context: { form: fg }\"></ng-container>\n </form>\n }\n }\n</ng-template>\n<!-- DispEdit noform-->\n<ng-template #dispeditFormTpl>\n @if (!edit()) {\n <ng-container *ngTemplateOutlet=\"dispTpl\"></ng-container>\n }\n @if (edit()) {\n @if (form()) {\n <ng-container *ngTemplateOutlet=\"editTpl; context: { form: form() }\"></ng-container>\n }\n }\n</ng-template>\n<!-- Dd display-->\n@if (mode() === \"dd\") {\n @if (!hideLabel()) {\n <dt [class.required]=\"required()\">\n <span\n class=\"editable\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"toggleEdit()\"\n (keydown.enter)=\"toggleEdit()\"\n (keydown.space)=\"$event.preventDefault(); toggleEdit()\"\n >\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </span>\n @if (realDefault() !== undefined && edit()) {\n <span\n class=\"pointer float-end\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Rétablir la valeur par défaut\"\n (click)=\"setDefault()\"\n (keydown.enter)=\"setDefault()\"\n (keydown.space)=\"$event.preventDefault(); setDefault()\"\n >\n <i class=\"bi bi-trash ms-2\"></i>\n </span>\n }\n </dt>\n }\n <dd [class.mb-0]=\"hideLabel()\">\n <ng-container *ngTemplateOutlet=\"dispeditTpl\"></ng-container>\n </dd>\n}\n<!-- Inline display-->\n@if (mode() === \"inline\") {\n @if (!hideLabel()) {\n @if (realDefault() !== undefined && edit()) {\n <span\n class=\"pointer float-end\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Rétablir la valeur par défaut\"\n (click)=\"setDefault()\"\n (keydown.enter)=\"setDefault()\"\n (keydown.space)=\"$event.preventDefault(); setDefault()\"\n >\n <i class=\"bi bi-trash ms-2\"></i>\n </span>\n }\n <label [class.required]=\"required()\" [attr.for]=\"inputId\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </label>\n }\n <ng-container *ngTemplateOutlet=\"dispeditTpl\"></ng-container>\n}\n<!-- Form display-->\n@if (mode() === \"form\") {\n @if (!hideLabel()) {\n @if (realDefault() !== undefined && edit()) {\n <span\n class=\"pointer float-end\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Rétablir la valeur par défaut\"\n (click)=\"setDefault()\"\n (keydown.enter)=\"setDefault()\"\n (keydown.space)=\"$event.preventDefault(); setDefault()\"\n >\n <i class=\"bi bi-trash ms-2\"></i>\n </span>\n }\n <label [class.required]=\"required()\" [attr.for]=\"inputId\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </label>\n }\n <ng-container *ngTemplateOutlet=\"dispeditFormTpl\"></ng-container>\n}\n","import { Component, DestroyRef, inject, input, model, OnInit, signal } from '@angular/core';\nimport { fieldValues } from '../../data/field-values';\n\nimport { DataModel } from '../../data/data-model';\nimport { debounceTime, firstValueFrom, Observable } from 'rxjs';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { DataMessageService } from '../../messages/message.service';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n/**\n * One available flag, as returned by the collection's flags endpoint.\n */\nexport interface IFlagItem {\n /** The flag value itself, as stored in the model's flags array. */\n flag: string;\n /** How many instances currently carry the flag; shown next to the option. */\n count: number;\n}\n\n@Component({\n selector: 'data-flags',\n imports: [ReactiveFormsModule],\n templateUrl: './flags.component.html',\n styleUrls: ['./flags.component.sass'],\n})\n/**\n * Displays and edits a `string[]` flags field as a set of badges.\n *\n * The list of flags available for selection is discovered at runtime rather\n * than declared: on first entering edit mode the component calls a collection\n * action (`get_flags` by default) and populates its dropdown from the result,\n * counts included. Users can also type a new flag, unless `[create]` is false.\n *\n * There are two persistence strategies, chosen by `[action]`:\n * - default: the flags array is written back to the model field and saved with\n * an ordinary field update.\n * - `[action]=\"true\"`: each change POSTs to the model's `add_flag` /\n * `remove_flag` actions instead, leaving the field update to the server.\n *\n * Either way the local badge list is updated optimistically, before the request\n * resolves.\n *\n * @example\n * ```html\n * <data-flags [model]=\"thing\" field=\"flags\">Flags</data-flags>\n * ```\n */\nexport class FlagsComponent<T extends DataModel> implements OnInit {\n /** Model instance carrying the flags field. Mandatory. */\n public model = input.required<T>();\n /** Name of the `string[]` field to edit. Defaults to `flags`. */\n public field = input<string>('flags');\n // FIXME: make all flags endpoint as optional parameters\n /**\n * Collection action queried (GET) for the list of available flags.\n *\n * Only consulted when `[flags]` is not supplied. The `add_flag` /\n * `remove_flag` action names used by `[action]` mode are not configurable.\n */\n public get_flags_endpoint = input<string>('get_flags');\n /** Whether the editor is shown. Two-way bindable; toggled by {@link toggleEdit}. */\n public edit = model<boolean>(false);\n /** Whether the field can be edited at all. Defaults to true. */\n public editable = input<boolean>(true);\n /**\n * Source of available flags, overriding the endpoint call.\n *\n * Writable because the component fills it in from the model's collection when\n * left unset. It is subscribed lazily, on first entering edit mode.\n */\n public flags = model<Observable<IFlagItem[]>>();\n /**\n * Free-entry mode: offer only a text input, with no dropdown of known flags.\n */\n public free = input<boolean>(false);\n /** Whether a text input for adding new flags is shown alongside the dropdown. */\n public create = input<boolean>(true);\n /**\n * Persist through the model's `add_flag` / `remove_flag` actions rather than\n * by updating the field.\n */\n public action = input<boolean>(false);\n /** Control for the free-text \"new flag\" input. */\n public ft!: FormControl<string | null>;\n /** Control for the known-flags dropdown; selecting a value adds it. */\n public fs!: FormControl<string | null>;\n /** Flags currently on the model, rendered as badges. */\n public curflags = signal<string[]>([]);\n /** Unused; kept for backwards compatibility. */\n public txtflag = '';\n /** Unused; kept for backwards compatibility. */\n public selflag = '';\n /** Available flags, fetched on first entering edit mode. */\n public flaglist = signal<IFlagItem[]>([]);\n private destroy$ = inject(DestroyRef);\n private _msg = inject(DataMessageService);\n\n /**\n * Resolve the flags source from the model's collection, seed the badge list\n * from the model field, and wire the dropdown so that selecting a value adds\n * the flag (debounced 250ms).\n */\n public ngOnInit(): void {\n const model = this.model();\n if (!this.flags() && model._collection) {\n this.flags.set(model._collection.action(null, 'GET', this.get_flags_endpoint()));\n }\n const flags = model && this.field() && fieldValues(model)[this.field()];\n if (flags) {\n this.curflags.set(flags as string[]);\n } else {\n console.warn('Model or field problem in flagsfield component');\n this.curflags.set([]);\n }\n this.ft = new FormControl<string | null>('');\n this.fs = new FormControl<string | null>('');\n this.fs.valueChanges.pipe(takeUntilDestroyed(this.destroy$), debounceTime(250)).subscribe((value) => {\n if (value) {\n void this.addFlag(value);\n }\n });\n }\n\n /** Add the flag currently typed in the free-text input. */\n public async addFreeFlag(): Promise<void> {\n await this.addFlag(this.ft.value ?? '');\n }\n\n /**\n * Add a flag and persist, unless it is already present.\n *\n * Persists via the model's `add_flag` action when `[action]` is set, else by\n * saving the whole field through {@link update}.\n *\n * @param flag flag value to add.\n */\n public async addFlag(flag: string): Promise<void> {\n if (!this.flagPresent(flag)) {\n this.curflags.update((c) => [...c, flag]);\n if (this.action()) {\n try {\n await firstValueFrom(this.model().action('POST', 'add_flag', { body: { flag } }));\n this._msg.success('Flag enregistré avec succès');\n } catch (e) {\n this._msg.error('Erreur lors de la sauvegarde', String(e));\n }\n } else {\n await this.update();\n }\n }\n }\n\n /**\n * Write the current flags back to the model field and save it, then reset\n * both inputs. Reports success or failure through the message service.\n */\n public async update(): Promise<void> {\n fieldValues(this.model())[this.field()] = this.curflags();\n try {\n await firstValueFrom(this.model().update([this.field()]));\n this.fs.setValue('', { emitEvent: false });\n this.ft.setValue('', { emitEvent: false });\n this._msg.success('Flag enregistré avec succès');\n } catch (error) {\n this._msg.error(\n 'Erreur lors de la sauvegarde',\n `API Return : ${String(error)}`,\n (error as { _body?: string })._body,\n );\n }\n }\n\n /**\n * Whether the flag is already on the model.\n *\n * @param flag flag value to look for.\n */\n public flagPresent(flag: string): boolean {\n return this.curflags().findIndex((f) => flag === f) !== -1;\n }\n\n /**\n * Remove a flag and persist, via the model's `remove_flag` action when\n * `[action]` is set, else by saving the whole field through {@link update}.\n *\n * @param flag flag value to remove.\n */\n public async removeFlag(flag: string): Promise<void> {\n this.curflags.update((c) => c.filter((f) => f !== flag));\n if (this.action()) {\n try {\n await firstValueFrom(this.model().action('POST', 'remove_flag', { body: { flag } }));\n this._msg.success('Removed');\n } catch (e) {\n this._msg.error('Removing flag failed', String(e));\n }\n } else {\n await this.update();\n }\n }\n\n /**\n * Switch between badge display and the editor.\n *\n * Entering edit mode resolves the available flags list first, so the dropdown\n * is populated. Does nothing but force display mode when `[editable]` is\n * false.\n */\n public async toggleEdit() {\n if (this.editable()) {\n if (!this.edit()) {\n this.flaglist.set(await firstValueFrom(this.flags()!));\n this.edit.set(true);\n } else {\n this.edit.set(false);\n }\n } else {\n this.edit.set(false);\n }\n }\n}\n","<dt\n (click)=\"toggleEdit()\"\n role=\"button\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleEdit()\"\n (keydown.space)=\"$event.preventDefault(); toggleEdit()\"\n>\n <ng-content></ng-content>\n</dt>\n@if (!edit()) {\n <dd\n (click)=\"toggleEdit()\"\n role=\"button\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleEdit()\"\n (keydown.space)=\"$event.preventDefault(); toggleEdit()\"\n >\n @for (flag of curflags(); track flag) {\n <span class=\"badge bg-info me-1\">{{ flag }}</span>\n }\n </dd>\n}\n@if (edit()) {\n <dd>\n <div class=\"row\">\n @if (!free()) {\n <div class=\"col\">\n <select class=\"form-select form-select-sm\" [formControl]=\"fs\">\n @for (flag of flaglist(); track flag) {\n <option [value]=\"flag.flag\">\n {{ flag.flag }}\n @if (flag.count) {\n <span class=\"ms-1\">({{ flag.count }})</span>\n }\n </option>\n }\n </select>\n </div>\n @if (create()) {\n <div class=\"col\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Nouveau flag\"\n [formControl]=\"ft\"\n (keyup.enter)=\"addFreeFlag()\"\n />\n </div>\n }\n }\n @if (free()) {\n <div class=\"col-12\">\n <input\n class=\"form-control form-select-sm\"\n placeholder=\"Nouveau flag\"\n [formControl]=\"ft\"\n (keyup.enter)=\"addFreeFlag()\"\n (keyup.escape)=\"toggleEdit()\"\n />\n </div>\n }\n </div>\n <div class=\"row\">\n <div class=\"col-sm-12\">\n @for (flag of curflags(); track flag) {\n <span\n class=\"badge bg-info me-1\"\n (click)=\"removeFlag(flag)\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Retirer le flag ' + flag\"\n (keydown.enter)=\"removeFlag(flag)\"\n (keydown.space)=\"$event.preventDefault(); removeFlag(flag)\"\n >\n <i class=\"bi bi-trash me-1\"></i>\n {{ flag }}\n </span>\n }\n <i\n class=\"bi bi-x-lg text-muted ms-2\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Fermer l'édition\"\n (click)=\"toggleEdit()\"\n (keydown.enter)=\"toggleEdit()\"\n (keydown.space)=\"$event.preventDefault(); toggleEdit()\"\n ></i>\n </div>\n </div>\n </dd>\n}\n","import { Component, ElementRef, inject, input, output, signal, ViewChild } from '@angular/core';\nimport { DataModel } from '../../data/data-model';\nimport { Collection } from '../../data/data-collection';\nimport { firstValueFrom } from 'rxjs';\nimport { NgbOffcanvas, NgbOffcanvasModule, NgbOffcanvasRef } from '@ng-bootstrap/ng-bootstrap';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { DataMessageService } from '../../messages/message.service';\n\n/** The two places an API error puts its human-readable message. */\ninterface IApiMessage {\n message?: string;\n error?: { message?: string };\n}\n\n/**\n * What a dry-run delete reports back: the blast radius of the real deletion.\n */\nexport interface FakeDeleteResult {\n /** Total number of database objects that would be removed. */\n count: number;\n /** Per-type breakdown, as `[object type name, count]` pairs. */\n details: [string, number][];\n}\n\n@Component({\n selector: 'data-safe-delete',\n templateUrl: './sdelete.component.html',\n styleUrls: ['./sdelete.component.sass'],\n imports: [NgTemplateOutlet, NgbOffcanvasModule],\n})\n/**\n * \"Safe delete\": a delete control that makes the user confirm what they are\n * about to destroy, cascade included.\n *\n * The flow is two round-trips. Clicking the control first sends a dry-run\n * delete (`doit: 'no'`), which the API answers with a {@link FakeDeleteResult}\n * counting everything that would be removed. That breakdown is shown in an\n * offcanvas panel, per object type, with `[checks]` translating database names\n * into human ones. Only if the user then confirms does a second, real delete go\n * out (`doit: 'really'`), and {@link deleted} fire.\n *\n * The dry run means the API must understand the `doit` parameter; `[actionFn]`\n * replaces the second step for models that delete differently.\n *\n * @example\n * ```html\n * <data-safe-delete [model]=\"thing\" (deleted)=\"reload()\">Delete</data-safe-delete>\n * ```\n */\nexport class SafeDeleteComponent<T extends DataModel> {\n /** Model instance to be deleted */\n public model = input.required<T>();\n /** Service to be used for deletion, taken from model if not provided */\n public service = input<Collection<T>>();\n /** Function to be called for deletion, overrides service deletion */\n public actionFn = input<(model: T) => Promise<{ success: boolean }>>();\n /** Translations of database objects names to human names */\n public checks = input<Record<string, string>>({});\n /** Messages to be displayed on success or error, default messages are used if not provided */\n public messages = input<{ success?: string; error?: string }>({});\n /** Event emitted on successful deletion */\n public deleted = output<FakeDeleteResult>();\n /** Display mode, default is button.\n *\n * - `fbutton`: floating button (small)\n * - `button`: button (small), with text taken from ng-content (no space around icon to allow empty buttons)\n * - `icon`: icon\n * - `custom`: custom : ng-content is surrounded by a clickable div\n * */\n public display = input<'fbutton' | 'button' | 'icon' | 'custom'>('button');\n\n /** Dry-run result driving the confirmation panel. */\n public result = signal<FakeDeleteResult | undefined>(undefined);\n @ViewChild('dialog', { static: true })\n private _dialogRef?: ElementRef<HTMLDivElement>;\n private ofc?: NgbOffcanvasRef;\n private _ofc = inject(NgbOffcanvas);\n private _msgs = inject(DataMessageService);\n\n /**\n * First step: run the dry-run delete and open the confirmation panel with its\n * result. Nothing is destroyed here.\n *\n * @param _model unused; the component always acts on its own `[model]` input.\n */\n public async checkDelete(_model: DataModel) {\n const service = this.service() || this.model()._collection;\n if (service) {\n try {\n this.result.set(\n (await firstValueFrom(service.delete(this.model(), { params: { doit: 'no' } }))) as FakeDeleteResult,\n );\n\n this.ofc = this._ofc.open(this._dialogRef, {\n position: 'end',\n });\n } catch (e) {\n console.error(e);\n if (this.messages().error) {\n this._msgs.error(\n this.messages().error!,\n (e as IApiMessage).error?.message || (e as IApiMessage).message || '',\n );\n }\n }\n }\n }\n\n /**\n * Second step: perform the actual deletion once the user has confirmed, then\n * close the panel and emit {@link deleted} with the dry-run result.\n *\n * Uses `[actionFn]` when provided, otherwise deletes through the service with\n * `doit: 'really'`. Nothing is emitted if the deletion fails.\n */\n public async reallyDelete() {\n const actionFn = this.actionFn();\n if (actionFn) {\n const res = await actionFn(this.model());\n if (res.success && this.messages().success) {\n this._msgs.success(this.messages().success!);\n } else if (!res.success && this.messages().error) {\n this._msgs.error(this.messages().error!);\n }\n this.ofc?.close();\n if (res.success) {\n this.deleted.emit(this.result()!);\n }\n } else {\n const service = this.service() || this.model()._collection;\n if (service) {\n try {\n this.result.set(\n (await firstValueFrom(service.delete(this.model(), { params: { doit: 'really' } }))) as FakeDeleteResult,\n );\n if (this.messages().success) {\n this._msgs.success(this.messages().success!);\n }\n this.ofc?.close();\n this.deleted.emit(this.result()!);\n } catch (e) {\n console.error(e);\n if (this.messages().error) {\n this._msgs.error(\n this.messages().error!,\n (e as IApiMessage).error?.message || (e as IApiMessage).message || '',\n );\n }\n }\n }\n }\n }\n}\n","<ng-template #dialog let-offcanvas>\n <div class=\"offcanvas-header\">\n <h2 class=\"offcanvas-title text-danger text-center\">\n <i class=\"bi bi-trash me-2\"></i>\n Supprimer réellement ??\n </h2>\n </div>\n @if (result(); as result) {\n <div class=\"offcanvas-body text-danger\">\n <div class=\"text-center my-4 fs-1\">\n <i class=\"bi bi-exclamation-diamond my-5\"></i>\n </div>\n <div class=\"fs-4\">\n <p>La suppression de cet élément supprimera {{ result.count }} éléments dans la base de données..</p>\n </div>\n <table class=\"table table-sm table-striped table-danger\">\n <thead>\n <tr>\n <th>Type d'élément</th>\n <th>Nombre</th>\n </tr>\n </thead>\n <tbody>\n @for (rl of result.details; track rl) {\n <tr>\n <td>{{ checks()[rl[0]] ? checks()[rl[0]] : rl[0] }}</td>\n <td>{{ rl[1] }}</td>\n </tr>\n }\n </tbody>\n </table>\n <button class=\"w-100 btn btn-lg btn-danger\" (click)=\"reallyDelete()\">\n <i class=\"bi bi-trash me-2\"></i>\n Je confirme la suppression\n </button>\n <button class=\"w-100 btn btn-outline-secondary my-3\" (click)=\"offcanvas.close()\">\n <i class=\"bi bi-door-open me-2\"></i>\n Je renonce à la suppression\n </button>\n </div>\n }\n</ng-template>\n<ng-template #contentTpl>\n <ng-content></ng-content>\n</ng-template>\n@if (display() === \"button\") {\n <button class=\"btn btn-sm btn-danger\" (click)=\"checkDelete(model())\">\n <i class=\"bi bi-trash\"></i>\n <ng-container *ngTemplateOutlet=\"contentTpl\"></ng-container>\n </button>\n}\n@if (display() === \"fbutton\") {\n <button class=\"btn btn-sm btn-outline-danger float-end\" (click)=\"checkDelete(model())\">\n <i class=\"bi bi-trash mx-2\"></i>\n </button>\n}\n@if (display() === \"icon\") {\n <i\n class=\"bi bi-trash mx-2\"\n (click)=\"checkDelete(model())\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Supprimer\"\n (keydown.enter)=\"checkDelete(model())\"\n (keydown.space)=\"$event.preventDefault(); checkDelete(model())\"\n ></i>\n}\n@if (display() === \"custom\") {\n <div\n (click)=\"checkDelete(model())\"\n role=\"button\"\n tabindex=\"0\"\n (keydown.enter)=\"checkDelete(model())\"\n (keydown.space)=\"$event.preventDefault(); checkDelete(model())\"\n >\n <ng-container *ngTemplateOutlet=\"contentTpl\"></ng-container>\n </div>\n}\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\nimport { ValidatorFn, Validators } from '@angular/forms';\nimport { DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\nimport { asText } from '../field-values';\n\n/**\n * A choice with a separate stored value and human label: `value` is what\n * travels to the API, `desc` is what the user sees.\n */\nexport interface ICharFieldDescChoice {\n /** The value stored on the model and sent to the API. */\n value: string;\n /** The human-readable label shown for that value. */\n desc: string;\n}\n\n/**\n * One entry of a `choices` list — either a `{value, desc}` pair, or a bare\n * string used as both the stored value and its own label.\n */\nexport type ICharFieldChoice = ICharFieldDescChoice | string;\n\n/**\n * Options for {@link charField} and, by extension, every other string field.\n */\nexport interface ICharFieldMetadata extends IFieldMetadata<string> {\n /** Minimum length; adds `Validators.minLength`. Ignored when `0`. */\n minLength?: number;\n /** Maximum length; adds `Validators.maxLength`. Ignored when `0`. */\n maxLength?: number;\n /** Regexp the value must match; adds `Validators.pattern`. */\n pattern?: RegExp | string;\n /**\n * Allowed values. Setting this switches the editor to a `'select'` dropdown.\n *\n * Note it is *not* enforced by a validator: choices shape the UI, they do\n * not currently reject an off-list value assigned in code.\n */\n choices?: ICharFieldChoice[];\n}\n\n/**\n * Options for {@link emailField}.\n */\nexport interface IEmailFieldMetadata extends ICharFieldMetadata {\n /** Apply `Validators.email`. Defaults to `true`. */\n validate?: boolean;\n}\n\n/**\n * Options for {@link passwordField}.\n */\nexport interface IPasswordFieldMetadata extends ICharFieldMetadata {\n /** Declarative only: `PasswordFieldManager` adds no validator of its own. */\n validate?: boolean;\n}\n\n/**\n * Options for {@link textField}.\n */\nexport interface ITextFieldMetadata extends ICharFieldMetadata {\n /**\n * Content syntax hint (e.g. markdown) for renderers. Carried as metadata;\n * the manager itself does not act on it.\n */\n syntax?: string;\n}\n\n/**\n * Manager for single-line string fields, and base for every other string\n * field type. Adds length and pattern validators, coerces incoming JSON to a\n * string, and switches {@link BaseFieldManager.editorType} to `'select'` when\n * `choices` is declared.\n */\nexport class CharFieldManager extends BaseFieldManager<string> {\n /** Minimum length; adds `Validators.minLength`. */\n declare public minLength?: number;\n /** Maximum length; adds `Validators.maxLength`. */\n declare public maxLength?: number;\n /** Allowed values; their presence switches the editor to a `'select'`. */\n declare public choices?: ICharFieldChoice[];\n /** Regexp the value must match; adds `Validators.pattern`. */\n declare public pattern?: RegExp | string;\n\n /**\n * Builds the manager and, when `choices` were declared, promotes the editor\n * from a free-text input to a dropdown.\n */\n constructor(params: ICharFieldMetadata) {\n super(params);\n if (this.choices) {\n this.editorType = 'select';\n }\n }\n\n /** Required, plus minLength / maxLength / pattern when declared. */\n public override get validators(): ValidatorFn[] {\n const v = super.getValidators();\n if (this.minLength) {\n v.push(Validators.minLength(this.minLength));\n }\n if (this.maxLength) {\n v.push(Validators.maxLength(this.maxLength));\n }\n if (this.pattern) {\n v.push(Validators.pattern(this.pattern));\n }\n // TODO: add choices validator ??\n return v;\n }\n\n /**\n * Coerces the incoming value to a string: `null` and `undefined` both yield\n * the field's default value, a string is kept as-is, and anything else is\n * interpolated (`42` → `'42'`).\n *\n * @param data raw value read from the JSON payload\n */\n public override fromJson(data: unknown): string {\n if (data === undefined) {\n return this.getDefaultValue()!;\n }\n if (data === null) {\n return this.getDefaultValue()!;\n }\n if (typeof data === 'string') {\n return data;\n }\n return asText(data);\n }\n}\n\n/**\n * Manager for email fields: renders an `input.email` editor and, unless\n * `validate: false`, applies `Validators.email`.\n *\n * Caveat, as currently implemented: its validator list is built from the\n * *base* manager, so it is `required` + `email` only. `minLength`,\n * `maxLength` and `pattern` declared on an `emailField` are **not** enforced,\n * even though the options are accepted.\n */\nexport class EmailFieldManager extends CharFieldManager implements ICharFieldMetadata {\n /** Whether `Validators.email` is applied. Defaults to `true`. */\n public validate = true;\n /** Renders an `input.email` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.email';\n\n /**\n * Builds the manager, defaulting {@link validate} to `true` when it was not\n * declared.\n */\n constructor(params: IEmailFieldMetadata) {\n super(params);\n if (this.validate === undefined) {\n this.validate = true;\n }\n }\n\n /**\n * `Validators.required` (when required) plus `Validators.email` (when\n * `validate`). Does not include the char-level length/pattern validators.\n */\n public override get validators(): ValidatorFn[] {\n const v = super.getValidators();\n if (this.validate) {\n // eslint-disable-next-line @typescript-eslint/unbound-method -- Validators.* are static and `this`-free\n v.push(Validators.email);\n }\n return v;\n }\n}\n\n/**\n * Manager for long-form text: a `CharFieldManager` rendered as a `textarea`.\n * Validation and serialisation are unchanged.\n */\nexport class TextFieldManager extends CharFieldManager {\n /** Content syntax hint (e.g. markdown) for renderers. */\n declare public syntax?: string;\n /** Renders a multi-line `textarea` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'textarea';\n}\n\n/**\n * Manager for password input: a `CharFieldManager` rendered as an\n * `input.password` (masked). It only changes the widget — the value is held\n * and transmitted as an ordinary string, with no hashing or extra validation.\n */\nexport class PasswordFieldManager extends CharFieldManager {\n /** Declarative only; unused by this manager. */\n declare public syntax?: string;\n /** Renders a masked `input.password` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.password';\n}\n\n/**\n * Declares a single-line string field — the default choice for any short text\n * value. Renders a text input, or a dropdown as soon as `choices` is given.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @charField({ description: 'Name', maxLength: 100 })\n * public name!: string;\n *\n * // `choices` alone switches the editor to a select\n * @charField({\n * description: 'Status',\n * defaultValue: 'draft',\n * choices: [\n * { value: 'draft', desc: 'Draft' },\n * { value: 'live', desc: 'Live' },\n * ],\n * })\n * public status!: string;\n * }\n */\nexport const charField = (updates: ICharFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'charField', CharFieldManager);\n\n/**\n * Declares an email field: a string rendered with an `input.email` editor and\n * validated with `Validators.email` unless `validate: false`.\n *\n * Note that `minLength`/`maxLength`/`pattern` are accepted but not enforced\n * here — see {@link EmailFieldManager}.\n *\n * @param updates field options\n */\nexport const emailField = (updates: IEmailFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'emailField', EmailFieldManager);\n\n/**\n * Declares a multi-line string field, rendered as a `textarea`. Reach for it\n * instead of {@link charField} for descriptions, notes and other long-form\n * content; behaviour is otherwise identical.\n *\n * @param updates field options\n */\nexport const textField = (updates: ITextFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'textField', TextFieldManager);\n\n/**\n * Declares a string field rendered with a masked `input.password` editor.\n * Masking is all it does: the value is stored and sent in clear, so treat it\n * as a UI affordance and not as a security measure.\n *\n * @param updates field options\n */\nexport const passwordField = (updates: IPasswordFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'passwordField', PasswordFieldManager);\n","import { BaseFieldManager, FieldDefaultArgs, genericDataField, IFieldMetadata } from './base';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\nimport { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\n/**\n * Options for {@link dateField}.\n */\nexport interface IDateFieldMetadata extends IFieldMetadata<Date | null> {\n /**\n * When no `defaultValue` is declared, use the current date as the default\n * instead of `null`. Note this only seeds the value on the client; it does\n * not re-stamp the field on every save.\n */\n autoNow?: boolean;\n /**\n * Same effect as {@link autoNow} in the current implementation: both flags\n * are tested together, so either one makes the default `new Date()`.\n */\n autoNowAdd?: boolean;\n /** Lower bound; adds {@link dateMinimum}. Exclusive — equal dates are rejected. */\n min?: Date;\n /** Upper bound; adds {@link dateMaximum}. Exclusive — equal dates are rejected. */\n max?: Date;\n}\n\n/**\n * Builds a validator rejecting any date that is not **strictly after** `date`.\n *\n * The bound is exclusive: the control is valid only when\n * `controlDate > date`, so a value exactly equal to `date` fails with a\n * `minDate` error. Empty controls (`null` / `undefined`) always pass —\n * emptiness is `required`'s business, not this validator's.\n *\n * @param date exclusive lower bound\n * @returns a `ValidatorFn` yielding `{minDate: {'date-minimum', actual}}` on failure\n */\nexport const dateMinimum = (date: Date): ValidatorFn => {\n return (control: AbstractControl): ValidationErrors | null => {\n if (control.value == null) {\n return null;\n }\n\n const controlDate = new Date(control.value as string | number | Date);\n\n const validationDate = date;\n\n return controlDate > validationDate\n ? null\n : {\n minDate: {\n 'date-minimum': validationDate,\n actual: controlDate,\n },\n };\n };\n};\n\n/**\n * Builds a validator rejecting any date that is not **strictly before**\n * `date`.\n *\n * As with {@link dateMinimum} the bound is exclusive: valid only when\n * `controlDate < date`, so a value exactly equal to `date` fails with a\n * `maxDate` error. Empty controls always pass.\n *\n * @param date exclusive upper bound\n * @returns a `ValidatorFn` yielding `{maxDate: {'date-maximum', actual}}` on failure\n */\nexport const dateMaximum = (date: Date): ValidatorFn => {\n return (control: AbstractControl): ValidationErrors | null => {\n if (control.value == null) {\n return null;\n }\n const controlDate = new Date(control.value as string | number | Date);\n const validationDate = date;\n\n return controlDate < validationDate\n ? null\n : {\n maxDate: {\n 'date-maximum': validationDate,\n actual: controlDate,\n },\n };\n };\n};\n\n/**\n * Options for {@link datetimeField}.\n */\nexport interface IDatetimeFieldMetadata extends IDateFieldMetadata {\n /**\n * How the wire format is interpreted and produced.\n *\n * - omitted / `null`: values are treated as **local time**. Any `Z` suffix\n * or `±HHMM` offset in the incoming string is stripped before parsing, and\n * `toJson` emits an offset-less ISO string shifted to local time.\n * - `'UTC'`: values are parsed as-is and serialised with `toISOString()`\n * (trailing `Z`).\n * - any other string: parsed as-is; on save the literal is appended to an\n * offset-less ISO string, so it must be a valid ISO offset like `'+0200'`.\n */\n timezone?: string | null;\n}\n\n/**\n * Manager for calendar dates (no time component). Parses anything the `Date`\n * constructor accepts, serialises back to a `YYYY-M-D` string built from\n * **UTC** parts, and adds exclusive `min`/`max` validators.\n *\n * It also overrides default-value resolution so that `autoNow`/`autoNowAdd`\n * yield the current date, and an undeclared default is `null` rather than\n * `undefined`.\n */\nexport class DateFieldManager extends BaseFieldManager<Date | null> implements IDateFieldMetadata {\n /** Default to the current date when no `defaultValue` is declared. */\n public autoNow = false;\n /** Equivalent to {@link autoNow}; both are tested together. */\n public autoNowAdd = false;\n /** Exclusive lower bound; adds {@link dateMinimum}. */\n declare public min?: Date;\n /** Exclusive upper bound; adds {@link dateMaximum}. */\n declare public max?: Date;\n /** Renders an `input.date` editor (no time component). */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.date';\n /** Rendered by the `date` display. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'date';\n\n /**\n * Builds the manager from the declared date options.\n *\n * @param params field options as passed to the decorator\n */\n constructor(params: IDateFieldMetadata) {\n super(params);\n }\n\n /** Required, plus {@link dateMinimum} / {@link dateMaximum} when declared. */\n public override get validators(): ValidatorFn[] {\n const v = super.validators;\n if (this.min) {\n v.push(dateMinimum(this.min));\n }\n if (this.max) {\n v.push(dateMaximum(this.max));\n }\n return v;\n }\n\n /**\n * Parses the incoming value with the `Date` constructor. `null`,\n * `undefined` and anything that parses to an invalid date all yield `null`,\n * so a malformed payload degrades to an empty field rather than throwing.\n *\n * @param data raw value read from the JSON payload\n */\n public override fromJson(data: unknown): Date | null {\n if (data === null || data === undefined) {\n return null;\n }\n const date = new Date(data as string | number | Date);\n if (date instanceof Date && !isNaN(date.getTime())) {\n return date;\n }\n return null;\n }\n\n /**\n * Serialises to a `YYYY-M-D` date string assembled from the **UTC** parts of\n * the value, dropping the time. Strings are re-parsed first; `null` and\n * `undefined` yield `null`.\n *\n * The parts are not zero-padded, so this emits `2024-1-5` rather than\n * `2024-01-05`.\n *\n * @param data current model value\n */\n public override toJson(data: Date | string | null): null | string {\n if (data === null || data === undefined) {\n return null;\n }\n if (typeof data === 'string') {\n const d = this.fromJson(data);\n if (d === null) {\n return null;\n }\n data = d;\n }\n return `${data.getUTCFullYear()}-${data.getUTCMonth() + 1}-${data.getUTCDate()}`;\n }\n\n /**\n * Resolves the default value, adding date-specific behaviour on top of the\n * base rules: a `defaultValue` function is called, a `required` field with\n * no default still throws, and an undeclared default resolves to\n * `new Date()` when `autoNow`/`autoNowAdd` is set, or `null` otherwise\n * (never `undefined`).\n *\n * @param args passed through to a `defaultValue` function\n * @throws Error if `required` is set and `defaultValue` is `undefined`\n * @protected\n */\n protected override getDefaultValue(args: FieldDefaultArgs = {}): Date | null | undefined {\n if (this.defaultValue instanceof Function) {\n return this.defaultValue(args);\n }\n if (this.required && this.defaultValue === undefined) {\n throw new Error(`Field ${this.name} : no default value for required field`);\n }\n if (this.defaultValue === undefined) {\n return this.autoNow || this.autoNowAdd ? new Date() : null;\n }\n return this.defaultValue;\n }\n}\n\n/**\n * Manager for date+time fields. Extends {@link DateFieldManager} with\n * timezone-aware (de)serialisation driven by\n * {@link IDatetimeFieldMetadata.timezone}, and switches to the\n * `input.datetime` / `datetime` widgets.\n *\n * Its default mode — no `timezone` — is deliberately *naive*: offsets are\n * stripped on read and never emitted on write, so wall-clock times round-trip\n * unshifted. Set `timezone: 'UTC'` when the instant matters more than the\n * wall-clock reading.\n */\nexport class DatetimeFieldManager extends DateFieldManager implements IDatetimeFieldMetadata {\n /** Wire timezone handling. See {@link IDatetimeFieldMetadata.timezone}. */\n declare public timezone?: string | null;\n /** Renders an `input.datetime` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.datetime';\n /** Rendered by the `datetime` display. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'datetime';\n\n /**\n * Builds the manager from the declared datetime options, `timezone`\n * included.\n *\n * @param params field options as passed to the decorator\n */\n constructor(params: IDatetimeFieldMetadata) {\n super(params);\n }\n\n /**\n * Serialises to an ISO 8601 string, shaped by `timezone`: naive local time\n * with no suffix when unset, `toISOString()` when `'UTC'`, or an\n * offset-less ISO string with the configured offset appended otherwise.\n * Strings are re-parsed first; `null`/`undefined` yield `null`.\n *\n * Never throws: a value that cannot be serialised is logged and `null` is\n * returned instead.\n *\n * @param data current model value\n */\n public override toJson(data: Date | string): string | null {\n if (data === null || data === undefined) {\n return null;\n }\n if (typeof data === 'string') {\n const d = this.fromJson(data);\n if (d === null) {\n return null;\n }\n data = d;\n }\n try {\n if (this.timezone === null || this.timezone === undefined) {\n const offset = data.getTimezoneOffset();\n const localDate = new Date(data.getTime() - offset * 60000);\n return localDate.toISOString().replace('Z', '');\n } else if (this.timezone === 'UTC') {\n return data.toISOString();\n } else {\n return data.toISOString().replace('Z', '') + this.timezone;\n }\n } catch (e) {\n console.error(e, data);\n return null;\n }\n }\n\n /**\n * Parses the incoming value into a `Date`, honouring `timezone`.\n *\n * With no `timezone` configured, incoming strings are read as local time:\n * a trailing `Z` or a `±HHMM` offset is stripped before parsing, so\n * `'2018-12-10T13:45:00Z'` yields 13:45 *local*, not 13:45 UTC. With a\n * `timezone` set, the string is handed to `Date` untouched. `null`,\n * `undefined` and unparseable values yield `null`.\n *\n * @param data raw value read from the JSON payload\n */\n public override fromJson(data: unknown): Date | null {\n if (data === null || data === undefined) {\n return null;\n }\n let date: Date;\n if (typeof data === 'string') {\n // If we don't have timezone info, we parse all dates as local\n if (this.timezone === null || this.timezone === undefined) {\n if (data.endsWith('Z')) {\n date = new Date(data.replace('Z', ''));\n } else if (data.match(/[-+]\\d{4}$/)) {\n date = new Date(data.replace(/[-+]\\d{4}$/, ''));\n } else {\n date = new Date(data);\n }\n } else {\n date = new Date(data);\n }\n } else {\n date = new Date(data as string | number | Date);\n }\n\n if (date instanceof Date && !isNaN(date.getTime())) {\n return date;\n }\n return null;\n }\n}\n\n/**\n * Declares a calendar-date field (no time of day) — birth dates, due dates,\n * anything where the time component would be noise. Held as a `Date`, sent as\n * a `YYYY-M-D` string built from UTC parts.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @dateField({ description: 'Due date', min: new Date('2024-01-01') })\n * public due!: Date | null;\n * }\n */\nexport const dateField = (updates: IDateFieldMetadata = {}) => genericDataField(updates, 'dateField', DateFieldManager);\n\n/**\n * Declares a date+time field. Defaults to naive local-time handling, which\n * round-trips wall-clock values unchanged; pass `timezone: 'UTC'` when the\n * field represents a true instant.\n *\n * The usual pairing for server-maintained stamps is\n * `{ readonly: true, priority: <low> }`, as `created`/`updated` are written by\n * the API and never by a form.\n *\n * @param updates field options\n */\nexport const datetimeField = (updates: IDatetimeFieldMetadata = {}) =>\n genericDataField(updates, 'datetimeField', DatetimeFieldManager);\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\nimport { DataModel } from '../data-model';\nimport { Collection, DataModelType } from '../data-collection';\nimport { fieldValues } from '../field-values';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\n\n/**\n * Options for {@link foreignKeyField}.\n */\nexport interface IForeignKeyFieldMetadata extends IFieldMetadata<number> {\n /**\n * Name of the target model, e.g. `'Category'`.\n *\n * **Inert.** Nothing in the library ever reads this string: it is not\n * resolved to a class, not validated, and not used to fetch anything. It is\n * a documentary annotation for humans and tooling, and a typo in it has no\n * runtime effect whatsoever.\n *\n * The actual link to the target model is `model:` on the paired\n * {@link detailsField}. If you set `related` and expect the relation to\n * work, it will not — add the `<field>_details` property.\n */\n related?: string;\n}\n\n/**\n * Options for {@link reverseForeignKeyField}.\n */\nexport interface IReverseForeignKeyFieldMetadata extends IFieldMetadata<number> {\n /**\n * Name of the model pointing back at this one.\n *\n * **Inert**, exactly as {@link IForeignKeyFieldMetadata.related}: required\n * by the type, but never read at runtime. Purely documentary; the real\n * deserialisation is done by the paired {@link detailsField}.\n */\n related: string;\n}\n\n/**\n * Options for {@link detailsField}.\n */\nexport interface IDetailsFieldMetadata<T> extends IFieldMetadata<T> {\n /** Name of the id field this details payload belongs to. Declarative only. */\n field?: string;\n /** Deserialise the payload as an array of `model` rather than a single one. */\n many?: boolean;\n /**\n * The target model **class** (a bare reference — not a string, not a\n * `forwardRef`, not a lambda). This is the real link of a relation: it is\n * what instantiates and populates the nested payload.\n */\n model?: DataModelType<DataModel>;\n /**\n * Custom deserialiser, taking precedence over `model`. Use it for payloads\n * that are not models — a plain shape, or a value needing transformation.\n */\n // A narrower parameter would not be assignable to one declared `unknown`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deserialize?: (data: any) => T;\n}\n\n/**\n * Options for {@link manyToManyField}.\n */\nexport interface IManyToManyFieldMetadata extends IFieldMetadata<number[]> {\n /**\n * Name of the target model.\n *\n * **Inert**, exactly as {@link IForeignKeyFieldMetadata.related}: required\n * by the type, but never read at runtime. The real link is `model:` on the\n * paired {@link detailsField}.\n */\n related: string;\n}\n\n/**\n * Manager for the id half of a foreign key. It carries a plain number with\n * pass-through serialisation; its real contribution is selecting the\n * `fkselect` editor and the `fkdetails` display, which are what make a bare\n * id render as a picker and as the related object's label.\n *\n * Both widgets read the sibling `<field>_details` property to do so — see\n * {@link DetailsFieldManager}.\n */\nexport class ForeignKeyFieldManager extends BaseFieldManager<number> implements IForeignKeyFieldMetadata {\n /** Target model name. Inert; see {@link IForeignKeyFieldMetadata.related}. */\n declare public related?: string;\n /** Renders an `fkselect` picker, populated from `<field>_details`. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'fkselect';\n /** Rendered by `fkdetails`, which reads `<field>_details`. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'fkdetails';\n}\n\n/**\n * Manager for the id half of a reverse foreign key. Unlike\n * {@link ForeignKeyFieldManager} it keeps the base text widgets, so it does\n * not render a picker: it marks the relation in metadata and leaves display to\n * the paired {@link detailsField}.\n */\nexport class ReverseForeignKeyFieldManager extends BaseFieldManager<number> implements IForeignKeyFieldMetadata {\n /** Source model name. Inert; see {@link IReverseForeignKeyFieldMetadata.related}. */\n declare public related?: string;\n}\n\n/**\n * Manager for the details half of a relation: it turns a nested JSON payload\n * into model instances (or whatever `deserialize` returns).\n *\n * **Naming is a runtime contract.** `dispedit` and `m2mselect` locate this\n * property by string concatenation, `` `${field}_details` ``, so the property\n * must be named exactly `<fkFieldName>_details` — `category` ⇒\n * `category_details`. The link is by name, never by type: rename one half\n * without the other and display and write-back break silently, with no\n * compile-time or runtime error.\n */\nexport class DetailsFieldManager<T> extends BaseFieldManager<T> implements IDetailsFieldMetadata<T> {\n /** Name of the id field this belongs to. Declarative only. */\n declare public field?: string;\n /** Deserialise an array rather than a single instance. */\n declare public many?: boolean;\n /** Target model class; the real link of the relation. */\n declare public model: DataModelType<DataModel>;\n /** Custom deserialiser, taking precedence over {@link model}. */\n // See IDetailsFieldMetadata.deserialize.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n declare public deserialize?: (data: any) => T;\n\n /**\n * Deserialises the nested payload, taking the first branch that applies:\n *\n * 1. `null` stays `null`, and `undefined` stays `undefined` — the two are\n * kept distinct, so an absent relation and an explicitly empty one remain\n * distinguishable.\n * 2. `deserialize` declared: the payload is handed to it and its result\n * returned as-is.\n * 3. `model` declared: a `new model(coll)` is built and populated via\n * `fromJson` — once, or once per element when `many: true`.\n * 4. Otherwise the raw JSON is passed **through untouched**. A bare\n * `detailsField()` with neither `model` nor `deserialize` is therefore a\n * legitimate way to hold server-computed payloads, string arrays and\n * other shapes that have no model of their own.\n *\n * @param data raw payload read from the JSON\n * @param coll collection handed to each constructed model instance\n */\n public override fromJson(data: unknown, coll?: Collection<DataModel>): T {\n if (data === null) {\n return data as T;\n }\n if (data === undefined) {\n return undefined as T;\n }\n if (this.deserialize) {\n return this.deserialize(data);\n }\n if (this.model) {\n if (!this.many) {\n const d = new this.model(coll);\n d.fromJson(fieldValues(data));\n return d as T;\n } else {\n const out: DataModel[] = [];\n for (const dt of data as unknown[]) {\n const d = new this.model(coll);\n d.fromJson(fieldValues(dt as object));\n out.push(d);\n }\n return out as T;\n }\n }\n return data as T;\n }\n}\n\n/**\n * Same as {@link IManyToManyFieldMetadata} but with `related` optional. It is\n * the interface {@link ManyToManyFieldManager} implements; the decorator's\n * public option type is `IManyToManyFieldMetadata`.\n */\nexport interface IManyToManyKeyFieldMetadata extends IFieldMetadata<number[]> {\n /** Target model name. Inert; see {@link IForeignKeyFieldMetadata.related}. */\n related?: string;\n}\n\n/**\n * Manager for the id half of a many-to-many relation: an array of numbers with\n * pass-through serialisation, rendered with the `m2mselect` editor and the\n * `m2mdetails` display.\n *\n * As with a foreign key, both widgets read the sibling `<field>_details`\n * property, which must be named accordingly.\n */\nexport class ManyToManyFieldManager extends BaseFieldManager<number[]> implements IManyToManyKeyFieldMetadata {\n /** Target model name. Inert; see {@link IManyToManyFieldMetadata.related}. */\n declare public related?: string;\n /** Renders an `m2mselect` multi-picker, populated from `<field>_details`. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'm2mselect';\n /** Rendered by `m2mdetails`, which reads `<field>_details`. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'm2mdetails';\n}\n\n/**\n * Declares the id half of a foreign key: the plain number the API stores.\n *\n * A relation is always **two fields**. This one holds the id; a companion\n * {@link detailsField} named `<thisField>_details` holds the nested object and\n * carries the `model:` that actually links the two. Declaring only the id\n * gives you a number and an empty picker.\n *\n * The id half conventionally takes `priority: -1` (\"load it, never show it\"),\n * since the details half is what a human should see. Its `related:` string is\n * documentation only — see {@link IForeignKeyFieldMetadata.related}.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * // id half — `related` is inert, `priority: -1` hides it from the UI\n * @foreignKeyField({ description: 'Category', related: 'Category', priority: -1 })\n * public category!: number;\n *\n * // details half — MUST be named `category_details`; `model` is the real link\n * @detailsField({ description: 'Category', model: Category, readonly: true, priority: 750 })\n * public category_details?: Category;\n * }\n */\nexport const foreignKeyField = (updates: IForeignKeyFieldMetadata): FieldDecoratorFn =>\n genericDataField(updates, 'foreignKeyField', ForeignKeyFieldManager);\n\n/**\n * Declares the id half of a reverse foreign key — the far side of a relation\n * another model owns. Unlike {@link foreignKeyField} it selects no relation\n * widget, so pair it with a {@link detailsField} for anything to be displayed.\n *\n * @param updates field options\n */\nexport const reverseForeignKeyField = (updates: IReverseForeignKeyFieldMetadata): FieldDecoratorFn =>\n genericDataField(updates, 'reverseForeignKeyField', ReverseForeignKeyFieldManager);\n\n/**\n * Declares the details half of a relation: the nested payload the API embeds\n * next to an id.\n *\n * **The property name is a runtime contract**: it must be exactly\n * `<idFieldName>_details`, because `dispedit` and `m2mselect` build the lookup\n * by concatenating `` `${field}_details` ``. Nothing checks it — get the name\n * wrong and display and write-back fail silently.\n *\n * Normally `readonly: true`: the nested object is rendered, but only the id\n * half is ever sent back. With neither `model` nor `deserialize` the raw JSON\n * is passed through, which is the idiomatic way to hold a server-computed\n * payload — see {@link DetailsFieldManager.fromJson}.\n *\n * @param meta field options\n * @example\n * // Pass-through: no model, so the raw JSON lands on the property as-is\n * @detailsField({ description: 'Labels', readonly: true })\n * public labels_details?: string[];\n */\nexport const detailsField = (meta: IDetailsFieldMetadata<unknown> = {}): FieldDecoratorFn =>\n genericDataField(meta, 'detailsField', DetailsFieldManager);\n\n/**\n * Declares the id half of a many-to-many relation: an array of ids, rendered\n * as a multi-select. Pairs with a `many: true` {@link detailsField} named\n * `<thisField>_details`, exactly as {@link foreignKeyField} does.\n *\n * Give it `defaultValue: []`. Without one the field deserialises to\n * `undefined` and the `m2mselect` editor has no array to work with.\n *\n * @param meta field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @manyToManyField({\n * description: 'Tags',\n * related: 'Tag', // inert: documentation only\n * defaultValue: [], // required in practice\n * priority: -1,\n * })\n * public tags!: number[];\n *\n * // `many: true` is what makes this deserialise an array of models\n * @detailsField({ description: 'Tags', model: Tag, many: true, readonly: true })\n * public tags_details?: Tag[];\n * }\n */\nexport const manyToManyField = (meta: IManyToManyFieldMetadata): FieldDecoratorFn =>\n genericDataField(meta, 'manyToManyField', ManyToManyFieldManager);\n","import { BaseFieldManager, genericDataField, IFieldMetadata } from './base';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\n\n/**\n * Options for {@link booleanField}. Adds nothing to the common metadata; the\n * value type is `boolean | null`, `null` standing for \"unset\".\n */\nexport type IBooleanFieldMetadata = IFieldMetadata<boolean | null>;\n\n/**\n * Manager for boolean fields. Renders a checkbox editor and a `boolean`\n * display, and — its real job — normalises the many shapes a truth value\n * arrives in over the wire (see {@link BooleanFieldManager.fromJson}).\n */\nexport class BooleanFieldManager extends BaseFieldManager<boolean | null> implements IBooleanFieldMetadata {\n /** Renders an `input.checkbox` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.checkbox';\n /** Rendered by the `boolean` display. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'boolean';\n\n /**\n * Coerces an incoming value to `boolean | null`, exactly as follows:\n *\n * - `null` / `undefined`: the default value when the field is `required`,\n * otherwise `null` — which is how a tri-state (true/false/unset) field is\n * modelled.\n * - a real boolean: returned unchanged.\n * - a string: `'true'`, `'1'`, `'ok'` and `'yes'` give `true`; `'false'`,\n * `'0'`, `'nok'` and `'no'` give `false`. **Any other string also gives\n * `true`**, including `''` and `'maybe'` — only the four listed spellings\n * are false. Matching is exact and case-sensitive, so `'True'` and `'YES'`\n * land in that catch-all and yield `true`.\n * - anything else: coerced with `!!data`.\n *\n * @param data raw value read from the JSON payload\n */\n public override fromJson(data: unknown): boolean | null {\n if (data === undefined) {\n if (this.required) {\n return this.getDefaultValue()!;\n } else {\n return null;\n }\n }\n if (data === null) {\n if (this.required) {\n return this.getDefaultValue()!;\n } else {\n return null;\n }\n }\n if (typeof data === 'boolean') {\n return data;\n }\n if (typeof data === 'string') {\n if (['true', '1', 'ok', 'yes'].indexOf(data) !== -1) {\n return true;\n }\n return ['false', '0', 'nok', 'no'].indexOf(data) === -1;\n }\n return !!data;\n }\n}\n\n/**\n * Declares a boolean field, rendered as a checkbox. Tolerant on input: string\n * spellings such as `'yes'` / `'0'` are coerced, so it copes with APIs that do\n * not send real JSON booleans.\n *\n * Left non-required, the field is tri-state — a missing or `null` payload\n * value stays `null` rather than becoming `false`. Set `required: true` with a\n * `defaultValue` to collapse it to a strict true/false.\n *\n * @param updates field options\n */\nexport const booleanField = (updates: IBooleanFieldMetadata = {}) =>\n genericDataField<boolean | null, IBooleanFieldMetadata, BooleanFieldManager>(\n updates,\n 'booleanField',\n BooleanFieldManager,\n );\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\nimport { DISPEDIT_DISPLAY_TYPES, DISPEDIT_EDITOR_TYPES } from '../../dispedit/dispedit/dispedit.constants';\nimport { ValidatorFn, Validators } from '@angular/forms';\n\n/**\n * Options for {@link integerField}.\n */\nexport interface IIntegerFieldMetadata extends IFieldMetadata<number> {\n /** Lower bound; adds `Validators.min`. */\n min?: number;\n /** Upper bound; adds `Validators.max`. */\n max?: number;\n}\n\n/**\n * Options for {@link floatField}.\n */\nexport interface IFloatFieldMetadata extends IFieldMetadata<number> {\n /** Lower bound; adds `Validators.min`. */\n min?: number;\n /** Upper bound; adds `Validators.max`. */\n max?: number;\n}\n\n/**\n * Options for {@link decimalField}.\n */\nexport interface IDecimalFieldMetadata extends IFieldMetadata<number> {\n /** Lower bound; adds `Validators.min`. Compared against the raw stored value. */\n min?: number;\n /** Upper bound; adds `Validators.max`. Compared against the raw stored value. */\n max?: number;\n /**\n * Scaling divisor used **for display only**.\n *\n * This is a trap worth reading twice: `factor` does not take part in\n * `fromJson`/`toJson`. The model property always holds the **raw wire\n * value**. The division happens exclusively in `dispedit` and in the\n * `factor`/`factorc` pipes (`value / factor`), and the editor multiplies\n * back by `factor` on save.\n *\n * So with `factor: 100`, `thing.price` is an integer number of cents:\n * `price === 1250` displays as `12.50`. `min`/`max` and any code reading the\n * property see cents too. Formatting a decimal field without the pipe shows\n * the unscaled value.\n */\n factor?: number;\n}\n\n/**\n * Manager for whole-number fields, and base for the other numeric managers.\n * Renders an `input.number` editor and adds `min`/`max` validators when\n * declared. Values are passed through unchanged by the base (de)serialisers —\n * nothing rounds or coerces to an integer at runtime.\n */\nexport class IntegerFieldManager extends BaseFieldManager<number> implements IIntegerFieldMetadata {\n /** Rendered as plain text. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'text';\n /** Renders an `input.number` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.number';\n\n /** Lower bound; adds `Validators.min`. */\n declare public min?: number;\n /** Upper bound; adds `Validators.max`. */\n declare public max?: number;\n\n /** Required, plus `Validators.min` / `Validators.max` when declared. */\n public override get validators(): ValidatorFn[] {\n const v = super.getValidators();\n if (this.min !== undefined) {\n v.push(Validators.min(this.min));\n }\n if (this.max !== undefined) {\n v.push(Validators.max(this.max));\n }\n return v;\n }\n}\n\n/**\n * Manager for real-number fields. Behaviourally identical to\n * {@link IntegerFieldManager} today — same widgets, same validators, same\n * pass-through serialisation — and exists to distinguish the two field types\n * in metadata.\n */\nexport class FloatFieldManager extends IntegerFieldManager implements IFloatFieldMetadata {\n /** Rendered as plain text. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'text';\n /** Renders an `input.number` editor. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.number';\n}\n\n/**\n * Manager for fixed-point fields stored as scaled integers. It selects the\n * `decimal` / `input.decimal` widgets, which are the pieces that apply\n * {@link IDecimalFieldMetadata.factor}.\n *\n * The manager itself does **not** scale: `fromJson`/`toJson` are the\n * inherited pass-throughs, so the model property holds the raw wire value\n * (cents, with the usual `factor: 100`) and only the display layer divides.\n */\nexport class DecimalFieldManager extends IntegerFieldManager implements IDecimalFieldMetadata {\n /** Display-only scaling divisor. See {@link IDecimalFieldMetadata.factor}. */\n declare public factor?: number;\n /** Rendered by the `decimal` display, which divides by `factor`. */\n public override displayType: DISPEDIT_DISPLAY_TYPES = 'decimal';\n /** Renders an `input.decimal` editor, which multiplies back by `factor` on save. */\n public override editorType: DISPEDIT_EDITOR_TYPES = 'input.decimal';\n}\n\n/**\n * Declares a whole-number field: counts, quantities, positions. Rendered as a\n * number input, with optional `min`/`max` validators.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @integerField({ description: 'Quantity', min: 0, defaultValue: 0 })\n * public quantity!: number;\n * }\n */\nexport const integerField = (updates: IIntegerFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'integerField', IntegerFieldManager);\n\n/**\n * Declares a real-number field, for values where a fractional part is\n * inherent (ratios, measurements, coordinates). Prefer {@link decimalField}\n * for money — floats are the wrong tool for exact amounts.\n *\n * @param updates field options\n */\nexport const floatField = (updates: IFloatFieldMetadata = {}): FieldDecoratorFn =>\n genericDataField(updates, 'floatField', FloatFieldManager);\n\n/**\n * Declares a fixed-point field stored as a scaled integer — the right choice\n * for money and other amounts that must stay exact.\n *\n * The model property holds the **raw, unscaled** value; `factor` only divides\n * at display time and multiplies back on save. See\n * {@link IDecimalFieldMetadata.factor} before using it.\n *\n * Two sharp edges on `factor`. The `{ factor: 100 }` default applies only when\n * the decorator is called with **no argument at all** — passing any options\n * object replaces it wholesale, so `decimalField({ min: 0 })` leaves `factor`\n * undefined, which the display layer treats as `1` (no scaling). Spell\n * `factor` out whenever you pass options.\n *\n * @param updates field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * // `price` holds cents: 1250 displays as 12.50\n * @decimalField({ description: 'Price', factor: 100, min: 0 })\n * public price!: number;\n * }\n */\nexport const decimalField = (updates: IDecimalFieldMetadata = { factor: 100 }): FieldDecoratorFn =>\n genericDataField(updates, 'decimalField', DecimalFieldManager);\n","import { BaseFieldManager, FieldDecoratorFn, genericDataField, IFieldMetadata } from './base';\nimport { DataModel } from '../data-model';\nimport { Collection } from '../data-collection';\nimport { ICharFieldChoice } from './stringfields';\n\n/**\n * Options for {@link computedField}.\n */\nexport interface IComputedFieldMetadata<T> extends IFieldMetadata<T> {\n /** Name of the source field this value is derived from. Declarative only. */\n field?: string;\n /**\n * Display scaling divisor, as on `decimalField`, for a computed value held\n * as a scaled integer. See `IDecimalFieldMetadata.factor`.\n */\n factor?: number;\n /**\n * Choice list used to render the value as a label rather than a raw code.\n * Note that, unlike `charField`, this does **not** switch the editor to a\n * select — a computed field has no editor.\n */\n choices?: ICharFieldChoice[];\n}\n\n/**\n * Manager for computed, display-only fields. It sets `computed = true`, which\n * makes `DataModel.setFV` skip assignment for the field entirely, and its\n * `fromJson` has an empty body — it always returns `undefined`.\n *\n * The combination means the model property is never populated by this manager:\n * the value is expected to come from a getter on the model itself, while the\n * field declaration exists to give that getter metadata (label, priority,\n * display type) so it can appear in generated lists and views.\n */\nexport class ComputedFieldManager<T> extends BaseFieldManager<T> implements IComputedFieldMetadata<T> {\n /** Source field name. Declarative only. */\n declare public field?: string;\n /** Always `true`, which is what makes `DataModel.setFV` skip this field. */\n public override computed = true;\n\n /**\n * Deserialises nothing: the body is empty, so the return is always\n * `undefined`. A computed field takes no value from the payload.\n *\n * @param _data ignored\n * @param _coll ignored\n */\n public override fromJson(_data: unknown, _coll?: Collection<DataModel>): T {\n // A computed field is derived on the client; the payload holds nothing.\n return undefined as T;\n }\n}\n\n/**\n * Declares a display-only field derived on the client, typically backed by a\n * getter on the model.\n *\n * It is **never written**: `fromJson` ignores the payload, and `DataModel.setFV`\n * refuses to assign to it. Reach for it to give a derived value the metadata\n * (label, priority, display type) it needs to show up in generated lists and\n * views, alongside real fields.\n *\n * @param meta field options\n * @example\n * class Thing extends DataModel {\n * static override readonly __name = 'Thing';\n *\n * @integerField({ description: 'Quantity' })\n * public quantity!: number;\n *\n * // Declared for display; the getter below is what produces the value\n * @computedField({ description: 'In stock', priority: 100 })\n * public get in_stock(): boolean {\n * return this.quantity > 0;\n * }\n * }\n */\nexport const computedField = (meta: IComputedFieldMetadata<unknown> = {}): FieldDecoratorFn =>\n genericDataField(meta, 'computedField', ComputedFieldManager);\n","/**\n * Public barrel for the field decorators — the library's primary API.\n *\n * Decorate a `DataModel` subclass (which must declare a `static __name`) with\n * these to describe each field once: the declaration then drives JSON\n * (de)serialisation, form controls and validators, and the widget `dispedit`\n * renders for the field.\n *\n * Only the decorators are re-exported here; the matching `*Manager` classes\n * and `I*Metadata` option interfaces are exported from their own modules.\n */\nexport { charField, emailField, textField, passwordField } from './stringfields';\nexport { primaryField } from './primaryfield';\nexport { dateField, datetimeField } from './datetime';\nexport { foreignKeyField, manyToManyField, reverseForeignKeyField, detailsField } from './relations';\nexport { booleanField } from './boolean';\nexport { decimalField, integerField, floatField } from './numbers';\nexport { computedField } from './computed';\n","import { Component, DestroyRef, inject, input, OnInit, signal } from '@angular/core';\nimport { DataMessageService, Message } from '../message.service';\n\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'data-message-zone',\n templateUrl: './message-zone.component.html',\n styleUrls: ['./message-zone.component.sass'],\n imports: [],\n})\n/**\n * Renders the notifications pushed through {@link DataMessageService} as dismissible\n * Bootstrap alerts.\n *\n * Place one instance in the application shell — typically next to the router outlet, so\n * it survives navigation. Without it, everything the library reports (dispedit save\n * errors, flag toggles, expired sessions) is queued and expires unseen. Each alert\n * carries a close button, and clicking the body toggles the stored trace, which is\n * useful for surfacing backend error details.\n */\nexport class MessageZoneComponent implements OnInit {\n /**\n * Currently unused: it is declared but never read, so it does not filter anything.\n */\n public filter = input<string>();\n /** Messages to render, mirrored from the service stream. */\n public current = signal<Message[]>([]);\n public messages = inject(DataMessageService);\n private destroy$ = inject(DestroyRef);\n\n public ngOnInit(): void {\n this.messages.current.pipe(takeUntilDestroyed(this.destroy$)).subscribe((messages) => {\n this.current.set(messages);\n });\n }\n}\n","<div class=\"messagezone\">\n @for (message of current(); track message) {\n <div\n class=\"alert\"\n animate.enter=\"fade-enter\"\n animate.leave=\"fade-leave\"\n [class]=\"message.style\"\n (click)=\"message.showTrace = !message.showTrace\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"message.showTrace\"\n aria-label=\"Afficher la trace\"\n (keydown.enter)=\"message.showTrace = !message.showTrace\"\n (keydown.space)=\"$event.preventDefault(); message.showTrace = !message.showTrace\"\n >\n <button class=\"btn-close\" type=\"button\" (click)=\"messages.ack(message)\" aria-label=\"Close\"></button>\n <strong>{{ message.title }}</strong>\n &nbsp; {{ message.message }}\n @if (message.showTrace) {\n <div class=\"pretrace\">{{ message.trace }}</div>\n }\n </div>\n }\n</div>\n","import { DataModel } from './data-model';\nimport { CollectionMock } from './data-collection.mock';\nimport { FilterData, IQueryMeta, IQuerysetOptions, SortData } from './data-query';\nimport { combineLatest, Observable, of } from 'rxjs';\n\n/**\n * Test double for {@link Queryset}, handed out by `CollectionMock.queryset()`.\n *\n * Lets you test list components — tables, paginators, filter bars — without HTTP:\n * set {@link mockData} and every read hands back exactly those rows, synchronously.\n *\n * The important caveat is that this double is **inert**. {@link filter},\n * {@link sort}, {@link paginateBy} and {@link setPage} accept their arguments,\n * discard them and return `this`, so chaining compiles and runs but changes\n * nothing: `mockData` comes back whatever you filtered by. That makes it right\n * for testing how a component *renders* rows and *reacts* to them, and wrong for\n * asserting that the component queried correctly — for the latter, spy on these\n * methods or use a real queryset against `HttpTestingController`.\n *\n * Reachable through `CollectionMock`, though not exported from the public API\n * under its own name.\n *\n * @example\n * ```ts\n * const things = new CollectionMock<Thing>(Thing);\n * const qs = things.queryset();\n * qs.mockData = things.fromJson([{ id: 1, name: 'a' }], true);\n * qs.get().subscribe((rows) => expect(rows.length).toBe(1));\n * ```\n */\nexport class QuerysetMock<T extends DataModel> {\n /**\n * Rows this queryset hands back. Falls through to the parent mock's\n * `mockValues` while left empty — but note the fallback is `||` on an array, so\n * the *default* `[]` is falsy-checked as an object and never triggers it: an\n * explicitly emptied `mockData` still shadows the collection's values.\n */\n public mockData: T[] = [];\n\n /** Present to match {@link Queryset}'s shape; never read or written by this mock. */\n public filterData: FilterData = {};\n /** Present to match {@link Queryset}'s shape; never read or written by this mock. */\n public sortData: SortData[] = [];\n /** Present to match {@link Queryset}'s shape; {@link paginateBy} does not update it. */\n public pageSize = 100;\n /** Present to match {@link Queryset}'s shape; {@link setPage} does not update it. */\n public page = 1;\n\n /**\n * Always `true` — unlike the real queryset, this is never flipped by\n * {@link get}. Components that branch on `pristine` to show an empty state\n * therefore behave as if no fetch had happened; set it yourself if that matters.\n */\n public pristine = true;\n /**\n * Always emits `false`, once. The mock resolves synchronously, so there is no\n * in-flight state to represent; components that gate rendering on `loading` see\n * a settled queryset from the start.\n */\n public loading = of(false);\n\n /**\n * @param _coll parent mock, used as the fallback source of rows\n * @param options recorded to match `Queryset`'s shape; no option is acted on\n */\n\n constructor(\n protected _coll: CollectionMock<T>,\n public options: IQuerysetOptions = {},\n ) {}\n\n /** Emits {@link mockData} (or the parent's `mockValues`) immediately, then completes. */\n public get results(): Observable<T[]> {\n return of(this.mockData || this._coll.mockValues);\n }\n\n /**\n * Emits a fixed, arbitrary pagination envelope (100 rows over 10 pages of 10) —\n * it bears no relation to {@link mockData}. Good enough to render a paginator,\n * useless for asserting counts; stub this getter when a test needs specific\n * numbers.\n */\n public get meta(): Observable<IQueryMeta> {\n return of({\n nav: { count: 100, next: 1, page: 1, pages: 10, prev: null, size: 10 },\n parameters: { page: 'page', page_size: 'page_size' },\n });\n }\n\n /** `[results, loading, meta]` combined, mirroring `Queryset.full`. */\n public get full(): Observable<[T[], boolean, IQueryMeta]> {\n return combineLatest([this.results, this.loading, this.meta]);\n }\n\n /** No-op returning `this`; the filter is discarded. See the class-level caveat. */\n public filter(_params: FilterData = {}): QuerysetMock<T> {\n return this;\n }\n\n /** No-op returning `this`; the ordering is discarded. See the class-level caveat. */\n public sort(..._sorting: string[]): QuerysetMock<T> {\n return this;\n }\n\n /** No-op returning `this`; {@link pageSize} is left untouched. */\n public paginateBy(_pageSize = 20): QuerysetMock<T> {\n return this;\n }\n\n /** No-op returning `this`; {@link page} is left untouched. */\n public setPage(_page: number): QuerysetMock<T> {\n return this;\n }\n\n /** Always returns `{}`, since no query state is retained. */\n public getQueryParams(): FilterData {\n return {};\n }\n\n /**\n * Emits the canned rows immediately. Takes no `refresh`/`sync` arguments, as\n * there is nothing to refresh; unlike the real `get()`, it leaves\n * {@link pristine} at `true`.\n */\n public get(): Observable<T[]> {\n return of(this.mockData || this._coll.mockValues);\n }\n}\n","import { DataModel } from './data-model';\nimport { Observable, of } from 'rxjs';\nimport { IQuerysetOptions } from './data-query';\nimport { QuerysetMock } from './data-query.mock';\nimport { Collection, IActionParams, IHttpMethod } from './data-collection';\n\n/**\n * Test double for {@link Collection}: same shape, no HTTP.\n *\n * This is how consumers test components that take a collection. Instead of\n * configuring `HttpClient`, `HttpTestingController` and a `DATA_API_URL`, you\n * hand the component a `CollectionMock`, set the canned values on it, and every\n * read resolves synchronously to those. {@link fromJson} is real, so the\n * instances handed out are genuine models with genuine field metadata — which is\n * what makes it a useful double for metadata-driven UI rather than a stub that\n * only returns plain objects.\n *\n * It deliberately does *not* extend `Collection` — it duplicates the read half of\n * the API structurally, so components typed against `Collection<T>` usually need\n * an `as any` at the injection point. The write half (`save`, `update`,\n * `delete`, `create`, `raw`, `blob`, `getUrl`) is **not implemented**; testing\n * those needs a real collection over `HttpTestingController`.\n *\n * See `projects/data/src/examples/catalog/catalog.spec.ts` for a worked example.\n *\n * @example\n * ```ts\n * const things = new CollectionMock<Thing>(Thing);\n * things.mockValues = things.fromJson([{ id: 1, name: 'a' }], true);\n * things.mockValue = things.fromJson({ id: 1, name: 'a' });\n *\n * TestBed.configureTestingModule({\n * providers: [{ provide: ThingService, useValue: things }],\n * });\n * ```\n */\nexport class CollectionMock<T extends DataModel> {\n /** Canned instance returned by every {@link fetch}, whatever the id. */\n public mockValue?: T;\n /**\n * Canned rows returned by {@link list}, and the fallback for\n * `QuerysetMock.get()` when the queryset has no `mockData` of its own.\n */\n public mockValues?: T[];\n /** Canned payload returned by every {@link action}, whatever the action name. */\n public actionValue: any;\n\n /**\n * @param model model class to instantiate in {@link fromJson}; pass the same\n * class the real collection is built on\n */\n constructor(protected model: new (coll: Collection<T>) => T) {}\n\n /**\n * Returns {@link mockValue}, ignoring the arguments entirely — including the\n * id, so a test that fetches two different ids gets the same instance back.\n * Reassign `mockValue` between calls if that matters.\n */\n public fetch(_id: number, _suffix = ''): Observable<T> {\n return of(this.mockValue as T);\n }\n\n /**\n * Returns {@link actionValue}, ignoring the arguments. Since it does not record\n * the call, assert on the effects rather than on the invocation, or spy on this\n * method when you need to check what was requested.\n */\n public action(_model: T | null, _method: IHttpMethod, _action: string, _params: IActionParams): Observable<any> {\n return of(this.actionValue);\n }\n\n /**\n * Opens a {@link QuerysetMock} backed by this mock, mirroring\n * `Collection.queryset()`. With no `mockData` set on it, the queryset falls\n * back to this mock's {@link mockValues}.\n */\n public queryset(options: IQuerysetOptions = {}): QuerysetMock<T> {\n return new QuerysetMock<T>(this, options);\n }\n\n /**\n * Returns `{ results: mockValues }` — the paginated envelope, matching what the\n * real `Collection.list()` unwraps. Arguments are ignored, so filters are not\n * applied; set {@link mockValues} to whatever the filtered result should be.\n */\n public list(_query: Record<string, string> = {}, _suffix = ''): Observable<any> {\n return of({ results: this.mockValues });\n }\n\n /**\n * Builds real model instances from JSON, exactly as a live collection would —\n * this is the method you use to prepare {@link mockValue}/{@link mockValues}.\n *\n * Two departures from `Collection.fromJson()` worth knowing when writing\n * fixtures. Arrays need `many: true` explicitly rather than being detected. And\n * a single object is only converted when it carries an `id`; anything else is\n * handed back **unchanged**, as a plain object rather than a model — so a\n * fixture for an unsaved record silently fails to become one.\n *\n * @param data JSON object or array of them\n * @param many set to `true` when `data` is an array\n */\n fromJson(data: any, many = false): any {\n if (data && data.id !== undefined) {\n const m = new this.model(this as any);\n m.fromJson(data);\n return m;\n } else {\n if (many && data && data.length) {\n const out: T[] = [];\n for (const r of data) {\n const ri = new this.model(this as any);\n ri.fromJson(r);\n out.push(ri);\n }\n return out;\n }\n return data;\n }\n }\n}\n","import { Subscription } from 'rxjs';\n\n/**\n * Limits applied to a queue, passed to the `options` input of the file select/drop\n * directives. Every field is a ceiling; omitted ones mean \"no limit\".\n */\nexport interface UploaderOptions {\n /** How many uploads may run at once. Use `Number.POSITIVE_INFINITY` for unbounded. */\n concurrency: number;\n /** Accepted MIME types; `['*']` (the default) accepts everything. Files failing this are emitted as `rejected`. */\n allowedContentTypes?: string[];\n /** Maximum number of files that may sit in the queue at once. */\n maxUploads?: number;\n /** Maximum accepted size per file, in bytes. */\n maxFileSize?: number;\n}\n\n/** A `Blob` that carries a filename, i.e. the shape of a `File` as the uploader sends it. */\nexport interface BlobFile extends Blob {\n name: string;\n}\n\n/** Where a queued file stands: waiting, in flight, finished, or aborted. */\nexport enum UploadStatus {\n Queue,\n Uploading,\n Done,\n Cancelled,\n}\n\n/**\n * Live progress of one file. `data` is present from the moment the file is queued, with\n * throughput and ETA figures filled in as the transfer advances.\n */\nexport interface UploadProgress {\n status: UploadStatus;\n data?: {\n percentage: number;\n speed: number;\n speedHuman: string;\n startTime: number | null;\n endTime: number | null;\n eta: number | null;\n etaHuman: string | null;\n };\n}\n\n/**\n * A file tracked by the uploader, from selection through to the server's response.\n *\n * The same object is mutated in place as the upload advances, so `progress` and the\n * `response*` fields change under you; `id` is what {@link UploadInput} commands refer to.\n */\nexport interface UploadFile {\n /** Random identifier generated on queueing; used to target this file in `cancel` and `remove` commands. */\n id: string;\n /** Position of the file within the batch it was added with, not within the queue. */\n fileIndex: number;\n lastModifiedDate: Date;\n name: string;\n size: number;\n /** MIME type as reported by the browser, matched against {@link UploaderOptions.allowedContentTypes}. */\n type: string;\n /** Multipart body sent for this file; extra `data` fields from the upload command are appended to it. */\n form: FormData;\n /** Live status and throughput figures, updated as the transfer progresses. */\n progress: UploadProgress;\n /** Response body, parsed as JSON when possible and left as raw text otherwise. Set once done. */\n response?: unknown;\n /** HTTP status code of the response. Set once done — note that a 4xx/5xx still completes as `done`. */\n responseStatus?: number;\n /** Subscription of the in-flight request, used to cancel it. */\n sub?: Subscription;\n /** The underlying browser `File`, i.e. what is actually transferred. */\n nativeFile?: File;\n /** Response headers, parsed into a plain object. Set once done. */\n responseHeaders?: Record<string, string>;\n}\n\n/**\n * An event emitted by the uploader on the `uploadOutput` output of the directives.\n *\n * Switch on `type` to drive your UI: `addedToQueue`/`allAddedToQueue` after selection,\n * `rejected` for files refused by the options, `start`/`uploading`/`done` over a\n * transfer's life, `cancelled`/`removed`/`removedAll` for queue edits, and\n * `dragOver`/`dragOut`/`drop` for drop-zone hover states.\n */\nexport interface UploadOutput {\n type:\n | 'addedToQueue'\n | 'allAddedToQueue'\n | 'uploading'\n | 'done'\n | 'start'\n | 'cancelled'\n | 'dragOver'\n | 'dragOut'\n | 'drop'\n | 'removed'\n | 'removedAll'\n | 'rejected';\n file?: UploadFile;\n nativeFile?: File;\n}\n\n/**\n * A command sent *to* the uploader by emitting it on the `EventEmitter` bound to the\n * directives' `uploadInput`.\n *\n * `uploadAll` and `uploadFile` carry the request details (url, method, headers, extra\n * data); the queue-management commands only need `type` and, where relevant, `id`.\n */\nexport interface UploadInput {\n type: 'uploadAll' | 'uploadFile' | 'cancel' | 'cancelAll' | 'remove' | 'removeAll';\n /** Target endpoint for `uploadAll`/`uploadFile`. Defaults to an empty string, which posts to the current url. */\n url?: string;\n /** HTTP method to use; defaults to `POST`. */\n method?: string;\n /** {@link UploadFile.id} to act on, required by `cancel` and `remove`. */\n id?: string;\n /** Multipart field name the file is sent under; defaults to `file`. */\n fieldName?: string;\n fileIndex?: number;\n /** The queued file to send with `uploadFile`; matched by identity against the queue. */\n file?: UploadFile;\n /** Extra form fields appended to the multipart body alongside the file. */\n data?: Record<string, string | Blob>;\n /** Extra request headers. Note the uploader uses `XMLHttpRequest` directly, so Angular HTTP interceptors — including the auth interceptor — do not apply; add any `Authorization` header here yourself. */\n headers?: Record<string, string>;\n includeWebKitFormBoundary?: boolean; // If false, only the file is send trough xhr.send (WebKitFormBoundary is omit)\n /** Sends credentials (cookies) cross-origin; defaults to `false`. */\n withCredentials?: boolean;\n}\n","import { EventEmitter } from '@angular/core';\nimport { Observable, Subject, Subscription } from 'rxjs';\nimport { finalize, mergeMap } from 'rxjs/operators';\nimport { BlobFile, UploadFile, UploadInput, UploadOutput, UploadStatus } from './interfaces';\n\n/**\n * Formats a byte count as a short human-readable string using binary (1024) steps, e.g.\n * `1.5 MB`. Used for the uploader's speed readouts, and generic enough for file sizes in\n * your own UI.\n */\nexport function humanizeBytes(bytes: number): string {\n if (bytes === 0) {\n return '0 Byte';\n }\n\n const k = 1024;\n const sizes: string[] = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];\n const i: number = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\n/**\n * The upload engine behind {@link NgFileSelectDirective} and {@link NgFileDropDirective}:\n * it owns the queue, enforces the option limits, and runs the transfers.\n *\n * Despite the name it is a plain class, not an Angular service — each directive news up\n * its own instance in `ngOnInit`, so a queue is scoped to one input or drop zone. Use the\n * directives rather than instantiating it directly unless you are building a custom host.\n *\n * Transfers go through `XMLHttpRequest` rather than `HttpClient`, in order to get upload\n * progress events; a consequence is that Angular's HTTP interceptors never see these\n * requests, so authentication headers must be passed explicitly on the\n * {@link UploadInput}.\n */\nexport class DataUploaderService {\n /** Files currently held, in insertion order. Mutated in place as files are added, cancelled or removed. */\n queue: UploadFile[];\n /** Stream of {@link UploadOutput} events; the directives forward it to their `uploadOutput` output. */\n serviceEvents: EventEmitter<UploadOutput>;\n /** Internal work queue; the `concurrency` limit is applied to it via `mergeMap`. */\n uploadScheduler: Subject<{ file: UploadFile; event: UploadInput }>;\n /** Per-file transfer subscriptions, kept so `cancel`/`cancelAll` can abort them. */\n subs: { id: string; sub: Subscription }[];\n contentTypes: string[];\n maxUploads: number;\n maxFileSize: number;\n\n /**\n * Builds a queue and starts its scheduler. All limits default to unbounded and all\n * content types are accepted.\n *\n * @param concurrency - how many transfers may run simultaneously.\n */\n constructor(\n concurrency: number = Number.POSITIVE_INFINITY,\n contentTypes: string[] = ['*'],\n maxUploads: number = Number.POSITIVE_INFINITY,\n maxFileSize: number = Number.POSITIVE_INFINITY,\n ) {\n this.queue = [];\n this.serviceEvents = new EventEmitter<UploadOutput>();\n this.uploadScheduler = new Subject();\n this.subs = [];\n this.contentTypes = contentTypes;\n this.maxUploads = maxUploads;\n this.maxFileSize = maxFileSize;\n\n this.uploadScheduler\n .pipe(mergeMap((upload) => this.startUpload(upload), concurrency))\n .subscribe((uploadOutput) => this.serviceEvents.emit(uploadOutput));\n }\n\n /**\n * Screens a batch of freshly selected or dropped files against the content type, queue\n * length and file size limits, queueing those that pass and emitting `rejected` for the\n * rest.\n *\n * Called by the directives on `change` and `drop`. Emits `addedToQueue` per accepted\n * file and a single `allAddedToQueue` at the end — the latter is the signal to act on if\n * you want to auto-start an upload.\n */\n handleFiles(incomingFiles: FileList): void {\n let acc: File[] = [];\n\n for (let i = 0; i < incomingFiles.length; i++) {\n const futureQueueLength = acc.length + this.queue.length + 1;\n const checkFile = incomingFiles[i];\n if (\n this.isContentTypeAllowed(checkFile.type) &&\n futureQueueLength <= this.maxUploads &&\n this.isFileSizeAllowed(checkFile.size)\n ) {\n acc = acc.concat(checkFile);\n } else {\n const rejectedFile: UploadFile = this.makeUploadFile(checkFile, i);\n this.serviceEvents.emit({ type: 'rejected', file: rejectedFile });\n }\n }\n for (let i = 0; i < acc.length; i++) {\n const file = acc[i];\n const uploadFile: UploadFile = this.makeUploadFile(file, i);\n this.serviceEvents.emit({ type: 'addedToQueue', file: uploadFile });\n this.queue.push(uploadFile);\n }\n this.serviceEvents.emit({ type: 'allAddedToQueue' });\n }\n\n /**\n * Wires an application-owned emitter as the command channel, so emitting an\n * {@link UploadInput} on it starts, cancels or clears uploads.\n *\n * The directives call this with whatever emitter is bound to their `uploadInput` and\n * unsubscribe on destroy.\n */\n initInputEvents(input: EventEmitter<UploadInput>): Subscription {\n return input.subscribe((event: UploadInput) => {\n switch (event.type) {\n case 'uploadFile': {\n const uploadFileIndex = this.queue.findIndex((file) => file === event.file);\n if (uploadFileIndex !== -1 && event.file) {\n this.uploadScheduler.next({\n file: this.queue[uploadFileIndex],\n event: event,\n });\n }\n break;\n }\n case 'uploadAll': {\n const files = this.queue.filter((file) => file.progress.status === UploadStatus.Queue);\n files.forEach((file) => this.uploadScheduler.next({ file: file, event: event }));\n break;\n }\n case 'cancel': {\n const id = event.id || null;\n if (!id) {\n return;\n }\n const subs = this.subs.filter((sub) => sub.id === id);\n subs.forEach((sub) => {\n if (sub.sub) {\n sub.sub.unsubscribe();\n const fileIndex = this.queue.findIndex((file) => file.id === id);\n if (fileIndex !== -1) {\n this.queue[fileIndex].progress.status = UploadStatus.Cancelled;\n this.serviceEvents.emit({\n type: 'cancelled',\n file: this.queue[fileIndex],\n });\n }\n }\n });\n break;\n }\n case 'cancelAll':\n this.subs.forEach((sub) => {\n if (sub.sub) {\n sub.sub.unsubscribe();\n }\n\n const file = this.queue.find((uploadFile) => uploadFile.id === sub.id);\n if (file) {\n file.progress.status = UploadStatus.Cancelled;\n this.serviceEvents.emit({ type: 'cancelled', file: file });\n }\n });\n break;\n case 'remove': {\n if (!event.id) {\n return;\n }\n\n const i = this.queue.findIndex((file) => file.id === event.id);\n if (i !== -1) {\n const file = this.queue[i];\n this.queue.splice(i, 1);\n this.serviceEvents.emit({ type: 'removed', file: file });\n }\n break;\n }\n case 'removeAll':\n if (this.queue.length) {\n this.queue = [];\n this.serviceEvents.emit({ type: 'removedAll' });\n }\n break;\n }\n });\n }\n\n /**\n * Wraps one {@link uploadFile} transfer so its subscription is registered for later\n * cancellation. Invoked by the scheduler under the concurrency limit rather than\n * directly.\n */\n startUpload(upload: { file: UploadFile; event: UploadInput }): Observable<UploadOutput> {\n return new Observable((observer) => {\n const sub = this.uploadFile(upload.file, upload.event)\n .pipe(\n finalize(() => {\n if (!observer.closed) {\n observer.complete();\n }\n }),\n )\n .subscribe({\n next: (output) => {\n observer.next(output);\n },\n error: (err) => {\n observer.error(err);\n observer.complete();\n },\n complete: () => {\n observer.complete();\n },\n });\n\n this.subs.push({ id: upload.file.id, sub: sub });\n });\n }\n\n /**\n * Performs the actual `XMLHttpRequest` transfer for one file, emitting `uploading` as\n * progress arrives and `done` when the request completes.\n *\n * Unsubscribing aborts the request. By default the file is sent as multipart form data\n * alongside `event.data`; set `includeWebKitFormBoundary: false` to send the raw file as\n * the body instead. Completion is reported for any HTTP status — inspect\n * {@link UploadFile.responseStatus} to tell success from a server-side error.\n */\n uploadFile(file: UploadFile, event: UploadInput): Observable<UploadOutput> {\n return new Observable((observer) => {\n const url = event.url || '';\n const method = event.method || 'POST';\n const data = event.data || {};\n const headers = event.headers || {};\n\n const xhr = new XMLHttpRequest();\n const time: number = new Date().getTime();\n let progressStartTime: number = (file.progress.data && file.progress.data.startTime) || time;\n let speed = 0;\n let eta: number | null = null;\n\n xhr.upload.addEventListener(\n 'progress',\n (e: ProgressEvent) => {\n if (e.lengthComputable) {\n const percentage = Math.round((e.loaded * 100) / e.total);\n const diff = new Date().getTime() - time;\n speed = Math.round((e.loaded / diff) * 1000);\n progressStartTime = (file.progress.data && file.progress.data.startTime) || new Date().getTime();\n eta = Math.ceil((e.total - e.loaded) / speed);\n\n file.progress = {\n status: UploadStatus.Uploading,\n data: {\n percentage: percentage,\n speed: speed,\n speedHuman: `${humanizeBytes(speed)}/s`,\n startTime: progressStartTime,\n endTime: null,\n eta: eta,\n etaHuman: this.secondsToHuman(eta),\n },\n };\n\n observer.next({ type: 'uploading', file: file });\n }\n },\n false,\n );\n\n xhr.upload.addEventListener('error', (e: Event) => {\n observer.error(e);\n observer.complete();\n });\n\n xhr.onreadystatechange = () => {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n const speedAverage = Math.round((file.size / (new Date().getTime() - progressStartTime)) * 1000);\n file.progress = {\n status: UploadStatus.Done,\n data: {\n percentage: 100,\n speed: speedAverage,\n speedHuman: `${humanizeBytes(speedAverage)}/s`,\n startTime: progressStartTime,\n endTime: new Date().getTime(),\n eta: eta,\n etaHuman: this.secondsToHuman(eta || 0),\n },\n };\n\n file.responseStatus = xhr.status;\n try {\n file.response = JSON.parse(xhr.response as string);\n } catch {\n file.response = xhr.response;\n }\n\n file.responseHeaders = this.parseResponseHeaders(xhr.getAllResponseHeaders());\n\n observer.next({ type: 'done', file: file });\n\n observer.complete();\n }\n };\n\n xhr.open(method, url, true);\n xhr.withCredentials = !!event.withCredentials;\n\n try {\n const uploadFile = file.nativeFile as BlobFile;\n const uploadIndex = this.queue.findIndex((outFile) => outFile.nativeFile === uploadFile);\n\n if (this.queue[uploadIndex].progress.status === UploadStatus.Cancelled) {\n observer.complete();\n }\n\n Object.keys(headers).forEach((key) => xhr.setRequestHeader(key, headers[key]));\n\n let bodyToSend: FormData | BlobFile;\n\n if (event.includeWebKitFormBoundary !== false) {\n Object.keys(data).forEach((key) => file.form.append(key, data[key]));\n file.form.append(event.fieldName || 'file', uploadFile, uploadFile.name);\n bodyToSend = file.form;\n } else {\n bodyToSend = uploadFile;\n }\n\n this.serviceEvents.emit({ type: 'start', file: file });\n xhr.send(bodyToSend);\n } catch {\n observer.complete();\n }\n\n return () => {\n xhr.abort();\n };\n });\n }\n\n /** Formats a number of seconds as `HH:MM:SS`, for the ETA readout. Values of a day or more wrap around. */\n secondsToHuman(sec: number): string {\n return new Date(sec * 1000).toISOString().substring(11, 11 + 8);\n }\n\n /** Generates the short random {@link UploadFile.id} given to each queued file. Random, not collision-proof. */\n generateId(): string {\n return Math.random().toString(36).substring(7);\n }\n\n /**\n * Replaces the accepted MIME types after construction, e.g. when the allowed types\n * depend on user input. A list containing `'*'`, or any non-array value, resets it to\n * \"accept everything\".\n */\n setContentTypes(contentTypes: string[]): void {\n if (typeof contentTypes !== 'undefined' && contentTypes instanceof Array) {\n if (contentTypes.find((type: string) => type === '*') !== undefined) {\n this.contentTypes = ['*'];\n } else {\n this.contentTypes = contentTypes;\n }\n return;\n }\n this.contentTypes = ['*'];\n }\n\n /** Whether the queue is in \"accept everything\" mode, i.e. `'*'` is among the content types. */\n allContentTypesAllowed(): boolean {\n return this.contentTypes.find((type: string) => type === '*') !== undefined;\n }\n\n /**\n * Whether a MIME type passes the filter. Matching is exact string equality, so wildcard\n * patterns such as `image/*` are not supported — only the bare `'*'` is.\n */\n isContentTypeAllowed(mimetype: string): boolean {\n if (this.allContentTypesAllowed()) {\n return true;\n }\n return this.contentTypes.find((type: string) => type === mimetype) !== undefined;\n }\n\n /** Whether a file is within {@link maxFileSize}. A falsy limit (including `0`) means no limit. */\n isFileSizeAllowed(fileSize: number): boolean {\n if (!this.maxFileSize) {\n return true;\n }\n return fileSize <= this.maxFileSize;\n }\n\n /**\n * Wraps a browser `File` into the {@link UploadFile} the queue works with, assigning it\n * an id and a zeroed progress record. Used for accepted and rejected files alike.\n */\n makeUploadFile(file: File, index: number): UploadFile {\n return {\n fileIndex: index,\n id: this.generateId(),\n name: file.name,\n size: file.size,\n type: file.type,\n form: new FormData(),\n progress: {\n status: UploadStatus.Queue,\n data: {\n percentage: 0,\n speed: 0,\n speedHuman: `${humanizeBytes(0)}/s`,\n startTime: null,\n endTime: null,\n eta: null,\n etaHuman: null,\n },\n },\n lastModifiedDate: new Date(file.lastModified),\n sub: undefined,\n nativeFile: file,\n };\n }\n\n private parseResponseHeaders(httpHeaders: string): Record<string, string> {\n if (!httpHeaders) {\n return {};\n }\n\n return httpHeaders\n .split('\\n')\n .map((x: string) => x.split(/: */, 2))\n .filter((x: string[]) => x[0])\n .reduce((acc: Record<string, string>, x: string[]) => {\n acc[x[0]] = x[1];\n return acc;\n }, {});\n }\n}\n","import { Directive, ElementRef, EventEmitter, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport { UploaderOptions, UploadInput, UploadOutput } from './interfaces';\nimport { DataUploaderService } from './ngx-uploader.class';\nimport { Subscription } from 'rxjs';\n\n@Directive({\n selector: '[dataFileDrop]',\n host: {\n '(drop)': 'onDrop($event)',\n '(dragover)': 'onDragOver($event)',\n '(dragleave)': 'onDragLeave($event)',\n },\n})\n/**\n * Turns any element into a drag-and-drop upload zone.\n *\n * Apply `dataFileDrop` to a container, bind `uploadOutput` to follow the queue and bind an\n * `EventEmitter<UploadInput>` to `uploadInput` to command it. Alongside the usual queue\n * events, it emits `dragOver`, `dragOut` and `drop`, which is what you hook to highlight\n * the zone while a file hovers over it. Drag events on the host are cancelled so the\n * browser does not navigate to the dropped file.\n *\n * The directive owns its own queue, so two drop zones do not share state.\n */\nexport class NgFileDropDirective implements OnInit, OnDestroy {\n /** Queue limits ({@link UploaderOptions}). Read once in `ngOnInit`; later changes have no effect. */\n public options = input<UploaderOptions>();\n /** Command channel: emit {@link UploadInput}s on it to start, cancel or clear uploads. */\n public uploadInput = input<EventEmitter<UploadInput>>();\n /** Queue and transfer events ({@link UploadOutput}), including the drag state events. */\n public uploadOutput = output<UploadOutput>();\n\n /** The queue backing this drop zone, created in `ngOnInit`. */\n public upload!: DataUploaderService;\n public el!: HTMLInputElement;\n public elementRef = inject(ElementRef);\n\n private _sub!: Subscription[];\n\n ngOnInit() {\n this._sub = [];\n const options = this.options();\n const concurrency = (options && options.concurrency) || Number.POSITIVE_INFINITY;\n const allowedContentTypes = (options && options.allowedContentTypes) || ['*'];\n const maxUploads = (options && options.maxUploads) || Number.POSITIVE_INFINITY;\n const maxFileSize = (options && options.maxFileSize) || Number.POSITIVE_INFINITY;\n this.upload = new DataUploaderService(concurrency, allowedContentTypes, maxUploads, maxFileSize);\n\n this.el = this.elementRef.nativeElement as HTMLInputElement;\n\n this._sub.push(\n this.upload.serviceEvents.subscribe((event: UploadOutput) => {\n this.uploadOutput.emit(event);\n }),\n );\n\n const uploadInput = this.uploadInput();\n if (uploadInput instanceof EventEmitter) {\n this._sub.push(this.upload.initInputEvents(uploadInput));\n }\n\n this.el.addEventListener('drop', this.stopEvent, false);\n this.el.addEventListener('dragenter', this.stopEvent, false);\n this.el.addEventListener('dragover', this.stopEvent, false);\n }\n\n ngOnDestroy() {\n if (this._sub) {\n this._sub.forEach((sub) => sub.unsubscribe());\n }\n }\n\n stopEvent = (e: Event) => {\n e.stopPropagation();\n e.preventDefault();\n };\n\n /** Handles a drop: emits `drop`, then screens and queues the dropped files. Bound to the host `drop` event. */\n public onDrop(e: DragEvent) {\n e.stopPropagation();\n e.preventDefault();\n\n const event: UploadOutput = { type: 'drop' };\n this.uploadOutput.emit(event);\n if (e.dataTransfer) {\n this.upload.handleFiles(e.dataTransfer.files);\n }\n }\n\n /** Emits `dragOver` while a drag hovers the zone, for highlighting it. Bound to the host `dragover` event. */\n public onDragOver(e: Event) {\n if (!e) {\n return;\n }\n\n const event: UploadOutput = { type: 'dragOver' };\n this.uploadOutput.emit(event);\n }\n\n /** Emits `dragOut` when a drag leaves the zone, to clear the highlight. Bound to the host `dragleave` event. */\n public onDragLeave(e: Event) {\n if (!e) {\n return;\n }\n\n const event: UploadOutput = { type: 'dragOut' };\n this.uploadOutput.emit(event);\n }\n}\n","import { Directive, ElementRef, EventEmitter, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport { UploaderOptions, UploadOutput } from './interfaces';\nimport { DataUploaderService } from './ngx-uploader.class';\nimport { Subscription } from 'rxjs';\nimport { UploadInput } from './interfaces';\n\n@Directive({\n selector: '[dataFileSelect]',\n})\n/**\n * Attaches an upload queue to an `<input type=\"file\">`.\n *\n * Apply `dataFileSelect` to the input, bind `uploadOutput` to follow the queue and bind an\n * `EventEmitter<UploadInput>` to `uploadInput` to command it. Files are queued whenever\n * the input's selection changes; nothing is sent until you emit an `uploadAll` or\n * `uploadFile` command carrying the target url.\n *\n * The directive owns its own queue, so several inputs do not share state. See\n * {@link NgFileDropDirective} for the drag-and-drop counterpart.\n */\nexport class NgFileSelectDirective implements OnInit, OnDestroy {\n /** Queue limits ({@link UploaderOptions}). Read once in `ngOnInit`; later changes have no effect. */\n public options = input<UploaderOptions>();\n /** Command channel: emit {@link UploadInput}s on it to start, cancel or clear uploads. */\n public uploadInput = input<EventEmitter<UploadInput>>();\n /** Queue and transfer events ({@link UploadOutput}) for this input. */\n public uploadOutput = output<UploadOutput>();\n\n /** The queue backing this input, created in `ngOnInit`. */\n public upload!: DataUploaderService;\n public el!: HTMLInputElement;\n public elementRef = inject(ElementRef);\n\n private _sub!: Subscription[];\n\n ngOnInit() {\n this._sub = [];\n const options = this.options();\n const concurrency = (options && options.concurrency) || Number.POSITIVE_INFINITY;\n const allowedContentTypes = (options && options.allowedContentTypes) || ['*'];\n const maxUploads = (options && options.maxUploads) || Number.POSITIVE_INFINITY;\n const maxFileSize = (options && options.maxFileSize) || Number.POSITIVE_INFINITY;\n this.upload = new DataUploaderService(concurrency, allowedContentTypes, maxUploads, maxFileSize);\n\n this.el = this.elementRef.nativeElement as HTMLInputElement;\n this.el.addEventListener('change', this.fileListener, false);\n\n this._sub.push(\n this.upload.serviceEvents.subscribe((event: UploadOutput) => {\n this.uploadOutput.emit(event);\n }),\n );\n\n const uploadInput = this.uploadInput();\n if (uploadInput instanceof EventEmitter) {\n this._sub.push(this.upload.initInputEvents(uploadInput));\n }\n }\n\n ngOnDestroy() {\n if (this.el) {\n this.el.removeEventListener('change', this.fileListener, false);\n this._sub.forEach((sub) => sub.unsubscribe());\n }\n }\n\n fileListener = () => {\n if (this.el.files) {\n this.upload.handleFiles(this.el.files);\n }\n };\n}\n","import { NgModule } from '@angular/core';\nimport { NgFileDropDirective } from './ng-file-drop.directive';\nimport { NgFileSelectDirective } from './ng-file-select.directive';\n\n/**\n * @deprecated `NgFileDropDirective` and `NgFileSelectDirective` are now standalone —\n * import them directly instead of importing `NgxUploaderModule`. This module is kept\n * as a thin compatibility shim and will be removed in a future major version.\n */\n@NgModule({\n imports: [NgFileDropDirective, NgFileSelectDirective],\n exports: [NgFileDropDirective, NgFileSelectDirective],\n})\nexport class NgxUploaderModule {}\n","/**\n * File upload primitives: a queue engine ({@link DataUploaderService}) plus two host\n * directives, {@link NgFileSelectDirective} for `<input type=\"file\">` and\n * {@link NgFileDropDirective} for drop zones.\n *\n * The API — the `UploadInput`/`UploadOutput` command and event pair, the directive\n * selectors, the `UploaderOptions` limits — follows that of the ngx-uploader project, from\n * which this module is adapted, as the retained file names indicate; it has since been\n * updated for standalone directives and the signal-based `input()`/`output()` APIs.\n *\n * Uploads bypass Angular's `HttpClient` (and therefore its interceptors) in order to\n * report progress, so authenticated uploads must set their headers on the\n * {@link UploadInput}.\n */\nexport * from './interfaces';\nexport * from './ng-file-drop.directive';\nexport * from './ng-file-select.directive';\nexport * from './ngx-uploader.class';\nexport * from './ngx-uploader.module';\n","import { jwtDecode } from 'jwt-decode';\n\n/**\n * Body returned by the token endpoint ({@link AuthParams.tokenUrl}): a full token pair.\n * Shaped after SimpleJWT's `TokenObtainPair` response.\n */\nexport interface IJwtResponseJson {\n access: string;\n refresh: string;\n}\n\n/**\n * Body returned by the refresh endpoint ({@link AuthParams.tokenRefreshUrl}), which\n * renews only the access token — the refresh token is kept by the client.\n */\nexport interface IJwtRefreshResponseJson {\n access: string;\n}\n\n/**\n * Minimal claims the library needs from a decoded access token.\n *\n * Extend it with your backend's own claims and pass the result as the `UserData`\n * parameter of {@link AuthServiceBase}. `user_id` is the one claim actually used: it\n * tells the auth service which user record to fetch.\n */\nexport interface IJwtBaseData {\n // FIXME: check minimal jwt data\n token_type: 'access' | 'refresh';\n user_id: number;\n // exp: number;\n // jti: string;\n}\n\n/**\n * Immutable holder for an access/refresh token pair and the claims decoded from the\n * access token.\n *\n * Decoding is done with the `jwt-decode` package, which only base64-decodes the\n * payload: **it does not verify the signature, the issuer or the expiry**. Treat the\n * claims as a convenience for client-side routing and user lookup only; every real\n * authorization decision belongs to the backend, which validates the token itself.\n *\n * Constructed with no argument it represents the anonymous state (no tokens, `data`\n * is `null`).\n *\n * @typeParam UserJwtData - the decoded payload shape, at least {@link IJwtBaseData}.\n */\nexport class Jwt<UserJwtData extends IJwtBaseData> {\n public readonly access?: string;\n public readonly refresh?: string;\n private readonly _data: UserJwtData | null = null;\n\n /**\n * Builds a token pair from a token endpoint response, decoding the access token\n * immediately; with no argument, builds the anonymous instance.\n *\n * Throws (via `jwt-decode`) if `response.access` is not a well-formed JWT, so callers\n * handing over externally-supplied tokens should be ready for that.\n */\n constructor(response?: IJwtResponseJson) {\n if (response) {\n this.access = response.access;\n this._data = Object.freeze(jwtDecode<UserJwtData>(response.access));\n this.refresh = response.refresh;\n } else {\n this._data = null;\n }\n }\n\n /**\n * Claims decoded from the access token, frozen at construction, or `null` when this\n * instance is anonymous. Unverified — see the class documentation.\n */\n public get data(): UserJwtData | null {\n return this._data;\n }\n\n /**\n * Serializes the token pair (without the decoded claims, which are recomputed on\n * construction). Used by {@link AuthServiceBase.saveAuth} to persist the session.\n */\n public toJson() {\n return { access: this.access, refresh: this.refresh };\n }\n}\n","import { Injectable, InjectionToken, inject } from '@angular/core';\nimport { IJwtBaseData, IJwtRefreshResponseJson, IJwtResponseJson, Jwt } from './jwt';\nimport { HttpClient } from '@angular/common/http';\nimport { catchError, map, switchMap, tap } from 'rxjs/operators';\nimport { Observable, of, ReplaySubject, Subject, throwError } from 'rxjs';\nimport { DataModel } from '../data/data-model';\nimport { Collection } from '../data/data-collection';\nimport { Router } from '@angular/router';\nimport { DataMessageService } from '../messages/message.service';\n\n/**\n * What this service reads off a failed HTTP call: DRF puts an application-level\n * code in the response body, and interceptors may put one on the error itself.\n */\ninterface IApiErrorResponse {\n code?: string;\n error?: { code?: string };\n}\n\n/**\n * Complete configuration surface of the authentication layer.\n *\n * Provided through the {@link DATA_AUTH_PARAMS} injection token and consumed by\n * {@link AuthServiceBase}. The URL fields are used verbatim as HTTP endpoints (no base\n * url is prepended), and the route fields are passed as-is to `Router.navigate`.\n * The optional reactivate/password-reset members are feature switches: when a url is\n * absent, the matching method short-circuits and returns `of(false)` without any request.\n */\nexport interface AuthParams {\n /** Endpoint posted to by `login()` to exchange credentials for an access/refresh token pair. */\n tokenUrl: string;\n /** Endpoint posted to by `refresh()` with `{refresh: <token>}` to obtain a fresh access token. */\n tokenRefreshUrl: string;\n /** Endpoint for `requestReactivate()`, which asks the backend to send a reactivation token. Omit to disable the feature. */\n requestReactivateUrl?: string;\n /** Endpoint for `processReactivate()`, which submits the received reactivation token. Omit to disable the feature. */\n processReactivateUrl?: string;\n /** Endpoint for `requestPwReset()`, which asks the backend to send a password reset token. Omit to disable the feature. */\n requestPwResetUrl?: string;\n /** Endpoint for `processPwReset()`, which submits the new password along with the reset token. Omit to disable the feature. */\n processPwResetUrl?: string;\n /** Name of the payload field carrying the user identifier; used by every credential post (login, reactivate, password reset). */\n loginField: string;\n /** Name of the payload field carrying the password, used by `login()` and `processPwReset()`. */\n passwordField: string;\n /** Name of the payload field carrying the one-shot token in `processReactivate()` and `processPwReset()`. */\n tokenField: string;\n /** Router commands to the login page. Navigated to automatically when a token refresh fails. */\n loginRoute: string[];\n /** Router commands to the logout page. Exposed via `logoutRoute` for consumers to link to; the library never navigates there itself. */\n logoutRoute: string[];\n /** Router commands to the password reset page, exposed via `pwresetRoute` for consumers to link to. */\n pwresetRoute?: string[];\n /** Router commands to the account reactivation page, exposed via `reactivateRoute` for consumers to link to. */\n reactivateRoute?: string[];\n /**\n * Field names requested when loading the current user after login or token decode.\n * Defaults to a Django-flavoured set (id, username, email, names, staff/superuser flags, ...).\n */\n userFetchFields?: string[];\n /**\n * How long a fetched user stays fresh before `currentUser$` re-fetches it from the API.\n * Defaults to 3600 seconds.\n */\n userFetchValiditySeconds?: number;\n}\n\n/**\n * Authentication configuration ({@link AuthParams}) for {@link AuthServiceBase}.\n *\n * Must be provided by the application; the library ships no default. Use `useValue`\n * with a plain object.\n */\nexport const DATA_AUTH_PARAMS = new InjectionToken<AuthParams>('data.auth.params');\n\n/**\n * The {@link Collection} used to load and instantiate the authenticated user model.\n *\n * Wire it with **`useExisting`** so it aliases the application's own singleton user\n * service rather than creating a second one:\n *\n * ```ts\n * providers: [\n * UserService,\n * { provide: DATA_AUTH_USER_SERVICE, useExisting: UserService },\n * ]\n * ```\n *\n * Using `useClass` here would give the auth layer a private instance whose cache and\n * state diverge from the one the rest of the application uses.\n */\nexport const DATA_AUTH_USER_SERVICE = new InjectionToken<Collection<DataModel>>('data.auth.user.service');\n\n/**\n * Generic JWT authentication service, meant to be **extended** by the application.\n *\n * It owns the token pair, the current user, and their persistence in `localStorage`\n * under the `auth` key. Subclass it with your own user model, user collection and JWT\n * payload shape, then provide the subclass both as itself and behind\n * {@link DATA_AUTH_SERVICE} (via `useExisting`) so that {@link AuthInterceptor} and\n * `ModelListService` observe the very same instance:\n *\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * export class AuthService extends AuthServiceBase<User, UserService, UserJwtData> {}\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideHttpClient(withInterceptorsFromDi()),\n * UserService,\n * AuthService,\n * { provide: DATA_AUTH_USER_SERVICE, useExisting: UserService },\n * { provide: DATA_AUTH_SERVICE, useExisting: AuthService },\n * { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },\n * {\n * provide: DATA_AUTH_PARAMS,\n * useValue: {\n * tokenUrl: '/path/to/token',\n * tokenRefreshUrl: '/path/to/token/refresh',\n * loginField: 'username',\n * passwordField: 'password',\n * tokenField: 'token',\n * loginRoute: ['/', 'auth', 'login'],\n * logoutRoute: ['/', 'auth', 'logout'],\n * } satisfies AuthParams,\n * },\n * ],\n * });\n * ```\n *\n * The constructor calls {@link autoLogin}, so a stored session is restored as soon as\n * the service is instantiated.\n *\n * @typeParam User - the application user model.\n * @typeParam UserService - the {@link Collection} able to fetch that model.\n * @typeParam UserData - the decoded JWT payload, at least an {@link IJwtBaseData}.\n */\n@Injectable()\nexport class AuthServiceBase<\n User extends DataModel,\n UserService extends Collection<User>,\n UserData extends IJwtBaseData,\n> {\n /**\n * Emits every time {@link logout} runs, whether triggered by the user, by a failed\n * token refresh, or by a login error.\n *\n * This is the library's session-teardown signal: `ModelListService` subscribes to it\n * and resets all of its cached model lists, so that data belonging to the previous\n * session is never served to the next one. Application code can subscribe for the\n * same purpose.\n */\n public logout$: Subject<void> = new Subject<void>();\n private _user!: User;\n private _user$ = new ReplaySubject<User | null>(1);\n private _token!: Jwt<UserData>;\n private _fetched?: number;\n\n /** Collection used to fetch the logged-in user, from {@link DATA_AUTH_USER_SERVICE}. */\n public userService = inject<UserService>(DATA_AUTH_USER_SERVICE);\n private _params = inject<AuthParams>(DATA_AUTH_PARAMS);\n private _router = inject(Router);\n private _http = inject(HttpClient);\n private _msgs = inject(DataMessageService);\n\n constructor() {\n this.autoLogin();\n }\n\n /** True when no access token is held, i.e. no session is active. Checked by {@link AuthInterceptor} before attaching a token. */\n public get isAnonymous(): boolean {\n return !this._token.access;\n }\n\n /** Current raw access token, or `null` when anonymous. Read by {@link AuthInterceptor} to build the `Authorization` header. */\n public get accessToken(): string | null {\n return this._token.access ? this._token.access : null;\n }\n\n /** Current raw refresh token, or `null` when anonymous. Posted to {@link AuthParams.tokenRefreshUrl} by {@link refresh}. */\n public get refreshToken(): string | null {\n return this._token.refresh ? this._token.refresh : null;\n }\n\n /**\n * Synchronous snapshot of the logged-in user, or `null` if there is none.\n * Returns the cached instance without triggering a fetch — use {@link currentUser$}\n * when freshness matters.\n */\n public get currentUser(): User | null {\n return this._user && this._user.id ? this._user : null;\n }\n\n /**\n * The logged-in user as a stream, emitting `null` when the session ends.\n *\n * Re-fetches the user from the API when the cached copy is older than\n * {@link AuthParams.userFetchValiditySeconds} (default 3600), so a long-lived session\n * eventually picks up server-side changes such as group membership.\n */\n public get currentUser$(): Observable<User | null> {\n // Needs refresh ?\n if (\n !this.isAnonymous &&\n (!this._fetched || Date.now() - this._fetched > (this._params.userFetchValiditySeconds || 3600) * 1000)\n ) {\n this._fetched = Date.now();\n return this._fetchUser().pipe(\n switchMap(() => {\n return this._user$.asObservable();\n }),\n );\n }\n return this._user$.asObservable();\n }\n\n /** Configured token refresh endpoint. Also read by {@link AuthInterceptor}, which never attaches a token to it. */\n public get refreshUrl(): string {\n return `${this._params.tokenRefreshUrl}`;\n }\n\n /** Configured token (login) endpoint. Also read by {@link AuthInterceptor}, which never attaches a token to it. */\n public get loginUrl(): string {\n return `${this._params.tokenUrl}`;\n }\n\n /** Router commands to the login page, for building links or redirects in the application. */\n public get loginRoute(): string[] {\n return this._params.loginRoute;\n }\n\n /** Router commands to the logout page, for building links in the application. */\n public get logoutRoute(): string[] {\n return this._params.logoutRoute;\n }\n\n /** Router commands to the password reset page, or `undefined` when the feature is not configured. */\n public get pwresetRoute(): string[] | undefined {\n return this._params.pwresetRoute;\n }\n\n /** Router commands to the account reactivation page, or `undefined` when the feature is not configured. */\n public get reactivateRoute(): string[] | undefined {\n return this._params.reactivateRoute;\n }\n\n /**\n * Ends the session: clears the stored `auth` entry, drops the token and user, emits\n * `null` on {@link currentUser$} and fires {@link logout$}.\n *\n * Purely local — no request is sent to the backend. It does not navigate either;\n * redirect using {@link logoutRoute} if needed.\n */\n public logout(): void {\n localStorage.removeItem('auth');\n\n this._token = new Jwt();\n this._user = this.userService.create();\n this._user$.next(null);\n this.logout$.next();\n }\n\n /**\n * Restores a session previously written to `localStorage` by {@link saveAuth}, and\n * falls back to {@link logout} when there is nothing stored.\n *\n * Called from the constructor, so consumers rarely need to invoke it themselves.\n * The restored token is trusted as-is; expiry is only discovered when the API first\n * answers 401 and {@link AuthInterceptor} triggers a refresh.\n */\n public autoLogin(): void {\n const localAuth = localStorage.getItem('auth');\n if (!localAuth) {\n return this.logout();\n }\n const { user, fetched, token } = JSON.parse(localAuth) as {\n user: Partial<User>;\n fetched: number;\n token: IJwtResponseJson;\n };\n this._token = new Jwt(token);\n this._user = this.userService.create(user);\n this._fetched = fetched;\n this._user$.next(this._user);\n }\n\n /**\n * Exchanges credentials for a token pair, loads the matching user and persists the\n * session.\n *\n * Never errors: on failure it logs out and emits the backend's error code (or\n * `'error'` when none is available), so callers can branch on the emitted string\n * rather than on an error callback.\n */\n public login(username: string, password: string): Observable<'success' | 'error' | 'invalid_token' | (string & {})> {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n payload[this._params.passwordField] = password;\n return this._http.post<IJwtResponseJson>(this.loginUrl, payload).pipe(\n tap((tok) => {\n this._token = new Jwt(tok);\n }),\n switchMap(() => {\n return this._fetchUser();\n }),\n map(() => 'success'),\n tap(() => this.saveAuth()),\n catchError((error: IApiErrorResponse) => {\n this.logout();\n const code = error.error?.code || error.code || 'error';\n console.error(code, error);\n return of(code);\n }),\n );\n }\n\n /**\n * Opens a session from an already-obtained token pair instead of credentials, for\n * flows where the tokens arrive out of band (SSO callback, impersonation, tests).\n *\n * Like {@link login}, it fetches the user, saves the session and reports failures as\n * an emitted code rather than an error.\n */\n public loginWithToken(\n accessToken: string,\n refreshToken: string,\n ): Observable<'success' | 'error' | 'invalid_token' | (string & {})> {\n this._token = new Jwt({\n access: accessToken,\n refresh: refreshToken,\n });\n return this._fetchUser().pipe(\n map(() => 'success'),\n tap(() => this.saveAuth()),\n catchError((error: IApiErrorResponse) => {\n this.logout();\n const code = error.error?.code || error.code || 'error';\n console.error(code, error);\n return of(code);\n }),\n );\n }\n\n /**\n * Asks the backend to send an account reactivation token to the given user.\n *\n * Emits `false` — without any request — when {@link AuthParams.requestReactivateUrl}\n * is not configured, and also when the request fails, so a failure and a disabled\n * feature are indistinguishable to the caller.\n */\n public requestReactivate(username: string): Observable<boolean> {\n if (this._params.requestReactivateUrl) {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n return this._http.post<unknown>(this._params.requestReactivateUrl, payload).pipe(\n map(() => true),\n catchError(() => of(false)),\n );\n }\n return of(false);\n }\n\n /**\n * Asks the backend to send a password reset token to the given user.\n *\n * Emits `false` when {@link AuthParams.requestPwResetUrl} is not configured or when\n * the request fails. Pair it with {@link processPwReset} to complete the flow.\n */\n public requestPwReset(username: string): Observable<boolean> {\n if (this._params.requestPwResetUrl) {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n return this._http.post<unknown>(this._params.requestPwResetUrl, payload).pipe(\n map(() => true),\n catchError(() => of(false)),\n );\n }\n return of(false);\n }\n\n /**\n * Completes the reactivation flow by submitting the token the user received.\n *\n * Emits `false` when {@link AuthParams.processReactivateUrl} is not configured or when\n * the token is rejected. Success does not open a session — call {@link login} afterwards.\n */\n public processReactivate(username: string, token: string): Observable<boolean> {\n if (this._params.processReactivateUrl) {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n payload[this._params.tokenField] = token;\n return this._http.post<unknown>(this._params.processReactivateUrl, payload).pipe(\n map(() => true),\n catchError(() => of(false)),\n );\n }\n return of(false);\n }\n\n /**\n * Completes the password reset flow by submitting the new password together with the\n * token the user received.\n *\n * Emits `false` when {@link AuthParams.processPwResetUrl} is not configured or when the\n * token is rejected. Success does not open a session — call {@link login} afterwards.\n */\n public processPwReset(username: string, password: string, token: string): Observable<boolean> {\n if (this._params.processPwResetUrl) {\n const payload: Record<string, string> = {};\n payload[this._params.loginField] = username;\n payload[this._params.passwordField] = password;\n payload[this._params.tokenField] = token;\n return this._http.post<unknown>(this._params.processPwResetUrl, payload).pipe(\n map(() => true),\n catchError(() => of(false)),\n );\n }\n return of(false);\n }\n\n /**\n * Persists the current user, token pair and fetch timestamp to `localStorage` under\n * the `auth` key, and pushes the user onto {@link currentUser$}.\n *\n * When anonymous it removes the entry instead. Called automatically after login, user\n * fetch and token refresh; call it manually only after mutating the cached user.\n */\n public saveAuth() {\n if (this.isAnonymous) {\n localStorage.removeItem('auth');\n this._user$.next(null);\n } else {\n localStorage.setItem(\n 'auth',\n JSON.stringify({\n user: this._user.toJson() as Record<string, unknown>,\n fetched: Date.now(),\n token: this._token.toJson(),\n }),\n );\n this._user$.next(this._user);\n }\n }\n\n /**\n * Trades the refresh token for a new access token and saves the session.\n *\n * Mainly driven by {@link AuthInterceptor} when the API answers 401. Emits `null` when\n * there is no refresh token or the backend refuses it; in that case it also logs out,\n * shows a warning through {@link DataMessageService} and navigates to\n * {@link AuthParams.loginRoute}.\n */\n public refresh(): Observable<IJwtRefreshResponseJson | null> {\n if (!this._token.refresh) {\n console.error('No refresh token available');\n this.logout();\n return of(null);\n }\n return this._http\n .post<IJwtRefreshResponseJson>(this.refreshUrl, {\n refresh: this._token.refresh,\n })\n .pipe(\n catchError((err, caught) => {\n console.error('Token refresh error', err, caught);\n this.logout();\n this._msgs.warning('Vous devez vous reconnecter');\n void this._router.navigate(this._params.loginRoute);\n return of(null);\n }),\n tap((tok) => {\n console.log('Token refresh response', tok);\n if (tok) {\n this._token = new Jwt({\n access: tok.access,\n refresh: this._token.refresh!,\n });\n this.saveAuth();\n }\n }),\n );\n }\n\n private _fetchUser(): Observable<User> {\n if (this._token.data && this._token.data.user_id) {\n // Fetch user data using token\n return this.userService\n .fetch(this._token.data.user_id, {\n params: {\n fields: (\n this._params.userFetchFields || [\n 'id',\n 'username',\n 'email',\n 'last_name',\n 'first_name',\n 'is_superuser',\n 'is_active',\n 'is_staff',\n 'last_login',\n 'current_groups_slugs',\n ]\n ).join(','),\n },\n })\n .pipe(\n tap((u) => {\n this._user = u;\n this.saveAuth();\n }),\n );\n } else {\n return throwError(() => {\n return { code: 'invalid_token' };\n });\n }\n }\n}\n","import { Route, Router } from '@angular/router';\nimport { fieldValues } from '../data/field-values';\n\n/**\n * Template function type.\n * Used for page title or other data to string operations.\n *\n * @param data: object\n * @param path: optional path (see: usage)\n */\nexport type TplFn<T> = (data: T, path?: string) => string;\n\n/**\n * Base route parameters interface.\n */\nexport interface BaseRouteParams {\n /** Skip route in breadcrumbs */\n skip?: boolean;\n /** Route title or title template */\n // Callers declare the data shape their template reads; `object` would\n // reject it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n title?: string | TplFn<any>;\n /** Route icon string */\n icon?: string;\n /** Route config item */\n route: RouteConfigItem;\n /** This route is a tree route */\n tree?: boolean;\n}\n\n/**\n * Route function type.\n * Takes parameters, return a route.\n *\n * The parameters are `any` on purpose: a route builder is written against the\n * models it links to (`(product: Product) => [...]`), and such a function is not\n * assignable to one declared over `unknown[]`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type RouteFn = (...args: any[]) => (string | number)[];\n\n/**\n * Route config item.\n * Stores route named parameters, route function and route name.\n */\nexport interface RouteConfigItem {\n params: string[];\n route: RouteFn;\n name: string;\n}\n\n/**\n * Identity helper that type-checks a route `data` literal against {@link BaseRouteParams}\n * while preserving its literal type.\n *\n * Use it when declaring routes so that mistakes in the `data` block are caught at\n * compile time instead of surfacing as a blank breadcrumb at runtime.\n */\nexport function RData<T extends BaseRouteParams>(value: T) {\n return value;\n}\n\n/**\n * A map of route names to their {@link RouteConfigItem}, keyed by a string-literal union\n * so that every name is known statically and typos are compile errors.\n */\nexport type RoutesConfig<T extends string> = Readonly<Record<T, RouteConfigItem>>;\n\n/** An Angular {@link Route} whose `data` is mandatory and typed as {@link BaseRouteParams}. */\nexport interface StrictRoutes extends Route {\n data: BaseRouteParams;\n}\n\n/** A route table built from {@link StrictRoutes}, i.e. where every route carries breadcrumb metadata. */\nexport type RoutesDefinition = StrictRoutes[];\n\ntype RouteArg<T> = Record<string, T>;\n\n/**\n * A bound, reusable reference to a route: it pairs a {@link RouteConfigItem} with a\n * context object from which the route's named parameters are read.\n *\n * The point is to build links without repeating parameter plumbing at each call site:\n * give it a context (a model instance, say) once, and {@link route} or {@link navigate}\n * will pull the declared parameters from it. Parameters can still be overridden per\n * call, and a missing one is reported on the console while yielding an empty route\n * rather than throwing.\n */\nexport class Link<T> {\n private _cargs: Record<string, unknown> = {};\n private _params: string[] = [];\n private _route: RouteFn;\n private _router?: Router;\n\n /**\n * Builds a link from a route config, optionally binding a context and a router.\n *\n * Passing a `router` here is what lets {@link navigate} be called without arguments\n * later. A missing `config` is tolerated (it warns and produces an inert link) so that\n * a partially-initialised template does not crash.\n */\n constructor(config?: RouteConfigItem, context?: object, router?: Router) {\n if (!config) {\n console.warn('Link created without config');\n }\n this._params = config?.params || [];\n this._route = config?.route || (() => []);\n this._router = router;\n this._name = config?.name || '';\n if (context) {\n this.context(context);\n }\n }\n\n private _name!: string;\n\n /** Name of the underlying route config item, or an empty string when the link was built without config. */\n public get name(): string {\n return this._name;\n }\n\n /**\n * Rebinds the object the route parameters are read from, replacing any previous\n * context. Only the parameters declared by the route config are picked up; those\n * missing from `ctx` are reset to `null`, not left over from the previous context.\n */\n public context(ctx: object): void {\n const values = fieldValues(ctx ?? {});\n for (const n of this._params) {\n if (values[n]) {\n this._cargs[n] = values[n];\n } else {\n this._cargs[n] = null;\n }\n }\n }\n\n /**\n * Builds the router commands array, resolving each declared parameter from `params`\n * first and falling back to the bound context.\n *\n * Suitable for `[routerLink]`. If a parameter cannot be resolved from either source it\n * logs an error and returns an empty array, which routerLink renders as a link to the\n * current url — so an empty result means a missing parameter, not a valid route.\n */\n public route(params?: Required<RouteArg<T>>): (string | number)[] {\n const rargs: unknown[] = [];\n for (const n of this._params) {\n if (params && params[n] !== undefined && params[n] !== null) {\n rargs.push(params[n]);\n } else if (this._cargs[n] !== undefined && this._cargs[n] !== null) {\n rargs.push(this._cargs[n]);\n } else {\n console.error('Missing route parameter', n);\n return [];\n }\n }\n // SEE: Check for undefined in rargs\n return this._route(...rargs);\n }\n\n /**\n * Resolves the route and navigates to it, using the router given here or the one bound\n * at construction.\n *\n * Resolves to `false` without navigating when no router is available from either\n * source; otherwise it resolves with the router's own result.\n */\n public async navigate(params?: Record<string, T>, router?: Router): Promise<boolean> {\n if (router) {\n return router.navigate(this.route(params));\n }\n if (this._router) {\n return this._router.navigate(this.route(params));\n }\n console.error('Router not provided, no navigation');\n return false;\n }\n}\n","import { Component, DestroyRef, inject, input, OnInit, signal } from '@angular/core';\nimport {\n ActivatedRoute,\n ActivatedRouteSnapshot,\n NavigationEnd,\n Router,\n RouterModule,\n RouterState,\n UrlSegment,\n} from '@angular/router';\nimport { filter } from 'rxjs/operators';\nimport { BaseRouteParams } from '../routing';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n/** One rendered breadcrumb entry: its absolute path, label, icon classes, and whether it is the active leaf. */\nexport interface IPathTreeItem {\n path: string;\n title: string;\n icon: string;\n current: boolean;\n}\n\n/**\n * Builds a breadcrumb for the active route from the {@link BaseRouteParams} declared in\n * each route's `data` block.\n *\n * It walks the router state from the root down to the leaf, and rebuilds itself on every\n * `NavigationEnd`, so a single instance in the layout keeps up with navigation. Each\n * route contributes an entry unless its config sets `skip`; routes marked `tree` emit one\n * entry per url segment, which is how a nested path renders as several crumbs.\n *\n * Route config data used here:\n * - `title`: a literal string, or a {@link TplFn} called with the route's `data` (and, for\n * `tree` routes, the current segment path) to compute the label.\n * - `icon`: icon classes, e.g. `fa fa-home` for Font Awesome.\n * - `skip`: exclude this route from the breadcrumb.\n * - `tree`: expand each url segment of this route into its own entry.\n *\n * Note that the icon and title are read from different sources: the icon comes from the\n * resolved route `data`, whereas the title comes from the static `routeConfig.data`.\n */\n@Component({\n selector: 'data-breadcrumb',\n templateUrl: './breadcrumb.component.html',\n styleUrls: ['./breadcrumb.component.css'],\n imports: [RouterModule],\n})\nexport class BreadcrumbComponent implements OnInit {\n /**\n * Additional data to be used in titleTemplate\n */\n public data = input<object>();\n /**\n * Do we display icons ?\n */\n public icons = input<boolean>(true);\n /** The computed breadcrumb entries, recomputed on every navigation and rendered by the template. */\n public tree = signal<IPathTreeItem[]>([]);\n public router = inject(Router);\n public route = inject(ActivatedRoute);\n private destroy$ = inject(DestroyRef);\n\n ngOnInit(): void {\n this.getRouteTree(this.router.routerState);\n this.router.events\n .pipe(\n takeUntilDestroyed(this.destroy$),\n filter((event) => event instanceof NavigationEnd),\n )\n .subscribe(() => {\n this.getRouteTree(this.router.routerState);\n });\n }\n\n /**\n * Walks the router state from root to leaf and rebuilds {@link tree}, accumulating url\n * segments so each entry gets an absolute path and flagging the last one as `current`.\n *\n * Called on init and on every `NavigationEnd`; public mainly so it can be driven\n * directly in tests.\n */\n public getRouteTree(current: RouterState): void {\n const tree: IPathTreeItem[] = [];\n const url: string[] = [];\n let p: ActivatedRouteSnapshot | null = current.root.snapshot;\n\n while (p != null) {\n let rdata: Partial<BaseRouteParams> = {\n tree: false,\n title: () => 'xxxx',\n icon: '',\n skip: true,\n };\n const data = p.data as BaseRouteParams;\n\n // Get route data\n if (p.routeConfig && p.routeConfig.data) {\n rdata = p.routeConfig.data;\n }\n\n if (rdata.tree) {\n // Get icon\n for (const u of p.url) {\n url.push(u.path);\n const rtd: IPathTreeItem = {\n icon: this.getIcon(rdata, data),\n title: this.getTitle(rdata, data, u),\n path: url.join('/'),\n current: false,\n };\n if (rtd.path.length > 0 && rtd.path[0] !== '/') {\n rtd.path = '/' + rtd.path;\n }\n if (!rdata.skip) {\n tree.push(rtd);\n }\n }\n } else {\n url.push(p.url.join('/'));\n const rtd: IPathTreeItem = {\n icon: this.getIcon(rdata, data),\n title: this.getTitle(rdata, data),\n path: url.join('/'),\n current: false,\n };\n if (rtd.path.length > 0 && rtd.path[0] !== '/') {\n rtd.path = '/' + rtd.path;\n }\n if (!rdata.skip) {\n tree.push(rtd);\n }\n }\n\n p = p.firstChild;\n }\n if (tree.length > 0) {\n tree[tree.length - 1].current = true;\n }\n this.tree.set(tree);\n }\n\n /**\n * Resolves one crumb's label: returns the configured string as-is, or invokes the\n * configured {@link TplFn} with the route data and, for `tree` routes, the segment path.\n *\n * Falls back to placeholder strings (`'xxx'`, or `'xx'` if a title template threw) so a\n * broken template degrades to visible filler rather than an exception.\n */\n public getTitle(rdata: Partial<BaseRouteParams>, data: BaseRouteParams, u?: UrlSegment): string {\n if (rdata['title']) {\n if (typeof rdata['title'] === 'function') {\n const tpl = rdata['title'];\n try {\n if (u) {\n return tpl(data, u.path);\n } else {\n return tpl(data);\n }\n } catch (e) {\n console.warn('Unable to process breadcrumb function', e);\n if (data.title != null) {\n return 'xx';\n }\n }\n } else {\n return rdata['title'];\n }\n }\n return 'xxx';\n }\n\n /**\n * Resolves one crumb's icon classes from the resolved route `data`, returning an empty\n * string when none is set. The `rdata` argument is accepted for symmetry with\n * {@link getTitle} but is not consulted.\n */\n public getIcon(rdata: Partial<BaseRouteParams>, data: BaseRouteParams): string {\n if (data.icon) {\n return data.icon;\n }\n return '';\n }\n}\n","<nav aria-label=\"breadcrumb\">\n <ol class=\"breadcrumb\">\n @for (p of tree(); track p) {\n @if (!p.current) {\n <li class=\"breadcrumb-item\">\n <a class=\"breadcrumb-item\" [routerLink]=\"p.path\">\n @if (icons() && p.icon) {\n <i class=\"me-2\" [class]=\"p.icon\"></i>\n {{ p.title }}\n }\n @if (!(icons() && p.icon)) {\n {{ p.title }}\n }\n </a>\n </li>\n }\n @if (p.current) {\n <li class=\"breadcrumb-item active\" aria-current=\"page\">\n @if (icons() && p.icon) {\n <i class=\"me-1\" [class]=\"p.icon\"></i>\n {{ p.title }}\n }\n @if (!(icons() && p.icon)) {\n {{ p.title }}\n }\n </li>\n }\n }\n </ol>\n</nav>\n","import { Injectable } from '@angular/core';\nimport { UrlSegment } from '@angular/router';\n\ninterface ITabStoredMem {\n name: string;\n value: string;\n}\n\n/**\n * Remembers the selected tab for one target route.\n *\n * Created and handed out by {@link TabMemoryService.memFor}; bind {@link current} to your\n * tab set to read and update the selection. When the driver was created with saving\n * enabled, assigning `current` writes the whole memory back to `localStorage`.\n */\nexport class NavDriver {\n private lastActive!: Date;\n\n /**\n * Seeds the selection with `defaults`, then overrides it with the persisted value when\n * `save` is set and one is stored. Instantiated by {@link TabMemoryService}; not meant\n * to be constructed directly.\n */\n constructor(\n private _parent: TabMemoryService,\n public name: string,\n public defaults: string,\n private save: boolean,\n ) {\n this._current = this.defaults;\n if (this.save) {\n const value = this._parent.load(this.name);\n if (value !== null) {\n this._current = value;\n }\n }\n }\n\n private _current: string;\n\n /** The remembered tab identifier for this route: the persisted value, or the default. */\n public get current(): string {\n return this._current;\n }\n\n /** Records the newly selected tab and, when saving is enabled, persists the memory immediately. */\n public set current(value: string) {\n this._current = value;\n this.lastActive = new Date();\n if (this.save) {\n this._parent.save();\n }\n }\n\n /** This driver's serializable form, used by {@link TabMemoryService.save}. */\n public get value(): ITabStoredMem {\n return { name: this.name, value: this._current };\n }\n}\n\n/**\n * Remembers which tab the user last opened on each route, so returning to a page restores\n * the tab they left it on instead of snapping back to the default.\n *\n * It keys memories by route target — the route commands joined into a `/a/b/c` string —\n * and hands out a {@link NavDriver} per key through {@link memFor}. The whole map is\n * persisted in `localStorage` under the single `tabmem` key, so it survives reloads and is\n * shared across tabs of the same browser; pass `save: false` for a memory that lasts only\n * for the current page session.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class TabMemoryService {\n private tabMem: Record<string, NavDriver> = {};\n\n private static targetToString(target: (string | number | UrlSegment)[]): string {\n let out = '';\n for (const t of target) {\n out += `/${String(t)}`;\n }\n return out;\n }\n\n /**\n * Returns the {@link NavDriver} for a route target, creating it on first use and\n * returning the same instance afterwards.\n *\n * Call it from a tabbed page's init with the route commands and the default tab. Pass\n * the current url `fragment` to let a deep link win over the remembered selection —\n * a non-empty fragment overwrites the memory.\n */\n public memFor(\n target: (string | number | UrlSegment)[],\n defaults: string,\n save = true,\n fragment?: string | null,\n ): NavDriver {\n const tname = TabMemoryService.targetToString(target);\n if (this.tabMem[tname] === undefined) {\n this.tabMem[tname] = new NavDriver(this, tname, defaults, save);\n }\n if (fragment) {\n this.tabMem[tname].current = fragment;\n }\n return this.tabMem[tname];\n }\n\n /**\n * Writes every known driver to the `tabmem` entry of `localStorage`, replacing whatever\n * was there. Called automatically when a saving driver's selection changes.\n */\n public save() {\n const tosave: Record<string, ITabStoredMem> = {};\n for (const tn of Object.keys(this.tabMem)) {\n tosave[tn] = this.tabMem[tn].value;\n }\n localStorage.setItem('tabmem', JSON.stringify(tosave));\n }\n\n /**\n * Reads back one stored selection by its target key, returning `null` when nothing is\n * stored for it. Used by {@link NavDriver} on construction.\n */\n public load(name: string): string | null {\n const tm = localStorage.getItem('tabmem');\n if (tm) {\n const tmd = JSON.parse(tm) as Record<string, { value?: string }>;\n const entry = tmd[name];\n if (entry?.value) {\n return entry.value;\n }\n }\n return null;\n }\n}\n","/**\n * Turns arbitrary text into a lowercase, dash-separated ASCII slug, suitable for urls,\n * anchors or generated identifiers.\n *\n * It trims, lowercases, folds a fixed set of Latin-1 accented characters onto their ASCII\n * equivalents, maps separator-ish characters (`·/_,:;`) to dashes, drops anything else\n * outside `[a-z0-9 -]`, and collapses runs of whitespace and dashes. Only the listed\n * accents are handled, so scripts outside that set (Cyrillic, Greek, CJK, and Latin\n * letters such as `ø` or `ß`) are stripped rather than transliterated, and text made\n * entirely of them yields an empty string.\n */\nexport const slugify = (str: string): string => {\n str = str.replace(/^\\s+|\\s+$/g, ''); // trim\n str = str.toLowerCase();\n\n // remove accents, swap ñ for n, etc\n const from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;';\n const to = 'aaaaeeeeiiiioooouuuunc------';\n for (let i = 0, l = from.length; i < l; i++) {\n str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));\n }\n\n str = str\n .replace(/[^a-z0-9 -]/g, '') // remove invalid chars\n .replace(/\\s+/g, '-') // collapse whitespace and replace by -\n .replace(/-+/g, '-'); // collapse dashes\n\n return str;\n};\n","/**\n * Teach jsdom the layout APIs CodeMirror and ProseMirror expect.\n *\n * Both editors measure the document to place the caret and decide what to\n * render, and jsdom has no layout engine: `getClientRects()` returns an empty\n * list and `elementFromPoint` does not exist at all. Zeroed rectangles are\n * enough — nothing in a spec depends on real geometry, it just has to not throw.\n *\n * Call it from `beforeEach` in any spec that instantiates an editor view. It is\n * idempotent, and only patches what is missing.\n */\nexport function installEditorDomShims(): void {\n const rect = () => new DOMRect(0, 0, 0, 0);\n const rectList = () => {\n const list = [rect()] as unknown as DOMRectList & { item: (index: number) => DOMRect | null };\n list.item = (index: number) => (index === 0 ? rect() : null);\n return list;\n };\n if (!Range.prototype.getClientRects) {\n Range.prototype.getClientRects = rectList;\n }\n if (!Range.prototype.getBoundingClientRect) {\n Range.prototype.getBoundingClientRect = rect;\n }\n if (!Element.prototype.getClientRects) {\n Element.prototype.getClientRects = rectList;\n }\n if (!document.elementFromPoint) {\n document.elementFromPoint = () => null;\n }\n if (!document.createRange().getClientRects) {\n // jsdom builds ranges from the prototype patched above; this is only a\n // guard for the case where an environment overrides createRange.\n Range.prototype.getClientRects = rectList;\n }\n}\n","import { computed, Directive, input, model, OnInit, output, signal } from '@angular/core';\nimport { FormControl, UntypedFormGroup } from '@angular/forms';\nimport { firstValueFrom } from 'rxjs';\nimport { asText, fieldValues } from '../data/field-values';\nimport { DataModel } from '../data/data-model';\nimport { BaseFieldManager } from '../data/fields/base';\nimport { uniqueId } from '../utils/unique-id';\n\n/**\n * The behaviour `<data-richedit>` and `<data-mdedit>` share with\n * `<data-dispedit>`: show the value, click to edit, save explicitly.\n *\n * It lives in the primary entry point so both editors can extend it — they\n * import `@solidev/data`, and the reverse would be a circular dependency\n * between entry points. Everything here is engine-agnostic: resolving which\n * field to read, which control to bind, when to show the editor, and how to\n * persist. The subclass owns its template and its editor widget.\n *\n * ## The source / rendered pair\n *\n * Long text is rarely one column. A markdown field is stored as its source\n * plus the HTML the server rendered from it, and this base follows that shape\n * by convention: given `field=\"description\"` it edits `description_src` and\n * displays `description_html` **when the model declares them**, and falls back\n * to `description` for both when it does not. `[htmlField]` overrides the\n * display half outright. A `field` that already ends in `_src` is understood,\n * so `field=\"description_src\"` resolves the same pair.\n */\n@Directive()\nexport abstract class FieldEditorBase<FT, T extends DataModel> implements OnInit {\n /** Id tying the label to the editor. */\n public readonly inputId = uniqueId('data-editor');\n /** Id of the label element, wired to the editor through `aria-labelledby`. */\n public readonly labelId = `${this.inputId}-label`;\n\n /** Model instance holding the field. */\n public model = input<T>();\n /**\n * Field to edit, or the base name of a source / rendered pair.\n *\n * See the class description for how `<field>_src` and `<field>_html` are\n * resolved.\n */\n public field = input<string>();\n /** Overrides the field read for the read-only display. */\n public htmlField = input<string>();\n /** Whether {@link toggleEdit} is allowed to reveal the editor. */\n public editable = input(true);\n /**\n * Whether the editor is showing, in `dd` mode.\n *\n * Defaults to false: the value renders and a click reveals the editor, the\n * way `<data-dispedit>` behaves. `inline` and `form` modes ignore this and\n * follow {@link showEditor}.\n */\n public edit = model(false);\n /**\n * Layout, and whether {@link save} persists.\n *\n * `dd` renders a `<dt>`/`<dd>` block and is the only mode that saves to the\n * API; `inline` and `form` render a label plus the editor and leave saving to\n * the caller.\n */\n public mode = input<'dd' | 'inline' | 'form'>('dd');\n /** Hide label (for inline forms). */\n public hideLabel = input(false);\n /**\n * Hide the built-in save button, for callers driving persistence themselves\n * from the {@link changed} output.\n */\n public hideButton = input(false);\n /**\n * Form control backing the editor.\n *\n * When supplied, the component uses it as-is and skips its own setup — no\n * field manager lookup, no seeding from the model, and no {@link changed}\n * emissions. Takes precedence over `[form]`.\n */\n public fc = input<FormControl<string | null>>();\n /**\n * External form group to register into, the way `<data-dispedit>` does.\n *\n * A control named after the resolved source field is added to it, seeded\n * from the model. Ignored when `[fc]` is supplied.\n */\n public form = input<UntypedFormGroup>();\n /** Emits the value on every change. Not wired for a caller-supplied `[fc]`. */\n public changed = output<string | null>();\n\n /** Field manager for the source field; only resolved when `fc` is created here. */\n public manager?: BaseFieldManager<FT>;\n /** Whether the manager declares the field required. */\n public readonly required = signal(false);\n /** The control actually in use. */\n public control!: FormControl<string | null>;\n\n /** The base name of the pair, with any trailing `_src` removed. */\n private readonly baseField = computed(() => (this.field() ?? '').replace(/_src$/, ''));\n\n /** The field actually edited. */\n public readonly sourceField = computed(() => {\n const base = this.baseField();\n return this.modelHas(`${base}_src`) ? `${base}_src` : (this.field() ?? '');\n });\n\n /** The field actually displayed in read-only mode. */\n public readonly displayField = computed(() => {\n const override = this.htmlField();\n if (override) return override;\n const base = this.baseField();\n return this.modelHas(`${base}_html`) ? `${base}_html` : (this.field() ?? '');\n });\n\n /**\n * Whether the editor is showing rather than the rendered value.\n *\n * The rule is `<data-dispedit>`'s: `dd` follows `[edit]`, `inline` shows the\n * editor unless the field is not editable, and `form` always shows it — a\n * form control that renders as static text would be a surprise.\n */\n public readonly showEditor = computed(() => {\n switch (this.mode()) {\n case 'dd':\n return this.edit();\n case 'inline':\n return this.editable();\n default:\n return true;\n }\n });\n\n /**\n * Resolve the control: the supplied `[fc]`, one registered into `[form]`, or\n * one of our own seeded from the model.\n */\n public ngOnInit(): void {\n const supplied = this.fc();\n if (supplied) {\n this.control = supplied;\n return;\n }\n this.control = new FormControl<string | null>('');\n const model = this.model();\n const field = this.sourceField();\n if (model && field) {\n this.manager = model.FM(field);\n this.required.set(this.manager?.required ?? false);\n this.control.setValue(asText(fieldValues(model)[field]), { emitEvent: false });\n }\n const form = this.form();\n if (form && field) {\n form.setControl(field, this.control, { emitEvent: false });\n }\n if (this.showEditor()) {\n this.control.enable();\n } else {\n this.control.disable();\n }\n }\n\n /**\n * Switch between the rendered value and the editor.\n * Does nothing when `[editable]` is false.\n */\n public toggleEdit(): void {\n if (!this.editable()) {\n this.edit.set(false);\n this.control.disable();\n return;\n }\n const next = !this.edit();\n this.edit.set(next);\n if (next) {\n this.control.enable();\n } else {\n this.control.disable();\n }\n }\n\n /**\n * The rendered value, as stored on the display field.\n *\n * Templates pass it through {@link SafeHtmlPipe} to inject it — **trusted,\n * not sanitized**, because Angular's sanitizer allow-list has no `style` and\n * would drop the alignment and colours the rich text editor writes. Point\n * these components at fields your own editor produced and your own API\n * stored.\n */\n public displayValue(): string {\n const model = this.model();\n const field = this.displayField();\n if (!model || !field) return '';\n return asText(fieldValues(model)[field]);\n }\n\n /**\n * Write the editor content back to the model's source field, and persist it\n * in `dd` mode only.\n *\n * In `inline` / `form` modes the model is updated in memory but no request is\n * sent, leaving the save to the surrounding form. Does nothing without both a\n * `[model]` and a `[field]`.\n */\n public async save(): Promise<void> {\n const model = this.model();\n const field = this.sourceField();\n if (!model || !field) return;\n model.setFV(field, this.control.value);\n if (this.mode() === 'dd') {\n await firstValueFrom(model.update([field], { updateModel: true }));\n // The API re-renders the HTML twin from the source it was just sent, and\n // `updateModel` writes the response back onto the model -- so the view\n // this component flips to shows the new rendering, not the old one.\n this.edit.set(false);\n this.control.disable();\n }\n }\n\n /** Whether the model declares a property under that name. */\n private modelHas(name: string): boolean {\n const model = this.model();\n if (!model || !name) return false;\n return name in fieldValues(model) || !!model.F.get(name);\n }\n}\n","// By default, Underscore uses ERB-style template delimiters, change the\n// following template settings to use alternative delimiters.\nconst settings = {\n evaluate: /<%([\\s\\S]+?)%>/g,\n interpolate: /<%=([\\s\\S]+?)%>/g,\n escape: /<%-([\\s\\S]+?)%>/g,\n variable: 'obj',\n};\n\n// When customizing `templateSettings`, if you don't want to define an\n// interpolation, evaluation or escaping regex, we need one that is\n// guaranteed not to match.\nconst noMatch = /.^/;\n\n// Certain characters need to be escaped so that they can be put into a\n// string literal.\nconst escapes: Record<string, string> = {\n '\\\\': '\\\\',\n \"'\": \"'\",\n r: '\\r',\n n: '\\n',\n t: '\\t',\n u2028: '\\u2028',\n u2029: '\\u2029',\n};\n\nfor (const p in escapes) {\n escapes[escapes[p]] = p;\n}\n\nconst escaper = /\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g;\n\n/**\n * Compiles (and optionally renders) an Underscore-style string template, using ERB\n * delimiters: `<%= expr %>` interpolates, `<% code %>` evaluates, and a `print()` helper\n * is available inside evaluated code.\n *\n * Called with `data`, it renders immediately and returns the resulting string; without\n * `data`, it returns a reusable render function carrying a `source` property with the\n * generated code. `objectName` renames the variable the data is exposed under — but note\n * it mutates module-level settings, so it persists for subsequent calls too.\n *\n * Within this library it backs route title templates (see {@link TplFn}). Two caveats:\n * compilation goes through `new Function`, so it will not run under a Content Security\n * Policy without `unsafe-eval`; and the escaping delimiter `<%- expr %>` is not usable,\n * as the code it emits calls `_.escape` while no `_` is in scope.\n */\n/**\n * A template compiled by {@link tmpl} but not yet rendered: call it with the\n * data. `source` carries the generated JS, which is handy when debugging.\n */\nexport type CompiledTemplate = ((data: object) => string) & { source?: string };\n\nexport function tmpl(text: string, data: object, objectName?: string): string;\nexport function tmpl(text: string, data?: undefined, objectName?: string): CompiledTemplate;\nexport function tmpl(text: string, data?: object, objectName?: string): string | CompiledTemplate {\n if (objectName) {\n settings.variable = objectName;\n }\n\n // Compile the template source, taking care to escape characters that\n // cannot be included in a string literal and then unescape them in code\n // blocks.\n let source =\n \"__p+='\" +\n text\n .replace(escaper, function (match) {\n return '\\\\' + escapes[match];\n })\n .replace(settings.escape || noMatch, function (match, code: string) {\n return \"'+\\n_.escape(\" + unescape(code) + \")+\\n'\";\n })\n .replace(settings.interpolate || noMatch, function (match, code: string) {\n return \"'+\\n(\" + unescape(code) + \")+\\n'\";\n })\n .replace(settings.evaluate || noMatch, function (match, code: string) {\n return \"';\\n\" + unescape(code) + \"\\n;__p+='\";\n }) +\n \"';\\n\";\n\n // If a variable is not specified, place data values in local scope.\n if (!settings.variable) {\n source = 'with(obj||{}){\\n' + source + '}\\n';\n }\n\n source =\n \"var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\\n\" + source + 'return __p;\\n';\n\n // The whole point of this module: `source` is the template compiled to JS.\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n const render = new Function(settings.variable || 'obj', source) as (data?: object) => string;\n\n if (data) {\n return render(data);\n }\n\n const template = ((data: object) => {\n return render(data);\n }) as CompiledTemplate;\n\n // Provide the compiled function source as a convenience for build time\n // precompilation.\n template.source = 'function(' + (settings.variable || 'obj') + '){\\n' + source + '}';\n\n return template;\n}\n","import { ApplicationRef, inject, Injectable } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { SwUpdate, VersionReadyEvent } from '@angular/service-worker';\nimport { filter, first, map, tap } from 'rxjs/operators';\nimport { merge, Observable, ReplaySubject, timer } from 'rxjs';\n\n/**\n * Watches the service worker for a newly deployed version and exposes it as a simple\n * \"an update is available\" flag.\n *\n * It polls `SwUpdate.checkForUpdate()` once the application first becomes stable and\n * then every 5 minutes, and flips {@link available$} to `true` when the service worker\n * reports a `VERSION_READY` event. Injecting it is enough to start the polling; render\n * {@link UpdateComponent} (or your own UI on `available$`) to let the user act on it.\n * Harmless without a service worker: the checks fail and are logged as warnings.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class UpdateService {\n private stable = false;\n\n private appRef = inject(ApplicationRef);\n private swUpdate = inject(SwUpdate);\n\n constructor() {\n this._available$ = new ReplaySubject<boolean>(1);\n this._available$.next(false);\n const appIsStable$ = this.appRef.isStable\n .pipe(first((isStable) => isStable))\n .pipe(tap(() => console.log('App is stable')));\n const checkInterval$ = timer(10 * 1000, 5 * 60 * 1000);\n const checkWhenStable$ = merge(appIsStable$, checkInterval$);\n const updatesAvailable = this.swUpdate.versionUpdates.pipe(\n tap((evt) => console.log('Version updates event', evt)),\n filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'),\n map((evt) => ({\n type: 'UPDATE_AVAILABLE',\n current: evt.currentVersion,\n available: evt.latestVersion,\n })),\n );\n updatesAvailable.pipe(takeUntilDestroyed()).subscribe(() => {\n this._available$.next(true);\n });\n checkWhenStable$.pipe(takeUntilDestroyed()).subscribe(() => {\n this.stable = true;\n void this._checkForUpdate();\n });\n }\n\n private _available$: ReplaySubject<boolean>;\n\n /**\n * Asks the service worker whether a new version is available. Swallows the\n * failure raised when no service worker is registered, which is the normal\n * case in development.\n */\n private async _checkForUpdate(): Promise<void> {\n try {\n console.log('Checking for update');\n const res = await this.swUpdate.checkForUpdate();\n console.log('Check for update result', res);\n } catch {\n console.warn('No service worker');\n }\n }\n\n /**\n * Whether a new version is ready to be activated. Starts at `false`, becomes `true` on\n * `VERSION_READY`, and returns to `false` once the user activates or dismisses it.\n */\n public get available$(): Observable<boolean> {\n return this._available$.asObservable();\n }\n\n /**\n * Applies the pending update by reloading the page, discarding any unsaved in-memory\n * state. Call it from a user-initiated action rather than automatically.\n */\n public activate(): void {\n this._available$.next(false);\n console.log('RELOADING FULL PAGE');\n document.location.reload();\n }\n\n /**\n * Hides the update prompt without reloading. The update stays pending and the prompt\n * reappears the next time the service worker signals a ready version.\n */\n public dismiss(): void {\n this._available$.next(false);\n }\n}\n","import { Component, inject } from '@angular/core';\nimport { UpdateService } from '../update.service';\nimport { AsyncPipe } from '@angular/common';\n\n@Component({\n selector: 'data-update',\n templateUrl: './update.component.html',\n styleUrls: ['./update.component.sass'],\n imports: [AsyncPipe],\n})\n/**\n * Snackbar prompting the user to reload when {@link UpdateService} reports a new\n * application version, with \"activate now\" and \"later\" actions.\n *\n * Place one instance in the application shell; it renders nothing until an update is\n * actually available. The prompt text is French and not translatable — supply your own\n * component bound to `UpdateService.available$` if that does not suit.\n */\nexport class UpdateComponent {\n /** The update service backing the prompt; also bound directly by the template. */\n public update = inject(UpdateService);\n}\n","@if (update.available$ | async) {\n <div class=\"snack\">\n <p>Une nouvelle version de l'application est disponible.</p>\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <button class=\"btn btn-primary btn-block w-100\" (click)=\"update.activate()\">L'ACTIVER MAINTENANT</button>\n </div>\n <div class=\"col-sm-6\">\n <button class=\"btn btn-warning btn-block w-100\" (click)=\"update.dismiss()\">Plus tard</button>\n </div>\n </div>\n </div>\n}\n","/*\n * Public API Surface of data\n */\n/// <reference types=\"@angular/localize\" />\n\nexport * from './lib/data/data-parameters';\nexport * from './lib/data/data-model';\nexport * from './lib/data/field-values';\nexport * from './lib/data/data-collection';\nexport * from './lib/data/data-backend';\nexport * from './lib/data/data-query';\n\nexport * from './lib/modellist/model-list.service';\nexport * from './lib/modellist/model-list-fields/model-list-fields-selector/model-list-fields-selector.component';\nexport * from './lib/modellist/model-list-fields/model-list-field-header/model-list-field-header.component';\nexport * from './lib/modellist/model-list-sorter/model-list-sorter/model-list-sorter.component';\nexport * from './lib/modellist/model-list-filters/model-list-filters-select/model-list-filters-select.component';\nexport * from './lib/modellist/model-list-filters/model-list-filters/model-list-filters.component';\nexport * from './lib/modellist/model-list-filters/model-list-filters';\nexport * from './lib/modellist/model-list-filters/model-list-filter';\nexport * from './lib/modellist/model-list-filters/model-list-filter-group';\n\nexport * from './lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetimerange-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter';\nexport * from './lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter';\n\nexport * from './lib/modellist/model-list-filters/filters/model-list-geodistance-filter/adapters/ban';\n\nexport * from './lib/modellist/model-list-paginator/model-list-paginator/model-list-paginator.component';\n\nexport * from './lib/dispedit/choice.pipe';\nexport * from './lib/dispedit/factor.pipe';\nexport * from './lib/dispedit/factorc.pipe';\nexport * from './lib/dispedit/dispedit/dispedit.component';\nexport * from './lib/dispedit/fkselect/fkselect.component';\nexport * from './lib/dispedit/m2mselect/m2mselect.component';\nexport * from './lib/dispedit/flags/flags.component';\n\nexport * from './lib/dispedit/sdelete/sdelete.component';\nexport * from './lib/data/fields/index';\nexport { BaseFieldManager } from './lib/data/fields/base';\n\nexport * from './lib/messages/message.service';\nexport * from './lib/messages/message-zone/message-zone.component';\n\nexport * from './lib/data/data-collection.mock';\nexport * from './lib/uploader/index';\n\nexport * from './lib/auth/auth.service';\nexport * from './lib/auth/auth-interceptor.service';\nexport * from './lib/auth/jwt';\n\nexport * from './lib/routing/routing';\nexport * from './lib/routing/breadcrumb/breadcrumb.component';\n\nexport * from './lib/utils/tab-memory.service';\nexport * from './lib/utils/slugify';\nexport * from './lib/utils/unique-id';\nexport * from './lib/utils/editor-dom-shims';\nexport * from './lib/editors/field-editor-base';\nexport * from './lib/editors/safe-html.pipe';\nexport * from './lib/utils/template';\n\nexport * from './lib/updates/update.service';\nexport * from './lib/updates/update/update.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2"],"mappings":"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"}