import { TemplateRef, Type } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { IResultList } from '@c8y/client';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { Observable } from 'rxjs';
import { ExtensionFactory } from '../common/extension-hooks';
import { GridConfigContext } from './data-grid-configuration.model';
import { SupportedIconsSuggestions } from '@c8y/ngx-components/icon-selector/icons';
/** Describes the interface of the data grid. */
export interface DataGrid {
    /** The list of columns. */
    columns: Column[];
    /** The list of items. */
    rows: Row[];
    /** Pagination object. */
    pagination: Pagination;
    /** A callback function to fetch server data. */
    serverSideDataCallback: ServerSideDataCallback;
    /** Whether items are selectable. */
    selectable: boolean;
    /** The name of the primary key property. */
    selectionPrimaryKey: string;
    /** Data grid display options. */
    displayOptions: DisplayOptions;
    /** Individual action controls. */
    actionControls: ActionControl[];
    /** Bulk action controls. */
    bulkActionControls: BulkActionControl[];
    /** Header action controls. */
    headerActionControls?: HeaderActionControl[];
}
/** Describes a data grid column. */
export interface Column {
    /** The name for the column. */
    name: string | SpecialColumnName;
    /** The column's header (if not given, `name` is used by default). */
    header?: string;
    /** The path in a row item to read the cell value from. */
    path?: string;
    /** Whether the column is displayed. */
    visible?: boolean;
    /** Whether the column can be moved to another position. */
    positionFixed?: boolean;
    /** Marks a user configured custom column */
    custom?: boolean;
    /** Whether the column can be resized. */
    resizable?: boolean;
    /** Optional type of data in the column (used to set data-type attribute, e.g. for additional styling). */
    dataType?: ColumnDataType;
    /** The column's size, e.g. "40 px". */
    gridTrackSize?: string;
    /** Additional CSS classes for the header cell. */
    headerCSSClassName?: string | string[];
    /** Additional CSS classes for data cells. */
    cellCSSClassName?: string | string[];
    /** Whether the column is sortable. */
    sortable?: boolean;
    /** Whether the sort order is ascending, descending or not specified. */
    sortOrder?: SortOrder;
    sortingConfig?: ColumnSortingConfig;
    /** Whether the column is filterable. */
    filterable?: boolean;
    /** The string to search for or a function for client-side filtering. */
    filterPredicate?: string | FilterPredicateFunction;
    /** Custom filtering form renderer can set any value here and it can be used to build a query to the server. */
    externalFilterQuery?: any;
    filteringConfig?: FormlyColumnFilteringConfig;
    /** Custom data cell renderer component. Inject `CellRendererContext` to get access to data value, item and column object. */
    cellRendererComponent?: Type<any>;
    /** Custom header cell renderer component. Inject `CellRendererContext` to get access to header value and column object. */
    headerCellRendererComponent?: Type<any>;
    /** Custom filtering form renderer component. Inject `FilteringFormRendererContext` to get access to column object and methods: applyFilter, resetFilter. */
    filteringFormRendererComponent?: Type<any>;
}
/** Describes a column configuration. */
export interface ColumnConfig {
    /** The name for the column. */
    name?: string;
    /** Whether the column is displayed. */
    visible?: boolean;
    /** Whether the sort order is ascending, descending or not specified. */
    sortOrder?: SortOrder;
    /** The settings of filter in a column. */
    filter?: Filter;
}
/** Describes a custom column configuration. */
export interface CustomColumnConfig extends ColumnConfig {
    /** JSON path to the managed object property to be displayed */
    path: string;
    /** Column header title */
    header: string;
    /** Flag to identify custom columns */
    custom: boolean;
}
/** Describes the settings of filter in a column. */
export interface Filter {
    /** Custom filtering form renderer can set any value here and it can be used to build a query to the server. */
    externalFilterQuery?: any;
    /** An optional property that holds a string to search for. */
    filterPredicate?: string | FilterPredicateFunction;
}
/** Describes an object with data grid configuration. */
export interface GridConfig {
    /** The configuration objects for all the columns. */
    columns: ColumnConfig[];
    /** Pagination object. */
    pagination: Pagination;
}
/**  */
export declare const enum SpecialColumnName {
    /** Column with checkbox. */
    Checkbox = "checkbox",
    /** Column with radio button. */
    RadioButton = "radio-button",
    /** Column with row actions. */
    Actions = "actions"
}
/**  */
export declare const enum ColumnDataType {
    /** Column with icon. */
    Icon = "icon",
    /** Numeric column. */
    Numeric = "numeric",
    /** Column with short text. */
    TextShort = "text-short",
    /** Column with long text. */
    TextLong = "text-long"
}
/** Classes for column data record. */
export declare const enum ColumnDataRecordClassName {
    /** An icon. */
    Icon = "data-record-icon",
    /** A header. */
    Header = "data-record-header",
    /** Default - empty. */
    Default = ""
}
export declare const minColumnGridTrackSize = 80;
/** Maps column types to relative widths. */
export declare const ratiosByColumnTypes: {
    /** The width ration for icon column type. */
    icon: number;
    /** The width ration for numeric column type. */
    numeric: number;
    /** The width ration for short text column type. */
    'text-short': number;
    /** The width ration for long text column type. */
    'text-long': number;
};
/** Sorting order: ascending, descending, or not specified. */
export type SortOrder = 'asc' | 'desc' | '';
/**
 * A filter predicate function.
 * @param item The current item to be checked.
 * @param path The property path configured in the current column.
 * @returns The boolean value indicating whether the item matches a condition or not.
 */
export type FilterPredicateFunction = (item: object, path: string) => boolean;
/** Filtering actions. */
export declare enum FilteringActionType {
    /** Action invoked when filter settings are to be applied. */
    ApplyFilter = "APPLY_FILTER",
    /** Action invoked when filter settings are to be cleared. */
    ResetFilter = "RESET_FILTER"
}
export interface FormlyColumnFilteringConfig {
    /** Defines a FieldConfig configuration for Formly.  */
    fields?: FormlyFieldConfig[];
    /** Defines a JSON schema for filtering config model. Can be used instead of `fields` */
    schema?: object;
    /** Defines a model that will be applied to rendered form. */
    model?: object;
    /** Defines FormGroup instance */
    formGroup?: FormGroup;
    /**
     * Transforms a filtering config model to an array of partial filter chip objects.
     * @param model An object with defined structure (e.g. by schema).
     * @returns An array of partial filter chip objects, each containing at least `displayValue` and the actual `value` to be updated.
     * Optionally, other properties from `FilterChip` are allowed, for example, a custom `remove` callback to be executed when a chip is being removed.
     */
    generateChips?: (model: any) => PartialFilterChipGenerationType[];
    /**
     * Transforms a filtering config model (e.g. coming from schema form component) to a query object.
     * However, using schema form component is not necessary.
     * Model can be defined arbitrarily but must converted to a valid query object.
     * @param model An object with defined structure (e.g. by schema).
     * @returns A query object to be used to generate a query string (QueryUtils).
     */
    getFilter: (model: any) => any;
}
export interface ColumnSortingConfig {
    pathSortingConfigs: PathSortingConfig[];
}
export interface PathSortingConfig {
    path: string;
    sortOrderModifier?: SortOrderModifier;
}
export declare const enum SortOrderModifier {
    Keep = 0,
    Invert = 1
}
/** Describes an item in the row. */
export interface Row {
    /** The unique identifier of the item. */
    id: string;
    /** Any item property. */
    [key: string]: any;
}
/** Describes a pagination object. */
export interface Pagination {
    /** The number of the current page. */
    currentPage?: number;
    /** The number of the next page. */
    nextPage?: number;
    /** The number of items on a single page. */
    pageSize: number;
}
/**
 * A callback function to fetch server data.
 * @param dataSourceModifier The current data source modifier.
 * @returns Returns the result from server.
 */
export type ServerSideDataCallback = (dataSourceModifier: DataSourceModifier) => ServerSideDataResult | Promise<ServerSideDataResult> | Observable<ServerSideDataResult>;
/** Describes a data source modifier for requesting server data. */
export interface DataSourceModifier {
    /** The list of columns. */
    columns: Column[];
    /** Text to search. */
    searchText: string;
    /** Pagination object. */
    pagination: Pagination;
    /** Selection info object. */
    selection: {
        /** Whether the selection is enabled. */
        enabled: boolean;
        /** The name of the primary key. */
        primaryKey: string;
    };
}
/** Describes a result from server with data and additional statistics. */
export type ServerSideDataResult = IResultList<object> & {
    /** The real grand total number of items (the whole dataset). */
    size: number;
    /** The number of items after filtering applied to the whole dataset (subset). */
    filteredSize: number;
    /** The list of ids of all filtered items (subset). */
    filteredDataIds?: string[];
};
/** Describes an object with data source statistics. */
export interface DataSourceStats {
    /** The real grand total number of items (the whole dataset). */
    size: number;
    /** The number of items after filtering applied to the whole dataset (subset). */
    filteredSize: number;
    /** The number of the current page. */
    currentPage: number;
    /** The number of the next page. */
    nextPage?: number;
    /** The number of items currently shown in the list view, a.k.a. current page (what the user sees on screen). */
    currentPageSize: number;
    /** The number of items on the first page.  */
    firstPageSize: number;
}
/** Describes data grid display options. */
export interface DisplayOptions {
    /** Show or hide zebra-striping in the table */
    striped: boolean;
    /** Show or hide each cell border */
    bordered: boolean;
    /** Show or hide the grid header */
    gridHeader: boolean;
    /** Show or hide filter label in the grid header */
    filter: boolean;
    /** Enable to display a background color on hover */
    hover: boolean;
}
/** Describes a data grid action control for individual item. */
export interface ActionControl {
    /** The type of the action, predefined or custom. */
    type: BuiltInActionType | string;
    /** The label for the action button. */
    text?: string;
    /** The icon for the action button. */
    icon?: SupportedIconsSuggestions;
    /** The icon classes for the action button icon. */
    iconClasses?: string;
    /** Action icon will be visible on hover only */
    showOnHover?: boolean;
    /**
     * A callback function.
     * @param item The item to perform the action on.
     * @param reload The function to call, if you want to reload the grid.
     */
    callback: ((item: Row, reload: () => void) => void) | Function;
    /**
     * Determines if the action should be shown for given item (if not defined, the action will be shown always).
     * @param item The item for which the action is supposed to be performed.
     */
    showIf?: ((item: Row & string[]) => boolean | Promise<boolean> | Observable<boolean>) | Function;
    /**
     * Defines the order in which action controls appear. Higher value means earlier position.
     * Controls without priority are handled with priority = 0. If you want to place an action after
     * an action without priority, negative numbers can be used.
     */
    priority?: number;
    [key: string]: any;
}
/** Describes a data grid action control for multiple items. */
export interface BulkActionControl extends ActionControl {
    /**
     * A callback function.
     * @param selectedItemIds The list of ids of the selected items.
     * @param reload The function to call, if you want to reload the grid.
     */
    callback(selectedItemIds: string[], reload: () => void): void;
    /**
     * Determines if the action should be shown for given selected items (if not defined, the action will be shown always).
     * @param selectedItemIds The list of ids of the selected items for which the action is supposed to be performed.
     */
    showIf?(selectedItemIds: string[]): boolean;
}
/** Describes a data grid action control for the header. */
export interface HeaderActionControl extends ActionControl {
    /**
     * Custom template can be provided. If no template is provided,
     * the default headerActionControl template is used.
     */
    template?: TemplateRef<any>;
    /**
     * A callback function.
     */
    callback(): void;
    /**
     * Determines if the action should be shown.
     */
    showIf?(): boolean;
}
/** Predefined types of actions. */
export declare enum BuiltInActionType {
    /** Edit built-in action. */
    Edit = "EDIT",
    /** Delete built-in action. */
    Delete = "DELETE",
    /** Export built-in action. */
    Export = "EXPORT"
}
/**
 * Allows to attach action controls to specified grids.
 */
export interface ActionControlHook {
    /**
     * The action control(s) that will be attached to the grid.
     */
    actionControls: ActionControl | ActionControl[];
    /**
     * A functions that determines to which grid(s) the action control(s) will be attached.
     * Not providing a function results in the actions control(s) not being attached to any grid.
     */
    matchesGrid: (route: ActivatedRoute, context?: GridConfigContext) => boolean | Promise<boolean> | Observable<boolean>;
}
/**
 * Factory to implement in order to add action controls from an extension.
 */
export type ActionControlFactory = ExtensionFactory<ActionControlHook>;
/**
 * Defines an interface for a filter chip object, which represents a filter applied to a column.
 */
export interface FilterChip {
    /**
     * The actual value that the chip will hold.
     * It can be just a string or a more complex object like
     * {id: 123, name: Test, value: test}.
     */
    value: any;
    /**
     * The value that the chip will display in the dropdown.
     */
    displayValue: string;
    /**
     * Optional label that will be displayed if filter chips are separated into multiple groups.
     */
    label?: string;
    /** An optional property that holds the path to the chip value in the externalFilterQuery. */
    path?: string[];
    /**
     * An optional property that holds the form value taken from the column configuration.
     */
    externalFilterQuery?: any;
    /**
     * An optional property that holds the formly filtering configuration for the column that this filter is applied to.
     */
    filteringConfig?: FormlyColumnFilteringConfig;
    /** An optional property that holds a string to search for. */
    filterPredicate?: string;
    /**
     * The name of the column that this filter is applied to.
     */
    columnName: string | SpecialColumnName;
    /**
     * An optional function to remove this filter from the column.
     * If not provided will set default removal function that will reduce the external query by removing the object that is resolved by the path set in the FilterChip.
     * @returns An object defined by the `FilterChip` type, including the `columnName` and  updated `externalFilterQuery` or 'filterPredicate' properties.
     * The returned object may also include additional properties defined by the `FilterChip` type as partials.
     */
    remove?: () => PartialFilterChipRemovalType;
}
/**
 * Represents a partial filter chip with either 'columnName' and 'externalFilterQuery' or 'columnName' and 'filterPredicate'.
 * @typedef {Object} PartialFilterChipRemovalType
 * @property {string} columnName - The column name for the filter chip.
 * @property {any} [externalFilterQuery] - The external filter query for the chip used for complex filters.
 * @property {any} [filterPredicate] - The filtering predicate for the chip used for simple filters with client-side filtering.
 * @property {...FilterChip} [optionalProperties] - Optional properties from the FilterChip type.
 */
export type PartialFilterChipRemovalType = (Required<Pick<FilterChip, 'columnName' | 'externalFilterQuery'>> | Required<Pick<FilterChip, 'columnName' | 'filterPredicate'>>) & Partial<FilterChip>;
/**
 * Represents a partial filter chip with required properties 'displayValue' and 'value'.
 * @typedef {Object} PartialFilterChipGenerationType
 * @property {string} displayValue - The display value for the filter chip.
 * @property {any} value - The value for the filter chip.
 * @property {...FilterChip} [optionalProperties] - Optional properties from the FilterChip type.
 */
export type PartialFilterChipGenerationType = Required<Pick<FilterChip, 'displayValue' | 'value'>> & Partial<FilterChip>;
/**
 * Defines an interface for a mapper function that maps a `FormlyFieldConfig` to a `FilterChip`.
 */
export interface FilterMapper {
    /**
     * The type or types of the `FormlyFieldConfig` that this mapper applies to.
     */
    fieldType: string[] | string;
    /**
     * Maps a `FormlyFieldConfig` and a `FilterChip` to an `Observable` of a `FilterChip`.
     *
     * This function extends the provided `FilterChip` object with additional properties based on the information in the `FormlyFieldConfig`.
     * The mapping process depends on the specific implementation of the `FilterMapper`.
     *
     * @param field - The `FormlyFieldConfig` to map.
     * @param filter - The `FilterChip` to map.
     * @returns An `Observable` that emits the mapped `FilterChip`.
     * If undefined is returned an error is thrown and the chip is not visualized.
     *
     * ```typescript
     * // Example implementation of `map` function in a `FilterMapper`
     * map(field: FormlyFieldConfig, filter: FilterChip): Observable<FilterChip> {
     *   if (this.fieldType.includes(field.type.toString())) {
     *     return toObservable(field.templateOptions.options).pipe(
     *       map(options => {
     *         const object = options.find(option => option.value === get(filter.externalFilterQuery, filter.path));
     *         return {
     *           ...filter,
     *           value: object,
     *           displayValue: object?.label
     *         };
     *       })
     *     );
     *   }
     * }
     * ```
     */
    map: (field: FormlyFieldConfig, filter: FilterChip) => Observable<FilterChip>;
}
//# sourceMappingURL=data-grid.model.d.ts.map