You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Frontend implementation in frontend-app-authoring. Parent design: #648. Foundation this builds on: #670, #671. Sibling on the same page: #672 (creates the associations this ticket deletes), 5.10c (deletes a whole Competency Criteria Group box — this ticket reuses its activeGroupId-recomputation and placeholder-fallback rendering logic when emptying a box's last association; no GitHub issue yet).
Blocked by:#674 (backend delete-association endpoint, which also cascades an emptied box away server-side); #672 (builds SelectedContentList/SelectedContentItem as "display only, no deselect action" — this ticket adds that action); 5.10c (the activeGroupId-recomputation rendering logic this ticket reuses when a box empties; no GitHub issue yet); #681 (GET groups + criteria endpoint).
Use Case
As a course author who associated the wrong gradeable subsection with a Competency Criteria Group, or no longer wants a subsection counted toward a competency, I want to remove a single association from a Competency Criteria Group box's Selected Content list, so that I can correct the rule's content without deleting or recreating the whole box.
Description
This ticket adds a remove/deselect action to a single Selected Content item, letting a course author remove one subsection's association from a Competency Criteria Group box without affecting that box's other associations.
Current behavior
An associated subsection is currently visible in two places at once: as an item in its Competency Criteria Group box's Selected Content list (SelectedContentItem, built "display only, no deselect action" by #672), and as an already-associated chip on the subsection itself in #670's Browse Courses panel. Neither currently offers a way to remove the association; the only "undo" available is deleting the entire Competency Criteria Group box (5.10c), which removes every other association in it too.
Clicking either X removes the same one association via [Placeholder for BE] Build Update/Delete endpoint to handle a user de-selecting a Competency Criteria association. #674; the Competency Criteria Group box, its logic operator, and its other associations are unaffected. Both surfaces are rendered from the same GET-backed association data, so removing from either X updates both at once: the item disappears from the box's Selected Content list, and the subsection's chip in the Browse Courses panel visibly reverts to unassociated, selectable again.
Frontend ticket. Testable once #672's Selected Content list and #670's Browse Courses panel chip exist, #674 exists, and 5.10c's group-removal rendering logic exists.
Scenario: Remove an association via its Competency Criteria Group box item
Given a gradeable subsection is associated with a Competency Criteria Group box, among other associations in the same box
When I click the remove ("X") affordance on that association's item in the box's Selected Content list
Then that association is removed
And the item no longer appears in the box's Selected Content list
And the subsection's chip in the Browse Courses panel no longer shows it as already-associated, and it is selectable again
And the box's other associations remain unchanged
Scenario: Remove an association via its Browse Courses panel chip
Given a gradeable subsection is associated with a Competency Criteria Group box, among other associations in the same box
When I click the remove ("X") affordance on that subsection's already-associated chip in the Browse Courses panel
Then that association is removed
And the subsection's chip in the Browse Courses panel no longer shows it as already-associated, and it is selectable again
And the item no longer appears in the box's Selected Content list
And the box's other associations remain unchanged
Scenario: Removing the last association empties a box with siblings present
Given a Competency Criteria Group box has exactly one association, and other boxes exist for the competency
When I remove that association, from either its Selected Content item or its Browse Courses panel chip
Then the now-empty box is removed from the page
And the competency's other boxes remain unaffected
Scenario: Removing the last association from the only remaining box
Given a Competency Criteria Group box has exactly one association, and it is the only box for the competency
When I remove that association, from either its Selected Content item or its Browse Courses panel chip
Then the box is removed
And a placeholder box is shown as the new implicit active target
Scenario: Backend rejects the removal
Given a remove request to the backend fails
When I click the remove affordance on an association, from either entry point
Then the association remains visible in the box's Selected Content list, and its Browse Courses panel chip still shows it as associated
And an error is shown, following this feature's existing generic-error-handling pattern
Scenario: A course author without write access cannot remove an association
Given I lack studio write access to the course the association's subsection belongs to
Then neither the Selected Content item's remove affordance nor the Browse Courses panel chip's remove affordance is rendered
On success: the invalidated GET query drops the removed association from both surfaces at once, since both render from the same GET-backed data — the item disappears from the box's Selected Content list, and the subsection's Browse Courses panel chip reverts to unassociated and selectable.
Because [Placeholder for BE] Build Update/Delete endpoint to handle a user de-selecting a Competency Criteria association. #674 cascades an emptied box away server-side, this ticket does not call 5.10c's delete endpoint. It does reuse 5.10c's activeGroupId-recomputation logic (not its API call) once the GET refetch reflects the box's removal, so the active target stays consistent with 5.10c's rules (falls back to a remaining sibling box, or the placeholder if none remain).
Neither remove affordance is rendered at all — not merely disabled — for a course author without studio write access to the course.
Example Resolution Prompt
Implement the frontend consumer of #674 in frontend-app-authoring, extending #671/#672's src/taxonomy/competency-management/criteria-groups/ directory (check whether 5.10c already added data/api.ts/data/apiHooks.ts entries before adding new ones). Add deleteCompetencyCriterion and useDeleteCompetencyCriterion per Technical Details → Data Structures. Add a remove affordance to SelectedContentItem.tsx (from #672) and a matching one to #670's already-associated subsection chip in the Browse Courses panel, both wired to this hook per Technical Details → Logic. Since #674 cascades an emptied box away server-side, do not call 5.10c's delete endpoint; reuse only its activeGroupId-recomputation logic once the GET refetch reflects the box's removal. Hide (not disable) both remove affordances without studio write access. No confirmation dialog (Use Case 10's job). Follow #672's generic error-handling pattern on failure.
Companion ticket whose rendering logic this one reuses: 5.10c (no GitHub issue yet) — owns the activeGroupId-recomputation and placeholder-fallback logic this ticket relies on once a box disappears.
Files to create and modify
Modified files (conditional: check whether #671/#672/5.10c already created these before adding new content)
Add a remove ("X") affordance to an already-associated subsection's chip, wired to the same useDeleteCompetencyCriterion hook; hidden without studio write access.
Frontend implementation in
frontend-app-authoring. Parent design: #648. Foundation this builds on: #670, #671. Sibling on the same page: #672 (creates the associations this ticket deletes), 5.10c (deletes a whole Competency Criteria Group box — this ticket reuses itsactiveGroupId-recomputation and placeholder-fallback rendering logic when emptying a box's last association; no GitHub issue yet).Blocked by: #674 (backend delete-association endpoint, which also cascades an emptied box away server-side); #672 (builds
SelectedContentList/SelectedContentItemas "display only, no deselect action" — this ticket adds that action); 5.10c (theactiveGroupId-recomputation rendering logic this ticket reuses when a box empties; no GitHub issue yet); #681 (GET groups + criteria endpoint).Use Case
As a course author who associated the wrong gradeable subsection with a Competency Criteria Group, or no longer wants a subsection counted toward a competency, I want to remove a single association from a Competency Criteria Group box's Selected Content list, so that I can correct the rule's content without deleting or recreating the whole box.
Description
This ticket adds a remove/deselect action to a single Selected Content item, letting a course author remove one subsection's association from a Competency Criteria Group box without affecting that box's other associations.
Current behavior
An associated subsection is currently visible in two places at once: as an item in its Competency Criteria Group box's Selected Content list (
SelectedContentItem, built "display only, no deselect action" by #672), and as an already-associated chip on the subsection itself in #670's Browse Courses panel. Neither currently offers a way to remove the association; the only "undo" available is deleting the entire Competency Criteria Group box (5.10c), which removes every other association in it too.Requested change
Explicitly out of scope
Acceptance Criteria
Frontend ticket. Testable once #672's Selected Content list and #670's Browse Courses panel chip exist, #674 exists, and 5.10c's group-removal rendering logic exists.
Technical Details
Data Structures
deleteCompetencyCriterion(criterionId)(data/api.ts): DELETE call to [Placeholder for BE] Build Update/Delete endpoint to handle a user de-selecting a Competency Criteria association. #674's endpoint. Contract assumed to mirror [BE] Build endpoint for creating Competency Criteria when a gradeable-subsection association is selected #665's URL shape (e.g.DELETE .../competencies/<tag_id>/criteria/<criterion_id>/). [Placeholder for BE] Build Update/Delete endpoint to handle a user de-selecting a Competency Criteria association. #674 deletes the emptied Competency Criteria Group box server-side, in the same call, when the removed association was that box's last one; the exact response shape is [Placeholder for BE] Build Update/Delete endpoint to handle a user de-selecting a Competency Criteria association. #674's own ticket to define.useDeleteCompetencyCriterion(data/apiHooks.ts): a React Query mutation hook mirroring [FE] Manage & Apply Competencies: select gradeable-subsection associations and target a competency's active group #672'suseCreateCompetencyCriterionconventions; invalidates the GET ([Placeholder for BE] Build GET endpoint to fetch Competency Criteria Groups and Criteria for a competency #681) query on success.Logic
useDeleteCompetencyCriterionhook:SelectedContentItem's new remove affordance (in the Competency Criteria Group box), and the matching remove affordance added to the subsection's already-associated chip in [FE] Build the competency-selection tree, Course Search, and gradeable-subsection browse UI for Competency Criteria Associations #670's Browse Courses panel.activeGroupId-recomputation logic (not its API call) once the GET refetch reflects the box's removal, so the active target stays consistent with 5.10c's rules (falls back to a remaining sibling box, or the placeholder if none remain).Example Resolution Prompt
Context
SelectedContentList/SelectedContentItemas display-only, and the "chip with an X" reference this ticket's affordance follows.activeGroupId-recomputation and placeholder-fallback logic this ticket relies on once a box disappears.Files to create and modify
Modified files (conditional: check whether #671/#672/5.10c already created these before adding new content)
src/taxonomy/competency-management/criteria-groups/SelectedContentItem.tsx(from #672)useDeleteCompetencyCriterion; hidden without studio write access.useDeleteCompetencyCriterionhook; hidden without studio write access.src/taxonomy/competency-management/data/api.tsdeleteCompetencyCriterion.src/taxonomy/competency-management/data/apiHooks.tsuseDeleteCompetencyCriterion.