Skip to content
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

Section settings side panel #11314

Merged
merged 30 commits into from
Oct 24, 2023
Merged

Section settings side panel #11314

merged 30 commits into from
Oct 24, 2023

Conversation

AllanOXDi
Copy link
Member

@AllanOXDi AllanOXDi commented Sep 28, 2023

Summary

Built Quiz Section Settings Side Panel.

References

closes #11016

Reviewer guidance

See the figma design.

Testing checklist

  • Contributor has fully tested the PR manually
  • If there are any front-end changes, before/after screenshots are included
  • Critical user journeys are covered by Gherkin stories
  • Critical and brittle code paths are covered by unit tests

PR process

  • PR has the correct target branch and milestone
  • PR has 'needs review' or 'work-in-progress' label
  • If PR is ready for review, a reviewer has been added. (Don't use 'Assignees')
  • If this is an important user-facing change, PR or related issue has a 'changelog' label
  • If this includes an internal dependency change, a link to the diff is provided

Reviewer checklist

  • Automated test coverage is satisfactory
  • PR is fully functional
  • PR has been tested for accessibility regressions
  • External dependency files were updated if necessary (yarn and pip)
  • Documentation is updated
  • Contributor is in AUTHORS.md

@github-actions github-actions bot added APP: Coach Re: Coach App (lessons, quizzes, groups, reports, etc.) SIZE: medium labels Sep 28, 2023
@AllanOXDi AllanOXDi marked this pull request as ready for review October 3, 2023 12:46
@AllanOXDi AllanOXDi mentioned this pull request Oct 3, 2023
9 tasks
@akolson
Copy link
Member

akolson commented Oct 4, 2023

Hi @AllanOXDi, could you please address the conflicts reported here?

@github-actions github-actions bot added DEV: backend Python, databases, networking, filesystem... APP: Learn Re: Learn App (content, quizzes, lessons, etc.) SIZE: large and removed DEV: backend Python, databases, networking, filesystem... APP: Learn Re: Learn App (content, quizzes, lessons, etc.) labels Oct 4, 2023
@marcellamaki marcellamaki self-requested a review October 4, 2023 15:13
Copy link
Member

@marcellamaki marcellamaki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @AllanOXDi - great work so far! It's really exciting seeing this work coming together. I've added some feedback in terms of some general code adjustments. The two main blockers for me right now are in regards to strings and swapping out hex color code for theme tokens.

I realize that a lot of this work is about getting the foundations of a component in place, but not necessarily all of the functionality, so I will defer to @nucleogenesis in regards to some of my comments about "not using placeholders" such as in strings and router paths. If you two have a plan for this approach, that's totally okay. But, one thing I am reflecting on a lot recently is that sometimes stubbing things out can mean that things get missed or problems don't surface until later on in the development process. At the same time, working out every detail before merging PRs can slow things down. I'd encourage you and Jacob to at least chat through the pros and cons together as you decide what is blocking and what can be done in follow up. (But really I would so greatly prefer that we do not merge placeholder strings if at all avoidable 😄)

Thanks again for all of the hard work here! It's great to see you contributing so much to this new feature. And please do not hesitate to reach out if there are any comments that I can clarify or help with 🙂


<KRouterLink
appearance="raised-button"
:to="{ path: 'new/123/replace-questions' }"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what these paths should be based on the architectural decisions made with @nucleogenesis, but I think if it's possible for these to be the real path (or alternatively, maybe they should be just a button and not a router link at all), it would be worth trying to work that out now and get as much of the behavior in place as possible, even if the actual "saving" and "replacing" to the database doesn't happen until later

@@ -4,6 +4,7 @@
v-if="$route.params.section_id"
ref="resourcePanel"
alignment="right"
sidePanelWidth="700px"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this is probably the width that is listed on the spec, it will be too big on smaller screens. This should be updated so that the width is 700px on larger screens, and smaller on small screens. In other places, we have a full-screen panel on mobile view, for example, where the width is 100% of the screen width. Worth confirming with @tomiwaoLE that this is the approach that would be correct for the designs, and also checking with @nucleogenesis about to implement (and if there is any logic we can repurpose from other places where we solve the same problem)

Copy link
Member Author

@AllanOXDi AllanOXDi Oct 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @tomiwaoLE ,I am dropping by to find out the intended side panel behaviour on a mobile device, could it be that it should occupy half the screen size or can take full screen ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AllanOXDi IIRC the side panel goes full width on mobile - you can double check by opening it for a piece of content in the library

numQuestions: 1,
};
},
$trs: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two high-level comments about strings here.

First, rather than put strings in the component and use strings in the component, we can now use the strings in enhancedQuizManagementStrings (see kolibri-common/strings/enhancedQuizManagementStrings.js). Based on the team feedback, we are going to try this out for this project. I know we were a bit delayed in getting these in, but I think having just one place for strings will hopefully make things easier. I think it is worth refactoring the strings here now, rather than merging these in and having to do the cleanup later. @nucleogenesis can probably do a cohack session with you (and @thanksameeelian if she is curious - I know she has some frontend work coming up) about how we will be accessing and using these strings within the components. Hopefully it will be easier. And, any edits that you need to make to the strings can be made directly to that file.

Secondly, and relatedly, I understand that you are just scaffolding out the UI here, but I think we should try to refrain from adding placeholder strings (such as "2 resources selected from 2 channels") unless they are absolutely necessary. I realize that the scope of this PR might not include all of the functionality that would enable some of the interactions on this section of the page, but I would prefer that use the real counts (i.e. if we don't have any selected resources, just have it be the data which would be 0) rather than pass in placeholder strings or placeholder values. I'm not sure I'm explaining this very well, so please do ask if you have questions about what I mean.

.section-order-list {
height: 2.5em;
margin-top: 0.5em;
border: 1px solid #dedede;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all of the colors throughout the css here, every time you are using a hex code, please swap this out with one of our theme tokens. To do this, it will mean adding it in the template, or calculating in computed as needed, rather than setting it here in the css. But, it means that our theming will not break :) There are several places throughout this PR where this is used, and this update should be applied to all of them.

Copy link
Member

@akolson akolson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @AllanOXDi! Code generally looks good. Also, I generally agree with Marcella's feedback on the areas she has pointed out that need improvement so it might be good to have these in before the merge.

@github-actions github-actions bot added SIZE: very large DEV: backend Python, databases, networking, filesystem... APP: Learn Re: Learn App (content, quizzes, lessons, etc.) and removed DEV: backend Python, databases, networking, filesystem... APP: Learn Re: Learn App (content, quizzes, lessons, etc.) labels Oct 4, 2023
Copy link
Member

@nucleogenesis nucleogenesis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few outstanding things to fix that I spotted in the code and testing.

:primary="true"
:text="applySettings$()"
class="apply-settings-style"
@click="quizForge.saveQuiz()"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't call on the saveQuiz but rather should be calling updateSection. saveQuiz will be connected to the "Save" button on the root page and commits changes to the server but updateSection will only update the quizForge state

Comment on lines 281 to 292
sectionOrderList: [
{
name: 'Section order',
current: this.currentSection$(),
isActive: true,
},
{
name: 'Section 2 / unique title',
current: null,
isActive: false,
},
],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this ought to probably be a computed property on this that reads from quizForge.allSections. I'll note above re: how/where the section order should be updated.

},
},
methods: {
handleSectionSort() {},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to call quizForge.updateQuiz so that the question_sources property reflects the updated sort order. Combining this with populating the drag container w/ the quizForge.allSections will get this working I think.

Comment on lines 236 to 251
sectionSettings$,
sectionTitle$,
numberOfQuestionsLabel$,
optionalDescriptionLabel$,
quizResourceSelection$,
numberOfSelectedResources$,
currentSection$,
deleteSection$,
applySettings$,
changeResources$,
sectionOrder$,
questionOrder$,
randomizedLabel$,
randomizedOptionDescription$,
fixedLabel$,
fixedOptionDescription$,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking thought here re: this new string convention (cc @marcellamaki @rtibbles )

I'm feeling of two minds on this convention where we destructure all of the message partials out and then return them in setup. With a lot of strings like this, it just adds 30 lines of cruft right at the top of the component definition.

So I'm wondering then if maybe we should, by convention, just return the strings object like:

setup() {
    /* ... */
    return {
         eqmStrings: enhancedQuizManagementStrings,
        /* ... */
    }

Then we'd use it like this.eqmStrings.sectionLabel$() or {{ eqmStrings.randomizedLabel$() }}.

Just feels like the destructuring of the strings, as a pattern, would be better suited for when you're pulling one string out of the common core, but when you're pulling in a full feature's strings then you're liable to be using quite a lot of them.

In any case -- just want to get some thoughts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a battle between:

Explicit is better than implicit.

and

Sparse is better than dense.

or

Beautiful is better than ugly.

The laundry list doesn't particularly bother me, simply because of the explicitness involved, it tells us exactly which strings are going to be used in the component, and the component doesn't have to have any knowledge beyond the setup function, as to where those strings have come from.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was also wondering if a component that has a lot of strings will mean initializing the string from the setup and calling them the template or javascript will just increase the number of lines of code in the component.
I think your approach @nucleogenesis would be good to limit that.

Comment on lines 296 to 313
sectionOrderList() {
return [
{
name: 'Section order',
current: this.currentSection$(),
isActive: true,
},
{
name: 'Section 2 / unique title',
current: null,
isActive: false,
},
];
},
},
methods: {
handleSectionSort() {
this.quizForge.updateQuiz();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to pass something to update here.

So, that @sort event that calls this handleSectionSort will pass a value (I think just the new version of the list values that have been sorted) -- you'll need to make sure that the list has objects that validate with the type defined as a QuizSection. So here you should basically expect to receive a parameter in this function.

The shape of the data given to this parameter, I believe, will be the same shape you define in sectionOrderList (which should be returning quizForge.allSections) -- so this means that if you're using that allSections list, which is a list of objects in this shape, then you can just take the value of that given parameter and pass that to the updateQuiz call.

Note how on the Quiz typedef you'll see there is a question_sources property which is where we store the quiz's list of QuizSection objects.

This means that the updateQuiz needs an object with keys that map to the Quiz type. In this particular case, you should be able to take in the param passed to handleSectionSort and then pass { question_sources: theParamThatWasPassedIn } to update the order of the sections.

:style="{ color: $themePalette.grey.v_700 }"
>
<p class="current-section-text space-content">
{{ section.current }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to my comment about handling the @sort event below -- since the sectionOrderList will be returning an array of QuizSection objects, we'll have the section_id on hand and can just check to see if quizForge.activeSection is equal to the section iterated over here.

Comment on lines +313 to +314
section_id: this.quizForge.activeSection.value.section_id,
section_title: this.sectionTitle,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final stretch here will be wiring up the radio buttons for the randomization, question count, and description and this should be all set here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A related issue is that the section's current settings aren't being applied to the form when it is initialized. For example, the first default created section has the title "Section 1" which should populate the "Title" textfield.

Comment on lines 141 to 144
<Draggable
v-for="(section,index) in sectionOrderList"
:key="index"
>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should put a background: $themeTokens.surface CSS value on this because otherwise, the background is transparent and you can see through it as you drag it making it kind of look/feel insubstantial in a weird way. (I just realized this while using the draggable stuff w/ the accordion)

Copy link
Member

@nucleogenesis nucleogenesis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as expected! The one issue re: the section title initializing as "" will be fixed elsewhere. When I apply the section title and open the side panel again it shows what I'd expect.

@nucleogenesis nucleogenesis dismissed marcellamaki’s stale review October 24, 2023 18:30

Will address the hard-coded side panel width elsewhere. Other feedback has been addressed

@AllanOXDi AllanOXDi merged commit e7c0d65 into learningequality:develop Oct 24, 2023
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
APP: Coach Re: Coach App (lessons, quizzes, groups, reports, etc.) SIZE: large SIZE: medium SIZE: very large
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants