import { ValidatorFn, AsyncValidatorFn, AbstractControl, UntypedFormGroup, UntypedFormArray, ValidationErrors, FormControl, FormGroup, FormGroupDirective, NgForm, ControlValueAccessor, NgControl } from '@angular/forms'; import * as _angular_router from '@angular/router'; import { ActivatedRoute, ResolveData, UrlSegment, Router, NavigationExtras, RouterLink, Data as Data$1, NavigationEnd, UrlMatcher, Params, QueryParamsHandling, UrlTree } from '@angular/router'; import { MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar'; import * as rxjs from 'rxjs'; import { Observable, Subject, BehaviorSubject, OperatorFunction, ObservedValueOf, MonoTypeOperatorFunction } from 'rxjs'; import * as i0 from '@angular/core'; import { Injector, InjectionToken, OnInit, DestroyRef, Type, EnvironmentProviders, OnChanges, SimpleChanges, AfterViewInit, PipeTransform, Provider, OnDestroy, EmbeddedViewRef, ComponentRef, StaticProvider, TemplateRef, DoCheck, ErrorHandler, ApplicationConfig } from '@angular/core'; import { ComponentType, BasePortalOutlet, CdkPortalOutlet, TemplatePortal, ComponentPortal } from '@angular/cdk/portal'; import { DataSource, SelectionModel } from '@angular/cdk/collections'; import { Apollo } from 'apollo-angular'; import { OperationVariables, WatchQueryFetchPolicy, ApolloLink, ApolloClient } from '@apollo/client'; import { DocumentNode, GraphQLFormattedError } from 'graphql'; import * as _angular_material_paginator from '@angular/material/paginator'; import { PageEvent } from '@angular/material/paginator'; import { MatTableDataSource, MatCellDef } from '@angular/material/table'; import { Sort } from '@angular/material/sort'; import { HttpLink, HttpBatchLink } from 'apollo-angular/http'; import { ErrorLink } from '@apollo/client/link/error'; import { HttpInterceptorFn } from '@angular/common/http'; import { NativeDateAdapter, ErrorStateMatcher } from '@angular/material/core'; import { MatTreeNestedDataSource } from '@angular/material/tree'; import { MatDialogConfig, MatDialogRef } from '@angular/material/dialog'; import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; import { MatSidenav, MatDrawerMode } from '@angular/material/sidenav'; import { MatButtonAppearance } from '@angular/material/button'; import * as _ecodev_natural from '@ecodev/natural'; declare class NaturalAlertService { private readonly dialog; private readonly snackBar; /** * Show an informative message in a snack bar */ info(message: string, duration?: number | null): MatSnackBarRef; /** * Show an error in a snack bar */ error(message: string, duration?: number | null, action?: string): MatSnackBarRef; /** * Show a simple confirmation dialog and returns true if user confirmed it */ confirm(title: string, message: string, confirmText: string, cancelText?: string): Observable; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } /** * TODO: implement route update when closing dialog with escape * @dynamic */ declare class NaturalPanelsService { private readonly router; private readonly dialog; private readonly injector; private hooksConfig; private readonly panelWidth; /** * Because of this static property Panels are **not** compatible with SSR. * And we cannot make it non-static, because `UrlMatcher` cannot be injected. */ private static _opened; static get opened(): boolean; /** * Stream that emits when all open dialog have finished closing */ readonly afterAllClosed: Subject; /** * Cache for panels counter. Works more like an ID. * Is used to give an unique identifier to multiple similar panels configurations */ private counter; /** * Class applied to dialog overlay related with panels * If change, change CSS too */ private panelClass; /** * Cache for panels setup before navigation change. * Used to detect panels openings/closings and adapt for new configuration */ private oldFullConfig; /** * Cache for subscription stop */ private routeSub?; /** * Cache for subscription stop */ private navSub?; /** * Horizontal gaps between panels */ private panelsOffsetH; /** * Vertical gaps between panels */ private panelsOffsetV; /** * Cache of previous screen size * Used to change panels stack orientation on small screens */ private isVertical; constructor(); /** * Notify the service to start listening to route changes to open panels * * @internal */ start(route: ActivatedRoute): void; /** * Uses given configuration to add at the end of current url */ private appendConfigToCurrentUrl; /** * Notify the service that all panels were closed * * @internal */ stop(): void; /** * Go to panel matching given component. Causes an url change. * * @internal */ goToPanelByComponent(component: NaturalAbstractPanel): void; /** * Go to panel matching given component. Causes an url change. */ goToPenultimatePanel(): void; /** * Calls the new url that only includes the segments from the panels we want to stay open */ private goToPanelByIndex; /** * Selecting a panel is equivalent to close all those that are in front of him * @param index of panel in stack. The most behind (the first one) is 0. */ private selectPanelByIndex; /** * Open new panels if url has changed with new segments */ private updatePanels; /** * Resolve all services, then open panels */ private openPanels; private getPanelData; private getResolvedData; private openPanel; private refreshPanel; /** * Return panel position (index) by searching matching component */ private getPanelIndex; /** * Whether the given panel is currently the top, visible, panel. If there are no panels opened at all, then any panel given is considered top, visible, panel. */ isTopPanel(component: NaturalAbstractPanel): boolean; /** * Repositions panels from start until given index */ private updateComponentsPosition; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type PaginatedData = { readonly items: readonly T[]; readonly offset?: number | null; readonly pageSize: number; readonly pageIndex: number; readonly length: number; }; /** * A NaturalDataSource will connect immediately, in order to know as soon as possible if * we need to show a template at all (as seen in my-ichtus) * * It also allow some extra data manipulation */ declare class NaturalDataSource = PaginatedData> extends DataSource { private readonly ngUnsubscribe; private readonly internalData; constructor(value: Observable | T); get internalDataObservable(): Observable; /** * Array of data that should be rendered by the table, where each object represents one row. */ get data(): T | null; set data(data: T | null); connect(): Observable; disconnect(): void; push(item: T['items'][0]): void; pop(): T['items'][0] | undefined; remove(item: T['items'][0]): void; } type QueryVariables = { filter?: any | null; pagination?: PaginationInput | null; sorting?: Sorting[] | null; }; type PaginationInput = { offset?: number | null; pageIndex?: number | null; pageSize?: number | null; }; type Sorting = { field: any; order?: SortingOrder | null; nullAsHighest?: boolean | null; emptyStringAsHighest?: boolean | null; }; declare enum SortingOrder { ASC = "ASC", DESC = "DESC" } /** * Filter manager stores a set of channels that contain a variable object and exposes an observable "variables" that updates with the result * of all channels merged together. * * A channel is supposed to be used by a given aspect of the GUI (pagination, sorting, search, others ?). * * ```ts * const fm = new QueryVariablesManager(); * fm.merge('componentA-variables', {a : [1, 2, 3]}); * ``` * * Variables attributes is a BehaviorSubject. That mean it's not mandatory to subscribe, we can just call getValue or value attributes on * it : * * ```ts * console.log(fm.variables.value); // {a : [1, 2, 3]} * ``` * * Set new variables for 'componentA-variables': * * ```ts * fm.merge('componentA-variables', {a : [1, 2]}); * console.log(fm.variables.value); // {a : [1, 2, 3]} * ``` * * Set new variables for new channel: * * ```ts * fm.merge('componentB-variables', {a : [3, 4]}); * console.log(fm.variables.value); // {a : [1, 2, 3, 4]} * ``` */ declare class NaturalQueryVariablesManager { readonly variables: BehaviorSubject; private readonly channels; constructor(queryVariablesManager?: NaturalQueryVariablesManager); /** * Set or override all the variables that may exist in the given channel */ set(channelName: string, variables: Partial | null | undefined): void; /** * Return a deep clone of the variables for the given channel name. * * Avoid returning the same reference to prevent an attribute change, then another channel update that would * used this changed attribute without having explicitly asked QueryVariablesManager to update it. */ get(channelName: string): Partial | undefined; /** * Merge variable into a channel, overriding arrays in same channel / key */ merge(channelName: string, newVariables: Partial): void; /** * Apply default values to a channel * Note : lodash defaults only defines values on destinations keys that are undefined */ defaults(channelName: string, newVariables: Partial): void; private getChannelsCopy; /** * Merge channels in a single object * Arrays are concatenated * Filter groups are combined smartly (see mergeGroupList) */ private updateVariables; /** * Cross merge two filters * Only accepts groups with same groupLogic (ignores the first one, because there is no groupLogic in this one) * @throws In case two non-empty lists of groups are given and at one of them mix groupLogic value, throws an error */ private mergeGroupList; } /** * Debounce subscriptions to update mutations, with the possibility to cancel one, flush one, or flush all of them. * * `modelService` is also used to separate objects by their types. So User with ID 1 is not confused with Product with ID 1. * * `id` must be the ID of the object that will be updated. */ declare class NaturalDebounceService { /** * Stores the debounced update function */ private readonly allDebouncedUpdateCache; /** * Debounce the `modelService.updateNow()` mutation for a short time. If called multiple times with the same * modelService and id, it will postpone the subscription to the mutation. * * All input variables for the same object (same service and ID) will be cumulated over time. So it is possible * to update `field1`, then `field2`, and they will be batched into a single XHR including `field1` and `field2`. * * But it will always keep the same debouncing timeline. */ debounce(modelService: UntypedModelService, id: string, object: Parameters[0]): ReturnType; cancelOne(modelService: UntypedModelService, id: string): void; /** * Immediately execute the pending update, if any. * * It should typically be called before resolving the object, to mutate it before re-fetching it from server. * * The returned observable will complete when the update completes, even if it errors. */ flushOne(modelService: UntypedModelService, id: string): Observable; /** * Immediately execute all pending updates. * * It should typically be called before login out. * * The returned observable will complete when all updates complete, even if some of them error. */ flush(): Observable; private internalFlush; /** * Count of pending updates */ get count(): number; private getMap; private delete; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type FormValidators = Record; type FormAsyncValidators = Record; type VariablesWithInput = { input: Literal; }; type FormControls = Record; type WithId = { id: string; } & T; type MutateOptionsWithoutVariables = Omit, 'mutation' | 'variables'>; type WatchQueryOptionsWithoutVariables = Omit, 'query' | 'variables' | 'notifyOnNetworkStatusChange'>; declare abstract class NaturalAbstractModelService, Vall extends QueryVariables, Tcreate, Vcreate extends VariablesWithInput, Tupdate, Vupdate extends { id: string; input: Literal; }, Tdelete, Vdelete extends { ids: string[]; }> { protected readonly name: string; protected readonly oneQuery: DocumentNode | null; readonly allQuery: DocumentNode | null; protected readonly createMutation: DocumentNode | null; protected readonly updateMutation: DocumentNode | null; protected readonly deleteMutation: DocumentNode | null; private readonly createName; private readonly updateName; private readonly deleteName; /** * Store the creation mutations that are pending */ private readonly creatingCache; protected readonly apollo: Apollo; protected readonly naturalDebounceService: NaturalDebounceService; private readonly plural; /** * * @param name service and single object query name (eg. userForFront or user). * @param oneQuery GraphQL query to fetch a single object from ID (eg. userForCrudQuery). * @param allQuery GraphQL query to fetch a filtered list of objects (eg. usersForCrudQuery). * @param createMutation GraphQL mutation to create an object. * @param updateMutation GraphQL mutation to update an object. * @param deleteMutation GraphQL mutation to delete a list of objects. * @param plural list query name (eg. usersForFront or users). * @param createName create object mutation name (eg. createUser). * @param updateName update object mutation name (eg. updateUser). * @param deleteName delete object mutation name (eg. deleteUsers). */ constructor(name: string, oneQuery: DocumentNode | null, allQuery: DocumentNode | null, createMutation: DocumentNode | null, updateMutation: DocumentNode | null, deleteMutation: DocumentNode | null, plural?: string | null, createName?: string | null, updateName?: string | null, deleteName?: string | null); /** * List of individual fields validators */ getFormValidators(model?: Literal): FormValidators; /** * List of individual async fields validators */ getFormAsyncValidators(model?: Literal): FormAsyncValidators; /** * List of grouped fields validators (like password + confirm password) */ getFormGroupValidators(model?: Literal): ValidatorFn[]; /** * List of async group fields validators (like unique constraint on multiple columns) */ getFormGroupAsyncValidators(model?: Literal): AsyncValidatorFn[]; getFormConfig(model: Literal): FormControls; /** * Create the final FormGroup for the object, including all validators * * This method should **not** be overridden, but instead `getFormConfig`, * `getFormGroupValidators`, `getFormGroupAsyncValidators` might be. */ getFormGroup(model: Literal): UntypedFormGroup; /** * Get a single object * * If available it will emit object from cache immediately, then it * will **always** fetch from network and then the observable will be completed. * * You must subscribe to start getting results (and fetch from network). */ getOne(id: string): Observable; /** * Watch a single object * * If available it will emit object from cache immediately, then it * will **always** fetch from network, and then keep watching the cache forever. * * You must subscribe to start getting results (and fetch from network). * * You **MUST** unsubscribe. */ watchOne(id: string, options?: WatchQueryOptionsWithoutVariables): Observable; private prepareOneQuery; /** * Get a collection of objects * * It will **always** fetch from network and then the observable will be completed. * No cache is ever used, so it's slow but correct. */ getAll(queryVariablesManager: NaturalQueryVariablesManager): Observable; /** * Get a collection of objects * * Every time the observable variables change, and they are not undefined, * it will return result from cache, then it will **always** fetch from network, * and then keep watching the cache forever. * * You must subscribe to start getting results (and fetch from network). * * You **MUST** unsubscribe. */ watchAll(queryVariablesManager: NaturalQueryVariablesManager, fetchPolicy?: WatchQueryFetchPolicy): Observable; /** * This functions allow to quickly create or update objects. * * Manages a "creation is pending" status, and update when creation is ready. * Uses regular `create()` (with immediate effect) and `update()` (with debounced effect) methods. * Used mainly when editing multiple objects in the same controller, like in editable arrays. */ createOrUpdate(object: Vcreate['input'] | WithId): Observable; /** * Create an object in DB */ create(object: Vcreate['input'], options?: MutateOptionsWithoutVariables): Observable; /** * Update an object, after a short debounce */ update(object: WithId): Observable; /** * Update an object immediately when subscribing */ updateNow(object: WithId, options?: MutateOptionsWithoutVariables): Observable; /** * Delete objects */ delete(objects: { id: string; }[], options?: MutateOptionsWithoutVariables): Observable; /** * If the id is provided, resolves an observable model. The observable model will only be emitted after we are sure * that Apollo cache is fresh and warm. Then the component can subscribe to the observable model to get the model * immediately from Apollo cache and any subsequents future mutations that may happen to Apollo cache. * * Without id, returns default values, in order to show a creation form. */ resolve(id: string | undefined): Observable>; /** * Return an object that match the GraphQL input type. * It creates an object with manually filled data and add uncompleted data (like required attributes that can be empty strings) */ getInput(object: Literal, forCreation: boolean): Vcreate['input'] | Vupdate['input']; /** * Return the number of objects matching the query. It may never complete. * * This is used for the unique validator */ count(queryVariablesManager: NaturalQueryVariablesManager): Observable; /** * Return empty object with some default values from server perspective * * This is typically useful when showing a form for creation */ getDefaultForServer(): Vcreate['input']; /** * You probably **should not** use this. * * If you are trying to *call* this method, instead you probably want to call `getDefaultForServer()` to get default * values for a model, or `getFormConfig()` to get a configured form that includes extra form fields. * * If you are trying to *override* this method, instead you probably want to override `getDefaultForServer()`. * * The only and **very rare** reason to override this method is if the client needs extra form fields that cannot be * accepted by the server (not part of `XXXInput` type) and that are strictly for the client form needs. In that case, * then you can return default values for those extra form fields, and the form returned by `getFormConfig()` will * include those extra fields. */ protected getFormExtraFieldDefaultValues(): Literal; /** * This is used to extract only the array of fetched objects out of the entire fetched data */ protected mapAll(): OperatorFunction, Tall>; /** * This is used to extract only the created object out of the entire fetched data */ protected mapCreation(result: Apollo.MutateResult): Tcreate; /** * This is used to extract only the updated object out of the entire fetched data */ protected mapUpdate(result: Apollo.MutateResult): Tupdate; /** * This is used to extract only flag when deleting an object */ protected mapDelete(result: Apollo.MutateResult): Tdelete; /** * Returns additional variables to be used when getting a single object * * This is typically a site or state ID, and is needed to get appropriate access rights */ protected getPartialVariablesForOne(): Observable>; /** * Returns additional variables to be used when getting multiple objects * * This is typically a site or state ID, but it could be something else to further filter the query */ getPartialVariablesForAll(): Observable>; /** * Returns additional variables to be used when creating an object * * This is typically a site or state ID */ protected getPartialVariablesForCreation(object: Literal): Partial; /** * Returns additional variables to be used when updating an object * * This is typically a site or state ID */ protected getPartialVariablesForUpdate(object: Literal): Partial; /** * Return additional variables to be used when deleting an object * * This is typically a site or state ID */ protected getPartialVariablesForDelete(objects: Literal[]): Partial; /** * Throw exception to prevent executing queries with invalid variables */ protected throwIfObservable(value: unknown): void; /** * Merge given ID with additional partial variables if there is any */ private getVariablesForOne; /** * Throw exception to prevent executing null queries */ private throwIfNotQuery; } /** * An object literal with any keys and values */ type Literal = Record; /** * An object with either a name or a fullName (or maybe both) */ type NameOrFullName = { id: string; name: string; fullName?: string; } | { id: string; name?: string; fullName: string; }; /** * Extract the Tone type from a NaturalAbstractModelService */ type ExtractTone

= P extends NaturalAbstractModelService ? Tone : never; /** * Extract the Vone type from a NaturalAbstractModelService */ type ExtractVone

= P extends NaturalAbstractModelService ? Vone extends { id: string; } ? Vone : never : never; /** * Extract the Tall type from a NaturalAbstractModelService */ type ExtractTall

= P extends NaturalAbstractModelService ? Tall extends PaginatedData ? Tall : never : never; /** * Extract the TallOne type for a single item coming from a list of items from a NaturalAbstractModelService */ type ExtractTallOne

= P extends NaturalAbstractModelService, any, any, any, any, any, any, any> ? TallOne extends Literal ? TallOne : never : never; /** * Extract the Vall type from a NaturalAbstractModelService */ type ExtractVall

= P extends NaturalAbstractModelService ? Vall extends QueryVariables ? Vall : never : never; /** * Extract the Tcreate type from a NaturalAbstractModelService */ type ExtractTcreate

= P extends NaturalAbstractModelService ? Tcreate : never; /** * Extract the Vcreate type from a NaturalAbstractModelService */ type ExtractVcreate

= P extends NaturalAbstractModelService ? Vcreate extends VariablesWithInput ? Vcreate : never : never; /** * Extract the Tupdate type from a NaturalAbstractModelService */ type ExtractTupdate

= P extends NaturalAbstractModelService ? Tupdate : never; /** * Extract the Vupdate type from a NaturalAbstractModelService */ type ExtractVupdate

= P extends NaturalAbstractModelService ? Vupdate extends { id: string; input: Literal; } ? Vupdate : never : never; /** * Extract the Tdelete type from a NaturalAbstractModelService */ type ExtractTdelete

= P extends NaturalAbstractModelService ? Tdelete : never; /** * Extract the Vdelete type from a NaturalAbstractModelService */ type ExtractVdelete

= P extends NaturalAbstractModelService ? Vdelete extends { ids: string[]; } ? Vdelete : never : never; /** * Extract the resolve type from a NaturalAbstractModelService */ type ExtractResolve

= P extends NaturalAbstractModelService ? ObservedValueOf>> : never; /** * This should be avoided if possible, and instead use a more precise type with some constraints on it to ensure that the model * service is able to fulfill its requirements. */ type UntypedModelService = NaturalAbstractModelService; /** * Returns the resolved data type, as available in components, from the given resolvers * * Eg: * * ```ts * const actionResolvers = { * model: resolveAction, * statuses: () => inject(NaturalEnumService).get('Status'), * } as const; * * // In action.component.ts * const data: ResolvedData; * data.statuses.forEach(...); * ``` */ type ResolvedData = { readonly [KeyType in keyof Pick]: ObservedValueOf[KeyType]>>; }; type NaturalPalette = 'primary' | 'tertiary' | 'error' | undefined; type LinkableObject = { id: string; __typename: string; }; declare class NaturalLinkMutationService { private readonly apollo; /** * Receives the list of available mutations */ private allMutations?; /** * Link two objects together */ link(obj1: LinkableObject, obj2: LinkableObject, otherName?: string | null, variables?: Literal): Observable>; /** * Link many objects */ linkMany(obj1: LinkableObject, objects: LinkableObject[], otherName?: string | null, variables?: Literal): Observable[]>; /** * Unlink two objects */ unlink(obj1: LinkableObject, obj2: LinkableObject, otherName?: string | null): Observable>; /** * Return the list of all available mutation names */ private getAllMutationNames; /** * Generate mutation using patterns and replacing variables */ private getMutation; /** * Execute mutation */ private execute; /** * Build the actual mutation string */ private buildTemplate; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } /** * Kind of snapshot of the instance of a panel activated route */ type NaturalPanelsRouteConfig = { segments: UrlSegment[]; path: string; }; /** * Config required to manage url and instantiate component correctly */ type NaturalPanelConfig = { component: ComponentType; injector: Injector | null; resolve: NaturalPanelResolves; params: Literal; rule: NaturalPanelsRouterRule; route: NaturalPanelsRouteConfig; }; /** * Data provided to instantiated components in context of a panel/dialog */ type NaturalPanelData = { config: NaturalPanelConfig; data: Literal; /** * Related objects that should be linked to the object shown in the panel after its creation */ linkableObjects: LinkableObject[]; }; /** * Similar to Angular functional resolver interface, but simpler for our panels' needs */ type NaturalPanelResolve = (route: NaturalPanelConfig) => Observable; type NaturalPanelResolves = Record>; /** * Configuration for a route */ type NaturalPanelsRouterRule = { path: string; component: ComponentType; resolve?: NaturalPanelResolves; }; type NaturalPanelsBeforeOpenPanel = { panelData: NaturalPanelData; fullPanelsConfig: NaturalPanelConfig[]; }; type NaturalPanelsHooksConfig = { beforeOpenPanel?: (injector: Injector, naturalPanelsBeforeOpenPanel: NaturalPanelsBeforeOpenPanel) => NaturalPanelData; }; type NaturalPanelsRoutesConfig = NaturalPanelsRouterRule[]; declare const PanelsHooksConfig: InjectionToken; declare abstract class NaturalAbstractPanel implements OnInit { protected readonly destroyRef: DestroyRef; /** * The data property is the container where the resolved content is stored * When loading a component from a panel opening (dialog), receives the data provided by the service */ data: any; /** * Bind isFrontPanel style class on root component */ isFrontPanel: boolean; /** * Bind isPanel style class on root component */ isPanel: boolean; /** * Merging of data provided by the very root component (that is in a route context) and inherited data through panels * TODO: provide type with available attributes */ panelData?: NaturalPanelData; panelService?: NaturalPanelsService; ngOnInit(): void; /** * Bind click on panels, to allow the selection of those who are behind */ clickPanel(): void; /** * Called when panel opens and component is loaded * Runs before ngOnInit() */ initPanel(panelData: NaturalPanelData): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } /** * `Data` contains in `model` either the model fetched from DB or default values (without ID). And besides `model`, * any other extra keys defined by Extra. */ type Data = { model: { id?: string; } & ExtractResolve; } & Extra; declare class NaturalAbstractDetail, QueryVariables, any, any, any, any, unknown, any>, ExtraResolve extends Literal = Record> extends NaturalAbstractPanel { #private; protected readonly key: string; readonly service: TService; protected readonly alertService: NaturalAlertService; protected readonly router: Router; protected readonly route: ActivatedRoute; private readonly _dialogData; /** * Data retrieved by the server via route resolvers. * * The key `model` is special. It is readonly and represents the model being updated * as it exists on server. The value is kept up to date when Apollo mutates it on server. * * The only time when `model` is not readonly is during creation. Only then can we modify the model values directly. * * Other keys, if present, are whatever is returned from route resolvers as-is. */ data: Data; /** * Form that manages the data from the controller */ form: UntypedFormGroup; /** * Show / hides the bottom fab button (mostly to hide it when we are on other tabs where semantic of button can conflict with ... * semantic of data on other tab, like relations that list other objects) */ showFabButton: boolean; /** * Once set, this must not change anymore, especially not right after the creation mutation, * so the form does not switch from creation mode to update mode without an actual reload of * model from DB (by navigating to update page). */ private _isUpdatePage; private readonly changes; constructor(key: string, service: TService); /** * You probably should not override this method. Instead, consider overriding `initForm()`. */ ngOnInit(): void; changeTab(index: number): void; /** * Returns whether `data.model` was fetched from DB, so we are on an update page, or if it is a new object * with (only) default values, so we are on a creation page. * * This should be used instead of checking `data.model.id` directly, in order to type guard and get proper typing */ protected isUpdatePage(): this is { data: { model: ExtractTone; }; }; /** * Update the object on the server with the values from the form fields that were modified since * the initialization, or since the previous successful update. * * Form fields that are never modified are **not** sent to the server, unless if you specify `submitAllFields`. */ update(now?: boolean, submitAllFields?: boolean): void; create(redirect?: boolean): void; /** * `confirmer` can be used to open a custom dialog, or anything else, to confirm the deletion, instead of the standard dialog */ delete(redirectionRoute?: unknown[] | { commands: unknown[]; extras: NavigationExtras; }, confirmer?: Observable): void; protected postUpdate(model: ExtractTupdate): void; /** * Returns an observable that will be subscribed to immediately and the * redirect navigation will only happen after the observable completes. */ protected postCreate(model: ExtractTcreate): Observable; protected preDelete(model: ExtractTone): void; /** * Returns an observable that will be subscribed to immediately and the * redirect navigation will only happen after the observable completes. */ protected postDelete(model: ExtractTone): Observable; /** * Initialize the form whenever it is needed. * * You should override this method, and not `ngOnInit()` if you need to customize the form. Because this will * correctly be called more than one time per component instance if needed, when the route changes. But `ngOnInit()` * will incorrectly be called exactly 1 time per component instance, even if the object changes via route navigation. */ protected initForm(): void; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵdir: i0.ɵɵDirectiveDeclaration, never, never, {}, {}, never, never, true, never>; } /** * This class helps managing non-paginated rows of items that can be edited in-place, typically in a . * But it does **not** mutate anything to persist the edits on the server. It is up to the consuming component to implement * custom mutation mechanism. * * To access data of this component from a parent component, use: * * ```ts * private readonly cmp = viewChildren(ComponentType); * * this.cmp.getItems(); * ``` * * To add empty line, call: * * ``` * this.cmp.addEmpty(); * ``` * * @dynamic */ declare class NaturalAbstractEditableList, QueryVariables, any, any, any, any, any, any>, T extends Literal = ExtractTallOne> { protected readonly service: TService; readonly form: UntypedFormGroup; readonly formArray: UntypedFormArray; readonly variablesManager: NaturalQueryVariablesManager>; readonly dataSource: MatTableDataSource, _angular_material_paginator.MatPaginator>; constructor(service: TService); /** * Set the list of items (overwriting what may have existed) */ setItems(items: readonly T[]): void; /** * Add given items to the list * Reproduces the model data loading the same way as it would be on a detail page (via AbstractDetail controller) but without resolving */ addItems(items: readonly T[]): void; removeAt(index: number): void; /** * Add empty item at the end of the list */ addEmpty(): void; /** * Return a list of models without any treatment. * * To mutate models, it would be required to map them using : * - AbstractModelService.getInput() * - AbstractModelService.getPartialVariablesForCreation() * - AbstractModelService.getPartialVariablesForUpdate() * - some other required treatment. * * TODO return type is incorrect and should be closer to `Partial[]` or an even looser type, because we don't really know what fields exists in the form. When we fix this, we should also remove type coercing in unit tests. */ getItems(): T[]; /** * Force the form validation. * * The valid state can then be read via `this.form.valid` */ validateForm(): void; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵdir: i0.ɵɵDirectiveDeclaration, never, never, {}, {}, never, never, true, never>; } type AvailableColumn = { /** * This must be the column ID as defined in `matColumnDef` * * Implementation details: * * Unfortunately, we cannot use a `Record` where keys would implicitly be unique and would replace * this ID property, because only ES2020 guarantee the order of object keys, and we must still support ES2015 for * iPhone 6. So, instead of `Record`, we use `AvailableColumn[]` for now. But this could be * revisited once we drop support of ES2015. * * @see https://stackoverflow.com/questions/30076219/does-es6-introduce-a-well-defined-order-of-enumeration-for-object-properties */ id: string; /** * Localized label of column for human */ label: string; /** * Initial checked state, defaults to `true`. */ checked?: boolean; /** * Initial visibility state, defaults to `false`. * * A column that is hidden will not appear in the list of choice, * but it will be included in the result of selected columns. */ hidden?: boolean; }; /** * A button that will be shown as an icon on desktop, or as a menu entry on mobile */ type Button = { /** * On desktop will be shown as tooltip, or as menu entry on mobile */ label: string; /** * The icon name to be used on desktop */ icon: string; /** * Whether to show the button at all. Defaults to `true`. */ show?: boolean; /** * Whether the button is disabled. Defaults to `false`. */ disabled?: boolean; /** * A checked button will have a highlight color as an icon, or a check mark as menu entry. Defaults to `false`. */ checked?: boolean; /** * The callback to call when button was clicked. */ click?: (button: Button, event: Event) => void; /** * Rarely used, only for OKpilot where we want to show proper URL, but click is actually intercepted to show dialog */ href?: string; /** * A non-empty list of sub-buttons (only 2 levels is supported). */ buttons?: SubButton[]; }; /** * A sub-button that will (always) be shown as a sub-menu entry */ type SubButton = { /** * Label for menu entry */ label: string; /** * Whether the button is disabled. Defaults to `false`. */ disabled?: boolean; /** * The callback to call when button was clicked. */ click: (subButton: SubButton, event: Event) => void; }; type Filter = { groups?: FilterGroup[] | null; }; type FilterGroup = { groupLogic?: LogicalOperator | null; conditionsLogic?: LogicalOperator | null; joins?: FilterGroupJoin | null; conditions?: FilterGroupCondition[] | null; }; type FilterGroupJoin = Record; type JoinOn = { type?: JoinType | null; joins?: FilterGroupJoin | null; conditions?: FilterGroupCondition[] | null; }; declare enum LogicalOperator { AND = "AND", OR = "OR" } declare enum JoinType { innerJoin = "innerJoin", leftJoin = "leftJoin" } type FilterGroupCondition = Record; type FilterGroupConditionField = { between?: BetweenOperator | null; equal?: EqualOperator | null; greater?: GreaterOperator | null; greaterOrEqual?: GreaterOrEqualOperator | null; in?: InOperator | null; less?: LessOperator | null; lessOrEqual?: LessOrEqualOperator | null; like?: LikeOperator | null; null?: NullOperator | null; have?: HaveOperator | null; empty?: EmptyOperator | null; [key: string]: Literal | undefined | null; }; type Scalar = number | string | boolean; type HaveOperator = { values: string[]; not?: boolean | null; }; type EmptyOperator = { not?: boolean | null; }; type BetweenOperator = { from: Scalar; to: Scalar; not?: boolean | null; }; type EqualOperator = { value: Scalar; not?: boolean | null; }; type GreaterOperator = { value: Scalar; not?: boolean | null; }; type GreaterOrEqualOperator = { value: Scalar; not?: boolean | null; }; type InOperator = { values: Scalar[]; not?: boolean | null; }; type LessOperator = { value: Scalar; not?: boolean | null; }; type LessOrEqualOperator = { value: Scalar; not?: boolean | null; }; type LikeOperator = { value: Scalar; not?: boolean | null; }; type NullOperator = { not?: boolean | null; }; type DropdownComponent = { /** * Observable of current value as string */ readonly renderedValue: BehaviorSubject; /** * Get condition, including rich object types */ getCondition(): FilterGroupConditionField; /** * Returns true if dropdown value is valid */ isValid(): boolean; /** * Returns true if the dropdown value has change */ isDirty(): boolean; }; /** * Type for a search selection */ type NaturalSearchSelection = { field: string; /** * This is required if the facet also have a `name`. * * See BasicFacet.name */ name?: string; condition: FilterGroupConditionField; }; /** * Groups are a list of values, that should be interpreted with AND condition */ type GroupSelections = NaturalSearchSelection[]; /** * List of groups, that should be interpreted with OR condition * Final input / output format */ type NaturalSearchSelections = GroupSelections[]; /** * Consolidated type for a selection and it's matching facet * Used internally for dropdown */ type DropdownResult = { condition: FilterGroupConditionField; facet?: Facet; }; type BasicFacet = { /** * The label to be used in the GUI */ display: string; /** * The field this facet should apply to. * * In most cases it should be the property name of the model. Something like: * * - name * - description * - artist.name */ field: string; /** * This is required only if there are duplicated `field` in all facets. * * If `name` exists it will be used as an alternative identifier for facet, instead of `field`, to match * a selection with its facet (in `getFacetFromSelection()`). So a selection must be given with the `name`, * instead of `field`. And it will also be present in the URL. But it will never appear in the GraphQL selection. * * https://github.com/Ecodev/natural-search/issues/16 */ name?: string; /** * A function to transform the selection before it is applied onto the filter. * * This would typically be useful to do unit conversion so the GUI has some user * friendly values, but the API works with a "low-level" unit. */ transform?: (s: NaturalSearchSelection) => NaturalSearchSelection; }; /** * Facet that is only a flag (set or unset) */ type FlagFacet = { /** * The value to be returned when the flag is set */ condition: Condition; /** * If true the value is set when the flag does NOT exist and the * value is unset when the flag exists. * * Defaults to `false`. */ inversed?: boolean; } & BasicFacet; /** * Facet that uses a component in a dropdown */ type DropdownFacet = { component: Type; /** * Show a button into the dropdown container to validate value. Gives alternative to "click out" and incoming "tab/esc" key. */ showValidateButton?: boolean; /** * Anything that could be useful for the dropdown component */ configuration?: C; } & BasicFacet; /** * A facet */ type Facet = DropdownFacet | FlagFacet; /** * Exhaustive list of facets */ type NaturalSearchFacets = Facet[]; /** * Validator for persisted values retrieved from NaturalPersistenceService. If returns false, the persisted value * will be ignored, and instead `null` will be returned. * * `storageKey` is only given if the value is coming from session storage (and not from URL). */ type PersistenceValidator = (key: string, storageKey: string | null, value: unknown) => boolean; declare const NATURAL_PERSISTENCE_VALIDATOR: InjectionToken; declare class NaturalPersistenceService { private readonly router; private readonly sessionStorage; private readonly isValid; /** * Persist in url and local storage the given value with the given key. * When stored in storage, we need more "key" to identify the controller. */ persist(key: string, value: unknown, route: ActivatedRoute, storageKey: string, navigationExtras?: NavigationExtras): Promise; /** * Return object with persisted data in url or in session storage * Url has priority over session storage because of url sharing. When url is provided, session storage is ignored. * Url and storage are synced when arriving in a component : * - When loading with url parameters, storage is updated to stay synced * - When loading without url, but with storage data, the url is updated */ get(key: string, route: ActivatedRoute, storageKey: string): any | null; /** * Get given key from the url parameters */ getFromUrl(key: string, route: ActivatedRoute): any | null; /** * Add/override given pair key-value in the url * Always JSON.stringify() the given value * If the value is falsey, the pair key-value is removed from the url. */ persistInUrl(key: string, value: unknown, route: ActivatedRoute, navigationExtras?: NavigationExtras): Promise; getFromStorage(key: string, storageKey: string): any | null; /** * Store value in session storage. * If value is falsy, the entry is removed */ persistInStorage(key: string, value: unknown, storageKey: string): void; private getStorageKey; private isFalseyValue; private deserialize; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type BreadcrumbItem = { id: string; name: string; } & Literal; type NavigableItem = { item: T; hasNavigation: boolean; }; /** * This class helps managing a list of paginated items that can be filtered, * selected, and then bulk actions can be performed on selection. * * @dynamic */ declare class NaturalAbstractNavigableList, QueryVariables, any, any, any, any, any, any>> extends NaturalAbstractList['items'][0]>>> implements OnInit { /** * Name of filter for child items to access ancestor item */ readonly ancestorRelationName: i0.InputSignal; private oldAncertorId; breadcrumbs: BreadcrumbItem[]; constructor(service: TService); ngOnInit(): void; protected getDataObservable(): Observable>>>; protected translateSearchAndRefreshList(naturalSearchSelections: NaturalSearchSelections): void; clearSearch(resetPagination?: boolean): void; search(naturalSearchSelections: NaturalSearchSelections, navigationExtras?: NavigationExtras, resetPagination?: boolean): void; /** * Return an array for router link usage */ getChildLink(ancestor: { id: string; } | null): RouterLink['routerLink']; /** * Depth is limited by queries * @param item with an ancestor relation (must match ancestorRelationName attribute) */ protected getBreadcrumb(item: BreadcrumbItem): BreadcrumbItem[]; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵdir: i0.ɵɵDirectiveDeclaration, never, never, { "ancestorRelationName": { "alias": "ancestorRelationName"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>; } type MaybeNavigable = Literal | NavigableItem; declare function getNumberRows(dataSource: { data?: PaginatedData | null; } | undefined): number; declare function getVisibleSelections(selection: SelectionModel, dataSource: { data?: PaginatedData | null; } | undefined): number; declare function isAllVisibleSelected(selection: SelectionModel, dataSource: { data?: PaginatedData | null; } | undefined): boolean; declare function isPartiallyVisibleSelected(selection: SelectionModel, dataSource: { data?: PaginatedData | null; } | undefined): boolean; declare function selectVisible(selection: SelectionModel, dataSource: { data?: PaginatedData | null; } | undefined): void; declare function unselectVisible(selection: SelectionModel, dataSource: { data?: PaginatedData | null; } | undefined): void; declare function masterToggleVisible(selection: SelectionModel, dataSource: { data?: PaginatedData | null; } | undefined): void; /** * This class helps managing a list of paginated items that can be filtered, * selected, and then bulk actions can be performed on selection. * * Components inheriting from this class can be used as standalone with input attributes. * * Usage : * * ```html * * ``` */ declare class NaturalAbstractList, QueryVariables, any, any, any, any, any, any>, Tall extends PaginatedData = ExtractTall> extends NaturalAbstractPanel { readonly service: TService; protected readonly router: Router; protected readonly route: ActivatedRoute; protected readonly alertService: NaturalAlertService; protected readonly persistenceService: NaturalPersistenceService; /** * Whether search should be loaded from url/storage and persisted in it too. */ persistSearch: boolean; /** * List of columns that are available to the end-user to select from, via `` */ availableColumns: AvailableColumn[]; /** * Columns list after interaction with `` */ columnsForTable: string[]; /** * The default column selection that automatically happened after `` initialization */ private defaultSelectedColumns; /** * Visible (checked) columns * * Instead of using this, you should consider correctly configuring `AvailableColumn.checked`. */ selectedColumns?: string[]; /** * Source of the list */ dataSource: NaturalDataSource | undefined; /** * Selection for bulk actions */ readonly selection: SelectionModel["items"][0]>; /** * Next executed action from bulk menu */ bulkActionSelected: string | null; /** * Centralisation of query variables */ variablesManager: NaturalQueryVariablesManager>; /** * Configuration for natural-search facets */ naturalSearchFacets: NaturalSearchFacets; /** * Result of a search (can be provided as input for initialisation) */ naturalSearchSelections: NaturalSearchSelections; /** * Data attribute provided by activated route snapshot */ routeData?: Data$1; /** * List of page sizes */ readonly pageSizeOptions: number[]; /** * Initial pagination setup */ protected defaultPagination: Required; /** * Initial sorting */ protected defaultSorting?: Sorting[]; protected readonly isAllVisibleSelected: typeof isAllVisibleSelected; protected readonly isPartiallyVisibleSelected: typeof isPartiallyVisibleSelected; protected readonly masterToggleVisible: typeof masterToggleVisible; constructor(service: TService); /** * Variables that are always forced on a list, in addition to whatever the end-user might select */ set forcedVariables(variables: QueryVariables | null | undefined); readonly resetSelectionOnChange: i0.InputSignal; /** * If change, check DocumentsComponent that overrides this function without calling super.ngOnInit(). */ ngOnInit(): void; protected handleHistoryNavigation(): void; /** * Persist search and then launch whatever is required to refresh the list */ search(naturalSearchSelections: NaturalSearchSelections, navigationExtras?: NavigationExtras, resetPagination?: boolean): void; /** * Change sorting variables for query and persist the new value in url and local storage * The default value is not persisted * @param sortingEvents List of material sorting events */ sorting(sortingEvents: (Sort & Partial>)[]): void; /** * Return current pagination, either the user defined one, or the default one */ protected getPagination(): PaginationInput; /** * Change pagination variables for query and persist in url and local storage the new value * The default value not persisted * * @param event Natural or Paginator PageEvent * @param defer Promise (usually a route promise) that defers the redirection from this call to prevent route navigation collision * @param navigationExtras Angular router navigation options. Is relevant only if persistSearch is true */ pagination(event: PaginationInput | PageEvent, defer?: Promise, navigationExtras?: NavigationExtras): void; protected persistPagination(pagination: PaginationInput | null, defer?: Promise, navigationExtras?: NavigationExtras): void; /** * Called when a bulk action is selected */ bulkAction(): void; /** * In non-panel context, header is always visible. * In panel context, header is hidden when no results. */ showHeader(): boolean; /** * Search is visible in most cases, but hidden on a panel */ showSearch(): boolean; /** * No results is shown when there is no items, but only in non-panel context only. * In panels we want discrete mode, there is no search and no "no-results" */ showNoResults(): boolean; /** * Initialize from route. * * Uses data provided by router such as: * * - `route.data.forcedVariables` * - `route.data.availableColumns` * - `route.data.selectedColumns` */ protected initFromRoute(): void; protected getDataObservable(): Observable; protected initFromPersisted(): void; protected translateSearchAndRefreshList(naturalSearchSelections: NaturalSearchSelections, ignoreEmptyFilter?: boolean): void; /** * Return current url excluding last route parameters; */ protected getStorageKey(): string; protected bulkdDeleteConfirmation(): Observable; /** * Delete multiple items at once, and then refresh the list of items automatically */ protected bulkDelete(): Observable; private applyForcedVariables; selectColumns(columns: string[]): void; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵdir: i0.ɵɵDirectiveDeclaration, never, never, { "persistSearch": { "alias": "persistSearch"; "required": false; }; "availableColumns": { "alias": "availableColumns"; "required": false; }; "selectedColumns": { "alias": "selectedColumns"; "required": false; }; "forcedVariables": { "alias": "forcedVariables"; "required": false; }; "resetSelectionOnChange": { "alias": "resetSelectionOnChange"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>; } /** * Detect if the given variables have a file to be uploaded or not, and * also convert date to be serialized with their timezone. */ declare function hasFilesAndProcessDate(variables: unknown): boolean; /** * Create an Apollo link that supports batched queries and file uploads. * * File uploads and mutations are never batched. */ declare function createHttpLink(httpLink: HttpLink, httpBatchLink: HttpBatchLink, options: HttpLink.Options): ApolloLink; /** * Service for storing the last error and redirecting to error page conveniently */ declare class ErrorService { private readonly document; private readonly router; private lastError; private lastErrorHref; /** * Redirect to error page and display given error */ redirectError(error: Error | GraphQLFormattedError): void; getLastError(): Error | GraphQLFormattedError | null; getLastErrorHref(): string | null; /** * Redirect to error page if the observable fails */ redirectIfError(observable: Observable): Observable; redirectIfDenied(observable: Observable): Observable; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type ProgressBar = { start: () => void; complete: () => void; }; /** * Intercept HTTP request from Angular to show them as activity */ declare const activityInterceptor: HttpInterceptorFn; /** * Singleton to track pending XHR and XHR errors in the whole application. * * You must: * * - start the tracking by calling `setProgressRef()` * - provide the HTTP interceptor `activityInterceptor` * * The tracking will be entirely disabled for SSR. */ declare class NetworkActivityService { private readonly isBrowser; private progress; /** * Count pending requests */ private pending; private readonly writableErrors; /** * GraphQL errors that happened recently */ readonly errors: i0.Signal; setProgressRef(progressBar: ProgressBar): void; /** * Notify an XHR started */ increase(): void; /** * Notify an XHR ended (even if unsuccessful) */ decrease(): void; /** * Add new GraphQL errors */ addErrors(errors: readonly GraphQLFormattedError[]): void; /** * Clear all GraphQL errors */ clearErrors(): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } /** * Create an Apollo link to show alert in case of error, and message if network is down */ declare function createErrorLink(networkActivityService: NetworkActivityService, errorService: ErrorService, alertService: NaturalAlertService): ErrorLink; /** * Behave like setTimeout(), but with a mandatory cancel mechanism. * * This is typically useful to replace setTimeout() in components where the callback * would crash if executed after the component destruction. That can easily happen * when the user navigates quickly between pages. * * Typical usage in a component would be: * * ```ts * cancellableTimeout(inject(DestroyRef)).subscribe(myCallback); * ``` * * or * * ```ts * cancellableTimeout(this.ngUnsubscribe).subscribe(myCallback); * ``` * * Instead of the more error-prone: * * ```ts * public foo(): void { * this.timeout = setTimeout(myCallBack); * } * * public ngOnDestroy(): void { * if (this.timeout) { * clearTimeout(this.timeout); * this.timeout = null; * } * } * ``` */ declare function cancellableTimeout(canceller: Observable | DestroyRef, milliSeconds?: number): Observable; /** * For debugging purpose only, will dump in console everything that happen to * the observable */ declare function debug(debugName: string): MonoTypeOperatorFunction; /** * Filter emitted results to only receive results that are successful (`result.data !== undefined`). * * This is a small wrapper around rxjs `filter()` for convenience only. * * This should be entirely deleted once we adopt Apollo Client 4.2 modern signatures that provide the same convenience but through typing inference only. * * See https://github.com/the-guild-org/apollo-angular/issues/2429 * * Usage: * * ```ts * apollo * .query({ * query: myQuery, * }) * .pipe(ignoreErrors()) * .subscribe(result => { * // Do something with complete result * }); * ``` */ declare function ignoreErrors(): OperatorFunction, ApolloClient.QueryResultMap['none']>; /** * Very basic formatting to get only date, without time and ignoring entirely the timezone * * So something like: "2021-09-23" */ declare function formatIsoDate(date: null): null; declare function formatIsoDate(date: Date): string; declare function formatIsoDate(date: Date | null): string | null; /** * Format a date and time in a way that will preserve the local time zone. * This allows the server side to know the day (without time) that was selected on client side. * * So something like: "2021-09-23T17:57:16+09:00" */ declare function formatIsoDateTime(date: Date): string; /** * Relations to full objects are converted to their IDs only. * * So {user: {id: 123}} becomes {user: 123} */ declare function relationsToIds(object: Literal): Literal; /** * Returns the plural form of the given name * * This is **not** necessarily valid english grammar. Its only purpose is for internal usage, not for humans. * * This **MUST** be kept in sync with `\Ecodev\Felix\Api\Plural:make()`. * * This is a bit performance-sensitive, so we should keep it fast and only cover cases that we actually need. */ declare function makePlural(name: string): string; /** * Returns the string with the first letter as capital */ declare function upperCaseFirstLetter(term: string): string; /** * Get contrasted color for text in the slider thumb * @param hexBgColor string in hexadecimals representing the background color */ declare function getForegroundColor(hexBgColor: string): 'black' | 'white'; /** * Convert RGB color to hexadecimal color * * ```ts * rgbToHex('rgb(255, 00, 255)'); // '#FF00FF' * ``` */ declare function rgbToHex(rgb: string): string; /** * Copy text to clipboard. * Accepts line breaks `\n` as textarea do. */ declare function copyToClipboard(document: Document, text: string): void; /** * Emits whenever we use the browser Back / Forward button and we navigate to the same component but with different matrix parameters */ declare function onHistoryEvent(router: Router, route: ActivatedRoute): Observable; /** * Returns an async validator function that checks that the form control value is unique */ declare function unique(fieldName: string, excludedId: string | null | undefined, modelService: UntypedModelService): AsyncValidatorFn; /** * Returns an async validator function that checks that the form control value is available * * Similar to `unique` validator, but allows to use a custom query for when the client does * not have permissions for `modelService.count()`. */ declare function available(getAvailableQuery: (value: string, excludedId: string | null) => Observable, excludedId?: string | null): AsyncValidatorFn; /** * Return all errors recursively for the given Form or control */ declare function collectErrors(control: AbstractControl): ValidationErrors | null; /** * Force validation of all form controls recursively. * * Recursively mark descending form tree as dirty and touched in order to show all invalid fields on demand. * Typically used when creating a new object and user clicked on create button but several fields were not * touched and are invalid. */ declare function validateAllFormControls(control: AbstractControl): void; /** * Emits exactly 0 or 1 time: * * - if the form is `VALID`, emits immediately * - if the form is `PENDING` emits if it changes from `PENDING` to `VALID` * - any other cases will **never** emit */ declare function ifValid(control: AbstractControl): Observable<'VALID'>; /** * Validate an email address according to RFC, and also that it is publicly deliverable (not "root@localhost" or "root@127.0.0.1") * * This is meant to replace **all** usages of Angular too permissive `Validators.email` */ declare function deliverableEmail(control: AbstractControl): ValidationErrors | null; declare const urlPattern: string; /** * Naive URL validator for "normal" web links, that is a bit too permissive * * - It enforces: * - http/https protocol * - one domain * - one tld * - It allows: * - any number of subdomains * - any parameters * - any fragments * - any characters for any parts (does not conform to rfc1738) */ declare const url: ValidatorFn; /** * Validates that the value is an integer (non-float) */ declare function integer(control: AbstractControl): ValidationErrors | null; /** * Validate that the value is a decimal number with up to `scale` digits * * The error contains the expected scale, so that the error message can explain * it to the end-user. */ declare function decimal(scale: number): ValidatorFn; /** * Validate that the value is an amount of money, meaning a number with at most 2 decimals, * and that is within the given `min` and `max` range (inclusive). * * A range is always required, because unbounded financial inputs allow gross typos (eg. an extra * digit) to slip through and cause data corruption, so callers must always think about a sensible * limit. For most cases, prefer the ready-made `signedMoney` or `unsignedMoney` helpers instead * of calling this directly. */ declare function money(min: number, max: number): ValidatorFn; /** * Validate a signed amount of money (can be negative), suitable for a value stored in a database * column of type `SIGNED INT`, such as a balance. */ declare const signedMoney: ValidatorFn; /** * Validate an unsigned amount of money (cannot be negative), suitable for a value stored in a * database column of type `UNSIGNED INT`, such as a price. */ declare const unsignedMoney: ValidatorFn; /** * Validate that the number is strictly greater than given one. * * `Validators.min()` is "greater than or equal", but this one is strictly * "greater than". * * **SHOULD NOT USE IT**, instead consider using Angular's native `Validators.min()`. * Because you should also apply `[attr.min]="123"` in the template to have the browser * help the user. And that attribute spec defines that it is "greater or equal", which * contradicts this validator. So we cannot use this validator and have the best UX. */ declare function greaterThan(min: number): ValidatorFn; /** * Validate a 32 bits MiFare hexadecimal CSN */ declare function nfcCardHex(control: AbstractControl): ValidationErrors | null; /** * Validate a time similar to "14h35", "14:35" or "14h". */ declare function time(control: AbstractControl): ValidationErrors | null; /** * Array of valid top-level-domains * IanaVersion 2020033100 * * This should ideally be kept in sync with \Laminas\Validator\Hostname * * See ftp://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain * See http://www.iana.org/domains/root/db/ Official list of supported TLDs */ declare const validTlds: readonly string[]; type IEnum = { value: string; name: string; }; declare class NaturalEnumService { private readonly apollo; /** * Return a list of observable enumerables considering the given name */ get(name: string): Observable; /** * Returns the enum user-friendly name, instead of its value. */ getValueName(value: string, enumName: string): Observable; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type AllThemes = [string, ...string[]]; /** * If you are using themes, or color scheme, then you must provide themes at the application level. * * If there is a only one theme, you still need to provide a name for it (eg: "my-app"), even if * it is not used in the SCSS. */ declare function provideThemes(config: AllThemes): EnvironmentProviders; declare enum ColorScheme { Light = "light", Dark = "dark", Auto = "auto" } /** * The source of truth is the DOM. And thus the index.html (or equivalent) must use vanilla JavaScript * to restore `data-color-scheme` and `data-theme` attributes on the `` element (eg: from * local storage, or from DB). */ declare class NaturalThemeService { private readonly allThemes; private readonly storage; private readonly platformId; protected readonly document: Document; private readonly htmlElement; private readonly isDarkSystem; private readonly isDark; private readonly _theme; /** * Currently selected theme. Use `setTheme()` to select a different theme. */ readonly theme: i0.Signal; private readonly _colorScheme; /** * Currently selected color scheme. Use `setColorScheme()` to select a different scheme. */ readonly colorScheme: i0.Signal; constructor(); /** * Set theme in memory and dom */ setTheme(theme: string): void; /** * Set dark/light/auto */ setColorScheme(scheme: ColorScheme, persistInStorage?: boolean): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } declare class NaturalSwissParsingDateAdapter extends NativeDateAdapter { /** * Parse commonly accepted swiss format, such as: * * - 24.12.2018 * - 1.4.18 * - 2018-12-24 */ parse(value: unknown): Date | null; private createDateIfValid; getFirstDayOfWeek(): number; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type NaturalConfirmData = { title: string; message: string; confirmText: string; cancelText: string; }; declare class NaturalConfirmComponent { readonly data: NaturalConfirmData; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare class NaturalColumnsPickerComponent implements OnChanges { private readonly destroyRef; private readonly breakpointObserver; private _selections?; private _availableColumns; readonly buttons: i0.InputSignal[] | null>; /** * Set all the columns that are available. */ set availableColumns(columns: readonly Readonly[] | undefined); /** * Set the columns that we would like to select but might be unavailable. * * If a column is unavailable it will be ignored silently. To know what columns were actually applied * you should use `selectionChange`. * * It is often set once on component initialization, but it can also be set again later in the lifespan of the component. */ set selections(columns: string[] | undefined); /** * Emit a list of valid and selected column keys whenever the selection changes */ readonly selectionChange: i0.OutputEmitterRef; /** * Displayed options in the dropdown menu */ displayedColumns: Required[]; readonly isMobile: rxjs.Observable; private initColumns; updateColumns(): void; ngOnChanges(changes: SimpleChanges): void; defaultTrue(value: boolean | undefined): boolean; color(button: Button): NaturalPalette | null; useCheckbox(button: Button): boolean; needMargin(button?: Button | null): string; someVisibleButtons(): boolean; protected menuItemClicked($event: MouseEvent, column: Required): void; protected checkboxClicked($event: MouseEvent, column: Required): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * Usage : * * ```html * * Tab 1 // First tab doesn't need id. This keeps url clean on default one * Tab 2 * ... * * ``` */ declare class NaturalLinkableTabDirective implements AfterViewInit { private readonly destroyRef; private readonly component; private readonly route; private readonly router; /** * If false, disables the persistent navigation */ readonly naturalLinkableTab: i0.InputSignal; private isLoadingRouteConfig; constructor(); ngAfterViewInit(): void; private getTabIndex; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } /** * Returns the string with the first letter as capital */ declare class NaturalCapitalizePipe implements PipeTransform { transform(value: string | null): string | null; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵpipe: i0.ɵɵPipeDeclaration; } declare class NaturalEllipsisPipe implements PipeTransform { transform(value: string, limit: number): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵpipe: i0.ɵɵPipeDeclaration; } /** * A pipe to output an enum user-friendly name, instead of its value. * * Usage would be: {{ element.priority | enum: 'Priority' | async }} */ declare class NaturalEnumPipe implements PipeTransform { private readonly enumService; transform(value: any, enumName: string): Observable; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵpipe: i0.ɵɵPipeDeclaration; } /** * Return a single error message for the first found error, if any. * * Typical usage is without `@if`: * * ```html * * * Nom * {{ form.get('name')?.errors | errorMessage }} * * ``` * * If you need custom error messages, you can override, or defined new ones like that: * * ```html * * * Nom * @if (form.get('name')?.hasError('required')) { * Ce champ est requis parce qu'il est vraiment très important * } @else { * {{ form.get('name')?.errors | errorMessage }} * } * * ``` * * Supported validators are: * * - Angular * - `Validators.max` * - `Validators.maxlength` * - `Validators.min` * - `Validators.minlength` * - `Validators.required` * - `matDatepickerMin` * - `matDatepickerMax` * - Natural * - `available` * - `decimal` * - `deliverableEmail` * - `greaterThan` * - `integer` * - `money` (also covers `signedMoney` and `unsignedMoney`) * - `nfcCardHex` * - `time` * - `unique` * - `url` * - Others, that live in individual projects, but we exceptionally support here * - `iban` * - `validateCity` * * @param unit is used to build the message for the following validators: `min`, `max`, `greaterThan` */ declare class NaturalErrorMessagePipe implements PipeTransform { transform(errors: ValidationErrors | null | undefined, unit?: string): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵpipe: i0.ɵɵPipeDeclaration; } /** * Returns a string to approximately describe the date. * * Eg: * * - "il y a quelques minutes" * - "dans 3 jours" * - "dans 3 ans" */ declare class NaturalTimeAgoPipe implements PipeTransform { fakedNow: number | null; private getNow; transform(date: Date | string | null | undefined): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵpipe: i0.ɵɵPipeDeclaration; } declare const SESSION_STORAGE: InjectionToken; declare const LOCAL_STORAGE: InjectionToken; /** * Normal `Storage` type, but without array access */ type NaturalStorage = Pick; /** * Memory storage to keep store volatile things in memory * * Should be used to shim sessionStorage when running on server or in our tests */ declare class NaturalMemoryStorage implements NaturalStorage { private readonly data; get length(): number; clear(): void; getItem(key: string): string | null; key(index: number): string | null; removeItem(key: string): void; setItem(key: string, value: string): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } declare function sessionStorageFactory(): NaturalStorage; /** * Standard `sessionStorage` provider that is compatible with SSR. * * In SSR environment, or when `sessionStorage` is not available, will return a `NaturalMemoryStorage` */ declare const sessionStorageProvider: Provider; /** * Provide in-memory session storage to be used only in tests or SSR */ declare const memorySessionStorageProvider: Provider; declare function localStorageFactory(): NaturalStorage; /** * Standard `localStorage` provider that is compatible with SSR. * * In SSR environment, or when `localStorage` is not available, will return a `NaturalMemoryStorage` */ declare const localStorageProvider: Provider; /** * Provide in-memory local storage to be used only in tests or SSR */ declare const memoryLocalStorageProvider: Provider; declare class NaturalSrcDensityDirective { private readonly elementRef; /** * Automatically apply image selection based on screen density. * * The given URL **MUST** be the normal density URL. And it **MUST** include * the size as last path segment. That size will automatically be changed * for other screen densities. That means that the server **MUST** be able to * serve an image of the given size. * * Usage: * * ```html * * ``` * * Will generate something like: * * ```html * * ``` * * See https://web.dev/codelab-density-descriptors/ */ readonly naturalSrcDensity: i0.InputSignal; constructor(); static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } declare class NaturalBackgroundDensityDirective { private readonly elementRef; /** * Automatically apply background image selection based on screen density. * * The given URL **MUST** be the normal density URL. And it **MUST** include * the size as last path segment. That size will automatically be changed * for other screen densities. That means that the server **MUST** be able to * serve an image of the given size. * * If the given URL starts with `url(`, or is not ending with a number, then * it will be set as-is, without any processing. This allows using url data, * such as `url(data:image/png;base64,aabbcc)`. * * Usage: * * ```html *

*
*
* ``` * * Will generate something like: * * ```html *
*
*
* ``` * * See https://developer.mozilla.org/en-US/docs/Web/CSS/image/image-set */ readonly naturalBackgroundDensity: i0.InputSignal; constructor(); static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } type NaturalSeo = NaturalSeoBasic | NaturalSeoCallback | NaturalSeoResolve; /** * Typically used for "static" pages where there is not a single resolved object. So * all pages such as "About", or list of objects (list of risks, etc.). * * This should be the most common used variant. */ type NaturalSeoBasic = Robots & { /** * The page title, that will be concatenated with application name */ title: string; /** * If given will be used as page description, otherwise fallback on default value */ description?: string; /** * List of parameters included in the canonical tag's url */ canonicalQueryParamsWhitelist?: string[]; }; /** * Typically used for a "dynamic" page where a single object is resolved. So a detail page, such * as the detail of a risk and so on. */ type NaturalSeoResolve = Robots & { /** * The key `model` will be used in the resolved data to find the resolved object. The fullName * or name of the object will be used for page title, and the object description, if any, * will be used for page description. */ resolve: true; }; /** * Rarely used for a page that has very specific needs and need to build title and description in a custom way. * The callback back will be given the resolved data, and it is up to the callback to find whatever it needs. */ type NaturalSeoCallback = (routeData: Data$1) => NaturalSeoBasic | Observable; /** * Typically used to type the routing data received in the component, eg: * * ```ts * class MyComponent extends NaturalAbstractDetail {} * ``` */ type NaturalSeoResolveData = { seo: NaturalSeoBasic; }; type Robots = { /** * If given will be used as robots meta tag, otherwise fallback on default value */ robots?: string; }; type NaturalSeoConfigPlain = { /** * The name of the application that will always appear in the page title */ readonly applicationName: string; /** * Default value for description meta that is used for pages without value */ readonly defaultDescription?: string; /** * Default value for robots meta that is used for pages without value */ readonly defaultRobots?: string; /** * If given, the callback will be called for each route and must return a string that will * be inserted between the page title and the application name. * * It should be used to complete the title with info that are often, but not necessarily always, * available throughout the entire application. Typically used for the site/state in OKpilot. */ readonly extraPart?: (routeData: Data$1) => string; /** * Used to generate alternative tags * */ readonly languages?: readonly string[]; }; type NaturalSeoConfig = NaturalSeoConfigPlain | Observable; declare const NATURAL_SEO_CONFIG: InjectionToken; /** * This service is responsible to keep up to date the page title and page description according * to what is configured in routing or default values. * * It **must** be injected in the root module of the application to have effects in all modules. And it * must be provided a configuration. * * The full title has the following structure: * * dialog title - page title - extra part - app name * * `dialog title` only exists if a `NaturalDialogTriggerComponent` is currently open, and that some SEO is * configured for it in the routing. */ declare class NaturalSeoService { private readonly router; private readonly titleService; private readonly metaTagService; private readonly document; private locale; private routeData?; private config; constructor(); /** * Update the SEO with given info. The extra part and app name will be appended automatically. * * In most cases, this should not be used. And instead, the SEO should be configured in the routing, * possibly with the callback variant for some dynamism. * * But in rare cases, only the Component is able to build a proper page title, after it gathered everything it * needed. For those cases, the Component can inject this service and update the SEO directly. */ update(seo: NaturalSeoBasic): void; private updateAlternates; private getUrlParts; /** * Add language between domain and uri https://example.com/fr/folder/page */ private getUrl; private addLanguageSegment; private join; private updateTag; private updateLinkTag; /** * Returns selector to use in querySelector to get the given link */ private parseSelector; /** * Returns the data from the most deep/specific activated route */ private getRouteData; /** * Returns the data from the `NaturalDialogTriggerComponent` if one is open */ private getDialogRouteData; private toBasic; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } /** * Configure and starts `NaturalSeoService` */ declare function provideSeo(config: NaturalSeoConfig): (EnvironmentProviders | Provider)[]; declare class NaturalDetailHeaderComponent { /** * Base URL used to build links, defaults to '/' */ readonly currentBaseUrl: i0.InputSignal; /** * Must be set to get proper links when used in panels */ readonly isPanel: i0.InputSignal; /** * If given will show icon before title */ icon: string; /** * Title shown if model has no name, or empty name. * * Typically should be the human name for the object type, eg: 'Product' */ label: string; /** * Label of the root of the breadcrumb, defaults to the value of `label`. * * Typically should be the plural form of the object type, eg: 'Products' */ rootLabel: string; /** * Title shown if model has no id. * * Typically should be similar to 'New product'. */ readonly newLabel: i0.InputSignal; readonly model: i0.InputSignal; readonly breadcrumbs: i0.InputSignal; readonly listRoute: i0.InputSignal; readonly listFragment: i0.InputSignal; readonly link: i0.InputSignal<((id: string) => any[]) | undefined>; getRootLink(): string[]; getLink(id: string): any[]; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type PossibleNullableOperatorKeys = 'any' | 'none'; type PossibleComparableOperatorKeys = keyof Pick | PossibleNullableOperatorKeys; type PossibleComparableOperator = { key: PossibleComparableOperatorKeys; label: string; }; declare const possibleComparableOperators: readonly PossibleComparableOperator[]; declare const possibleNullComparableOperators: readonly PossibleComparableOperator[]; type PossibleDiscreteOperatorKeys = 'is' | 'isnot' | PossibleNullableOperatorKeys; type PossibleDiscreteOperator = { key: PossibleDiscreteOperatorKeys; label: string; }; type TypeSelectItem = Scalar | { id: Scalar; name: Scalar; } | { value: Scalar; name: Scalar; }; type TypeSelectConfiguration = { items: TypeSelectItem[] | Observable; multiple?: boolean; /** * If true (default) a selectbox allows to choose an operator. Otherwise, the selectbox is hidden and the operator will always be `is`. */ operators?: boolean; }; declare class TypeSelectComponent implements DropdownComponent { private readonly destroyRef; readonly renderedValue: BehaviorSubject; requireValueCtrl: boolean; readonly operators: readonly PossibleDiscreteOperator[]; readonly operatorCtrl: FormControl; readonly valueCtrl: FormControl; readonly form: FormGroup<{ operator: FormControl; value: FormControl; }>; items: TypeSelectItem[]; readonly configuration: Required; private readonly defaults; constructor(); getId(item: TypeSelectItem): Scalar; getDisplay(item: TypeSelectItem): Scalar; getCondition(): FilterGroupConditionField; isValid(): boolean; isDirty(): boolean; private initValidators; private isMultiple; private getItemById; private reloadCondition; /** * Reload the value from API (`operatorCtrl` should not be touched) */ private reloadValue; private getRenderedValue; private conditionToOperatorKey; private operatorKeyToCondition; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type NaturalDropdownContainerData = { showValidateButton: boolean; }; declare class NaturalDropdownContainerComponent extends BasePortalOutlet implements OnDestroy { private readonly elementRef; private readonly focusTrapFactory; readonly data: NaturalDropdownContainerData; readonly portalOutlet: i0.Signal; readonly closed: Subject; /** Current state of the panel animation. */ protected panelAnimationState: 'void' | 'enter'; private focusTrap; private elementFocusedBeforeDialogWasOpened; ngOnDestroy(): void; close(): void; attachTemplatePortal(portal: TemplatePortal): EmbeddedViewRef; attachComponentPortal(portal: ComponentPortal): ComponentRef; /** Callback that is invoked when the panel animation completes. */ protected onAnimationDone(state: string): void; private trapFocus; /** Restores focus to the element that was focused before the dialog opened. */ private restoreFocus; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare class NaturalDropdownRef { private readonly dropdownContainer; readonly componentInstance: DropdownComponent; readonly closed: Subject; constructor(dropdownContainer: NaturalDropdownContainerComponent, component: ComponentType, customProviders: StaticProvider[], parentInjector: Injector, containerRef: ComponentRef); close(result?: DropdownResult): void; } type NaturalDropdownData = { condition: FilterGroupConditionField | null; configuration: C; title?: string; }; declare const NATURAL_DROPDOWN_DATA: InjectionToken>; type NaturalHierarchicConfiguration = { /** * An AbstractModelService to be used to fetch items */ service: Type; /** * A list of FilterConditionField name to filter items * * Those will be used directly to build filter to fetch items, so they must be * valid API FilterConditionField names for the given service. * * Eg: given the QuestionService, possible names would be: * * - "chapter" to filter by the question's chapter * - "parent" to filter by the question's parent question */ parentsRelationNames?: string[]; /** * A list of FilterConditionField name to declare hierarchy * * Those must be the `parentsRelationNames` name, that correspond to this service, * of all children services. * * Eg: given the QuestionService, possible names would be: * * - "questions" coming from ChapterService * - "questions" coming from QuestionService */ childrenRelationNames?: string[]; /** * Additional filters applied in the query sent by getList function */ filter?: QueryVariables['filter']; /** * Key of the returned literal container models by config / service */ selectableAtKey?: string; /** * Displayed icon for items retrieved for that config */ icon?: string; /** * Callback function that returns boolean. If true the item is selectable, if false, it's not. * If missing, item is selectable. * * In fact, this means isDisabled. Also applies to unselect. */ isSelectableCallback?: (item: any) => boolean; /** * Functions that receives a model and returns a string for display value * * If missing, fallback on global `NaturalHierarchicSelectorComponent.displayWith` */ displayWith?: (item: any) => string; }; type HierarchicFilterConfiguration$1 = { service: NaturalHierarchicConfiguration['service']; filter: T; }; type HierarchicFiltersConfiguration$1 = HierarchicFilterConfiguration$1[]; type HierarchicModel = { __typename: string; } & NameOrFullName; /** * Wrapper for the original model from the DB with specific metadata for tree */ declare class ModelNode { model: HierarchicModel; readonly config: NaturalHierarchicConfiguration; readonly childrenChange: BehaviorSubject; isLoading: boolean; isExpandable: boolean; isSelectable: boolean; constructor(model: HierarchicModel, config: NaturalHierarchicConfiguration); get children(): Observable; get hasChildren(): boolean; } type OrganizedModelSelection = Record; declare class NaturalHierarchicSelectorService { private readonly injector; /** * We use cache because dataSource has nested data and would require recursive search */ private readonly nodeCache; isTooBig(): boolean; /** * Retrieve elements from the server * Get root elements if node is null, or child elements if node is given */ getList(node: (ModelNode | null) | undefined, filters: (HierarchicFiltersConfiguration$1 | null) | undefined, variables: (QueryVariables | null) | undefined, configurations: NaturalHierarchicConfiguration[]): Observable; countChildren(node: ModelNode, filters: (HierarchicFiltersConfiguration$1 | null) | undefined, configurations: NaturalHierarchicConfiguration[]): void; private getContextualizedConfigs; /** * Return models matching given FlatNodes * Returns a Literal of models grouped by their configuration attribute "selectableAtKey" */ toOrganizedSelection(nodes: ModelNode[], configurations: NaturalHierarchicConfiguration[]): OrganizedModelSelection; /** * Transforms an OrganizedModelSelection into a list of ModelNodes */ fromOrganizedSelection(organizedModelSelection: OrganizedModelSelection, configurations: NaturalHierarchicConfiguration[]): ModelNode[]; /** * Checks that each configuration.selectableAtKey attribute is unique */ validateConfiguration(configurations: NaturalHierarchicConfiguration[]): void; /** * Return configurations setup in the list after the given one */ private getNextConfigs; /** * Builds queryVariables filter for children query */ private getServiceFilter; /** * Return a context filter applicable to the service for given config * * @param config Applicable config * @param contextFilters List of context filters */ private getFilterByService; /** * Search in configurations.selectableAtKey attribute to find given key and return the configuration */ private getConfigurationBySelectableKey; private getOrCreateNode; /** * Returns an identifier key for map cache * As many object types can be used, this function considers typename and ID to return something like document-123 */ private getCacheKey; getAllFetchedNodes(): ModelNode[]; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type HierarchicFilterConfiguration = { service: NaturalHierarchicConfiguration['service']; filter: T; }; type HierarchicFiltersConfiguration = HierarchicFilterConfiguration[]; type TypeHierarchicSelectorConfiguration = { key: string; service: UntypedModelService; config: NaturalHierarchicConfiguration[]; filters?: HierarchicFiltersConfiguration; }; declare class TypeHierarchicSelectorComponent extends AbstractAssociationSelectComponent { getCondition(): FilterGroupConditionField; protected reloadValue(condition: FilterGroupConditionField): Observable; protected renderValueWithoutOperator(): string; selectionChange(selection: OrganizedModelSelection): void; /** * We need to keep `null` in our valueCtrl so the required validator works properly, so * filter here */ private noEmptySelection; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type PossibleWhereKeys = 'DebitOrCredit' | 'Debit' | 'Credit'; type PossibleWhere = { key: PossibleWhereKeys; label: string; render: string; }; /** * This is a specialized facet for Account model with extra fields specific to the specialized operator on the server side. */ declare class TypeAccountSelectorComponent extends TypeHierarchicSelectorComponent { readonly whereCtrl: FormControl; readonly recursiveCtrl: FormControl; protected readonly possibleWhere: readonly PossibleWhere[]; constructor(); protected operatorKeyToCondition(key: PossibleDiscreteOperatorKeys, values: string[]): FilterGroupConditionField; protected reloadCondition(condition: FilterGroupConditionField | null): void; protected getRenderedValue(): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare abstract class AbstractAssociationSelectComponent implements DropdownComponent { configuration: C; readonly renderedValue: BehaviorSubject; requireValueCtrl: boolean; readonly operators: readonly PossibleDiscreteOperator[]; readonly operatorCtrl: FormControl; readonly valueCtrl: FormControl; readonly form: FormGroup<{ operator: FormControl; value: FormControl; where?: FormControl; recursive?: FormControl; }>; constructor(); protected init(data: NaturalDropdownData): void; /** * Reload the value from API (`operatorCtrl` should not be touched) */ protected abstract reloadValue(condition: FilterGroupConditionField): Observable; protected abstract renderValueWithoutOperator(): string; abstract getCondition(): FilterGroupConditionField; isValid(): boolean; isDirty(): boolean; private initValidators; protected reloadCondition(condition: FilterGroupConditionField | null): void; protected getRenderedValue(): string; protected conditionToOperatorKey(condition: FilterGroupConditionField): PossibleDiscreteOperatorKeys; protected operatorKeyToCondition(key: PossibleDiscreteOperatorKeys, values: string[], extra?: Record): FilterGroupConditionField; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵdir: i0.ɵɵDirectiveDeclaration, never, never, {}, {}, never, never, true, never>; } type TypeSelectNaturalConfiguration = { service: TService; placeholder: string; filter?: ExtractVall['filter']; pageSize?: number; }; declare class TypeNaturalSelectComponent extends AbstractAssociationSelectComponent> { getCondition(): FilterGroupConditionField; protected reloadValue(condition: FilterGroupConditionField): Observable>; protected renderValueWithoutOperator(): string; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵcmp: i0.ɵɵComponentDeclaration, "ng-component", never, {}, {}, never, never, true, never>; } /** * Show an error message if the control has a value and an error, even if control is not dirty and not touched. */ declare class InvalidWithValueStateMatcher$1 implements ErrorStateMatcher { isErrorState(control: FormControl | null): boolean; } declare class TypeTextComponent implements DropdownComponent { protected dropdownRef: NaturalDropdownRef; readonly renderedValue: BehaviorSubject; readonly formCtrl: FormControl; readonly matcher: InvalidWithValueStateMatcher$1; constructor(); getCondition(): FilterGroupConditionField; isValid(): boolean; isDirty(): boolean; close(): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type TypeNumberConfiguration = { min?: number | null; max?: number | null; step?: number | null; /** * If true, two extra choices, "avec" and "sans", will be shown to filter by the (in-)existence of a value */ nullable?: boolean; }; declare class TypeNumberComponent implements DropdownComponent { protected dropdownRef: NaturalDropdownRef; readonly renderedValue: BehaviorSubject; readonly configuration: Required; readonly operatorCtrl: FormControl; readonly valueCtrl: FormControl; readonly matcher: InvalidWithValueStateMatcher$1; readonly form: FormGroup<{ operator: FormControl; value: FormControl; }>; requireValueCtrl: boolean; readonly operators: readonly PossibleComparableOperator[]; private readonly defaults; constructor(); getCondition(): FilterGroupConditionField; isValid(): boolean; isDirty(): boolean; close(): void; private initValidators; private reloadCondition; private getRenderedValue; private conditionToOperatorKey; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type TypeDateConfiguration = { min?: D | null; max?: D | null; /** * If true, two extra choices, "avec" and "sans", will be shown to filter by the (in-)existence of a value */ nullable?: boolean; }; declare class TypeDateComponent implements DropdownComponent { private dateAdapter; private dateFormats; readonly renderedValue: BehaviorSubject; readonly configuration: Required>; readonly operatorCtrl: FormControl; readonly valueCtrl: FormControl; readonly todayCtrl: FormControl; requireValueCtrl: boolean; readonly operators: readonly PossibleComparableOperator[]; readonly form: FormGroup<{ operator: FormControl; value: FormControl; today: FormControl; }>; private readonly defaults; constructor(); getCondition(): FilterGroupConditionField; isValid(): boolean; isDirty(): boolean; private reloadCondition; private conditionToOperatorKey; private setTodayOrDate; private initValidators; private getDayAfter; private getRenderedValue; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵcmp: i0.ɵɵComponentDeclaration, "ng-component", never, {}, {}, never, never, true, never>; } type TypeDateRangeConfiguration = { min?: D | null; max?: D | null; }; declare class InvalidWithValueStateMatcher implements ErrorStateMatcher { isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean; } /** * Date range with mandatory bounding dates. * * If you need optional bounding date, then use `TypeDateComponent` instead. */ declare class TypeDateRangeComponent implements DropdownComponent { private dateAdapter; private dateFormats; readonly renderedValue: BehaviorSubject; readonly configuration: Required>; readonly matcher: InvalidWithValueStateMatcher; readonly fromCtrl: FormControl; readonly toCtrl: FormControl; readonly form: FormGroup<{ from: FormControl; to: FormControl; }>; private readonly defaults; constructor(); getCondition(): FilterGroupConditionField; isValid(): boolean; isDirty(): boolean; private reloadCondition; private initValidators; render(value: D | null): string; private getRenderedValue; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵcmp: i0.ɵɵComponentDeclaration, "ng-component", never, {}, {}, never, never, true, never>; } type TypeOption = { display: string; condition: Literal; }; type TypeOptionsConfiguration = { options: TypeOption[]; }; declare class TypeOptionsComponent implements DropdownComponent { protected readonly dropdownRef: NaturalDropdownRef; readonly renderedValue: BehaviorSubject; readonly formControl: FormControl; readonly configuration: Required; private readonly defaults; constructor(); getCondition(): FilterGroupConditionField; isValid(): boolean; isDirty(): boolean; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type TypeBooleanConfiguration = { displayWhenActive: string; displayWhenInactive: string; }; declare class TypeBooleanComponent extends TypeOptionsComponent implements DropdownComponent { static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type FileModel = { __typename?: 'File' | 'AccountingDocument' | 'Image'; id?: string; file?: File; mime?: string; src?: string; }; declare class NaturalFileService { private readonly document; /** * Allow to subscribe to selected files in the entire application. So a * child component is able to receive a file that was dropped on a parent * component. * * Typically useful to drop a file on the entire screen, instead of a precise * component. */ readonly filesChanged: Subject; getDownloadLink(model: FileModel | null): null | string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type InvalidFile = { file: File; error: string; }; type FileSelection = { /** * The list of files that have been selected. */ valid: File[]; /** * The list of files that have been selected but are invalid according to validators. */ invalid: InvalidFile[]; }; /** * A master base set of logic intended to support file select/drag/drop operations * * In most cases you probably want click-to-select and drag-to-select, so you should use: * *
* * @dynamic */ declare abstract class NaturalAbstractFile implements OnInit, OnDestroy, OnChanges { private readonly element; protected readonly naturalFileService: NaturalFileService; private readonly document; private fileElement?; /** * Whether we should accept a single file or multiple files */ readonly multiple: i0.InputSignal; /** * Comma-separated list of unique file type specifiers. Like the native element, * it can be a mix of mime-type and file extensions. * * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept */ readonly accept: i0.InputSignal; /** * Maximum file size in bytes. 0 means no validation at all. */ readonly maxSize: i0.InputSignal; /** * Disable the file selection entirely */ readonly fileSelectionDisabled: i0.InputSignal; /** * Whether the user can click on the element to select something * * This has only effect during initialization. Subsequent changes will have * no effect. */ readonly selectable: i0.InputSignal; /** * If true, the file selection will be broadcast through `NaturalFileService.filesChanged`. * * It is useful to set this to false if there are two uploads on a page with different purposes, * and the second upload should not be confused with the first one. */ broadcast: boolean; private readonly fileChange$; /** * The single valid file that has been selected. * * It is for convenience of use, and will only emit if there is at least one * valid file. See `filesChange` for a more complete output. */ readonly fileChange: i0.OutputRef; private readonly filesChange$; /** * The list of files that have been selected. */ readonly filesChange: i0.OutputRef; ngOnDestroy(): void; ngOnInit(): void; ngOnChanges(changes: SimpleChanges): void; private getFileElement; private enableSelecting; protected handleFiles(files: File[]): void; /** * Called when input has files */ private changeFn; private clickHandler; private beforeSelect; onChange(event: Event): void; private validate; protected hasObservers(): boolean; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } /** * This directive has all options to select files, and adds support for drag'n'drop. * * It will add the CSS class `natural-file-over` on the component when a file is * dragged over. It is up to the component to have some specific styling by using * this class. * * In most cases you probably also want click-to-select, so you should use: * * ```html *
* ``` */ declare class NaturalFileDropDirective extends NaturalAbstractFile implements OnInit { private readonly destroyRef; fileOverClass: boolean; /** * Emits whenever files are being dragged over */ readonly fileOver: i0.OutputEmitterRef; private readonly rawFileOver; ngOnInit(): void; protected onDrop(event: DragEvent): void; protected onDragOver(event: DragEvent): void; private closeDrags; protected onDragLeave(event: DragEvent): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } /** * This directive has all options to select files, except drag'n'drop. */ declare class NaturalFileSelectDirective extends NaturalAbstractFile { /** * Whether the user can click on the element to select something * * Override parent to enable it by default */ readonly selectable: i0.InputSignal; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } declare class NaturalFileComponent implements OnInit, OnChanges { private readonly naturalFileService; private readonly alertService; private readonly document; readonly height: i0.InputSignal; readonly iconHeight: i0.Signal; readonly fontSize: i0.Signal; readonly action: i0.InputSignal<"download" | "upload" | null>; readonly backgroundSize: i0.InputSignal; /** * Comma-separated list of unique file type specifiers. Like the native element, * it can be a mix of mime-type and file extensions. * * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept */ readonly accept: i0.InputSignal; /** * If given, it will be called when a new file is selected. The callback should typically upload the file * to the server and link the newly uploaded file to the existing related object. * * The callback **must** be able to run even if the calling component has been destroyed. That means in most * cases you **must** `bind()` the callback explicitly, like so: * * ```html * * ``` * * Also, you probably **should** set a `[formCtrl]` so that the form is updated automatically, instead of doing * it manually within the callback. */ readonly uploader: i0.InputSignal<((file: File) => Observable) | undefined>; model: FileModel | null; /** * If provided, its value will get updated when the model changes. * But its value is never read, so if you want to set a value use `[model]` instead. */ readonly formCtrl: i0.InputSignal | null | undefined>; /** * This **must not** be used to mutate the server, because it is very likely it will never be called if the * human navigates away from the page before the upload is finished. Instead, you should use `[uploader]`. */ readonly modelChange: i0.OutputEmitterRef; imagePreview: string; filePreview: string | null; ngOnChanges(changes: SimpleChanges): void; ngOnInit(): void; upload(file: File): void; getDownloadLink(): null | string; private updateImage; private getBase64; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * Common image mime type that are supported by Felix out of the box. * * Should be kept in sync with `\Ecodev\Felix\Model\Traits\Image::getAcceptedMimeTypes` */ declare const commonImageMimeTypes = "image/avif,image/bmp,image/x-ms-bmp,image/gif,image/heic,image/heif,image/jpeg,image/pjpeg,image/png,image/svg+xml,image/svg,image/webp"; declare class NaturalFixedButtonComponent { readonly icon: i0.InputSignal; readonly label: i0.InputSignal; readonly link: i0.InputSignal; readonly color: i0.InputSignal; readonly disabled: i0.InputSignal; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type Model = { id?: string; permissions?: { delete: boolean; }; }; declare class NaturalFixedButtonDetailComponent { private canChange; isCreation: boolean; get model(): Model; set model(value: Model); private _model; form: FormGroup; readonly create: i0.OutputEmitterRef; readonly delete: i0.OutputEmitterRef; constructor(); clickCreate(): void; clickDelete(): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare class NaturalHierarchicSelectorComponent implements OnInit, OnChanges { protected readonly hierarchicSelectorService: NaturalHierarchicSelectorService; /** * Function that receives a model and returns a string for display value */ readonly displayWith: i0.InputSignal<((item: any) => string) | undefined>; /** * Config for items and relations arrangement */ readonly config: i0.InputSignal; /** * If multiple or single item selection */ readonly multiple: i0.InputSignal; /** * Selected items * Organized by key, containing each an array of selected items of same type */ readonly selected: i0.InputSignal; /** * Filters that apply to each query */ readonly filters: i0.InputSignal; /** * Search facets */ readonly searchFacets: i0.InputSignal; /** * Selections to apply on natural-search on component initialisation */ readonly searchSelections: i0.InputSignal; /** * Select all fetched items of the current search result * * Use very carefully as recursivity is ignored. The selection includes children (if any) even if the child list has been closed * * Should be used __only__ for non-recursive use cases. Avoid with recursive because it's not intuitive for end user */ readonly allowSelectAll: i0.InputSignal; /** * Emits when natural-search selections change */ readonly searchSelectionChange: i0.OutputEmitterRef; /** * Emits selection change * Returns a Literal where selected models are organized by key */ readonly selectionChange: i0.OutputEmitterRef; /** * List selected items (right listing) */ protected selection: SelectionModel; /** * Data source for result listing (left listing) */ protected readonly dataSource: MatTreeNestedDataSource; loading: boolean; /** * Angular OnChange implementation */ ngOnChanges(changes: SimpleChanges): void; ngOnInit(): void; /** * Toggle selection of a node, considering if multiple selection is activated or not */ toggleSelection(node: ModelNode): void; protected selectAll(): void; /** * When unselecting an element from the mat-chips, it can be deep in the hierarchy, and the tree element may not * exist... * ... but we still need to remove the element from the mat-chips list. */ unselect(node: ModelNode): void; protected getDisplayFn(config: NaturalHierarchicConfiguration): (item: any) => string; private loadRoot; search(selections: NaturalSearchSelections): void; /** * Get list of children, considering given FlatNode id as a parent. * Mark loading status individually on nodes. */ loadChildren(node: ModelNode): void; protected childrenAccessor: (node: ModelNode) => Observable; /** * Sync inner selection (tree and mat-chips) according to selected input attribute */ private updateInnerSelection; /** * Transform the given elements into the organized selection that is emitted to output */ private updateSelection; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type HierarchicDialogResult = { hierarchicSelection?: OrganizedModelSelection; searchSelections?: NaturalSearchSelections | null; }; type HierarchicDialogConfig = { /** * Configuration to setup rules of hierarchy */ hierarchicConfig: NaturalHierarchicConfiguration[]; /** * Selected items when HierarchicComponent initializes */ hierarchicSelection?: OrganizedModelSelection; /** * Filters to apply on queries (when opening new level of hierarchy) */ hierarchicFilters?: HierarchicFiltersConfiguration$1 | null; /** * Multiple selection if true or single selection if false */ multiple?: boolean; /** * Allow to select all items with dedicated button */ allowSelectAll?: boolean; /** * Facets for natural-search in HierarchicComponent */ searchFacets?: NaturalSearchFacets; /** * Selections of natural search to initialize on HierarchicComponent initialisation */ searchSelections?: NaturalSearchSelections | null; }; declare class NaturalHierarchicSelectorDialogComponent { private dialogRef; /** * Set of hierarchic configurations to pass as attribute to HierarchicComponent */ config: HierarchicDialogConfig; /** * Natural search selections after initialisation */ searchSelectionsOutput: NaturalSearchSelections | undefined | null; constructor(); close(selected: OrganizedModelSelection | undefined): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare class NaturalHierarchicSelectorDialogService { private readonly dialog; open(hierarchicConfig: HierarchicDialogConfig, dialogConfig?: MatDialogConfig): MatDialogRef; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type NaturalIconType = { name: string; svg?: string; font?: string; class?: 'negative' | 'neutral' | 'positive'; }; type NaturalIconConfig = { svg?: string; font?: string; class?: 'negative' | 'neutral' | 'positive'; }; type NaturalIconsConfig = Record; declare const NATURAL_ICONS_CONFIG: InjectionToken; /** * Allows to use `` without knowing where an icon comes from (SVG or font) or with aliases for Material font. * * SVG icons and Material font aliases must be configured ahead of time, via `NATURAL_ICONS_CONFIG`. * * It also make it easy to give a specific size to the icon via `[size]`. * * Usage: * * ```html * * * * * ``` */ declare class NaturalIconDirective { private readonly matIconRegistry; private readonly domSanitizer; private readonly config; private readonly matIconComponent; private readonly isBrowser; readonly naturalIcon: i0.InputSignalWithTransform; readonly size: i0.InputSignal; protected readonly icon: i0.Signal; constructor(); private registerIcons; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } /** * Configure Material Symbols, instead of Material Icons, and configure custom Natural icons. * * This means that `https://fonts.googleapis.com/icon?family=Material+Icons` must be * replaced by `https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:FILL@1`. */ declare function provideIcons(config: NaturalIconsConfig): (EnvironmentProviders | Provider)[]; declare function providePanels(hooks: NaturalPanelsHooksConfig): Provider[]; declare class NaturalPanelsComponent implements OnDestroy { private readonly panelsService; constructor(); ngOnDestroy(): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare const naturalPanelsUrlMatcher: UrlMatcher; /** * Url fallback matcher to be used instead of `path: '**'` when Panel system * is used in the project. */ declare const fallbackIfNoOpenedPanels: UrlMatcher; /** * Custom template usage : * * ```html * * * {{ item.xxx }} * * * ``` */ declare class NaturalRelationsComponent, QueryVariables, unknown, any, unknown, any, unknown, any>> implements OnInit, OnChanges { private readonly destroyRef; private readonly linkMutationService; private readonly hierarchicSelectorDialog; private readonly select; readonly itemTemplate: i0.Signal | undefined>; private _service; get service(): TService; set service(service: TService); /** * The placeholder used in the button to add a new relation */ readonly placeholder: i0.InputSignal; /** * Filter for autocomplete selector */ readonly autocompleteSelectorFilter: i0.InputSignal["filter"] | null | undefined>; /** * Function to customize the rendering of the selected item as text in input */ readonly displayWith: i0.InputSignal<((item: ExtractTallOne | null) => string) | undefined>; /** * Whether the relations can be changed */ disabled: boolean; /** * The main object to which all relations belong to */ main: LinkableObject & { permissions?: { update: boolean; }; }; /** * Emits after relations were successfully added on the server */ readonly selectionChange: i0.OutputEmitterRef; /** * Filters for hierarchic selector */ readonly hierarchicSelectorFilters: i0.InputSignal; /** * Configuration in case we prefer hierarchic selection over autocomplete selection */ readonly hierarchicSelectorConfig: i0.InputSignal; /** * Link mutation semantic */ otherName?: string | null; /** * Listing service instance */ dataSource: NaturalDataSource>; loading: boolean; /** * Table columns */ displayedColumns: string[]; readonly pageSizeOptions: number[]; protected readonly defaultPagination: { pageIndex: number; pageSize: number; }; /** * Observable variables/options for listing service usage and apollo watchQuery */ private variablesManager; readonly removing: Set; /** * The filter used to filter relations * * So if the relations are from one action -> to many objectives, then the filter must filter * the objectives that have indeed a relation to the particular action. */ set filter(filter: ExtractVall['filter']); /** * The sorting used to sort relations * * So if the relations are from one action -> to many objectives, then the sorting must sort * the objectives that have indeed a relation to the particular action. */ set sorting(sorting: ExtractVall['sorting']); ngOnChanges(): void; ngOnInit(): void; /** * Unlink action * Refetch result to display it in table */ removeRelation(relation: LinkableObject): void; /** * Link action * Refetch result to display it in table * TODO : could maybe use "update" attribute of apollo.mutate function to update table faster (but hard to do it here) */ addRelations(relations: (LinkableObject | ExtractTallOne | string | null)[]): void; pagination(event?: PageEvent): void; getDisplayFn(): (item: ExtractTallOne | null) => string; openNaturalHierarchicSelector(): void; private getSelectKey; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵcmp: i0.ɵɵComponentDeclaration, "natural-relations", never, { "service": { "alias": "service"; "required": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "autocompleteSelectorFilter": { "alias": "autocompleteSelectorFilter"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; }; "main": { "alias": "main"; "required": true; }; "hierarchicSelectorFilters": { "alias": "hierarchicSelectorFilters"; "required": false; "isSignal": true; }; "hierarchicSelectorConfig": { "alias": "hierarchicSelectorConfig"; "required": false; "isSignal": true; }; "otherName": { "alias": "otherName"; "required": false; }; "filter": { "alias": "filter"; "required": false; }; "sorting": { "alias": "sorting"; "required": false; }; }, { "selectionChange": "selectionChange"; }, ["itemTemplate"], never, true, never>; } declare function toGraphQLDoctrineFilter(facets: NaturalSearchFacets | null, selections: NaturalSearchSelections | null): Filter; /** * Returns a string representation of the selection that can be used in URL. * * The string can be parsed back with `fromUrl()` */ declare function toUrl(selections: NaturalSearchSelections | null): string | null; /** * Parse a string, probably coming from URL, into a selection */ declare function fromUrl(selections: string | null): NaturalSearchSelections; /** * Transform a search selection to navigation parameters to be used in URL. * * This is typically useful to craft URL to pre-filtered lists. */ declare function toNavigationParameters(selections: NaturalSearchSelections): Params; /** * Wrap the searched value by `%` SQL wildcard * * So: * * {field: 'myFieldName', condition: {like: {value: 'foo'}}} * * will become * * {field: 'myFieldName', condition: {like: {value: '%foo%'}}} */ declare function wrapLike(selection: NaturalSearchSelection): NaturalSearchSelection; /** * Search by prefix using `%' SQL wildcard * * So: * * {field: 'myFieldName', condition: {like: {value: 'foo'}}} * * will become * * {field: 'myFieldName', condition: {like: {value: 'foo%'}}} */ declare function wrapPrefix(selection: NaturalSearchSelection): NaturalSearchSelection; /** * Search by suffix using `%' SQL wildcard * * So: * * {field: 'myFieldName', condition: {like: {value: 'foo'}}} * * will become * * {field: 'myFieldName', condition: {like: {value: '%foo'}}} */ declare function wrapSuffix(selection: NaturalSearchSelection): NaturalSearchSelection; /** * Replace the operator name (usually "like", "in" or "between") with the * attribute "field" defined in the configuration * * So: * * {field: 'myFieldName', condition: {in: {values: [1, 2, 3]}}} * * will become * * {field: 'myFieldName', condition: {myFieldName: {values: [1, 2, 3]}}} */ declare function replaceOperatorByField(selection: NaturalSearchSelection): NaturalSearchSelection; /** * Replace the operator name (usually "like", "in" or "between") with the * attribute "name" defined in the configuration * * So: * * {field: 'myFieldName', name:'myConfigName', condition: {in: {values: [1, 2, 3]}}} * * will become * * {field: 'myFieldName', name:'myConfigName', condition: {myConfigName: {values: [1, 2, 3]}}} */ declare function replaceOperatorByName(selection: NaturalSearchSelection): NaturalSearchSelection; declare class NaturalSearchComponent implements OnChanges { #private; private readonly breakpointObserver; /** * Placeholder for last input (the free search input) */ readonly placeholder: i0.InputSignal; /** * Exhaustive list of facets to be used in this */ facets: NaturalSearchFacets; /** * Whether to allow end-user to create multiple `OR` groups */ readonly multipleGroups: i0.InputSignal; /** * Text display in the dropdown to select the facet */ readonly dropdownTitle: i0.InputSignal; /** * Emits when some selection has been setted by the user */ readonly selectionChange: i0.OutputEmitterRef; /** * Cleaned inputted selections. This public API is useful because `selectionChange` does not emit changes made via `[selections]` */ readonly innerSelections: i0.Signal; /** * Input to display at component initialisation */ set selections(selections: NaturalSearchSelections); readonly isMobile: rxjs.Observable; ngOnChanges(): void; updateGroup(groupSelections: GroupSelections, groupIndex: number): void; addGroup(): void; removeGroup(index: number): void; clear(): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * This will completely ignore internal formControl and instead use the one from the component * which comes from outside of this component. This basically allows us to **not** depend on * touched status propagation between outside and inside world, and thus get rid of our legacy * custom FormControl class ("NaturalFormControl"). */ declare class ExternalFormControlMatcher extends ErrorStateMatcher { private readonly component; constructor(component: AbstractSelect); isErrorState(): boolean; } declare abstract class AbstractSelect implements OnInit, ControlValueAccessor, DoCheck { readonly ngControl: NgControl | null; readonly placeholder: i0.InputSignal; /** * Mat-hint, if given, and it is non-empty, then `computedSubscriptSizing` will * automatically be set to `dynamic` to allow for long, wrapping text. */ readonly hint: i0.InputSignal; /** * Explicit subscript sizing. Takes priority over the computed value when non-null. */ readonly subscriptSizing: i0.InputSignal<"dynamic" | "fixed" | null>; protected readonly computedSubscriptSizing: i0.Signal<"dynamic" | "fixed">; /** * If given an error message, it will be displayed in a ``, but only if the control * is actually in an error state via one of its validators. * * This is not needed for the special case of the required validator, because the message is hardcoded. */ error: string | null; /** * If the field is required */ set required(value: boolean); get required(): boolean; private _required; /** * Add a suffix button that is a link to given destination */ navigateTo?: any[] | string | null; /** * If provided cause a new clear button to appear */ readonly clearLabel: i0.InputSignal; /** * Whether to show the search icon */ readonly showIcon: i0.InputSignal; /** * Icon name */ readonly icon: i0.InputSignal; /** * Function to customize the rendering of the selected item as text in input */ readonly displayWith: i0.InputSignal<((item: TValue | null) => string) | undefined>; /** * Emit the selected value whenever it changes */ readonly selectionChange: i0.OutputEmitterRef; /** * Emits when internal input is blurred */ readonly blur: i0.OutputEmitterRef; /** * Contains internal representation for current selection AND searched text (for autocomplete) * * It is **not** necessarily `TValue | null`. * * - NaturalSelectComponent: `string | TValue | null`. We allow `string` * only when `optionRequired` is false, so most of the time it is `TValue | null`. * - NaturalSelectHierarchicComponent: `string | null`. * - NaturalSelectEnumComponent: `TValue | null`. * * In natural-select context, we use pristine and dirty to identify if the displayed value is search or committed model : * - Pristine status (unchanged value) means the model is displayed and propagated = the selection is committed * - Dirty status (changed value) means we are in search/autocomplete mode */ readonly internalCtrl: FormControl; /** * Interface with ControlValueAccessor * Notifies parent model / form controller */ onChange?: (item: TValue | null) => void; /** * Interface with ControlValueAccessor * Notifies parent model / form controller */ onTouched?: () => void; readonly matcher: ExternalFormControlMatcher; constructor(); ngDoCheck(): void; writeValue(value: TInput | null): void; ngOnInit(): void; /** * Whether the value can be changed */ set disabled(disabled: boolean); registerOnChange(fn: (item: TValue | null) => void): void; registerOnTouched(fn: () => void): void; abstract getDisplayFn(): (item: TValue | null) => string; /** * Commit the model to null * Emit and event to update the model */ clear(): void; /** * If input is dirty (search running) restore to model value */ onBlur(): void; /** * Commit the model change */ propagateValue(value: TValue | null): void; setDisabledState(isDisabled: boolean): void; showClearButton(): boolean; touch(): void; hasRequiredError(): boolean; /** * Apply Validators.required on the internal form, based on ngControl or [required] attribute, giving priority to attribute. */ private applyRequired; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵdir: i0.ɵɵDirectiveDeclaration, never, never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "subscriptSizing": { "alias": "subscriptSizing"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; }; "required": { "alias": "required"; "required": false; }; "navigateTo": { "alias": "navigateTo"; "required": false; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "showIcon": { "alias": "showIcon"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "selectionChange": "selectionChange"; "blur": "blur"; }, never, never, true, never>; } type Value = IEnum['value'] | IEnum['value'][]; declare class NaturalSelectEnumComponent extends AbstractSelect implements OnInit, ControlValueAccessor { private readonly enumService; /** * The name of the enum type, eg: `"ActionStatus"` */ readonly enumName: i0.InputSignal; /** * If given an extra option is added to select `null` with given label */ nullLabel?: string; /** * Functions that receives an enum value and returns whether that value is disabled */ optionDisabled?: (item: IEnum) => boolean; /** * Whether the user should be allowed to select multiple options */ readonly multiple: i0.InputSignal; items?: Observable; ngOnInit(): void; getDisplayFn(): (item: Value | null) => string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * Default usage: * * ```html * * ``` * * `[(ngModel)]` and `(ngModelChange)` are optional. * * Placeholder : * * ```html * * ``` */ declare class NaturalSelectHierarchicComponent extends AbstractSelect implements OnInit, ControlValueAccessor { private readonly hierarchicSelectorDialogService; /** * If provided cause a new select button to appear */ selectLabel?: string; /** * Configuration for hierarchic relations * * It should be an array with at least one element with `selectableAtKey` configured, otherwise the selector will never open. */ config: NaturalHierarchicConfiguration[] | null; /** * Filters formatted for hierarchic selector */ readonly filters: i0.InputSignal; /** * The selected value as an object. The internal value is `internalCtrl.value`, and that is a string. */ private value; /** * On Firefox, the combination of event and dialog opening cause some strange bug where focus event is called multiple * times This prevents it. */ private lockOpenDialog; /** * Very important to return something, above all if [select]='displayedValue' attribute value is used */ getDisplayFn(): (item: Literal | null) => string; /** * Override parent because our internalCtrl store the textual representation as string instead of raw Literal */ writeValue(value: Literal | string | null): void; openDialog(): void; showSelectButton(): boolean; private getSelectKey; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type ValueTypeFor = string | ExtractTallOne; /** * Default usage: * ```html * * ``` * * Custom template usage : * ```html * * * {{ item.xxx }} * * * ``` * * `[(ngModel)]` and `(ngModelChange)` are optional. * * Placeholder : * ```html * * ``` * * Search with like %xxx% on specified field `name` instead of custom filter on whole object * ```html * * ``` * * Allows to input free string without selecting an option from autocomplete suggestions * ```html * * ``` */ declare class NaturalSelectComponent, QueryVariables, any, any, any, any, any, any>> extends AbstractSelect, ValueTypeFor> implements OnInit, ControlValueAccessor, AfterViewInit { private readonly destroyRef; readonly autoTrigger: i0.Signal; readonly itemTemplate: i0.Signal | undefined>; /** * Service with watchAll function that accepts queryVariables. */ readonly service: i0.InputSignal; /** * If false, allows to input free string without selecting an option from autocomplete suggestions */ readonly optionRequired: i0.InputSignal; /** * The field on which to search for, default to 'custom'. */ searchField: 'custom' | string; /** * The operator with which to search for, default to 'search' if `searchField` is 'custom', else 'like'. */ searchOperator: 'search' | string | null; /** * Cache the committed value during search mode. * It's used to be restored in case we cancel the selection */ private lastValidValue; /** * Additional filter for query */ set filter(filter: ExtractVall['filter'] | null | undefined); /** * Items returned by server to show in listing */ items: null | Observable; /** * Whether we are searching something */ loading: boolean; /** * If some items are not shown in result list * Shows a message after list if true */ hasMoreItems: boolean; nbTotal: number; /** * Default page size */ readonly pageSize: i0.InputSignal; /** * Init search options */ private readonly variablesManager; /** * Whether the value can be changed */ set disabled(disabled: boolean); ngOnInit(): void; ngAfterViewInit(): void; onInternalFormChange(): void; onBlur(): void; /** * Reset form to it's initial value * Discard searched text (in autocomplete use case) * Doest not commit the change to the model (no change event is emitted) */ reset(): void; /** * Enter semantic means we want to validate something. * If we hit ENTER while typing a text, the stroke is ignored because the value is invalid (it's accepted in free text mode) * If we hit ENTER while the input field is empty, we validate the unselection (empty is a valid value) */ onKeyEnter(): void; writeValue(value: ValueTypeFor | null): void; private initService; startSearch(): void; /** * Commit the model change * Set internal form as pristine to reflect that the visible value match the model */ propagateValue(value: ValueTypeFor | null): void; /** * Very important to return something, above all if [select]='displayedValue' attribute value is used */ getDisplayFn(): (item: ValueTypeFor | null) => string; clear(): void; search(term: ValueTypeFor | null): void; showClearButton(): boolean; private getSearchFilter; getVariablesForDebug(): Readonly | undefined; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵcmp: i0.ɵɵComponentDeclaration, "natural-select", never, { "service": { "alias": "service"; "required": true; "isSignal": true; }; "optionRequired": { "alias": "optionRequired"; "required": false; "isSignal": true; }; "searchField": { "alias": "searchField"; "required": false; }; "searchOperator": { "alias": "searchOperator"; "required": false; }; "filter": { "alias": "filter"; "required": false; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; }; }, {}, ["itemTemplate"], never, true, never>; } declare class NaturalSidenavContainerComponent implements OnInit, OnDestroy { readonly sidenavService: NaturalSidenavService; /** * Unique identifier used for the local storage */ readonly name: i0.InputSignal; /** * The side that the drawer is attached to */ readonly position: i0.InputSignal<"start" | "end">; /** * If true listens to route changes to close side nav after a route change if mobile view is active * Actually a navigation to current route does not emit a route change, and the sidenav don't close. */ readonly mobileAutoClose: i0.InputSignal; /** * Width of the minimized menu */ readonly minimizedWidth: i0.InputSignal; /** * If true, prevents "native" material sidenav to scroll at container level and delegates the scroll responsability to the transcluded * content */ readonly noScroll: i0.InputSignal; /** * Inner "native" material sidenav */ readonly menuSidenav: i0.Signal; get isMinimized(): boolean; get isMobileView(): boolean; ngOnInit(): void; ngOnDestroy(): void; toggle(): void; close(): void; open(): void; minimize(): void; expand(): void; toggleMinimized(): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * TODO: Fix nav minimize and maximize resize * Since Material 2 beta 10, when nav is resized the body is not resized * https://github.com/angular/material2/issues/6743 * Maybe the better is to wait next release */ declare class NaturalSidenavService { private readonly destroyRef; private readonly breakpointObserver; private readonly router; private readonly sessionStorage; private readonly naturalSidenavStackService; /** * Navigation modes * First is for desktop view * Second is for mobile view */ private modes; /** * Activated mode * Default to desktop view */ private mode; /** * Whether nav is opened or not */ private opened; /** * Stores the opened status during mobile view, to restore if we come back to desktop view */ private tmpOpened; /** * Whether nav is minimized or not */ private minimized; /** * LocalStorage key that stores the minimized status */ private readonly minimizedStorageKey; /** * LocalStorage key that stores the opened status */ private readonly openedStorageKey; private minimizedStorageKeyWithName; private openedStorageKeyWithName; private _isMobileView; get activeMode(): MatDrawerMode; get isOpened(): boolean; get isMinimized(): boolean; destroy(component: NaturalSidenavContainerComponent): void; init(component: NaturalSidenavContainerComponent): void; isMobileView(): boolean; /** * Close nav on mobile view after a click */ navItemClicked(): void; /** * Change minimized status and stores the new value */ setMinimized(value: boolean): void; minimize(): void; expand(): void; toggleMinimized(): void; /** * Get the stored minimized status */ getMinimizedStatus(): boolean; /** * Get the stored opened status * Default on an opened status if nothing is stored */ getMenuOpenedStatus(): boolean; /** * Toggle menu but expand it if mobile mode is activated * Stores the status in local storage */ toggle(): void; close(): void; open(): void; setOpened(value: boolean): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } declare class NaturalSidenavStackService { /** * The stack of all currently living sidenavs */ private readonly sidenavs; /** * Emits the most recent living SidenavContainer whenever it changes. So it's * either the SidenavContainer that was just added, or the one "before" the * SidenavContainer that was just removed */ readonly currentSidenav: Subject; /** * For internal use only * @internal */ register(sidenav: NaturalSidenavContainerComponent): void; /** * For internal use only * @internal */ unregister(sidenav: NaturalSidenavContainerComponent): void; private next; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } declare class NaturalSidenavComponent { static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare class NaturalSidenavContentComponent { static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type Stamped = { creator: NameOrFullName | null; updater: NameOrFullName | null; creationDate: string | null; updateDate: string | null; }; declare class NaturalStampComponent { readonly item: i0.InputSignal; protected readonly showUpdate: i0.Signal; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * Button that fits well in a `` and support either * route navigation via `navigate`, or external URL via `href`, * or callback via `buttonClick`. * * If neither `navigate` nor `href` nor `buttonClick` have a meaningful value, then * it will show the icon and/or label in a `` instead of a button. * * External URL will always be opened in new tab. */ declare class NaturalTableButtonComponent { readonly queryParams: i0.InputSignal; readonly queryParamsHandling: i0.InputSignal; readonly label: i0.InputSignalWithTransform; readonly icon: i0.InputSignal; readonly href: i0.InputSignal; readonly navigate: i0.InputSignal; readonly fragment: i0.InputSignal; readonly preserveFragment: i0.InputSignal; readonly disabled: i0.InputSignal; readonly appearance: i0.InputSignal; readonly color: i0.InputSignal; protected readonly buttonClick$: Subject; readonly buttonClick: i0.OutputRef; protected readonly type: i0.Signal<"none" | "href" | "routerLinkOrClick">; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type NavigateCommands = Parameters[0]; type NaturalDialogTriggerRoutingData = { component: ComponentType; afterClosedRoute?: NavigateCommands; dialogConfig: MatDialogConfig; }; type NaturalDialogTriggerProvidedData = { data?: Readonly | null; activatedRoute: ActivatedRoute; }; type NaturalDialogTriggerRedirectionValues = NavigateCommands | null | undefined | '' | -1; declare class NaturalDialogTriggerComponent implements OnDestroy { private readonly dialog; private readonly route; private readonly router; private readonly dialogRef; private readonly triggerConfig; constructor(); /** * Called when router leaves route, and so on, closes the modal with undefined value to prevent a new redirection */ ngOnDestroy(): void; /** * Redirects on modal closing under following rules/conditions * * If -1 : no redirection * If array: assumed to be navigation commands and navigate to that * If routing data provides navigation commands, navigate to that * Anything else: fallbacks on parent route * * CAUTION: `exitValue` is typed, but we can actually receive anything, because of non-typed template usages such as `[mat-dialog-close]="true"` */ redirect(exitValue: NaturalDialogTriggerRedirectionValues): void; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵcmp: i0.ɵɵComponentDeclaration, "ng-component", never, {}, {}, never, never, true, never>; } /** * A creator interface used to instantiate source implementation */ type SourceCreator = new (sourceValue: string) => Source; /** * Contract of all Sources. * Every source must implements the fetch method * in order to provide the avatar source. */ declare abstract class Source { private readonly value; constructor(value: string); getValue(): string; /** * Gets the avatar that usually is a URL, but, * for example it can also be a string of initials from the name. */ abstract getAvatar(size: number): Promise; /** * Whether the avatar is purely textual or an URL for an image */ abstract isTextual(): boolean; } /** * Show an avatar from different sources */ declare class NaturalAvatarComponent { private readonly avatarService; readonly image: i0.InputSignal; readonly initials: i0.InputSignal; readonly gravatar: i0.InputSignal; readonly size: i0.InputSignal; readonly decorated: i0.InputSignal; readonly textSizeRatio: i0.InputSignal; readonly bgColor: i0.InputSignal; readonly fgColor: i0.InputSignal; readonly borderRadius: i0.InputSignal; readonly textMaximumLength: i0.InputSignal; private readonly sources; protected readonly currentSource: i0.Signal; protected readonly imageAvatar: i0.Signal | undefined>; protected readonly textAvatar: i0.Signal | undefined>; /** * Try to use the next available avatar source that has not already failed in the past */ tryNextSource(): void; private findNextNonFailingIndex; /** * Returns initials style */ protected readonly textualStyle: i0.Signal>; /** * Returns image style */ protected readonly imageStyle: i0.Signal>; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } type SourceType = 'gravatar' | 'image' | 'initials'; /** * Provides utilities methods related to Avatar component */ declare class AvatarService { /** * Ordered pairs of possible sources. First in the list is the highest priority. * And key must match one the input of AvatarComponent. */ private readonly sourceCreators; private readonly avatarColors; private readonly failedSources; getRandomColor(avatarText: string): string; getCreators(): IterableIterator<[SourceType, SourceCreator]>; private getSourceKey; sourceHasFailedBefore(source: Source): boolean; markSourceAsFailed(source: Source): void; private calculateAsciiCode; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } /** * Incomplete list of Matomo functions. But it should be enough * for our basic needs. * * To complete this list, maybe see https://developer.matomo.org/guides/tracking-javascript-guide */ type MatomoFunction = 'setCustomUrl' | 'setCustomDimension' | 'setDocumentTitle' | 'setReferrerUrl' | 'setSiteId' | 'setTrackerUrl' | 'trackPageView'; type PaqItem = [MatomoFunction, ...(number | string | null)[]]; /** * Service to track visitors via Matomo. * * @dynamic */ declare class NaturalMatomoService { private readonly router; private readonly document; private readonly titleService; private readonly isBrowser; private readonly window; private subscription; private referrerUrl; constructor(); /** * Inject Matomo script and start tracking all page navigation */ startTracking(url: string | null, site: number | null): void; stopTracking(): void; /** * Push a Matomo command on the stack * * It can be called at any time, including before Matomo is even loaded. * * Also see https://developer.matomo.org/guides/tracking-javascript-guide */ push(functionName: PaqItem[0], ...args: PaqItem[1][]): void; private injectTrackingCode; private listenForRouteChanges; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } type NaturalLoggerType = { message: string; stacktrace?: string; href?: string; host?: string; path?: string; agent?: string; status?: number; referrer?: string; url?: string; userId?: string; user?: string; [key: string]: any; }; type NaturalLoggerExtra = { /** * Return an observable of extra data that will be logged. Those data will be merged into * the original data, and so it can override things. * * Only the first emitted value will be used. */ getExtras(error: unknown): Observable>; }; declare const NaturalLoggerConfigUrl: InjectionToken; declare const NaturalLoggerConfigExtra: InjectionToken; /** * Replace Angular's error handler to also send the log to a remote server via HTTP POST. * * Usage is automatic as soon as we provide it via: * * ```ts * provideErrorHandler('http://example.com', ExtraService), * ``` */ declare class NaturalErrorHandler extends ErrorHandler { private readonly http; private readonly document; private readonly url; private readonly loggerExtra; constructor(); handleError(error: any): void; private toMessage; /** * Send parameters to remote log */ private postLog; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } declare function provideErrorHandler(url: string | null, extraService?: Type): Provider[]; declare class NaturalColorSchemerComponent { protected readonly themeService: NaturalThemeService; protected readonly colorSchemeOptions: readonly [{ readonly value: _ecodev_natural.ColorScheme.Auto; readonly label: string; readonly icon: "routine"; }, { readonly value: _ecodev_natural.ColorScheme.Light; readonly label: string; readonly icon: "light_mode"; }, { readonly value: _ecodev_natural.ColorScheme.Dark; readonly label: string; readonly icon: "dark_mode"; }]; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare class NaturalCompactColorSchemerComponent { protected readonly themeService: NaturalThemeService; protected readonly colorSchemeOptions: readonly [{ readonly value: _ecodev_natural.ColorScheme.Auto; readonly label: string; readonly icon: "routine"; }, { readonly value: _ecodev_natural.ColorScheme.Light; readonly label: string; readonly icon: "light_mode"; }, { readonly value: _ecodev_natural.ColorScheme.Dark; readonly label: string; readonly icon: "dark_mode"; }]; protected readonly current: i0.Signal<{ readonly value: _ecodev_natural.ColorScheme.Auto; readonly label: string; readonly icon: "routine"; } | { readonly value: _ecodev_natural.ColorScheme.Light; readonly label: string; readonly icon: "light_mode"; } | { readonly value: _ecodev_natural.ColorScheme.Dark; readonly label: string; readonly icon: "dark_mode"; } | undefined>; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare class NaturalThemeChangerComponent { protected readonly themeService: NaturalThemeService; protected readonly allThemes: [string, ...string[]]; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * Need to add http:// prefix if we don't have prefix already AND we don't have part of it */ declare function ensureHttpPrefix(value: string | null): string | null; /** * This directive only supports ReactiveForms due to ngModel/ngControl encapsulation and changes emissions. */ declare class NaturalHttpPrefixDirective { readonly naturalHttpPrefix: i0.InputSignal | null>; protected httpize($event: string): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } /** * Exactly the same as the original `MatCellDef`, but with the additional `dataSource` * input to specify the type of the element. * * Usage: * * ```html * * * * * *
Name * {{ element.name }} *
* ``` */ declare class TypedMatCellDef extends MatCellDef { /** * Should be the same value as the one used in `` */ readonly matCellDefDataSource: i0.InputSignal | DataSource | undefined>; static ngTemplateContextGuard(dir: TypedMatCellDef, ctx: any): ctx is { $implicit: T; index: number; }; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵdir: i0.ɵɵDirectiveDeclaration, "[matCellDef]", never, { "matCellDefDataSource": { "alias": "matCellDefDataSource"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>; } /** * Minimal, global providers for Natural to work */ declare const naturalProviders: ApplicationConfig['providers']; /** * Sign all HTTP POST requests that are GraphQL queries against `/graphql` endpoint with a custom signature. * * The server will validate the signature before executing the GraphQL query. */ declare function graphqlQuerySigner(key: string): HttpInterceptorFn; export { AvatarService, ColorScheme, ErrorService, InvalidWithValueStateMatcher$1 as InvalidWithValueStateMatcher, LOCAL_STORAGE, NATURAL_DROPDOWN_DATA, NATURAL_ICONS_CONFIG, NATURAL_PERSISTENCE_VALIDATOR, NATURAL_SEO_CONFIG, NaturalAbstractDetail, NaturalAbstractEditableList, NaturalAbstractList, NaturalAbstractModelService, NaturalAbstractNavigableList, NaturalAbstractPanel, NaturalAlertService, NaturalAvatarComponent, NaturalBackgroundDensityDirective, NaturalCapitalizePipe, NaturalColorSchemerComponent, NaturalColumnsPickerComponent, NaturalCompactColorSchemerComponent, NaturalConfirmComponent, NaturalDataSource, NaturalDebounceService, NaturalDetailHeaderComponent, NaturalDialogTriggerComponent, NaturalDropdownRef, NaturalEllipsisPipe, NaturalEnumPipe, NaturalEnumService, NaturalErrorHandler, NaturalErrorMessagePipe, NaturalFileComponent, NaturalFileDropDirective, NaturalFileSelectDirective, NaturalFileService, NaturalFixedButtonComponent, NaturalFixedButtonDetailComponent, NaturalHierarchicSelectorComponent, NaturalHierarchicSelectorDialogComponent, NaturalHierarchicSelectorDialogService, NaturalHierarchicSelectorService, NaturalHttpPrefixDirective, NaturalIconDirective, NaturalLinkMutationService, NaturalLinkableTabDirective, NaturalLoggerConfigExtra, NaturalLoggerConfigUrl, NaturalMatomoService, NaturalMemoryStorage, NaturalPanelsComponent, NaturalPanelsService, NaturalPersistenceService, NaturalQueryVariablesManager, NaturalRelationsComponent, NaturalSearchComponent, NaturalSelectComponent, NaturalSelectEnumComponent, NaturalSelectHierarchicComponent, NaturalSeoService, NaturalSidenavComponent, NaturalSidenavContainerComponent, NaturalSidenavContentComponent, NaturalSidenavService, NaturalSidenavStackService, NaturalSrcDensityDirective, NaturalStampComponent, NaturalSwissParsingDateAdapter, NaturalTableButtonComponent, NaturalThemeChangerComponent, NaturalThemeService, NaturalTimeAgoPipe, NetworkActivityService, PanelsHooksConfig, SESSION_STORAGE, SortingOrder, TypeAccountSelectorComponent, TypeBooleanComponent, TypeDateComponent, TypeDateRangeComponent, TypeHierarchicSelectorComponent, TypeNaturalSelectComponent, TypeNumberComponent, TypeOptionsComponent, TypeSelectComponent, TypeTextComponent, TypedMatCellDef, activityInterceptor, available, cancellableTimeout, collectErrors, commonImageMimeTypes, copyToClipboard, createErrorLink, createHttpLink, debug, decimal, deliverableEmail, ensureHttpPrefix, fallbackIfNoOpenedPanels, formatIsoDate, formatIsoDateTime, fromUrl, getForegroundColor, getNumberRows, getVisibleSelections, graphqlQuerySigner, greaterThan, hasFilesAndProcessDate, ifValid, ignoreErrors, integer, isAllVisibleSelected, isPartiallyVisibleSelected, localStorageFactory, localStorageProvider, makePlural, masterToggleVisible, memoryLocalStorageProvider, memorySessionStorageProvider, money, naturalPanelsUrlMatcher, naturalProviders, nfcCardHex, onHistoryEvent, possibleComparableOperators, possibleNullComparableOperators, provideErrorHandler, provideIcons, providePanels, provideSeo, provideThemes, relationsToIds, replaceOperatorByField, replaceOperatorByName, rgbToHex, selectVisible, sessionStorageFactory, sessionStorageProvider, signedMoney, time, toGraphQLDoctrineFilter, toNavigationParameters, toUrl, unique, unselectVisible, unsignedMoney, upperCaseFirstLetter, url, urlPattern, validTlds, validateAllFormControls, wrapLike, wrapPrefix, wrapSuffix }; export type { AvailableColumn, Button, DropdownComponent, DropdownFacet, ExtractResolve, ExtractTall, ExtractTallOne, ExtractTcreate, ExtractTdelete, ExtractTone, ExtractTupdate, ExtractVall, ExtractVcreate, ExtractVdelete, ExtractVone, ExtractVupdate, Facet, FileModel, FileSelection, Filter, FilterGroupConditionField, FlagFacet, FormAsyncValidators, FormControls, FormValidators, HierarchicDialogConfig, HierarchicDialogResult, HierarchicFilterConfiguration$1 as HierarchicFilterConfiguration, HierarchicFiltersConfiguration$1 as HierarchicFiltersConfiguration, IEnum, InvalidFile, LinkableObject, Literal, MutateOptionsWithoutVariables, NameOrFullName, NaturalConfirmData, NaturalDialogTriggerProvidedData, NaturalDialogTriggerRedirectionValues, NaturalDialogTriggerRoutingData, NaturalDropdownData, NaturalHierarchicConfiguration, NaturalIconConfig, NaturalIconsConfig, NaturalLoggerExtra, NaturalLoggerType, NaturalPalette, NaturalPanelConfig, NaturalPanelData, NaturalPanelResolves, NaturalPanelsBeforeOpenPanel, NaturalPanelsHooksConfig, NaturalPanelsRouteConfig, NaturalPanelsRouterRule, NaturalPanelsRoutesConfig, NaturalSearchFacets, NaturalSearchSelection, NaturalSearchSelections, NaturalSeo, NaturalSeoBasic, NaturalSeoCallback, NaturalSeoConfig, NaturalSeoResolve, NaturalSeoResolveData, NaturalStorage, NavigableItem, OrganizedModelSelection, PaginatedData, PaginationInput, PersistenceValidator, PossibleComparableOperator, PossibleComparableOperatorKeys, QueryVariables, ResolvedData, Sorting, SubButton, TypeBooleanConfiguration, TypeDateConfiguration, TypeDateRangeConfiguration, TypeHierarchicSelectorConfiguration, TypeNumberConfiguration, TypeOption, TypeOptionsConfiguration, TypeSelectConfiguration, TypeSelectItem, TypeSelectNaturalConfiguration, VariablesWithInput, WatchQueryOptionsWithoutVariables, WithId };