feat(apollo-vertex): add Solution Tests view + template#782
Draft
frankkluijtmans wants to merge 1 commit into
Draft
feat(apollo-vertex): add Solution Tests view + template#782frankkluijtmans wants to merge 1 commit into
frankkluijtmans wants to merge 1 commit into
Conversation
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Dependency License Review
License distribution
Excluded packages
|
There was a problem hiding this comment.
Pull request overview
Adds a new, domain-neutral Solution Tests page-level template to the Apollo Vertex registry (adapter + config driven, i18n-ready), and enhances the shared DataTable with an expand/collapse-all header toggle when expandable rows are enabled.
Changes:
- Introduces the
registry/solution-testsfeature (types, adapter contract, config, context/provider, view, dialogs, expanded row content, KPI bar, message rendering). - Adds a previewable template + docs page + i18n strings, and a
tsconfigalias for@/components/ui/solution-tests. - Updates the shared data table to render an expand/collapse-all affordance in the
expandcolumn header for expandable tables.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/apollo-vertex/tsconfig.json | Adds path alias for @/components/ui/solution-tests. |
| apps/apollo-vertex/templates/SolutionTestsTemplate.tsx | Client-side demo template wiring provider + config to the view. |
| apps/apollo-vertex/templates/solution-tests/mock-db.ts | In-memory mock data for template preview. |
| apps/apollo-vertex/templates/solution-tests/mock-adapter.ts | Mock adapter implementing the Solution Tests adapter contract. |
| apps/apollo-vertex/registry/solution-tests/index.ts | Public entrypoint exports for the Solution Tests registry feature. |
| apps/apollo-vertex/registry/solution-tests/types.ts | Domain-neutral view models + status enums + user-message types. |
| apps/apollo-vertex/registry/solution-tests/adapter.ts | Adapter interface defining reads/writes for wiring to any backend. |
| apps/apollo-vertex/registry/solution-tests/config.ts | Config shape + defaults for subject-specific labels/columns/behavior. |
| apps/apollo-vertex/registry/solution-tests/context.tsx | Provider/context wiring adapter + resolved config to the component tree. |
| apps/apollo-vertex/registry/solution-tests/use-solution-tests-data.ts | React Query data + mutation orchestration for the view. |
| apps/apollo-vertex/registry/solution-tests/status-maps.ts | Status→badge mappings and per-status class overrides. |
| apps/apollo-vertex/registry/solution-tests/utils.ts | Formatting helpers and small status/result utilities. |
| apps/apollo-vertex/registry/solution-tests/user-messages.ts | Parsing + severity derivation + icon/color/style maps for user messages. |
| apps/apollo-vertex/registry/solution-tests/user-messages-view.tsx | UI components to render message stacks + tooltip icon. |
| apps/apollo-vertex/registry/solution-tests/solution-tests-view.tsx | Main page-level Solution Tests UI (tabs, tables, actions). |
| apps/apollo-vertex/registry/solution-tests/kpi-bar.tsx | KPI cards + score trend chart. |
| apps/apollo-vertex/registry/solution-tests/expanded-agents.tsx | Expanded-row content for baseline agent outputs. |
| apps/apollo-vertex/registry/solution-tests/expanded-run-tests.tsx | Expanded-row content for batch run test runs + run details launcher. |
| apps/apollo-vertex/registry/solution-tests/run-details-dialog.tsx | Run details dialog with per-agent results + baseline actions. |
| apps/apollo-vertex/registry/solution-tests/result-expanded-content.tsx | Per-result expanded content (JSON panels, evaluator results, errors). |
| apps/apollo-vertex/registry/solution-tests/evaluator-results-view.tsx | Evaluator results list rendering with threshold coloring. |
| apps/apollo-vertex/registry/solution-tests/json-viewer-dialog.tsx | Generic dialog for viewing JSON (expected output). |
| apps/apollo-vertex/registry/solution-tests/delete-confirm-dialog.tsx | Confirmation dialog for deleting a test. |
| apps/apollo-vertex/registry/data-table/data-table.tsx | Adds expand/collapse-all toggle in the expand header when expandable. |
| apps/apollo-vertex/registry.json | Registers the new solution-tests registry component with deps. |
| apps/apollo-vertex/locales/en.json | Adds i18n keys used by Solution Tests UI and table toggle labels. |
| apps/apollo-vertex/app/templates/solution-tests/page.mdx | Adds docs page + preview + install/configuration snippet. |
| apps/apollo-vertex/app/templates/_meta.ts | Adds “Solution tests” entry under Templates nav. |
Comment on lines
+30
to
+48
| const { data, isLoading, error } = useQuery({ | ||
| queryKey: QUERY_KEY, | ||
| queryFn: () => fetchData(adapter), | ||
| }); | ||
|
|
||
| const tests = data?.tests ?? []; | ||
| const batchRuns = data?.batchRuns ?? []; | ||
|
|
||
| const hasActiveRuns = batchRuns.some( | ||
| (r) => r.Status === RunStatus.Pending || r.Status === RunStatus.Running, | ||
| ); | ||
|
|
||
| // Poll while runs are active (syncing with an external timer). | ||
| useQuery({ | ||
| queryKey: [...QUERY_KEY, "polling"], | ||
| queryFn: () => fetchData(adapter), | ||
| refetchInterval: config.pollIntervalMs, | ||
| enabled: hasActiveRuns, | ||
| }); |
Comment on lines
+157
to
+166
| async updateBaseline(resultId) { | ||
| await delay(); | ||
| const result = db.results.find((r) => r.Id === resultId); | ||
| if (!result) return { success: false, message: "Result not found" }; | ||
| const job = db.jobs.find((j) => j.ProcessName === result.ProcessName); | ||
| if (job) { | ||
| job.SourceRunResultId = resultId; | ||
| job.ProcessVersion = result.ProcessVersion; | ||
| } | ||
| return { success: true }; |
Comment on lines
+3
to
+4
| import { useTranslation } from "react-i18next"; | ||
| import { Button } from "@/components/ui/button"; |
| @@ -0,0 +1,51 @@ | |||
| "use client"; | |||
|
|
|||
| import { useSolutionTestsConfig } from "./context"; | |||
Comment on lines
+3
to
+4
| import { useState, useCallback } from "react"; | ||
| import { useQuery } from "@tanstack/react-query"; |
| @@ -0,0 +1,211 @@ | |||
| "use client"; | |||
|
|
|||
| import { useState, useCallback } from "react"; | |||
| @@ -0,0 +1,181 @@ | |||
| "use client"; | |||
|
|
|||
| import { useTranslation } from "react-i18next"; | |||
| @@ -0,0 +1,147 @@ | |||
| "use client"; | |||
|
|
|||
| import { useTranslation } from "react-i18next"; | |||
| @@ -0,0 +1,507 @@ | |||
| "use client"; | |||
|
|
|||
| import { useState, useCallback } from "react"; | |||
| @@ -0,0 +1,518 @@ | |||
| "use client"; | |||
|
|
|||
| import { useState } from "react"; | |||
51bd37c to
c907341
Compare
c907341 to
b9242b3
Compare
Comment on lines
+43
to
+47
| useQuery({ | ||
| queryKey: [...QUERY_KEY, "polling"], | ||
| queryFn: () => fetchData(adapter), | ||
| refetchInterval: config.pollIntervalMs, | ||
| enabled: hasActiveRuns, |
Comment on lines
+77
to
+85
| const runAllMutation = useMutation({ | ||
| mutationFn: () => adapter.runTests(), | ||
| onSuccess: (result) => { | ||
| assertOk(result, t("failed_to_run_tests")); | ||
| toast.success(t("all_tests_triggered")); | ||
| invalidate(); | ||
| }, | ||
| onError: onMutationError(), | ||
| }); |
Comment on lines
+87
to
+95
| const runTestMutation = useMutation({ | ||
| mutationFn: (testId: string) => adapter.runTests([testId]), | ||
| onSuccess: (result) => { | ||
| assertOk(result, t("failed_to_run_test")); | ||
| toast.success(t("test_triggered")); | ||
| invalidate(); | ||
| }, | ||
| onError: onMutationError(), | ||
| }); |
Comment on lines
+107
to
+115
| const forceStopBatchMutation = useMutation({ | ||
| mutationFn: (batchId: string) => adapter.forceStopBatch(batchId), | ||
| onSuccess: (result) => { | ||
| assertOk(result, t("failed_to_force_stop_batch")); | ||
| toast.success(t("force_stop_initiated")); | ||
| invalidate(); | ||
| }, | ||
| onError: onMutationError(), | ||
| }); |
Comment on lines
+117
to
+126
| const deleteMutation = useMutation({ | ||
| mutationFn: (testId: string) => adapter.deleteTest(testId), | ||
| onSuccess: (result) => { | ||
| assertOk(result, t("failed_to_delete_test")); | ||
| toast.success(t("test_deleted")); | ||
| invalidate(); | ||
| }, | ||
| onError: onMutationError(), | ||
| onSettled: () => setDeleteConfirmId(null), | ||
| }); |
Comment on lines
+89
to
+101
| const forceStopMutation = useMutation({ | ||
| mutationFn: (runId: string) => adapter.forceStopRun(runId), | ||
| onSuccess: (result) => { | ||
| if (!result.success) { | ||
| throw new Error(result.message ?? t("failed_to_force_stop_run")); | ||
| } | ||
| toast.success(t("force_stop_initiated")); | ||
| onRefresh(); | ||
| }, | ||
| onError: () => { | ||
| toast.error(t("failed_to_force_stop_run")); | ||
| }, | ||
| }); |
b9242b3 to
1a24a5c
Compare
1a24a5c to
c2b61f8
Compare
Comment on lines
+163
to
+172
| async updateBaseline(resultId) { | ||
| await delay(); | ||
| const result = db.results.find((r) => r.Id === resultId); | ||
| if (!result) return { success: false, message: "Result not found" }; | ||
| const job = db.jobs.find((j) => j.ProcessName === result.ProcessName); | ||
| if (job) { | ||
| job.SourceRunResultId = resultId; | ||
| job.ProcessVersion = result.ProcessVersion; | ||
| } | ||
| return { success: true }; |
Comment on lines
+263
to
+270
| <Button | ||
| variant="ghost" | ||
| size="sm" | ||
| disabled={state.isDeleting} | ||
| onClick={() => state.setDeleteConfirmId(test.Id)} | ||
| > | ||
| <Trash2 className="size-3 text-destructive" /> | ||
| </Button> |
Comment on lines
+57
to
+60
| <Tooltip> | ||
| <TooltipTrigger asChild> | ||
| <Icon className={`size-3.5 ${colorClass}`} /> | ||
| </TooltipTrigger> |
Comment on lines
+38
to
+42
| <span | ||
| className={`text-sm font-semibold ${score != null && score >= passThreshold ? "text-green-600" : "text-red-500"}`} | ||
| > | ||
| {scoreStr} | ||
| </span> |
Comment on lines
+111
to
+113
| <span className="text-3xl font-bold"> | ||
| {testsPassing == null ? "-" : `${testsPassing}/${testsTotal}`} | ||
| </span> |
1258a4c to
e3b6b1c
Compare
c2b61f8 to
4e82eec
Compare
e3b6b1c to
b9d2ae2
Compare
4e82eec to
9fa912e
Compare
b9d2ae2 to
cf96c5b
Compare
9fa912e to
3d0c309
Compare
cf96c5b to
7992e7f
Compare
3d0c309 to
b943803
Compare
The UI + registry wiring for the Solution Tests component, stacked on the data layer PR (#790). The view is presentational (dumb): data + handlers arrive via props/render-props from a smart container that calls the collection hooks. The demo renders the dumb view with in-memory mock data (no vs-core), mirroring the GroupMembershipGuard demo.
7992e7f to
fde61bb
Compare
b943803 to
7ed497c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The UI + registry wiring for the Solution Tests component. Stacked on #790 (the data layer) — the view consumes the adapter/context/config/hooks from there, so this targets the
solution-tests-hooksbranch and should merge after #790.Contents:
SolutionTestsView+ KPI bar, tabs, expandable rows, run-details dialog, evaluator results, JSON viewer, delete-confirm, user-message popoverindex.tsbarrel +registry.jsonentry (installable as@uipath/solution-tests) +tsconfigpath aliasSolutionTestsTemplatedemo (in-memory mock) + the Templates docs page and nav entryTesting
pnpm typecheck,pnpm lint,pnpm format:check, andpnpm registry:buildall pass (the registry item bundles all 20 files across both PRs).🤖 Generated with Claude Code