@pilotiq/pilotiq 0.23.1 → 0.24.2
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/CHANGELOG.md +91 -0
- package/boost/guidelines.md +566 -0
- package/boost/skills/pilotiq-fields/SKILL.md +47 -0
- package/boost/skills/pilotiq-fields/rules/field-catalog.md +288 -0
- package/boost/skills/pilotiq-fields/rules/reactive-fields.md +199 -0
- package/boost/skills/pilotiq-fields/rules/validation.md +198 -0
- package/boost/skills/pilotiq-relations/SKILL.md +47 -0
- package/boost/skills/pilotiq-relations/rules/relation-managers.md +256 -0
- package/boost/skills/pilotiq-relations/rules/repeater-relationship.md +177 -0
- package/boost/skills/pilotiq-resource/SKILL.md +61 -0
- package/boost/skills/pilotiq-resource/rules/authorization.md +242 -0
- package/boost/skills/pilotiq-resource/rules/defining-resources.md +228 -0
- package/boost/skills/pilotiq-resource/rules/page-overrides.md +296 -0
- package/dist/actions/exportFactory.d.ts +10 -0
- package/dist/actions/exportFactory.d.ts.map +1 -1
- package/dist/actions/exportFactory.js +10 -0
- package/dist/actions/exportFactory.js.map +1 -1
- package/dist/react/CollabRoomContext.d.ts +5 -5
- package/dist/react/index.d.ts +0 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +0 -1
- package/dist/react/index.js.map +1 -1
- package/dist/routes/helpers.d.ts.map +1 -1
- package/dist/routes/helpers.js +6 -2
- package/dist/routes/helpers.js.map +1 -1
- package/dist/routes/relations.d.ts.map +1 -1
- package/dist/routes/relations.js +12 -0
- package/dist/routes/relations.js.map +1 -1
- package/package.json +6 -1
- package/.turbo/turbo-build.log +0 -8
- package/CLAUDE.md +0 -265
- package/dist/react/useCollabSeed.d.ts +0 -23
- package/dist/react/useCollabSeed.d.ts.map +0 -1
- package/dist/react/useCollabSeed.js +0 -82
- package/dist/react/useCollabSeed.js.map +0 -1
- package/src/Cluster.test.ts +0 -283
- package/src/Cluster.ts +0 -83
- package/src/Column.test.ts +0 -199
- package/src/Column.ts +0 -710
- package/src/Global.test.ts +0 -367
- package/src/Global.ts +0 -169
- package/src/Page.test.ts +0 -114
- package/src/Page.ts +0 -208
- package/src/Pilotiq.perf.test.ts +0 -252
- package/src/Pilotiq.test.ts +0 -129
- package/src/Pilotiq.ts +0 -1158
- package/src/PilotiqRegistry.ts +0 -36
- package/src/PilotiqServiceProvider.ts +0 -121
- package/src/RelationManager.test.ts +0 -400
- package/src/RelationManager.ts +0 -527
- package/src/RenderHook.test.ts +0 -252
- package/src/RenderHook.ts +0 -242
- package/src/Resource.test.ts +0 -284
- package/src/Resource.ts +0 -526
- package/src/RightPanel.test.ts +0 -202
- package/src/RightPanel.ts +0 -132
- package/src/Tab.test.ts +0 -91
- package/src/Tab.ts +0 -156
- package/src/UserMenuItem.ts +0 -145
- package/src/actions/Action.test.ts +0 -2526
- package/src/actions/Action.ts +0 -1515
- package/src/actions/ActionGroup.test.ts +0 -112
- package/src/actions/ActionGroup.ts +0 -173
- package/src/actions/attachFactory.ts +0 -172
- package/src/actions/bulkFactories.ts +0 -168
- package/src/actions/crudFactories.ts +0 -220
- package/src/actions/exportFactory.ts +0 -215
- package/src/actions/factoryHelpers.ts +0 -177
- package/src/actions/importFactory.ts +0 -243
- package/src/actions/index.ts +0 -17
- package/src/actions/m2mFactories.ts +0 -193
- package/src/actions/relationFactories.ts +0 -372
- package/src/applyPageHooks.test.ts +0 -463
- package/src/applyPageHooks.ts +0 -330
- package/src/authorization.test.ts +0 -483
- package/src/breadcrumbs.test.ts +0 -238
- package/src/cells/coerce.test.ts +0 -85
- package/src/cells/coerce.ts +0 -84
- package/src/clusterPaths.ts +0 -35
- package/src/columns/BadgeColumn.test.ts +0 -54
- package/src/columns/BadgeColumn.ts +0 -32
- package/src/columns/BooleanColumn.test.ts +0 -41
- package/src/columns/BooleanColumn.ts +0 -18
- package/src/columns/ColorColumn.test.ts +0 -37
- package/src/columns/ColorColumn.ts +0 -38
- package/src/columns/IconColumn.test.ts +0 -54
- package/src/columns/IconColumn.ts +0 -37
- package/src/columns/ImageColumn.test.ts +0 -41
- package/src/columns/ImageColumn.ts +0 -28
- package/src/columns/SelectColumn.ts +0 -98
- package/src/columns/TextColumn.test.ts +0 -190
- package/src/columns/TextColumn.ts +0 -20
- package/src/columns/TextInputColumn.ts +0 -68
- package/src/columns/ToggleColumn.ts +0 -46
- package/src/columns/editableColumns.test.ts +0 -238
- package/src/columns/index.ts +0 -9
- package/src/defaultGlobalPages.ts +0 -95
- package/src/defaultPages.test.ts +0 -634
- package/src/defaultPages.ts +0 -617
- package/src/defaultViewPage.test.ts +0 -147
- package/src/elements/Form.test.ts +0 -223
- package/src/elements/Form.ts +0 -416
- package/src/elements/ListTabs.ts +0 -28
- package/src/elements/Table.test.ts +0 -422
- package/src/elements/Table.ts +0 -850
- package/src/elements/TableGroup.test.ts +0 -260
- package/src/elements/TableGroup.ts +0 -334
- package/src/elements/dispatchAction.test.ts +0 -463
- package/src/elements/dispatchAction.ts +0 -355
- package/src/elements/dispatchForm.test.ts +0 -477
- package/src/elements/dispatchForm.ts +0 -1993
- package/src/elements/dispatchTable.test.ts +0 -1514
- package/src/elements/dispatchTable.ts +0 -745
- package/src/elements/index.ts +0 -21
- package/src/entries/BadgeEntry.ts +0 -39
- package/src/entries/CodeEntry.test.ts +0 -40
- package/src/entries/CodeEntry.ts +0 -52
- package/src/entries/ColorEntry.ts +0 -63
- package/src/entries/ComponentEntry.test.ts +0 -173
- package/src/entries/ComponentEntry.ts +0 -95
- package/src/entries/Entry.ts +0 -304
- package/src/entries/IconEntry.ts +0 -49
- package/src/entries/ImageEntry.ts +0 -61
- package/src/entries/KeyValueEntry.ts +0 -47
- package/src/entries/RepeatableEntry.test.ts +0 -239
- package/src/entries/RepeatableEntry.ts +0 -173
- package/src/entries/TextEntry.test.ts +0 -394
- package/src/entries/TextEntry.ts +0 -60
- package/src/entries/index.ts +0 -12
- package/src/entries/leaves.test.ts +0 -306
- package/src/entries/registry.ts +0 -54
- package/src/fields/BuilderField.test.ts +0 -1188
- package/src/fields/BuilderField.ts +0 -605
- package/src/fields/BuilderRelationship.test.ts +0 -811
- package/src/fields/CheckboxField.test.ts +0 -44
- package/src/fields/CheckboxField.ts +0 -27
- package/src/fields/CheckboxListField.test.ts +0 -99
- package/src/fields/CheckboxListField.ts +0 -66
- package/src/fields/ColorPickerField.test.ts +0 -33
- package/src/fields/ColorPickerField.ts +0 -25
- package/src/fields/DateField.ts +0 -54
- package/src/fields/DateTimeField.test.ts +0 -55
- package/src/fields/EmailField.ts +0 -16
- package/src/fields/Field.test.ts +0 -654
- package/src/fields/Field.ts +0 -817
- package/src/fields/FileUploadField.test.ts +0 -143
- package/src/fields/FileUploadField.ts +0 -159
- package/src/fields/HiddenField.test.ts +0 -27
- package/src/fields/HiddenField.ts +0 -28
- package/src/fields/KeyValueField.test.ts +0 -105
- package/src/fields/KeyValueField.ts +0 -55
- package/src/fields/MarkdownField.test.ts +0 -167
- package/src/fields/MarkdownField.ts +0 -162
- package/src/fields/NumberField.ts +0 -33
- package/src/fields/RadioField.test.ts +0 -94
- package/src/fields/RadioField.ts +0 -67
- package/src/fields/RepeaterField.test.ts +0 -1806
- package/src/fields/RepeaterField.ts +0 -939
- package/src/fields/RepeaterRelationship.test.ts +0 -1923
- package/src/fields/RepeaterSimple.test.ts +0 -248
- package/src/fields/RowButton.test.ts +0 -219
- package/src/fields/RowButton.ts +0 -135
- package/src/fields/SelectField.test.ts +0 -192
- package/src/fields/SelectField.ts +0 -235
- package/src/fields/SliderField.test.ts +0 -50
- package/src/fields/SliderField.ts +0 -53
- package/src/fields/SlugField.ts +0 -24
- package/src/fields/TagsInputField.test.ts +0 -154
- package/src/fields/TagsInputField.ts +0 -133
- package/src/fields/TextField.test.ts +0 -213
- package/src/fields/TextField.ts +0 -177
- package/src/fields/TextareaField.test.ts +0 -58
- package/src/fields/TextareaField.ts +0 -59
- package/src/fields/ToggleButtonsField.test.ts +0 -106
- package/src/fields/ToggleButtonsField.ts +0 -59
- package/src/fields/ToggleField.ts +0 -16
- package/src/fields/disableOptionsWhenSelectedInSiblingRepeaterItems.test.ts +0 -319
- package/src/fields/optionsResolver.ts +0 -95
- package/src/fields/resolveField.ts +0 -28
- package/src/filters/BooleanFilter.ts +0 -35
- package/src/filters/DateRangeFilter.test.ts +0 -194
- package/src/filters/DateRangeFilter.ts +0 -148
- package/src/filters/Filter.test.ts +0 -268
- package/src/filters/Filter.ts +0 -184
- package/src/filters/FormFilter.test.ts +0 -238
- package/src/filters/FormFilter.ts +0 -215
- package/src/filters/MultiSelectFilter.test.ts +0 -119
- package/src/filters/MultiSelectFilter.ts +0 -78
- package/src/filters/QueryBuilderFilter.test.ts +0 -662
- package/src/filters/QueryBuilderFilter.ts +0 -398
- package/src/filters/SelectFilter.ts +0 -46
- package/src/filters/TernaryFilter.test.ts +0 -160
- package/src/filters/TernaryFilter.ts +0 -72
- package/src/filters/TrashedFilter.test.ts +0 -149
- package/src/filters/TrashedFilter.ts +0 -55
- package/src/filters/queryBuilder/BooleanConstraint.ts +0 -31
- package/src/filters/queryBuilder/Constraint.ts +0 -115
- package/src/filters/queryBuilder/DateConstraint.ts +0 -69
- package/src/filters/queryBuilder/NumberConstraint.ts +0 -66
- package/src/filters/queryBuilder/SelectConstraint.ts +0 -72
- package/src/filters/queryBuilder/TextConstraint.ts +0 -64
- package/src/filters/queryBuilder/index.ts +0 -12
- package/src/icons/index.ts +0 -2
- package/src/icons/lucide.ts +0 -204
- package/src/icons/registry.test.ts +0 -56
- package/src/icons/registry.ts +0 -41
- package/src/icons/types.ts +0 -47
- package/src/index.ts +0 -525
- package/src/io/csv.test.ts +0 -142
- package/src/io/csv.ts +0 -170
- package/src/nestedRelationManagerData.test.ts +0 -547
- package/src/notifications/Notification.test.ts +0 -210
- package/src/notifications/Notification.ts +0 -354
- package/src/notifications/broadcast.test.ts +0 -110
- package/src/notifications/broadcast.ts +0 -95
- package/src/notifications/database.test.ts +0 -383
- package/src/notifications/database.ts +0 -398
- package/src/notifications/databaseNotifications.test.ts +0 -187
- package/src/notifications/dispatchNotificationAction.test.ts +0 -341
- package/src/notifications/dispatchNotificationAction.ts +0 -142
- package/src/notifications/flash.test.ts +0 -89
- package/src/notifications/flash.ts +0 -71
- package/src/notifications/index.ts +0 -45
- package/src/notifications/registerBroadcastAuth.test.ts +0 -134
- package/src/notifications/registerBroadcastAuth.ts +0 -100
- package/src/notifications/resolveSavedNotification.test.ts +0 -82
- package/src/notifications/resolveSavedNotification.ts +0 -59
- package/src/notifications/types.ts +0 -93
- package/src/orm/m2mAccessor.ts +0 -66
- package/src/orm/modelDefaults.test.ts +0 -633
- package/src/orm/modelDefaults.ts +0 -666
- package/src/pageData/breadcrumbs.ts +0 -288
- package/src/pageData/forms.ts +0 -578
- package/src/pageData/helpers.ts +0 -857
- package/src/pageData/misc.ts +0 -347
- package/src/pageData/navigation.ts +0 -842
- package/src/pageData/relationPages.ts +0 -1248
- package/src/pageData/relationTabs.ts +0 -286
- package/src/pageData/resourcePages.ts +0 -609
- package/src/pageData.test.ts +0 -1545
- package/src/pageData.ts +0 -341
- package/src/plugins/index.ts +0 -8
- package/src/plugins/themeEditor.test.ts +0 -36
- package/src/plugins/themeEditor.ts +0 -45
- package/src/react/AppShell.tsx +0 -251
- package/src/react/CollabExtensionFactoryRegistry.ts +0 -55
- package/src/react/CollabRoomContext.ts +0 -98
- package/src/react/CollabTextRendererRegistry.ts +0 -102
- package/src/react/CommandPalette.tsx +0 -375
- package/src/react/CurrentUserContext.tsx +0 -50
- package/src/react/CustomPageWrapperGate.tsx +0 -69
- package/src/react/CustomPageWrapperRegistry.ts +0 -45
- package/src/react/FieldFocusReporterRegistry.ts +0 -37
- package/src/react/FieldLabelSlotRegistry.ts +0 -30
- package/src/react/FieldPresenceRegistry.ts +0 -46
- package/src/react/FormCollabBindingRegistry.ts +0 -242
- package/src/react/FormStateContext.tsx +0 -591
- package/src/react/HeadHooks.tsx +0 -126
- package/src/react/MarkdownEditorRegistry.test.ts +0 -38
- package/src/react/MarkdownEditorRegistry.ts +0 -107
- package/src/react/NotificationActionStrip.tsx +0 -263
- package/src/react/NotificationBell.tsx +0 -426
- package/src/react/PendingSuggestionApplierRegistry.test.ts +0 -97
- package/src/react/PendingSuggestionApplierRegistry.ts +0 -98
- package/src/react/PendingSuggestionOverlayRegistry.ts +0 -54
- package/src/react/PendingSuggestionsContext.tsx +0 -172
- package/src/react/RecordWrapperGate.tsx +0 -58
- package/src/react/RecordWrapperRegistry.ts +0 -39
- package/src/react/RenderHookSlot.tsx +0 -32
- package/src/react/RightSidebar.tsx +0 -257
- package/src/react/RightSidebarContext.tsx +0 -234
- package/src/react/RightSidebarTrigger.tsx +0 -53
- package/src/react/RowCoordsContext.tsx +0 -23
- package/src/react/SchemaRenderer.tsx +0 -549
- package/src/react/SearchTrigger.tsx +0 -46
- package/src/react/ThemeProvider.tsx +0 -93
- package/src/react/ThemeSettingsPage.tsx +0 -579
- package/src/react/ThemeToggle.tsx +0 -20
- package/src/react/Toaster.tsx +0 -158
- package/src/react/UserMenu.tsx +0 -196
- package/src/react/WidgetDataContext.tsx +0 -157
- package/src/react/cells/EditableCell.tsx +0 -389
- package/src/react/component-slots.test.ts +0 -103
- package/src/react/component-slots.ts +0 -116
- package/src/react/fieldJsHandler.test.ts +0 -166
- package/src/react/fieldJsHandler.ts +0 -79
- package/src/react/fields/BuilderInput.tsx +0 -1078
- package/src/react/fields/CheckboxInput.tsx +0 -39
- package/src/react/fields/CheckboxListInput.tsx +0 -102
- package/src/react/fields/ColorInput.tsx +0 -71
- package/src/react/fields/DateFieldInput.tsx +0 -70
- package/src/react/fields/DateTimeInput.tsx +0 -62
- package/src/react/fields/FieldShell.tsx +0 -348
- package/src/react/fields/FileUploadInput.tsx +0 -639
- package/src/react/fields/HiddenInput.tsx +0 -17
- package/src/react/fields/KeyValueInput.tsx +0 -230
- package/src/react/fields/MarkdownInput.tsx +0 -560
- package/src/react/fields/RadioInput.tsx +0 -81
- package/src/react/fields/RepeaterInput.test.ts +0 -116
- package/src/react/fields/RepeaterInput.tsx +0 -1420
- package/src/react/fields/SelectFieldInput.tsx +0 -280
- package/src/react/fields/SliderInput.tsx +0 -81
- package/src/react/fields/TagsInput.tsx +0 -283
- package/src/react/fields/TextLikeInput.tsx +0 -256
- package/src/react/fields/ToggleButtonsInput.tsx +0 -60
- package/src/react/fields/ToggleFieldInput.tsx +0 -56
- package/src/react/fields/relationshipRenameDispatch.test.ts +0 -106
- package/src/react/fields/relationshipRenameDispatch.ts +0 -97
- package/src/react/fields/repeaterReconcile.test.ts +0 -114
- package/src/react/fields/repeaterReconcile.ts +0 -104
- package/src/react/fields/rowChromeButton.tsx +0 -336
- package/src/react/fields/rowState.ts +0 -106
- package/src/react/fields/syncRowGates.test.ts +0 -202
- package/src/react/fields/syncRowGates.ts +0 -66
- package/src/react/fields/textInputControls.tsx +0 -238
- package/src/react/fields/useRowReorderDnd.ts +0 -78
- package/src/react/formStateHelpers.test.ts +0 -508
- package/src/react/formStateHelpers.ts +0 -381
- package/src/react/hooks/use-mobile.ts +0 -19
- package/src/react/icon-context.tsx +0 -60
- package/src/react/index.ts +0 -195
- package/src/react/layouts/SidebarLayout.tsx +0 -250
- package/src/react/layouts/TopbarLayout.tsx +0 -258
- package/src/react/navigate.tsx +0 -37
- package/src/react/onProviderSynced.test.ts +0 -90
- package/src/react/parseRecordEditUrl.test.ts +0 -122
- package/src/react/parseRecordEditUrl.ts +0 -94
- package/src/react/persistedState.ts +0 -40
- package/src/react/registry.ts +0 -48
- package/src/react/right-panel-registry.tsx +0 -47
- package/src/react/schemaRenderer/AlertRenderer.tsx +0 -112
- package/src/react/schemaRenderer/EntryRenderer.tsx +0 -501
- package/src/react/schemaRenderer/SectionRenderer.tsx +0 -120
- package/src/react/schemaRenderer/SimpleElements.tsx +0 -306
- package/src/react/schemaRenderer/TabsRenderer.tsx +0 -62
- package/src/react/schemaRenderer/WizardRenderer.tsx +0 -338
- package/src/react/schemaRenderer/action/ActionGroupTrigger.tsx +0 -177
- package/src/react/schemaRenderer/action/ActionModalDialog.tsx +0 -273
- package/src/react/schemaRenderer/action/ConfirmActionDialog.tsx +0 -61
- package/src/react/schemaRenderer/action/HandlerActionButton.tsx +0 -43
- package/src/react/schemaRenderer/action/MethodActionButton.tsx +0 -64
- package/src/react/schemaRenderer/action/buttons.tsx +0 -99
- package/src/react/schemaRenderer/action/helpers.ts +0 -140
- package/src/react/schemaRenderer/action/renderAction.tsx +0 -245
- package/src/react/schemaRenderer/columnFormat.ts +0 -65
- package/src/react/schemaRenderer/constants.ts +0 -50
- package/src/react/schemaRenderer/form/FormRenderer.tsx +0 -274
- package/src/react/schemaRenderer/form/renderField.tsx +0 -511
- package/src/react/schemaRenderer/helpers.tsx +0 -81
- package/src/react/schemaRenderer/table/CardsLayoutBody.tsx +0 -308
- package/src/react/schemaRenderer/table/TableRenderer.tsx +0 -123
- package/src/react/schemaRenderer/table/TableRendererBody.tsx +0 -974
- package/src/react/schemaRenderer/table/filters.tsx +0 -1233
- package/src/react/schemaRenderer/table/formatCell.tsx +0 -264
- package/src/react/schemaRenderer/table/links.tsx +0 -112
- package/src/react/schemaRenderer/table/renderRowActions.tsx +0 -52
- package/src/react/schemaRenderer/table/url.tsx +0 -143
- package/src/react/theme-preview/apply.ts +0 -99
- package/src/react/theme-preview/build-html.ts +0 -436
- package/src/react/ui/button.tsx +0 -51
- package/src/react/ui/calendar.tsx +0 -67
- package/src/react/ui/checkbox.tsx +0 -29
- package/src/react/ui/dialog.tsx +0 -108
- package/src/react/ui/dropdown-menu.tsx +0 -97
- package/src/react/ui/input.tsx +0 -20
- package/src/react/ui/label.tsx +0 -21
- package/src/react/ui/popover.tsx +0 -50
- package/src/react/ui/select.tsx +0 -169
- package/src/react/ui/separator.tsx +0 -25
- package/src/react/ui/sheet.tsx +0 -136
- package/src/react/ui/sidebar.tsx +0 -723
- package/src/react/ui/skeleton.tsx +0 -13
- package/src/react/ui/slider.tsx +0 -34
- package/src/react/ui/switch.tsx +0 -28
- package/src/react/ui/table.tsx +0 -105
- package/src/react/ui/tabs.tsx +0 -63
- package/src/react/ui/textarea.tsx +0 -18
- package/src/react/ui/tooltip.tsx +0 -64
- package/src/react/useCollabSeed.ts +0 -86
- package/src/react/useResizableWidth.ts +0 -139
- package/src/react/utils.ts +0 -6
- package/src/react/widgetRegistry.test.ts +0 -43
- package/src/react/widgetRegistry.ts +0 -50
- package/src/react/widgets/StatsOverviewRenderer.tsx +0 -232
- package/src/react/widgets/TableWidgetRenderer.tsx +0 -231
- package/src/react/widgets/ViewRenderer.tsx +0 -71
- package/src/relationManagerData.test.ts +0 -1595
- package/src/richtext/index.ts +0 -8
- package/src/richtext/registry.ts +0 -89
- package/src/routes/globals.ts +0 -148
- package/src/routes/guard.test.ts +0 -325
- package/src/routes/helpers.ts +0 -700
- package/src/routes/pages.ts +0 -175
- package/src/routes/panel.ts +0 -204
- package/src/routes/relations.ts +0 -1227
- package/src/routes/resources.ts +0 -781
- package/src/routes/theme.ts +0 -91
- package/src/routes-nested-relations.test.ts +0 -676
- package/src/routes-relations.test.ts +0 -972
- package/src/routes.test.ts +0 -2027
- package/src/routes.ts +0 -303
- package/src/schema/Alert.test.ts +0 -109
- package/src/schema/Alert.ts +0 -131
- package/src/schema/Block.ts +0 -169
- package/src/schema/Breadcrumbs.ts +0 -40
- package/src/schema/Card.ts +0 -35
- package/src/schema/Divider.ts +0 -20
- package/src/schema/Element.ts +0 -219
- package/src/schema/EmptyState.test.ts +0 -37
- package/src/schema/EmptyState.ts +0 -63
- package/src/schema/Fieldset.ts +0 -43
- package/src/schema/Grid.ts +0 -43
- package/src/schema/Group.ts +0 -30
- package/src/schema/Heading.ts +0 -39
- package/src/schema/Html.ts +0 -67
- package/src/schema/Icon.ts +0 -54
- package/src/schema/Image.ts +0 -57
- package/src/schema/LinkTag.ts +0 -41
- package/src/schema/Markdown.ts +0 -85
- package/src/schema/MetaTag.ts +0 -41
- package/src/schema/RelationTabs.ts +0 -71
- package/src/schema/ScriptTag.ts +0 -55
- package/src/schema/Section.ts +0 -160
- package/src/schema/ServerDataElement.test.ts +0 -140
- package/src/schema/ServerDataElement.ts +0 -156
- package/src/schema/SlotComponent.test.ts +0 -77
- package/src/schema/SlotComponent.ts +0 -71
- package/src/schema/Split.ts +0 -50
- package/src/schema/Stat.test.ts +0 -118
- package/src/schema/Stat.ts +0 -154
- package/src/schema/StatsOverview.test.ts +0 -141
- package/src/schema/StatsOverview.ts +0 -119
- package/src/schema/StyleTag.ts +0 -35
- package/src/schema/TableWidget.test.ts +0 -297
- package/src/schema/TableWidget.ts +0 -289
- package/src/schema/Tabs.ts +0 -79
- package/src/schema/Text.ts +0 -58
- package/src/schema/UnorderedList.ts +0 -49
- package/src/schema/View.test.ts +0 -111
- package/src/schema/View.ts +0 -127
- package/src/schema/Wizard.ts +0 -220
- package/src/schema/containers.test.ts +0 -564
- package/src/schema/headTags.test.ts +0 -134
- package/src/schema/index.ts +0 -40
- package/src/schema/primes.test.ts +0 -269
- package/src/schema/resolveSchema.test.ts +0 -379
- package/src/schema/resolveSchema.ts +0 -917
- package/src/schema/sanitize.ts +0 -58
- package/src/search.test.ts +0 -446
- package/src/search.ts +0 -178
- package/src/sessionFilters.test.ts +0 -375
- package/src/sessionFilters.ts +0 -143
- package/src/slot-components/index.ts +0 -10
- package/src/slot-components/registry.ts +0 -56
- package/src/styles/file-upload.css +0 -13
- package/src/summarizers/Summarizer.test.ts +0 -84
- package/src/summarizers/Summarizer.ts +0 -123
- package/src/summarizers/index.ts +0 -11
- package/src/theme/base-colors.ts +0 -68
- package/src/theme/chart-colors.ts +0 -50
- package/src/theme/colors.ts +0 -447
- package/src/theme/generate-css.test.ts +0 -139
- package/src/theme/generate-css.ts +0 -44
- package/src/theme/generate-scale.test.ts +0 -106
- package/src/theme/generate-scale.ts +0 -97
- package/src/theme/icon-map.ts +0 -42
- package/src/theme/index.ts +0 -34
- package/src/theme/migrate.test.ts +0 -178
- package/src/theme/migrate.ts +0 -81
- package/src/theme/presets.ts +0 -135
- package/src/theme/radius.ts +0 -18
- package/src/theme/resolve.test.ts +0 -238
- package/src/theme/resolve.ts +0 -96
- package/src/theme/spacing.ts +0 -18
- package/src/theme/storage.test.ts +0 -126
- package/src/theme/storage.ts +0 -106
- package/src/theme/theme-colors.ts +0 -88
- package/src/theme/types.ts +0 -125
- package/src/uploads/UploadAdapter.ts +0 -35
- package/src/uploads/index.ts +0 -2
- package/src/uploads/localUpload.test.ts +0 -70
- package/src/uploads/localUpload.ts +0 -84
- package/src/validation/Validator.ts +0 -49
- package/src/validation/index.ts +0 -28
- package/src/validation/rules.ts +0 -78
- package/src/validation/runValidators.ts +0 -435
- package/src/validation/uniqueValidator.test.ts +0 -196
- package/src/validation/uniqueValidator.ts +0 -133
- package/src/validation/validators.test.ts +0 -268
- package/src/vite.test.ts +0 -184
- package/src/vite.ts +0 -787
- package/src/widgets/index.ts +0 -10
- package/src/widgets/registry.ts +0 -45
- package/src/widgets.test.ts +0 -592
- package/tsconfig.build.json +0 -11
- package/tsconfig.json +0 -4
- package/tsconfig.test.json +0 -10
- package/views/react/Dashboard.tsx +0 -27
- package/views/react/Resources/Form.tsx +0 -102
- package/views/react/Resources/Index.tsx +0 -49
package/src/Column.ts
DELETED
|
@@ -1,710 +0,0 @@
|
|
|
1
|
-
import { Element, type ElementMeta } from './schema/Element.js'
|
|
2
|
-
import { Summarizer, type SummarizerMeta } from './summarizers/Summarizer.js'
|
|
3
|
-
import type { SanitizeConfig } from './schema/sanitize.js'
|
|
4
|
-
import type {
|
|
5
|
-
Validator,
|
|
6
|
-
ValidatorContext,
|
|
7
|
-
SerializedRule,
|
|
8
|
-
} from './validation/Validator.js'
|
|
9
|
-
|
|
10
|
-
/** Cell content alignment. Maps to text-{start|center|end} on the cell. */
|
|
11
|
-
export type ColumnAlignment = 'start' | 'center' | 'end'
|
|
12
|
-
|
|
13
|
-
/** Visual variant. The default `text` covers most cases — formatters
|
|
14
|
-
* (dateTime / money / since / numeric / limit) layer on top.
|
|
15
|
-
* `badge` / `icon` / `boolean` / `image` are subclasses that change
|
|
16
|
-
* how the cell is *rendered* rather than just *formatted*.
|
|
17
|
-
* `textInput` / `toggle` / `select` are inline-edit subclasses — the
|
|
18
|
-
* renderer mounts an interactive control that PATCHes a single column
|
|
19
|
-
* via `POST {base}/{slug}/:id/_cell/:column`. */
|
|
20
|
-
export type ColumnType =
|
|
21
|
-
| 'text' | 'badge' | 'icon' | 'boolean' | 'image' | 'color'
|
|
22
|
-
| 'textInput' | 'toggle' | 'select'
|
|
23
|
-
|
|
24
|
-
/** Per-row predicate for `Column.disabled(fn)` — evaluated server-side
|
|
25
|
-
* inside `loadTableRecords` so the renderer just reads the result. */
|
|
26
|
-
export type ColumnDisabledFn = (record: Record<string, unknown>) => boolean
|
|
27
|
-
|
|
28
|
-
/** Context handed to `Column.beforeStateUpdated / afterStateUpdated`
|
|
29
|
-
* hooks on editable cell columns. `record` is the row as loaded
|
|
30
|
-
* *before* the update; `user` is the resolved panel user. */
|
|
31
|
-
export interface CellStateHookContext {
|
|
32
|
-
record: Record<string, unknown>
|
|
33
|
-
user?: unknown
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Hook signature for `Column.beforeStateUpdated / afterStateUpdated`.
|
|
37
|
-
* Return value is ignored — these are side-effect hooks. Throw an
|
|
38
|
-
* Error to halt the PATCH; the thrown message lands under `errors._cell`
|
|
39
|
-
* in the 422 response so the renderer can surface it next to the cell. */
|
|
40
|
-
export type CellStateHook = (
|
|
41
|
-
value: unknown,
|
|
42
|
-
ctx: CellStateHookContext,
|
|
43
|
-
) => void | Promise<void>
|
|
44
|
-
|
|
45
|
-
/** SelectColumn option shape — mirrors `SelectField`'s static option form. */
|
|
46
|
-
export interface ColumnSelectOption {
|
|
47
|
-
value: string
|
|
48
|
-
label: string
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Font weight preset — maps to a Tailwind `font-*` class. */
|
|
52
|
-
export type ColumnWeight = 'normal' | 'medium' | 'semibold' | 'bold'
|
|
53
|
-
|
|
54
|
-
/** Color preset for the cell text. `muted` greys the value. */
|
|
55
|
-
export type ColumnColor = 'default' | 'muted' | 'primary' | 'destructive' | 'success' | 'warning' | 'info'
|
|
56
|
-
|
|
57
|
-
/** Built-in formatters serialized to the client. `kind` drives the
|
|
58
|
-
* client-side switch; the rest of the fields carry per-kind options. */
|
|
59
|
-
export type ColumnFormat =
|
|
60
|
-
| { kind: 'dateTime'; pattern?: string }
|
|
61
|
-
| { kind: 'since' }
|
|
62
|
-
| { kind: 'money'; currency: string; locale?: string }
|
|
63
|
-
| { kind: 'numeric'; decimals?: number; locale?: string }
|
|
64
|
-
| { kind: 'limit'; chars: number }
|
|
65
|
-
| { kind: 'words'; words: number }
|
|
66
|
-
|
|
67
|
-
/** Rich-text column kind — server-rendered HTML stamped per row.
|
|
68
|
-
* Markdown values run through `marked` first; HTML values pass straight
|
|
69
|
-
* to `sanitize-html`. Both honor `_sanitize` (default `true`). */
|
|
70
|
-
export type ColumnRichTextKind = 'markdown' | 'html'
|
|
71
|
-
|
|
72
|
-
/** Per-row formatter callback. Returns the rendered cell content as a
|
|
73
|
-
* string. Runs server-side inside `loadTableRecords` (the function
|
|
74
|
-
* isn't serializable to the client). */
|
|
75
|
-
export type FormatStateHandler = (value: unknown, record: Record<string, unknown>) => string
|
|
76
|
-
|
|
77
|
-
/** Per-row record-URL callback. Returns the destination URL for clicks
|
|
78
|
-
* on this column's cell, or `undefined` to skip linking that row. Runs
|
|
79
|
-
* server-side inside `loadTableRecords`. */
|
|
80
|
-
export type ColumnRecordUrlHandler = (record: Record<string, unknown>) => string | undefined
|
|
81
|
-
|
|
82
|
-
/** Configuration for `Column.toggleable(...)`. The user can show / hide the
|
|
83
|
-
* column from a per-table dropdown; preference persists to localStorage so
|
|
84
|
-
* it survives reloads + SPA navs. `initiallyHidden` flips the default state
|
|
85
|
-
* so the column starts off-screen and the user opts in. */
|
|
86
|
-
export interface ColumnToggleableConfig {
|
|
87
|
-
initiallyHidden?: boolean
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export interface ColumnMeta extends ElementMeta {
|
|
91
|
-
type: 'column'
|
|
92
|
-
name: string
|
|
93
|
-
label: string
|
|
94
|
-
sortable: boolean
|
|
95
|
-
searchable: boolean
|
|
96
|
-
columnType?: ColumnType
|
|
97
|
-
alignment?: ColumnAlignment
|
|
98
|
-
width?: string
|
|
99
|
-
default?: string
|
|
100
|
-
tooltip?: string
|
|
101
|
-
wrap?: boolean
|
|
102
|
-
lineClamp?: number
|
|
103
|
-
weight?: ColumnWeight
|
|
104
|
-
color?: ColumnColor
|
|
105
|
-
format?: ColumnFormat
|
|
106
|
-
/** True when a `formatStateUsing` callback is set. The renderer reads
|
|
107
|
-
* formatted values out of `row._formatted[columnName]` instead of
|
|
108
|
-
* re-applying the column's format spec. */
|
|
109
|
-
hasFormatter?: boolean
|
|
110
|
-
/** Per-column footer summarizers — kind + optional label. The actual
|
|
111
|
-
* computed values for each summarizer land on the table meta under
|
|
112
|
-
* `summaries[columnName]` (`SummaryResult[]`), not on the column. */
|
|
113
|
-
summaries?: SummarizerMeta[]
|
|
114
|
-
/** True when the user can show / hide this column from the toolbar's
|
|
115
|
-
* "Columns" dropdown. `initiallyHidden` flips the default state so
|
|
116
|
-
* the column starts off until the user opts in. */
|
|
117
|
-
toggleable?: { initiallyHidden?: true }
|
|
118
|
-
/** Render array values one-per-line (each item separated by `<br>`).
|
|
119
|
-
* Composes with `bulleted()` — when both are set, `bulleted()` wins
|
|
120
|
-
* and the renderer mounts a `<ul>` with bullet markers instead. */
|
|
121
|
-
listWithLineBreaks?: true
|
|
122
|
-
/** Render array values as a `<ul>` bullet list. Wins over
|
|
123
|
-
* `listWithLineBreaks()` when both are set. */
|
|
124
|
-
bulleted?: true
|
|
125
|
-
/** Mounts a copy-to-clipboard trigger after the cell value. The string
|
|
126
|
-
* is the toast message shown after a successful copy (default
|
|
127
|
-
* `"Copied!"` when bare `.copyable()` is used). */
|
|
128
|
-
copyMessage?: string
|
|
129
|
-
/** Server-rendered rich-text discriminator. When set, the renderer
|
|
130
|
-
* reads the rendered HTML from `row._formatted[col.name]` and
|
|
131
|
-
* dangerouslySetsInnerHTML it (matches the existing Tiptap richtext
|
|
132
|
-
* cell path). The kind drives server-side rendering — `markdown` runs
|
|
133
|
-
* through `marked` first; `html` is passthrough. Sanitization applies
|
|
134
|
-
* to both unless the column opts out. */
|
|
135
|
-
richText?: ColumnRichTextKind
|
|
136
|
-
/**
|
|
137
|
-
* Per-column record-URL behavior. The default (absent) means the cell
|
|
138
|
-
* inherits the table's `recordUrl` for click navigation. `false` opts
|
|
139
|
-
* the column out — clicks on this column's cell don't navigate anywhere.
|
|
140
|
-
* `true` means the column has its own URL handler; the resolved URL
|
|
141
|
-
* is stamped onto each row under `row._columnRecordUrls[columnName]`.
|
|
142
|
-
*/
|
|
143
|
-
recordUrl?: boolean
|
|
144
|
-
// ─── Editable cell columns (TextInput / Toggle / Select) ───
|
|
145
|
-
/** Confirmation message — when set, the renderer gates the PATCH
|
|
146
|
-
* behind a Dialog confirm before firing. */
|
|
147
|
-
confirm?: string
|
|
148
|
-
/** Static disable. Per-row disable (`disabled(fn)`) lands on the row
|
|
149
|
-
* under `row._cellDisabled[columnName]` — not on the column meta. */
|
|
150
|
-
disabled?: true
|
|
151
|
-
/** Mirrored validator descriptors — same shape as `FieldMeta.rules`,
|
|
152
|
-
* for client-side hint rendering. The actual rules run server-side
|
|
153
|
-
* inside the `_cell` route. */
|
|
154
|
-
rules?: SerializedRule[]
|
|
155
|
-
/** Default debounce (ms) for committed-after-typing PATCHes on
|
|
156
|
-
* `TextInputColumn`. Stamped on the meta only when explicitly set;
|
|
157
|
-
* the renderer falls back to its own default. */
|
|
158
|
-
debounceMs?: number
|
|
159
|
-
// Subclass-specific extras land in `_extra` to keep the meta typed.
|
|
160
|
-
// BadgeColumn — value-to-color map.
|
|
161
|
-
badgeColors?: Record<string, string>
|
|
162
|
-
// IconColumn — value-to-{icon,color} map.
|
|
163
|
-
iconOptions?: Record<string, { icon: string; color?: string }>
|
|
164
|
-
// ImageColumn — sizing.
|
|
165
|
-
imageSize?: number
|
|
166
|
-
imageShape?: 'square' | 'circle'
|
|
167
|
-
// ColorColumn — swatch shape + value-text suppression.
|
|
168
|
-
colorShape?: 'rounded' | 'square' | 'circle'
|
|
169
|
-
colorHideValue?: true
|
|
170
|
-
// TextInputColumn.
|
|
171
|
-
inputType?: 'text' | 'number' | 'email' | 'url' | 'tel'
|
|
172
|
-
inputPlaceholder?: string
|
|
173
|
-
inputStep?: number
|
|
174
|
-
inputMin?: number
|
|
175
|
-
inputMax?: number
|
|
176
|
-
// ToggleColumn.
|
|
177
|
-
toggleOnColor?: ColumnColor
|
|
178
|
-
toggleOffColor?: ColumnColor
|
|
179
|
-
toggleOnIcon?: string
|
|
180
|
-
toggleOffIcon?: string
|
|
181
|
-
// SelectColumn.
|
|
182
|
-
selectOptions?: ColumnSelectOption[]
|
|
183
|
-
selectNullable?: true
|
|
184
|
-
/** Hide the placeholder option once a value is set. Default: keep
|
|
185
|
-
* showing it so users can clear the value (matches Filament). */
|
|
186
|
-
selectablePlaceholder?: false
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Base column primitive — used directly for text cells (the most common
|
|
191
|
-
* case) or extended into `BadgeColumn` / `IconColumn` / `BooleanColumn` /
|
|
192
|
-
* `ImageColumn` for visual variants. Joins the schema tree as an
|
|
193
|
-
* Element so it serializes through the same resolver pipeline as
|
|
194
|
-
* Fields and display elements. Lives as a child of `Table`.
|
|
195
|
-
*/
|
|
196
|
-
export class Column extends Element {
|
|
197
|
-
readonly name: string
|
|
198
|
-
protected _label?: string
|
|
199
|
-
protected _sortable = false
|
|
200
|
-
protected _searchable = false
|
|
201
|
-
|
|
202
|
-
// Visual / layout
|
|
203
|
-
protected _columnType: ColumnType = 'text'
|
|
204
|
-
protected _alignment?: ColumnAlignment
|
|
205
|
-
protected _width?: string
|
|
206
|
-
protected _default?: string
|
|
207
|
-
protected _tooltip?: string
|
|
208
|
-
protected _wrap = false
|
|
209
|
-
protected _lineClamp?: number
|
|
210
|
-
protected _weight?: ColumnWeight
|
|
211
|
-
protected _color?: ColumnColor
|
|
212
|
-
|
|
213
|
-
// Formatters
|
|
214
|
-
protected _format?: ColumnFormat
|
|
215
|
-
protected _formatState?: FormatStateHandler
|
|
216
|
-
|
|
217
|
-
// Per-column record-URL override / opt-out. `false` disables linking
|
|
218
|
-
// for this column; a function overrides the table's URL with a
|
|
219
|
-
// column-specific one. Unset = inherit the table's recordUrl.
|
|
220
|
-
protected _recordUrl?: false | ColumnRecordUrlHandler
|
|
221
|
-
|
|
222
|
-
// Footer summarizers (Sum / Average / Count / Range). Computed by
|
|
223
|
-
// `loadTableRecords` over the rendered rows; values land on the
|
|
224
|
-
// table-level summaries map keyed by column name.
|
|
225
|
-
protected _summarizers: Summarizer[] = []
|
|
226
|
-
|
|
227
|
-
// Rich-display chrome (Filament-parity Tier-2). All optional, all
|
|
228
|
-
// emit-only-when-set — the wire shape stays tidy on the bare-text path.
|
|
229
|
-
protected _listWithLineBreaks = false
|
|
230
|
-
protected _bulleted = false
|
|
231
|
-
protected _copyMessage?: string
|
|
232
|
-
// Rich-text rendering — either `'markdown'` or `'html'`. The dispatcher
|
|
233
|
-
// server-renders the cell + stamps `_formatted[name] / _richtextCells[name]`.
|
|
234
|
-
protected _richText?: ColumnRichTextKind
|
|
235
|
-
protected _sanitize: boolean | SanitizeConfig = true
|
|
236
|
-
|
|
237
|
-
// User-toggleable column visibility — `Table.toggleColumns()` opt-in
|
|
238
|
-
// chrome reads this and stamps the toolbar dropdown. State persists
|
|
239
|
-
// per-table to localStorage so the user's choice sticks across loads.
|
|
240
|
-
protected _toggleable: false | ColumnToggleableConfig = false
|
|
241
|
-
|
|
242
|
-
// ─── Editable cell columns (TextInput / Toggle / Select) ───
|
|
243
|
-
// Per-cell PATCH validators — same shape as Field validators. Only
|
|
244
|
-
// consulted when the column is editable (the route handler reads
|
|
245
|
-
// them server-side). Inert on read-only columns.
|
|
246
|
-
protected _required = false
|
|
247
|
-
protected _validators: Validator[] = []
|
|
248
|
-
protected _confirm?: string
|
|
249
|
-
protected _staticDisabled = false
|
|
250
|
-
protected _disabledFn?: ColumnDisabledFn
|
|
251
|
-
protected _beforeStateUpdated?: CellStateHook
|
|
252
|
-
protected _afterStateUpdated?: CellStateHook
|
|
253
|
-
|
|
254
|
-
protected constructor(name: string) {
|
|
255
|
-
super()
|
|
256
|
-
this.name = name
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
static make(name: string): Column {
|
|
260
|
-
return new Column(name)
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// ─── Identity ─────────────────────────────────────────
|
|
264
|
-
|
|
265
|
-
label(l: string): this { this._label = l; return this }
|
|
266
|
-
sortable(v = true): this { this._sortable = v; return this }
|
|
267
|
-
searchable(v = true): this { this._searchable = v; return this }
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Let the user show / hide this column from the table toolbar's
|
|
271
|
-
* "Columns" dropdown. Preference persists per-table to localStorage
|
|
272
|
-
* under `pilotiq.table.<currentPath>.columns.<col>` so the choice
|
|
273
|
-
* sticks across reloads + SPA navigations.
|
|
274
|
-
*
|
|
275
|
-
* Pass `{ initiallyHidden: true }` to start the column off-screen —
|
|
276
|
-
* useful for technical / debug columns the user opts into.
|
|
277
|
-
*
|
|
278
|
-
* Column.make('email').toggleable()
|
|
279
|
-
* Column.make('internalId').toggleable({ initiallyHidden: true })
|
|
280
|
-
* Column.make('name').toggleable(false) // explicit opt-out
|
|
281
|
-
*
|
|
282
|
-
* Any non-toggleable column always renders. Hidden state is purely
|
|
283
|
-
* presentational — the column's data still loads from the server (so
|
|
284
|
-
* sorts / filters that reference it keep working, and a re-toggle
|
|
285
|
-
* shows fresh values without a roundtrip).
|
|
286
|
-
*/
|
|
287
|
-
toggleable(opts: boolean | ColumnToggleableConfig = true): this {
|
|
288
|
-
if (opts === false) {
|
|
289
|
-
this._toggleable = false
|
|
290
|
-
} else if (opts === true) {
|
|
291
|
-
this._toggleable = {}
|
|
292
|
-
} else {
|
|
293
|
-
this._toggleable = { ...opts }
|
|
294
|
-
}
|
|
295
|
-
return this
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
isToggleable(): boolean { return this._toggleable !== false }
|
|
299
|
-
getToggleableConfig(): ColumnToggleableConfig | undefined {
|
|
300
|
-
return this._toggleable === false ? undefined : this._toggleable
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// ─── Layout ───────────────────────────────────────────
|
|
304
|
-
|
|
305
|
-
alignment(a: ColumnAlignment): this { this._alignment = a; return this }
|
|
306
|
-
width(w: string): this { this._width = w; return this }
|
|
307
|
-
|
|
308
|
-
/** Fallback string when the cell value is null / undefined / empty. */
|
|
309
|
-
default(s: string): this { this._default = s; return this }
|
|
310
|
-
/** Alias for `default()` to match the Filament spelling. */
|
|
311
|
-
placeholder(s: string): this { return this.default(s) }
|
|
312
|
-
|
|
313
|
-
tooltip(t: string): this { this._tooltip = t; return this }
|
|
314
|
-
|
|
315
|
-
/** Render the cell with `whitespace-normal`; long content wraps onto
|
|
316
|
-
* multiple lines instead of getting truncated. */
|
|
317
|
-
wrap(v = true): this { this._wrap = v; return this }
|
|
318
|
-
|
|
319
|
-
/** CSS line-clamp for multi-line truncation (replaces `wrap`). */
|
|
320
|
-
lineClamp(n: number): this { this._lineClamp = n; return this }
|
|
321
|
-
|
|
322
|
-
weight(w: ColumnWeight): this { this._weight = w; return this }
|
|
323
|
-
color(c: ColumnColor): this { this._color = c; return this }
|
|
324
|
-
|
|
325
|
-
// ─── Built-in formatters ──────────────────────────────
|
|
326
|
-
|
|
327
|
-
/** Format a date / datetime value via `Intl.DateTimeFormat`. The
|
|
328
|
-
* default pattern produces "Jan 1, 2026, 9:00 AM"-style output. */
|
|
329
|
-
dateTime(pattern?: string): this {
|
|
330
|
-
this._format = pattern ? { kind: 'dateTime', pattern } : { kind: 'dateTime' }
|
|
331
|
-
return this
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/** Render the value as relative time ("5 minutes ago"). */
|
|
335
|
-
since(): this {
|
|
336
|
-
this._format = { kind: 'since' }
|
|
337
|
-
return this
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/** Format the value as currency. `currency` is the ISO 4217 code
|
|
341
|
-
* (e.g. 'USD', 'EUR'). */
|
|
342
|
-
money(currency: string, locale?: string): this {
|
|
343
|
-
this._format = locale ? { kind: 'money', currency, locale } : { kind: 'money', currency }
|
|
344
|
-
return this
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/** Format the value as a decimal number. */
|
|
348
|
-
numeric(opts: { decimals?: number; locale?: string } = {}): this {
|
|
349
|
-
this._format = {
|
|
350
|
-
kind: 'numeric',
|
|
351
|
-
...(opts.decimals !== undefined ? { decimals: opts.decimals } : {}),
|
|
352
|
-
...(opts.locale !== undefined ? { locale: opts.locale } : {}),
|
|
353
|
-
}
|
|
354
|
-
return this
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/** Truncate the cell to `chars` characters with an ellipsis. */
|
|
358
|
-
limit(chars: number): this {
|
|
359
|
-
this._format = { kind: 'limit', chars }
|
|
360
|
-
return this
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Truncate the cell to `n` words with an ellipsis. Splits on whitespace
|
|
365
|
-
* runs (`/\s+/`) — empty lead/trail tokens collapse so a value like
|
|
366
|
-
* `" hello world "` truncates the same as `"hello world"`. Composes
|
|
367
|
-
* mutually-exclusively with `limit()` and `characters()` (each
|
|
368
|
-
* formatter overwrites the previous one — last call wins).
|
|
369
|
-
*/
|
|
370
|
-
words(n: number): this {
|
|
371
|
-
this._format = { kind: 'words', words: n }
|
|
372
|
-
return this
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Filament-parity alias for `limit(n)`. Same wire shape — both call
|
|
377
|
-
* sites read better depending on whether you're capping by character
|
|
378
|
-
* count or word count.
|
|
379
|
-
*/
|
|
380
|
-
characters(n: number): this { return this.limit(n) }
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Render array values one-per-line. Non-array values pass through
|
|
384
|
-
* unchanged. Composes with `bulleted()` — when both are set,
|
|
385
|
-
* `bulleted()` wins (bullet list is the strictly richer presentation;
|
|
386
|
-
* line breaks become implicit).
|
|
387
|
-
*/
|
|
388
|
-
listWithLineBreaks(v = true): this { this._listWithLineBreaks = v; return this }
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Render array values as a `<ul>` bullet list. Non-array values pass
|
|
392
|
-
* through unchanged. Wins over `listWithLineBreaks()` when both are
|
|
393
|
-
* set.
|
|
394
|
-
*/
|
|
395
|
-
bulleted(v = true): this { this._bulleted = v; return this }
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Mount a copy-to-clipboard trigger next to the cell value. The
|
|
399
|
-
* `message` (default `"Copied!"`) is the toast shown after a
|
|
400
|
-
* successful copy. The button copies the rendered cell text — for
|
|
401
|
-
* rich-text cells (`markdown() / html()`) the underlying source is
|
|
402
|
-
* copied instead of the rendered HTML so users get the version they
|
|
403
|
-
* can re-edit. Bare `copyMessage()` opts in with the default copy.
|
|
404
|
-
*/
|
|
405
|
-
copyMessage(message?: string): this {
|
|
406
|
-
this._copyMessage = message ?? 'Copied!'
|
|
407
|
-
return this
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* Render the cell's value as Markdown — server-runs through `marked`
|
|
412
|
-
* (already a dep of pilotiq from `Markdown` prime) and the result
|
|
413
|
-
* lands as sanitized HTML in `row._formatted[name]` with
|
|
414
|
-
* `_richtextCells[name] = true`. The renderer recognizes the flag and
|
|
415
|
-
* mounts the cell via `dangerouslySetInnerHTML` against the same
|
|
416
|
-
* `prose-sm` container the Tiptap richtext path uses.
|
|
417
|
-
*
|
|
418
|
-
* Mutually exclusive with `html()` — the last call wins. Pair with
|
|
419
|
-
* `.allowRaw()` / `.sanitize({ allowedTags: [...] })` to relax the
|
|
420
|
-
* default-secure allowlist for admin-trusted content.
|
|
421
|
-
*/
|
|
422
|
-
markdown(v = true): this {
|
|
423
|
-
if (v) this._richText = 'markdown'
|
|
424
|
-
else delete this._richText
|
|
425
|
-
return this
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Render the cell's value as raw HTML — passes straight through
|
|
430
|
-
* `sanitize-html` against the default-secure allowlist (no Markdown
|
|
431
|
-
* conversion). Mutually exclusive with `markdown()`.
|
|
432
|
-
*/
|
|
433
|
-
html(v = true): this {
|
|
434
|
-
if (v) this._richText = 'html'
|
|
435
|
-
else delete this._richText
|
|
436
|
-
return this
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Sanitization control for `markdown()` / `html()` cells. Default
|
|
441
|
-
* `true` — runs the rendered HTML through `DEFAULT_SANITIZE_CONFIG`
|
|
442
|
-
* before the wire shape ships. Pass `false` (or call `.allowRaw()`)
|
|
443
|
-
* to disable; pass a `sanitize-html` config to widen the allowlist
|
|
444
|
-
* (e.g. legacy CMS content with embedded media). Mirrors the
|
|
445
|
-
* `Markdown` / `Html` prime APIs so authors can carry the same
|
|
446
|
-
* intuition into a column context.
|
|
447
|
-
*/
|
|
448
|
-
sanitize(v: boolean | SanitizeConfig = true): this {
|
|
449
|
-
this._sanitize = v
|
|
450
|
-
return this
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/** Sugar — opt out of the default-secure sanitizer. */
|
|
454
|
-
allowRaw(): this { this._sanitize = false; return this }
|
|
455
|
-
|
|
456
|
-
/** Custom per-row formatter — runs server-side inside `loadTableRecords`
|
|
457
|
-
* and stashes the resulting string on `row._formatted[name]`. Wins
|
|
458
|
-
* over the built-in `format` spec when both are set. */
|
|
459
|
-
formatStateUsing(fn: FormatStateHandler): this {
|
|
460
|
-
this._formatState = fn
|
|
461
|
-
return this
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Per-column record-URL behavior. Pass `false` to opt this column out
|
|
466
|
-
* of the table's row-level `recordUrl` — clicks on this column's cell
|
|
467
|
-
* won't navigate. Pass a function to override with a column-specific
|
|
468
|
-
* URL. Without calling this, the column inherits the table's
|
|
469
|
-
* `recordUrl`.
|
|
470
|
-
*
|
|
471
|
-
* Filament parity: matches `Tables\Columns\Column::url(...)` and
|
|
472
|
-
* `->recordUrl(false)` semantics.
|
|
473
|
-
*/
|
|
474
|
-
recordUrl(target: false | ColumnRecordUrlHandler): this {
|
|
475
|
-
this._recordUrl = target
|
|
476
|
-
return this
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
/**
|
|
480
|
-
* Attach summarizers (Sum / Average / Count / Range) to this column.
|
|
481
|
-
* They render in a `<tfoot>` row under the column. Values are computed
|
|
482
|
-
* server-side over the rows currently on screen — per-page only in
|
|
483
|
-
* v1; cross-page aggregation is deferred.
|
|
484
|
-
*/
|
|
485
|
-
summarize(summarizers: Summarizer[]): this {
|
|
486
|
-
this._summarizers = summarizers
|
|
487
|
-
return this
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// ─── Editable cell columns ────────────────────────────
|
|
491
|
-
// These are no-ops on read-only column types but live on the base so
|
|
492
|
-
// subclass authors don't need to redeclare. `isEditable()` derives
|
|
493
|
-
// from `_columnType` — TextInputColumn / ToggleColumn / SelectColumn
|
|
494
|
-
// call `setColumnType()` in their `make()` factory.
|
|
495
|
-
|
|
496
|
-
/** Mark the value as required for inline edits. Auto-contributes a
|
|
497
|
-
* required check unless `validate(required())` is already present
|
|
498
|
-
* (matches `Field.required()` semantics — see `hasRequiredValidator`). */
|
|
499
|
-
required(v = true): this { this._required = v; return this }
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Attach one or more server-side validators. Reuses the same `Validator`
|
|
503
|
-
* type used by `Field.validate()` so existing rules (`required`, `email`,
|
|
504
|
-
* `minLength`, `unique`, …) work unchanged. Validators run inside the
|
|
505
|
-
* `POST {…}/_cell/:column` route before `R.model.update`; on failure
|
|
506
|
-
* the response is `422 { ok:false, errors: { value: string[] } }`.
|
|
507
|
-
*/
|
|
508
|
-
validate(v: Validator | Validator[]): this {
|
|
509
|
-
if (Array.isArray(v)) this._validators.push(...v)
|
|
510
|
-
else this._validators.push(v)
|
|
511
|
-
return this
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* Gate the PATCH behind a confirm dialog. Renderer opens a Dialog with
|
|
516
|
-
* `message` before firing the network call; cancel rolls back the
|
|
517
|
-
* optimistic local state.
|
|
518
|
-
*/
|
|
519
|
-
confirm(message: string): this { this._confirm = message; return this }
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Run a hook on the server BEFORE the editable cell's value is written
|
|
523
|
-
* to the database. Receives the coerced + validated value plus the
|
|
524
|
-
* current row as `{ record, user }`. Use for cross-cell invariants,
|
|
525
|
-
* audit-log writes that must precede the update, or async availability
|
|
526
|
-
* checks that the schema-level validators don't cover. Throw an Error
|
|
527
|
-
* to halt — the thrown message lands under the reserved `_cell` error
|
|
528
|
-
* key in the 422 response.
|
|
529
|
-
*/
|
|
530
|
-
beforeStateUpdated(fn: CellStateHook): this { this._beforeStateUpdated = fn; return this }
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Run a hook on the server AFTER the editable cell's value is written
|
|
534
|
-
* to the database. Same context shape as `beforeStateUpdated`. Use for
|
|
535
|
-
* notifications, broadcast events, or follow-up writes that should
|
|
536
|
-
* fire only on a confirmed save. Throwing here returns 422 with the
|
|
537
|
-
* message under `_cell` — the row is already updated, so prefer
|
|
538
|
-
* surfacing the error and letting the user retry rather than rolling
|
|
539
|
-
* back manually.
|
|
540
|
-
*/
|
|
541
|
-
afterStateUpdated(fn: CellStateHook): this { this._afterStateUpdated = fn; return this }
|
|
542
|
-
|
|
543
|
-
getBeforeStateUpdated(): CellStateHook | undefined { return this._beforeStateUpdated }
|
|
544
|
-
getAfterStateUpdated(): CellStateHook | undefined { return this._afterStateUpdated }
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* Render the inline-edit control disabled. Pass `true` (or call with no
|
|
548
|
-
* args) for static disable; pass a `(record) => boolean` predicate for
|
|
549
|
-
* per-row disable — evaluated server-side inside `loadTableRecords`,
|
|
550
|
-
* stashed under `row._cellDisabled[columnName]`.
|
|
551
|
-
*
|
|
552
|
-
* Independent from `R.canEdit(user, record)` — the auth check fires
|
|
553
|
-
* regardless and a forbidden record never sees an editable affordance.
|
|
554
|
-
*/
|
|
555
|
-
disabled(value: boolean | ColumnDisabledFn = true): this {
|
|
556
|
-
if (typeof value === 'function') {
|
|
557
|
-
this._disabledFn = value
|
|
558
|
-
this._staticDisabled = false
|
|
559
|
-
} else {
|
|
560
|
-
this._staticDisabled = value
|
|
561
|
-
delete this._disabledFn
|
|
562
|
-
}
|
|
563
|
-
return this
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
// ─── Column-type setter (subclass internal) ───────────
|
|
567
|
-
|
|
568
|
-
protected setColumnType(t: ColumnType): this {
|
|
569
|
-
this._columnType = t
|
|
570
|
-
return this
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
// ─── Getters ──────────────────────────────────────────
|
|
574
|
-
|
|
575
|
-
getLabel(): string {
|
|
576
|
-
return this._label ?? this.name.charAt(0).toUpperCase() + this.name.slice(1)
|
|
577
|
-
}
|
|
578
|
-
isSortable(): boolean { return this._sortable }
|
|
579
|
-
isSearchable(): boolean { return this._searchable }
|
|
580
|
-
getColumnType(): ColumnType { return this._columnType }
|
|
581
|
-
getFormatStateHandler(): FormatStateHandler | undefined { return this._formatState }
|
|
582
|
-
hasFormatter(): boolean { return this._formatState !== undefined }
|
|
583
|
-
/** True when a built-in `format` spec (`dateTime / since / money /
|
|
584
|
-
* numeric / limit`) is configured. Used by walkers that want to skip
|
|
585
|
-
* columns the user has already chosen formatting for. */
|
|
586
|
-
hasFormat(): boolean { return this._format !== undefined }
|
|
587
|
-
getRecordUrlHandler(): ColumnRecordUrlHandler | undefined {
|
|
588
|
-
return typeof this._recordUrl === 'function' ? this._recordUrl : undefined
|
|
589
|
-
}
|
|
590
|
-
hasRecordUrlHandler(): boolean { return typeof this._recordUrl === 'function' }
|
|
591
|
-
isRecordUrlDisabled(): boolean { return this._recordUrl === false }
|
|
592
|
-
getSummarizers(): ReadonlyArray<Summarizer> { return this._summarizers }
|
|
593
|
-
hasSummarizers(): boolean { return this._summarizers.length > 0 }
|
|
594
|
-
|
|
595
|
-
/** Rich-text discriminator. Used by `dispatchTable` to decide whether
|
|
596
|
-
* to server-render the cell value through `marked` + `sanitize-html`. */
|
|
597
|
-
getRichTextKind(): ColumnRichTextKind | undefined { return this._richText }
|
|
598
|
-
isRichText(): boolean { return this._richText !== undefined }
|
|
599
|
-
getSanitize(): boolean | SanitizeConfig { return this._sanitize }
|
|
600
|
-
|
|
601
|
-
// ─── Editable getters ─────────────────────────────────
|
|
602
|
-
|
|
603
|
-
/** True for `TextInputColumn / ToggleColumn / SelectColumn`. The route
|
|
604
|
-
* handler + `dispatchTable` per-row stamping consult this. */
|
|
605
|
-
isEditable(): boolean {
|
|
606
|
-
return this._columnType === 'textInput'
|
|
607
|
-
|| this._columnType === 'toggle'
|
|
608
|
-
|| this._columnType === 'select'
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
/** Resolve per-row disable for an editable cell. Returns `true` when
|
|
612
|
-
* the static flag is set or the optional predicate returns truthy.
|
|
613
|
-
* Errors in the predicate fail closed (disabled) — silently swallowing
|
|
614
|
-
* a save attempt is the worse outcome here. */
|
|
615
|
-
isDisabledFor(record: Record<string, unknown>): boolean {
|
|
616
|
-
if (this._staticDisabled) return true
|
|
617
|
-
if (this._disabledFn) {
|
|
618
|
-
try { return Boolean(this._disabledFn(record)) }
|
|
619
|
-
catch { return true }
|
|
620
|
-
}
|
|
621
|
-
return false
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
isRequired(): boolean { return this._required }
|
|
625
|
-
getValidators(): ReadonlyArray<Validator> { return this._validators }
|
|
626
|
-
|
|
627
|
-
/** Run the column's validators against a candidate value. Mirrors
|
|
628
|
-
* `Field.runValidators` — including the implicit required check when
|
|
629
|
-
* `_required` is set without an explicit `required()` validator. */
|
|
630
|
-
async runValidators(value: unknown, ctx?: ValidatorContext): Promise<string[]> {
|
|
631
|
-
const errors: string[] = []
|
|
632
|
-
if (this._required && !this.hasRequiredValidator()) {
|
|
633
|
-
if (value === undefined || value === null || value === '') {
|
|
634
|
-
errors.push('This field is required')
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
for (const v of this._validators) {
|
|
638
|
-
const result = await v(value, ctx)
|
|
639
|
-
if (result) errors.push(result)
|
|
640
|
-
}
|
|
641
|
-
return errors
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
private hasRequiredValidator(): boolean {
|
|
645
|
-
return this._validators.some(v => v.serialized?.rule === 'required')
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
/** Serialized rule descriptors mirrored to the client. */
|
|
649
|
-
protected getSerializedRules(): SerializedRule[] {
|
|
650
|
-
const rules: SerializedRule[] = []
|
|
651
|
-
if (this._required && !this.hasRequiredValidator()) {
|
|
652
|
-
rules.push({ rule: 'required', message: 'This field is required' })
|
|
653
|
-
}
|
|
654
|
-
for (const v of this._validators) {
|
|
655
|
-
if (v.serialized) rules.push(v.serialized)
|
|
656
|
-
}
|
|
657
|
-
return rules
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
// ─── Serialization ────────────────────────────────────
|
|
661
|
-
|
|
662
|
-
override getType(): string { return 'column' }
|
|
663
|
-
|
|
664
|
-
override toMeta(): ColumnMeta {
|
|
665
|
-
const meta: ColumnMeta = {
|
|
666
|
-
type: 'column',
|
|
667
|
-
name: this.name,
|
|
668
|
-
label: this.getLabel(),
|
|
669
|
-
sortable: this._sortable,
|
|
670
|
-
searchable: this._searchable,
|
|
671
|
-
}
|
|
672
|
-
// Only emit columnType when non-default to keep meta tidy.
|
|
673
|
-
if (this._columnType !== 'text') meta.columnType = this._columnType
|
|
674
|
-
if (this._alignment !== undefined) meta.alignment = this._alignment
|
|
675
|
-
if (this._width !== undefined) meta.width = this._width
|
|
676
|
-
if (this._default !== undefined) meta.default = this._default
|
|
677
|
-
if (this._tooltip !== undefined) meta.tooltip = this._tooltip
|
|
678
|
-
if (this._wrap) meta.wrap = true
|
|
679
|
-
if (this._lineClamp !== undefined) meta.lineClamp = this._lineClamp
|
|
680
|
-
if (this._weight !== undefined) meta.weight = this._weight
|
|
681
|
-
if (this._color !== undefined) meta.color = this._color
|
|
682
|
-
if (this._format !== undefined) meta.format = this._format
|
|
683
|
-
if (this._formatState !== undefined) meta.hasFormatter = true
|
|
684
|
-
if (this._summarizers.length > 0) meta.summaries = this._summarizers.map(s => s.toMeta())
|
|
685
|
-
if (this._toggleable !== false) {
|
|
686
|
-
meta.toggleable = this._toggleable.initiallyHidden ? { initiallyHidden: true } : {}
|
|
687
|
-
}
|
|
688
|
-
if (this._listWithLineBreaks) meta.listWithLineBreaks = true
|
|
689
|
-
if (this._bulleted) meta.bulleted = true
|
|
690
|
-
if (this._copyMessage !== undefined) meta.copyMessage = this._copyMessage
|
|
691
|
-
if (this._richText !== undefined) meta.richText = this._richText
|
|
692
|
-
if (this._recordUrl === false) meta.recordUrl = false
|
|
693
|
-
else if (typeof this._recordUrl === 'function') meta.recordUrl = true
|
|
694
|
-
// Editable cell columns — chrome that the renderer needs to mount
|
|
695
|
-
// the right inline control. Per-row `_cellEditable / _cellEditUrls /
|
|
696
|
-
// _cellDisabled` are stamped onto each row by `loadTableRecords` +
|
|
697
|
-
// `tagCellEditUrls` and aren't part of the column's static meta.
|
|
698
|
-
if (this.isEditable()) {
|
|
699
|
-
if (this._confirm !== undefined) meta.confirm = this._confirm
|
|
700
|
-
if (this._staticDisabled) meta.disabled = true
|
|
701
|
-
const rules = this.getSerializedRules()
|
|
702
|
-
if (rules.length > 0) meta.rules = rules
|
|
703
|
-
}
|
|
704
|
-
this.serializeExtras(meta)
|
|
705
|
-
return meta
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
/** Hook for subclasses to add columnType-specific fields to the meta. */
|
|
709
|
-
protected serializeExtras(_meta: ColumnMeta): void {}
|
|
710
|
-
}
|