spine-framework 0.4.3 → 0.5.0-rc.4
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/.env.example +13 -3
- package/.framework/cli/commands/bootstrap.ts +392 -0
- package/.framework/cli/commands/dev.ts +91 -218
- package/.framework/cli/commands/doctor.ts +132 -26
- package/.framework/cli/commands/generate.ts +38 -298
- package/.framework/cli/commands/init.ts +20 -1
- package/.framework/cli/commands/migrate.ts +36 -30
- package/.framework/cli/commands/migrations.ts +16 -56
- package/.framework/cli/commands/upgrade.ts +35 -0
- package/.framework/cli/commands/validate-schema.ts +147 -0
- package/.framework/cli/context.ts +223 -110
- package/.framework/cli/index.ts +6 -0
- package/.framework/cli/lib/project-files.ts +241 -1
- package/.framework/functions/_shared/agent-runner.ts +1000 -81
- package/.framework/functions/_shared/cil.ts +2 -1
- package/.framework/functions/_shared/db.ts +3 -6
- package/.framework/functions/_shared/hash-api-key.ts +183 -79
- package/.framework/functions/_shared/kb.ts +61 -7
- package/.framework/functions/_shared/logging.ts +562 -224
- package/.framework/functions/_shared/message-sequence.ts +53 -0
- package/.framework/functions/_shared/middleware.ts +47 -44
- package/.framework/functions/_shared/pipeline-runner.ts +150 -37
- package/.framework/functions/_shared/principal.ts +9 -6
- package/.framework/functions/_shared/trigger-engine.ts +149 -40
- package/.framework/functions/admin-data.ts +48 -31
- package/.framework/functions/ai-agents.ts +103 -33
- package/.framework/functions/api-keys.ts +301 -122
- package/.framework/functions/apps.ts +43 -26
- package/.framework/functions/cil-ingest.ts +48 -15
- package/.framework/functions/debug-auth.ts +14 -8
- package/.framework/functions/deliveries.ts +39 -12
- package/.framework/functions/embeddings.ts +145 -76
- package/.framework/functions/integration-outbound.ts +67 -27
- package/.framework/functions/integrations.ts +254 -127
- package/.framework/functions/logs.ts +273 -133
- package/.framework/functions/observability.ts +277 -147
- package/.framework/functions/pipeline-executions.ts +1 -1
- package/.framework/functions/pipeline-runner-background.ts +120 -0
- package/.framework/functions/pipelines.ts +14 -9
- package/.framework/functions/prompt-configs.ts +7 -4
- package/.framework/functions/roles.ts +8 -5
- package/.framework/functions/security.ts +30 -17
- package/.framework/functions/system-cron.ts +250 -128
- package/.framework/functions/tests.ts +7 -6
- package/.framework/functions/timers.ts +310 -107
- package/.framework/functions/trigger-scheduler.ts +65 -5
- package/.framework/functions/triggers.ts +28 -13
- package/.framework/functions/types.ts +13 -10
- package/.framework/migrations/064_episode_leases.sql +196 -0
- package/.framework/migrations/065_execution_tables_updated_at.sql +20 -0
- package/.framework/migrations/066_episode_steal_thread_merge.sql +148 -0
- package/.framework/migrations/067_episode_lease_stale_steal.sql +93 -0
- package/.framework/migrations/068_cron_schedule_timer_rpcs.sql +251 -0
- package/.framework/migrations/069_log_stats_window.sql +54 -0
- package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
- package/.framework/migrations/071_timer_interval_keys.sql +96 -0
- package/.framework/migrations/072_slug_autofill.sql +77 -0
- package/.framework/migrations/073_seed_member_roles.sql +26 -0
- package/.framework/schemas/spine.config.schema.json +62 -0
- package/.framework/src/App.tsx +3 -1
- package/.framework/src/apps/admin/index.tsx +1141 -775
- package/.framework/src/components/ErrorBoundary.tsx +136 -0
- package/.framework/src/components/admin/AdminListPage.tsx +81 -73
- package/.framework/src/components/admin/AdminSidebar.tsx +92 -81
- package/.framework/src/components/admin/EntitySelect.tsx +181 -0
- package/.framework/src/components/admin/PageInstructions.tsx +86 -127
- package/.framework/src/components/app-shell/GenericAppShell.tsx +3 -1
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
- package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
- package/.framework/src/components/auth/TurnstileWidget.tsx +9 -6
- package/.framework/src/components/kb/KBArticleEditor.tsx +49 -6
- package/.framework/src/components/layout/Layout.tsx +4 -2
- package/.framework/src/components/layout/Sidebar.tsx +304 -179
- package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
- package/.framework/src/components/runtime/DataHeader.tsx +96 -48
- package/.framework/src/components/runtime/DataListPage.tsx +3 -26
- package/.framework/src/components/runtime/DataStats.tsx +10 -10
- package/.framework/src/components/runtime/DataTable.tsx +12 -10
- package/.framework/src/components/ui/sheet.tsx +24 -26
- package/.framework/src/components/ui/textarea.tsx +74 -48
- package/.framework/src/hooks/useBranding.ts +47 -0
- package/.framework/src/hooks/useEntityList.ts +12 -9
- package/.framework/src/hooks/useListSchema.ts +108 -58
- package/.framework/src/instructions/README.md +57 -0
- package/.framework/src/instructions/ai-agents.md +69 -0
- package/.framework/src/instructions/alerts.md +80 -0
- package/.framework/src/instructions/api-keys.md +87 -0
- package/.framework/src/instructions/apps.md +77 -0
- package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
- package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
- package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
- package/.framework/src/instructions/concepts/automation.md +186 -0
- package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
- package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
- package/.framework/src/instructions/concepts/design-schema.md +152 -0
- package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
- package/.framework/src/instructions/concepts/observability.md +116 -0
- package/.framework/src/instructions/concepts/permissions.md +150 -0
- package/.framework/src/instructions/concepts/runtime-records.md +111 -0
- package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
- package/.framework/src/instructions/concepts/spine-way.md +172 -0
- package/.framework/src/instructions/deliveries.md +59 -0
- package/.framework/src/instructions/guide/00-orientation.md +106 -0
- package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
- package/.framework/src/instructions/guide/02-project-map.md +147 -0
- package/.framework/src/instructions/guide/03-domain-model.md +223 -0
- package/.framework/src/instructions/guide/04-first-app.md +227 -0
- package/.framework/src/instructions/guide/05-glossary.md +183 -0
- package/.framework/src/instructions/integrations.md +96 -0
- package/.framework/src/instructions/internal/cil-markers.md +83 -0
- package/.framework/src/instructions/invites.md +60 -0
- package/.framework/src/instructions/kb.md +80 -0
- package/.framework/src/instructions/logs.md +77 -0
- package/.framework/src/instructions/observability.md +61 -0
- package/.framework/src/instructions/operations/deployment.md +115 -0
- package/.framework/src/instructions/operations/migrations.md +125 -0
- package/.framework/src/instructions/operations/security-checklist.md +148 -0
- package/.framework/src/instructions/operations/troubleshooting.md +170 -0
- package/.framework/src/instructions/operations/upgrade.md +116 -0
- package/.framework/src/instructions/pipeline-executions.md +62 -0
- package/.framework/src/instructions/pipelines.md +78 -0
- package/.framework/src/instructions/prompts.md +95 -0
- package/.framework/src/instructions/reference/api/admin-data.md +162 -0
- package/.framework/src/instructions/reference/api/auth.md +113 -0
- package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
- package/.framework/src/instructions/reference/app-manifest.md +150 -0
- package/.framework/src/instructions/reference/cli.md +124 -0
- package/.framework/src/instructions/reference/database.md +132 -0
- package/.framework/src/instructions/reference/design-schema.md +280 -0
- package/.framework/src/instructions/reference/env-vars.md +133 -0
- package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
- package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
- package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
- package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
- package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
- package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
- package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
- package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
- package/.framework/src/instructions/reference/functions/apps.md +140 -0
- package/.framework/src/instructions/reference/functions/auth.md +99 -0
- package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
- package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
- package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
- package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
- package/.framework/src/instructions/reference/functions/index.md +103 -0
- package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
- package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
- package/.framework/src/instructions/reference/functions/integrations.md +130 -0
- package/.framework/src/instructions/reference/functions/invites.md +182 -0
- package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
- package/.framework/src/instructions/reference/functions/kb.md +166 -0
- package/.framework/src/instructions/reference/functions/logs.md +141 -0
- package/.framework/src/instructions/reference/functions/observability.md +105 -0
- package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
- package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
- package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
- package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
- package/.framework/src/instructions/reference/functions/roles.md +121 -0
- package/.framework/src/instructions/reference/functions/security.md +140 -0
- package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
- package/.framework/src/instructions/reference/functions/system.md +106 -0
- package/.framework/src/instructions/reference/functions/tests.md +97 -0
- package/.framework/src/instructions/reference/functions/timers.md +117 -0
- package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
- package/.framework/src/instructions/reference/functions/triggers.md +140 -0
- package/.framework/src/instructions/reference/functions/types.md +146 -0
- package/.framework/src/instructions/reference/seeds.md +126 -0
- package/.framework/src/instructions/reference/shared-modules.md +127 -0
- package/.framework/src/instructions/reference/spine-config.md +114 -0
- package/.framework/src/instructions/roles.md +80 -0
- package/.framework/src/instructions/runtime-detail.md +70 -0
- package/.framework/src/instructions/runtime-list.md +77 -0
- package/.framework/src/instructions/security.md +67 -0
- package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
- package/.framework/src/instructions/tasks/add-a-role.md +96 -0
- package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
- package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
- package/.framework/src/instructions/tasks/add-a-type.md +151 -0
- package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
- package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
- package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
- package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
- package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
- package/.framework/src/instructions/tasks/test-your-code.md +108 -0
- package/.framework/src/instructions/tasks/write-a-function.md +132 -0
- package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
- package/.framework/src/instructions/testing.md +59 -0
- package/.framework/src/instructions/timers.md +82 -0
- package/.framework/src/instructions/triggers.md +69 -0
- package/.framework/src/instructions/types.md +93 -0
- package/.framework/src/lib/branding.ts +128 -0
- package/.framework/src/pages/NoAppPage.tsx +3 -1
- package/.framework/src/pages/NotFoundPage.tsx +62 -31
- package/.framework/src/pages/SetupPage.tsx +5 -2
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
- package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
- package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
- package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
- package/.framework/src/pages/admin/AppsPage.tsx +104 -66
- package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
- package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
- package/.framework/src/pages/admin/LogsPage.tsx +144 -76
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
- package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
- package/.framework/src/pages/admin/RolesPage.tsx +86 -43
- package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
- package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
- package/.framework/src/pages/admin/TimersPage.tsx +90 -62
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
- package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
- package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
- package/.framework/src/pages/admin/TypesPage.tsx +90 -48
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +3 -1
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +3 -1
- package/.framework/src/pages/auth/LoginPage.tsx +4 -2
- package/.framework/src/pages/auth/RegisterPage.tsx +3 -1
- package/.framework/templates/agent/AGENTS.md +150 -0
- package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
- package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
- package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
- package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
- package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
- package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
- package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
- package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
- package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
- package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
- package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
- package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
- package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
- package/.framework/templates/project.json +5 -1
- package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
- package/.framework/tests/unit/agent-files.test.ts +355 -0
- package/.framework/tests/unit/agent-runner.test.ts +496 -47
- package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
- package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
- package/.framework/tests/unit/bootstrap.test.ts +242 -0
- package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
- package/.framework/tests/unit/debug-auth.test.ts +38 -0
- package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
- package/.framework/tests/unit/episode-lease.test.ts +695 -0
- package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
- package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +19 -0
- package/.framework/tests/unit/logging-app-id.test.ts +75 -0
- package/.framework/tests/unit/pipeline-runner-background.test.ts +120 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +153 -1
- package/.framework/tests/unit/principal-cache.test.ts +15 -0
- package/.framework/tests/unit/system-context-denial.test.ts +145 -0
- package/.framework/tests/unit/system-cron.test.ts +240 -0
- package/.framework/tests/unit/timers.test.ts +159 -0
- package/.framework/tests/unit/trigger-engine.test.ts +278 -91
- package/.framework/tests/unit/trigger-scheduler.test.ts +78 -0
- package/README.md +125 -166
- package/config/tsconfig.cli.json +2 -2
- package/netlify.toml +5 -0
- package/package.json +15 -4
- package/templates/project/package-lock.json +2 -2
- 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/assembly-launch-guide.md +0 -138
- package/.framework/docs/audit-results.md +0 -590
- package/.framework/docs/db-api-inventory.md +0 -95
- package/.framework/docs/gap-remediation-backlog.md +0 -103
- 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/mcp/index.ts +0 -133
- package/.framework/mcp/load-env.ts +0 -60
- package/.framework/mcp/shared/app-manifest.ts +0 -275
- package/.framework/mcp/shared/db.ts +0 -477
- package/.framework/mcp/shared/kb.ts +0 -118
- package/.framework/mcp/tools/architect.ts +0 -431
- package/.framework/mcp/tools/cil/context.ts +0 -345
- package/.framework/mcp/tools/cil/graph.ts +0 -242
- package/.framework/mcp/tools/cil/ingest.ts +0 -1217
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
- package/.framework/mcp/tools/cil/pipeline.ts +0 -767
- package/.framework/mcp/tools/cil/project.ts +0 -791
- package/.framework/mcp/tools/cil/retrieval.ts +0 -336
- package/.framework/mcp/tools/cil/search-core.ts +0 -454
- package/.framework/mcp/tools/cil/search.ts +0 -97
- package/.framework/mcp/tools/cil/suggest.ts +0 -186
- package/.framework/mcp/tools/cil/validate.ts +0 -1369
- package/.framework/mcp/tools/kb/delete.ts +0 -139
- package/.framework/mcp/tools/kb/index.ts +0 -52
- package/.framework/mcp/tools/kb/ingest.ts +0 -84
- package/.framework/mcp/tools/kb/list-types.ts +0 -102
- package/.framework/mcp/tools/kb/publish.ts +0 -100
- package/.framework/mcp/tools/kb/reindex.ts +0 -86
- package/.framework/mcp/tools/kb/revoke.ts +0 -85
- package/.framework/mcp/tools/kb/search.ts +0 -101
- package/.framework/mcp/tools/kb/upsert.ts +0 -125
- package/.framework/mcp/tools/observability.ts +0 -510
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/TimerDetailPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/admin/TimerDetailPage.tsx"]
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @module TimerDetailPage
|
|
4
|
+
* @audience internal
|
|
5
|
+
* @layer app-specific
|
|
6
|
+
* @stability stable
|
|
7
|
+
*
|
|
8
|
+
* The TimerDetailPage module is responsible for displaying and managing the details of a timer within the admin interface. It allows users to view, edit, and configure timer settings, leveraging various UI components for a seamless experience.
|
|
9
|
+
* INVARIANT: The user must have appropriate permissions to access this page.
|
|
10
|
+
*
|
|
11
|
+
* @seeAlso apiFetch (handles API requests for timer data).
|
|
12
|
+
* @seeAlso PageInstructions (provides guidance on using the page).
|
|
13
|
+
* @seeAlso EntitySelect (used for selecting related entities).
|
|
14
|
+
*
|
|
15
|
+
* @cil-generated
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
10
26
|
|
|
11
27
|
|
|
12
28
|
|
|
@@ -21,29 +37,39 @@ import { Textarea } from '../../components/ui/textarea'
|
|
|
21
37
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../components/ui/select'
|
|
22
38
|
import { Checkbox } from '../../components/ui/checkbox'
|
|
23
39
|
import { Label } from '../../components/ui/label'
|
|
40
|
+
import { AppSelect, PipelineSelect } from '../../components/admin/EntitySelect'
|
|
24
41
|
import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card'
|
|
25
42
|
import { Skeleton } from '../../components/ui/skeleton'
|
|
26
43
|
import { Alert, AlertDescription, AlertTitle } from '../../components/ui/alert'
|
|
27
44
|
import { Badge } from '../../components/ui/badge'
|
|
28
45
|
import { ArrowLeft, Clock, AlertCircle } from 'lucide-react'
|
|
29
46
|
import { formatDateTime } from '../../lib/utils'
|
|
30
|
-
import { PageInstructions } from '../../components/admin/PageInstructions'
|
|
31
|
-
|
|
32
|
-
// CIL[DOC-VECTOR type="context" content="purpose='Admin detail page for creating and editing scheduled timers.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx"]
|
|
33
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
34
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
35
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
36
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
37
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
38
47
|
// CIL[END stable_id="~/.framework/src/pages/admin/TimerDetailPage.tsx:module_header:module_header"]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
39
65
|
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/TimerDetailPage.tsx:Timer:interface" type="interface" identity="Timer" parent="~/.framework/src/pages/admin/TimerDetailPage.tsx"]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
66
|
+
/**
|
|
67
|
+
* The Timer interface defines the structure for timer objects used in the application, encapsulating properties related to timer configuration, state, and metadata. It serves as a blueprint for managing timers effectively within the system.
|
|
68
|
+
*
|
|
69
|
+
* @sideEffects none
|
|
70
|
+
* @stability stable
|
|
71
|
+
* @cil-generated
|
|
72
|
+
*/
|
|
47
73
|
interface Timer {
|
|
48
74
|
id: string
|
|
49
75
|
name: string
|
|
@@ -57,47 +83,75 @@ interface Timer {
|
|
|
57
83
|
created_at: string
|
|
58
84
|
updated_at: string
|
|
59
85
|
}
|
|
60
|
-
// CIL[DOC-VECTOR type="context" content="purpose='TypeScript type contract for a Timer record.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx"]
|
|
61
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
62
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
63
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
64
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
65
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
66
86
|
// CIL[END stable_id="~/.framework/src/pages/admin/TimerDetailPage.tsx:Timer:interface"]
|
|
67
87
|
|
|
68
88
|
|
|
69
89
|
|
|
70
90
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/TimerDetailPage.tsx:TIMER_TYPES:constant" type="constant" identity="TIMER_TYPES" parent="~/.framework/src/pages/admin/TimerDetailPage.tsx"]
|
|
109
|
+
/**
|
|
110
|
+
* TIMER_TYPES defines a set of timer configurations available in the application, providing options for interval-based, cron-based, and one-time timers. This constant is used to facilitate the selection of timer types in the user interface.
|
|
111
|
+
*
|
|
112
|
+
* @sideEffects none
|
|
113
|
+
* @stability stable
|
|
114
|
+
* @cil-generated
|
|
115
|
+
*/
|
|
79
116
|
const TIMER_TYPES = [
|
|
80
117
|
{ value: 'interval', label: 'Interval' },
|
|
81
118
|
{ value: 'cron', label: 'Cron Expression' },
|
|
82
119
|
{ value: 'once', label: 'One-time' }
|
|
83
120
|
]
|
|
84
|
-
// CIL[
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
121
|
+
// CIL[END stable_id="~/.framework/src/pages/admin/TimerDetailPage.tsx:TIMER_TYPES:constant"]
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
91
139
|
|
|
92
140
|
|
|
93
141
|
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/TimerDetailPage.tsx:TimerDetailPage:component" type="component" identity="TimerDetailPage" parent="~/.framework/src/pages/admin/TimerDetailPage.tsx"]
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
142
|
+
/**
|
|
143
|
+
* The TimerDetailPage component manages the creation and editing of timer configurations in an admin interface. It fetches existing timer data for editing or initializes a new timer for creation.
|
|
144
|
+
*
|
|
145
|
+
* @macro Component responsible for displaying and managing timer details.
|
|
146
|
+
* @micro Uses React hooks to manage state and side effects for fetching and saving timer data.
|
|
147
|
+
* @outputSpec JSX.Element
|
|
148
|
+
* @throws Error — Invalid config JSON, Error — Invalid metadata JSON
|
|
149
|
+
* @sideEffects Fetches timer data from an external API, saves timer data to an external API.
|
|
150
|
+
* @stability stable
|
|
151
|
+
* @calls apiFetch, useParams, useNavigate
|
|
152
|
+
* @errorHandling Sets error state on failure to fetch or save timer data.
|
|
153
|
+
* @cil-generated
|
|
154
|
+
*/
|
|
101
155
|
export function TimerDetailPage() {
|
|
102
156
|
const { id } = useParams<{ id: string }>()
|
|
103
157
|
const navigate = useNavigate()
|
|
@@ -111,7 +165,7 @@ export function TimerDetailPage() {
|
|
|
111
165
|
description: '',
|
|
112
166
|
app_id: '',
|
|
113
167
|
timer_type: 'interval' as const,
|
|
114
|
-
config: JSON.stringify({
|
|
168
|
+
config: JSON.stringify({ interval_minutes: 60 }, null, 2),
|
|
115
169
|
pipeline_id: '',
|
|
116
170
|
metadata: '{}',
|
|
117
171
|
is_active: true
|
|
@@ -203,57 +257,18 @@ export function TimerDetailPage() {
|
|
|
203
257
|
) : !isCreateMode && <Button onClick={() => setIsEditing(true)}>Edit</Button>}
|
|
204
258
|
</div>
|
|
205
259
|
</div>
|
|
206
|
-
|
|
207
|
-
<PageInstructions
|
|
208
|
-
description="Schedule a timer to run actions at intervals, via cron, or once."
|
|
209
|
-
sections={[
|
|
210
|
-
{ title: 'What this timer controls', content: 'A timer is a scheduled job that calls a target function or pipeline on an interval, a cron schedule, or one time. It is the Spine equivalent of a recurring or one-off background task.' },
|
|
211
|
-
{ title: 'Fields explained', content: <ul className="list-disc pl-4 space-y-1">
|
|
212
|
-
<li><strong>Name</strong> — string. The display name. Missing name prevents saving.</li>
|
|
213
|
-
<li><strong>Type</strong> — select. interval, cron, or once. Controls which schedule field in Config is used and how the next run is calculated.</li>
|
|
214
|
-
<li><strong>App ID</strong> — string. Optional owning app UUID; blank means account-scoped.</li>
|
|
215
|
-
<li><strong>Pipeline ID</strong> — string. The pipeline to invoke when the timer fires.</li>
|
|
216
|
-
<li><strong>Active</strong> — checkbox. Inactive timers are skipped by the scheduler.</li>
|
|
217
|
-
<li><strong>Description</strong> — string. Optional notes.</li>
|
|
218
|
-
<li><strong>Config (JSON)</strong> — JSON. The timer schedule, e.g. { `{ "schedule": "0 */6 * * *" }` } for cron, { `{ "interval_seconds": 3600 }` } for interval, or { `{ "run_at": "2026-01-01T00:00:00Z" }` } for once.</li>
|
|
219
|
-
<li><strong>Metadata (JSON)</strong> — JSON. Optional metadata about the timer.</li>
|
|
220
|
-
</ul> },
|
|
221
|
-
{ title: 'Options and values', content: <ul className="list-disc pl-4 space-y-1">
|
|
222
|
-
<li><strong>interval</strong>: config should contain interval_seconds.</li>
|
|
223
|
-
<li><strong>cron</strong>: config should contain a schedule cron expression like 0 */6 * * *.</li>
|
|
224
|
-
<li><strong>once</strong>: config should contain a run_at ISO timestamp.</li>
|
|
225
|
-
</ul> },
|
|
226
|
-
{ title: 'Downstream impact', content: <ul className="list-disc pl-4 space-y-1">
|
|
227
|
-
<li>The scheduler uses the active flag and the timer_type/config fields to determine the next run and to enqueue the pipeline.</li>
|
|
228
|
-
<li>Pipeline ID must refer to an existing pipeline; otherwise the timer will fail with a missing handler.</li>
|
|
229
|
-
</ul> },
|
|
230
|
-
{ title: 'How to create, save, and validate', content: <ol className="list-decimal pl-4 space-y-1">
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
<li>Pick the timer type and fill the Config JSON with the matching schedule. Enter the Pipeline ID and optional Metadata JSON.</li>
|
|
234
|
-
<li>Click Create to save or Edit then Save for existing timers.</li>
|
|
235
|
-
<li>Validation checks the name, timer type, and that Config and Metadata are valid JSON.</li>
|
|
236
|
-
</ol> },
|
|
237
|
-
{ title: 'Common mistakes', content: <ul className="list-disc pl-4 space-y-1">
|
|
238
|
-
<li>Selecting cron but filling interval_seconds instead of a cron schedule.</li>
|
|
239
|
-
<li>Using an invalid cron expression, which the scheduler will not run.</li>
|
|
240
|
-
<li>Leaving Pipeline ID blank when the scheduler expects a pipeline to invoke.</li>
|
|
241
|
-
</ul> },
|
|
242
|
-
]}
|
|
243
|
-
/>
|
|
244
|
-
|
|
245
260
|
<Card><CardContent className="p-6 space-y-6">
|
|
246
261
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
247
262
|
<div className="space-y-4">
|
|
248
263
|
<h3 className="text-sm font-medium text-muted-foreground">Configuration</h3>
|
|
249
264
|
<div className="space-y-2"><Label>Name</Label>{isEditing ? <Input value={formData.name} onChange={e => setFormData({...formData, name: e.target.value})} /> : <div className="text-sm">{timer?.name}</div>}</div>
|
|
250
|
-
<div className="space-y-2"><Label>App
|
|
265
|
+
<div className="space-y-2"><Label>App</Label>{isEditing ? <AppSelect value={formData.app_id} onChange={v => setFormData({...formData, app_id: v})} /> : <div className="text-sm font-mono">{timer?.app_id || '—'}</div>}</div>
|
|
251
266
|
<div className="space-y-2"><Label>Type</Label>{isEditing ? <Select value={formData.timer_type} onValueChange={v => setFormData({...formData, timer_type: v as any})}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent>{TIMER_TYPES.map(t => <SelectItem key={t.value} value={t.value}>{t.label}</SelectItem>)}</SelectContent></Select> : <Badge>{timer?.timer_type}</Badge>}</div>
|
|
252
267
|
<div className="space-y-2"><Label>Active</Label>{isEditing ? <div className="flex items-center gap-2"><Checkbox id="active" checked={formData.is_active} onCheckedChange={c => setFormData({...formData, is_active: c === true})} /><Label htmlFor="active">Enabled</Label></div> : <div className="text-sm">{timer?.is_active ? 'Yes' : 'No'}</div>}</div>
|
|
253
268
|
</div>
|
|
254
269
|
<div className="space-y-4">
|
|
255
270
|
<h3 className="text-sm font-medium text-muted-foreground">Execution</h3>
|
|
256
|
-
<div className="space-y-2"><Label>Pipeline
|
|
271
|
+
<div className="space-y-2"><Label>Pipeline</Label>{isEditing ? <PipelineSelect value={formData.pipeline_id} onChange={v => setFormData({...formData, pipeline_id: v})} /> : <div className="text-sm font-mono">{timer?.pipeline_id || '—'}</div>}</div>
|
|
257
272
|
</div>
|
|
258
273
|
</div>
|
|
259
274
|
<div className="mt-6 space-y-2"><Label>Description</Label>{isEditing ? <Textarea value={formData.description} onChange={e => setFormData({...formData, description: e.target.value})} rows={3} /> : <div className="text-sm">{timer?.description || '—'}</div>}</div>
|
|
@@ -263,11 +278,13 @@ export function TimerDetailPage() {
|
|
|
263
278
|
</div>
|
|
264
279
|
)
|
|
265
280
|
}
|
|
266
|
-
|
|
267
|
-
// CIL[DOC-VECTOR type="context" content="purpose='Renders the timer detail form and handles create/update logic.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx"]
|
|
268
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
269
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
270
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
271
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
272
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
273
281
|
// CIL[END stable_id="~/.framework/src/pages/admin/TimerDetailPage.tsx:TimerDetailPage:component"]
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
|
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/TimersPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/admin/TimersPage.tsx"]
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @module TimersPage
|
|
4
|
+
* @audience both
|
|
5
|
+
* @layer shared-core
|
|
6
|
+
* @stability stable
|
|
7
|
+
*
|
|
8
|
+
* The TimersPage module provides a user interface for managing timers within the admin section of the application. It leverages React hooks for state management and API interactions, allowing users to view, create, and manipulate timer entries.
|
|
9
|
+
* INVARIANT: The module expects a valid API context to function correctly.
|
|
10
|
+
*
|
|
11
|
+
* @seeAlso useApi (provides API interaction capabilities).
|
|
12
|
+
* @seeAlso LoadingSpinner (displays loading state).
|
|
13
|
+
* @seeAlso AdminListPage (displays a list of admin items).
|
|
14
|
+
*
|
|
15
|
+
* @cil-generated
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
10
26
|
|
|
11
27
|
|
|
12
28
|
|
|
@@ -21,22 +37,32 @@ import { Badge } from '../../components/ui/badge'
|
|
|
21
37
|
import { formatDateTime } from '../../lib/utils'
|
|
22
38
|
import { AdminListPage } from '../../components/admin/AdminListPage'
|
|
23
39
|
import { SortableTableHeader } from '../../components/admin/SortableTableHeader'
|
|
24
|
-
|
|
25
|
-
// CIL[DOC-VECTOR type="context" content="purpose='Timers admin page module: imports, types, and React component for managing scheduled and recurring tasks'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
26
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
27
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
28
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
29
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
30
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
31
40
|
// CIL[END stable_id="~/.framework/src/pages/admin/TimersPage.tsx:module_header:module_header"]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
32
58
|
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/TimersPage.tsx:Timer:interface" type="interface" identity="Timer" parent="~/.framework/src/pages/admin/TimersPage.tsx"]
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
59
|
+
/**
|
|
60
|
+
* The Timer interface defines the structure for timer objects used in the application, encapsulating their properties and configuration. It standardizes how timers are represented and managed within the system.
|
|
61
|
+
*
|
|
62
|
+
* @sideEffects none
|
|
63
|
+
* @stability internal
|
|
64
|
+
* @cil-generated
|
|
65
|
+
*/
|
|
40
66
|
interface Timer {
|
|
41
67
|
id: string
|
|
42
68
|
name: string
|
|
@@ -62,22 +88,39 @@ interface Timer {
|
|
|
62
88
|
success_count: number
|
|
63
89
|
failure_count: number
|
|
64
90
|
}
|
|
65
|
-
// CIL[DOC-VECTOR type="context" content="purpose='Define the Timer data shape used by the admin timers page'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
66
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
67
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
68
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
69
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
70
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
71
91
|
// CIL[END stable_id="~/.framework/src/pages/admin/TimersPage.tsx:Timer:interface"]
|
|
72
92
|
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
73
110
|
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/TimersPage.tsx:TimersPage:component" type="component" identity="TimersPage" parent="~/.framework/src/pages/admin/TimersPage.tsx"]
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
111
|
+
/**
|
|
112
|
+
* The TimersPage component manages the display and filtering of timer data in the admin interface. It allows users to search, filter by type and status, and sort timers.
|
|
113
|
+
*
|
|
114
|
+
* @macro Component responsible for rendering and managing timer data in an admin UI.
|
|
115
|
+
* @micro Utilizes a custom API hook to fetch timer data and applies client-side filtering based on user input.
|
|
116
|
+
* @outputSpec JSX.Element - renders the TimersPage component with timer data and UI elements.
|
|
117
|
+
* @throws Error — if the timer fetch fails
|
|
118
|
+
* @sideEffects Fetches timer data from an external API.
|
|
119
|
+
* @stability internal
|
|
120
|
+
* @calls useApi, apiFetch
|
|
121
|
+
* @errorHandling throws an error if the timer fetch fails
|
|
122
|
+
* @cil-generated
|
|
123
|
+
*/
|
|
81
124
|
export function TimersPage() {
|
|
82
125
|
const navigate = useNavigate()
|
|
83
126
|
const [searchTerm, setSearchTerm] = useState('')
|
|
@@ -88,27 +131,10 @@ export function TimersPage() {
|
|
|
88
131
|
|
|
89
132
|
const { data: timers, loading, error, refetch } = useApi<Timer[]>(
|
|
90
133
|
async ({ signal }: { signal?: AbortSignal }) => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (!response.ok) {
|
|
97
|
-
console.error('Response not ok:', response.statusText)
|
|
98
|
-
throw new Error(`Failed to fetch timers: ${response.statusText}`)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const result = await response.json()
|
|
102
|
-
console.log('Raw API result:', result)
|
|
103
|
-
|
|
104
|
-
const timers = result.data || result
|
|
105
|
-
console.log('Timers after processing:', timers)
|
|
106
|
-
|
|
107
|
-
return timers
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error('Error in TimersPage:', error)
|
|
110
|
-
throw error
|
|
111
|
-
}
|
|
134
|
+
const response = await apiFetch('/api/timers?action=list', { signal })
|
|
135
|
+
if (!response.ok) throw new Error('Failed to fetch timers')
|
|
136
|
+
const result = await response.json()
|
|
137
|
+
return result.data || result
|
|
112
138
|
},
|
|
113
139
|
{ immediate: true }
|
|
114
140
|
)
|
|
@@ -391,16 +417,18 @@ export function TimersPage() {
|
|
|
391
417
|
</td>
|
|
392
418
|
</tr>
|
|
393
419
|
))}
|
|
420
|
+
|
|
394
421
|
</tbody>
|
|
395
422
|
</table>
|
|
396
423
|
)}
|
|
397
424
|
</AdminListPage>
|
|
398
425
|
)
|
|
399
426
|
}
|
|
400
|
-
// CIL[DOC-VECTOR type="context" content="purpose='Render the admin timers list page with search, filters, sorting, and execution statistics'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
401
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
402
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
403
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
404
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
405
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
406
427
|
// CIL[END stable_id="~/.framework/src/pages/admin/TimersPage.tsx:TimersPage:component"]
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
|