-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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 #6210: Added an exploration whitelist #6255
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #6255 +/- ##
===========================================
- Coverage 75.47% 75.46% -0.02%
===========================================
Files 958 958
Lines 77879 77891 +12
Branches 4634 4640 +6
===========================================
+ Hits 58777 58778 +1
- Misses 19102 19113 +11
Continue to review full report at Codecov.
|
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 @aks681! Took a pass and left some comments (but I think those comments have an effect on the rest of the PR).
core/controllers/features.py
Outdated
@@ -39,4 +39,6 @@ def get(self, exploration_id): | |||
config_domain.IS_IMPROVEMENTS_TAB_ENABLED.value, | |||
'is_playthrough_recording_enabled': | |||
exploration_id in whitelisted_exploration_ids_for_playthroughs, | |||
'can_add_prerequisite_skill_to_state': |
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.
Normally we use this phrasing ("can do XXX") to convey something about the user's permissions, so perhaps you want to go with something like are_prerequisite_skills_editable instead.
Having said that, I think it would actually be a better idea to combine this and the above property into a single "is_exploration_whitelisted" variable, and use that instead throughout. /cc @brianrodri
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 actually think it's a good idea to expose it as a separate FE variable, it'll make changing things much simpler in the future and helps distinguish the fact that the two are separate but related.
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.
But they're really based on the same constant, right? I don't see them ever giving different results, so in that case shouldn't the branching happen in the frontend (and only when that branching is actually needed)?
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.
Hi @aks681, I chatted with @brianrodri about this, and we suggest:
(a) Send a single value from the backend
(b) Use this to populate a service in the frontend that's dedicated to answering the question "is exploration curated" (or "is exploration part of story" or something). Not sure if this should be part of ExplorationContextService or something else.
(c) Any other frontend services that need this should use the service in (b) as a source of truth.
Does that sound good?
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.
Since all editor directives already import StateEditorService and it already stores whether the editor is a question or exploration editor, shall I return is_exploration_whitelisted
from the backend and set a corresponding value in it?
Also, should is_playthrough_recording_enabled
be removed? Since that is an exploration feature and does not tell the context of the exploration.
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 think that sounds OK to me (on both counts).
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.
Ok, done.
@@ -37,7 +37,7 @@ oppia.directive('outcomeDestinationEditor', [ | |||
EXPLORATION_AND_SKILL_ID_PATTERN, PLACEHOLDER_OUTCOME_DEST) { | |||
var currentStateName = null; | |||
$scope.canAddPrerequisiteSkill = | |||
constants.ENABLE_NEW_STRUCTURE_EDITORS; | |||
StateEditorService.getCanAddPrerequisiteSkill(); |
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 it be: "constants.ENABLE_NEW_STRUCTURE_EDITORS && isExplorationWhitelisted()"? I.e. if we are not removing the "enable" flag yet we should keep it everywhere, and remove it "all at once" later.
Ditto elsewhere.
Btw, just to check, refresher exps are also behind a whitelist flag, right?
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.
Ok.
For refresher explorations, I think the restriction is that only admins/moderators can add them. Other than that, they can be added to any exploration.
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.
Hm, I think that's OK (though please check that the restriction you cited is actually the case). We plan to remove that feature in the long run anyway so I guess it's up to you whether to migrate it or not to the new flag.
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.
Yes, that is the case, as seen here, where permission to add refresher exploration is restricted to only admins and moderators.
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.
Done initial comment. Added new structures flag check as well.
@@ -323,6 +323,9 @@ oppia.directive('stateResponses', [ | |||
|
|||
EditorFirstTimeEventsService.registerFirstSaveRuleEvent(); | |||
|
|||
if (!$scope.tmpOutcome.missingPrerequisiteSkillId) { |
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.
What is its value before being null?
Ideally we would set this value to null at the very outset, rather than having a possible case where it's "kinda null but not really".
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 null when initialised, but I think it becomes undefined when an invalid sequence is entered, after validation by ng-pattern, which was causing the error in the issue.
So, here I am just checking if it's undefined and changing value to null.
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.
Hm, but I think it should never become undefined in the first place. Can we find a way to make that not happen?
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.
Done, used ng-model-options
as explained here.
@aks681 -- just to double-check, does this actually need to go in the current release? I thought we were only turning on the new structures flag in March; does this have ill-effects on the Feb release if not merged? |
Confirmed with @aks681, this PR need not go out in Feb as it would only affect stuff when the new structures editor flag is true. |
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 @aks681! Some minor changes but otherwise it's good to go I think.
@@ -22,7 +22,7 @@ | |||
</div> | |||
<div style="margin-top: 12px;" ng-if="isSelfLoop() && canAddPrerequisiteSkill"> | |||
<b>Prerequisite skill ID (optional): </b> | |||
<input type="text" name="missingPrerequisiteSkillId" ng-model="outcome.missingPrerequisiteSkillId" class="form-control" tabindex="0" aria-invalid="false" ng-pattern="explorationAndSkillIdPattern"> | |||
<input type="text" name="missingPrerequisiteSkillId" ng-model="outcome.missingPrerequisiteSkillId" class="form-control" tabindex="0" aria-invalid="false" ng-model-options="{allowInvalid: true}" ng-pattern="explorationAndSkillIdPattern"> |
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.
Does this mean that a non-empty invalid string can still be saved? If so, that might be a problem.
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, it doesn't allow it to be saved. ng-model-options
just makes sure the scope variable is never undefined, i.e even if it's invalid, the value will be stored in the scope variable, but the Save button will still be disabled and there is still a red outline around the text box (tested it locally). So, I don't think it will be an issue.
@@ -95,7 +95,7 @@ | |||
(try again, with refresher exploration "<[outcome.refresherExplorationId]>") | |||
</span> | |||
</span> | |||
<div style="margin-top: 1em;" ng-if="outcome.missingPrerequisiteSkillId && canAddPrerequisiteSkill"> | |||
<div style="margin-top: 1em;" ng-if="outcome.missingPrerequisiteSkillId && isSelfLoop(outcome) && canAddPrerequisiteSkill"> |
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 to check, why must the outcome be a self loop? Sometimes we might redirect to a helper card if there's a missing prerequisite, but knowing that there's a missing prerequisite might give useful information for skill mastery updates.
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.
Currently, prerequisite skill ID input text box is only visible if it is a self loop, just like refresher explorations.
If it is not a self loop, then what would be the flow for the learner? Would the learner be shown the skill card and then the next card?
Since, usually self loops correspond to wrong answers and an answer that leads to another card is correct. If the next card is related to clarifying a wrong answer also, we can remove that option altogether and link that answer group with a skill anyway, so I think a skill need only be linked to a self looped answer group, is that correct?
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 think the flow for the learner and whether the answer group is annotated with a prereq skill are two separate things. We can still keep that info there but not display the prereq skill card (e.g. it may be useful to record that the learner hasn't mastered the prereq yet). So probably still worth letting it be edited, right?
Now, for the learner flow when it's not a self loop -- I don't know the answer yet. But I think we can figure out when we implement the skill cards. We could always use logic that's something like: if self-loop, show skill card, otherwise ignore skill card (for purposes of flow) and move to destination card.
What do you think? If you agree, maybe delete the added clause.
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.
Actually, in addition to the above, let's add a new flag for enabling this feature separately and turn it off for now (for all explorations). It blocks on the following:
- Validation of the skill ID that's being entered
- Making it possible for creators to select the skill ID from a dropdown.
Please file an issue for this (with checkboxes), with the last step being to turn the flag on.
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.
Done. Created issue #6341
Also, deleted the self loop clause.
core/templates/dev/head/pages/exploration_editor/ExplorationEditor.js
Outdated
Show resolved
Hide resolved
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.
@aks681 Just one more comment, but after that please feel free to merge. Thanks!
@@ -95,7 +95,7 @@ | |||
(try again, with refresher exploration "<[outcome.refresherExplorationId]>") | |||
</span> | |||
</span> | |||
<div style="margin-top: 1em;" ng-if="outcome.missingPrerequisiteSkillId && canAddPrerequisiteSkill"> | |||
<div style="margin-top: 1em;" ng-if="outcome.missingPrerequisiteSkillId && isSelfLoop(outcome) && canAddPrerequisiteSkill"> |
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.
Actually, in addition to the above, let's add a new flag for enabling this feature separately and turn it off for now (for all explorations). It blocks on the following:
- Validation of the skill ID that's being entered
- Making it possible for creators to select the skill ID from a dropdown.
Please file an issue for this (with checkboxes), with the last step being to turn the flag on.
Thanks @aks681! |
Fix #6210. Restricted addition of prerequisite skill ids to states to just a set of whitelisted exploration, which are listed in
config_domain.WHITELISTED_EXPLORATION_IDS_FOR_PLAYTHROUGHS
.Also fixed the issue description.