-
Notifications
You must be signed in to change notification settings - Fork 733
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: Side panel closing confirmation & logic in child component #11862
Merged
nucleogenesis
merged 17 commits into
learningequality:develop
from
nucleogenesis:fix--side-panel-closure
Feb 27, 2024
+183
−154
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
c27bd8f
fix: side panel closing confirmation & logic in child component
nucleogenesis ac67c8d
simplify comparison; recalling that the pools are now lists of IDs no…
nucleogenesis e542bce
remove unused property
nucleogenesis 5271380
flip the boolean checking if resources have changed
nucleogenesis edb1257
add confirmation modal to sectioneditor, always set panelClosing=fals…
nucleogenesis 468cb26
save channels when they're loaded, then set the content list to it wh…
nucleogenesis 86ada9c
$route watcher params better match router terminology
nucleogenesis 6216dc5
leverage vue-router nested routes for simplified side panel routing
nucleogenesis 87761d3
use route names for less brittle routing
nucleogenesis 24ad9bb
fix: side panel closing confirmation & logic in child component
nucleogenesis 60a3f69
simplify comparison; recalling that the pools are now lists of IDs no…
nucleogenesis 99e045c
flip the boolean checking if resources have changed
nucleogenesis 6e0ae16
add confirmation modal to sectioneditor, always set panelClosing=fals…
nucleogenesis 124a670
leverage vue-router nested routes for simplified side panel routing
nucleogenesis 4b3b75e
fix post-rebase
nucleogenesis a5eba12
add comment explaining use of snake_case in js context
nucleogenesis dae568b
lint
nucleogenesis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,13 +105,18 @@ | |
style="float: right;" | ||
:text="coreString('saveChangesAction')" | ||
:primary="true" | ||
:disabled="!hasTopicId() && !showBookmarks" | ||
:disabled="!workingPoolHasChanged" | ||
@click="saveSelectedResource" | ||
/> | ||
</KGridItem> | ||
</KGrid> | ||
</div> | ||
</div> | ||
<ConfirmCancellationModal | ||
v-if="showConfirmationModal" | ||
@cancel="handleCancelClose" | ||
@continue="handleConfirmClose" | ||
/> | ||
</div> | ||
|
||
</template> | ||
|
@@ -133,6 +138,7 @@ | |
import { injectQuizCreation } from '../../../composables/useQuizCreation'; | ||
import LessonsSearchBox from '../LessonResourceSelectionPage/SearchTools/LessonsSearchBox.vue'; | ||
import ContentCardList from './../LessonResourceSelectionPage/ContentCardList.vue'; | ||
import ConfirmCancellationModal from './ConfirmCancellationModal.vue'; | ||
import ResourceSelectionBreadcrumbs from './../LessonResourceSelectionPage/SearchTools/ResourceSelectionBreadcrumbs.vue'; | ||
|
||
export default { | ||
|
@@ -142,9 +148,10 @@ | |
BookmarkIcon, | ||
LessonsSearchBox, | ||
ResourceSelectionBreadcrumbs, | ||
ConfirmCancellationModal, | ||
}, | ||
mixins: [commonCoreStrings], | ||
setup() { | ||
setup(_, context) { | ||
const store = getCurrentInstance().proxy.$store; | ||
const route = computed(() => store.state.route); | ||
const topicId = computed(() => route.value.params.topic_id); | ||
|
@@ -154,6 +161,9 @@ | |
const showBookmarks = computed(() => route.value.query.showBookmarks); | ||
const searchQuery = computed(() => route.value.query.search); | ||
const { updateSection, activeResourcePool, selectAllQuestions } = injectQuizCreation(); | ||
const showConfirmationModal = ref(false); | ||
|
||
const prevRoute = ref({ name: PageNames.EXAM_CREATION_ROOT }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be set to the SectionEditor during |
||
|
||
const { | ||
sectionSettings$, | ||
|
@@ -377,6 +387,7 @@ | |
// call this annotateTopicsWithDescendantCounts method to ensure that the channels are | ||
// annotated with their num_assessments and those without assessments are filtered out | ||
annotateTopicsWithDescendantCounts(resources.value.map(c => c.id)).then(() => { | ||
channels.value = resources.value; | ||
_loading.value = false; | ||
}); | ||
}); | ||
|
@@ -408,6 +419,10 @@ | |
return searchResults.value; | ||
} | ||
|
||
if (!topicId.value) { | ||
return channels.value; | ||
} | ||
|
||
return resources.value; | ||
}); | ||
|
||
|
@@ -432,16 +447,36 @@ | |
return fetchMoreQuizResources(); | ||
} | ||
|
||
function handleCancelClose() { | ||
showConfirmationModal.value = false; | ||
} | ||
|
||
function handleConfirmClose() { | ||
context.emit('closePanel'); | ||
} | ||
|
||
const workingPoolHasChanged = computed(() => { | ||
return ( | ||
workingResourcePool.value.length != activeResourcePool.value.length || | ||
!isEqual(workingResourcePool.value.sort(), activeResourcePool.value.sort()) | ||
); | ||
}); | ||
|
||
return { | ||
selectAllChecked, | ||
selectAllIndeterminate, | ||
showSelectAll, | ||
handleSelectAll, | ||
toggleSelected, | ||
prevRoute, | ||
workingPoolHasChanged, | ||
handleConfirmClose, | ||
handleCancelClose, | ||
topic, | ||
topicId, | ||
contentList, | ||
resources, | ||
showConfirmationModal, | ||
hasCheckbox, | ||
loading, | ||
hasMore, | ||
|
@@ -464,18 +499,13 @@ | |
updateSection, | ||
selectAllQuestions, | ||
workingResourcePool, | ||
activeResourcePool, | ||
addToWorkingResourcePool, | ||
removeFromWorkingResourcePool, | ||
showBookmarks, | ||
selectedResourcesInformation$, | ||
}; | ||
}, | ||
props: { | ||
closePanelRoute: { | ||
type: Object, | ||
required: true, | ||
}, | ||
}, | ||
computed: { | ||
isTopicIdSet() { | ||
return this.$route.params.topic_id; | ||
|
@@ -506,6 +536,19 @@ | |
this.bookmarksCount = newVal.length; | ||
}, | ||
}, | ||
beforeRouteEnter(_, from, next) { | ||
next(vm => { | ||
vm.prevRoute = from; | ||
}); | ||
}, | ||
beforeRouteLeave(_, __, next) { | ||
if (!this.showConfirmationModal && this.workingPoolHasChanged) { | ||
this.showConfirmationModal = true; | ||
next(false); | ||
} else { | ||
next(); | ||
} | ||
}, | ||
methods: { | ||
showTopicSizeWarningCard(content) { | ||
return !this.hasCheckbox(content) && content.kind === ContentNodeKinds.TOPIC; | ||
|
@@ -547,9 +590,6 @@ | |
topicsLink(topicId) { | ||
return this.topicListingLink({ ...this.$route.params, topicId }); | ||
}, | ||
hasTopicId() { | ||
return Boolean(this.$route.params.topic_id); | ||
}, | ||
saveSelectedResource() { | ||
this.updateSection({ | ||
section_id: this.$route.params.section_id, | ||
|
@@ -559,7 +599,7 @@ | |
//Also reset workingResourcePool | ||
this.resetWorkingResourcePool(); | ||
|
||
this.$router.replace(this.closePanelRoute); | ||
this.$router.replace(this.prevRoute); | ||
}, | ||
selectionMetadata(content) { | ||
if (content.kind === ContentNodeKinds.TOPIC) { | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None blocking comment: curious why we had to re-introduce nested routes when Richard suggested not to use it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rtibbles initial note about the nested routes I think was more of a warning as things can get squirrely in the nested routes when not done correctly.
I was motivated to try the nested approach again because of the routing fix that stopped the page reloading on every navigation and because I found it impossible to reliably capture the browser back event before closing the side panel in order to show the confirmation modal before letting the user close the panel... unless each of the pages were their own route because then I could use
beforeRoute*
guards within the components.Previously, I couldn't do
beforeRouteLeave
on the side panel components because each route just rendered the same quiz root component so the only placebeforeRoute*
stuff worked was on that root component which only would happen when leaving the quiz creation altogether.With the nested structure, however, I was able to clean up the components' hierarchies in the side panel. The key thing is that because each route is being associated with a specific component, we can block between all of routes by way of the
beforeRouteLeave
guard and define that directly in each of the SectionEditor, ResourceSelection, & ReplaceQuestions components themselves. This has the added benefit that they can handle the logic of when they show the modal or not themselves rather than trying to pass values up to the base side panel component.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Good job and thanks for explaining!