import { AllowedComponentProps, Component, ComponentCustomProps, VNode, VNodeProps, } from 'vue'; import { DialogConfirmProps } from '../dialogconfirm'; import { MenuItem } from '../menuitem'; import { DateOptions } from '../utils/date.util'; import { WangsIconseverities } from '../icon'; import { EmitFn, HintedString } from '../ts-helpers.d'; export interface DataTableLocaleConfig { /** * Message to display on loading ovevrlay while downloading */ downloadingMessage?: string; /** * Text when booleanValue is true */ trueText?: string; /** * Text when booleanValue is false */ falseText?: string; /** * Text on paginator when data exist */ paginationReportFound?: string; /** * Text on paginator when data doesn't exist */ paginationReportNotFound?: string; /** * Specify the error message download excel * * @example 'Error, failed to download {fileName}' - fileName will be replaced */ excelToastErrorMessage?: string; /** * Custom message when data table is empty * * Will be shown bellow no-data animation */ emptyTableMessage?: string; } export type ChildGroup = { groupHeader: string; groupItems: T[]; }; export type Data> = T & { children?: ChildGroup[]; hasChildren?: boolean; }; export type QueryParams = Partial>; /** * Custom sort event. * @see {@link BaseDataTableEmits.sort} */ export interface DataTableSortEvent { /** * Browser event. */ originalEvent: Event; /** * Number of rows to display in new page */ rows: number; /** * Field to sort against */ sortField: string | undefined; /** * Sort order as integer */ sortOrder: 1 | 0 | -1 | undefined | null; } /** * Custom pagination event. * @see {@link BaseDataTableEmits.page} * @extends DataTableSortEvent */ export interface DataTablePageEvent extends DataTableSortEvent { /** * New page number */ page: number; /** * Total page count */ pageCount: number; } /** * Custom datatable operator filter metadata. */ export interface DataTableOperatorFilterMetaData { /** * Filter operator */ operator: string; /** * Array of filter meta data. */ constraints: DataTableFilterMetaData[]; } /** * Custom datatable filter metadata. */ export interface DataTableFilterMetaData { /** * Filter value */ value: any; /** * Filter match mode */ matchMode: | HintedString< | 'startsWith' | 'contains' | 'notContains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'lt' | 'lte' | 'gt' | 'gte' | 'between' | 'dateIs' | 'dateIsNot' | 'dateBefore' | 'dateAfter' > | undefined; } /** * Custom datatable filter metadata. */ export interface DataTableFilterMeta { /** * Extra options */ [key: string]: | string | DataTableFilterMetaData | DataTableOperatorFilterMetaData; } export type FetchListResponse = { message: string; data: { data: T[]; totalRecords: number; }; }; export type ShortFetchListResponse = { status: number; message: string; data: T[]; }; export type TableCellComponent = { component: Component; /** * Props to pass to the component */ props?: object; /** * Events or emits to pass to the component */ events?: any; /** * Model to pass to the component * @deprecated use `props` instead */ model?: any; /** * Callback when component model changed * @param itemData The row data object. * @returns The new value of the component. * @deprecated use `events` instead */ onChange?: (itemData: T) => void; disabled?: boolean; /** * To tell DataTable component whether this component should stop propagation or not * * @default true - since old logic was automatically stop event click from bodyComponent */ stop?: boolean; }; export type TogglePresetConfirmDialogProps = Omit< DialogConfirmProps, 'visible' | 'list' | 'onConfirm' > & { /** * When the dialog should be shown? * Pass a boolean returning function to show dialog when it returns true. * * @default both - leave this as undefined to show on both states */ showWhen?: | 'active' | 'inactive' | ((data: T, state: boolean) => boolean) | ((data: T, state: boolean) => Promise); }; interface ColumnConfirmActionPresetBase { /** * Use dialog confirmation */ confirmDialogProps?: | TogglePresetConfirmDialogProps | ((state: boolean, data: T) => TogglePresetConfirmDialogProps); /** * Callback for confirmation */ onConfirm?: (state: boolean, data: T, revertFunction: () => void) => void; } export interface ColumnTogglePreset extends ColumnConfirmActionPresetBase { type: 'toggle'; /** * Callback function when toggle state changes * * IMPORTANT: This callback is ALWAYS called regardless of whether confirmation dialog is shown * The 'state' parameter represents the NEW state that user sees on screen * * Usage Pattern: * 1. Check if confirmation dialog will be shown using your business logic * 2. If confirmation needed: Don't call API here, wait for onConfirm callback * 3. If no confirmation needed: Call API immediately to persist state * 4. If API fails: Call revertFunction() to restore previous state * * @param state boolean - NEW toggle state (what user sees on screen) * @param data T - The row data object * @param revertFunction - Function to revert state when API call fails or user cancels * @returns void */ onToggle?: (state: boolean, data: T, revertFunction: () => void) => void; /** * Add conditional disabling for each row */ disabled?: boolean | ((data: T) => boolean); } export interface ColumnCheckboxPreset extends ColumnConfirmActionPresetBase { type: 'checkbox'; /** * Callback function when checkbox state changes * * IMPORTANT: This callback is ALWAYS called regardless of whether confirmation dialog is shown * The 'state' parameter represents the NEW state that user sees on screen * * Usage Pattern: * 1. Check if confirmation dialog will be shown using your business logic * 2. If confirmation needed: Don't call API here, wait for onConfirm callback * 3. If no confirmation needed: Call API immediately to persist state * 4. If API fails: Call revertFunction() to restore previous state * * @param state boolean - NEW checkbox state (what user sees on screen) * @param data T - The row data object * @param revertFunction - Function to revert state when API call fails or user cancels * @returns void */ onCheck?: (state: boolean, data: T, revertFunction: () => void) => void; /** * Add conditional disabling for each row */ disabled?: boolean | ((data: T) => boolean); } export interface ColumnMultiRowPreset { type: 'multirow'; fieldAttributes?: (data: T) => MultiRowAttribute[]; } export interface MultiRowAttribute { class?: string | string[]; value?: string; bodyComponent?: TableCellComponent; } export type ColumnPreset = | ColumnTogglePreset | ColumnMultiRowPreset | ColumnCheckboxPreset; export interface CombinedHeaders { parent: TableParentHeader[]; child: TreeTableColumns[]; } export interface TableParentHeader extends Pick< TableColumn, 'header' | 'info' | 'infoSeverity' | 'headerClass' | 'sortable' > { /** * Field is used as the header's key, parent headers with * the same field will be grouped into one cell */ field: string; /** * Note: colspan is calculated automatically * @ignore */ colspan?: number; /** * Note: rowspan is calculated automatically * @ignore */ rowspan?: number; } export interface TableColumn { /** * The text rendered on th on each column */ header?: string; /** * The headers placed above certain child headers. If there are * multiple child headers with the same parent header, the parent * will have its colspan extended. The parent header will be shown * when at least one of its child headers is visible. */ parentHeader?: TableParentHeader; /** * The field name of the column. * Field is representing field on the row object to be displayed on the column. * The field is crucial for sorting and filtering the data. */ field: string; fieldType?: 'string' | 'number' | 'boolean' | 'array'; /** * Display information icon on the column header and show tooltip information about the column. */ info?: string; /** * The severity of the information icon. */ infoSeverity?: WangsIconseverities; /** * Whether the column is editable. * Editable column will set contenteditable to true on the cell. */ editable?: boolean; /** * If the column is editable, only allow number inputs. */ numberInputOnly?: boolean; /** * Whether the column is sortable. * Sortable column will add sort icon on the column header. It will produce query `sortBy` and `sortOrder`. The value for sortBy determined by column 'field'. */ sortable?: boolean; /** * Controls whether column appears in column visibility menu for reordering * @default true * @example * // Column appears in menu and can be reordered * { field: 'name', reorderable: true } * * // Column does NOT appear in menu (but still visible in table) * { field: 'id', reorderable: false } */ reorderable?: boolean; /** * Controls whether column can be dragged to reorder position in column visibility menu * @default true * @example * // Column can be reordered by dragging * { field: 'category', dragable: true } * * // Column cannot be dragged (but may still appear in menu) * { field: 'code', dragable: false } */ dragable?: boolean; /** * Makes column completely fixed - no visibility changes allowed * @default false * @example * // Fixed column - never appears in visibility menu AND cannot be hidden * { field: 'id', fixed: true } * * // Normal behavior - can be hidden/shown as needed * { field: 'name', fixed: false } */ fixed?: boolean; /** * Controls initial visibility state of column * @default true * @example * // Column starts visible * { field: 'name', visible: true } * * // Column starts hidden * { field: 'internalId', visible: false } */ visible?: boolean; /** * Use commonly used component as preset, simplify the common use-cases of bodyComponent with DataTable component. */ preset?: ColumnPreset; /** * Whether the column is checked by default, only for Custom Report Table * @default true */ checkedByDefault?: boolean; /** * The column width in pixel. */ width?: number | string; /** * Exclude column from download/export excel. */ excluded?: boolean; /** * Set the field for Export Excel, when you need to export different field of column field. * * @default undefined - the export field using column 'field' */ exportField?: string; /** * Specify the header when exported */ exportHeader?: string; /** * Specify the property or field which value in the array should be used for exporting to Excel. * * @example 'field.name.fullName' */ arrayValueField?: string; /** * Download Excel Config * * When needs to export only the property has Truthy value, set this to true, * The Excel result will only get the property object which the value is truthy. * * @example * Example Object: * "roles": { * roleA: true, * roleB: true, * roleC: false, * roleD: null, // falsy * roleE: '', // falsy * roleF: 'role', // truthy * } * * The result will be: "roleA, roleB, roleF" - Only the properties with truthy values will be included. */ includeTruthyProperties?: boolean; /** * Convert boolean into text Yes/No */ booleanValue?: boolean; /** * The text to display in the Excel cell when the value is true. (should be used with booleanValue) */ trueText?: string; /** * The text to display in the Excel cell when the value is false. (should be used with booleanValue) */ falseText?: string; /** * Specify the options for formatting date values using the formatDate utility. * * The date format primarily uses the general settings configurations. * Within this property, you only need to set the `showTime` or `showDate` options. */ dateFormatOptions?: DateOptions; /** * Set the fallback text when the cell value is empty. Used in export excel. * * @example 'N/A' */ emptyText?: string; /** * Customize the cell content rendered in the table body. Use this when the value of `field` specified needs custom formatting. * * @param data The row data object. * @param index The index of the row. * @returns The custom cell content as a string or undefined. */ bodyTemplate?: (data: T, index: number) => string | undefined; /** * Customize the cell component rendered in the table body. Use this when the value of `field` specified needs custom component rendering. * * @param data The row data object. * @param index The index of the row. * @returns The custom cell component as a TableCellComponent or undefined. */ bodyComponent?: (data: T, index: number) => TableCellComponent; /** * Inline style of header, body and footer cells. */ style?: string | (() => string); /** * Style class of header, body and footer cells. */ class?: string | string[] | (() => string | string[]); /** * Inline style of the column header. */ headerStyle?: string | (() => string); /** * Style class of the column header. */ headerClass?: string | string[] | (() => string | string[]); /** * Inline style of the column body. */ bodyStyle?: string | (() => string); /** * Style class of the column body. */ bodyClass?: string | string[] | ((data: T) => string | string[]); /** * Style class of the column body if the row is selected (useful for dark classes). */ bodySelectedClass?: string | ((data: T) => string); } /** * Extending the base table column, tree table column will only available when props.treeTable is sets to be `true` */ export interface TreeTableColumns extends TableColumn { /** * How much the column spanning */ colspan?: number; /** * The list of parents columns fields * The colspan will be counted from it lengths * This column will be shown when at least one of parent columns is visible * * @example * This column spans from parent column A to C, * this property value should be ['a', 'b', 'c'], * which each value in array is a 'column.field' of the parent columns * * The counted colspan will be 3 */ parentColumnsFields?: string[]; } /** * Emit payload for `cellEdited` */ export interface DataTableCellEditedEvent { /** * The row item were edited */ item: T; /** * The column field were edited */ field: string; /** * The index of row item */ index: number; /** * The text content of editable field */ value?: string; } /** * Emit payload for `rowReorder` */ export interface DataTableRowReorderEvent { item: T; fromIndex?: number; toIndex?: number; } /** * Custom row click event. * @see {@link DataTableEmits['row-click']} */ export interface DataTableRowClickEvent { /** * Browser event. */ originalEvent: Event; /** * Selected row data. */ data: T; /** * Row index. */ index: number; } export type ChildTableProps = Partial< Omit, 'fetchFunction'> > & { /** * Use the header of each column in child table * * @default false */ useColumnsHeader?: boolean; /** * The function to fetch data on row expand */ fetchFunction?: ( parentData: T, ) => Promise> | undefined>; }; export interface DataTableBaseProps { /** * Optional unique table name for ID generation and integration with components like FilterContainer, ButtonSearch, ButtonBulkAction. * Must be unique to avoid collisions. * * @optional */ tableName?: string; /** * Optional property to set a unique table title for export into excel. * * @optional */ tableTitle?: string; /** * Whether show single action option. * @default true; */ useOption?: boolean; /** * An array of objects to display in the table. * Mainly used for static table. For dynamic table that need to fetch data on demand, use fetchFunction instead. */ data?: T[]; /** * The key of the data object to use as a unique identifier. * Each row data must have a unique value for this key. Otherwise, the behavior of the table may be unpredictable. * * @default '_id' - You can specify a custom key if your data object uses a different unique identifier. */ dataKey?: string; /** * Style class of the row body. */ rowClass?: string | string[] | ((data?: any) => string | string[]); /** * The key of the data object to determine whether the row data should be disabled. * If the value of this key is truthy, the row will be disabled. */ disableKey?: string; /** * Determine whether disabled rows should be included in the check all process or not */ includeCheckDisabledRows?: boolean; /** * The key of data object to determine whether the row data has context highlighted or not * If the value of this key is truthy, the row will be highlighted. */ highlightKey?: string; /** * Boolean to specify whether all rows should be disabled. */ disableAllRows?: boolean; /** * Determine the type of DataTable. * * Sets to lazy if you need to dynamically shows data. */ lazy?: boolean; /** * The default query params that must be included every fetch request. * Will be merged with query params from fetchFunction. */ defaultQueryParams?: Readonly>; /** * The function to fetch data on DataTable mounted and on queryParams dependencies updated. * * @param params this is required */ fetchFunction?: ( params: QueryParams, ) => Promise | undefined>; /** * The number of rows to display per page. * @defaultValue 10 */ rows?: number; /** * Sets loading animation for DataTable that's not lazy. */ loading?: boolean; /** * Whether to enable 'checkbox' | 'single' selection. * * @default 'checkbox' */ selectionType?: 'single' | 'checkbox' | 'none'; /** * An array of selected objects from `data`. */ selectedData?: T[]; /** * An array of selected objects from `data`. */ expandedRows?: { [key: string]: boolean }; /** * Whether display pagination under the table or not. */ usePaginator?: boolean; /** * The options that will be visible for each row data. * To use this, set 'useOption' to true. * The options menu will be displayed on the right side of the table row. */ options?: MenuItem[]; /** * Whether the column is customizable or not. * * @default true - the table is able to reorder and toggle visibility column; */ customColumn?: boolean; /** * Props to set scroll height, this will make table content scrollable * @example '50vh' or '300px' */ scrollHeight?: string; /** * When the row height sets to fixed, it will have 35px height * * @defaultValue 'fixed' */ rowHeight?: 'fixed' | 'auto'; /** * To determine if row table is reorder-able */ reorderable?: boolean; /** * Total disabled rows in table (used for synchronizing with bulk action button) */ totalDisabledRows?: number; } export interface DataTableProps extends DataTableBaseProps { /** * Disable tree table mode */ treeTable?: false; childTableProps?: undefined; /** * An array of table columns to display. */ columns: TableColumn[]; } export interface TreeTableProps extends DataTableBaseProps { /** * Activate tree table mode */ treeTable: true; /** * V-model single selection. Works with selectionType 'single' */ singleSelection?: T; /** * An array of table columns to display. */ columns: TreeTableColumns[]; /** * Properties to be passed into sub table */ childTableProps?: ChildTableProps; } export interface BaseDataTableEmits { /** * Emits when option menu button clicked. */ 'toggleOption': [data: T]; /** * Emits when an item is double clicked. */ 'doubleClick': [data: T]; 'rowSelect': [data: DataTableRowClickEvent]; /** * Event emitted when the page changes in the data table. * * @event page * @param {DataTablePageEvent} data - The event data containing information about the new page. * * @example * * * This will call the `handlePageChange` method whenever the page changes in the data table. */ 'page': [data: DataTablePageEvent]; /** * Event emitted when the sort order changes in the data table. * * @event sort * @param {DataTableSortEvent} data - The event data containing information about the new sort order. * * @example * * * This will call the `handleSortChange` method whenever the sort order changes in the data table. */ 'sort': [data: DataTableSortEvent]; /** * Event emitted when the `selectedData` property is updated. * * @event update:selectedData * @param {Data[]} datas - The updated array of selected data objects. * * @example * * * This will update the `selectedData` value whenever a row is selected or deselected. */ 'update:selectedData': [datas: T[]]; } export interface TreeTableEmits extends BaseDataTableEmits { /** * Emitted when a row is clicked/selected. Only available on `single` selectionType */ 'update:singleSelection': [data: T]; /** * Emitted when cell has lost focus. */ 'cellEdited': [payload: DataTableCellEditedEvent]; /** * Emitted on Drop Event occurred after dragging a row. * Only available on * */ 'rowReorder': [payload?: DataTableRowReorderEvent]; } export interface DataTableEmits extends TreeTableEmits {} export interface DataTableSlots { /** * Slot for rendering sub content below a table row. */ 'row-subcontent': (props: { item: T }) => VNode[]; } /** * **WangsVue - DataTable** * * * _DataTable displays data in tabular format._ * * [Live Demo](https://fewangsit.github.io/wangsvue/table) * --- --- * ![WangsVue](https://www.wangsit.id/wp-content/uploads/2023/12/cropped-Logo_Wangsid-removebg-preview-192x192.png) * * @group Component */ declare const DataTable: ( props: (DataTableProps | TreeTableProps) & VNodeProps & AllowedComponentProps & ComponentCustomProps, context?: { slots: DataTableSlots; emit: EmitFn>; attrs: Record; }, ) => VNode & { __ctx?: { props: typeof props; slots: typeof context.slots } }; export default DataTable;