spine-framework 0.3.124 → 0.3.126
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/.framework/cli/commands/agents.ts +35 -37
- package/.framework/cli/commands/auth.ts +35 -34
- package/.framework/cli/commands/create-app.ts +104 -40
- package/.framework/cli/commands/dev.ts +104 -69
- package/.framework/cli/commands/doctor.ts +179 -69
- package/.framework/cli/commands/generate.ts +83 -143
- package/.framework/cli/commands/init.ts +72 -34
- package/.framework/cli/commands/install-app.ts +260 -125
- package/.framework/cli/commands/items.ts +33 -44
- package/.framework/cli/commands/migrate.ts +122 -40
- package/.framework/cli/commands/migrations.ts +33 -40
- package/.framework/cli/commands/pipelines.ts +31 -39
- package/.framework/cli/commands/status.ts +47 -23
- package/.framework/cli/commands/system.ts +47 -37
- package/.framework/cli/commands/test.ts +112 -68
- package/.framework/cli/commands/validate-app.ts +215 -121
- package/.framework/cli/context.ts +112 -130
- package/.framework/cli/env-loader.ts +47 -18
- package/.framework/cli/index.ts +81 -42
- package/.framework/docs/runtime-types.md +1024 -0
- package/.framework/functions/_shared/agent-runner.ts +1296 -961
- package/.framework/functions/_shared/app-manifest.ts +82 -68
- package/.framework/functions/_shared/audit.ts +135 -83
- package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
- package/.framework/functions/_shared/db.ts +80 -126
- package/.framework/functions/_shared/hash-api-key.ts +63 -0
- package/.framework/functions/_shared/index.ts +224 -335
- package/.framework/functions/_shared/kb.ts +319 -0
- package/.framework/functions/_shared/llm.ts +92 -0
- package/.framework/functions/_shared/logging.ts +288 -0
- package/.framework/functions/_shared/middleware.ts +329 -365
- package/.framework/functions/_shared/outcomes.ts +36 -0
- package/.framework/functions/_shared/permissions.ts +359 -643
- package/.framework/functions/_shared/pipeline-runner.ts +243 -316
- package/.framework/functions/_shared/principal.ts +376 -468
- package/.framework/functions/_shared/resolve-credentials.ts +102 -0
- package/.framework/functions/_shared/resolve-ids.ts +188 -16
- package/.framework/functions/_shared/retry-deliveries.ts +104 -0
- package/.framework/functions/_shared/schema-utils.ts +611 -373
- package/.framework/functions/_shared/testing.ts +207 -137
- package/.framework/functions/_shared/tracing.ts +276 -0
- package/.framework/functions/_shared/trigger-engine.ts +159 -211
- package/.framework/functions/_shared/webhook-registration.ts +95 -81
- package/.framework/functions/_shared/webhook-registry.ts +153 -75
- package/.framework/functions/account-nodes.ts +31 -53
- package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
- package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
- package/.framework/functions/adapters/openai-outbound.ts +40 -0
- package/.framework/functions/admin-data.ts +685 -537
- package/.framework/functions/admin-funnel.ts +31 -20
- package/.framework/functions/admin-install-funnel.ts +47 -28
- package/.framework/functions/admin-signals.ts +47 -29
- package/.framework/functions/ai-agents.ts +122 -147
- package/.framework/functions/ai-interactions.ts +180 -90
- package/.framework/functions/api-keys.ts +250 -192
- package/.framework/functions/apps.ts +203 -197
- package/.framework/functions/auth.ts +98 -91
- package/.framework/functions/cil-agent-ingest.ts +773 -0
- package/.framework/functions/cil-agent.ts +592 -0
- package/.framework/functions/cil-callmap.ts +1227 -0
- package/.framework/functions/cil-config.ts +583 -0
- package/.framework/functions/cil-context.ts +445 -0
- package/.framework/functions/cil-doc.ts +1752 -0
- package/.framework/functions/cil-embeddings.ts +1202 -0
- package/.framework/functions/cil-graph.ts +585 -0
- package/.framework/functions/cil-ingest.ts +2416 -0
- package/.framework/functions/cil-pipeline.ts +318 -0
- package/.framework/functions/cil-project.ts +499 -0
- package/.framework/functions/cil-validate.ts +469 -0
- package/.framework/functions/debug-auth.ts +73 -53
- package/.framework/functions/deliveries.ts +117 -0
- package/.framework/functions/embeddings.ts +528 -516
- package/.framework/functions/eval-harness.ts +158 -106
- package/.framework/functions/integration-outbound.ts +311 -0
- package/.framework/functions/integration-routes.ts +240 -466
- package/.framework/functions/integrations.ts +132 -140
- package/.framework/functions/invites.ts +401 -201
- package/.framework/functions/item-progress.ts +113 -53
- package/.framework/functions/kb.ts +28 -0
- package/.framework/functions/logs.ts +239 -222
- package/.framework/functions/observability.ts +308 -259
- package/.framework/functions/pipeline-executions.ts +179 -235
- package/.framework/functions/pipelines.ts +163 -205
- package/.framework/functions/prompt-configs.ts +109 -156
- package/.framework/functions/roles.ts +97 -147
- package/.framework/functions/system-cron.ts +132 -218
- package/.framework/functions/system.ts +112 -52
- package/.framework/functions/tests.ts +32 -28
- package/.framework/functions/timers.ts +162 -210
- package/.framework/functions/triggers.ts +282 -346
- package/.framework/functions/types.ts +283 -400
- package/.framework/migrations/001_core_schema.sql +630 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
- package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
- package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
- package/.framework/migrations/005_core_observability.sql +598 -0
- package/.framework/migrations/006_security_hardening_rls.sql +97 -0
- package/.framework/migrations/007_kb_article_list.sql +237 -0
- package/.framework/migrations/008_items_target.sql +8 -0
- package/.framework/migrations/009_roles_slug_unique.sql +11 -0
- package/.framework/public/spine.config.json +91 -0
- package/.framework/scripts/app-install-cli.ts +112 -98
- package/.framework/src/App.tsx +67 -20
- package/.framework/src/apps/admin/index.tsx +97 -27
- package/.framework/src/components/AppWrapper.tsx +50 -11
- package/.framework/src/components/CustomAppLoader.tsx +131 -22
- package/.framework/src/components/admin/AdminListPage.tsx +75 -8
- package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
- package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
- package/.framework/src/components/admin/PageInstructions.tsx +49 -0
- package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
- package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
- package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
- package/.framework/src/components/app-sidebar.tsx +50 -3
- package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
- package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
- package/.framework/src/components/kb/KBArticleList.tsx +557 -0
- package/.framework/src/components/layout/AppShell.tsx +54 -16
- package/.framework/src/components/layout/Header.tsx +50 -38
- package/.framework/src/components/layout/Layout.tsx +48 -32
- package/.framework/src/components/layout/Sidebar.tsx +167 -16
- package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
- package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
- package/.framework/src/components/runtime/DataFilters.tsx +78 -1
- package/.framework/src/components/runtime/DataHeader.tsx +32 -29
- package/.framework/src/components/runtime/DataListPage.tsx +161 -2
- package/.framework/src/components/runtime/DataStats.tsx +48 -1
- package/.framework/src/components/runtime/DataTable.tsx +153 -1
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
- package/.framework/src/components/runtime/index.ts +16 -9
- package/.framework/src/components/search-form.tsx +33 -1
- package/.framework/src/components/shared/AgentView.tsx +48 -51
- package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
- package/.framework/src/components/shared/InviteManager.tsx +113 -52
- package/.framework/src/components/shared/MemberList.tsx +182 -0
- package/.framework/src/components/shared/SchemaFields.tsx +96 -78
- package/.framework/src/components/ui/DataTable.tsx +86 -56
- package/.framework/src/components/ui/Form.tsx +188 -109
- package/.framework/src/components/ui/ItemCard.tsx +86 -58
- package/.framework/src/components/ui/ItemListView.tsx +88 -61
- package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
- package/.framework/src/components/ui/Modal.tsx +81 -4
- package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
- package/.framework/src/components/ui/accordion.tsx +97 -5
- package/.framework/src/components/ui/alert-dialog.tsx +225 -13
- package/.framework/src/components/ui/alert.tsx +113 -6
- package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
- package/.framework/src/components/ui/avatar.tsx +129 -7
- package/.framework/src/components/ui/badge.tsx +65 -3
- package/.framework/src/components/ui/breadcrumb.tsx +145 -8
- package/.framework/src/components/ui/button-group.tsx +81 -4
- package/.framework/src/components/ui/button.tsx +49 -2
- package/.framework/src/components/ui/calendar.tsx +65 -3
- package/.framework/src/components/ui/card.tsx +145 -8
- package/.framework/src/components/ui/carousel.tsx +129 -7
- package/.framework/src/components/ui/chart.tsx +161 -10
- package/.framework/src/components/ui/checkbox.tsx +49 -2
- package/.framework/src/components/ui/collapsible.tsx +81 -5
- package/.framework/src/components/ui/combobox.tsx +305 -20
- package/.framework/src/components/ui/command.tsx +177 -11
- package/.framework/src/components/ui/context-menu.tsx +273 -17
- package/.framework/src/components/ui/dialog.tsx +209 -27
- package/.framework/src/components/ui/direction.tsx +64 -4
- package/.framework/src/components/ui/drawer.tsx +193 -12
- package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
- package/.framework/src/components/ui/empty.tsx +145 -9
- package/.framework/src/components/ui/field.tsx +209 -14
- package/.framework/src/components/ui/hover-card.tsx +81 -4
- package/.framework/src/components/ui/input-group.tsx +162 -10
- package/.framework/src/components/ui/input-otp.tsx +98 -5
- package/.framework/src/components/ui/input.tsx +49 -2
- package/.framework/src/components/ui/item.tsx +225 -13
- package/.framework/src/components/ui/kbd.tsx +65 -3
- package/.framework/src/components/ui/label.tsx +49 -2
- package/.framework/src/components/ui/menubar.tsx +289 -17
- package/.framework/src/components/ui/native-select.tsx +97 -5
- package/.framework/src/components/ui/navigation-menu.tsx +177 -10
- package/.framework/src/components/ui/pagination.tsx +161 -9
- package/.framework/src/components/ui/popover.tsx +145 -8
- package/.framework/src/components/ui/progress.tsx +49 -2
- package/.framework/src/components/ui/radio-group.tsx +65 -3
- package/.framework/src/components/ui/resizable.tsx +82 -4
- package/.framework/src/components/ui/scroll-area.tsx +65 -3
- package/.framework/src/components/ui/select.tsx +193 -11
- package/.framework/src/components/ui/separator.tsx +49 -2
- package/.framework/src/components/ui/sheet.tsx +193 -11
- package/.framework/src/components/ui/sidebar.tsx +481 -38
- package/.framework/src/components/ui/skeleton.tsx +49 -2
- package/.framework/src/components/ui/slider.tsx +49 -2
- package/.framework/src/components/ui/sonner.tsx +49 -2
- package/.framework/src/components/ui/spinner.tsx +49 -2
- package/.framework/src/components/ui/switch.tsx +49 -2
- package/.framework/src/components/ui/table-primitives.tsx +160 -33
- package/.framework/src/components/ui/table.tsx +161 -9
- package/.framework/src/components/ui/tabs.tsx +113 -6
- package/.framework/src/components/ui/textarea.tsx +49 -2
- package/.framework/src/components/ui/toggle-group.tsx +81 -4
- package/.framework/src/components/ui/toggle.tsx +65 -3
- package/.framework/src/components/ui/tooltip.tsx +97 -5
- package/.framework/src/contexts/AppContext.tsx +129 -45
- package/.framework/src/contexts/AuthContext.tsx +187 -144
- package/.framework/src/hooks/use-mobile.ts +48 -2
- package/.framework/src/hooks/useApi.ts +208 -159
- package/.framework/src/hooks/useAppPath.ts +32 -23
- package/.framework/src/hooks/useApps.ts +51 -20
- package/.framework/src/hooks/useEntityList.ts +32 -78
- package/.framework/src/hooks/useEntityRecord.ts +35 -96
- package/.framework/src/hooks/useForm.ts +32 -92
- package/.framework/src/hooks/useListSchema.ts +49 -78
- package/.framework/src/hooks/useSchemaRecord.ts +114 -105
- package/.framework/src/lib/api.ts +195 -116
- package/.framework/src/lib/supabase.ts +98 -64
- package/.framework/src/lib/utils.ts +287 -151
- package/.framework/src/main.tsx +49 -3
- package/.framework/src/pages/DashboardPage.tsx +52 -29
- package/.framework/src/pages/NotFoundPage.tsx +32 -10
- package/.framework/src/pages/SetupPage.tsx +32 -12
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
- package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
- package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
- package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
- package/.framework/src/pages/admin/AppsPage.tsx +49 -2
- package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
- package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
- package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
- package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
- package/.framework/src/pages/admin/LogsPage.tsx +422 -75
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
- package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
- package/.framework/src/pages/admin/RolesPage.tsx +171 -18
- package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
- package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
- package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
- package/.framework/src/pages/admin/TimersPage.tsx +48 -20
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
- package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
- package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
- package/.framework/src/pages/admin/TypesPage.tsx +48 -20
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
- package/.framework/src/pages/auth/LoginPage.tsx +50 -23
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
- package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
- package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
- package/.framework/src/types/auth.ts +128 -71
- package/.framework/src/types/types.ts +373 -157
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
- package/docs/README.md +9 -130
- package/netlify.toml +5 -2
- package/package.json +13 -25
- package/scripts/kb-ingest-docs.ts +203 -0
- package/spine.config.json +65 -4
- package/.framework/migrations/001_schema.sql +0 -425
- package/.framework/migrations/002_rls_and_functions.sql +0 -763
- package/.framework/migrations/004_enhancements.sql +0 -43
- package/.framework/migrations/005_auth_user_trigger.sql +0 -105
- package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
- package/.framework/migrations/016_invites.sql +0 -27
- package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
- package/.framework/migrations/018_apps_required_roles.sql +0 -17
- package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
- package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
- package/.framework/migrations/021_app_domains.sql +0 -112
- package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
- package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
- package/.framework/migrations/024_messages_account_id.sql +0 -9
- package/.framework/migrations/025_retype_threads_messages.sql +0 -240
- package/.framework/migrations/026_fix_rls_policies.sql +0 -47
- package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
- package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
- package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
- package/.framework/migrations/030_messages_updated_by.sql +0 -6
- package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
- package/docs/APPS.md +0 -232
- package/docs/ARCHITECTURE.md +0 -246
- package/docs/INSTALL.md +0 -155
- package/docs/design-schema-spec.md +0 -1837
- package/docs/dev-guides/01-create-an-app.md +0 -183
- package/docs/dev-guides/02-create-a-function.md +0 -178
- package/docs/dev-guides/03-create-a-component.md +0 -178
- package/docs/dev-guides/04-webhook-handlers.md +0 -129
- package/docs/dev-guides/05-testing.md +0 -168
- package/docs/dev-guides/README.md +0 -40
- package/docs/npm-packages-plan.md +0 -288
- package/docs/spine-core--api-reference.md +0 -822
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import React, { useState, useEffect, useCallback, useMemo } from 'react'
|
|
2
|
+
import { apiFetch } from '../../lib/api'
|
|
3
|
+
|
|
4
|
+
export interface AllowedRole {
|
|
5
|
+
slug: string
|
|
6
|
+
name: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface Member {
|
|
10
|
+
id: string
|
|
11
|
+
full_name: string | null
|
|
12
|
+
email: string
|
|
13
|
+
status: string
|
|
14
|
+
role: { id: string; slug: string; name: string } | null
|
|
15
|
+
is_active: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function callInvitesApi(action: string, params: Record<string, any> = {}, method: 'GET' | 'POST' = 'GET') {
|
|
19
|
+
const base = '/.netlify/functions/invites'
|
|
20
|
+
if (method === 'GET') {
|
|
21
|
+
const qs = new URLSearchParams({ action, ...params }).toString()
|
|
22
|
+
const res = await apiFetch(`${base}?${qs}`)
|
|
23
|
+
return res.json()
|
|
24
|
+
}
|
|
25
|
+
const res = await apiFetch(`${base}?action=${action}`, {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
headers: { 'Content-Type': 'application/json' },
|
|
28
|
+
body: JSON.stringify(params),
|
|
29
|
+
})
|
|
30
|
+
return res.json()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface MemberListProps {
|
|
34
|
+
accountId?: string
|
|
35
|
+
allowedRoles: AllowedRole[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function MemberList({ accountId, allowedRoles }: MemberListProps) {
|
|
39
|
+
const [members, setMembers] = useState<Member[]>([])
|
|
40
|
+
const [loading, setLoading] = useState(true)
|
|
41
|
+
const [error, setError] = useState('')
|
|
42
|
+
const [search, setSearch] = useState('')
|
|
43
|
+
const [selectedRole, setSelectedRole] = useState<Record<string, string>>({})
|
|
44
|
+
|
|
45
|
+
const load = useCallback(async () => {
|
|
46
|
+
if (!accountId) return
|
|
47
|
+
setLoading(true)
|
|
48
|
+
setError('')
|
|
49
|
+
const result = await callInvitesApi('list-members', { account_id: accountId })
|
|
50
|
+
setLoading(false)
|
|
51
|
+
if (result.error) {
|
|
52
|
+
setError(result.error)
|
|
53
|
+
} else {
|
|
54
|
+
const rows = (result.data || []).filter((m: Member) => m.is_active || m.status === 'active')
|
|
55
|
+
setMembers(rows)
|
|
56
|
+
const roleMap: Record<string, string> = {}
|
|
57
|
+
for (const m of rows) {
|
|
58
|
+
if (m.role?.slug) roleMap[m.id] = m.role.slug
|
|
59
|
+
}
|
|
60
|
+
setSelectedRole(roleMap)
|
|
61
|
+
}
|
|
62
|
+
}, [accountId])
|
|
63
|
+
|
|
64
|
+
useEffect(() => { load() }, [load])
|
|
65
|
+
|
|
66
|
+
const handleRoleChange = async (personId: string) => {
|
|
67
|
+
const newSlug = selectedRole[personId]
|
|
68
|
+
const current = members.find(m => m.id === personId)?.role?.slug
|
|
69
|
+
if (!newSlug || newSlug === current) return
|
|
70
|
+
|
|
71
|
+
setError('')
|
|
72
|
+
const result = await callInvitesApi('update-member', { person_id: personId, role_slug: newSlug }, 'POST')
|
|
73
|
+
if (result.error) {
|
|
74
|
+
setError(result.error)
|
|
75
|
+
} else {
|
|
76
|
+
await load()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const handleDeactivate = async (personId: string) => {
|
|
81
|
+
setError('')
|
|
82
|
+
const result = await callInvitesApi('deactivate-member', { person_id: personId }, 'POST')
|
|
83
|
+
if (result.error) {
|
|
84
|
+
setError(result.error)
|
|
85
|
+
} else {
|
|
86
|
+
await load()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const filtered = useMemo(() => {
|
|
91
|
+
const q = search.toLowerCase()
|
|
92
|
+
if (!q) return members
|
|
93
|
+
return members.filter(m =>
|
|
94
|
+
(m.full_name ?? '').toLowerCase().includes(q) ||
|
|
95
|
+
m.email.toLowerCase().includes(q) ||
|
|
96
|
+
(m.role?.name ?? '').toLowerCase().includes(q)
|
|
97
|
+
)
|
|
98
|
+
}, [members, search])
|
|
99
|
+
|
|
100
|
+
const canShowRole = (slug: string) => allowedRoles.some(r => r.slug === slug)
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<div className="space-y-4">
|
|
104
|
+
<div className="flex items-center justify-between">
|
|
105
|
+
<h2 className="text-lg font-medium text-slate-900">Active members</h2>
|
|
106
|
+
<input
|
|
107
|
+
type="text"
|
|
108
|
+
value={search}
|
|
109
|
+
onChange={e => setSearch(e.target.value)}
|
|
110
|
+
placeholder="Search members…"
|
|
111
|
+
className="w-64 px-3 py-2 border border-slate-300 rounded-[5px] shadow-sm placeholder-slate-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
{error && (
|
|
116
|
+
<div className="rounded-md bg-red-50 p-3">
|
|
117
|
+
<p className="text-sm text-red-800">{error}</p>
|
|
118
|
+
</div>
|
|
119
|
+
)}
|
|
120
|
+
|
|
121
|
+
{loading ? (
|
|
122
|
+
<div className="flex items-center justify-center py-12">
|
|
123
|
+
<div className="animate-spin rounded-full h-6 w-6 border-b-2 border-slate-900" />
|
|
124
|
+
</div>
|
|
125
|
+
) : filtered.length === 0 ? (
|
|
126
|
+
<div className="text-center py-8 text-slate-500">
|
|
127
|
+
<p className="text-sm">No active members.</p>
|
|
128
|
+
</div>
|
|
129
|
+
) : (
|
|
130
|
+
<div className="overflow-x-auto">
|
|
131
|
+
<table className="min-w-full divide-y divide-slate-200">
|
|
132
|
+
<thead>
|
|
133
|
+
<tr>
|
|
134
|
+
<th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Name</th>
|
|
135
|
+
<th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Email</th>
|
|
136
|
+
<th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Role</th>
|
|
137
|
+
<th className="px-4 py-3 text-right text-xs font-medium text-slate-500 uppercase tracking-wider">Actions</th>
|
|
138
|
+
</tr>
|
|
139
|
+
</thead>
|
|
140
|
+
<tbody className="divide-y divide-slate-100">
|
|
141
|
+
{filtered.map(m => (
|
|
142
|
+
<tr key={m.id} className="hover:bg-slate-50">
|
|
143
|
+
<td className="px-4 py-3 text-sm text-slate-900">{m.full_name || '—'}</td>
|
|
144
|
+
<td className="px-4 py-3 text-sm text-slate-600">{m.email}</td>
|
|
145
|
+
<td className="px-4 py-3 text-sm text-slate-600">
|
|
146
|
+
{canShowRole(m.role?.slug ?? '') ? m.role?.name : '—'}
|
|
147
|
+
</td>
|
|
148
|
+
<td className="px-4 py-3 text-right">
|
|
149
|
+
<div className="flex gap-2 justify-end items-center flex-wrap">
|
|
150
|
+
<select
|
|
151
|
+
value={selectedRole[m.id] ?? m.role?.slug ?? ''}
|
|
152
|
+
onChange={e => setSelectedRole(s => ({ ...s, [m.id]: e.target.value }))}
|
|
153
|
+
className="text-sm border border-slate-300 rounded-[5px] px-2 py-1 focus:outline-none focus:ring-blue-500 focus:border-blue-500"
|
|
154
|
+
>
|
|
155
|
+
{allowedRoles.map(r => (
|
|
156
|
+
<option key={r.slug} value={r.slug}>{r.name}</option>
|
|
157
|
+
))}
|
|
158
|
+
</select>
|
|
159
|
+
<button
|
|
160
|
+
onClick={() => handleRoleChange(m.id)}
|
|
161
|
+
disabled={selectedRole[m.id] === m.role?.slug}
|
|
162
|
+
className="text-xs text-blue-600 hover:text-blue-800 px-2 py-1 rounded border border-blue-200 hover:border-blue-400 disabled:opacity-50"
|
|
163
|
+
>
|
|
164
|
+
Update
|
|
165
|
+
</button>
|
|
166
|
+
<button
|
|
167
|
+
onClick={() => handleDeactivate(m.id)}
|
|
168
|
+
className="text-xs text-red-600 hover:text-red-800 px-2 py-1 rounded border border-red-200 hover:border-red-400"
|
|
169
|
+
>
|
|
170
|
+
Deactivate
|
|
171
|
+
</button>
|
|
172
|
+
</div>
|
|
173
|
+
</td>
|
|
174
|
+
</tr>
|
|
175
|
+
))}
|
|
176
|
+
</tbody>
|
|
177
|
+
</table>
|
|
178
|
+
</div>
|
|
179
|
+
)}
|
|
180
|
+
</div>
|
|
181
|
+
)
|
|
182
|
+
}
|
|
@@ -1,66 +1,52 @@
|
|
|
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
1
|
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// CIL[BEGIN chunk_id="SchemaFields_module_header_1783927912" type="module_header" identity="module_header" parent="none"]
|
|
8
|
+
// CIL[DOC-MACRO purpose="Import dependencies and define schema field component interfaces"]
|
|
9
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Manage React imports and field component prop types"]
|
|
10
|
+
// CIL[DOC-CONTEXT module="schema-fields" layer="frontend-component" related_files="[\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
|
|
11
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Imported modules and interfaces" errors="none" side_effects="none"]
|
|
12
|
+
// CIL[DOC-MICRO logic_summary="Imports React, field types, and component, defines SchemaFieldsProps interface" notable_decisions="[]"]
|
|
13
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
14
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
15
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
16
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, \."]
|
|
17
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
18
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
19
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
20
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
21
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
29
22
|
import React from 'react'
|
|
30
23
|
import { FieldDefinition } from '../../types/types'
|
|
31
24
|
import { FieldRenderer } from './FieldRenderer'
|
|
32
25
|
|
|
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
26
|
interface SchemaFieldsProps {
|
|
46
27
|
fields: FieldDefinition[]
|
|
47
28
|
data: Record<string, any>
|
|
48
29
|
onChange?: (name: string, value: any) => void
|
|
49
30
|
readonly?: boolean
|
|
50
31
|
errors?: Record<string, string>
|
|
51
|
-
/** Render fields in a two-column grid (default: true) */
|
|
52
32
|
twoColumn?: boolean
|
|
53
|
-
/** display_type per field key, sourced from view config — never from field definitions */
|
|
54
33
|
displayTypes?: Record<string, string>
|
|
55
34
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
35
|
+
// CIL[END chunk_id="SchemaFields_module_header_1783927912"]
|
|
36
|
+
// CIL[BEGIN chunk_id="SchemaFields_schemafields_1783927912" type="function" identity="SchemaFields" parent="none"]
|
|
37
|
+
// CIL[DOC-MACRO purpose="Render schema-driven field grid with responsive layout"]
|
|
38
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display and manage multiple schema fields in grid format"]
|
|
39
|
+
// CIL[DOC-CONTEXT module="schema-fields" layer="frontend-component" related_files="[\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
|
|
40
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Responsive field grid" errors="none" side_effects="Renders UI, calls onChange"]
|
|
41
|
+
// CIL[DOC-MICRO logic_summary="Maps field definitions to SchemaField components, handles system vs JSONB data resolution" notable_decisions="[]"]
|
|
42
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
43
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
44
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/src/components/ui/dialog.tsx, \."]
|
|
45
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
46
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
47
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
48
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
49
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
64
50
|
export function SchemaFields({
|
|
65
51
|
fields,
|
|
66
52
|
data,
|
|
@@ -95,8 +81,21 @@ export function SchemaFields({
|
|
|
95
81
|
</div>
|
|
96
82
|
)
|
|
97
83
|
}
|
|
98
|
-
|
|
99
|
-
|
|
84
|
+
// CIL[END chunk_id="SchemaFields_schemafields_1783927912"]
|
|
85
|
+
// CIL[BEGIN chunk_id="SchemaFields_interface_1783927912" type="interface" identity="SchemaFieldProps" parent="none"]
|
|
86
|
+
// CIL[DOC-MACRO purpose="Define props interface for individual schema field wrapper"]
|
|
87
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Type definition for SchemaField component props"]
|
|
88
|
+
// CIL[DOC-CONTEXT module="schema-fields" layer="frontend-component" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
|
|
89
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Interface definition" errors="none" side_effects="Type definition"]
|
|
90
|
+
// CIL[DOC-MICRO logic_summary="Defines SchemaFieldProps interface with field, value, and callback properties" notable_decisions="[]"]
|
|
91
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
92
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
93
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
|
|
94
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
95
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
96
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
97
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
98
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
100
99
|
interface SchemaFieldProps {
|
|
101
100
|
field: FieldDefinition
|
|
102
101
|
value: any
|
|
@@ -105,7 +104,21 @@ interface SchemaFieldProps {
|
|
|
105
104
|
error?: string
|
|
106
105
|
displayType?: string
|
|
107
106
|
}
|
|
108
|
-
|
|
107
|
+
// CIL[END chunk_id="SchemaFields_interface_1783927912"]
|
|
108
|
+
// CIL[BEGIN chunk_id="SchemaFields_schemafield_1783927912" type="function" identity="SchemaField" parent="none"]
|
|
109
|
+
// CIL[DOC-MACRO purpose="Wrapper component that binds field name to FieldRenderer"]
|
|
110
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Connect individual field to FieldRenderer with proper callbacks"]
|
|
111
|
+
// CIL[DOC-CONTEXT module="schema-fields" layer="frontend-component" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
|
|
112
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="FieldRenderer component" errors="none" side_effects="Renders FieldRenderer"]
|
|
113
|
+
// CIL[DOC-MICRO logic_summary="Wraps FieldRenderer with name-binding logic and readonly handling" notable_decisions="[]"]
|
|
114
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
115
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
116
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/components/ui/dialog.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
|
|
117
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
118
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
119
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
120
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
121
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
109
122
|
function SchemaField({ field, value, onChange, readonly, error, displayType }: SchemaFieldProps) {
|
|
110
123
|
return (
|
|
111
124
|
<FieldRenderer
|
|
@@ -118,16 +131,21 @@ function SchemaField({ field, value, onChange, readonly, error, displayType }: S
|
|
|
118
131
|
/>
|
|
119
132
|
)
|
|
120
133
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
// CIL[END chunk_id="SchemaFields_schemafield_1783927912"]
|
|
135
|
+
// CIL[BEGIN chunk_id="SchemaFields_schemafielddisplay_1783927912" type="function" identity="SchemaFieldDisplay" parent="none"]
|
|
136
|
+
// CIL[DOC-MACRO purpose="Render read-only field value as label:value display row"]
|
|
137
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display formatted field values in compact detail view"]
|
|
138
|
+
// CIL[DOC-CONTEXT module="schema-fields" layer="frontend-component" related_files="[]"]
|
|
139
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Formatted display row" errors="none" side_effects="Renders UI"]
|
|
140
|
+
// CIL[DOC-MICRO logic_summary="Formats field value and renders as label-value pair with proper styling" notable_decisions="[]"]
|
|
141
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
142
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
143
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
144
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
145
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
146
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
147
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
148
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
131
149
|
export function SchemaFieldDisplay({
|
|
132
150
|
field,
|
|
133
151
|
value
|
|
@@ -148,22 +166,21 @@ export function SchemaFieldDisplay({
|
|
|
148
166
|
</div>
|
|
149
167
|
)
|
|
150
168
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
*/
|
|
169
|
+
// CIL[END chunk_id="SchemaFields_schemafielddisplay_1783927912"]
|
|
170
|
+
// CIL[BEGIN chunk_id="SchemaFields_formatfieldvalue_1783927912" type="function" identity="formatFieldValue" parent="none"]
|
|
171
|
+
// CIL[DOC-MACRO purpose="Format field values for read-only display based on data type"]
|
|
172
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Apply type-specific formatting to field values"]
|
|
173
|
+
// CIL[DOC-CONTEXT module="schema-fields" layer="frontend-component" related_files="[]"]
|
|
174
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Formatted ReactNode" errors="none" side_effects="none"]
|
|
175
|
+
// CIL[DOC-MICRO logic_summary="Switches on data_type to apply appropriate formatting (dates, booleans, URLs, JSON)" notable_decisions="[]"]
|
|
176
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
177
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
178
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
179
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
180
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
181
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
182
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
183
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
167
184
|
function formatFieldValue(field: FieldDefinition, value: any): React.ReactNode {
|
|
168
185
|
if (value === null || value === undefined || value === '') {
|
|
169
186
|
return <span className="text-slate-400 italic">—</span>
|
|
@@ -224,3 +241,4 @@ function formatFieldValue(field: FieldDefinition, value: any): React.ReactNode {
|
|
|
224
241
|
return String(value)
|
|
225
242
|
}
|
|
226
243
|
}
|
|
244
|
+
// CIL[END chunk_id="SchemaFields_formatfieldvalue_1783927912"]
|
|
@@ -1,27 +1,29 @@
|
|
|
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
1
|
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// CIL[BEGIN chunk_id="DataTable_moduleheader_1783907801" type="module_header" identity="imports" parent="none"]
|
|
13
|
+
// CIL[DOC-MACRO purpose="Import React and table dependencies"]
|
|
14
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide all external dependencies for data table components"]
|
|
15
|
+
// CIL[DOC-CONTEXT module="DataTable" layer="frontend-component" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
|
|
16
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="React, useState, table components, UI components" errors="none" side_effects="none"]
|
|
17
|
+
// CIL[DOC-MICRO logic_summary="Imports React hooks, shadcn table primitives, badge, button, icons" notable_decisions="[]"]
|
|
18
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
19
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
20
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
21
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/src/components/ui/dialog.tsx, \."]
|
|
22
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
23
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
24
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
25
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
26
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
25
27
|
import React, { useState } from 'react'
|
|
26
28
|
import {
|
|
27
29
|
Table,
|
|
@@ -35,41 +37,61 @@ import { Badge } from './badge'
|
|
|
35
37
|
import { Button } from './button'
|
|
36
38
|
import { Search, Filter } from 'lucide-react'
|
|
37
39
|
import { cn } from '../../lib/utils'
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// CIL[END chunk_id="DataTable_moduleheader_1783907801"]
|
|
41
|
+
// CIL[BEGIN chunk_id="DataTable_tablecolumn_1783907801" type="interface" identity="TableColumn" parent="none"]
|
|
42
|
+
// CIL[DOC-MACRO purpose="Define base table column interface"]
|
|
43
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Specify basic column properties for table rendering"]
|
|
44
|
+
// CIL[DOC-CONTEXT module="DataTable" layer="frontend-component" related_files="[\".framework/src/components/layout/Sidebar.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
|
|
45
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="TableColumn interface" errors="none" side_effects="none"]
|
|
46
|
+
// CIL[DOC-MICRO logic_summary="Generic column interface with key, title, render function, and sort flag" notable_decisions="[]"]
|
|
47
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
48
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
49
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: .framework/src/components/layout/Sidebar.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/principal.ts, \."]
|
|
50
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
51
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
52
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
53
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
54
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
42
55
|
interface TableColumn<T> {
|
|
43
56
|
key: keyof T | string
|
|
44
57
|
title: string
|
|
45
58
|
render?: (row: T) => React.ReactNode
|
|
46
59
|
sortable?: boolean
|
|
47
60
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
61
|
+
// CIL[END chunk_id="DataTable_tablecolumn_1783907801"]
|
|
62
|
+
// CIL[BEGIN chunk_id="DataTable_datatablecolumn_1783907801" type="interface" identity="DataTableColumn" parent="none"]
|
|
63
|
+
// CIL[DOC-MACRO purpose="Define extended table column interface with filtering"]
|
|
64
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Extend TableColumn with filter-specific properties"]
|
|
65
|
+
// CIL[DOC-CONTEXT module="DataTable" layer="frontend-component" related_files="[\".framework/src/components/layout/Sidebar.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"\\\"]"]
|
|
66
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="DataTableColumn interface" errors="none" side_effects="none"]
|
|
67
|
+
// CIL[DOC-MICRO logic_summary="Adds filterable flag and filter options array to base column interface" notable_decisions="[]"]
|
|
68
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
69
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
70
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: .framework/src/components/layout/Sidebar.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/functions/custom_cil-embeddings.ts, \."]
|
|
71
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
72
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
73
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
74
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
75
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
52
76
|
interface DataTableColumn<T> extends TableColumn<T> {
|
|
53
77
|
filterable?: boolean
|
|
54
78
|
filterOptions?: Array<{ value: string; label: string }>
|
|
55
79
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
* @prop emptyMessage - Empty-state text
|
|
72
|
-
*/
|
|
80
|
+
// CIL[END chunk_id="DataTable_datatablecolumn_1783907801"]
|
|
81
|
+
// CIL[BEGIN chunk_id="DataTable_datatableprops_1783907801" type="interface" identity="DataTableProps" parent="none"]
|
|
82
|
+
// CIL[DOC-MACRO purpose="Define comprehensive data table props interface"]
|
|
83
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Specify all props needed for DataTable component configuration"]
|
|
84
|
+
// CIL[DOC-CONTEXT module="DataTable" layer="frontend-component" related_files="[\".framework/src/components/layout/Sidebar.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
|
|
85
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="DataTableProps interface" errors="none" side_effects="none"]
|
|
86
|
+
// CIL[DOC-MICRO logic_summary="Extensive props for data, columns, search, filters, pagination, and callbacks" notable_decisions="[]"]
|
|
87
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
88
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
89
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: .framework/src/components/layout/Sidebar.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/schema-utils.ts, .framework/functions/_shared/principal.ts, \."]
|
|
90
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
91
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
92
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
93
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
94
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
73
95
|
interface DataTableProps<T> {
|
|
74
96
|
data: T[]
|
|
75
97
|
columns: DataTableColumn<T>[]
|
|
@@ -94,14 +116,21 @@ interface DataTableProps<T> {
|
|
|
94
116
|
emptyMessage?: string
|
|
95
117
|
className?: string
|
|
96
118
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
119
|
+
// CIL[END chunk_id="DataTable_datatableprops_1783907801"]
|
|
120
|
+
// CIL[BEGIN chunk_id="DataTable_datatable_1783907801" type="function" identity="DataTable" parent="none"]
|
|
121
|
+
// CIL[DOC-MACRO purpose="Render full-featured data table with search, filters, sort, and pagination"]
|
|
122
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Handle table state management, user interactions, and data rendering"]
|
|
123
|
+
// CIL[DOC-CONTEXT module="DataTable" layer="frontend-component" related_files="[]"]
|
|
124
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Table with search/filter controls" errors="none" side_effects="Calls search/filter/sort callbacks"]
|
|
125
|
+
// CIL[DOC-MICRO logic_summary="Manages internal search/filter state, renders UI controls and table body" notable_decisions="[]"]
|
|
126
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
127
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
128
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
129
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
130
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
131
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
132
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
133
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
105
134
|
export function DataTable<T extends Record<string, any>>({
|
|
106
135
|
data,
|
|
107
136
|
columns,
|
|
@@ -341,3 +370,4 @@ export function DataTable<T extends Record<string, any>>({
|
|
|
341
370
|
</div>
|
|
342
371
|
)
|
|
343
372
|
}
|
|
373
|
+
// CIL[END chunk_id="DataTable_datatable_1783907801"]
|