-
Notifications
You must be signed in to change notification settings - Fork 716
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
Quiz creation bookmark selection #11835
Quiz creation bookmark selection #11835
Conversation
Build Artifacts
|
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.
Some follow-up notes from a cohack today where we discussed another approach -- overall, I think that the duplication is maybe a bit too much and that we can find another way to approach this more simply.
I'll describe two possible paths here
1 - The path we explored together - bookmarks query parameter
- Update the
getBookmarksLink
property to return the current route, but place a query parameter on it called something likeshowBookmarks
- Within the
contentList
computed property, conditionally return the list of bookmarks if that query parameter is in place - Update the conditions for showing the "Bookmarks" button-card so that it doesn't show while listing the bookmarks -- could be a computed property
showBookmarksButton
that uses that same logic, but also takes into consideration whether or not we're listing the bookmarks (which could be its own computed property as wellshowBookmarks
) - Note that these computed properties can also be leveraged to update the text on the screen, for example on this Figma where it says "Channel name" we may instead see "Bookmarks" as the title for the list.
Pros
- Less duplication
- Don't need to use a new route for the side panel
- Faster to get things working
Cons
- Adds more bloat to the sizable ResourceSelection component
- Comments explaining complexity may not always be helpful
- Just putting a query parameter on the route to change the page's behavior is a bit brittle -- if we ever allow bookmarking whole topics, this may not be so easy to update
- This might get a bit more hairy when we implement search (as we may find that will have another query parameter
searchTerm
or something that we'd have to conditionalize against for what we're showing, how and where. - If & when we need to tweak designs you can find yourself wrestling with a series of boolean computed properties and managing a bunch of conditionals throughout the template
2 - A path more similar to the one you have here
- Rather than copying and pasting the bulk of the
ResourceSelection
component here (including the footer, and such), you could trim the newShowBookMarkedResources
component down to just basically be the title text (eg "Bookmarks") and theContentCardList
components, then pass the values needed in as props fromResourceSelection
. This would result also in needing to leaveResourceSelection
as the component for the bookmarks route - Then in
ResourceSelection
you could conditionally display that new component in place of the similar section of template that it has (ie, the title, breadcrumbs, ContentCardList, etc) - You could even consider making three total child components, one each for the three possible ways in which
ResourceSelection
might display all the things.
In this instance, the pattern would result in needing to pass in some of the methods that we're currently just using directly within ResourceSelection
for the interaction handling rather than importing them all in each of the child components.
As a rough example:
<template>
<div ...>
<div v-if="loading">
<KCircularLoader />
</div>
<div v-else>
<component :is="visibleComponent" :isChecked="isChecked" :selectAllChecked... />
</div>
<!-- the footer business -->
</template>
<script>
/* imports and such */
setup {
// The component which is shown to list the items
const visibleComponent = computed(() => {
if(!topicId) {
if(route.value.name == PageNames.BOOK_MARKED_RESOURCES) {
// The component that fetches & lists bookmarks
return ShowBookMarkedResources;
} else {
// The component that shows the Bookmarks link card
// and fetches & shows channels
return ShowChannels;
}
} else {
// The component that fetches and shows the children for the current
// topicId value & the breadcrumbs
return ShowTopic;
}
});
/* everything else */
Pros
- The logic for each individual way in which we might show contents listed out is encapsulated in its own component
- The
ResourceSelection
component has its own responsibilities reduced as it will no longer handle the fetching but, rather, will delegate the heavy lifting to those child components - It can be easier to reason about what is happening and debug using dev tools when logic is spread around like this
- This can be more extensible -- that is to say that it would then be relatively easy to add a similar "search" route and a new
ShowQuizSearchResults
component, which may indeed have its own specific behavioral needs.
Cons
- Will require more upfront work to dismantle the current
ResourceSelection
component so that the fetching business happens in the child components - As you begin to pull at the seams of the existing component, you'll have to make the decision around which props can be (or need to be) defined in which component for their own purposes, such as the passing down of various things imported from
useQuizResources
Overall, I think that the second path is probably the "golden path" in that it abides common patterns and principles in Vue development such as encapsulation & the separation of concerns.
However, the first path is probably much faster and simpler to implement -- but only for now as we may find that we wish we'd taken the second path a few months down the line when we have to implement the Coach metadata search business.
ce2aebd
to
a0df1a8
Compare
a0df1a8
to
8f5c1ee
Compare
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.
Just a couple of stylistic comments, one blocking, another not. Also one request for adding comments.
Overall, looking at this diff the solution doesn't feel like it adds too much complexity as I'd worried it might.
Rather, I think that there is just some complexity inherent to this component that we'd do well to clean up sooner than later and this particular approach isn't the source of the complexity.
kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue
Outdated
Show resolved
Hide resolved
kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue
Outdated
Show resolved
Hide resolved
@@ -113,6 +113,7 @@ | |||
const store = getCurrentInstance().proxy.$store; | |||
const route = computed(() => store.state.route); | |||
const topicId = computed(() => route.value.params.topic_id); | |||
const bookMarksFlag = computed(() => route.value.query.bookmarks); |
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'd also love to see a comment here explaining what this is used for to give some context around how this whole solution works (ie, we're using the query parameter as a " route " of sorts to determine if we should be showing bookmarks or not.
Overall I think that @AlexVelezLl might do well to take inspiration from this approach for the work on #11786
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.
LGTM after the updates - thanks @ozer550
Summary
References
closes #11818
Reviewer guidance
Testing checklist
PR process
Reviewer checklist
yarn
andpip
)