@pilotiq/pilotiq 0.24.1 → 0.24.3
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 +57 -0
- package/boost/guidelines.md +571 -0
- package/boost/skills/pilotiq-actions/SKILL.md +49 -0
- package/boost/skills/pilotiq-actions/rules/dispatch-modes.md +177 -0
- package/boost/skills/pilotiq-actions/rules/factories.md +130 -0
- package/boost/skills/pilotiq-actions/rules/visibility-and-authorization.md +125 -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/Pilotiq.d.ts +31 -0
- package/dist/Pilotiq.d.ts.map +1 -1
- package/dist/Pilotiq.js +3 -1
- package/dist/Pilotiq.js.map +1 -1
- package/dist/PilotiqRegistry.d.ts +13 -0
- package/dist/PilotiqRegistry.d.ts.map +1 -1
- package/dist/PilotiqRegistry.js +15 -0
- package/dist/PilotiqRegistry.js.map +1 -1
- package/dist/pageData/misc.d.ts.map +1 -1
- package/dist/pageData/misc.js +6 -0
- package/dist/pageData/misc.js.map +1 -1
- package/dist/pageData/navigation.d.ts +1 -0
- package/dist/pageData/navigation.d.ts.map +1 -1
- package/dist/pageData/navigation.js +3 -0
- package/dist/pageData/navigation.js.map +1 -1
- package/dist/pageData/relationPages.d.ts.map +1 -1
- package/dist/pageData/relationPages.js +3 -0
- package/dist/pageData/relationPages.js.map +1 -1
- package/dist/pageData/resourcePages.d.ts.map +1 -1
- package/dist/pageData/resourcePages.js +8 -0
- package/dist/pageData/resourcePages.js.map +1 -1
- package/dist/react/AppShell.d.ts +8 -0
- package/dist/react/AppShell.d.ts.map +1 -1
- package/dist/react/AppShell.js.map +1 -1
- package/dist/react/layouts/SidebarLayout.d.ts.map +1 -1
- package/dist/react/layouts/SidebarLayout.js +10 -2
- package/dist/react/layouts/SidebarLayout.js.map +1 -1
- package/dist/react/widgets/StatsOverviewRenderer.d.ts.map +1 -1
- package/dist/react/widgets/StatsOverviewRenderer.js +32 -18
- package/dist/react/widgets/StatsOverviewRenderer.js.map +1 -1
- package/dist/routes/relations.d.ts.map +1 -1
- package/dist/routes/relations.js +25 -18
- package/dist/routes/relations.js.map +1 -1
- package/dist/routes/resources.js.map +1 -1
- package/package.json +10 -5
- package/.turbo/turbo-build.log +0 -8
- package/CLAUDE.md +0 -265
- 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 -225
- 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 -194
- 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/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 -704
- package/src/routes/pages.ts +0 -175
- package/src/routes/panel.ts +0 -204
- package/src/routes/relations.ts +0 -1243
- 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/schema/Section.ts
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { Element } from './Element.js'
|
|
2
|
-
import type { Action } from '../actions/Action.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Container that groups related Elements (typically Fields) under a heading
|
|
6
|
-
* with optional description. Supports multi-column layouts and a collapsible
|
|
7
|
-
* disclosure pattern. Mirrors panels' `Section` element.
|
|
8
|
-
*
|
|
9
|
-
* Used inside Forms to group related inputs, but composes anywhere a
|
|
10
|
-
* container Element fits (e.g. inside a Card or another Section).
|
|
11
|
-
*
|
|
12
|
-
* Plan #8 polish: `icon / badge / aside / compact / persistCollapsed`.
|
|
13
|
-
*/
|
|
14
|
-
export class Section extends Element {
|
|
15
|
-
private _description?: string
|
|
16
|
-
private _icon?: string
|
|
17
|
-
private _badge?: string
|
|
18
|
-
private _columns: 1 | 2 | 3 = 1
|
|
19
|
-
private _collapsible = false
|
|
20
|
-
private _defaultCollapsed = false
|
|
21
|
-
private _aside = false
|
|
22
|
-
private _compact = false
|
|
23
|
-
private _dense = false
|
|
24
|
-
private _secondary = false
|
|
25
|
-
private _persistCollapsed = false
|
|
26
|
-
private _persistKey?: string
|
|
27
|
-
private _afterHeader?: Action[]
|
|
28
|
-
/**
|
|
29
|
-
* Cascading `inlineLabel` default for descendant `Field`s. Read by
|
|
30
|
-
* `resolveSchema.deriveChildContext`. Per-field
|
|
31
|
-
* `Field.inlineLabel(...)` overrides; a more deeply-nested
|
|
32
|
-
* `Section.inlineLabel(...)` overrides for its subtree.
|
|
33
|
-
*/
|
|
34
|
-
private _inlineLabel?: boolean
|
|
35
|
-
|
|
36
|
-
private constructor(private _title?: string) {
|
|
37
|
-
super()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
static make(title?: string): Section {
|
|
41
|
-
return new Section(title)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
description(d: string): this { this._description = d; return this }
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Icon shown next to the section title. Resolved through the icon
|
|
48
|
-
* registry (`registerIcons({ name: Component })`) at render. Schema-time
|
|
49
|
-
* icons are string-only — component-typed icons are reserved for
|
|
50
|
-
* Resource/Global/Page where the Vite plugin can mint a manifest key.
|
|
51
|
-
*/
|
|
52
|
-
icon(name: string): this { this._icon = name; return this }
|
|
53
|
-
|
|
54
|
-
/** Right-aligned pill in the section header. Pure cosmetic. */
|
|
55
|
-
badge(text: string): this { this._badge = text; return this }
|
|
56
|
-
|
|
57
|
-
/** Number of columns the section's children are laid out in. Defaults to 1. */
|
|
58
|
-
columns(n: 1 | 2 | 3): this { this._columns = n; return this }
|
|
59
|
-
|
|
60
|
-
/** Allow the user to collapse this section. Off by default. */
|
|
61
|
-
collapsible(v = true): this { this._collapsible = v; return this }
|
|
62
|
-
|
|
63
|
-
/** Start collapsed (only meaningful when `collapsible` is true). */
|
|
64
|
-
defaultCollapsed(v = true): this { this._defaultCollapsed = v; return this }
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Render this section as the right-rail aside when nested inside a
|
|
68
|
-
* `Split` parent. No-op outside a `Split`.
|
|
69
|
-
*/
|
|
70
|
-
aside(v = true): this { this._aside = v; return this }
|
|
71
|
-
|
|
72
|
-
/** Tighter padding + smaller heading. Useful in dense settings pages. */
|
|
73
|
-
compact(v = true): this { this._compact = v; return this }
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Cascade `inlineLabel` to every descendant `Field` in this section
|
|
77
|
-
* whose own `.inlineLabel(...)` hasn't been called. Overrides any
|
|
78
|
-
* outer-form / outer-section setting for this subtree only. Pass
|
|
79
|
-
* `false` to revert to label-above for the subtree.
|
|
80
|
-
*/
|
|
81
|
-
inlineLabel(v = true): this { this._inlineLabel = v; return this }
|
|
82
|
-
/** Internal — read by `resolveSchema.deriveChildContext`. */
|
|
83
|
-
getInlineLabel(): boolean | undefined { return this._inlineLabel }
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Tighter spacing between the section's children. Orthogonal to
|
|
87
|
-
* `compact()` (which trims the section's outer padding/heading):
|
|
88
|
-
* `dense()` shrinks the inner grid `gap` so a long form fits more
|
|
89
|
-
* fields per scroll. Compose both for a settings-page look.
|
|
90
|
-
*/
|
|
91
|
-
dense(v = true): this { this._dense = v; return this }
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Muted background variant — uses the `bg-muted/40` token instead of
|
|
95
|
-
* `bg-card`. Pairs well with sections that wrap secondary or auxiliary
|
|
96
|
-
* controls (e.g. an "Advanced settings" group inside a primary card).
|
|
97
|
-
*/
|
|
98
|
-
secondary(v = true): this { this._secondary = v; return this }
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Persist the open/closed state to localStorage so user choices survive
|
|
102
|
-
* navigation. Only meaningful when `collapsible` is true. The optional
|
|
103
|
-
* `key` overrides the auto-key (which is built from the page slug +
|
|
104
|
-
* section title at render time).
|
|
105
|
-
*/
|
|
106
|
-
persistCollapsed(key?: string): this {
|
|
107
|
-
this._persistCollapsed = true
|
|
108
|
-
if (key !== undefined) this._persistKey = key
|
|
109
|
-
return this
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Action buttons rendered to the right of the section header. v1
|
|
114
|
-
* accepts `Action[]` only — Element-typed children would require a
|
|
115
|
-
* second resolver pass; keeping the slot Action-only dodges the
|
|
116
|
-
* resolution question (Actions serialize via `toMeta()` and their
|
|
117
|
-
* visibility evaluates inside the standard resolver walk that
|
|
118
|
-
* `resolveSchema` runs against `getAfterHeader()`).
|
|
119
|
-
*
|
|
120
|
-
* Actions placed here keep their full chrome surface — `.color() /
|
|
121
|
-
* .icon() / .iconButton() / .visible() / .disabled()` all work the
|
|
122
|
-
* same as anywhere else.
|
|
123
|
-
*/
|
|
124
|
-
afterHeader(actions: Action[]): this {
|
|
125
|
-
this._afterHeader = actions
|
|
126
|
-
return this
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/** Read-only access for the resolver. */
|
|
130
|
-
getAfterHeader(): Action[] | undefined { return this._afterHeader }
|
|
131
|
-
|
|
132
|
-
/** Set the section's children. Any Element type is accepted. */
|
|
133
|
-
schema(elements: Element[]): this {
|
|
134
|
-
this._children = elements
|
|
135
|
-
return this
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
getType(): string { return 'section' }
|
|
139
|
-
|
|
140
|
-
toMeta(): Record<string, unknown> {
|
|
141
|
-
return {
|
|
142
|
-
type: 'section' as const,
|
|
143
|
-
...(this._title ? { title: this._title } : {}),
|
|
144
|
-
...(this._description ? { description: this._description } : {}),
|
|
145
|
-
...(this._icon ? { icon: this._icon } : {}),
|
|
146
|
-
...(this._badge ? { badge: this._badge } : {}),
|
|
147
|
-
columns: this._columns,
|
|
148
|
-
collapsible: this._collapsible,
|
|
149
|
-
...(this._collapsible && this._defaultCollapsed ? { defaultCollapsed: true } : {}),
|
|
150
|
-
...(this._collapsible && this._persistCollapsed ? {
|
|
151
|
-
persistCollapsed: true,
|
|
152
|
-
...(this._persistKey ? { persistKey: this._persistKey } : {}),
|
|
153
|
-
} : {}),
|
|
154
|
-
...(this._aside ? { aside: true } : {}),
|
|
155
|
-
...(this._compact ? { compact: true } : {}),
|
|
156
|
-
...(this._dense ? { dense: true } : {}),
|
|
157
|
-
...(this._secondary ? { secondary: true } : {}),
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
ServerDataElement,
|
|
6
|
-
isServerDataElement,
|
|
7
|
-
stampServerDataMeta,
|
|
8
|
-
} from './ServerDataElement.js'
|
|
9
|
-
import { Element } from './Element.js'
|
|
10
|
-
import { resolveSchema } from './resolveSchema.js'
|
|
11
|
-
|
|
12
|
-
class FakeWidget extends ServerDataElement {
|
|
13
|
-
private _payload: unknown
|
|
14
|
-
constructor(id: string | undefined, payload: unknown) {
|
|
15
|
-
super()
|
|
16
|
-
if (id) this._id = id
|
|
17
|
-
this._payload = payload
|
|
18
|
-
}
|
|
19
|
-
getType() { return 'fake-widget' }
|
|
20
|
-
toMeta() { return { type: 'fake-widget' as const, label: 'fake' } }
|
|
21
|
-
async resolveServerData() { return this._payload }
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
class PlainElement extends Element {
|
|
25
|
-
getType() { return 'plain' }
|
|
26
|
-
toMeta() { return { type: 'plain' as const } }
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
describe('ServerDataElement', () => {
|
|
30
|
-
describe('identity', () => {
|
|
31
|
-
it('falls back to constructor name when no id was set', () => {
|
|
32
|
-
class Contributions extends ServerDataElement {
|
|
33
|
-
getType() { return 'view' }
|
|
34
|
-
toMeta() { return { type: 'view' as const } }
|
|
35
|
-
async resolveServerData() { return null }
|
|
36
|
-
}
|
|
37
|
-
const w = new Contributions()
|
|
38
|
-
assert.equal(w.getId(), 'Contributions')
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('uses the explicit id when set via constructor', () => {
|
|
42
|
-
const w = new FakeWidget('posts-chart', null)
|
|
43
|
-
assert.equal(w.getId(), 'posts-chart')
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('id() setter overrides any inferred id', () => {
|
|
47
|
-
class Foo extends ServerDataElement {
|
|
48
|
-
getType() { return 'view' }
|
|
49
|
-
toMeta() { return { type: 'view' as const } }
|
|
50
|
-
async resolveServerData() { return null }
|
|
51
|
-
}
|
|
52
|
-
const w = new Foo().id('custom-id')
|
|
53
|
-
assert.equal(w.getId(), 'custom-id')
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
describe('flags', () => {
|
|
58
|
-
it('default isLazy() is true', () => {
|
|
59
|
-
const w = new FakeWidget('a', null)
|
|
60
|
-
assert.equal(w.isLazy(), true)
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('lazy(false) opts out', () => {
|
|
64
|
-
const w = new FakeWidget('a', null).lazy(false)
|
|
65
|
-
assert.equal(w.isLazy(), false)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
it('lazy() with no arg defaults to true', () => {
|
|
69
|
-
const w = new FakeWidget('a', null).lazy(false).lazy()
|
|
70
|
-
assert.equal(w.isLazy(), true)
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('poll(seconds) stores positive numbers', () => {
|
|
74
|
-
const w = new FakeWidget('a', null).poll(30)
|
|
75
|
-
assert.equal(w.getPoll(), 30)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('poll() ignores zero / negative / non-finite', () => {
|
|
79
|
-
const w = new FakeWidget('a', null).poll(0).poll(-5).poll(NaN)
|
|
80
|
-
assert.equal(w.getPoll(), undefined)
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
describe('isServerDataElement', () => {
|
|
85
|
-
it('returns true for ServerDataElement subclasses', () => {
|
|
86
|
-
assert.equal(isServerDataElement(new FakeWidget('a', null)), true)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('returns false for plain Element subclasses', () => {
|
|
90
|
-
assert.equal(isServerDataElement(new PlainElement()), false)
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
describe('stampServerDataMeta + resolveSchema integration', () => {
|
|
95
|
-
it('stamps serverData / id / lazy on the meta during schema resolve', async () => {
|
|
96
|
-
const w = new FakeWidget('my-id', null)
|
|
97
|
-
const [meta] = await resolveSchema([w])
|
|
98
|
-
assert.equal(meta!['serverData'], true)
|
|
99
|
-
assert.equal(meta!['id'], 'my-id')
|
|
100
|
-
assert.equal(meta!['lazy'], true) // default
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('emits poll on the meta when set', async () => {
|
|
104
|
-
const w = new FakeWidget('my-id', null).poll(60)
|
|
105
|
-
const [meta] = await resolveSchema([w])
|
|
106
|
-
assert.equal(meta!['poll'], 60)
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
it('emits lazy: false explicitly when lazy(false)', async () => {
|
|
110
|
-
const w = new FakeWidget('my-id', null).lazy(false)
|
|
111
|
-
const [meta] = await resolveSchema([w])
|
|
112
|
-
assert.equal(meta!['lazy'], false)
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('preserves the subclass toMeta() surface', async () => {
|
|
116
|
-
const w = new FakeWidget('my-id', null)
|
|
117
|
-
const [meta] = await resolveSchema([w])
|
|
118
|
-
assert.equal(meta!['label'], 'fake')
|
|
119
|
-
assert.equal(meta!.type, 'fake-widget')
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
it('does NOT stamp on non-ServerDataElement elements', async () => {
|
|
123
|
-
const [meta] = await resolveSchema([new PlainElement()])
|
|
124
|
-
assert.equal(meta!['serverData'], undefined)
|
|
125
|
-
assert.equal(meta!['id'], undefined)
|
|
126
|
-
})
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
describe('stampServerDataMeta direct call', () => {
|
|
130
|
-
it('mutates the meta in place', () => {
|
|
131
|
-
const w = new FakeWidget('foo', null).poll(15)
|
|
132
|
-
const meta: Record<string, unknown> & { type: string } = { type: 'fake-widget' }
|
|
133
|
-
stampServerDataMeta(w, meta)
|
|
134
|
-
assert.equal(meta['serverData'], true)
|
|
135
|
-
assert.equal(meta['id'], 'foo')
|
|
136
|
-
assert.equal(meta['poll'], 15)
|
|
137
|
-
assert.equal(meta['lazy'], true)
|
|
138
|
-
})
|
|
139
|
-
})
|
|
140
|
-
})
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { Element, type ElementMeta } from './Element.js'
|
|
2
|
-
import type { RenderContext } from './resolveSchema.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Element subclasses that compute their render-time payload from the
|
|
6
|
-
* server. Plan #15 widgets — `Stat / StatsOverview / Chart / Table /
|
|
7
|
-
* View` extend this. The contract is intentionally tiny:
|
|
8
|
-
*
|
|
9
|
-
* - identity: every element carries an id (`Stat.make(id)` / inferred
|
|
10
|
-
* class name fallback) so the polling endpoint can find it,
|
|
11
|
-
* - hook: `resolveServerData(ctx)` returns whatever JSON-clean
|
|
12
|
-
* payload the renderer should consume,
|
|
13
|
-
* - flags: `poll(seconds)`, `lazy(bool=true)` shape the wire.
|
|
14
|
-
*
|
|
15
|
-
* `pageData.resolveServerDataElements` walks every page-data builder's
|
|
16
|
-
* tree, collects elements where `isServerDataElement()` is true, and
|
|
17
|
-
* runs `resolveServerData(ctx)` in parallel — except for lazy ones,
|
|
18
|
-
* which paint a skeleton client-side and fetch via the polling endpoint
|
|
19
|
-
* on mount. Results land on a single `_widgetData[id]` map alongside
|
|
20
|
-
* `schemaData` so the renderer can look up its payload by id.
|
|
21
|
-
*
|
|
22
|
-
* Subclasses don't need to call `super.toMeta()` — the resolver stamps
|
|
23
|
-
* `serverData / poll / lazy / id` onto the meta after the subclass's own
|
|
24
|
-
* `toMeta()` runs. This keeps subclass meta authoring focused on the
|
|
25
|
-
* widget's own surface (label, type, columns, …).
|
|
26
|
-
*/
|
|
27
|
-
export abstract class ServerDataElement extends Element {
|
|
28
|
-
protected _id?: string
|
|
29
|
-
protected _poll?: number
|
|
30
|
-
// Default lazy=true (matches Filament v5's `$isLazy = true` default).
|
|
31
|
-
// `undefined` is treated as `true` everywhere; explicit `false` opts
|
|
32
|
-
// out (synchronous server-side resolve, ships data on first paint).
|
|
33
|
-
protected _lazy?: boolean
|
|
34
|
-
// Polling-endpoint URL stamped by `pageData.tagWidgetUrls`. The
|
|
35
|
-
// renderer reads `meta.widgetUrl` to fetch lazy data on mount and to
|
|
36
|
-
// re-fetch on `poll(seconds)` ticks. Set server-side per page-data
|
|
37
|
-
// pass — the field never round-trips back from the client.
|
|
38
|
-
protected _widgetUrl?: string
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Stable identifier. Required so the polling endpoint can find this
|
|
42
|
-
* element after re-walking the schema. Subclasses that use a fluent
|
|
43
|
-
* factory (`Chart.make('posts-chart')`) pass an explicit id; subclasses
|
|
44
|
-
* that don't (e.g. `View`, where the user extends with `class
|
|
45
|
-
* ContributionMap extends View {}`) fall back to the constructor's
|
|
46
|
-
* class name via `getId()`.
|
|
47
|
-
*/
|
|
48
|
-
getId(): string {
|
|
49
|
-
if (this._id) return this._id
|
|
50
|
-
const ctor = this.constructor as { name?: string }
|
|
51
|
-
return ctor.name ?? 'widget'
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** Set an explicit id. Useful when two instances of the same subclass
|
|
55
|
-
* appear on the same page (e.g. two `View.component(X)` widgets). */
|
|
56
|
-
id(value: string): this {
|
|
57
|
-
this._id = value
|
|
58
|
-
return this
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/** Polling interval in seconds. Number-only by design (cleaner than
|
|
62
|
-
* Filament's '30s' string). Zero / negative / non-finite values are
|
|
63
|
-
* ignored. */
|
|
64
|
-
poll(seconds: number): this {
|
|
65
|
-
if (Number.isFinite(seconds) && seconds > 0) this._poll = seconds
|
|
66
|
-
return this
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
getPoll(): number | undefined {
|
|
70
|
-
return this._poll
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Opt out of (or back into) lazy loading. Default is lazy: the server
|
|
75
|
-
* paints a skeleton on first render and the client fetches the
|
|
76
|
-
* payload via the polling endpoint on mount. `lazy(false)` makes the
|
|
77
|
-
* server resolve `getServerData(ctx)` synchronously and ship the
|
|
78
|
-
* payload with the page.
|
|
79
|
-
*/
|
|
80
|
-
lazy(value: boolean = true): this {
|
|
81
|
-
this._lazy = value
|
|
82
|
-
return this
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** True when this element should ship lazy (skeleton + first-paint
|
|
86
|
-
* fetch). Default is true; unset === true. */
|
|
87
|
-
isLazy(): boolean {
|
|
88
|
-
return this._lazy !== false
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** Stamp the polling-endpoint URL. Called by `pageData.tagWidgetUrls`
|
|
92
|
-
* during page-data builds — `${base}/_widget/:id` for panel-scope
|
|
93
|
-
* dashboards and `${base}/${pageSlug}/_widget/:id` for custom-page
|
|
94
|
-
* scope. The renderer reads `meta.widgetUrl` to fetch. */
|
|
95
|
-
withWidgetUrl(url: string): this {
|
|
96
|
-
this._widgetUrl = url
|
|
97
|
-
return this
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
getWidgetUrl(): string | undefined {
|
|
101
|
-
return this._widgetUrl
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/** Discriminator that pageData / routes use to find server-data
|
|
105
|
-
* elements without `instanceof` (Vite SSR module-cache duplication
|
|
106
|
-
* trap — same posture as `findForms`). */
|
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- structural marker
|
|
108
|
-
isServerDataElement(): true { return true }
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Compute this element's render-time payload. Receives the same
|
|
112
|
-
* `RenderContext` the resolver builds (record/user/values/$get/...).
|
|
113
|
-
* Implementations should return a JSON-clean value — the resolver
|
|
114
|
-
* stamps it under `_widgetData[id]` for the renderer to consume.
|
|
115
|
-
*
|
|
116
|
-
* May throw — `resolveServerDataElements` swallows the throw and
|
|
117
|
-
* stamps `_widgetData[id] = { error: '...' }` so a single failing
|
|
118
|
-
* widget doesn't blank the whole dashboard. The polling-endpoint
|
|
119
|
-
* path handles errors symmetrically.
|
|
120
|
-
*/
|
|
121
|
-
abstract resolveServerData(ctx: RenderContext): Promise<unknown>
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Structural type guard — Vite SSR module-cache duplication breaks
|
|
126
|
-
* `instanceof` across module-graph entries (see
|
|
127
|
-
* `feedback_vite_ssr_module_dup_instanceof.md`). Matches the
|
|
128
|
-
* `findForms / findActions / isRepeaterField / isBuilderField` pattern.
|
|
129
|
-
*/
|
|
130
|
-
export function isServerDataElement(el: Element): el is ServerDataElement {
|
|
131
|
-
const probe = el as unknown as { isServerDataElement?: () => unknown }
|
|
132
|
-
return typeof probe.isServerDataElement === 'function' && probe.isServerDataElement() === true
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Stamp `serverData / id / poll / lazy` onto an element's meta after
|
|
137
|
-
* subclass `toMeta()` runs. Called by `resolveSchema` for every
|
|
138
|
-
* `ServerDataElement`. Subclasses keep their `toMeta()` clean — they
|
|
139
|
-
* only emit their own surface (label, kind, columns, …).
|
|
140
|
-
*
|
|
141
|
-
* Only stamps `lazy: true` when explicit; undefined-default ships as
|
|
142
|
-
* `lazy: true` since the renderer treats absent as true. Keeps the wire
|
|
143
|
-
* compact for the synchronous case (`lazy(false)` → no key emitted, but
|
|
144
|
-
* `_widgetData[id]` already carries the payload).
|
|
145
|
-
*/
|
|
146
|
-
export function stampServerDataMeta(el: ServerDataElement, meta: ElementMeta): void {
|
|
147
|
-
meta['serverData'] = true
|
|
148
|
-
meta['id'] = el.getId()
|
|
149
|
-
const poll = el.getPoll()
|
|
150
|
-
if (poll !== undefined) meta['poll'] = poll
|
|
151
|
-
// Always emit `lazy` so the renderer doesn't have to fall back through
|
|
152
|
-
// a default — explicit > implicit on the wire.
|
|
153
|
-
meta['lazy'] = el.isLazy()
|
|
154
|
-
const widgetUrl = el.getWidgetUrl()
|
|
155
|
-
if (widgetUrl !== undefined) meta['widgetUrl'] = widgetUrl
|
|
156
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { SlotComponent } from './SlotComponent.js'
|
|
5
|
-
|
|
6
|
-
describe('SlotComponent schema primitive', () => {
|
|
7
|
-
it('emits component name and no props by default', () => {
|
|
8
|
-
const meta = SlotComponent.make('BookmarkButton').toMeta()
|
|
9
|
-
assert.equal(meta['type'], 'slotComponent')
|
|
10
|
-
assert.equal(meta['component'], 'BookmarkButton')
|
|
11
|
-
assert.equal('props' in meta, false)
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('ships .props({...}) verbatim under meta.props', () => {
|
|
15
|
-
const meta = SlotComponent.make('BookmarkButton')
|
|
16
|
-
.props({ basePath: '/admin', recordId: '42' })
|
|
17
|
-
.toMeta()
|
|
18
|
-
assert.deepEqual(meta['props'], { basePath: '/admin', recordId: '42' })
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('successive .props() calls merge shallowly', () => {
|
|
22
|
-
const meta = SlotComponent.make('X')
|
|
23
|
-
.props({ a: 1, b: 2 })
|
|
24
|
-
.props({ b: 3, c: 4 })
|
|
25
|
-
.toMeta()
|
|
26
|
-
assert.deepEqual(meta['props'], { a: 1, b: 3, c: 4 })
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('exposes the component name via getComponentName()', () => {
|
|
30
|
-
const el = SlotComponent.make('BookmarkButton')
|
|
31
|
-
assert.equal(el.getComponentName(), 'BookmarkButton')
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('inherits Element.visible() / hidden() / columnSpan', () => {
|
|
35
|
-
const el = SlotComponent.make('X').visible(false).columnSpan(2)
|
|
36
|
-
assert.equal(el.hasVisibilityRule(), true)
|
|
37
|
-
assert.deepEqual(el.getLayoutPositioning(), { columnSpan: 2 })
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('getType returns slotComponent (matches wire shape discriminator)', () => {
|
|
41
|
-
assert.equal(SlotComponent.make('X').getType(), 'slotComponent')
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
describe('Slot component runtime registry', () => {
|
|
46
|
-
it('registers, retrieves, and resets', async () => {
|
|
47
|
-
const { registerSlotComponents, getSlotComponent, _resetSlotComponentRegistryForTests } =
|
|
48
|
-
await import('../slot-components/registry.js')
|
|
49
|
-
_resetSlotComponentRegistryForTests()
|
|
50
|
-
const Stub = (() => null) as unknown as Parameters<typeof registerSlotComponents>[0][string]
|
|
51
|
-
registerSlotComponents({ Stub })
|
|
52
|
-
assert.equal(getSlotComponent('Stub'), Stub)
|
|
53
|
-
assert.equal(getSlotComponent('Missing'), undefined)
|
|
54
|
-
_resetSlotComponentRegistryForTests()
|
|
55
|
-
assert.equal(getSlotComponent('Stub'), undefined)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
it('skips falsy values during register', async () => {
|
|
59
|
-
const { registerSlotComponents, getSlotComponent, _resetSlotComponentRegistryForTests } =
|
|
60
|
-
await import('../slot-components/registry.js')
|
|
61
|
-
_resetSlotComponentRegistryForTests()
|
|
62
|
-
registerSlotComponents({ Bad: undefined as never })
|
|
63
|
-
assert.equal(getSlotComponent('Bad'), undefined)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('multiple registrations merge into the same registry', async () => {
|
|
67
|
-
const { registerSlotComponents, getSlotComponent, _resetSlotComponentRegistryForTests } =
|
|
68
|
-
await import('../slot-components/registry.js')
|
|
69
|
-
_resetSlotComponentRegistryForTests()
|
|
70
|
-
const A = (() => null) as never
|
|
71
|
-
const B = (() => null) as never
|
|
72
|
-
registerSlotComponents({ A })
|
|
73
|
-
registerSlotComponents({ B })
|
|
74
|
-
assert.equal(getSlotComponent('A'), A)
|
|
75
|
-
assert.equal(getSlotComponent('B'), B)
|
|
76
|
-
})
|
|
77
|
-
})
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { Element } from './Element.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Escape-hatch schema element that hands rendering off to a user-supplied
|
|
5
|
-
* React component registered via `registerSlotComponents()`. Distinct from
|
|
6
|
-
* `ComponentEntry` (which is record-bound and label-shelled for infolists)
|
|
7
|
-
* and from `View` (which is widget-shaped with `getData`/polling). Use for
|
|
8
|
-
* plugin-contributed UI that needs to mount inline at any schema position
|
|
9
|
-
* — toolbars, header chips, sidebar contributions, anywhere `Action` /
|
|
10
|
-
* `ActionGroup` would otherwise live.
|
|
11
|
-
*
|
|
12
|
-
* Wire shape ships only the registered name + a serialisable `props` bag.
|
|
13
|
-
* The `_components.ts` build-time manifest doesn't see runtime-registered
|
|
14
|
-
* components (they live in plugin packages, not `cfg.resources / globals
|
|
15
|
-
* / pages` statics), so the lookup happens at render via the runtime
|
|
16
|
-
* registry — same model as `registerEntryComponents` and
|
|
17
|
-
* `registerWidgetComponents`.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // bootstrap/providers.ts
|
|
21
|
-
* registerSlotComponents({ BookmarkButton })
|
|
22
|
-
*
|
|
23
|
-
* // A plugin / app contributes the chip into the resource-edit header:
|
|
24
|
-
* panel.renderHook(
|
|
25
|
-
* 'panels::resource.pages.edit-record.header.actions.before',
|
|
26
|
-
* (ctx) => [
|
|
27
|
-
* SlotComponent.make('BookmarkButton').props({
|
|
28
|
-
* basePath: ctx.basePath,
|
|
29
|
-
* resourceSlug: ctx.resource?.getSlug(),
|
|
30
|
-
* recordId: ctx.recordId,
|
|
31
|
-
* }),
|
|
32
|
-
* ],
|
|
33
|
-
* )
|
|
34
|
-
*/
|
|
35
|
-
export class SlotComponent extends Element {
|
|
36
|
-
protected _componentName: string
|
|
37
|
-
protected _props?: Record<string, unknown>
|
|
38
|
-
|
|
39
|
-
protected constructor(componentName: string) {
|
|
40
|
-
super()
|
|
41
|
-
this._componentName = componentName
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
static make(componentName: string): SlotComponent {
|
|
45
|
-
return new SlotComponent(componentName)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Static props passed verbatim to the registered component. Must be
|
|
50
|
-
* JSON-serialisable — they ride through `viewProps` to the client.
|
|
51
|
-
* Successive calls merge shallowly with the previous bag.
|
|
52
|
-
*/
|
|
53
|
-
props(props: Record<string, unknown>): this {
|
|
54
|
-
this._props = { ...(this._props ?? {}), ...props }
|
|
55
|
-
return this
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
getComponentName(): string {
|
|
59
|
-
return this._componentName
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
override getType(): string { return 'slotComponent' }
|
|
63
|
-
|
|
64
|
-
override toMeta(): Record<string, unknown> {
|
|
65
|
-
return {
|
|
66
|
-
type: 'slotComponent' as const,
|
|
67
|
-
component: this._componentName,
|
|
68
|
-
...(this._props ? { props: this._props } : {}),
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
package/src/schema/Split.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Element } from './Element.js'
|
|
2
|
-
|
|
3
|
-
export type SplitFrom = 'left' | 'right'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Two-column layout — main + aside. Renders as a stacked flex on small
|
|
7
|
-
* viewports and a horizontal flex on `@md` (container query). Children
|
|
8
|
-
* tagged with `.aside()` (e.g. `Section.aside()`) become the right-rail
|
|
9
|
-
* (or left, when `from('left')`); without explicit markers, the second
|
|
10
|
-
* child is treated as the aside.
|
|
11
|
-
*
|
|
12
|
-
* The renderer picks the aside-styled width from a small palette of
|
|
13
|
-
* shadcn-flavoured sidebar widths (~20rem). The main child grows to
|
|
14
|
-
* fill the remaining space.
|
|
15
|
-
*
|
|
16
|
-
* Useful for settings pages with a navigation card on the side, or for
|
|
17
|
-
* resource forms where the primary content is a long article body and
|
|
18
|
-
* the aside holds publish controls.
|
|
19
|
-
*/
|
|
20
|
-
export class Split extends Element {
|
|
21
|
-
private _from: SplitFrom = 'right'
|
|
22
|
-
private _gap = 6
|
|
23
|
-
|
|
24
|
-
private constructor() { super() }
|
|
25
|
-
|
|
26
|
-
static make(): Split {
|
|
27
|
-
return new Split()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Which side the aside child sits on. Defaults to `'right'`. */
|
|
31
|
-
from(side: SplitFrom): this { this._from = side; return this }
|
|
32
|
-
|
|
33
|
-
/** Gap between main and aside (Tailwind spacing scale). Default 6 (24px). */
|
|
34
|
-
gap(n: number): this { this._gap = n; return this }
|
|
35
|
-
|
|
36
|
-
schema(elements: Element[]): this {
|
|
37
|
-
this._children = elements
|
|
38
|
-
return this
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
getType(): string { return 'split' }
|
|
42
|
-
|
|
43
|
-
toMeta(): Record<string, unknown> {
|
|
44
|
-
return {
|
|
45
|
-
type: 'split' as const,
|
|
46
|
-
from: this._from,
|
|
47
|
-
gap: this._gap,
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|