Repository navigation
Conversation
- Association rows now use the Figma unlink icon with “Detach from learning objective” tooltip and distinct accessible naming. - Detaching preserves the sub-objective, course references, and other LO associations. - Added persisted objective_type so final-detached sub-objectives remain distinguishable and recoverable. - Add Existing now supports Status → Unassociated, searchable results, re-adding, and permanent deletion. - Permanent deletion is server-guarded against LO associations and page/activity/selection references. - Added explicit confirmation copy, success/error announcements, and dialog focus restoration. - Top-level delete tooltip is now exactly “Delete Learning Objective”.
AI Review — performanceAvoid unconditional sorting of objective mappingsfile: lib/oli/publishing.ex Recursive JSONPath lookup creates a publication-wide scanfile: lib/oli/publishing.ex |
AI Review — securityNo issues found |
AI Review — uiAdd action allows duplicate submissionsfile: lib/oli_web/live/workspaces/course_author/objectives/select_existing_sub_modal.ex Deleting state exposes the wrong tooltipfile: lib/oli_web/live/workspaces/course_author/objectives/listing.ex |
AI Review — elixirCall the SQL adapter for the isolation statementfile: lib/oli/authoring/editing/objective_editor.ex Declare the class attribute before the componentfile: lib/oli_web/icons.ex |
AI Review — typescriptDocument listener scales with every tooltipfile: assets/src/hooks/global_tooltip.ts |
|
Elixir review follow-up: the objective-type migration is present at |
|
TypeScript review follow-up: no code change was needed for the reported modal focus-listener ordering. In the current PR, |
darrensiegel
left a comment
There was a problem hiding this comment.
There is no need to add a new Revision field for objective_type (:objective or :sub_objective) here to address this ticket.
All that needs to be done in the ObjectiveLive view is an upfront traversal of the graph of objectives. For each objective, store a list of parents. When a child being "removed" has more than one parents we simply unlink. When a child being removed has only one parent, we show a warning message indicating that it is about to be deleted.
|
Hi @darrensiegel the field was added in order to fulfill the following acceptance criteria:
When the final association is removed both an unassociated subobjective and a top level objective have zero parents, so using the graph alone I don't think i can distinguish them to populate the |
|
@manelli I still do not believe that a new Revision field is necessary to accomplish this. All we are requesting is that when we are removing the ONLY instance of a sub objective, we delete that sub objective. That tracking can be strictly accomplished by maintaining an in-memory "graph" of the learning objectives. "A detached sub-objective remains available in the Add Existing modal and can be associated with a learning objective again." This is an INCORRECT acceptance criteria. We cannot - and do not want - to support detaching sub objectives and later reattaching them. |
|
Hi @darrensiegel, updated this to follow your clarification. The new Revision field and its migration have been removed. ObjectivesLive now builds a parent map from the objective graph: shared sub-objectives use the unlink action, while removing the final association requires an explicit permanent-deletion confirmation. Final-association deletion is blocked if the sub-objective is tagged to course content, and the server rechecks both references and parent associations when confirmation is submitted. Shared unlinking preserves the child and its other associations. I also removed the Unassociated workflow from Add Existing and updated the PR description to explicitly document which original ticket criteria this clarification supersedes. |
Summary
Clarifies sub-objective removal by deriving parent associations from the objective graph, without adding a
Revision.objective_typefield or migration.Scope clarification
Per Darren’s review clarification, removing the final association deletes the sub-objective after confirmation; detached, unassociated sub-objectives are not retained for later reattachment.
This intentionally supersedes MER-5786’s original criteria for preserving the final detached sub-objective, offering an Unassociated status filter, and restricting permanent deletion to the unassociated list. The Unassociated workflow and its delete action have been removed. The ticket still contains the original criteria; this PR documents the agreed implementation scope.