Repository: oppia/oppia

Issue:
Separate inline controllers from $uibModal.open method in new files.
<!--
  - Thanks for taking the time to propose a new feature for the Oppia project.
  - Before filing a new issue, please do a quick search to check that it hasn't
  - already been filed on the [issue tracker](https://github.com/oppia/oppia/issues)._
  -->
**Is your feature request related to a problem? Please describe.**
Some AngularJS files like controllers, directives, and services use $uibModal.open method from Angular UI Bootstrap library:
![image](https://user-images.githubusercontent.com/34922478/80324438-3004f000-8807-11ea-9453-9bb55f7b1235.png)

In almost all files, the controller property from the object passed as parameter is declared as an inline controller, instead of referencing the controller name, e.g.:
![image](https://user-images.githubusercontent.com/34922478/80324479-4743dd80-8807-11ea-8524-f9d60ffb581b.png)

An inline controller makes hard to test the file itself since there isn't any solution for covering it and properly testing it with unit tests. Also, using an inline controller instead of referencing an existed one difficulty the calculation of controllers unit test coverage, since the number of controllers is not precise.

**Describe the solution you'd like**
The first thing to be done is to create a generic modal and replace it or inherit it in all common and similar inline modals that use close or dismiss actions only, then the code will be reused often. (Fixed in #9167).
After that, the main solution is to replace all the inline controllers by separating controllers in its own file, as you can see in the following PRs: #8805, #8799, #8791, #8775 
**Describe alternatives you've considered**
You can follow this example:
![Screenshot from 2020-04-26 21-57-42](https://user-images.githubusercontent.com/34922478/80325183-89bae980-880a-11ea-8c43-564312ce105e.png)
![Screenshot from 2020-04-26 22-08-36](https://user-images.githubusercontent.com/34922478/80325188-8c1d4380-880a-11ea-9f0b-735d4f48e1b2.png)
When inline controller uses variables from the external scope (from the file itself or the function where is being called), resolve property must be used to pass these variables as local in the new controller:
![Screenshot from 2020-04-26 22-09-49](https://user-images.githubusercontent.com/34922478/80325235-ac4d0280-880a-11ea-81b5-bc82351dbd4f.png)

For the **name convention of the file** all the inline controllers must follow the file name of templateUrl property value in `$uibModal.open` method but the extension should be `.controller.t`s instead of `.html`.

**List of files where calls $uibModal.open method**
- [ ] create-activity-button.directive.ts
- [ ] exploration-embed-button.service.ts
- [ ] exploration-creation.service.ts
- [ ] story-creation.service.ts
- [ ] topic-creation.service.ts
- [ ] thumbnail-uploader.directive.ts
- [ ] question-player.directive.ts
- [ ] questions-list.directive.ts
- [ ] skills-mastery-list.directive.ts
- [ ] answer-group-editor.directive.ts
- [ ] state-hints-editor.directive.ts
- [ ] state-interaction-editor.directive.ts
- [ ] state-responses.directive.ts
- [ ] state-solution-editor.directive.ts
- [ ] version-diff-visualization.directive.ts
- [ ] collection-editor-navbar.directive.ts
- [ ] contributions-and-review.directive.ts
- [ ] question-opportunities.directive.ts
- [ ] translation-opportunities.directive.ts
- [ ] delete-account-page.controller.ts
- [ ] exploration-editor-page.controller.ts
- [ ] editor-navigation.directive.ts
- [ ] exploration-graph.directive.ts
- [ ] unresolved-answers-overview.directive.ts
- [ ] feedback-tab.directive.ts
- [ ] history-tab.directive.ts
- [ ] preview-tab.directive.ts
- [ ] exploration-save.service.ts
- [ ] exploration-states.service.ts
- [ ] settings-tab.directive.ts
- [ ] statistics-tab.directive.ts
- [ ] suggestion-modal-for-exploration-editor.service.ts
- [ ] translation-tab.directive.ts
- [ ] audio-translation-bar.directive.ts
- [ ] state-translation-editor.directive.ts
- [ ] learner-local-nav.directive.ts
- [ ] learner-view-info.directive.ts
- [ ] fatigue-detection.service.ts
- [ ] hint-and-solution-modal.service.ts
- [ ] refresher-exploration-confirmation-modal.service.ts
- [ ] suggestion-modal-for-exploration-player.service.ts
- [ ] learner-dashboard-page.controller.ts
- [ ] suggestion-modal-for-learner-dashboard.service.ts
- [ ] preferences-page.controller.ts
- [ ] signup-page.controller.ts
- [ ] skill-concept-card-editor.directive.ts
- [ ] skill-misconceptions-editor.directive.ts
- [ ] skill-prerequisite-skills-editor.directive.ts
- [ ] skill-editor-navbar.directive.ts
- [ ] story-editor-page.controller.ts
- [ ] story-editor.directive.ts
- [ ] story-node-editor.directive.ts
- [ ] story-editor-navbar-breadcrumb.directive.ts
- [ ] story-editor-navbar.directive.ts
- [ ] topic-editor-stories-list.directive.ts
- [ ] topic-editor-tab.directive.ts
- [ ] topic-editor-navbar.directive.ts
- [ ] subtopics-list-tab.directive.ts
- [ ] topics-and-skills-dashboard-page.controller.ts
- [ ] topics-and-skills-dashboard-navbar.directive.ts
- [ ] skills-list.directive.ts
- [ ] topics-list.directive.ts.






Discussion:
Hey, @marianazangrossi I believe this is a pretty huge and comparatively easy task and an eligible good first issue, can you please take a look at this [doc here](https://docs.google.com/document/d/1m4kuLYhDJYTReJHCr-kY866OoHCO4WmBRFTmbU45k-c/edit) and update the issue description accordingly? Let me know if you need some help or clarity. And I believe this falls in the category one(you'll know what's this once you go through the doc).
Hi @Showtim3, I'm a GSoC application for testing directives and controllers project and while I was studying about the codebase I've created this issue. However, it's part of my proposal. Even if I get reject in GSoC, I think it's an important thing to do in the codebase. Is there a problem to keep this issue open until GSoC results? Please let me know what is the best solution. Thanks!
I think you don't need to keep this open until GSoC -- we should just do it anyway, since it's a generally important codebase issue. Maybe let's discuss it when we meet?
Sure. But when we meet, the GSoC deadline will be reached already. If we work on it alright, some part of my proposal will be already done when result be announced (if I get approved).
Update: @marianazangrossi and I chatted about this, and she's going to work on it for the moment. Let's not make it a general starter issue yet -- it's actually a bit more complicated than it looks at first glance, because she's planning to do some consolidation of the existing modals so that we don't have 30 separate modals doing basically the same thing. She'll post back on this thread once the project is in a good state for multiple people to work on simultaneously.

Thanks!
Hi @seanlip and @Showtim3, I've done the consolidation of the similar modals (as you can see in the PR above). Also, I've updated the main comment with new instructions. I was thinking to let people work on the list I've created only after the PR is merged. What do you think?
> I was thinking to let people work on the list I've created only after the PR is merged. What do you think?

I think that sounds totally fine -- thanks, @marianazangrossi! 

Resolving patch:
diff --git a/scripts/check_frontend_coverage.py b/scripts/check_frontend_coverage.py
--- a/scripts/check_frontend_coverage.py
+++ b/scripts/check_frontend_coverage.py
@@ -35,6 +35,9 @@
 NOT_FULLY_COVERED_FILENAMES = [
     'about-page.module.ts',
     'activity-tiles-infinity-grid.directive.ts',
+    'add-answer-group-modal.controller.ts',
+    'add-hint-modal.controller.ts',
+    'add-or-update-solution-modal.controller.ts',
     'admin-config-tab.directive.ts',
     'admin-dev-mode-activities-tab.directive.ts',
     'admin-jobs-tab.directive.ts',
@@ -66,6 +69,7 @@
     'Base.ts',
     'boolean-editor.directive.ts',
     'change-list.service.ts',
+    'change-question-difficulty-modal.controller.ts',
     'circular-image.directive.ts',
     'ck-editor-4-rte.directive.ts',
     'ck-editor-4-widgets.initializer.ts',
@@ -77,6 +81,8 @@
     'collection-editor-navbar-breadcrumb.directive.ts',
     'collection-editor-navbar.directive.ts',
     'collection-editor-page.directive.ts',
+    'collection-editor-pre-publish-modal.controller.ts',
+    'collection-editor-save-modal.controller.ts',
     'collection-editor-state.service.ts',
     'collection-editor-tab.directive.ts',
     'collection-footer.directive.ts',
@@ -98,6 +104,7 @@
     'community-dashboard-page.component.ts',
     'concept-card.directive.ts',
     'ConceptCardObjectFactory.ts',
+    'confirm-delete-state-modal.controller.ts',
     'context.service.ts',
     'continue-button.directive.ts',
     'contribution-and-review.service.ts',
@@ -112,9 +119,12 @@
     'copier.directive.ts',
     'correctness-footer.directive.ts',
     'create-activity-button.directive.ts',
+    'create-activity-modal.controller.ts',
+    'create-feedback-thread-modal.controller.ts',
     'creator-dashboard-page.component.ts',
     'csrf-token.service.ts',
     'current-interaction.service.ts',
+    'customize-interaction-modal.controller.ts',
     'cyclic-transitions-issue.directive.ts',
     'delete-account-page.component.ts',
     'donate-page.component.ts',
@@ -122,26 +132,33 @@
     'drag-and-drop-positive-int-editor.directive.ts',
     'drag-and-drop-sort-input-validation.service.ts',
     'early-quit-issue.directive.ts',
+    'edit-thumbnail-modal.controller.ts',
     'editable-collection-backend-api.service.ts',
     'editable-story-backend-api.service.ts',
     'editor-navbar-breadcrumb.directive.ts',
     'editor-navigation.directive.ts',
+    'editor-reloading-modal.controller.ts',
     'email-dashboard-data.service.ts',
     'error-page.component.ts',
     'exploration-automatic-text-to-speech.service.ts',
     'exploration-creation.service.ts',
     'exploration-diff.service.ts',
     'exploration-editor-page.controller.ts',
+    'exploration-editor-suggestion-modal.controller.ts',
     'exploration-editor-tab.directive.ts',
+    'exploration-embed-button-modal.controller.ts',
     'exploration-embed-button.service.ts',
     'exploration-engine.service.ts',
     'exploration-footer.directive.ts',
+    'exploration-graph-modal.controller.ts',
     'exploration-graph.directive.ts',
+    'exploration-metadata-modal.controller.ts',
     'exploration-objective-editor.directive.ts',
     'exploration-player-page.controller.ts',
     'exploration-player-state.service.ts',
     'exploration-recommendations.service.ts',
     'exploration-save-and-publish-buttons.directive.ts',
+    'exploration-save-modal.controller.ts',
     'exploration-save.service.ts',
     'exploration-states.service.ts',
     'exploration-summary-tile.directive.ts',
@@ -168,6 +185,7 @@
     'graph-layout.service.ts',
     'graph-property-editor.directive.ts',
     'graph-viz.directive.ts',
+    'help-modal.controller.ts',
     'hint-and-solution-buttons.directive.ts',
     'hint-and-solution-modal.service.ts',
     'hint-editor.directive.ts',
@@ -209,11 +227,14 @@
     'mathjax-bind.directive.ts',
     'messenger.service.ts',
     'misconception-editor.directive.ts',
+    'moderator-unpublish-exploration-modal.controller.ts',
     'multiple-incorrect-issue.directive.ts',
     'multiple-incorrect-submissions-issue.directive.ts',
     'music-notes-input-rules.service.ts',
     'music-phrase-editor.directive.ts',
     'music-phrase-player.service.ts',
+    'new-story-title-editor-modal.controller.ts',
+    'new-topic-name-editor-modal.controller.ts',
     'nonnegative-int-editor.directive.ts',
     'normalize-whitespace-punctuation-and-case.pipe.ts',
     'normalized-string-editor.directive.ts',
@@ -304,10 +325,13 @@
     'playthrough-issues.directive.ts',
     'playthrough.service.ts',
     'Polyfills.ts',
+    'post-publish-modal.controller.ts',
     'practice-session-page.controller.ts',
     'practice-tab.directive.ts',
     'preferences-page.component.ts',
     'pretest-question-backend-api.service.ts',
+    'preview-set-parameters-modal.controller.ts',
+    'preview-summary-tile-modal.controller.ts',
     'preview-tab.directive.ts',
     'profile-link-image.directive.ts',
     'profile-link-text.directive.ts',
@@ -319,12 +343,18 @@
     'python-program.tokenizer.ts',
     'question-creation.service.ts',
     'question-difficulty-selector.directive.ts',
+    'question-editor-modal.controller.ts',
     'question-editor.directive.ts',
+    'question-opportunities-select-skill-and-difficulty-modal.controller.ts',
     'question-opportunities.directive.ts',
+    'question-player-concept-card-modal.controller.ts',
     'question-player-engine.service.ts',
     'question-player.directive.ts',
+    'question-suggestion-editor-modal.controller.ts',
+    'question-suggestion-review-modal.controller.ts',
     'question-suggestion.service.ts',
     'question-update.service.ts',
+    'questions-list-select-skill-and-difficulty-modal.controller.ts',
     'questions-list.directive.ts',
     'random-selector.directive.ts',
     'rating-display.directive.ts',
@@ -334,6 +364,7 @@
     'remove-duplicates-in-array.pipe.ts',
     'request-interceptor.service.ts',
     'response-header.directive.ts',
+    'revert-exploration-modal.controller.ts',
     'review-material-editor.directive.ts',
     'review-test-page.directive.ts',
     'role-graph.directive.ts',
@@ -362,6 +393,7 @@
     'score-ring.directive.ts',
     'search-bar.directive.ts',
     'search-results.directive.ts',
+    'select-skill-modal.controller.ts',
     'select2-dropdown.directive.ts',
     'set-of-html-string-editor.directive.ts',
     'set-of-unicode-string-editor.directive.ts',
@@ -378,6 +410,7 @@
     'skill-editor-navbar.directive.ts',
     'skill-editor-page.controller.ts',
     'skill-editor-state.service.ts',
+    'skill-mastery-modal.controller.ts',
     'skill-mastery.directive.ts',
     'skill-misconceptions-editor.directive.ts',
     'skill-prerequisite-skills-editor.directive.ts',
@@ -389,11 +422,13 @@
     'SkillDifficultyObjectFactory.ts',
     'SkillObjectFactory.ts',
     'skills-list.directive.ts',
+    'skills-mastery-list-concept-card-modal.controller.ts',
     'skills-mastery-list.directive.ts',
     'social-buttons.directive.ts',
     'solution-editor.directive.ts',
     'solution-explanation-editor.directive.ts',
     'state-content-editor.directive.ts',
+    'state-diff-modal.controller.ts',
     'state-editor.directive.ts',
     'state-editor.service.ts',
     'state-graph-visualization.directive.ts',
@@ -405,6 +440,7 @@
     'state-property.service.ts',
     'state-responses.directive.ts',
     'state-solution-editor.directive.ts',
+    'state-stats-modal.controller.ts',
     'state-top-answers-stats.service.ts',
     'state-translation-editor.directive.ts',
     'state-translation-status-graph.directive.ts',
@@ -443,6 +479,8 @@
     'summary-list-header.directive.ts',
     'supplemental-card.directive.ts',
     'svm-prediction.service.ts',
+    'tag-misconception-modal.controller.ts',
+    'teach-oppia-modal.controller.ts',
     'teacher.ts',
     'teacher2.ts',
     'test-interaction-panel.directive.ts',
@@ -473,7 +511,9 @@
     'training-panel.directive.ts',
     'translate-text.service.ts',
     'translation-file-hash-loader.service.ts',
+    'translation-modal.controller.ts',
     'translation-opportunities.directive.ts',
+    'translation-suggestion-review-modal.controller.ts',
     'translation-tab.directive.ts',
     'translator-overview.directive.ts',
     'truncate-and-capitalize.filter.ts',
@@ -484,6 +524,7 @@
     'tutor-card.directive.ts',
     'unicode-string-editor.directive.ts',
     'unresolved-answers-overview.directive.ts',
+    'upload-activity-modal.controller.ts',
     'url-interpolation.service.ts',
     'utils.service.ts',
     'value-generator-editor.directive.ts',
@@ -492,6 +533,8 @@
     'voiceover-opportunities.directive.ts',
     'voiceover-recording.service.ts',
     'warnings-and-alerts.directive.ts',
+    'welcome-modal.controller.ts',
+    'welcome-translation-modal.controller.ts',
     'worked-example-editor.directive.ts',
 ]
 


Test patch: