//@ts-ignore import dom from '@left4code/tw-starter/dist/js/dom' import { nextTick } from 'vue' import { icons, createIcons } from 'lucide' import { COLLAPSE_ORDER } from './Column' import { Resource } from '../../types/Resource' interface IconSettings { wrapperClass?: string title: string iconName: string } const iconWrapperClass = 'mr-3 last:mr-0' const iconSettings: Record = { edit: { wrapperClass: iconWrapperClass, title: 'Rediģēt', iconName: 'check-square', }, delete: { wrapperClass: `text-danger ${iconWrapperClass}`, title: 'Dzēst', iconName: 'trash-2', }, view: { wrapperClass: iconWrapperClass, title: 'Apskatīt', iconName: 'eye', }, } // either object of settings, or function that renders the action icon export type CustomAction = | { shouldShow: (data: any) => boolean clickHandler: (data: any) => void settings: IconSettings dataTest?: string } | ((data: any) => HTMLElement | null) export const ACTION_ICON_SIZE = 18 export const ACTION_ICON_MR = 12 export const ACTION_ICON_TOTAL_WIDTH = ACTION_ICON_SIZE + ACTION_ICON_MR export const ACTION_COLUMN_MIN_WIDTH = 90 const createIcon = ( wrapper: HTMLElement, clickHandler: () => void, settings: IconSettings, dataTest = '' ) => { const element = dom(` `) dom(element).on('click', async (e: Event) => { e.preventDefault() clickHandler() }) wrapper.append(element[0]) } export const renderIcons = () => { createIcons({ icons, attrs: { 'stroke-width': 1.5 }, nameAttr: 'data-lucide', }) } type TableProps = { edit: boolean delete: boolean view: boolean movableRows: boolean canUpdateRecordFunc: (cell: Tabulator.CellComponent) => boolean customActions?: CustomAction[] } const computeActionColumnWidth = (props: TableProps) => { let res = 10 if (props.edit) res += ACTION_ICON_TOTAL_WIDTH if (props.delete) res += ACTION_ICON_TOTAL_WIDTH if (props.view) res += ACTION_ICON_TOTAL_WIDTH if (props.customActions) { res += props.customActions.length * ACTION_ICON_TOTAL_WIDTH } return res > ACTION_COLUMN_MIN_WIDTH ? res : ACTION_COLUMN_MIN_WIDTH } const createActionColumn = ( props: TableProps, clickHandlers: { edit: >(resource: R) => void delete: >(resource: R) => void view: >(resource: R) => void } ): Tabulator.ColumnDefinition => { return { title: 'DARBĪBAS', field: 'actions', width: computeActionColumnWidth(props), headerSort: false, vertAlign: 'middle', hozAlign: 'right', headerHozAlign: 'right', responsive: COLLAPSE_ORDER.never, formatter(cell: Tabulator.CellComponent) { const data = cell.getData() as Resource const wrapper = dom( `
` ) if (props.movableRows) { wrapper.append( dom( `` )[0] ) } if (props.edit && props.canUpdateRecordFunc(cell)) { createIcon( wrapper, () => clickHandlers.edit(data), iconSettings.edit, 'table-edit-btn' ) } if (props.delete && props.canUpdateRecordFunc(cell)) { createIcon( wrapper, () => clickHandlers.delete(data), iconSettings.delete, 'table-delete-btn' ) } if (props.view) { createIcon( wrapper, () => clickHandlers.view(data), iconSettings.view, 'table-view-btn' ) } if (props.customActions) { props.customActions.forEach((a) => { if (typeof a === 'function') { const actionIcon = a(data) if (actionIcon) wrapper.append(actionIcon) } else { if (a.shouldShow(data)) { createIcon( wrapper, () => a.clickHandler(data), a.settings, a.dataTest ) } } }) } nextTick(renderIcons) return wrapper[0] }, } } export default createActionColumn