-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
[BD-32] feat: add filter before dashboard rendering process starts #29994
[BD-32] feat: add filter before dashboard rendering process starts #29994
Conversation
Thanks for the pull request, @mariajgrimaldi! I've created BLENDED-1118 to keep track of it in Jira. More details are on the BD-32 project page. When this pull request is ready, tag your edX technical lead. |
df0dddc
to
f4e433e
Compare
87b6f84
to
30a58a7
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.
This changeset is working flawlessly. All the controls from PR#29996 are here and working as expected.
Great work @mariajgrimaldi. I think we can squash this and be ready for another reviewer.
I think that @MichaelRoytman could lend us a hand with a review from edX and maybe @pomegranited could bring some community eyes into this. Does any of you think that you could look at this?
@felipemontoya @mariajgrimaldi Cooool... I'd love a chance to play with your hooks extension framework! But it'll likely be a couple weeks before I've got time to look at it, and I bet you can get it merged before then :) But I'll keep an eye on it and put in my 2c if there's time. |
30a58a7
to
784ba2e
Compare
Thanks for the pull request, @mariajgrimaldi! I've created BLENDED-1195 to keep track of it in Jira. More details are on the BD-32 project page. When this pull request is ready, tag your edX technical lead. |
Thanks Jill, we'll be happy to have your feedback when time permits. We would still like to get this over the line before the cut, so I'll just throw a long shot and see if @ormsbee or @justinhynes could give a look at this. |
784ba2e
to
c259ca7
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.
These content hooks are really powerful but so clean and simple.. it's a pleasure to play around with them and see them extended.
@mariajgrimaldi CC @felipemontoya I've suggested some changes, but the concept and implementation are great!
except DashboardRenderStarted.RenderAlternativeDashboard as exc: | ||
response = render_to_response(exc.dashboard_template, exc.template_context) | ||
except DashboardRenderStarted.RedirectToPage as exc: | ||
response = HttpResponseRedirect(exc.redirect_to or 'account_settings') |
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.
<lms_root>/account_settings
404s.. shouldn't this be:
response = HttpResponseRedirect(exc.redirect_to or 'account_settings') | |
response = HttpResponseRedirect(exc.redirect_to or reverse('account_settings')) |
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 absolutely missed this. Thank you so much!
|
||
|
||
class DashboardRenderNotAllowed(DashboardException): | ||
pass |
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 don't see DashboardRenderNotAllowed
or DashboardException
used anywhere.. should these be removed?
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.
Thanks for noting. I thought we could do something with this, but we just ignored it. I'll remove 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.
Thanks @mariajgrimaldi ! Feel free to ping me for a 2nd review when you're ready?
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.
Nudge @mariajgrimaldi CC @felipemontoya -- do you have an estimate for when you'll be able to address my comments?
Just planning my week, and want to make sure I allow time for a 2nd review. Thanks!
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'm so sorry for the delayed response; I got caught up with other stuff. I'll take some time this week to address your comments!
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.
No worries @mariajgrimaldi, thanks for getting back to me :)
try: | ||
# .. filter_implemented_name: DashboardRenderStarted | ||
# .. filter_type: org.openedx.learning.dashboard.render.started.v1 | ||
context, dashboard_template = DashboardRenderStarted.run_filter( | ||
context=context, template_name=dashboard_template, | ||
) | ||
except DashboardRenderStarted.RenderAlternativeDashboard as exc: | ||
response = render_to_response(exc.dashboard_template, exc.template_context) |
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.
It looks like, instead of raising DashboardRenderStarted.RenderAlternativeDashboard
, a dashboard render filter could return something like this and surreptitiously change the template and/or context:
return {
"context": context,
"template_name": "alternative_template.html",
}
It's cleaner if everything is handled using the exception mechanism, even changes to the context
dict:
try: | |
# .. filter_implemented_name: DashboardRenderStarted | |
# .. filter_type: org.openedx.learning.dashboard.render.started.v1 | |
context, dashboard_template = DashboardRenderStarted.run_filter( | |
context=context, template_name=dashboard_template, | |
) | |
except DashboardRenderStarted.RenderAlternativeDashboard as exc: | |
response = render_to_response(exc.dashboard_template, exc.template_context) | |
try: | |
# .. filter_implemented_name: DashboardRenderStarted | |
# .. filter_type: org.openedx.learning.dashboard.render.started.v1 | |
DashboardRenderStarted.run_filter( | |
context=context, template_name=dashboard_template, | |
) | |
except DashboardRenderStarted.RenderAlternativeDashboard as exc: | |
response = render_to_response(exc.dashboard_template, exc.template_context) |
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.
This design was intended as the following:
Happy path -> modify return values to render a valid dashboard but modified
Unhappy path -> modify the return values through exceptions
For clarity we could change:
RenderAlternativeDashboard
For:
RenderInvalidDashboard?
Does this make sense? @pomegranited @felipemontoya
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.
That naming change would make things clearer @mariajgrimaldi , good suggestion. Also some docs to explain the expected usage?
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.
We mentioned it in the OEP-50:
Filters on the other hand are passed data and are expected to return something. This something will be used by the platform code. The most common case is to be passed data and return the same of somewhat changed, but similar data. Other common case would be to receive data and raise an exception in accordance with the definition of the hook. Most likely to completely halt the process that would happen after the hook.
But it would be useful to add it in a straightforward way to the opened-filters documentation.
Again, thank you for the great suggestions! 😄
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.
Ah cool, I haven't read all the OEPs :) I'd be fine with just referencing the relevant ones in your openedx-filters README, and then leave it to the users of the library to read up on the details there. No need to re-write what's already been written and reviewed :)
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.
This is working great now :) But we need a small update to
https://github.com/eduNEXT/openedx-filters-samples/blob/master/openedx_filters_samples/samples/pipeline.py#L525 -- needs to raise DashboardRenderStarted.RenderInvalidDashboard
.
""" | ||
response = self.client.get(self.dashboard_url) | ||
|
||
self.assertEqual(status.HTTP_302_FOUND, response.status_code) |
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.
Should also test that the redirect is headed to the expected location, both when redirect_to
is set on the exception, and when it isn't (and falls back to redirecting to the account settings).
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.
Great catch! I'll add that check
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.
Yay thank you @mariajgrimaldi :) Could you also add a check that's like TestRedirectDashboardPageStep, but without the redirect_to
value set, so we can see the default redirection to account_settings
?
""" | ||
response = self.client.get(self.dashboard_url) | ||
|
||
self.assertContains(response, "This is a custom response.") |
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.
Can go even harder here:
self.assertContains(response, "This is a custom response.") | |
self.assertEqual("This is a custom response.", response.content.decode("utf-8")) |
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.
Thank you! :)
So many good suggestions @pomegranited! Thank you so much. I'll be committing your suggestions this week. |
f648338
to
36797ab
Compare
acf101a
to
202aed9
Compare
Hello there @pomegranited! I think I got all of your suggestions! Again, thanks for such valuable insight 🥳 |
👍 Thank you for your changes @mariajgrimaldi ! This is working really smoothly now.
|
e43fa27
to
e736ae3
Compare
086bf60
to
22cd7de
Compare
* Add dashboard filter to dashboard student's view * Add tests/docs for filter's integration
22cd7de
to
895a649
Compare
@mariajgrimaldi 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future. |
EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production. |
EdX Release Notice: This PR has been deployed to the production environment. |
<!-- 🌰🌰 🌰🌰🌰🌰 🌰 Note: the Nutmeg master branch has been created. Please consider whether your change 🌰🌰🌰🌰 should also be applied to Nutmeg. If so, make another pull request against the 🌰🌰🌰🌰 open-release/nutmeg.master branch, or ping @nedbat for help or questions. 🌰🌰 Please give your pull request a short but descriptive title. Use conventional commits to separate and summarize commits logically: https://open-edx-proposals.readthedocs.io/en/latest/oep-0051-bp-conventional-commits.html Use this template as a guide. Omit sections that don't apply. You may link to information rather than copy it. More details about the template are at openedx/open-edx-proposals#180 (link will be updated when that document merges) --> ## Description Backport filters that didn't make it to nutmeg release: **Add filter before certificate creation starts** (cherry picked from commit e8fa890) **Add cohort change filter before moving users from cohorts** (cherry picked from commit 465e5c0) **Add filter before certificate rendering process starts** (cherry picked from commit 7f974d1) **Add filter before course dashboard rendering process starts** (cherry picked from commit 895a649) **Add filter before course about rendering process starts** (cherry picked from commit ccfa0b4) **Integrate cohort assignment filter definition to cohort model** (cherry picked from commit ec69659) ## Supporting information Refer to the BTR wg github issue for the rationale behind this PR: openedx/wg-build-test-release#187 ## Testing instructions 1. Install the needed library release: `openedx-filters==0.7.0` 2. Install the samples library: `pip install git+https://github.com/eduNEXT/openedx-filters-samples.git@master#egg=openedx_filters_samples` 3. Then, configure each filter. If you want to test all the filters simultaneously, use this configuration and try to do each operation the filter is related to; the filter sample step will stop the operation. ``` OPEN_EDX_FILTERS_CONFIG = { "org.openedx.learning.certificate.creation.requested.v1": { "fail_silently": False, "pipeline": [ "openedx_filters_samples.samples.pipeline.StopCertificateCreation" ] }, "org.openedx.learning.cohort.change.requested.v1": { "fail_silently": False, "pipeline": [ "openedx_filters_samples.samples.pipeline.StopCohortChange" ] }, "org.openedx.learning.certificate.render.started.v1": { "fail_silently": False, "pipeline": [ "openedx_filters_samples.samples.pipeline.RenderAlternativeCertificate", ] }, "org.openedx.learning.dashboard.render.started.v1": { "fail_silently": False, "pipeline": [ "openedx_filters_samples.samples.pipeline.RenderAlternativeDashboard", ] }, "org.openedx.learning.course_about.render.started.v1": { "fail_silently": False, "pipeline": [ "openedx_filters_samples.samples.pipeline.RenderAlternativeCourseAbout", ] }, "org.openedx.learning.cohort.assignment.requested.v1": { "fail_silently": False, "pipeline": [ "openedx_filters_samples.samples.pipeline.StopCohortAssignment" ] }, } ``` Please, for detailed instructions on how to test each filter, refer to each of these PR(s): Filter for certificate creation: #29949 Filter for cohort change: #29964 Filter for certificate rendering: #29976 Filter for dashboard rendering: #29994 Filter for course about rendering: #29996 Filter for cohort assignment: #30431 ## Deadline For the next nutmeg release.
Description
As part of the Hooks Extension Framework implementation plan, this PR adds a filter before the dashboard rendering process starts.
Supporting information
ADR(s) on:
Testing instructions
With this configuration, you won't be able to: