@postxl/generators 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/frontend-core/frontend.generator.d.ts +0 -58
- package/dist/frontend-core/frontend.generator.js +6 -172
- package/dist/frontend-core/frontend.generator.js.map +1 -1
- package/dist/frontend-core/template/README.md +1 -1
- package/dist/frontend-core/template/src/components/admin/table-filter.tsx +1 -5
- package/dist/frontend-core/template/src/components/ui/color-mode-toggle/color-mode-toggle.tsx +10 -4
- package/dist/frontend-core/template/src/pages/dashboard/dashboard.page.tsx +2 -3
- package/dist/frontend-core/template/src/pages/error/default-error.page.tsx +1 -1
- package/dist/frontend-core/template/src/pages/error/not-found-error.page.tsx +1 -1
- package/dist/frontend-core/template/src/styles/styles.css +13 -1
- package/dist/frontend-core/template/tsconfig.json +2 -0
- package/dist/frontend-core/types/component.d.ts +1 -1
- package/dist/frontend-forms/generators/discriminated-union/fields.generator.js +4 -6
- package/dist/frontend-forms/generators/discriminated-union/fields.generator.js.map +1 -1
- package/dist/frontend-forms/generators/discriminated-union/inputs.generator.js +1 -1
- package/dist/frontend-forms/generators/discriminated-union/inputs.generator.js.map +1 -1
- package/dist/frontend-forms/generators/enum/inputs.generator.js +1 -1
- package/dist/frontend-forms/generators/enum/inputs.generator.js.map +1 -1
- package/dist/frontend-forms/generators/model/forms.generator.js +8 -12
- package/dist/frontend-forms/generators/model/forms.generator.js.map +1 -1
- package/dist/frontend-forms/generators/model/inputs.generator.js +2 -6
- package/dist/frontend-forms/generators/model/inputs.generator.js.map +1 -1
- package/dist/frontend-forms/template/src/components/ui/field/field.tsx +1 -4
- package/dist/frontend-tables/generators/model-table.generator.js +1 -5
- package/dist/frontend-tables/generators/model-table.generator.js.map +1 -1
- package/package.json +3 -2
- package/dist/frontend-core/template/src/components/ui/accordion/accordion.stories.tsx +0 -47
- package/dist/frontend-core/template/src/components/ui/accordion/accordion.tsx +0 -52
- package/dist/frontend-core/template/src/components/ui/admin-sidebar/admin-sidebar.tsx +0 -195
- package/dist/frontend-core/template/src/components/ui/alert/alert.stories.tsx +0 -61
- package/dist/frontend-core/template/src/components/ui/alert/alert.tsx +0 -45
- package/dist/frontend-core/template/src/components/ui/alert-dialog/alert-dialog.stories.tsx +0 -52
- package/dist/frontend-core/template/src/components/ui/alert-dialog/alert-dialog.tsx +0 -105
- package/dist/frontend-core/template/src/components/ui/avatar/avatar.stories.tsx +0 -30
- package/dist/frontend-core/template/src/components/ui/avatar/avatar.tsx +0 -39
- package/dist/frontend-core/template/src/components/ui/badge/badge.stories.tsx +0 -78
- package/dist/frontend-core/template/src/components/ui/badge/badge.tsx +0 -48
- package/dist/frontend-core/template/src/components/ui/breadcrumb/breadcrumb.stories.tsx +0 -67
- package/dist/frontend-core/template/src/components/ui/breadcrumb/breadcrumb.tsx +0 -85
- package/dist/frontend-core/template/src/components/ui/button/button.stories.tsx +0 -150
- package/dist/frontend-core/template/src/components/ui/button/button.tsx +0 -68
- package/dist/frontend-core/template/src/components/ui/calendar/calendar.stories.tsx +0 -160
- package/dist/frontend-core/template/src/components/ui/calendar/calendar.tsx +0 -293
- package/dist/frontend-core/template/src/components/ui/card/card.stories.tsx +0 -77
- package/dist/frontend-core/template/src/components/ui/card/card.tsx +0 -45
- package/dist/frontend-core/template/src/components/ui/card-hover/card-hover.stories.tsx +0 -29
- package/dist/frontend-core/template/src/components/ui/card-hover/card-hover.tsx +0 -28
- package/dist/frontend-core/template/src/components/ui/carousel/carousel.stories.tsx +0 -154
- package/dist/frontend-core/template/src/components/ui/carousel/carousel.tsx +0 -227
- package/dist/frontend-core/template/src/components/ui/checkbox/checkbox.stories.tsx +0 -106
- package/dist/frontend-core/template/src/components/ui/checkbox/checkbox.tsx +0 -88
- package/dist/frontend-core/template/src/components/ui/checkbox/shadcn-checkbox.stories.tsx +0 -90
- package/dist/frontend-core/template/src/components/ui/checkbox/shadcn-checkbox.tsx +0 -54
- package/dist/frontend-core/template/src/components/ui/collapse/collapse.stories.tsx +0 -52
- package/dist/frontend-core/template/src/components/ui/collapse/collapse.tsx +0 -9
- package/dist/frontend-core/template/src/components/ui/combobox/combobox.stories.tsx +0 -207
- package/dist/frontend-core/template/src/components/ui/combobox/combobox.tsx +0 -79
- package/dist/frontend-core/template/src/components/ui/command/command.stories.tsx +0 -186
- package/dist/frontend-core/template/src/components/ui/command/command.tsx +0 -165
- package/dist/frontend-core/template/src/components/ui/command-palette/command-palette.stories.tsx +0 -160
- package/dist/frontend-core/template/src/components/ui/command-palette/command-palette.tsx +0 -134
- package/dist/frontend-core/template/src/components/ui/content-frame/content-frame.stories.tsx +0 -198
- package/dist/frontend-core/template/src/components/ui/content-frame/content-frame.tsx +0 -100
- package/dist/frontend-core/template/src/components/ui/context-menu/context-menu.stories.tsx +0 -78
- package/dist/frontend-core/template/src/components/ui/context-menu/context-menu.tsx +0 -179
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/cell-variant-types.ts +0 -11
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/checkbox-cell.tsx +0 -116
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/date-cell.tsx +0 -157
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/gantt-cell.tsx +0 -82
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/long-text-cell.tsx +0 -180
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/multi-select-cell.tsx +0 -280
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/number-cell.tsx +0 -169
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/react-node-cell.tsx +0 -33
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/select-cell.tsx +0 -175
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/short-text-cell.tsx +0 -138
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/utils/gantt-timeline.tsx +0 -92
- package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/utils/gantt-timerange-picker.tsx +0 -330
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-cell-wrapper.tsx +0 -212
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-cell.tsx +0 -157
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-column-header.tsx +0 -340
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-context-menu.tsx +0 -271
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-row.tsx +0 -123
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-search.tsx +0 -211
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-types.ts +0 -159
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-utils.ts +0 -67
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-view-menu.tsx +0 -360
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid.stories.tsx +0 -780
- package/dist/frontend-core/template/src/components/ui/data-grid/data-grid.tsx +0 -217
- package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-callback-ref.ts +0 -22
- package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-data-grid.tsx +0 -1892
- package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-debounced-callback.ts +0 -19
- package/dist/frontend-core/template/src/components/ui/data-grid/styles.css +0 -3
- package/dist/frontend-core/template/src/components/ui/data-table/context-menu-simple.tsx +0 -141
- package/dist/frontend-core/template/src/components/ui/data-table/data-table.stories.tsx +0 -146
- package/dist/frontend-core/template/src/components/ui/data-table/data-table.tsx +0 -447
- package/dist/frontend-core/template/src/components/ui/data-table/renderers/country-array-cell-renderer.tsx +0 -77
- package/dist/frontend-core/template/src/components/ui/data-table/renderers/country-cell-renderer.tsx +0 -56
- package/dist/frontend-core/template/src/components/ui/data-table/renderers/favorite-cell-renderer.tsx +0 -68
- package/dist/frontend-core/template/src/components/ui/data-table/renderers/links-cell-renderer.tsx +0 -205
- package/dist/frontend-core/template/src/components/ui/data-table/utils/columns.ts +0 -351
- package/dist/frontend-core/template/src/components/ui/data-table/utils/data-table.utils.ts +0 -49
- package/dist/frontend-core/template/src/components/ui/date-picker/date-picker.stories.tsx +0 -149
- package/dist/frontend-core/template/src/components/ui/date-picker/date-picker.tsx +0 -30
- package/dist/frontend-core/template/src/components/ui/dialog/dialog.stories.tsx +0 -80
- package/dist/frontend-core/template/src/components/ui/dialog/dialog.tsx +0 -134
- package/dist/frontend-core/template/src/components/ui/drawer/drawer.stories.tsx +0 -104
- package/dist/frontend-core/template/src/components/ui/drawer/drawer.tsx +0 -87
- package/dist/frontend-core/template/src/components/ui/dropdown-menu/dropdown-menu.stories.tsx +0 -168
- package/dist/frontend-core/template/src/components/ui/dropdown-menu/dropdown-menu.tsx +0 -225
- package/dist/frontend-core/template/src/components/ui/input/input.stories.tsx +0 -141
- package/dist/frontend-core/template/src/components/ui/input/input.tsx +0 -47
- package/dist/frontend-core/template/src/components/ui/label/label.stories.tsx +0 -41
- package/dist/frontend-core/template/src/components/ui/label/label.tsx +0 -20
- package/dist/frontend-core/template/src/components/ui/loader/loader.stories.tsx +0 -45
- package/dist/frontend-core/template/src/components/ui/loader/loader.tsx +0 -17
- package/dist/frontend-core/template/src/components/ui/mark-value-renderer/mark-value-renderer.stories.tsx +0 -114
- package/dist/frontend-core/template/src/components/ui/mark-value-renderer/mark-value-renderer.tsx +0 -48
- package/dist/frontend-core/template/src/components/ui/menubar/menu.stories.tsx +0 -134
- package/dist/frontend-core/template/src/components/ui/menubar/menubar.tsx +0 -208
- package/dist/frontend-core/template/src/components/ui/modal/modal.stories.tsx +0 -297
- package/dist/frontend-core/template/src/components/ui/modal/modal.tsx +0 -80
- package/dist/frontend-core/template/src/components/ui/navigation-menu/navigation-menu.stories.tsx +0 -213
- package/dist/frontend-core/template/src/components/ui/navigation-menu/navigation-menu.tsx +0 -142
- package/dist/frontend-core/template/src/components/ui/pagination/pagination.stories.tsx +0 -49
- package/dist/frontend-core/template/src/components/ui/pagination/pagination.tsx +0 -84
- package/dist/frontend-core/template/src/components/ui/popover/popover.stories.tsx +0 -82
- package/dist/frontend-core/template/src/components/ui/popover/popover.tsx +0 -55
- package/dist/frontend-core/template/src/components/ui/progress/progress.stories.tsx +0 -80
- package/dist/frontend-core/template/src/components/ui/progress/progress.tsx +0 -17
- package/dist/frontend-core/template/src/components/ui/radio-group/radio-group.stories.tsx +0 -154
- package/dist/frontend-core/template/src/components/ui/radio-group/radio-group.tsx +0 -68
- package/dist/frontend-core/template/src/components/ui/resizable/resizable.stories.tsx +0 -73
- package/dist/frontend-core/template/src/components/ui/resizable/resizeable.tsx +0 -38
- package/dist/frontend-core/template/src/components/ui/scroll-area/scroll-area.stories.tsx +0 -55
- package/dist/frontend-core/template/src/components/ui/scroll-area/scroll-area.tsx +0 -39
- package/dist/frontend-core/template/src/components/ui/select/select.stories.tsx +0 -297
- package/dist/frontend-core/template/src/components/ui/select/select.tsx +0 -227
- package/dist/frontend-core/template/src/components/ui/separator/separator.tsx +0 -21
- package/dist/frontend-core/template/src/components/ui/separator/seperator.stories.tsx +0 -25
- package/dist/frontend-core/template/src/components/ui/sheet/sheet.stories.tsx +0 -45
- package/dist/frontend-core/template/src/components/ui/sheet/sheet.tsx +0 -107
- package/dist/frontend-core/template/src/components/ui/skeleton/skeleton.stories.tsx +0 -26
- package/dist/frontend-core/template/src/components/ui/skeleton/skeleton.tsx +0 -7
- package/dist/frontend-core/template/src/components/ui/slider/slider.stories.tsx +0 -101
- package/dist/frontend-core/template/src/components/ui/slider/slider.tsx +0 -98
- package/dist/frontend-core/template/src/components/ui/spinner/spinner.stories.tsx +0 -19
- package/dist/frontend-core/template/src/components/ui/spinner/spinner.tsx +0 -21
- package/dist/frontend-core/template/src/components/ui/switch/switch.stories.tsx +0 -33
- package/dist/frontend-core/template/src/components/ui/switch/switch.tsx +0 -28
- package/dist/frontend-core/template/src/components/ui/tabs/tabs.stories.tsx +0 -215
- package/dist/frontend-core/template/src/components/ui/tabs/tabs.tsx +0 -70
- package/dist/frontend-core/template/src/components/ui/textarea/textarea.stories.tsx +0 -138
- package/dist/frontend-core/template/src/components/ui/textarea/textarea.tsx +0 -40
- package/dist/frontend-core/template/src/components/ui/toast/toast.mdx +0 -31
- package/dist/frontend-core/template/src/components/ui/toast/toast.stories.tsx +0 -89
- package/dist/frontend-core/template/src/components/ui/toggle/toggle.stories.tsx +0 -65
- package/dist/frontend-core/template/src/components/ui/toggle/toggle.tsx +0 -38
- package/dist/frontend-core/template/src/components/ui/toggle-group/toggle-group.stories.tsx +0 -85
- package/dist/frontend-core/template/src/components/ui/toggle-group/toggle-group.tsx +0 -54
- package/dist/frontend-core/template/src/components/ui/tooltip/tooltip.stories.tsx +0 -29
- package/dist/frontend-core/template/src/components/ui/tooltip/tooltip.tsx +0 -29
package/dist/frontend-core/template/src/components/ui/data-table/renderers/links-cell-renderer.tsx
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type CustomCell,
|
|
3
|
-
type CustomRenderer,
|
|
4
|
-
getMiddleCenterBias,
|
|
5
|
-
GridCellKind,
|
|
6
|
-
measureTextCached,
|
|
7
|
-
} from '@glideapps/glide-data-grid'
|
|
8
|
-
|
|
9
|
-
import { YesNo, YesNoBlank } from '@components/ui/data-table/utils/columns'
|
|
10
|
-
|
|
11
|
-
export type Link = {
|
|
12
|
-
readonly label: string
|
|
13
|
-
|
|
14
|
-
readonly isFilteredOut?: boolean
|
|
15
|
-
/**
|
|
16
|
-
* Will be triggered if the user clicks on the link.
|
|
17
|
-
*/
|
|
18
|
-
readonly onClick?: () => void
|
|
19
|
-
|
|
20
|
-
readonly url?: URL
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
type LinksCellProps = {
|
|
24
|
-
readonly kind: 'links-cell'
|
|
25
|
-
/**
|
|
26
|
-
* Used to hand tune the position of the underline as this is not a native canvas capability,
|
|
27
|
-
* it can need tweaking for different fonts.
|
|
28
|
-
*/
|
|
29
|
-
readonly underlineOffset?: number
|
|
30
|
-
readonly links: readonly Link[]
|
|
31
|
-
/**
|
|
32
|
-
* Will only be triggered if the user click outside of a link - or if
|
|
33
|
-
* the items does not have a separate `onClick` handler.
|
|
34
|
-
*/
|
|
35
|
-
readonly onClick?: <T>(items: T) => void
|
|
36
|
-
|
|
37
|
-
readonly rowData: any
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export type LinksCell = CustomCell<LinksCellProps>
|
|
41
|
-
|
|
42
|
-
export function stringToLink(item: string | Link): Link {
|
|
43
|
-
if (typeof item === 'string') {
|
|
44
|
-
return { label: item }
|
|
45
|
-
}
|
|
46
|
-
return item
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function booleanToLink(item: boolean | YesNo | YesNoBlank | null | undefined | Link): Link {
|
|
50
|
-
if (typeof item === 'object') {
|
|
51
|
-
return item as Link
|
|
52
|
-
} else if (item === null || item === undefined) {
|
|
53
|
-
return { label: '' }
|
|
54
|
-
} else if (item === true || item === 'Yes') {
|
|
55
|
-
return { label: 'Yes' }
|
|
56
|
-
} else if (item === false || item === 'No') {
|
|
57
|
-
return { label: 'No' }
|
|
58
|
-
}
|
|
59
|
-
return { label: '' }
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function linkToBoolean(item: boolean | string | undefined | null | Link): boolean | null {
|
|
63
|
-
if (typeof item === 'boolean') {
|
|
64
|
-
return item
|
|
65
|
-
} else if (typeof item === 'string') {
|
|
66
|
-
return item === 'Yes'
|
|
67
|
-
} else if (typeof item === 'object') {
|
|
68
|
-
return item?.label === 'Yes'
|
|
69
|
-
} else {
|
|
70
|
-
return null
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function linkToString(item: string | Link): string {
|
|
75
|
-
if (typeof item === 'string') {
|
|
76
|
-
return item
|
|
77
|
-
}
|
|
78
|
-
return item.label
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Based on the mouse position, this function will return the link that
|
|
82
|
-
* is currently hovered. If no link is hovered, it will return `undefined`.
|
|
83
|
-
*/
|
|
84
|
-
function getHoveredLink(e: Parameters<NonNullable<CustomRenderer<LinksCell>['onSelect']>>[0]) {
|
|
85
|
-
const canvas = document.createElement('canvas')
|
|
86
|
-
const ctx = canvas.getContext('2d', { alpha: false })
|
|
87
|
-
if (ctx === null) {
|
|
88
|
-
return
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const { posX: hoverX, bounds: rect, cell, theme } = e
|
|
92
|
-
const font = theme.baseFontFull
|
|
93
|
-
ctx.font = font
|
|
94
|
-
|
|
95
|
-
const { links } = cell.data
|
|
96
|
-
|
|
97
|
-
const xPad = theme.cellHorizontalPadding
|
|
98
|
-
|
|
99
|
-
let drawX = rect.x + xPad
|
|
100
|
-
|
|
101
|
-
const mouseX = rect.x + hoverX
|
|
102
|
-
|
|
103
|
-
for (const [index, link] of links.entries()) {
|
|
104
|
-
const needsComma = index < links.length - 1
|
|
105
|
-
const metrics = measureTextCached(link.label, ctx)
|
|
106
|
-
const commaMetrics = needsComma ? measureTextCached(link.label + ',', ctx, font) : metrics
|
|
107
|
-
|
|
108
|
-
const isHovered = drawX <= mouseX && mouseX <= drawX + metrics.width
|
|
109
|
-
|
|
110
|
-
if (isHovered) {
|
|
111
|
-
return link
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
drawX += commaMetrics.width + 5
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return undefined
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export const linksTableRenderer: CustomRenderer<LinksCell> = {
|
|
121
|
-
kind: GridCellKind.Custom,
|
|
122
|
-
needsHover: true,
|
|
123
|
-
needsHoverPosition: true,
|
|
124
|
-
isMatch: (c): c is LinksCell => (c.data as { kind?: string }).kind === 'links-cell',
|
|
125
|
-
onSelect: (e) => {
|
|
126
|
-
if (getHoveredLink(e) !== undefined) {
|
|
127
|
-
e.preventDefault()
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
onClick: (event) => {
|
|
131
|
-
// We first check if the user clicked on a specific link and if we have a link-specific handler.
|
|
132
|
-
const clickedItem = getHoveredLink(event)
|
|
133
|
-
if (clickedItem?.onClick) {
|
|
134
|
-
clickedItem.onClick()
|
|
135
|
-
event.preventDefault()
|
|
136
|
-
return undefined
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// In case the item has a URL, we open it in a new tab
|
|
140
|
-
if (clickedItem?.url) {
|
|
141
|
-
window.open(clickedItem.url, '_blank')
|
|
142
|
-
return undefined
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// As a fallback, ie if either the user clicked in the cell but not on a link or if the
|
|
146
|
-
// cell does not have a separate `onClick` handler, we check if the cell has a generic
|
|
147
|
-
// `onClick` handler.
|
|
148
|
-
const { onClick: genericCellOnClick } = event.cell.data
|
|
149
|
-
if (genericCellOnClick) {
|
|
150
|
-
genericCellOnClick(event.cell.data.rowData)
|
|
151
|
-
event.preventDefault()
|
|
152
|
-
return undefined
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return undefined
|
|
156
|
-
},
|
|
157
|
-
|
|
158
|
-
draw: (args, cell) => {
|
|
159
|
-
const { ctx, rect, theme, hoverX = -100 } = args
|
|
160
|
-
const { links, underlineOffset = 5 } = cell.data
|
|
161
|
-
|
|
162
|
-
const xPad = theme.cellHorizontalPadding
|
|
163
|
-
|
|
164
|
-
let drawX = rect.x + xPad
|
|
165
|
-
|
|
166
|
-
const rectHoverX = rect.x + hoverX
|
|
167
|
-
|
|
168
|
-
const font = theme.baseFontFull
|
|
169
|
-
|
|
170
|
-
const middleCenterBias = getMiddleCenterBias(ctx, font)
|
|
171
|
-
const drawY = rect.y + rect.height / 2 + middleCenterBias
|
|
172
|
-
|
|
173
|
-
for (const [index, l] of links.entries()) {
|
|
174
|
-
const needsComma = index < links.length - 1
|
|
175
|
-
const metrics = measureTextCached(l.label, ctx, font)
|
|
176
|
-
const commaMetrics = needsComma ? measureTextCached(l.label + ',', ctx, font) : metrics
|
|
177
|
-
|
|
178
|
-
const isHovered = rectHoverX > drawX && rectHoverX < drawX + metrics.width
|
|
179
|
-
|
|
180
|
-
if (isHovered) {
|
|
181
|
-
args.overrideCursor?.('pointer')
|
|
182
|
-
ctx.moveTo(drawX, Math.floor(drawY + underlineOffset) + 0.5)
|
|
183
|
-
ctx.lineTo(drawX + metrics.width, Math.floor(drawY + underlineOffset) + 0.5)
|
|
184
|
-
|
|
185
|
-
ctx.lineWidth = 1
|
|
186
|
-
ctx.strokeStyle = theme.textDark
|
|
187
|
-
ctx.stroke()
|
|
188
|
-
|
|
189
|
-
ctx.fillStyle = theme.linkColor
|
|
190
|
-
} else {
|
|
191
|
-
ctx.fillStyle = theme.textDark
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (l.isFilteredOut === true) {
|
|
195
|
-
ctx.fillStyle = theme.textLight
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
ctx.fillText(needsComma ? l.label + ',' : l.label, drawX, drawY)
|
|
199
|
-
|
|
200
|
-
drawX += commaMetrics.width + 4
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return true
|
|
204
|
-
},
|
|
205
|
-
}
|
|
@@ -1,351 +0,0 @@
|
|
|
1
|
-
import { type BaseGridCell, type CellClickedEventArgs, GridCellKind, type GridColumn } from '@glideapps/glide-data-grid'
|
|
2
|
-
|
|
3
|
-
import type { ContextMenuAction } from '../context-menu-simple'
|
|
4
|
-
import { type DataTableColumn } from '../data-table'
|
|
5
|
-
import { booleanToLink, type Link, linkToBoolean, linkToString, stringToLink } from '../renderers/links-cell-renderer'
|
|
6
|
-
|
|
7
|
-
export type YesNo = 'Yes' | 'No'
|
|
8
|
-
export type YesNoBlank = 'Yes' | 'No' | 'Blank'
|
|
9
|
-
|
|
10
|
-
export type ColumnDefinition<Row extends object, ColumnId extends string> = GridColumn & {
|
|
11
|
-
id: ColumnId
|
|
12
|
-
tooltip?: string
|
|
13
|
-
onClick?: (row: Row, event: CellClickedEventArgs) => void
|
|
14
|
-
themeOverride?: (row: Row) => BaseGridCell['themeOverride']
|
|
15
|
-
onContextMenu?: (row: Row, event: CellClickedEventArgs) => ContextMenuAction[]
|
|
16
|
-
isSelected?: (row: Row) => boolean
|
|
17
|
-
sortComparator?: (row1: Row, row2: Row, direction: 'asc' | 'desc' | null) => number
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// STRING ----------------------------------------------------------------------
|
|
21
|
-
export function stringColumn<Row extends object, ColumnId extends string>(
|
|
22
|
-
lookup: (item: Row) => Link | string,
|
|
23
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
24
|
-
): DataTableColumn<Row, ColumnId> {
|
|
25
|
-
return {
|
|
26
|
-
width: definition.title.length * 10,
|
|
27
|
-
sortComparator: (row1, row2, direction) => {
|
|
28
|
-
const value1 = linkToString(lookup(row1))
|
|
29
|
-
const value2 = linkToString(lookup(row2))
|
|
30
|
-
return compare(value1, value2, direction)
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
...definition,
|
|
34
|
-
// We omit the `onClick` property because the custom renderer has its own handler for it.
|
|
35
|
-
onClick: undefined,
|
|
36
|
-
themeOverride: undefined,
|
|
37
|
-
toCell: (item) => ({
|
|
38
|
-
kind: GridCellKind.Custom,
|
|
39
|
-
allowOverlay: true,
|
|
40
|
-
copyData: linkToString(lookup(item)),
|
|
41
|
-
data: {
|
|
42
|
-
kind: 'links-cell',
|
|
43
|
-
underlineOffset: 6,
|
|
44
|
-
links: [stringToLink(lookup(item))],
|
|
45
|
-
onClick: definition.onClick,
|
|
46
|
-
rowData: item,
|
|
47
|
-
},
|
|
48
|
-
themeOverride: definition.themeOverride?.(item),
|
|
49
|
-
}),
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// STRING ARRAY ----------------------------------------------------------------
|
|
54
|
-
export function stringArrayColumn<Row extends object, ColumnId extends string>(
|
|
55
|
-
lookup: (item: Row) => Link[] | string[],
|
|
56
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
57
|
-
): DataTableColumn<Row, ColumnId> {
|
|
58
|
-
return {
|
|
59
|
-
width: definition.title.length * 10,
|
|
60
|
-
sortComparator: (row1, row2, direction) => {
|
|
61
|
-
const value1 = linkToString(lookup(row1)[0]) ?? ''
|
|
62
|
-
const value2 = linkToString(lookup(row2)[0]) ?? ''
|
|
63
|
-
return compare(value1, value2, direction)
|
|
64
|
-
},
|
|
65
|
-
...definition,
|
|
66
|
-
// We omit the `onClick` property because the custom renderer has its own handler for it.
|
|
67
|
-
onClick: undefined,
|
|
68
|
-
toCell: (item) => ({
|
|
69
|
-
kind: GridCellKind.Custom,
|
|
70
|
-
allowOverlay: true,
|
|
71
|
-
copyData: lookup(item).map(linkToString).join(', '),
|
|
72
|
-
data: {
|
|
73
|
-
kind: 'links-cell',
|
|
74
|
-
underlineOffset: 6,
|
|
75
|
-
links: lookup(item).map(stringToLink),
|
|
76
|
-
onClick: definition.onClick,
|
|
77
|
-
rowData: item,
|
|
78
|
-
},
|
|
79
|
-
themeOverride: definition.themeOverride?.(item),
|
|
80
|
-
}),
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// NUMBER ----------------------------------------------------------------------
|
|
85
|
-
|
|
86
|
-
export function numberColumn<Row extends object, ColumnId extends string>(
|
|
87
|
-
lookup: (item: Row) => number,
|
|
88
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
89
|
-
): DataTableColumn<Row, ColumnId> {
|
|
90
|
-
return {
|
|
91
|
-
width: definition.title.length * 10,
|
|
92
|
-
sortComparator: (row1, row2, direction) => compare(lookup(row1), lookup(row2), direction),
|
|
93
|
-
...definition,
|
|
94
|
-
toCell: (item) => ({
|
|
95
|
-
contentAlign: 'right',
|
|
96
|
-
kind: GridCellKind.Text,
|
|
97
|
-
data: lookup(item).toLocaleString(),
|
|
98
|
-
allowOverlay: false,
|
|
99
|
-
displayData: lookup(item).toLocaleString(),
|
|
100
|
-
themeOverride: { cellHorizontalPadding: 0, ...definition.themeOverride?.(item) },
|
|
101
|
-
}),
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function optionalNumberColumn<Row extends object, ColumnId extends string>(
|
|
106
|
-
lookup: (item: Row) => number | undefined | null,
|
|
107
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
108
|
-
): DataTableColumn<Row, ColumnId> {
|
|
109
|
-
return {
|
|
110
|
-
width: definition.title.length * 10,
|
|
111
|
-
sortComparator: (row1, row2, direction) => compare(lookup(row1), lookup(row2), direction),
|
|
112
|
-
...definition,
|
|
113
|
-
toCell: (item) => ({
|
|
114
|
-
contentAlign: 'right',
|
|
115
|
-
kind: GridCellKind.Text,
|
|
116
|
-
data: lookup(item)?.toLocaleString() ?? '',
|
|
117
|
-
allowOverlay: false,
|
|
118
|
-
displayData: lookup(item)?.toLocaleString() ?? '',
|
|
119
|
-
themeOverride: { cellHorizontalPadding: 0, ...definition.themeOverride?.(item) },
|
|
120
|
-
}),
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// PERCENTAGE ------------------------------------------------------------------
|
|
125
|
-
export function percentageColumn<Row extends object, ColumnId extends string>(
|
|
126
|
-
lookup: (item: Row) => string,
|
|
127
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
128
|
-
): DataTableColumn<Row, ColumnId> {
|
|
129
|
-
return {
|
|
130
|
-
width: definition.title.length * 10,
|
|
131
|
-
sortComparator: (row1, row2, direction) => compare(lookup(row1), lookup(row2), direction),
|
|
132
|
-
...definition,
|
|
133
|
-
themeOverride: undefined,
|
|
134
|
-
toCell: (item) => ({
|
|
135
|
-
kind: GridCellKind.Text,
|
|
136
|
-
data: lookup(item),
|
|
137
|
-
allowOverlay: false,
|
|
138
|
-
displayData: lookup(item),
|
|
139
|
-
|
|
140
|
-
contentAlign: 'right',
|
|
141
|
-
themeOverride: definition.themeOverride?.(item),
|
|
142
|
-
}),
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
//BOOLEAN ----------------------------------------------------------------------
|
|
147
|
-
export function booleanColumn<Row extends object, ColumnId extends string>(
|
|
148
|
-
lookup: (item: Row) => Link | YesNo | YesNoBlank | boolean | null | undefined,
|
|
149
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
150
|
-
): DataTableColumn<Row, ColumnId> {
|
|
151
|
-
return {
|
|
152
|
-
width: definition.title.length * 10,
|
|
153
|
-
sortComparator: (row1, row2, direction) =>
|
|
154
|
-
compare(linkToBoolean(lookup(row1)) ? 1 : 0, linkToBoolean(lookup(row2)) ? 1 : 0, direction),
|
|
155
|
-
|
|
156
|
-
...definition,
|
|
157
|
-
// We omit the `onClick` property because the custom renderer has its own handler for it.
|
|
158
|
-
onClick: undefined,
|
|
159
|
-
toCell: (item) => ({
|
|
160
|
-
kind: GridCellKind.Custom,
|
|
161
|
-
allowOverlay: true,
|
|
162
|
-
copyData: linkToBoolean(lookup(item)) ? 'true' : 'false',
|
|
163
|
-
data: {
|
|
164
|
-
kind: 'links-cell',
|
|
165
|
-
underlineOffset: 6,
|
|
166
|
-
links: [booleanToLink(lookup(item))],
|
|
167
|
-
onClick: definition.onClick,
|
|
168
|
-
rowData: item,
|
|
169
|
-
},
|
|
170
|
-
themeOverride: definition.themeOverride?.(item),
|
|
171
|
-
}),
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export function toYesNo(value: boolean | null): 'Yes' | 'No' | '-' {
|
|
176
|
-
if (value === null) {
|
|
177
|
-
return '-'
|
|
178
|
-
}
|
|
179
|
-
return value ? 'Yes' : 'No'
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export function toYesNoBlank(value: YesNoBlank): 'Yes' | 'No' | '-' {
|
|
183
|
-
if (value === 'Yes') {
|
|
184
|
-
return 'Yes'
|
|
185
|
-
}
|
|
186
|
-
if (value === 'No') {
|
|
187
|
-
return 'No'
|
|
188
|
-
}
|
|
189
|
-
return '-'
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// COUNTRY ---------------------------------------------------------------------
|
|
193
|
-
export function countryColumn<Row extends object, ColumnId extends string>(
|
|
194
|
-
lookup: (item: Row) => { name: string; code: string },
|
|
195
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
196
|
-
): DataTableColumn<Row, ColumnId> {
|
|
197
|
-
return {
|
|
198
|
-
width: Math.max(definition.title.length * 10, 200),
|
|
199
|
-
sortComparator: (row1, row2, direction) => compare(lookup(row1).name, lookup(row2).name, direction),
|
|
200
|
-
...definition,
|
|
201
|
-
toCell: (item) => ({
|
|
202
|
-
kind: GridCellKind.Custom,
|
|
203
|
-
data: { kind: 'country', ...lookup(item) },
|
|
204
|
-
copyData: lookup(item).name,
|
|
205
|
-
displayData: lookup(item).name,
|
|
206
|
-
allowOverlay: false,
|
|
207
|
-
themeOverride: definition.themeOverride?.(item),
|
|
208
|
-
}),
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// COUNTRY ARRAY ----------------------------------------------------------------
|
|
213
|
-
export function countryArrayColumn<Row extends object, ColumnId extends string>(
|
|
214
|
-
lookup: (item: Row) => { code: string; label: string; hoverLabel?: string }[],
|
|
215
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
216
|
-
): DataTableColumn<Row, ColumnId> {
|
|
217
|
-
return {
|
|
218
|
-
width: Math.max(definition.title.length * 10, 200),
|
|
219
|
-
sortComparator: (row1, row2, direction) =>
|
|
220
|
-
compare(lookup(row1)[0]?.label ?? '', lookup(row2)[0]?.label ?? '', direction),
|
|
221
|
-
...definition,
|
|
222
|
-
toCell: (item) => {
|
|
223
|
-
const values = lookup(item)
|
|
224
|
-
return {
|
|
225
|
-
kind: GridCellKind.Custom,
|
|
226
|
-
allowOverlay: true,
|
|
227
|
-
copyData: values.map((v) => v.label).join(', '),
|
|
228
|
-
data: {
|
|
229
|
-
kind: 'country-array-cell',
|
|
230
|
-
countries: values.map((v) => ({ id: v.code, label: v.label, hoverLabel: v.hoverLabel })),
|
|
231
|
-
rowData: item,
|
|
232
|
-
},
|
|
233
|
-
themeOverride: definition.themeOverride?.(item),
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// INLINE BAR ------------------------------------------------------------------
|
|
240
|
-
export function inlineBarChartColumn<Row extends object, ColumnId extends string>(
|
|
241
|
-
lookup: (item: Row) => number[],
|
|
242
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
243
|
-
): DataTableColumn<Row, ColumnId> {
|
|
244
|
-
return {
|
|
245
|
-
sortComparator: () => 0, // No sorting for inline bar charts
|
|
246
|
-
...definition,
|
|
247
|
-
toCell: (item: Row) => ({
|
|
248
|
-
kind: GridCellKind.Custom,
|
|
249
|
-
data: { kind: 'inline-bar-chart', datapoints: lookup(item) },
|
|
250
|
-
copyData: lookup(item).join(', '),
|
|
251
|
-
allowOverlay: false,
|
|
252
|
-
themeOverride: definition.themeOverride?.(item),
|
|
253
|
-
}),
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// FAVORITE -------------------------------------------------------------------
|
|
258
|
-
export function favoriteColumn<Row extends object, ColumnId extends string>(
|
|
259
|
-
lookup: (item: Row) => boolean,
|
|
260
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
261
|
-
): DataTableColumn<Row, ColumnId> {
|
|
262
|
-
return {
|
|
263
|
-
width: definition.title.length * 10,
|
|
264
|
-
sortComparator: () => 0, // No sorting for favorites
|
|
265
|
-
...definition,
|
|
266
|
-
toCell: (item) => ({
|
|
267
|
-
kind: GridCellKind.Custom,
|
|
268
|
-
allowOverlay: false,
|
|
269
|
-
data: { kind: 'favorite', isFavorite: lookup(item), rowData: item, isSelected: definition.isSelected?.(item) },
|
|
270
|
-
copyData: lookup(item) ? 'true' : 'false',
|
|
271
|
-
onClick: definition.onClick,
|
|
272
|
-
themeOverride: definition.themeOverride?.(item),
|
|
273
|
-
}),
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
export function compare(
|
|
278
|
-
value1: string | number | null | undefined,
|
|
279
|
-
value2: string | number | null | undefined,
|
|
280
|
-
direction: 'asc' | 'desc' | null,
|
|
281
|
-
): number {
|
|
282
|
-
if (direction === null) {
|
|
283
|
-
return 0
|
|
284
|
-
}
|
|
285
|
-
if (value1 === null || value1 === undefined) {
|
|
286
|
-
return direction === 'asc' ? -1 : 1
|
|
287
|
-
}
|
|
288
|
-
if (value2 === null || value2 === undefined) {
|
|
289
|
-
return direction === 'asc' ? 1 : -1
|
|
290
|
-
}
|
|
291
|
-
if (value1 < value2) {
|
|
292
|
-
return direction === 'asc' ? -1 : 1
|
|
293
|
-
}
|
|
294
|
-
if (value1 > value2) {
|
|
295
|
-
return direction === 'asc' ? 1 : -1
|
|
296
|
-
}
|
|
297
|
-
return 0
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export type FrontendSort<Row extends object, Fieldname extends string> =
|
|
301
|
-
| { order: null; field: null }
|
|
302
|
-
| {
|
|
303
|
-
order: 'asc' | 'desc'
|
|
304
|
-
sortComparator: (row1: Row, row2: Row, direction: 'asc' | 'desc' | null) => number
|
|
305
|
-
field: Fieldname
|
|
306
|
-
}
|
|
307
|
-
export function sortData<Row extends object, Fieldname extends string>(
|
|
308
|
-
sortConfig: FrontendSort<Row, Fieldname>,
|
|
309
|
-
data: Row[],
|
|
310
|
-
): Row[] {
|
|
311
|
-
if (!sortConfig.order) {
|
|
312
|
-
return data
|
|
313
|
-
}
|
|
314
|
-
return data.toSorted((a, b) => {
|
|
315
|
-
return sortConfig.sortComparator(a, b, sortConfig.order)
|
|
316
|
-
})
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// DATE ------------------------------------------------------------------------
|
|
320
|
-
type FallbackValue = {
|
|
321
|
-
/**
|
|
322
|
-
* Default value to use when the number is null or undefined.
|
|
323
|
-
* Defaults to an empty string.
|
|
324
|
-
* @default ''
|
|
325
|
-
* @example '-', '0.00', 'N/A'
|
|
326
|
-
*/
|
|
327
|
-
fallback: string
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
export function dateColumn<Row extends object, ColumnId extends string>(
|
|
331
|
-
lookup: (item: Row) => Date | null | undefined,
|
|
332
|
-
definition: ColumnDefinition<Row, ColumnId>,
|
|
333
|
-
format: Intl.DateTimeFormatOptions & FallbackValue = {
|
|
334
|
-
year: 'numeric',
|
|
335
|
-
month: '2-digit',
|
|
336
|
-
day: '2-digit',
|
|
337
|
-
fallback: '',
|
|
338
|
-
},
|
|
339
|
-
): DataTableColumn<Row, ColumnId> {
|
|
340
|
-
return {
|
|
341
|
-
width: definition.title.length * 10,
|
|
342
|
-
sortComparator: () => 0, // TODO: implement sorting for dates later
|
|
343
|
-
...definition,
|
|
344
|
-
toCell: (item) => {
|
|
345
|
-
const date = lookup(item)
|
|
346
|
-
const formattedDate = date ? date.toLocaleDateString(undefined, format) : format.fallback
|
|
347
|
-
|
|
348
|
-
return { kind: GridCellKind.Text, data: formattedDate, allowOverlay: false, displayData: formattedDate }
|
|
349
|
-
},
|
|
350
|
-
}
|
|
351
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Theme } from '@context-providers/theme-context-provider'
|
|
2
|
-
import type { CustomCell, CustomRenderer } from '@glideapps/glide-data-grid'
|
|
3
|
-
|
|
4
|
-
const cache: Record<string, string> = {}
|
|
5
|
-
export function cssVarToTableString(name: string, theme: Theme) {
|
|
6
|
-
const themeName = `${theme}_${name}`
|
|
7
|
-
|
|
8
|
-
if (!(themeName in cache) || cache[themeName] === '' || cache[themeName] === undefined) {
|
|
9
|
-
let value = getComputedStyle(document.documentElement).getPropertyValue(name).trim()
|
|
10
|
-
// Convert numeric font-weight to keyword if variable name suggests font-weight
|
|
11
|
-
if (name.includes('font-weight')) {
|
|
12
|
-
value = value === '700' ? 'bold' : 'normal'
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
cache[themeName] = value
|
|
16
|
-
}
|
|
17
|
-
return cache[themeName]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const getTableTheme = (theme: Theme) => ({
|
|
21
|
-
bgHeader: cssVarToTableString('--background', theme),
|
|
22
|
-
bgHeaderHovered: cssVarToTableString('--background', theme),
|
|
23
|
-
bgHeaderHasFocus: cssVarToTableString('--background', theme),
|
|
24
|
-
bgCell: cssVarToTableString('--background', theme),
|
|
25
|
-
accentColor: 'transparent',
|
|
26
|
-
textHeaderSelected: cssVarToTableString('--foreground', theme),
|
|
27
|
-
textGroupHeader: cssVarToTableString('--foreground', theme),
|
|
28
|
-
textHeader: cssVarToTableString('--foreground', theme),
|
|
29
|
-
textLight: cssVarToTableString('--background', theme),
|
|
30
|
-
textDark: cssVarToTableString('--table-foreground', theme),
|
|
31
|
-
textMedium: cssVarToTableString('--muted-foreground', theme),
|
|
32
|
-
|
|
33
|
-
accentLight: cssVarToTableString('--background', theme),
|
|
34
|
-
linkColor: cssVarToTableString('--primary', theme),
|
|
35
|
-
drilldownBorder: cssVarToTableString('--background', theme),
|
|
36
|
-
cellHorizontalPadding: 15,
|
|
37
|
-
headerFontStyle: `${cssVarToTableString('--font-weight-bold', theme)} ${cssVarToTableString('--text-base', theme)}`,
|
|
38
|
-
baseFontStyle: `${cssVarToTableString('--font-weight-medium', theme)} ${cssVarToTableString('--text-base', theme)}`,
|
|
39
|
-
|
|
40
|
-
fontFamily: 'Helvetica, sans-serif',
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
export type HoverableRenderer<T extends CustomCell = CustomCell> = {
|
|
44
|
-
hoverOverlay?: (cellData: T['data']) => React.ReactNode
|
|
45
|
-
} & CustomRenderer<T>
|
|
46
|
-
|
|
47
|
-
export function isHoverableRenderer(r: any): r is { hoverOverlay: (data: any) => React.ReactNode } {
|
|
48
|
-
return typeof r?.hoverOverlay === 'function'
|
|
49
|
-
}
|