spine-framework 0.1.61 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +223 -0
- package/README.md +327 -0
- package/package.json +107 -216
- package/src/cli/commands/init.ts +192 -0
- package/src/cli/commands/install.ts +25 -0
- package/src/cli/commands/list.ts +33 -0
- package/src/cli/commands/migrate.ts +24 -0
- package/src/cli/index.ts +46 -0
- package/src/components/AppLayout.tsx +21 -0
- package/src/components/AuthGuard.tsx +21 -0
- package/src/components/RoleGuard.tsx +23 -0
- package/src/components/index.ts +3 -0
- package/src/contexts/AppContext.tsx +122 -0
- package/src/contexts/AuthContext.tsx +87 -0
- package/src/contexts/SpineContext.tsx +46 -0
- package/src/contexts/index.ts +3 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useItems.ts +78 -0
- package/src/hooks/useThreads.ts +73 -0
- package/src/hooks/useWebSocket.ts +97 -0
- package/src/index.ts +22 -0
- package/src/types/index.ts +163 -0
- package/src/utils/api.ts +88 -0
- package/src/utils/client.ts +146 -0
- package/src/utils/config.ts +20 -0
- package/src/utils/index.ts +3 -0
- package/.framework/README.md +0 -129
- package/.framework/cli/bin.cjs +0 -14
- package/.framework/cli/commands/agents.ts +0 -153
- package/.framework/cli/commands/auth.ts +0 -94
- package/.framework/cli/commands/create-app.ts +0 -185
- package/.framework/cli/commands/dev.ts +0 -113
- package/.framework/cli/commands/doctor.ts +0 -442
- package/.framework/cli/commands/generate.ts +0 -332
- package/.framework/cli/commands/init.ts +0 -186
- package/.framework/cli/commands/install-app.ts +0 -565
- package/.framework/cli/commands/items.ts +0 -253
- package/.framework/cli/commands/migrate.ts +0 -139
- package/.framework/cli/commands/migrations.ts +0 -141
- package/.framework/cli/commands/pipelines.ts +0 -166
- package/.framework/cli/commands/status.ts +0 -197
- package/.framework/cli/commands/system.ts +0 -184
- package/.framework/cli/commands/test.ts +0 -227
- package/.framework/cli/commands/uninstall-app.ts +0 -166
- package/.framework/cli/context.ts +0 -268
- package/.framework/cli/env-loader.ts +0 -36
- package/.framework/cli/index.ts +0 -116
- package/.framework/cli/welcome.cjs +0 -45
- package/.framework/docs/API.md +0 -384
- package/.framework/docs/STABILITY.md +0 -52
- package/.framework/docs/admin-routes.md +0 -76
- package/.framework/docs/api-docs-progress.md +0 -38
- package/.framework/docs/api-governance.md +0 -146
- package/.framework/docs/api-testing-results.md +0 -212
- package/.framework/docs/apis/admin-configs.md +0 -567
- package/.framework/docs/apis/admin-data.md +0 -272
- package/.framework/docs/apis/index.md +0 -231
- package/.framework/docs/apis/internal.md +0 -295
- package/.framework/docs/apis/runtime.md +0 -537
- package/.framework/docs/assembly-launch-guide.md +0 -138
- package/.framework/docs/audit-results.md +0 -590
- package/.framework/docs/authorization-model.md +0 -170
- package/.framework/docs/db-api-inventory.md +0 -95
- package/.framework/docs/examples/custom-app/README.md +0 -77
- package/.framework/docs/examples/custom-function/README.md +0 -27
- package/.framework/docs/examples/custom-function/handler.ts +0 -48
- package/.framework/docs/examples/custom-webhook/README.md +0 -68
- package/.framework/docs/gap-remediation-backlog.md +0 -103
- package/.framework/docs/guides/cli-guide.md +0 -224
- package/.framework/docs/guides/getting-started.md +0 -103
- package/.framework/docs/guides/import-guide.md +0 -193
- package/.framework/docs/guides/testing-guide.md +0 -229
- package/.framework/docs/permission-examples.md +0 -326
- package/.framework/docs/ui-adoption-verification.md +0 -111
- package/.framework/docs/ui-api-coverage.md +0 -84
- package/.framework/docs/v2-compatibility-audit.md +0 -228
- package/.framework/functions/.gitkeep +0 -1
- package/.framework/functions/_shared/agent-runner.ts +0 -1097
- package/.framework/functions/_shared/app-manifest.ts +0 -184
- package/.framework/functions/_shared/audit.ts +0 -150
- package/.framework/functions/_shared/db.ts +0 -178
- package/.framework/functions/_shared/index.ts +0 -391
- package/.framework/functions/_shared/middleware.ts +0 -490
- package/.framework/functions/_shared/permissions.ts +0 -1325
- package/.framework/functions/_shared/pipeline-runner.ts +0 -731
- package/.framework/functions/_shared/principal.ts +0 -818
- package/.framework/functions/_shared/resolve-ids.ts +0 -106
- package/.framework/functions/_shared/schema-utils.ts +0 -967
- package/.framework/functions/_shared/testing.ts +0 -258
- package/.framework/functions/_shared/trigger-engine.ts +0 -425
- package/.framework/functions/_shared/webhook-registration.ts +0 -168
- package/.framework/functions/_shared/webhook-registry.ts +0 -129
- package/.framework/functions/account-nodes.ts +0 -111
- package/.framework/functions/admin-data.ts +0 -606
- package/.framework/functions/ai-agents.ts +0 -323
- package/.framework/functions/api-keys.ts +0 -376
- package/.framework/functions/apps.ts +0 -483
- package/.framework/functions/auth.ts +0 -196
- package/.framework/functions/debug-auth.ts +0 -107
- package/.framework/functions/embeddings.ts +0 -556
- package/.framework/functions/integration-routes.ts +0 -523
- package/.framework/functions/integrations.ts +0 -319
- package/.framework/functions/item-progress.ts +0 -272
- package/.framework/functions/logs.ts +0 -438
- package/.framework/functions/observability.ts +0 -275
- package/.framework/functions/pipeline-executions.ts +0 -494
- package/.framework/functions/pipelines.ts +0 -485
- package/.framework/functions/prompt-configs.ts +0 -339
- package/.framework/functions/roles.ts +0 -387
- package/.framework/functions/system-cron.ts +0 -742
- package/.framework/functions/system.ts +0 -323
- package/.framework/functions/tests.ts +0 -119
- package/.framework/functions/timers.ts +0 -357
- package/.framework/functions/triggers.ts +0 -563
- package/.framework/functions/types.ts +0 -604
- package/.framework/index.html +0 -16
- package/.framework/migrations/000_foundation.sql +0 -1266
- package/.framework/migrations/001_seed.sql +0 -163
- package/.framework/migrations/002_seed_constraints.sql +0 -19
- package/.framework/migrations/003_auth_user_trigger.sql +0 -67
- package/.framework/src/App.tsx +0 -126
- package/.framework/src/apps/admin/index.tsx +0 -173
- package/.framework/src/components/AppWrapper.tsx +0 -56
- package/.framework/src/components/CustomAppLoader.tsx +0 -116
- package/.framework/src/components/admin/AdminListPage.tsx +0 -151
- package/.framework/src/components/admin/AdminSidebar.tsx +0 -166
- package/.framework/src/components/admin/AdminStatsCard.tsx +0 -62
- package/.framework/src/components/admin/SortableTableHeader.tsx +0 -42
- package/.framework/src/components/app-shell/GenericAppShell.tsx +0 -181
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +0 -200
- package/.framework/src/components/app-shell/GenericListPage.tsx +0 -116
- package/.framework/src/components/app-sidebar.tsx +0 -228
- package/.framework/src/components/auth/ProtectedRoute.tsx +0 -88
- package/.framework/src/components/layout/AppShell.tsx +0 -91
- package/.framework/src/components/layout/Header.tsx +0 -88
- package/.framework/src/components/layout/Layout.tsx +0 -95
- package/.framework/src/components/layout/Sidebar.tsx +0 -329
- package/.framework/src/components/runtime/DataDetailHeader.tsx +0 -77
- package/.framework/src/components/runtime/DataDetailPage.tsx +0 -171
- package/.framework/src/components/runtime/DataFilters.tsx +0 -91
- package/.framework/src/components/runtime/DataHeader.tsx +0 -68
- package/.framework/src/components/runtime/DataListPage.tsx +0 -124
- package/.framework/src/components/runtime/DataStats.tsx +0 -70
- package/.framework/src/components/runtime/DataTable.tsx +0 -174
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +0 -134
- package/.framework/src/components/runtime/index.ts +0 -18
- package/.framework/src/components/search-form.tsx +0 -29
- package/.framework/src/components/shared/AgentView.tsx +0 -213
- package/.framework/src/components/shared/FieldRenderer.tsx +0 -478
- package/.framework/src/components/shared/SchemaFields.tsx +0 -226
- package/.framework/src/components/ui/DataTable.tsx +0 -343
- package/.framework/src/components/ui/Form.tsx +0 -281
- package/.framework/src/components/ui/ItemCard.tsx +0 -296
- package/.framework/src/components/ui/ItemListView.tsx +0 -308
- package/.framework/src/components/ui/LoadingSpinner.tsx +0 -52
- package/.framework/src/components/ui/Modal.tsx +0 -61
- package/.framework/src/components/ui/RichTextEditor.tsx +0 -210
- package/.framework/src/components/ui/accordion.tsx +0 -82
- package/.framework/src/components/ui/alert-dialog.tsx +0 -197
- package/.framework/src/components/ui/alert.tsx +0 -76
- package/.framework/src/components/ui/aspect-ratio.tsx +0 -11
- package/.framework/src/components/ui/avatar.tsx +0 -110
- package/.framework/src/components/ui/badge.tsx +0 -49
- package/.framework/src/components/ui/breadcrumb.tsx +0 -122
- package/.framework/src/components/ui/button-group.tsx +0 -83
- package/.framework/src/components/ui/button.tsx +0 -65
- package/.framework/src/components/ui/calendar.tsx +0 -222
- package/.framework/src/components/ui/card.tsx +0 -100
- package/.framework/src/components/ui/carousel.tsx +0 -240
- package/.framework/src/components/ui/chart.tsx +0 -368
- package/.framework/src/components/ui/checkbox.tsx +0 -31
- package/.framework/src/components/ui/collapsible.tsx +0 -33
- package/.framework/src/components/ui/combobox.tsx +0 -299
- package/.framework/src/components/ui/command.tsx +0 -193
- package/.framework/src/components/ui/context-menu.tsx +0 -261
- package/.framework/src/components/ui/dialog.tsx +0 -165
- package/.framework/src/components/ui/direction.tsx +0 -6
- package/.framework/src/components/ui/drawer.tsx +0 -132
- package/.framework/src/components/ui/dropdown-menu.tsx +0 -269
- package/.framework/src/components/ui/empty.tsx +0 -104
- package/.framework/src/components/ui/field.tsx +0 -238
- package/.framework/src/components/ui/hover-card.tsx +0 -42
- package/.framework/src/components/ui/input-group.tsx +0 -153
- package/.framework/src/components/ui/input-otp.tsx +0 -87
- package/.framework/src/components/ui/input.tsx +0 -19
- package/.framework/src/components/ui/item.tsx +0 -196
- package/.framework/src/components/ui/kbd.tsx +0 -26
- package/.framework/src/components/ui/label.tsx +0 -22
- package/.framework/src/components/ui/menubar.tsx +0 -277
- package/.framework/src/components/ui/native-select.tsx +0 -61
- package/.framework/src/components/ui/navigation-menu.tsx +0 -164
- package/.framework/src/components/ui/pagination.tsx +0 -129
- package/.framework/src/components/ui/popover.tsx +0 -87
- package/.framework/src/components/ui/progress.tsx +0 -31
- package/.framework/src/components/ui/radio-group.tsx +0 -42
- package/.framework/src/components/ui/resizable.tsx +0 -50
- package/.framework/src/components/ui/scroll-area.tsx +0 -53
- package/.framework/src/components/ui/select.tsx +0 -195
- package/.framework/src/components/ui/separator.tsx +0 -26
- package/.framework/src/components/ui/sheet.tsx +0 -145
- package/.framework/src/components/ui/sidebar.tsx +0 -706
- package/.framework/src/components/ui/skeleton.tsx +0 -13
- package/.framework/src/components/ui/slider.tsx +0 -59
- package/.framework/src/components/ui/sonner.tsx +0 -47
- package/.framework/src/components/ui/spinner.tsx +0 -10
- package/.framework/src/components/ui/switch.tsx +0 -33
- package/.framework/src/components/ui/table-primitives.tsx +0 -141
- package/.framework/src/components/ui/table.tsx +0 -114
- package/.framework/src/components/ui/tabs.tsx +0 -90
- package/.framework/src/components/ui/textarea.tsx +0 -18
- package/.framework/src/components/ui/toggle-group.tsx +0 -89
- package/.framework/src/components/ui/toggle.tsx +0 -45
- package/.framework/src/components/ui/tooltip.tsx +0 -57
- package/.framework/src/contexts/AppContext.tsx +0 -133
- package/.framework/src/contexts/AuthContext.tsx +0 -371
- package/.framework/src/hooks/use-mobile.ts +0 -19
- package/.framework/src/hooks/useApi.ts +0 -526
- package/.framework/src/hooks/useApps.ts +0 -114
- package/.framework/src/hooks/useEntityList.ts +0 -190
- package/.framework/src/hooks/useEntityRecord.ts +0 -308
- package/.framework/src/hooks/useForm.ts +0 -307
- package/.framework/src/hooks/useListSchema.ts +0 -264
- package/.framework/src/hooks/useSchemaRecord.ts +0 -223
- package/.framework/src/index.css +0 -128
- package/.framework/src/lib/api.ts +0 -156
- package/.framework/src/lib/supabase.ts +0 -94
- package/.framework/src/lib/utils.ts +0 -317
- package/.framework/src/main.tsx +0 -27
- package/.framework/src/pages/DashboardPage.tsx +0 -181
- package/.framework/src/pages/NotFoundPage.tsx +0 -39
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +0 -161
- package/.framework/src/pages/admin/AIAgentsPage.tsx +0 -318
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +0 -199
- package/.framework/src/pages/admin/APIKeysPage.tsx +0 -303
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +0 -523
- package/.framework/src/pages/admin/AppDetailPage.tsx +0 -493
- package/.framework/src/pages/admin/AppsPage.tsx +0 -355
- package/.framework/src/pages/admin/DesignedPage.tsx +0 -491
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +0 -534
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +0 -424
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +0 -176
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +0 -109
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +0 -402
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +0 -187
- package/.framework/src/pages/admin/IntegrationsPage.tsx +0 -301
- package/.framework/src/pages/admin/LogsPage.tsx +0 -283
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +0 -85
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +0 -470
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +0 -183
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +0 -279
- package/.framework/src/pages/admin/PipelinesPage.tsx +0 -390
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +0 -299
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +0 -292
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +0 -434
- package/.framework/src/pages/admin/RoleDetailPage.tsx +0 -273
- package/.framework/src/pages/admin/RolesPage.tsx +0 -292
- package/.framework/src/pages/admin/SelectTestPage.tsx +0 -61
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +0 -588
- package/.framework/src/pages/admin/SimpleDashboard.tsx +0 -387
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +0 -172
- package/.framework/src/pages/admin/TestingDashboard.tsx +0 -257
- package/.framework/src/pages/admin/TimerDetailPage.tsx +0 -151
- package/.framework/src/pages/admin/TimersPage.tsx +0 -376
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +0 -149
- package/.framework/src/pages/admin/TriggersPage.tsx +0 -381
- package/.framework/src/pages/admin/TypeDetailPage.tsx +0 -694
- package/.framework/src/pages/admin/TypesPage.tsx +0 -295
- package/.framework/src/pages/auth/LoginPage.tsx +0 -187
- package/.framework/src/pages/auth/RegisterPage.tsx +0 -163
- package/.framework/src/pages/spine-framework/APIPage.tsx +0 -17
- package/.framework/src/pages/spine-framework/CLIPage.tsx +0 -25
- package/.framework/src/types/auth.ts +0 -125
- package/.framework/src/types/types.ts +0 -407
- package/STRUCTURE.md +0 -150
- package/bin/spine-framework.cjs +0 -62
- package/bin/welcome.cjs +0 -45
- package/bin/ws-shim.cjs +0 -8
- package/bin/ws-shim.ts +0 -10
- package/config/components.json +0 -25
- package/config/deno.lock +0 -108
- package/config/package-lock.json +0 -17183
- package/config/postcss.config.cjs +0 -10
- package/config/tailwind.config.cjs +0 -78
- package/config/tsconfig.build.json +0 -32
- package/config/tsconfig.cli.json +0 -18
- package/config/tsconfig.json +0 -41
- package/config/tsconfig.node.json +0 -17
- package/config/tsconfig.node.tsbuildinfo +0 -1
- package/config/tsconfig.tsbuildinfo +0 -1
- package/config/typedoc.json +0 -16
- package/config/vite.config.d.ts +0 -2
- package/config/vite.config.ts +0 -72
- package/dist/cli/commands/agents.d.ts +0 -39
- package/dist/cli/commands/agents.d.ts.map +0 -1
- package/dist/cli/commands/auth.d.ts +0 -36
- package/dist/cli/commands/auth.d.ts.map +0 -1
- package/dist/cli/commands/create-app.d.ts +0 -23
- package/dist/cli/commands/create-app.d.ts.map +0 -1
- package/dist/cli/commands/dev.d.ts +0 -24
- package/dist/cli/commands/dev.d.ts.map +0 -1
- package/dist/cli/commands/doctor.d.ts +0 -42
- package/dist/cli/commands/doctor.d.ts.map +0 -1
- package/dist/cli/commands/generate.d.ts +0 -36
- package/dist/cli/commands/generate.d.ts.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -20
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/install-app.d.ts +0 -30
- package/dist/cli/commands/install-app.d.ts.map +0 -1
- package/dist/cli/commands/items.d.ts +0 -45
- package/dist/cli/commands/items.d.ts.map +0 -1
- package/dist/cli/commands/migrate.d.ts +0 -21
- package/dist/cli/commands/migrate.d.ts.map +0 -1
- package/dist/cli/commands/migrations.d.ts +0 -41
- package/dist/cli/commands/migrations.d.ts.map +0 -1
- package/dist/cli/commands/pipelines.d.ts +0 -40
- package/dist/cli/commands/pipelines.d.ts.map +0 -1
- package/dist/cli/commands/status.d.ts +0 -23
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/system.d.ts +0 -29
- package/dist/cli/commands/system.d.ts.map +0 -1
- package/dist/cli/commands/test.d.ts +0 -46
- package/dist/cli/commands/test.d.ts.map +0 -1
- package/dist/cli/commands/uninstall-app.d.ts +0 -23
- package/dist/cli/commands/uninstall-app.d.ts.map +0 -1
- package/dist/cli/context.d.ts +0 -88
- package/dist/cli/context.d.ts.map +0 -1
- package/dist/cli/env-loader.d.ts +0 -14
- package/dist/cli/env-loader.d.ts.map +0 -1
- package/dist/cli/index.d.ts +0 -41
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/functions/_shared/agent-runner.d.ts +0 -156
- package/dist/functions/_shared/agent-runner.d.ts.map +0 -1
- package/dist/functions/_shared/app-manifest.d.ts +0 -68
- package/dist/functions/_shared/app-manifest.d.ts.map +0 -1
- package/dist/functions/_shared/audit.d.ts +0 -91
- package/dist/functions/_shared/audit.d.ts.map +0 -1
- package/dist/functions/_shared/db.d.ts +0 -125
- package/dist/functions/_shared/db.d.ts.map +0 -1
- package/dist/functions/_shared/index.d.ts +0 -299
- package/dist/functions/_shared/index.d.ts.map +0 -1
- package/dist/functions/_shared/middleware.d.ts +0 -315
- package/dist/functions/_shared/middleware.d.ts.map +0 -1
- package/dist/functions/_shared/permissions.d.ts +0 -626
- package/dist/functions/_shared/permissions.d.ts.map +0 -1
- package/dist/functions/_shared/pipeline-runner.d.ts +0 -124
- package/dist/functions/_shared/pipeline-runner.d.ts.map +0 -1
- package/dist/functions/_shared/principal.d.ts +0 -284
- package/dist/functions/_shared/principal.d.ts.map +0 -1
- package/dist/functions/_shared/resolve-ids.d.ts +0 -10
- package/dist/functions/_shared/resolve-ids.d.ts.map +0 -1
- package/dist/functions/_shared/schema-utils.d.ts +0 -181
- package/dist/functions/_shared/schema-utils.d.ts.map +0 -1
- package/dist/functions/_shared/testing.d.ts +0 -172
- package/dist/functions/_shared/testing.d.ts.map +0 -1
- package/dist/functions/_shared/trigger-engine.d.ts +0 -140
- package/dist/functions/_shared/trigger-engine.d.ts.map +0 -1
- package/dist/functions/_shared/webhook-registration.d.ts +0 -81
- package/dist/functions/_shared/webhook-registration.d.ts.map +0 -1
- package/dist/functions/_shared/webhook-registry.d.ts +0 -57
- package/dist/functions/_shared/webhook-registry.d.ts.map +0 -1
- package/dist/functions/account-nodes.d.ts +0 -48
- package/dist/functions/account-nodes.d.ts.map +0 -1
- package/dist/functions/admin-data.d.ts +0 -178
- package/dist/functions/admin-data.d.ts.map +0 -1
- package/dist/functions/ai-agents.d.ts +0 -125
- package/dist/functions/ai-agents.d.ts.map +0 -1
- package/dist/functions/api-keys.d.ts +0 -140
- package/dist/functions/api-keys.d.ts.map +0 -1
- package/dist/functions/apps.d.ts +0 -163
- package/dist/functions/apps.d.ts.map +0 -1
- package/dist/functions/auth.d.ts +0 -74
- package/dist/functions/auth.d.ts.map +0 -1
- package/dist/functions/debug-auth.d.ts +0 -33
- package/dist/functions/debug-auth.d.ts.map +0 -1
- package/dist/functions/embeddings.d.ts +0 -205
- package/dist/functions/embeddings.d.ts.map +0 -1
- package/dist/functions/integration-routes.d.ts +0 -45
- package/dist/functions/integration-routes.d.ts.map +0 -1
- package/dist/functions/integrations.d.ts +0 -124
- package/dist/functions/integrations.d.ts.map +0 -1
- package/dist/functions/item-progress.d.ts +0 -41
- package/dist/functions/item-progress.d.ts.map +0 -1
- package/dist/functions/logs.d.ts +0 -162
- package/dist/functions/logs.d.ts.map +0 -1
- package/dist/functions/observability.d.ts +0 -123
- package/dist/functions/observability.d.ts.map +0 -1
- package/dist/functions/pipeline-executions.d.ts +0 -190
- package/dist/functions/pipeline-executions.d.ts.map +0 -1
- package/dist/functions/pipelines.d.ts +0 -171
- package/dist/functions/pipelines.d.ts.map +0 -1
- package/dist/functions/prompt-configs.d.ts +0 -125
- package/dist/functions/prompt-configs.d.ts.map +0 -1
- package/dist/functions/roles.d.ts +0 -118
- package/dist/functions/roles.d.ts.map +0 -1
- package/dist/functions/system-cron.d.ts +0 -65
- package/dist/functions/system-cron.d.ts.map +0 -1
- package/dist/functions/system.d.ts +0 -29
- package/dist/functions/system.d.ts.map +0 -1
- package/dist/functions/tests.d.ts +0 -28
- package/dist/functions/tests.d.ts.map +0 -1
- package/dist/functions/timers.d.ts +0 -139
- package/dist/functions/timers.d.ts.map +0 -1
- package/dist/functions/triggers.d.ts +0 -203
- package/dist/functions/triggers.d.ts.map +0 -1
- package/dist/functions/types.d.ts +0 -151
- package/dist/functions/types.d.ts.map +0 -1
- package/dist/src/types/types.d.ts +0 -364
- package/dist/src/types/types.d.ts.map +0 -1
- package/index.html +0 -13
- package/netlify.toml +0 -36
- package/package-project.json +0 -64
- package/scripts/app-install-cli.ts +0 -286
- package/scripts/assemble-frontend.sh +0 -79
- package/scripts/assemble-functions.sh +0 -62
- package/scripts/assemble.sh +0 -41
- package/scripts/boundary-check.sh +0 -106
- package/scripts/build-manifest.sh +0 -80
- package/scripts/check-core-integrity.sh +0 -82
- package/scripts/ingest-chunks.cjs +0 -202
- package/scripts/kb-chunk-parser.cjs +0 -312
- package/scripts/kb-chunk-parser.ts +0 -330
- package/scripts/load-test-app-install.ts +0 -484
- package/scripts/netlify-dev-wrapper.sh +0 -22
- package/scripts/verify-integrity.sh +0 -69
- package/vitest.config.ts +0 -45
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/components/shared/SchemaFields
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-component
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Schema-driven field grid. Renders an ordered list of `FieldDefinition`
|
|
8
|
-
* entries via `FieldRenderer`, managing the name→value mapping and
|
|
9
|
-
* propagating `onChange` calls back to the parent.
|
|
10
|
-
*
|
|
11
|
-
* **Value source resolution** (per field):
|
|
12
|
-
* - `system` flag set → `data[name]` (top-level column)
|
|
13
|
-
* - `system` flag unset → `data.data?.[name] ?? data[name]` (JSONB field
|
|
14
|
-
* with column fallback)
|
|
15
|
-
*
|
|
16
|
-
* **Layout:** two-column responsive grid by default (`twoColumn=true`);
|
|
17
|
-
* pass `twoColumn=false` for a single-column stacked layout.
|
|
18
|
-
*
|
|
19
|
-
* **Exports:**
|
|
20
|
-
* - `SchemaFields` — full editable/read-only field grid
|
|
21
|
-
* - `SchemaFieldDisplay` — read-only single-field key:value display row
|
|
22
|
-
* - `SchemaField` (unexported) — internal wrapper binding name to value
|
|
23
|
-
*
|
|
24
|
-
* @seeAlso src/components/shared/FieldRenderer.tsx
|
|
25
|
-
* @seeAlso src/types/types.ts (FieldDefinition)
|
|
26
|
-
* @seeAlso src/components/runtime/SchemaDetailForm.tsx (primary consumer)
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
import React from 'react'
|
|
30
|
-
import { FieldDefinition } from '../../types/types'
|
|
31
|
-
import { FieldRenderer } from './FieldRenderer'
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Props for `SchemaFields`.
|
|
35
|
-
*
|
|
36
|
-
* @prop fields - Ordered array of field definitions to render
|
|
37
|
-
* @prop data - Record containing current field values; may be flat or
|
|
38
|
-
* nested under a `.data` key for JSONB fields
|
|
39
|
-
* @prop onChange - `(name, value)` callback; omit for pure read-only display
|
|
40
|
-
* @prop readonly - Passes read-only mode down to every `FieldRenderer`
|
|
41
|
-
* @prop errors - Per-field validation error messages
|
|
42
|
-
* @prop twoColumn - Two-column responsive grid (default: `true`)
|
|
43
|
-
* @prop displayTypes - Widget override map keyed by field name (from view config)
|
|
44
|
-
*/
|
|
45
|
-
interface SchemaFieldsProps {
|
|
46
|
-
fields: FieldDefinition[]
|
|
47
|
-
data: Record<string, any>
|
|
48
|
-
onChange?: (name: string, value: any) => void
|
|
49
|
-
readonly?: boolean
|
|
50
|
-
errors?: Record<string, string>
|
|
51
|
-
/** Render fields in a two-column grid (default: true) */
|
|
52
|
-
twoColumn?: boolean
|
|
53
|
-
/** display_type per field key, sourced from view config — never from field definitions */
|
|
54
|
-
displayTypes?: Record<string, string>
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Renders a full schema field grid.
|
|
59
|
-
*
|
|
60
|
-
* @param props - `SchemaFieldsProps`
|
|
61
|
-
* @returns Two-column (or single-column) field grid, or an empty-state message
|
|
62
|
-
* @sideEffects none (delegates changes to `onChange`)
|
|
63
|
-
*/
|
|
64
|
-
export function SchemaFields({
|
|
65
|
-
fields,
|
|
66
|
-
data,
|
|
67
|
-
onChange,
|
|
68
|
-
readonly = false,
|
|
69
|
-
errors = {},
|
|
70
|
-
twoColumn = true,
|
|
71
|
-
displayTypes = {}
|
|
72
|
-
}: SchemaFieldsProps) {
|
|
73
|
-
if (!fields || fields.length === 0) {
|
|
74
|
-
return (
|
|
75
|
-
<p className="text-sm text-slate-500 italic">No schema fields defined for this type.</p>
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<div className={twoColumn ? 'grid grid-cols-1 md:grid-cols-2 gap-4' : 'space-y-4'}>
|
|
81
|
-
{fields.filter(f => !!f.name).map((field) => {
|
|
82
|
-
const name = field.name!
|
|
83
|
-
return (
|
|
84
|
-
<SchemaField
|
|
85
|
-
key={name}
|
|
86
|
-
field={field}
|
|
87
|
-
value={field.system ? data[name] : (data.data?.[name] ?? data[name])}
|
|
88
|
-
onChange={onChange}
|
|
89
|
-
readonly={readonly || field.readonly}
|
|
90
|
-
error={errors[name]}
|
|
91
|
-
displayType={displayTypes[name]}
|
|
92
|
-
/>
|
|
93
|
-
)
|
|
94
|
-
})}
|
|
95
|
-
</div>
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** Internal props for the `SchemaField` name-binding wrapper. */
|
|
100
|
-
interface SchemaFieldProps {
|
|
101
|
-
field: FieldDefinition
|
|
102
|
-
value: any
|
|
103
|
-
onChange?: (name: string, value: any) => void
|
|
104
|
-
readonly?: boolean
|
|
105
|
-
error?: string
|
|
106
|
-
displayType?: string
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function SchemaField({ field, value, onChange, readonly, error, displayType }: SchemaFieldProps) {
|
|
110
|
-
return (
|
|
111
|
-
<FieldRenderer
|
|
112
|
-
field={field}
|
|
113
|
-
value={value}
|
|
114
|
-
onChange={readonly ? undefined : (val) => field.name && onChange?.(field.name, val)}
|
|
115
|
-
readonly={readonly}
|
|
116
|
-
error={error}
|
|
117
|
-
displayType={displayType}
|
|
118
|
-
/>
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Read-only display of a single schema field value as a label:value row.
|
|
124
|
-
* Useful for compact detail views outside the full form layout.
|
|
125
|
-
*
|
|
126
|
-
* @param field - Field definition (used for label and data_type formatting)
|
|
127
|
-
* @param value - Raw value to display
|
|
128
|
-
* @returns A `<div>` with label on the left and formatted value on the right
|
|
129
|
-
* @sideEffects none (pure rendering)
|
|
130
|
-
*/
|
|
131
|
-
export function SchemaFieldDisplay({
|
|
132
|
-
field,
|
|
133
|
-
value
|
|
134
|
-
}: {
|
|
135
|
-
field: FieldDefinition
|
|
136
|
-
value: any
|
|
137
|
-
}) {
|
|
138
|
-
const displayValue = formatFieldValue(field, value)
|
|
139
|
-
|
|
140
|
-
return (
|
|
141
|
-
<div className="flex justify-between items-start py-2">
|
|
142
|
-
<dt className="text-xs text-slate-500 font-medium flex-shrink-0 mr-4">
|
|
143
|
-
{field.label || field.name}:
|
|
144
|
-
</dt>
|
|
145
|
-
<dd className="text-sm text-slate-900 text-right">
|
|
146
|
-
{displayValue}
|
|
147
|
-
</dd>
|
|
148
|
-
</div>
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Formats a raw field value for read-only display, applying type-specific
|
|
154
|
-
* transformations:
|
|
155
|
-
* - `boolean`/`checkbox` → `'Yes'` / `'No'`
|
|
156
|
-
* - `date` / `datetime` → locale string
|
|
157
|
-
* - `select` → resolves option label from `field.options`
|
|
158
|
-
* - `multiselect` → comma-joined option labels
|
|
159
|
-
* - `json` → `<pre>` code block
|
|
160
|
-
* - `url` → `<a>` link
|
|
161
|
-
* - Null/undefined/empty → em-dash placeholder
|
|
162
|
-
*
|
|
163
|
-
* @param field - Field definition
|
|
164
|
-
* @param value - Raw value
|
|
165
|
-
* @returns Formatted `ReactNode`
|
|
166
|
-
*/
|
|
167
|
-
function formatFieldValue(field: FieldDefinition, value: any): React.ReactNode {
|
|
168
|
-
if (value === null || value === undefined || value === '') {
|
|
169
|
-
return <span className="text-slate-400 italic">—</span>
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
switch (field.data_type) {
|
|
173
|
-
case 'boolean':
|
|
174
|
-
case 'checkbox':
|
|
175
|
-
return value ? 'Yes' : 'No'
|
|
176
|
-
|
|
177
|
-
case 'date':
|
|
178
|
-
try {
|
|
179
|
-
return new Date(value).toLocaleDateString()
|
|
180
|
-
} catch {
|
|
181
|
-
return String(value)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
case 'datetime':
|
|
185
|
-
try {
|
|
186
|
-
return new Date(value).toLocaleString()
|
|
187
|
-
} catch {
|
|
188
|
-
return String(value)
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
case 'select': {
|
|
192
|
-
const option = field.options?.find(o => typeof o === 'object' && o.value === value)
|
|
193
|
-
return option && typeof option === 'object' ? option.label : String(value)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
case 'multiselect': {
|
|
197
|
-
if (!Array.isArray(value)) return String(value)
|
|
198
|
-
return value.map(v => {
|
|
199
|
-
const option = field.options?.find(o => typeof o === 'object' && o.value === v)
|
|
200
|
-
return option && typeof option === 'object' ? option.label : v
|
|
201
|
-
}).join(', ')
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
case 'json':
|
|
205
|
-
return (
|
|
206
|
-
<pre className="text-xs bg-slate-50 rounded p-2 max-w-xs overflow-x-auto">
|
|
207
|
-
{JSON.stringify(value, null, 2)}
|
|
208
|
-
</pre>
|
|
209
|
-
)
|
|
210
|
-
|
|
211
|
-
case 'url':
|
|
212
|
-
return (
|
|
213
|
-
<a
|
|
214
|
-
href={value}
|
|
215
|
-
target="_blank"
|
|
216
|
-
rel="noopener noreferrer"
|
|
217
|
-
className="text-blue-600 hover:text-blue-800 underline"
|
|
218
|
-
>
|
|
219
|
-
{value}
|
|
220
|
-
</a>
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
default:
|
|
224
|
-
return String(value)
|
|
225
|
-
}
|
|
226
|
-
}
|
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/components/ui/DataTable
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-component
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Higher-level table wrapper that adds search, column filters, active-filter
|
|
8
|
-
* chips, and pagination using shadcn/ui table primitives.
|
|
9
|
-
*
|
|
10
|
-
* **Search:** when `searchable=true`, renders a text input that calls
|
|
11
|
-
* `onSearch` on each keystroke and shows an active chip while a query
|
|
12
|
-
* is present.
|
|
13
|
-
*
|
|
14
|
-
* **Column filters:** columns with `filterable=true` and `filterOptions`
|
|
15
|
-
* appear in an expandable filter panel as `<select>` dropdowns. Active
|
|
16
|
-
* filter chips are shown above the table; each chip has an inline
|
|
17
|
-
* dismiss button.
|
|
18
|
-
*
|
|
19
|
-
* **Pagination:** built-in pagination controls using shadcn Button components.
|
|
20
|
-
*
|
|
21
|
-
* @seeAlso src/components/ui/table.tsx
|
|
22
|
-
* @seeAlso src/lib/utils.ts (cn)
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import React, { useState } from 'react'
|
|
26
|
-
import {
|
|
27
|
-
Table,
|
|
28
|
-
TableBody,
|
|
29
|
-
TableCell,
|
|
30
|
-
TableHead,
|
|
31
|
-
TableHeader,
|
|
32
|
-
TableRow,
|
|
33
|
-
} from './table'
|
|
34
|
-
import { Badge } from './badge'
|
|
35
|
-
import { Button } from './button'
|
|
36
|
-
import { Search, Filter } from 'lucide-react'
|
|
37
|
-
import { cn } from '../../lib/utils'
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Column definition for DataTable
|
|
41
|
-
*/
|
|
42
|
-
interface TableColumn<T> {
|
|
43
|
-
key: keyof T | string
|
|
44
|
-
title: string
|
|
45
|
-
render?: (row: T) => React.ReactNode
|
|
46
|
-
sortable?: boolean
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Extends `TableColumn<T>` with column-level filter support.
|
|
51
|
-
*/
|
|
52
|
-
interface DataTableColumn<T> extends TableColumn<T> {
|
|
53
|
-
filterable?: boolean
|
|
54
|
-
filterOptions?: Array<{ value: string; label: string }>
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Props for `DataTable<T>`.
|
|
59
|
-
*
|
|
60
|
-
* @prop data - Row data array
|
|
61
|
-
* @prop columns - Column descriptors (may include filter config)
|
|
62
|
-
* @prop loading - Shows spinner while true
|
|
63
|
-
* @prop searchable - Shows search input (default: `true`)
|
|
64
|
-
* @prop searchPlaceholder - Placeholder text for the search input
|
|
65
|
-
* @prop filterable - Shows the filter toggle button (default: `true`)
|
|
66
|
-
* @prop pagination - Pagination config; omit to hide pagination
|
|
67
|
-
* @prop onSort / sortColumn / sortDirection - Sort state and callback
|
|
68
|
-
* @prop onRowClick - Row click callback
|
|
69
|
-
* @prop onSearch - Callback invoked with the current search query
|
|
70
|
-
* @prop onFilter - Callback invoked with the active filter map
|
|
71
|
-
* @prop emptyMessage - Empty-state text
|
|
72
|
-
*/
|
|
73
|
-
interface DataTableProps<T> {
|
|
74
|
-
data: T[]
|
|
75
|
-
columns: DataTableColumn<T>[]
|
|
76
|
-
loading?: boolean
|
|
77
|
-
searchable?: boolean
|
|
78
|
-
searchPlaceholder?: string
|
|
79
|
-
filterable?: boolean
|
|
80
|
-
pagination?: {
|
|
81
|
-
currentPage: number
|
|
82
|
-
totalPages: number
|
|
83
|
-
totalItems: number
|
|
84
|
-
itemsPerPage: number
|
|
85
|
-
onPageChange: (page: number) => void
|
|
86
|
-
onItemsPerPageChange: (itemsPerPage: number) => void
|
|
87
|
-
}
|
|
88
|
-
onSort?: (column: keyof T, direction: 'asc' | 'desc') => void
|
|
89
|
-
sortColumn?: keyof T
|
|
90
|
-
sortDirection?: 'asc' | 'desc'
|
|
91
|
-
onRowClick?: (item: T) => void
|
|
92
|
-
onSearch?: (query: string) => void
|
|
93
|
-
onFilter?: (filters: Record<string, any>) => void
|
|
94
|
-
emptyMessage?: string
|
|
95
|
-
className?: string
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Full-featured data table with search, filters, sort, and pagination.
|
|
100
|
-
*
|
|
101
|
-
* @param props - `DataTableProps<T>`
|
|
102
|
-
* @returns Search/filter bar + `Table` + optional `TablePagination`
|
|
103
|
-
* @sideEffects none (all state changes delegated to callbacks)
|
|
104
|
-
*/
|
|
105
|
-
export function DataTable<T extends Record<string, any>>({
|
|
106
|
-
data,
|
|
107
|
-
columns,
|
|
108
|
-
loading = false,
|
|
109
|
-
searchable = true,
|
|
110
|
-
searchPlaceholder = 'Search...',
|
|
111
|
-
filterable = true,
|
|
112
|
-
pagination,
|
|
113
|
-
onSort,
|
|
114
|
-
sortColumn,
|
|
115
|
-
sortDirection,
|
|
116
|
-
onRowClick,
|
|
117
|
-
onSearch,
|
|
118
|
-
onFilter,
|
|
119
|
-
emptyMessage = 'No data available',
|
|
120
|
-
className
|
|
121
|
-
}: DataTableProps<T>) {
|
|
122
|
-
const [searchQuery, setSearchQuery] = useState('')
|
|
123
|
-
const [filters, setFilters] = useState<Record<string, any>>({})
|
|
124
|
-
const [showFilters, setShowFilters] = useState(false)
|
|
125
|
-
|
|
126
|
-
const handleSearch = (query: string) => {
|
|
127
|
-
setSearchQuery(query)
|
|
128
|
-
onSearch?.(query)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const handleFilter = (key: string, value: any) => {
|
|
132
|
-
const newFilters = { ...filters, [key]: value }
|
|
133
|
-
if (value === '' || value === null || value === undefined) {
|
|
134
|
-
delete newFilters[key]
|
|
135
|
-
}
|
|
136
|
-
setFilters(newFilters)
|
|
137
|
-
onFilter?.(newFilters)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const clearFilters = () => {
|
|
141
|
-
setFilters({})
|
|
142
|
-
onFilter?.({})
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const hasActiveFilters = Object.keys(filters).length > 0
|
|
146
|
-
const hasActiveSearch = searchQuery.length > 0
|
|
147
|
-
|
|
148
|
-
return (
|
|
149
|
-
<div className={cn('space-y-4', className)}>
|
|
150
|
-
{/* Search and Filters */}
|
|
151
|
-
{(searchable || filterable) && (
|
|
152
|
-
<div className="bg-card shadow rounded-lg p-4">
|
|
153
|
-
<div className="flex flex-col sm:flex-row gap-4">
|
|
154
|
-
{/* Search */}
|
|
155
|
-
{searchable && (
|
|
156
|
-
<div className="flex-1">
|
|
157
|
-
<div className="relative">
|
|
158
|
-
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5 text-muted-foreground" />
|
|
159
|
-
<input
|
|
160
|
-
type="text"
|
|
161
|
-
placeholder={searchPlaceholder}
|
|
162
|
-
value={searchQuery}
|
|
163
|
-
onChange={(e) => handleSearch(e.target.value)}
|
|
164
|
-
className="pl-10 pr-4 py-2 w-full border border-input rounded-md focus:ring-ring focus:border-ring"
|
|
165
|
-
/>
|
|
166
|
-
</div>
|
|
167
|
-
</div>
|
|
168
|
-
)}
|
|
169
|
-
|
|
170
|
-
{/* Filters */}
|
|
171
|
-
{filterable && (
|
|
172
|
-
<div className="flex items-center space-x-2">
|
|
173
|
-
<Button
|
|
174
|
-
variant="outline"
|
|
175
|
-
size="sm"
|
|
176
|
-
onClick={() => setShowFilters(!showFilters)}
|
|
177
|
-
className={cn(
|
|
178
|
-
hasActiveFilters && 'bg-primary/10 border-primary text-primary'
|
|
179
|
-
)}
|
|
180
|
-
>
|
|
181
|
-
<Filter className="h-4 w-4 mr-2" />
|
|
182
|
-
Filters
|
|
183
|
-
{hasActiveFilters && (
|
|
184
|
-
<Badge variant="info">
|
|
185
|
-
{Object.keys(filters).length}
|
|
186
|
-
</Badge>
|
|
187
|
-
)}
|
|
188
|
-
</Button>
|
|
189
|
-
|
|
190
|
-
{hasActiveFilters && (
|
|
191
|
-
<Button variant="ghost" size="sm" onClick={clearFilters}>
|
|
192
|
-
Clear
|
|
193
|
-
</Button>
|
|
194
|
-
)}
|
|
195
|
-
</div>
|
|
196
|
-
)}
|
|
197
|
-
</div>
|
|
198
|
-
|
|
199
|
-
{/* Advanced Filters */}
|
|
200
|
-
{showFilters && filterable && (
|
|
201
|
-
<div className="mt-4 pt-4 border-t border-border">
|
|
202
|
-
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
203
|
-
{columns
|
|
204
|
-
.filter(column => column.filterable && column.filterOptions)
|
|
205
|
-
.map((column) => (
|
|
206
|
-
<div key={String(column.key)}>
|
|
207
|
-
<label className="block text-sm font-medium text-foreground mb-1">
|
|
208
|
-
{column.title}
|
|
209
|
-
</label>
|
|
210
|
-
<select
|
|
211
|
-
value={filters[String(column.key)] || ''}
|
|
212
|
-
onChange={(e) => handleFilter(String(column.key), e.target.value || null)}
|
|
213
|
-
className="w-full px-3 py-2 border border-input rounded-md focus:ring-ring focus:border-ring"
|
|
214
|
-
>
|
|
215
|
-
<option value="">All</option>
|
|
216
|
-
{column.filterOptions?.map((option) => (
|
|
217
|
-
<option key={option.value} value={option.value}>
|
|
218
|
-
{option.label}
|
|
219
|
-
</option>
|
|
220
|
-
))}
|
|
221
|
-
</select>
|
|
222
|
-
</div>
|
|
223
|
-
))}
|
|
224
|
-
</div>
|
|
225
|
-
</div>
|
|
226
|
-
)}
|
|
227
|
-
</div>
|
|
228
|
-
)}
|
|
229
|
-
|
|
230
|
-
{/* Active filters display */}
|
|
231
|
-
{(hasActiveFilters || hasActiveSearch) && (
|
|
232
|
-
<div className="flex flex-wrap gap-2">
|
|
233
|
-
{hasActiveSearch && (
|
|
234
|
-
<Badge variant="info" className="flex items-center">
|
|
235
|
-
Search: "{searchQuery}"
|
|
236
|
-
<button
|
|
237
|
-
onClick={() => handleSearch('')}
|
|
238
|
-
className="ml-1 text-primary hover:text-primary/80"
|
|
239
|
-
>
|
|
240
|
-
×
|
|
241
|
-
</button>
|
|
242
|
-
</Badge>
|
|
243
|
-
)}
|
|
244
|
-
|
|
245
|
-
{Object.entries(filters).map(([key, value]) => {
|
|
246
|
-
const column = columns.find(col => String(col.key) === key)
|
|
247
|
-
const option = column?.filterOptions?.find(opt => opt.value === value)
|
|
248
|
-
|
|
249
|
-
return (
|
|
250
|
-
<Badge key={key} variant="info" className="flex items-center">
|
|
251
|
-
{column?.title}: {option?.label || value}
|
|
252
|
-
<button
|
|
253
|
-
onClick={() => handleFilter(key, null)}
|
|
254
|
-
className="ml-1 text-primary hover:text-primary/80"
|
|
255
|
-
>
|
|
256
|
-
×
|
|
257
|
-
</button>
|
|
258
|
-
</Badge>
|
|
259
|
-
)
|
|
260
|
-
})}
|
|
261
|
-
</div>
|
|
262
|
-
)}
|
|
263
|
-
|
|
264
|
-
{/* Table */}
|
|
265
|
-
<div className="rounded-md border">
|
|
266
|
-
<Table>
|
|
267
|
-
<TableHeader>
|
|
268
|
-
<TableRow>
|
|
269
|
-
{columns.map((column) => (
|
|
270
|
-
<TableHead key={String(column.key)} className={column.sortable ? 'cursor-pointer' : ''}>
|
|
271
|
-
{column.title}
|
|
272
|
-
</TableHead>
|
|
273
|
-
))}
|
|
274
|
-
</TableRow>
|
|
275
|
-
</TableHeader>
|
|
276
|
-
<TableBody>
|
|
277
|
-
{loading ? (
|
|
278
|
-
<TableRow>
|
|
279
|
-
<TableCell colSpan={columns.length} className="h-24 text-center">
|
|
280
|
-
Loading...
|
|
281
|
-
</TableCell>
|
|
282
|
-
</TableRow>
|
|
283
|
-
) : data.length === 0 ? (
|
|
284
|
-
<TableRow>
|
|
285
|
-
<TableCell colSpan={columns.length} className="h-24 text-center">
|
|
286
|
-
{emptyMessage}
|
|
287
|
-
</TableCell>
|
|
288
|
-
</TableRow>
|
|
289
|
-
) : (
|
|
290
|
-
data.map((row, index) => (
|
|
291
|
-
<TableRow
|
|
292
|
-
key={index}
|
|
293
|
-
onClick={() => onRowClick?.(row)}
|
|
294
|
-
className={onRowClick ? 'cursor-pointer' : ''}
|
|
295
|
-
>
|
|
296
|
-
{columns.map((column) => (
|
|
297
|
-
<TableCell key={String(column.key)}>
|
|
298
|
-
{column.render
|
|
299
|
-
? column.render(row)
|
|
300
|
-
: String(row[column.key as keyof T] ?? '')}
|
|
301
|
-
</TableCell>
|
|
302
|
-
))}
|
|
303
|
-
</TableRow>
|
|
304
|
-
))
|
|
305
|
-
)}
|
|
306
|
-
</TableBody>
|
|
307
|
-
</Table>
|
|
308
|
-
</div>
|
|
309
|
-
|
|
310
|
-
{/* Pagination */}
|
|
311
|
-
{pagination && (
|
|
312
|
-
<div className="flex items-center justify-between px-2">
|
|
313
|
-
<div className="text-sm text-muted-foreground">
|
|
314
|
-
Showing {(pagination.currentPage - 1) * pagination.itemsPerPage + 1} to{' '}
|
|
315
|
-
{Math.min(pagination.currentPage * pagination.itemsPerPage, pagination.totalItems)} of{' '}
|
|
316
|
-
{pagination.totalItems} entries
|
|
317
|
-
</div>
|
|
318
|
-
<div className="flex items-center gap-2">
|
|
319
|
-
<Button
|
|
320
|
-
variant="outline"
|
|
321
|
-
size="sm"
|
|
322
|
-
onClick={() => pagination.onPageChange(pagination.currentPage - 1)}
|
|
323
|
-
disabled={pagination.currentPage <= 1}
|
|
324
|
-
>
|
|
325
|
-
Previous
|
|
326
|
-
</Button>
|
|
327
|
-
<span className="text-sm">
|
|
328
|
-
Page {pagination.currentPage} of {pagination.totalPages}
|
|
329
|
-
</span>
|
|
330
|
-
<Button
|
|
331
|
-
variant="outline"
|
|
332
|
-
size="sm"
|
|
333
|
-
onClick={() => pagination.onPageChange(pagination.currentPage + 1)}
|
|
334
|
-
disabled={pagination.currentPage >= pagination.totalPages}
|
|
335
|
-
>
|
|
336
|
-
Next
|
|
337
|
-
</Button>
|
|
338
|
-
</div>
|
|
339
|
-
</div>
|
|
340
|
-
)}
|
|
341
|
-
</div>
|
|
342
|
-
)
|
|
343
|
-
}
|