PluginProbe
The Innovative Form Builder – IvyForms / 1.1
The Innovative Form Builder – IvyForms v1.1
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / table / renderers / actionsCellRenderer.ts

actionsCellRenderer.ts in The Innovative Form Builder – IvyForms 1.1, at frontend/src/views/_components/table/renderers/actionsCellRenderer.ts

83 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { h, type VNode } from 'vue'
2 import IvyButtonAction from '@/views/_components/button/IvyButtonAction.vue'
3 import IvyTooltip from '@/views/_components/tooltip/IvyTooltip.vue'
4 import type { CellRenderProps } from '@/views/_components/table/IvyCellRendererProps'
5
6 export interface CellAction<Row> {
7 icon: string | ((row: Row) => string)
8 tooltip: string | ((row: Row) => string)
9 onClick: (row: Row, e?: Event) => void | Promise<void>
10 priority?: 'tertiary' | 'danger' | 'success'
11 type?: 'ghost' | 'fill'
12 iconStartType?: 'outline' | 'fill'
13 visible?: (row: Row) => boolean
14 refKey?: string
15 }
16
17 export interface ActionsCellOptions<Row> {
18 actions: CellAction<Row>[] | ((row: Row) => CellAction<Row>[])
19 idKey?: keyof Row & string
20 onButtonRef?: (id: unknown, el: HTMLElement | null) => void
21 }
22
23 const resolve = <Row, T>(value: T | ((row: Row) => T), row: Row): T =>
24 typeof value === 'function' ? (value as (row: Row) => T)(row) : value
25
26 export function actionsCellRenderer<Row extends Record<string, unknown>>(
27 options: ActionsCellOptions<Row>,
28 ) {
29 const idKey = options.idKey ?? ('id' as keyof Row & string)
30
31 return (props: CellRenderProps): VNode | null => {
32 const row = props.rowData as unknown as Row
33 if (!row) return null
34
35 const actions = typeof options.actions === 'function' ? options.actions(row) : options.actions
36 const visibleActions = actions
37 .map((action, index) => ({ action, index }))
38 .filter(({ action }) => (action.visible ? action.visible(row) : true))
39 const rowId = row[idKey] as unknown
40
41 return h(
42 'div',
43 {
44 class: ['ivyforms-column-actions', { hovered: rowId === props.hoveredRowId }],
45 },
46 visibleActions.map(({ action, index }) =>
47 h(
48 IvyTooltip,
49 {
50 key: `${String(rowId)}-${String(resolve(action.icon, row))}-${index}`,
51 content: resolve(action.tooltip, row),
52 placement: 'top',
53 },
54 () => [
55 h(IvyButtonAction, {
56 iconOnly: true,
57 iconStart: resolve(action.icon, row),
58 size: 's',
59 type: action.type ?? 'ghost',
60 priority: action.priority ?? 'tertiary',
61 iconStartType: action.iconStartType ?? 'outline',
62 ref: action.refKey
63 ? (el: unknown) => {
64 if (!options.onButtonRef) return
65 const node =
66 el &&
67 typeof el === 'object' &&
68 '$el' in el &&
69 (el as { $el: unknown }).$el instanceof HTMLElement
70 ? (el as { $el: HTMLElement }).$el
71 : null
72 options.onButtonRef(rowId, node)
73 }
74 : undefined,
75 onClick: (e: Event) => action.onClick(row, e),
76 }),
77 ],
78 ),
79 ),
80 )
81 }
82 }
83