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,281 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/components/ui/Form
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-component
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Schema-driven form layout components.
|
|
8
|
-
*
|
|
9
|
-
* **`Form`** — renders a `<form>` element from an ordered `FieldDefinition[]`
|
|
10
|
-
* array via `FieldRenderer`. Manages touched-based error display (errors only
|
|
11
|
-
* shown for fields the user has interacted with). Includes Submit + optional
|
|
12
|
-
* Cancel buttons.
|
|
13
|
-
*
|
|
14
|
-
* **`FormField`** — single field wrapper delegating to `FieldRenderer` with
|
|
15
|
-
* touched-based error display.
|
|
16
|
-
*
|
|
17
|
-
* **`FormSection`** — optional titled group container for logical field
|
|
18
|
-
* groups within a form.
|
|
19
|
-
*
|
|
20
|
-
* **`FormRow`** / **`FormColumn`** — two-column responsive grid layout
|
|
21
|
-
* helpers. `FormColumn` accepts `span=2` to span both columns.
|
|
22
|
-
*
|
|
23
|
-
* @seeAlso src/components/shared/FieldRenderer.tsx
|
|
24
|
-
* @seeAlso src/hooks/useForm.ts (state management companion)
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import React from 'react'
|
|
28
|
-
import { FieldDefinition } from '../../types/types'
|
|
29
|
-
import { FieldRenderer } from '../shared/FieldRenderer'
|
|
30
|
-
import { Button } from './button'
|
|
31
|
-
import { cn } from '../../lib/utils'
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Props for `Form`.
|
|
35
|
-
*
|
|
36
|
-
* @prop fields - Ordered field definitions to render
|
|
37
|
-
* @prop data - Controlled field values keyed by field name
|
|
38
|
-
* @prop errors - Validation errors per field name
|
|
39
|
-
* @prop touched - Map of fields that have been interacted with
|
|
40
|
-
* @prop onChange - `(field, value)` change callback
|
|
41
|
-
* @prop onBlur - `(field)` blur callback for marking a field as touched
|
|
42
|
-
* @prop onSubmit - Form submit handler (receives the native `FormEvent`)
|
|
43
|
-
* @prop isSubmitting - Shows spinner on submit button when true
|
|
44
|
-
* @prop submitText - Submit button label (default: `'Submit'`)
|
|
45
|
-
* @prop cancelText - Cancel button label (default: `'Cancel'`)
|
|
46
|
-
* @prop onCancel - Cancel button callback
|
|
47
|
-
* @prop showCancel - Shows the cancel button (default: `false`)
|
|
48
|
-
* @prop disabled - Disables all fields and the submit button
|
|
49
|
-
* @prop className - Additional Tailwind classes for the `<form>` element
|
|
50
|
-
*/
|
|
51
|
-
interface FormProps {
|
|
52
|
-
fields: FieldDefinition[]
|
|
53
|
-
data: Record<string, any>
|
|
54
|
-
errors: Record<string, string>
|
|
55
|
-
touched: Record<string, boolean>
|
|
56
|
-
onChange: (field: string, value: any) => void
|
|
57
|
-
onBlur?: (field: string) => void
|
|
58
|
-
onSubmit?: (e: React.FormEvent) => void
|
|
59
|
-
isSubmitting?: boolean
|
|
60
|
-
submitText?: string
|
|
61
|
-
cancelText?: string
|
|
62
|
-
onCancel?: () => void
|
|
63
|
-
showCancel?: boolean
|
|
64
|
-
disabled?: boolean
|
|
65
|
-
className?: string
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Schema-driven `<form>` with submit + optional cancel actions.
|
|
70
|
-
*
|
|
71
|
-
* @param props - `FormProps`
|
|
72
|
-
* @returns Form element with field list and action buttons
|
|
73
|
-
* @sideEffects Calls `e.preventDefault()` on submit before forwarding to `onSubmit`
|
|
74
|
-
*/
|
|
75
|
-
export function Form({
|
|
76
|
-
fields,
|
|
77
|
-
data,
|
|
78
|
-
errors,
|
|
79
|
-
touched,
|
|
80
|
-
onChange,
|
|
81
|
-
onBlur,
|
|
82
|
-
onSubmit,
|
|
83
|
-
isSubmitting = false,
|
|
84
|
-
submitText = 'Submit',
|
|
85
|
-
cancelText = 'Cancel',
|
|
86
|
-
onCancel,
|
|
87
|
-
showCancel = false,
|
|
88
|
-
disabled = false,
|
|
89
|
-
className
|
|
90
|
-
}: FormProps) {
|
|
91
|
-
const handleSubmit = (e: React.FormEvent) => {
|
|
92
|
-
e.preventDefault()
|
|
93
|
-
onSubmit?.(e)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const handleFieldChange = (fieldName: string, value: any) => {
|
|
97
|
-
onChange(fieldName, value)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const handleFieldBlur = (fieldName: string) => {
|
|
101
|
-
onBlur?.(fieldName)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<form onSubmit={handleSubmit} className={cn('space-y-6', className)}>
|
|
106
|
-
{fields.filter(f => !!f.name).map((field) => {
|
|
107
|
-
const name = field.name!
|
|
108
|
-
return (
|
|
109
|
-
<FieldRenderer
|
|
110
|
-
key={name}
|
|
111
|
-
field={field}
|
|
112
|
-
value={data[name]}
|
|
113
|
-
onChange={(value) => handleFieldChange(name, value)}
|
|
114
|
-
error={touched[name] ? errors[name] : undefined}
|
|
115
|
-
onBlur={() => handleFieldBlur(name)}
|
|
116
|
-
readonly={disabled}
|
|
117
|
-
/>
|
|
118
|
-
)
|
|
119
|
-
})}
|
|
120
|
-
|
|
121
|
-
{/* Form Actions */}
|
|
122
|
-
<div className="flex justify-end space-x-3">
|
|
123
|
-
{showCancel && (
|
|
124
|
-
<Button
|
|
125
|
-
type="button"
|
|
126
|
-
variant="outline"
|
|
127
|
-
onClick={onCancel}
|
|
128
|
-
disabled={isSubmitting}
|
|
129
|
-
>
|
|
130
|
-
{cancelText}
|
|
131
|
-
</Button>
|
|
132
|
-
)}
|
|
133
|
-
|
|
134
|
-
<Button
|
|
135
|
-
type="submit"
|
|
136
|
-
loading={isSubmitting}
|
|
137
|
-
disabled={disabled}
|
|
138
|
-
>
|
|
139
|
-
{submitText}
|
|
140
|
-
</Button>
|
|
141
|
-
</div>
|
|
142
|
-
</form>
|
|
143
|
-
)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Props for `FormField`.
|
|
148
|
-
*
|
|
149
|
-
* @prop field - Field definition
|
|
150
|
-
* @prop value - Current value
|
|
151
|
-
* @prop error - Validation error string
|
|
152
|
-
* @prop touched - Whether this field has been interacted with (gates error display)
|
|
153
|
-
* @prop onChange / onBlur / readonly - Passed through to `FieldRenderer`
|
|
154
|
-
*/
|
|
155
|
-
interface FormFieldProps {
|
|
156
|
-
field: FieldDefinition
|
|
157
|
-
value: any
|
|
158
|
-
error?: string
|
|
159
|
-
touched?: boolean
|
|
160
|
-
onChange: (value: any) => void
|
|
161
|
-
onBlur?: () => void
|
|
162
|
-
readonly?: boolean
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Single field with touched-gated error display.
|
|
167
|
-
*
|
|
168
|
-
* @param props - `FormFieldProps`
|
|
169
|
-
* @returns `FieldRenderer` instance with error shown only when touched
|
|
170
|
-
* @sideEffects none (delegates to `onChange` / `onBlur`)
|
|
171
|
-
*/
|
|
172
|
-
export function FormField({
|
|
173
|
-
field,
|
|
174
|
-
value,
|
|
175
|
-
error,
|
|
176
|
-
touched,
|
|
177
|
-
onChange,
|
|
178
|
-
onBlur,
|
|
179
|
-
readonly = false
|
|
180
|
-
}: FormFieldProps) {
|
|
181
|
-
return (
|
|
182
|
-
<FieldRenderer
|
|
183
|
-
field={field}
|
|
184
|
-
value={value}
|
|
185
|
-
onChange={onChange}
|
|
186
|
-
error={touched ? error : undefined}
|
|
187
|
-
onBlur={onBlur}
|
|
188
|
-
readonly={readonly}
|
|
189
|
-
/>
|
|
190
|
-
)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Props for `FormSection`.
|
|
195
|
-
*
|
|
196
|
-
* @prop title - Optional section heading
|
|
197
|
-
* @prop description - Optional subtitle text
|
|
198
|
-
*/
|
|
199
|
-
interface FormSectionProps {
|
|
200
|
-
title?: string
|
|
201
|
-
description?: string
|
|
202
|
-
children: React.ReactNode
|
|
203
|
-
className?: string
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Titled group container for a set of related form fields.
|
|
208
|
-
*
|
|
209
|
-
* @param props - `FormSectionProps`
|
|
210
|
-
* @returns `<div>` with optional title/description and `children` below
|
|
211
|
-
* @sideEffects none (pure rendering)
|
|
212
|
-
*/
|
|
213
|
-
export function FormSection({ title, description, children, className }: FormSectionProps) {
|
|
214
|
-
return (
|
|
215
|
-
<div className={cn('space-y-4', className)}>
|
|
216
|
-
{(title || description) && (
|
|
217
|
-
<div>
|
|
218
|
-
{title && (
|
|
219
|
-
<h3 className="text-lg font-medium text-slate-900">{title}</h3>
|
|
220
|
-
)}
|
|
221
|
-
{description && (
|
|
222
|
-
<p className="mt-1 text-sm text-slate-600">{description}</p>
|
|
223
|
-
)}
|
|
224
|
-
</div>
|
|
225
|
-
)}
|
|
226
|
-
{children}
|
|
227
|
-
</div>
|
|
228
|
-
)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/** Props for `FormRow`. */
|
|
232
|
-
interface FormRowProps {
|
|
233
|
-
children: React.ReactNode
|
|
234
|
-
className?: string
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Two-column responsive grid row for form fields.
|
|
239
|
-
*
|
|
240
|
-
* @param props - children + optional className
|
|
241
|
-
* @returns `<div>` with `grid-cols-1 sm:grid-cols-2 gap-4`
|
|
242
|
-
* @sideEffects none (pure rendering)
|
|
243
|
-
*/
|
|
244
|
-
export function FormRow({ children, className }: FormRowProps) {
|
|
245
|
-
return (
|
|
246
|
-
<div className={cn('grid grid-cols-1 sm:grid-cols-2 gap-4', className)}>
|
|
247
|
-
{children}
|
|
248
|
-
</div>
|
|
249
|
-
)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Props for `FormColumn`.
|
|
254
|
-
*
|
|
255
|
-
* @prop span - Column span within a `FormRow` (1 or 2, default: 1)
|
|
256
|
-
*/
|
|
257
|
-
interface FormColumnProps {
|
|
258
|
-
children: React.ReactNode
|
|
259
|
-
span?: 1 | 2
|
|
260
|
-
className?: string
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Column within a `FormRow` grid.
|
|
265
|
-
*
|
|
266
|
-
* @param props - `FormColumnProps`
|
|
267
|
-
* @returns `<div>` with appropriate `col-span` class
|
|
268
|
-
* @sideEffects none (pure rendering)
|
|
269
|
-
*/
|
|
270
|
-
export function FormColumn({ children, span = 1, className }: FormColumnProps) {
|
|
271
|
-
const spanClasses = {
|
|
272
|
-
1: 'col-span-1',
|
|
273
|
-
2: 'col-span-2'
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return (
|
|
277
|
-
<div className={cn(spanClasses[span], className)}>
|
|
278
|
-
{children}
|
|
279
|
-
</div>
|
|
280
|
-
)
|
|
281
|
-
}
|
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/components/ui/ItemCard
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-component
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Item display components for grid-based views.
|
|
8
|
-
*
|
|
9
|
-
* **`ItemCard`** — renders a single `Item` in either full (`compact=false`)
|
|
10
|
-
* or compact (`compact=true`) form. Derives its display values from
|
|
11
|
-
* `item.title`, `item.description`, and the first 3 entries of `item.data`.
|
|
12
|
-
* Optional action buttons (`onView`, `onEdit`, `onDelete`) are shown when
|
|
13
|
-
* `showActions=true`.
|
|
14
|
-
*
|
|
15
|
-
* **`ItemGrid`** — renders a responsive grid of `ItemCard` instances.
|
|
16
|
-
* Shows a spinner on `loading=true` and an empty state with a doc icon
|
|
17
|
-
* when `items` is empty.
|
|
18
|
-
*
|
|
19
|
-
* @seeAlso src/components/ui/ItemListView.tsx (combines with DataTable)
|
|
20
|
-
* @seeAlso src/types/types.ts (Item, ItemType)
|
|
21
|
-
* @seeAlso src/lib/utils.ts (formatDateTime, truncateText)
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import React from 'react'
|
|
25
|
-
import { Item, ItemType } from '../../types/types'
|
|
26
|
-
import { Badge } from './badge'
|
|
27
|
-
import { Button } from './button'
|
|
28
|
-
import { Box, FileText, Calendar, User, MoreVertical } from 'lucide-react';
|
|
29
|
-
import { formatDateTime, truncateText } from '../../lib/utils'
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Props for `ItemCard`.
|
|
33
|
-
*
|
|
34
|
-
* @prop item - `Item` with optional resolved `item_type` relation
|
|
35
|
-
* @prop onEdit - Edit action callback
|
|
36
|
-
* @prop onDelete - Delete action callback
|
|
37
|
-
* @prop onView - View action callback
|
|
38
|
-
* @prop showActions - Shows action buttons (default: `true`)
|
|
39
|
-
* @prop compact - Condensed single-line layout (default: `false`)
|
|
40
|
-
*/
|
|
41
|
-
interface ItemCardProps {
|
|
42
|
-
item: Item & { item_type?: ItemType | string }
|
|
43
|
-
onEdit?: (item: Item) => void
|
|
44
|
-
onDelete?: (item: Item) => void
|
|
45
|
-
onView?: (item: Item) => void
|
|
46
|
-
showActions?: boolean
|
|
47
|
-
compact?: boolean
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Item card with optional action buttons.
|
|
52
|
-
*
|
|
53
|
-
* @param props - `ItemCardProps`
|
|
54
|
-
* @returns White rounded card in full or compact layout
|
|
55
|
-
* @sideEffects none (delegates actions to `onEdit` / `onDelete` / `onView`)
|
|
56
|
-
*/
|
|
57
|
-
export function ItemCard({
|
|
58
|
-
item,
|
|
59
|
-
onEdit,
|
|
60
|
-
onDelete,
|
|
61
|
-
onView,
|
|
62
|
-
showActions = true,
|
|
63
|
-
compact = false
|
|
64
|
-
}: ItemCardProps) {
|
|
65
|
-
const getPrimaryValue = () => item.title || 'Untitled Item'
|
|
66
|
-
|
|
67
|
-
const getSecondaryValue = () => {
|
|
68
|
-
if (item.description) return truncateText(item.description, 100)
|
|
69
|
-
return null
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const getTypeIcon = () => {
|
|
73
|
-
return <Box className="h-5 w-5 text-blue-500" />
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const getTypeName = () => {
|
|
77
|
-
if (!item.item_type) return item.item_type_slug || ''
|
|
78
|
-
if (typeof item.item_type === 'string') return item.item_type
|
|
79
|
-
return (item.item_type as ItemType).name || ''
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const getTypeBadgeColor = () => {
|
|
83
|
-
if (!item.item_type || typeof item.item_type === 'string') return 'info'
|
|
84
|
-
return (item.item_type as ItemType).is_active ? 'success' : 'default'
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (compact) {
|
|
88
|
-
return (
|
|
89
|
-
<div className="bg-white border border-slate-200 rounded-lg p-4 hover:shadow-md transition-shadow">
|
|
90
|
-
<div className="flex items-start justify-between">
|
|
91
|
-
<div className="flex items-start space-x-3 flex-1">
|
|
92
|
-
<div className="flex-shrink-0">
|
|
93
|
-
{getTypeIcon()}
|
|
94
|
-
</div>
|
|
95
|
-
<div className="flex-1 min-w-0">
|
|
96
|
-
<div className="flex items-center space-x-2">
|
|
97
|
-
<h3 className="text-sm font-medium text-slate-900 truncate">
|
|
98
|
-
{getPrimaryValue()}
|
|
99
|
-
</h3>
|
|
100
|
-
<Badge variant={getTypeBadgeColor()}>
|
|
101
|
-
{getTypeName()}
|
|
102
|
-
</Badge>
|
|
103
|
-
</div>
|
|
104
|
-
{getSecondaryValue() && (
|
|
105
|
-
<p className="text-xs text-slate-500 mt-1">
|
|
106
|
-
{getSecondaryValue()}
|
|
107
|
-
</p>
|
|
108
|
-
)}
|
|
109
|
-
<div className="flex items-center space-x-4 mt-2 text-xs text-slate-500">
|
|
110
|
-
<span>Updated {formatDateTime(item.updated_at)}</span>
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
113
|
-
</div>
|
|
114
|
-
|
|
115
|
-
{showActions && (
|
|
116
|
-
<div className="flex items-center space-x-1">
|
|
117
|
-
{onView && (
|
|
118
|
-
<Button
|
|
119
|
-
variant="ghost"
|
|
120
|
-
size="sm"
|
|
121
|
-
onClick={() => onView(item)}
|
|
122
|
-
>
|
|
123
|
-
View
|
|
124
|
-
</Button>
|
|
125
|
-
)}
|
|
126
|
-
<Button
|
|
127
|
-
variant="ghost"
|
|
128
|
-
size="sm"
|
|
129
|
-
>
|
|
130
|
-
<MoreVertical className="h-4 w-4" />
|
|
131
|
-
</Button>
|
|
132
|
-
</div>
|
|
133
|
-
)}
|
|
134
|
-
</div>
|
|
135
|
-
</div>
|
|
136
|
-
)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return (
|
|
140
|
-
<div className="bg-white border border-slate-200 rounded-lg p-6 hover:shadow-md transition-shadow">
|
|
141
|
-
<div className="flex items-start justify-between">
|
|
142
|
-
<div className="flex items-start space-x-4 flex-1">
|
|
143
|
-
<div className="flex-shrink-0">
|
|
144
|
-
{getTypeIcon()}
|
|
145
|
-
</div>
|
|
146
|
-
<div className="flex-1 min-w-0">
|
|
147
|
-
<div className="flex items-center space-x-2 mb-2">
|
|
148
|
-
<h3 className="text-lg font-medium text-slate-900 truncate">
|
|
149
|
-
{getPrimaryValue()}
|
|
150
|
-
</h3>
|
|
151
|
-
<Badge variant={getTypeBadgeColor()}>
|
|
152
|
-
{getTypeName()}
|
|
153
|
-
</Badge>
|
|
154
|
-
</div>
|
|
155
|
-
|
|
156
|
-
{getSecondaryValue() && (
|
|
157
|
-
<p className="text-sm text-slate-600 mb-3">
|
|
158
|
-
{getSecondaryValue()}
|
|
159
|
-
</p>
|
|
160
|
-
)}
|
|
161
|
-
|
|
162
|
-
{/* Additional data fields */}
|
|
163
|
-
{Object.keys(item.data || {}).length > 0 && (
|
|
164
|
-
<div className="space-y-2 mb-4">
|
|
165
|
-
{Object.entries(item.data)
|
|
166
|
-
.filter(([, v]) => v !== undefined && v !== null && v !== '')
|
|
167
|
-
.slice(0, 3)
|
|
168
|
-
.map(([key, value]) => (
|
|
169
|
-
<div key={key} className="flex items-center space-x-2">
|
|
170
|
-
<span className="text-xs font-medium text-slate-500">{key}:</span>
|
|
171
|
-
<span className="text-xs text-slate-900">
|
|
172
|
-
{truncateText(typeof value === 'boolean' ? (value ? 'Yes' : 'No') : String(value), 50)}
|
|
173
|
-
</span>
|
|
174
|
-
</div>
|
|
175
|
-
))}
|
|
176
|
-
</div>
|
|
177
|
-
)}
|
|
178
|
-
|
|
179
|
-
{/* Metadata */}
|
|
180
|
-
<div className="flex items-center justify-between text-xs text-slate-500">
|
|
181
|
-
<div className="flex items-center space-x-4">
|
|
182
|
-
<span className="flex items-center">
|
|
183
|
-
<Calendar className="h-3 w-3 mr-1" />
|
|
184
|
-
Created {formatDateTime(item.created_at)}
|
|
185
|
-
</span>
|
|
186
|
-
<span className="flex items-center">
|
|
187
|
-
<User className="h-3 w-3 mr-1" />
|
|
188
|
-
ID: {item.id.slice(0, 8)}...
|
|
189
|
-
</span>
|
|
190
|
-
</div>
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
</div>
|
|
194
|
-
|
|
195
|
-
{showActions && (
|
|
196
|
-
<div className="flex items-center space-x-2 ml-4">
|
|
197
|
-
{onView && (
|
|
198
|
-
<Button
|
|
199
|
-
variant="outline"
|
|
200
|
-
size="sm"
|
|
201
|
-
onClick={() => onView(item)}
|
|
202
|
-
>
|
|
203
|
-
View
|
|
204
|
-
</Button>
|
|
205
|
-
)}
|
|
206
|
-
{onEdit && (
|
|
207
|
-
<Button
|
|
208
|
-
variant="outline"
|
|
209
|
-
size="sm"
|
|
210
|
-
onClick={() => onEdit(item)}
|
|
211
|
-
>
|
|
212
|
-
Edit
|
|
213
|
-
</Button>
|
|
214
|
-
)}
|
|
215
|
-
<Button
|
|
216
|
-
variant="ghost"
|
|
217
|
-
size="sm"
|
|
218
|
-
>
|
|
219
|
-
<MoreVertical className="h-4 w-4" />
|
|
220
|
-
</Button>
|
|
221
|
-
</div>
|
|
222
|
-
)}
|
|
223
|
-
</div>
|
|
224
|
-
</div>
|
|
225
|
-
)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Props for `ItemGrid`.
|
|
230
|
-
*
|
|
231
|
-
* @prop items - Typed item array with resolved `item_type`
|
|
232
|
-
* @prop loading - Shows spinner while true
|
|
233
|
-
* @prop compact - Passes compact mode to each `ItemCard`
|
|
234
|
-
* @prop emptyMessage - Text shown when `items` is empty
|
|
235
|
-
*/
|
|
236
|
-
interface ItemGridProps {
|
|
237
|
-
items: (Item & { item_type: ItemType })[]
|
|
238
|
-
loading?: boolean
|
|
239
|
-
onEdit?: (item: Item) => void
|
|
240
|
-
onDelete?: (item: Item) => void
|
|
241
|
-
onView?: (item: Item) => void
|
|
242
|
-
compact?: boolean
|
|
243
|
-
emptyMessage?: string
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Responsive card grid for items.
|
|
248
|
-
*
|
|
249
|
-
* @param props - `ItemGridProps`
|
|
250
|
-
* @returns Responsive grid, loading spinner, or empty state
|
|
251
|
-
* @sideEffects none (delegates actions to `onEdit` / `onDelete` / `onView`)
|
|
252
|
-
*/
|
|
253
|
-
export function ItemGrid({
|
|
254
|
-
items,
|
|
255
|
-
loading = false,
|
|
256
|
-
onEdit,
|
|
257
|
-
onDelete,
|
|
258
|
-
onView,
|
|
259
|
-
compact = false,
|
|
260
|
-
emptyMessage = 'No items found'
|
|
261
|
-
}: ItemGridProps) {
|
|
262
|
-
if (loading) {
|
|
263
|
-
return (
|
|
264
|
-
<div className="flex justify-center py-8">
|
|
265
|
-
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
|
|
266
|
-
</div>
|
|
267
|
-
)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (items.length === 0) {
|
|
271
|
-
return (
|
|
272
|
-
<div className="text-center py-8">
|
|
273
|
-
<FileText className="mx-auto h-12 w-12 text-slate-400" />
|
|
274
|
-
<h3 className="mt-2 text-sm font-medium text-slate-900">{emptyMessage}</h3>
|
|
275
|
-
</div>
|
|
276
|
-
)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return (
|
|
280
|
-
<div className={compact
|
|
281
|
-
? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
|
|
282
|
-
: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"
|
|
283
|
-
}>
|
|
284
|
-
{items.map((item) => (
|
|
285
|
-
<ItemCard
|
|
286
|
-
key={item.id}
|
|
287
|
-
item={item}
|
|
288
|
-
onEdit={onEdit}
|
|
289
|
-
onDelete={onDelete}
|
|
290
|
-
onView={onView}
|
|
291
|
-
compact={compact}
|
|
292
|
-
/>
|
|
293
|
-
))}
|
|
294
|
-
</div>
|
|
295
|
-
)
|
|
296
|
-
}
|