Skip to content

feat(assessment): Rebuild UI with new design - #264

Merged
vprashrex merged 12 commits into
devfrom
chore/assessment-ui-ux-v2
Sep 16, 2026
Merged

vprashrex merged 12 commits into
devfrom
chore/assessment-ui-ux-v2

Conversation

@vprashrex

@vprashrex vprashrex commented Sep 15, 2026 •

Copy link
Copy Markdown
Collaborator

Issue

Closes #263

Summary

  • Rebuilds the Assessment UI to the approved design.
  • Consolidated features into two main parts:
    • Home
      • Two panels: Assessors and Runs.
      • Allows search, version filtering, and run management.
    • Wizard
      • One 4-step flow with three entry modes.
  • Enhanced prompt editor with:
    • Token highlighting and two-stage mentions.
    • Live preview and draggable split pane.
  • Save functionality now enabled only on meaningful changes.
  • Results table includes detailed modal and CSV export.
  • New BFF API routes for batch assessments.

Checklist

Before submitting a pull request, please ensure that you mark these task.

  • Ran npm run dev and npm run build in the repository root and test.
  • If you've fixed a bug or added code that is tested
Original PR description

Issue

Closes #263

Summary

The old Assessment surface split one job across three tabs (Datasets / Config / Result) and a 5-step wizard, with no way to reopen a saved config. This rebuilds it to the approved design in docs/assessment-ui-ux-flow.md and moves it onto the BATCH assessments API.

  • Home — two panels: Assessors (search, version chips, cursor pagination, delete) and Runs (filter by assessor/version, Export, View results). Selecting a version enables Edit and New run.
  • Wizard — one 4-step flow (Submission → Pre-filter → Assessment → Run) with three entry modes: new assessor, edit version, run existing.
  • Prompt editor — two zones per step with token highlighting, two-stage @-mentions (column → Text/Image/PDF), live preview filled with row 1, draggable split pane, per-step model picker.
  • Save — Review & save writes vN+1, enabled only on a real diff against the loaded version; whitespace-only edits don't count.
  • Results — table with a row-detail modal (scores + reasons, feedback, attachments), CSV export, spreadsheet view still one click away; polls until the run is terminal.
  • API — new /api/assessment/batch BFF routes; fetchers split into lib/assessment/api/{assessors,runs,submissions}.ts. configBlob.ts maps the wizard draft to the stored ASSESSMENT config blob, batchResults.ts flattens the nested BATCH result into the row the table reads.

Column mapping is gone — text and attachment columns are derived from the prompt's @Column / <Column> tokens.

Checklist

Before submitting a pull request, please ensure that you mark these task.

  • Ran npm run dev and npm run build in the repository root and test.
  • If you've fixed a bug or added code that is tested

Notes

  • ~6.7k LOC removed: the legacy wizard, the 1–4 config fan-out UI, and the old review sections. A run now targets one assessor version instead of up to four configs.
  • Duplicate detection is no longer configurable in the wizard; the stage still renders on a run.
  • PostProcessingPanel.tsx / PostProcessingStep.tsx are kept but unreachable — the 4-step flow has no place for them. Needs a call on re-hosting or dropping.
  • tsc, npm run lint (0 errors) and npm run build are clean.

Replaces the tabbed Datasets/Config/Result surface with the approved v2 design:
a two-panel Home (assessors | runs) and one 4-step wizard (Submission →
Pre-filter → Assessment → Run) with new / edit-version / run entry modes.

- prompt editor: two zones per step, token highlighting, two-stage @-mentions
  (column → Text/Image/PDF), live preview, split pane, anchored scroll sync
- per-step model picker; Review & save bumps a version, gated on a real diff
- results: row-detail modal, CSV export, polling until terminal status
- moves onto /api/assessment/batch; fetchers split into lib/assessment/api/*,
  configBlob maps the wizard draft to the stored ASSESSMENT config blob
- column mapping dropped — text and attachment columns come from prompt tokens
- retires the legacy wizard and the 1-4 config fan-out (~6.7k LOC removed)

Refs #263
@coderabbitai

coderabbitai Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 151 files, which is 51 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 1efba406-ab5a-4054-b8f8-e654f701a362

📥 Commits

Reviewing files that changed from the base of the PR and between adddd8d and 04c64f8.

📒 Files selected for processing (151)
  • app/(main)/assessment/results/[runId]/page.tsx
  • app/(main)/settings/credentials/page.tsx
  • app/api/assessment/batch/[assessment_id]/route.ts
  • app/api/assessment/batch/route.ts
  • app/components/assessment/AssessmentChildRunCard.tsx
  • app/components/assessment/ChildRunActions.tsx
  • app/components/assessment/ColumnMapperStep.tsx
  • app/components/assessment/ConfigPanel.tsx
  • app/components/assessment/DatasetsTab.tsx
  • app/components/assessment/DownloadDropdown.tsx
  • app/components/assessment/EvaluationsTab.tsx
  • app/components/assessment/OutputSchemaEditor.tsx
  • app/components/assessment/OutputSchemaStep.tsx
  • app/components/assessment/PageLayout.tsx
  • app/components/assessment/PostProcessingStep.tsx
  • app/components/assessment/PrefilterStep.tsx
  • app/components/assessment/PromptAndConfigStep.tsx
  • app/components/assessment/ReviewStep.tsx
  • app/components/assessment/SpreadsheetView.tsx
  • app/components/assessment/Stepper.tsx
  • app/components/assessment/datasets/CreatePanel.tsx
  • app/components/assessment/datasets/DatasetList.tsx
  • app/components/assessment/datasets/SubmissionList.tsx
  • app/components/assessment/editor/EditorStepLayout.tsx
  • app/components/assessment/editor/MentionDropdown.tsx
  • app/components/assessment/editor/PreviewPane.tsx
  • app/components/assessment/editor/PromptZoneCard.tsx
  • app/components/assessment/editor/PromptZoneEditor.tsx
  • app/components/assessment/home/AssessorRow.tsx
  • app/components/assessment/home/AssessorVersionChips.tsx
  • app/components/assessment/home/AssessorVersionList.tsx
  • app/components/assessment/home/AssessorsPanel.tsx
  • app/components/assessment/home/DeleteAssessorDialog.tsx
  • app/components/assessment/home/HomePanel.tsx
  • app/components/assessment/home/HomeView.tsx
  • app/components/assessment/home/RunRow.tsx
  • app/components/assessment/home/RunRowActions.tsx
  • app/components/assessment/home/RunRowMeta.tsx
  • app/components/assessment/home/RunsPanel.tsx
  • app/components/assessment/model/ModelChip.tsx
  • app/components/assessment/model/ModelPicker.tsx
  • app/components/assessment/output-schema/OutputSchemaModal.tsx
  • app/components/assessment/prompt-config/AssessmentConfiguration.tsx
  • app/components/assessment/prompt-config/ConfigCreator.tsx
  • app/components/assessment/prompt-config/PromptEditor.tsx
  • app/components/assessment/prompt-config/PromptPanel.tsx
  • app/components/assessment/prompt-config/ResponseSchema.tsx
  • app/components/assessment/prompt-config/SavedConfigCard.tsx
  • app/components/assessment/prompt-config/SavedConfigs.tsx
  • app/components/assessment/prompt-config/SelectedConfigs.tsx
  • app/components/assessment/prompt-config/SetupProgress.tsx
  • app/components/assessment/prompt-config/SystemPrompt.tsx
  • app/components/assessment/prompt-config/UserPrompt.tsx
  • app/components/assessment/prompt-config/index.ts
  • app/components/assessment/results/ResultsHeader.tsx
  • app/components/assessment/results/ResultsToolbar.tsx
  • app/components/assessment/review/ColumnsReview.tsx
  • app/components/assessment/review/ConfigsReview.tsx
  • app/components/assessment/review/DatasetReview.tsx
  • app/components/assessment/review/ExperimentReview.tsx
  • app/components/assessment/review/InputReview.tsx
  • app/components/assessment/review/PostProcessingReview.tsx
  • app/components/assessment/review/PrefilterReview.tsx
  • app/components/assessment/review/ReviewSection.tsx
  • app/components/assessment/review/SchemaReview.tsx
  • app/components/assessment/review/SubmitReview.tsx
  • app/components/assessment/wizard/AssessmentStep.tsx
  • app/components/assessment/wizard/PrefilterStep.tsx
  • app/components/assessment/wizard/ReviewSaveModal.tsx
  • app/components/assessment/wizard/RunStep.tsx
  • app/components/assessment/wizard/SavedNextModal.tsx
  • app/components/assessment/wizard/SubmissionStep.tsx
  • app/components/assessment/wizard/WizardFooter.tsx
  • app/components/assessment/wizard/WizardStepBody.tsx
  • app/components/assessment/wizard/WizardView.tsx
  • app/components/assessment/wizard/wizardCopy.ts
  • app/components/datasets/UploadDatasetModal.tsx
  • app/components/document/UploadDocumentModal.tsx
  • app/components/icons/common/HomeIcon.tsx
  • app/components/icons/common/ImageIcon.tsx
  • app/components/icons/common/LockClosedIcon.tsx
  • app/components/icons/document/CloudUploadIcon.tsx
  • app/components/icons/index.tsx
  • app/components/settings/credentials/CredentialForm.tsx
  • app/components/settings/credentials/CredentialFormPanel.tsx
  • app/components/settings/onboarding/OnboardingCredentials.tsx
  • app/components/ui/CursorPager.tsx
  • app/components/ui/Field.tsx
  • app/components/ui/Pager.tsx
  • app/components/ui/Select.tsx
  • app/components/ui/SplitPane.tsx
  • app/components/ui/index.ts
  • app/hooks/index.ts
  • app/hooks/useAssessmentData.ts
  • app/hooks/useAssessmentDatasetsTab.ts
  • app/hooks/useAssessmentDownload.ts
  • app/hooks/useAssessmentFeatureGuard.ts
  • app/hooks/useAssessmentHome.ts
  • app/hooks/useAssessmentHomeData.ts
  • app/hooks/useAssessmentResults.ts
  • app/hooks/useAssessmentWizard.ts
  • app/hooks/useAssessmentWorkflow.ts
  • app/hooks/useAssessorSave.ts
  • app/hooks/useAssessorVersionContext.ts
  • app/hooks/useLatestConfigModels.ts
  • app/hooks/usePromptAndConfigStep.ts
  • app/hooks/usePromptMentions.ts
  • app/hooks/usePromptPlaceholderEditor.ts
  • app/hooks/useRunNameDraft.ts
  • app/hooks/useRunResults.ts
  • app/hooks/useRunSubmit.ts
  • app/hooks/useSubmissionForm.ts
  • app/hooks/useSubmissionList.ts
  • app/hooks/useSubmissionStep.ts
  • app/hooks/useSyncedScroll.ts
  • app/hooks/useVersionSaveFlow.ts
  • app/hooks/useWizardDraft.ts
  • app/lib/assessment/api/assessors.ts
  • app/lib/assessment/api/runs.ts
  • app/lib/assessment/api/submissions.ts
  • app/lib/assessment/apiSource.ts
  • app/lib/assessment/batchResults.ts
  • app/lib/assessment/configBlob.ts
  • app/lib/assessment/constants.ts
  • app/lib/assessment/draft.ts
  • app/lib/assessment/home.ts
  • app/lib/assessment/promptCopy.ts
  • app/lib/assessment/promptTokens.ts
  • app/lib/assessment/resultRow.ts
  • app/lib/assessment/results.ts
  • app/lib/assessment/scrollMap.ts
  • app/lib/assessment/wizard.ts
  • app/lib/data/assessmentModels.ts
  • app/lib/modelSchema.ts
  • app/lib/types/assessment/batch.ts
  • app/lib/types/assessment/config.ts
  • app/lib/types/assessment/core.ts
  • app/lib/types/assessment/dataSource.ts
  • app/lib/types/assessment/dataset.ts
  • app/lib/types/assessment/home.ts
  • app/lib/types/assessment/index.ts
  • app/lib/types/assessment/prompt.ts
  • app/lib/types/assessment/results.ts
  • app/lib/types/assessment/submission.ts
  • app/lib/types/assessment/wizard.ts
  • app/lib/types/assessment/workflow.ts
  • app/lib/types/configs.ts
  • app/lib/types/credentials.ts
  • app/lib/utils.ts
  • app/lib/utils/assessment.ts
  • app/lib/utils/assessmentFetcher.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot changed the title feat(assessment): rebuild module on BATCH API (UI/UX v2) feat(assessment): Rebuild UI with new design Sep 15, 2026
@vprashrex vprashrex self-assigned this Sep 15, 2026
@vprashrex vprashrex added the enhancement New feature or request label Sep 15, 2026
CI runs `npm run format:check` before linting; ten files in the previous
commit were not Prettier-clean. Formatting only, no behaviour change.
Props interfaces and hook result types were declared inline across the
assessment module, several of them imported by a second file. Moves them to
the domain type files so each shape has one home:

- prompt.ts: editor zones, mentions, preview, model picker
- home.ts: panels, rows, version chips, delete target
- wizard.ts: steps, footer, modals, stepper
- submission.ts: list, create panel, submission hook results
- results.ts: toolbar, table, row modal, spreadsheet, view mode

Also drops the props types the retired legacy components left behind
(ColumnMapperStepProps, PromptPanelProps, ConfigPanelProps and friends),
the unused imports the moves exposed, and trims an over-long comment.
Scoped to files this branch already touches.

Refs #263
@vprashrex
vprashrex requested a review from Ayush8923 September 15, 2026 09:13
Fallout the prop-type centralization exposed:

- workflow.ts: remove AssessmentFormState, PromptPanelProps,
  ResponseSchemaProps and ConfigPanelProps — props for the components
  retired when the wizard shell replaced ConfigPanel/SubViewBar.
  Nothing imports them (99 -> 28 LOC). PageLayoutProps and
  PostProcessing{Step,Panel}Props are still referenced and stay.
- Stepper.tsx, HomePanel.tsx: remove `import {} from "react"`, left
  empty when their last named import moved to a type file.

Scoped to files this branch already touches.

Refs #263
@vprashrex
vprashrex changed the base branch from main to dev September 15, 2026 09:21
@Prajna1999
Prajna1999 self-requested a review September 15, 2026 11:14
@vprashrex
vprashrex requested review from Prajna1999 and removed request for Prajna1999 September 15, 2026 11:15
The runs list is ordered by inserted_at (newest first, done in the
API), but the row meta rendered updated_at. A run created yesterday
and touched by a status transition a minute ago read "2m ago" while
sitting below newer rows, so the list looked unsorted.

Show "Started <inserted_at>" instead, matching the API's sort key.
Ordering stays entirely server-side; no client-side sort added.

AssessorRow keeps updated_at — a version bump is genuinely an update
there, and that list is ordered separately.

Refs #263
Run step (step 4):

- Add a Preview button beside the submission select, showing at most
  10 rows (RUN_PREVIEW_ROW_LIMIT) in the existing DataViewModal via
  the cached preview loader step 1 already uses. Passes an explicit
  subtitle so the modal reports "First 10 of N rows" rather than
  claiming the set only has 10. Step 1's View is unchanged.
- Block Run while a file sits in the inline upload form uncreated.
  Previously the run went ahead against the previously selected set
  and the upload was silently dropped. The footer now disables the
  primary and explains why.
- Collapsing "Upload new" resets the form, and CreatePanel takes an
  optional onCancel, so a pending file can't linger behind a closed
  panel and block Run with no visible cause.

wizardFooterState now takes a params object; four positional
arguments including two booleans had become unreadable.

Refs #263
import ResultRowModal from "@/app/components/assessment/results/ResultRowModal";
import ResultsTable from "@/app/components/assessment/results/ResultsTable";
import ResultsToolbar from "@/app/components/assessment/results/ResultsToolbar";
import { useRunResults } from "@/app/hooks/useRunResults";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import this inside the index.js and then import from that file. and use like this:

import { useRunResults } from "@/app/hooks";

instead of the import every file.

Comment on lines +7 to +9
import ResultRowModal from "@/app/components/assessment/results/ResultRowModal";
import ResultsTable from "@/app/components/assessment/results/ResultsTable";
import ResultsToolbar from "@/app/components/assessment/results/ResultsToolbar";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment for this.

cancelled = true;
};
}, [apiKey, isAuthenticated, isHydrated, runId, toast]);
const assessmentId = params?.runId ?? "";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is optional channing needed here?

Comment thread app/api/assessment/batch/route.ts Outdated

const BATCH_ENDPOINT = "/api/v1/assessments";

/** GET /api/assessment/batch — list assessments, optionally by config + version. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** GET /api/assessment/batch — list assessments, optionally by config + version. */

Comment thread app/api/assessment/batch/route.ts Outdated
}
}

/** POST /api/assessment/batch — submit a batch assessment run. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** POST /api/assessment/batch — submit a batch assessment run. */

p: "mb-2.5 text-sm leading-7 text-text-primary",
};

/** Read-only mirror of the prompt the model will see, filled with row 1. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Read-only mirror of the prompt the model will see, filled with row 1. */

return `/assessment/results/${assessment.assessment_id}?${query}`;
}

/** Export / View results, per the run's status. Retry has no BATCH endpoint yet. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not need these type of the comment in the every component and if you want to add then add the high lebal simple what this component do.

return (
<>
<p className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-text-secondary">
{/* Creation time, not updated_at — the API orders this list by inserted_at. */}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{/* Creation time, not updated_at — the API orders this list by inserted_at. */}

Comment thread app/lib/types/assessment/batch.ts Outdated
@@ -0,0 +1,96 @@
// BATCH assessment API shapes. Field names mirror the backend.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove these all unwanted comments.

Comment thread app/lib/types/assessment/dataSource.ts Outdated
@@ -0,0 +1,113 @@
// Assessment types: the data-source contract shared by the mock fixture and the API layer.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove these too from all the types files.

Review comments from #264:

- Export the assessment hooks from app/hooks/index.ts and import them
  from "@/app/hooks" rather than reaching past the barrel. Hook-to-hook
  imports keep their deep paths so the barrel doesn't import itself.
- Drop optional chaining on useParams in the results page. Next types
  it as non-nullable, so the fallback was dead code.
- Remove comments from the assessment type files, the components and
  the batch route handlers.

Algorithm notes under lib/assessment and hooks are kept: they explain
non-obvious behaviour rather than restating the code.

Refs #263
emptyDraft() starts a new assessor with prefilterEnabled false, so the
optional step is opt-in rather than opt-out.

Only the new-assessor flow changes. draftFromVersion still derives the
toggle from the saved blob, so reopening a version that has a
pre-filter configured still opens with it on.

Refs #263
@vprashrex
vprashrex force-pushed the chore/assessment-ui-ux-v2 branch from a1d8096 to e26ac70 Compare September 16, 2026 05:51
@vprashrex
vprashrex requested a review from Ayush8923 September 16, 2026 05:59
The results page showed two identical headers in spreadsheet mode:
ResultsToolbar rendered one, and SpreadsheetView rendered its own title,
subtitle and a second Download CSV. SpreadsheetView predates the toolbar
and owned its header as a standalone panel.

Remove the Table view rather than reconciling two headers:

- Delete ResultsTable and ResultRowModal, the view switch and
  ResultsViewMode. The table row click was the modal's only trigger.
- Delete SpreadsheetView's header block. Its Download CSV exported the
  Univer snapshot, which only holds the capped preview rows; the
  toolbar's re-derives from the full results, so that one is correct.
- Fix SpreadsheetView's h-screen nested inside the page's own h-screen
  column, which gave it double height.

Also remove Export from the run cards, which retires the chain feeding
it: the isExporting/onExport props through RunRow and RunsPanel, and
exportRun/exportingId in useAssessmentHomeData and useAssessmentHome.
View results stays on the card; Download CSV lives on the results page.

Refs #263
@vprashrex
vprashrex merged commit b256ae3 into dev Sep 16, 2026
2 checks passed
@vprashrex
vprashrex deleted the chore/assessment-ui-ux-v2 branch September 16, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request ready-for-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Assessment: Rebuild UI/UX design

3 participants