Conversation
… and association with test cases
…d update WorkspaceQueryController for custom tag filtering
…th fetchFilterOptions
…usage counting in TagService, and update workspace-tags.js for improved tag management
…d rename "Tags" to "Type" for clarity
…nced tag management
There was a problem hiding this comment.
Pull request overview
This PR adds first-class “custom tags” (name + color) to the workspace/test-case flows, including CRUD APIs, per-test-case assignment, bulk assignment, UI filtering, and displaying tags in the grid/preview/details views.
Changes:
- Introduces
Tagdomain model + repository/service/controller endpoints for/api/custom-tagswith validation, conflict handling, and usage counts. - Adds APIs + UI for assigning custom tags to a test case and bulk add/remove across selected test cases.
- Updates workspace UI to separate “Type” (existing components/testCaseType tags) from the new custom tags (filter + badges + details section).
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/com/formswim/teststream/workspace/TagApiIntegrationTests.java | Integration coverage for custom-tag CRUD + assignment + bulk assignment endpoints |
| src/main/resources/templates/workspace/_main.html | Renames “Tags” column header to “Type” |
| src/main/resources/templates/workspace/_header.html | Adds custom-tag filter select and adjusts filter grid layout |
| src/main/resources/templates/workspace/_drawer.html | Renames drawer “Tags” label to “Type” |
| src/main/resources/templates/workspace/_bulk-bar.html | Adds “Tag” bulk action button |
| src/main/resources/templates/upload-review.html | Renames “Tags” label to “Type” |
| src/main/resources/templates/test-case-details.html | Adds custom-tags section with badges and “Edit tags” button |
| src/main/resources/static/js/workspace/test-case-details.js | Wires details-page tag popover + DOM badge updates |
| src/main/resources/static/js/workspace/state/workspace-ui-state.js | Persists customTagId in URL/query state |
| src/main/resources/static/js/workspace/page.js | Initializes tag popover controller + bulk tag assignment + filter wiring |
| src/main/resources/static/js/workspace/grid.js | Renders custom-tag badges under title and binds click/keyboard to open tag popover |
| src/main/resources/static/js/workspace/features/workspace-data-controller.js | Loads custom-tag filter options and updates row state after tag changes |
| src/main/resources/static/js/workspace/components/workspace-tags.js | New popover component for assigning/creating/editing/deleting custom tags |
| src/main/resources/static/js/workspace/components/workspace-inline-preview-row.js | Displays custom-tag badges in the inline preview row |
| src/main/resources/static/js/workspace/components/workspace-bulk-tags.js | New bulk tag assignment popover (add/remove + create) |
| src/main/resources/static/js/workspace/api/workspace-page-api.js | Adds /api/custom-tags to filter option fetching |
| src/main/java/com/formswim/teststream/workspace/services/WorkspaceQueryService.java | Initializes customTags in ordered-id query within a read-only transaction |
| src/main/java/com/formswim/teststream/workspace/services/TagService.java | Core tag CRUD + assignment + bulk operations |
| src/main/java/com/formswim/teststream/workspace/services/TagNotFoundException.java | Custom exception for 404 scenarios |
| src/main/java/com/formswim/teststream/workspace/services/TagConflictException.java | Custom exception for 409 scenarios |
| src/main/java/com/formswim/teststream/workspace/services/TagBadRequestException.java | Custom exception for 400 scenarios |
| src/main/java/com/formswim/teststream/workspace/dto/TagResponse.java | Response DTO for tag payloads (incl. usageCount) |
| src/main/java/com/formswim/teststream/workspace/dto/TagRequest.java | Request DTO for create/update |
| src/main/java/com/formswim/teststream/workspace/dto/BulkTagRequest.java | Request DTO for bulk assignment |
| src/main/java/com/formswim/teststream/workspace/controllers/WorkspaceQueryController.java | Adds customTagId query param for /api/testcases |
| src/main/java/com/formswim/teststream/workspace/controllers/WorkspacePageController.java | Adds detailsCustomTags model attribute for details page |
| src/main/java/com/formswim/teststream/workspace/controllers/WorkspaceMetadataController.java | Adds /api/custom-tags + assignment endpoints under metadata controller |
| src/main/java/com/formswim/teststream/shared/domain/TestCaseRepository.java | Extends workspace filter/search JPQL to include custom tag id + custom tag name search |
| src/main/java/com/formswim/teststream/shared/domain/TestCase.java | Adds customTags many-to-many association (lazy + batch size) |
| src/main/java/com/formswim/teststream/shared/domain/TagRepository.java | Tag persistence + native usage counting + join-table cleanup |
| src/main/java/com/formswim/teststream/shared/domain/Tag.java | New Tag entity (team-scoped, name/color, unique constraint) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| loadAllTags().then(() => { | ||
| renderPopover(); | ||
| positionPopover(); | ||
| }); | ||
|
|
||
| setTimeout(() => { document.addEventListener('mousedown', onOutsideClick); }, 0); | ||
| } |
There was a problem hiding this comment.
Same setTimeout(... addEventListener ...) pattern as the tag popover: if close() executes before the timeout fires, a document-level mousedown listener can be added after teardown and never removed. Track/clear the timeout or guard before adding the listener to prevent leaks.
| and lower(coalesce(testStep.stepSummary, '')) like lower(concat('%', :search, '%')) | ||
| ) | ||
| or exists ( | ||
| select 1 from testCase.customTags ct | ||
| where lower(ct.name) like lower(concat('%', :search, '%')) | ||
| ) |
There was a problem hiding this comment.
Custom tag names are now included in the full-text search filter via an exists subquery on testCase.customTags. This is user-facing behavior and should be covered by an integration test (e.g., searching by a custom tag name returns the tagged case).
|
Really like the UI here |
…rvice.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ory.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This pull requests implements a requested custom tag feature.
Includes:
-Tags with customizable names and colors
-Filtering by tag name
-Bulk editing tags
-Warning checks for removing tags in use
-Tags viewable in single edit page and preview
-Counters to check how many times a tag is used