Repository: oppia/oppia

Issue:
Implement the breadcrumb of the collection editor page
The collection editor page's breadcrumb currently only has "Oppia" on it. This implementation (which should follow what the exploration editor has) involves adding the following:
1. The page header. (e.g: Oppia > Collections > Intro To Collections > Edit)
2. Publish Changes button
3. Preview button
4. Settings button
5. History button
6. Statistics button
7. Feedback button
8. Help button

The buttons functionality need not to be implemented in this phase.



Discussion:
The individual pages should be blank, navigation should work, and the tabs should be hidden behind feconf flags. These flags, when enabled, will show the individual tabs (one flag per tab/page), but with the feconf flag disabled (which will be by default), the tabs won't show up. This allows us to have several developers working on each page individually. The major work of this issue involves a few things:
1. Implement blank controllers for each page of the collection editor
2. Implement tab buttons to navigate to each page (including the main editor)
3. Add feconf flags to hide those tabs by default
4. Implement breadcrumbs on the navigation bar for the collection editor

For adding feconf flags, you have to add one flag in `feconf.py`, like so:

https://github.com/oppia/oppia/blob/031111cbe3ba04e19413ff6f181d5080ba442138/feconf.py#L402

Then, you need to make sure this flag is shared with the frontend:

https://github.com/oppia/oppia/blob/8e863f90d2f6ab69c79b7fc9732958704d145079/core/controllers/editor.py#L250 (except in this case, we would send it through the `collection_editor.py` backend controller).

Finally, you can use Jinja template conditionals to ignore markup in the frontend when the flag is disabled, see:

https://github.com/oppia/oppia/blob/ed8c912b6f82b004c2f58d3c53e5e64641d21686/core/templates/dev/head/editor/state_statistics.html#L40

@oskarcieslik, just to confirm -- would you like to take this on? 

@seanlip Yes :) 

~~To be thorough and specific, this issue is meant to also include the following sub-items from #1462:~~
- ~~There should be a settings tab for editing the title, category, and objective in the same way as the exploration editor. The category should be edited using a drop-down menu of categories.~~
- ~~The saving functionality should match the exploration editor with a save dialog, drafts, and a comment. There should also be an indicator as to how many changes are being saved. This includes a confirmation that the save was successful or failed.~~

~~If this issue starts getting a bit large, please reach out to either me or @amgowano. There's a decent break-down of work above, but there are still some elements not covered in significant detail.~~

Please see #1611 and #1612 instead.

@BenHenning, a question: are we planning to use the same services for saving etc. from the exploration editor so that they apply to both places, or create entirely new ones for the collection editor? Doing the former is harder (since it involves figuring out what they have in common and abstracting that out), but doing the latter results in severe code duplication which isn't good long-term.

@seanlip @BenHenning I hope to make some progress this weekend :) 
Also I think that it would be better to abstract out some behaviour of saving in exploration editor (like dialog showing up) and use it in collections editor.

Great, thanks @oskarcieslik! If it gets too big, feel free to break it down into smaller individual projects and do a bit at a time. 

I share @seanlip's thought here. This issue is slightly larger than one divisible starter project. Splitting this up will be very helpful on the reviewer (likely me), so I would greatly appreciate it. :)

@seanlip, I think it's mostly a question about the modal and overall saving/publishing flow. I think we should try and reuse that part, but I'm not keen on reusing the services which summarize the changes that were done. It would probably be more effective to leverage the UndoRedoService and our change domain objects for this sort of thing. We could attach some sort of summary message to each change specifying what it means, then just pull that list and display it in the modal. As I recall, this seems much cleaner than the way the exploration editor does it and deprecates the old behavior.

Either way, I don't think this issue necessarily needs to care about this stuff yet. Listing which changes were done to the collection when saving/publishing is not part of this issue; it can be done, but I would rather the work be minimized here or else it risks exploding into a bunch of large PRs.

I agree about not needing to duplicate the "which changes were done" part -- we're actually planning to rewrite that part anyway for the exploration editor.

@BenHenning / @oskarcieslik / @amgowano : could one of you sketch the definition of a reasonable "first PR" project, and get the others' agreement? I think it's worth agreeing on what this is before starting to code it.

Hi @amgowano @BenHenning, I finally got time to start working on this, but I can't figure out what is the route for collection's editor page. I tried URLs from feconf.py, but they don't seem to work for me, can you help me figure out what am I doing wrong? Thanks :)

OK, this was a bit tricky -- I tried to figure it out from scratch, too. This is what you do:
- Go to /admin, look for the config property called "Names of users allowed to use the collection editor", and type in your username, then scroll to the bottom of that section and click "Save changes". The reason this switch is here is because collections functionality isn't ready to ship yet.
- Reload the demo collection (see the "Reload a single collection" section on the /admin page).
- Go to /collection_editor/create/0.

@BenHenning, @amgowano:
- should we have these instructions in some canonical location, and link to them in all collection-related issues? Otherwise, everyone is going to run into this.
- also, how do I create a brand-new collection? The option to do so doesn't show up for me in the gallery.

Awesome @seanlip, thanks! :)

Hi @seanlip @BenHenning @amgowano. :) I implemented breadcrumb just like in exploration editor (without functionality for the moment like saving etc.) and I observed some issue I think. 

When I wanted to show current selected tab in breadcrumb I used RouterService from like in Exploration Editor, problem is it has a lot of dependencies from exploration editor, even ExplorationEditor.js itself, which in my opinion is a problem or maybe I'm wrong? 

I think we should create RouterService which would only be responsible for returning some part of current path and it shouldn't be dependent on any controller. What do you guys think?

I'd be fine with abstracting RouterService out into something more generic, if it is possible to find a clean way to do so. I don't think it has an explicit dependency on ExplorationEditor.js, though, unless you mean that it uses the names of the tabs from there?

Also, if you do go down this route, it may be sensible to make a separate PR from develop that refactors RouterService to be independent of the exploration editor, and wait for that to go in before working on this issue directly. However, that refactoring PR strikes me as slightly nontrivial. What did you have in mind for the API of the proposed RouterService?

I think RouterService is dependent on ExplorationEditor because I couldn't make it work without adding "ExplorationEditor.js" file in collections editor's html file (https://goo.gl/ZLddpm).

I think it's a good idea to make a new PR request for abstracting RouterService to something more generic, but I haven't thought of API yet, I will first try to finish this task.

Sorry for late replies, I didn't mean to neglect this @oskarcieslik!

@seanlip let's use this issue thread as the canonical location for how to create collections, since you covered half of the material here. It sounds like the whitelist might not actually be used in production, so I'm not keen on publicizing the behavior too much. We can reference other developers to this issue if they need help using the collection editor.

Beyond Sean's instructions for accessing the collection editor, creating a new collection can be done by going to the 'My Explorations' page from the profile menu. When your name is in the whitelist of usernames allowed to access the collection editor, a 'Create Collection' button will show up on this page next to 'Create Exploration'.

Now, regarding breaking down this issue. I see in #1610 @oskarcieslik set up the breadcrumb, buttons, and feconf flags. I think it should also add blank controllers for each page so that something shows up when you click on the tabs (even if it's a blank area in the editor) and I will mention this in the PR. Other than that, #1610 is exactly what I was thinking of for the first PR of this issue.

The rest of the issue can be broken down into two subsequent PRs. Because of that, I am splitting this issue into two new ones. Please see #1611 and #1612, which contain the additional work that was originally part of this issue. If you're interested in tackling either of those after this one, @oskarcieslik, please let one of us know. :)

Hi @BenHenning, I made a new PR 2 days ago and forgot to mention it, can you take a look at it? :)

I forgot about blank controllers for each page, I will work on it today :)

Hi all! I'm sorry for delay, but I finally pushed new PR in which I added controllers and fixed issues that @BenHenning pointed out :)

Thanks, Oskar! I will take a look at this soon (probably Wed).

On Mon, Mar 21, 2016 at 12:55 PM, Oskar Cieślik notifications@github.com
wrote:

> Hi all! I'm sorry for delay, but I finally pushed new PR in which I added
> controllers and fixed issues that @BenHenning
> https://github.com/BenHenning pointed out :)
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly or view it on GitHub
> https://github.com/oppia/oppia/issues/1587#issuecomment-199448599


Resolving patch:
diff --git a/core/controllers/collection_editor.py b/core/controllers/collection_editor.py
--- a/core/controllers/collection_editor.py
+++ b/core/controllers/collection_editor.py
@@ -22,6 +22,7 @@
 from core.domain import rights_manager
 from core.domain import summary_services
 from core.platform import models
+import feconf
 import utils
 
 current_user_services = models.Registry.import_current_user_services()
@@ -127,7 +128,15 @@ def get(self, collection_id):
             'title': collection.title,
             'can_unpublish': rights_manager.Actor(
                 self.user_id).can_unpublish(
-                    rights_manager.ACTIVITY_TYPE_COLLECTION, collection_id)
+                    rights_manager.ACTIVITY_TYPE_COLLECTION, collection_id),
+            'SHOW_COLLECTION_NAVIGATION_TAB_SETTINGS': (
+                feconf.SHOW_COLLECTION_NAVIGATION_TAB_SETTINGS),
+            'SHOW_COLLECTION_NAVIGATION_TAB_HISTORY': (
+                feconf.SHOW_COLLECTION_NAVIGATION_TAB_HISTORY),
+            'SHOW_COLLECTION_NAVIGATION_TAB_FEEDBACK': (
+                feconf.SHOW_COLLECTION_NAVIGATION_TAB_FEEDBACK),
+            'SHOW_COLLECTION_NAVIGATION_TAB_STATS': (
+                feconf.SHOW_COLLECTION_NAVIGATION_TAB_STATS)
         })
 
         self.render_template('collection_editor/collection_editor.html')
diff --git a/feconf.py b/feconf.py
--- a/feconf.py
+++ b/feconf.py
@@ -437,6 +437,10 @@ def get_empty_ratings():
 # Unfinished features.
 SHOW_TRAINABLE_UNRESOLVED_ANSWERS = False
 ENABLE_STRING_CLASSIFIER = False
+SHOW_COLLECTION_NAVIGATION_TAB_SETTINGS = False
+SHOW_COLLECTION_NAVIGATION_TAB_HISTORY = False
+SHOW_COLLECTION_NAVIGATION_TAB_FEEDBACK = False
+SHOW_COLLECTION_NAVIGATION_TAB_STATS = False
 
 # Output formats of downloaded explorations.
 OUTPUT_FORMAT_JSON = 'json'


Test patch: