Jasig/uPortal — pull request #290 by apetro (2014-04-10 18:18:23+00:00)
Title: UP-3896 Favorites Portlet initial implementation for uPortal 4.1

This pull request proposes including the Favorites portlet in `Jasig/master` for inclusion in uPortal 4.1.

See also [the Favorites wiki page](https://wiki.jasig.org/display/UPC/Favorites).

See also the pull requests that brought some of Favorites features into its feature branch:

* #203 (Un-favoriting)
* #215 (Portlet definition naming)
* #230 (Favorites collections as their own folder type)
* #260 (Maximizing a portlet supersedes focusing on a fragment)

Features
========

View and Actuate Favorite Portlets
-----------------------------------

Favorite portlets display in the view mode of the Favorites portlet:

![a_few_of_my_favorite_things](https://cloud.githubusercontent.com/assets/952283/2671334/5b05c794-c0d9-11e3-9370-32e5ceb3142e.png)

Clicking an individual favorite renders that portlet focused.

There's a special-case UI when the user has zero favorites.

![got-no-favorites](https://cloud.githubusercontent.com/assets/952283/2671425/13514fa8-c0da-11e3-8d16-0825910a12fd.png)

If your portal [voice involves sad robots](http://techcrunch.com/2011/03/02/googles-new-404-fail-robot-says-thats-an-error-thats-all-we-know/), that's where you put your sad robot image.

Favorite and Unfavorite Individual Portlets
----------------------------------

Users can mark a portlet they're looking at as their favorite via the portlet titlebar gear menu:

![add_to_favorites_contextual_menu](https://cloud.githubusercontent.com/assets/952283/2670030/99057636-c0c8-11e3-9859-f31e4c4f695d.png)

A noty notification confirms to the user that they have added the favorite.

![added_emerg_admin_favorite](https://cloud.githubusercontent.com/assets/952283/2671216/1fcbe60a-c0d8-11e3-9330-7593c3eebb86.png)

Users can change their minds and [unfavorite](https://en.wiktionary.org/wiki/unfavorite) as well:

![remove_from_favorites](https://cloud.githubusercontent.com/assets/952283/2671270/aa7cfd98-c0d8-11e3-9f77-08d84f56fd98.png)

Use favorite collections
------------------------

Besides individual favorites, users can also *have* favorite collections. These have a caret instead of a star.

![favorite_collection](https://cloud.githubusercontent.com/assets/952283/2670471/489c5f4c-c0ce-11e3-96f1-6b7c06ea6e52.png)

Clicking a favorited collection renders that collection focused. Focusing (as opposed to just selecting) a fragment is a new capability of the structure transform.

![focused_collection](https://cloud.githubusercontent.com/assets/952283/2671376/bc84ffda-c0d9-11e3-9bff-1ecad8cc7382.png)

Users can't favorite collections.

This feature isn't fully baked and you probably won't choose to implement it in your uPortal implementation. Degrades gracefully so choosing not to use favorite collections is totally reasonable.

Edit mode
--------------

The favorites portlet has an edit mode. Subject to DLM delete and move restrictions, users can unfavorite and re-order their favorite portlets (among other favorite portlets) and their favorite collections (among other favorite collections).

![reorderable](https://cloud.githubusercontent.com/assets/952283/2671130/d5a85ba4-c0d6-11e3-86ec-b9ac2a35e444.png)

The portlet supports but does not require Marketplace. When configured with the `fname` of a Marketplace portlet via a `portal.properties` property, Favorites will display a link to access the Marketplace to invite users to gather additional favorites.

There's a special-case UI when the user has zero favorites.

Configuration
===========

The theme features to include add/remove favorite in the portlet titlebar gear menu detects whether the user has a folder of type `favorites` in the layout. If the user doesn't have a folder for storing favorites, the favorites add/remove control is suppressed. Thus favorites degrades gracefully and is configured naturally (give it to users you want to have it, or not, via DLM fragment audience management).

The Favorites portlet will simply not display favorite collections when the user has none. If you're not ready to deliver favorite collections, and you're almost certainly not (see caveats below), simply don't push any to users, and you don't have to worry about the feature, perhaps after you tweak message bundle messages to your liking.

Favorites honors DLM delete restrictions and tries to honor DLM re-ordering restrictions. You can use DLM fragment permission restriction features to influence what users can do with the favorites you give them by default and can ex-post-facto adjust the default favorites of established favorites-portlet-using folk.

Implementation Notes
==================

* Structure transform now signals to theme transform about whether the Add Tab UI control is appropriate. Favorites uses this to suppress the control when rendering focused-on-a-favorites-collection.
* Changes `IUserLayoutFolderDescription` to represent folder types as the same Strings as the XML representation, rather than using integers in the Java model.
* `UserLayoutNodeDescription` copy constructor now copies DLM attributes; demonstrated with unit test.
* Enhances layout Java model to reflect the folder type from the XML representation.
* DLM logging enhanced in support of favorites troubleshooting. This is some but not all of the enhancements in flight around #256 .

Known issues and technical debt
==========================

Compelling defaults
--------------------------
* Default favorites and favorite collections in uPortal ootb should be improved to provide a more compelling starting point. What's here demonstrates the Favorites functionality but isn't great. This love could be included with some more general love on uPortal default content for the uPortal 4.1 release.

Ghosts in the machine
-----------------------------
* Resetting the user layout doesn't restore the user's consumption of favorited-by-default collections that the user un-favorited.

UI Edge Cases in Favoriting and Unfavoriting
-----------------------------
* Adding a favorite doesn't cause the Favorites portlet to refresh if it's on-screen, so it won't immediately reflect an added portlet. This probably isn't a real problem in that most of the time users won't be adding favorites while also looking at the favorites portlet and any time they're adding a favorite they're looking at the thing they're favoriting so they don't need the Favorites portlet to refresh until next page reload anyway.
* Likewise with removing a favorite.
* Users can Favorite the Favorites portlet. Which works, but probably isn't useful to anyone. Fun, though.

Edit UI issues
-------------------
* The click surface to actuate un-favoriting is probably way too big and should just be the trash glyph. This is backlogged at Wisconsin for improvement.
* Un-favoriting is currently a traditional portlet-action-URL request, portal page re-render. This is "jarring" and might be better implemented as an AJAX interaction not requiring page re-render. (Anything that can be JavaScript will eventually become JavaScript.)
* Re-ordering makes some attempt to reflect DLM ordering restrictions. It does not successfully reflect all DLM re-ordering restrictions. DLM will nonetheless enforce these restrictions on eventual layout reload. This may be a non-issue since for real implementation you may choose to allow users to re-order favorites as much as they like.
* The Customize drawer brokenness when a portlet is maximized issue ( #264 ) means that re-ordering favorites doesn't work when Favorites is maximized.

Limited functionality for Favorite Collections
--------------------------------------------------------
* There's no way to "favorite" a collection. Even with #216 Marketplace, there's no UI for viewing available collections and favoriting them. You just get whatever favorite collections DLM gives you.
* You can un-favorite a collection (if DLM lets you) but once you do, there's no way to get it back.
* This limited functionality may actually be enough for you to implement Favorite Collections locally. By restricting permissions on the favorite collection folders such that end users can't delete them you avoid users losing them and if you publish sensible defaults maybe those collections of favorites are good enough to start. It is a little weird to tell people what their favorites are and not let them express differently though. :/
* Of course, you can disable the favorites collection feature entirely by just not having any folders of type `favorite_collection`.
* Implementing more features around favorite collections up to Wisconsin's needs is backlogged at Wisconsin. This is still in-flight design where it's not entirely clear what favorite collections will become.

Requires styles in Respondr
------------------------------------

* Favorites is designed and developed for use in Respondr. It renders under Universality, but no attempt has been made to make it look good or be functional.

Merge tasks
----------------
* This pull adds focused-on-a-fragment capability to the structure tranfsorm. This means that the resolution to #264 (Customize drawer broken when a portlet is maximized) will need to consider what the Customize drawer experience ought to be (none?) in the focused-on-a-fragment view.
* Rebasing got messy at some point and there's probably some noise needing cleaned up, e.g. around configuring whether to show portlet control icons.