Skip to content

Restructure project table - #406

Merged
brucetony merged 10 commits into
developfrom
405-disable-project-approval-toggle
Aug 4, 2026
Merged

Restructure project table#406
brucetony merged 10 commits into
developfrom
405-disable-project-approval-toggle

Conversation

@brucetony

@brucetony brucetony commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Introduced a projects table with search, filtering, sorting, expandable rows, analysis summaries, execution statuses, and data-store indicators.
    • Added project status labels, progress meters, legends, timestamps, and truncation warnings.
    • Added reusable data-store badges for required, optional, and creation states.
  • Bug Fixes

    • Improved handling of missing data stores and incomplete analysis information.
  • Tests

    • Added comprehensive coverage for project displays, statuses, filtering, data stores, pagination, and error states.

@brucetony brucetony linked an issue Aug 4, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The projects page now renders project analysis summaries with derived statuses, filters, meters, data-store indicators, refresh handling, and truncation warnings. Shared data-store actions replace duplicated markup. Obsolete proposal and approval components and tests were removed.

Changes

Project status table

Layer / File(s) Summary
Project analysis aggregation and status model
app/utils/summarise-project-analyses.ts, test/utils/summarise-project-analyses.test.ts
Adds project-level analysis summaries, execution-state buckets, data-store flags, status precedence, severity, ranks, and filter options with test coverage.
Project analysis data loading
app/composables/useProjectAnalysisSummary.ts, test/composables/useProjectAnalysisSummary.test.ts
Adds paginated analysis-node loading, data-store route lookup, execution-status merging, truncation tracking, fallback summaries, and refresh tests.
Shared data-store indicator integration
app/components/shared/DataStoreBadge.vue, app/components/analysis/AnalysesTable.vue, test/components/shared/DataStoreBadge.spec.ts
Adds the reusable data-store badge and uses it in AnalysesTable.vue, including nullable project IDs and creation actions.
Projects table page integration
app/components/projects/ProjectsTable.vue, app/pages/projects.vue, test/components/projects/ProjectsTable.spec.ts, test/components/projects/constants.ts
Adds the projects table and replaces the proposal table on the projects page. Obsolete proposal and approval components and their tests were removed.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProjectsTable
  participant useProjectAnalysisSummary
  participant HubAPI
  participant KongRoutes
  participant PodOrchestrator
  participant summariseProjectAnalyses
  ProjectsTable->>useProjectAnalysisSummary: refresh()
  useProjectAnalysisSummary->>HubAPI: fetch analysis nodes
  useProjectAnalysisSummary->>KongRoutes: fetch data-store routes
  useProjectAnalysisSummary->>PodOrchestrator: fetch execution statuses
  useProjectAnalysisSummary->>summariseProjectAnalyses: merge and summarize data
  summariseProjectAnalyses-->>ProjectsTable: project summaries and statuses
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: replacing and restructuring the project table implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 405-disable-project-approval-toggle

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (5)
app/components/projects/ProjectsTable.vue (3)

332-400: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Scope the style block.

The <style> block is global, so .status-meter, .project-status, and .status-legend* leak into every page. All selectors target elements owned by this component, so scoped works without change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/projects/ProjectsTable.vue` around lines 332 - 400, Add the
scoped attribute to the style block in ProjectsTable.vue so the
component-specific selectors, including .status-meter, .project-status, and
.status-legend*, apply only within ProjectsTable. Leave the existing CSS
declarations unchanged.

18-22: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unused expander state and rename proposals.

expandRowEntries stays empty, so the expander column at line 185 never renders and expandedRows is never populated. The component renders projects, so proposals is a stale name carried over from ProjectProposalTable. Drop the expander wiring or populate it, and rename the row state to projects.

Also applies to: 169-185

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/projects/ProjectsTable.vue` around lines 18 - 22, In
ProjectsTable, rename the row data state `proposals` to `projects` and update
all references to match the component’s project data. Remove the unused
`expandedRows` state and `expandRowEntries`/expander-column wiring, or populate
it consistently if expansion is required; keep the rendered table behavior
aligned with the actual project rows.

85-93: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Handle refreshSummaries failures separately.

The analysis-summary fetches are already masked as undefined, but refreshSummaries still throws if summariseProjectAnalyses or deriveProjectStatus runs on unexpected input. The finally makes loading false without an error message. Catch refreshSummaries() at the top-level render and in onTableRefresh, keep the project rows rendered, and display the summary-load failure so stale summaries do not block refresh.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/projects/ProjectsTable.vue` around lines 85 - 93, Handle
refreshSummaries failures separately in the top-level render flow and
onTableRefresh: catch errors from summariseProjectAnalyses or
deriveProjectStatus, display the summary-load failure, and continue rendering
the existing project rows instead of propagating the exception. Preserve the
loading cleanup and ensure table refresh still completes even when summary
loading fails.
test/components/projects/ProjectsTable.spec.ts (1)

79-85: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unused toast setup.

ProjectsTable.vue does not call useToast, so the mockToast declaration and vi.mocked(useToast).mockReturnValue(mockToast) line add only unused test setup.

♻️ Proposed change
-import { useToast } from "primevue/usetoast";
 import { computed, defineComponent } from "vue";
@@
 describe("ProjectsTable.vue", () => {
-  let mockToast;
   let ProjectsTableTestComponent;
 
   beforeEach(() => {
     vi.restoreAllMocks(); // Reset mocks before each test
-    vi.mocked(useToast).mockReturnValue(mockToast);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/components/projects/ProjectsTable.spec.ts` around lines 79 - 85, Remove
the unused mockToast declaration and the
vi.mocked(useToast).mockReturnValue(mockToast) setup from the ProjectsTable.vue
test’s beforeEach block, leaving the remaining mock-reset behavior unchanged.
test/components/projects/constants.ts (1)

53-66: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Clone the shared proposal entry in fakeTwoProposalsResp.

fakeTwoProposalsResp[0] reuses fakeProposalsResp[0], and the second entry copies its node by reference. ProjectsTable.parseData adds project_name, summary, and project_status to the formatted rows, so this fixture can carry test-local state into later expectations. Clone the source entry for both rows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/components/projects/constants.ts` around lines 53 - 66, Update
fakeTwoProposalsResp to clone fakeProposalsResp[0] for its first entry as well
as the customized second entry, ensuring both rows have independent node
objects. Preserve the second proposal’s existing project-specific fields while
preventing ProjectsTable.parseData mutations from leaking into shared fixture
state.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/components/projects/ProjectsTable.vue`:
- Around line 192-196: Update the tooltip binding in the ProjectsTable body
template to safely access the optional project relation, matching the
optional-chaining pattern already used for this field elsewhere in the
component. Preserve the existing project name rendering.

In `@app/components/shared/DataStoreBadge.vue`:
- Around line 32-41: Update the DataStoreBadge button rendering around the
createDataStore click handler so the optional state (required false) uses a
non-disabled wrapper or other non-interactive element that still exposes
missingTooltip to v-tooltip.top, while preserving the button and click behavior
for required stores. Ensure the “Data store missing, but not required” tooltip
can trigger without allowing creation from the optional state.

In `@app/composables/useProjectAnalysisSummary.ts`:
- Around line 42-55: Keep upstream failures distinct from valid empty responses
throughout useProjectAnalysisSummary and refreshSummaries: in
app/composables/useProjectAnalysisSummary.ts lines 42-55, mark failed
analysis-page requests as incomplete or unavailable; lines 64-73, preserve Kong
unavailability separately from an empty data-store Set; lines 76-103, preserve
unavailable pod-status data separately from missing analysis entries; and lines
111-150, expose these availability states so consumers do not publish normal
statuses from incomplete data. Update
test/composables/useProjectAnalysisSummary.test.ts lines 42-50, 90-100, and
124-132 to assert each unavailable state, with no direct change required beyond
validating the corresponding implementation behavior.
- Around line 25-28: Add PodStatus.Stopped to FINISHED_STATUSES so
mergeExecutionStatuses preserves a Hub stopped status when /po/status has no
matching analysis entry. Extend the no-entry coverage in the
useProjectAnalysisSummary test to verify stopped analyses remain counted and
summarized as Stopped.

---

Nitpick comments:
In `@app/components/projects/ProjectsTable.vue`:
- Around line 332-400: Add the scoped attribute to the style block in
ProjectsTable.vue so the component-specific selectors, including .status-meter,
.project-status, and .status-legend*, apply only within ProjectsTable. Leave the
existing CSS declarations unchanged.
- Around line 18-22: In ProjectsTable, rename the row data state `proposals` to
`projects` and update all references to match the component’s project data.
Remove the unused `expandedRows` state and `expandRowEntries`/expander-column
wiring, or populate it consistently if expansion is required; keep the rendered
table behavior aligned with the actual project rows.
- Around line 85-93: Handle refreshSummaries failures separately in the
top-level render flow and onTableRefresh: catch errors from
summariseProjectAnalyses or deriveProjectStatus, display the summary-load
failure, and continue rendering the existing project rows instead of propagating
the exception. Preserve the loading cleanup and ensure table refresh still
completes even when summary loading fails.

In `@test/components/projects/constants.ts`:
- Around line 53-66: Update fakeTwoProposalsResp to clone fakeProposalsResp[0]
for its first entry as well as the customized second entry, ensuring both rows
have independent node objects. Preserve the second proposal’s existing
project-specific fields while preventing ProjectsTable.parseData mutations from
leaking into shared fixture state.

In `@test/components/projects/ProjectsTable.spec.ts`:
- Around line 79-85: Remove the unused mockToast declaration and the
vi.mocked(useToast).mockReturnValue(mockToast) setup from the ProjectsTable.vue
test’s beforeEach block, leaving the remaining mock-reset behavior unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ec9bff73-fec1-4581-8cff-39b447fae19d

📥 Commits

Reviewing files that changed from the base of the PR and between 2c2df0e and 5bf111d.

📒 Files selected for processing (15)
  • app/components/analysis/AnalysesTable.vue
  • app/components/projects/ProjectProposalTable.vue
  • app/components/projects/ProjectsTable.vue
  • app/components/shared/DataStoreBadge.vue
  • app/components/table/ApproveRejectToggle.vue
  • app/composables/useProjectAnalysisSummary.ts
  • app/pages/projects.vue
  • app/utils/summarise-project-analyses.ts
  • test/components/projects/ProjectProposalTable.spec.ts
  • test/components/projects/ProjectsTable.spec.ts
  • test/components/projects/constants.ts
  • test/components/shared/DataStoreBadge.spec.ts
  • test/components/table/ApproveRejectToggle.spec.ts
  • test/composables/useProjectAnalysisSummary.test.ts
  • test/utils/summarise-project-analyses.test.ts
💤 Files with no reviewable changes (4)
  • app/components/projects/ProjectProposalTable.vue
  • app/components/table/ApproveRejectToggle.vue
  • test/components/projects/ProjectProposalTable.spec.ts
  • test/components/table/ApproveRejectToggle.spec.ts

Comment thread app/components/projects/ProjectsTable.vue
Comment thread app/components/shared/DataStoreBadge.vue
Comment thread app/composables/useProjectAnalysisSummary.ts
Comment thread app/composables/useProjectAnalysisSummary.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/composables/useProjectAnalysisSummary.ts`:
- Around line 74-86: Update the route-fetching logic in the project analysis
summary to follow ListRoutes.offset until no next page remains, aggregating
project IDs from every response and preserving unavailable handling for request
failures. Ensure summaryFor receives the complete projectIds set, and add
coverage for a project route returned on a subsequent page.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f4974790-b458-422c-939a-0c13e380a065

📥 Commits

Reviewing files that changed from the base of the PR and between 5bf111d and ecc5cc1.

📒 Files selected for processing (5)
  • app/components/projects/ProjectsTable.vue
  • app/components/shared/DataStoreBadge.vue
  • app/composables/useProjectAnalysisSummary.ts
  • test/components/shared/DataStoreBadge.spec.ts
  • test/composables/useProjectAnalysisSummary.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/components/shared/DataStoreBadge.spec.ts
  • app/components/shared/DataStoreBadge.vue
  • test/composables/useProjectAnalysisSummary.test.ts
  • app/components/projects/ProjectsTable.vue

Comment thread app/composables/useProjectAnalysisSummary.ts
@brucetony
brucetony merged commit 26d85bb into develop Aug 4, 2026
3 checks passed
@brucetony
brucetony deleted the 405-disable-project-approval-toggle branch August 4, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Disable project approval toggle

1 participant