Skip to content
This repository has been archived by the owner on May 4, 2022. It is now read-only.

feat: add keyboard controls for widget layout #795

Merged
merged 18 commits into from
Mar 16, 2018

Conversation

thevoiceofzeke
Copy link
Contributor

@thevoiceofzeke thevoiceofzeke commented Mar 15, 2018

MUMUP-3249: "As a keyboard user I would like to re-order my layout so that I can customize my MyUW experience to my needs."

In this PR:

  • Replace incompatible jQuery UI drag and drop implementation with angular-drag-and-drop-lists
  • Using arrow keys while focusing a widget will move it up or down in the layout order
  • Add initial focus point with aria label in list of widgets
  • Add controls for compact mode
  • Remove ui bootstrap layout implementation and replace with CSS-grid (with flex box fallback for unsupported browsers)

Related PR: uportal-app-framework#721

Demos

New drag and drop

draggable

Keyboard controls

keyboard-controls

New responsive layout

new-layout


Contributor License Agreement adherence:

* @param event {Object} The event object
* @return {boolean} True if proper conditions aren't met
*/
$scope.moveWithKeyboard = function(widget, event) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could something like fluid drag and drop work here? https://wiki.fluidproject.org/display/fluid/Drag+and+Drop+Design+Pattern

Or could this be contributed upstream so that everyone can enjoy an accessible experience?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I don't agree that sortable widgets is something that should be in the app framework. I don't even think widgets should be in the app framework at all. We included them because on-campus developers using the framework to develop other apps asked us to, and in retrospect I would have fought against doing it.

Hopefully there comes a day when the app framework becomes a collection of API-driven web components. Then this separation of concerns won't be an issue. 🤷‍♂️

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't agree that sortable widgets is something that should be in the app framework.

I agree 👍
Hence the suggestion to contribute it upstream at Angular drag and drop lists.
Thanks @apetro for providing the link to the issue. 🙇

* @return {number} Index of the desired item or -1
*/
var findLayoutIndex = function(array, attribute, value) {
for (var i = 0; i < array.length; i+= 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -239,7 +329,7 @@ define(['angular', 'jquery'], function(angular, $) {
/**
* Sets href attribute for 'BASIC' type widget
* @param portlet
* @returns {*}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/gajus/eslint-plugin-jsdoc recommends returns. Either return or returns works for me.
Either way we should add that to the lint rules and make it consistent across the app.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in there already and triggers a warning. The instances changed in this PR were fixed automatically by running eslint with the --fix flag.

* @param event {Object} The event object
* @return {boolean} True if proper conditions aren't met
*/
$scope.moveWithKeyboard = function(widget, event) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this different from web/src/main/webapp/my-app/layout/controllers.js line 79-130? are both needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily, no. It's duplicated because the two views use different controllers, and refactoring those controllers isn't in the scope of this story. It's something we should do at some point.

* @param fname {String} The moved widget's fname
* @param dropIndex {Number} Index where the widget landed
* @param startIndex {Number} (optional) Index before moving the widget
* @return {boolean}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the semantics of the boolean returned? true means what? false means what?

* Respond to arrow key-presses when focusing a movable list element
* @param widget {Object} The widget trying to move
* @param event {Object} The event object
* @return {boolean} True if proper conditions aren't met
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's up with the boolean return? true means didn't do anything? Is this idiomatic? In some Java methods, for instance, true means had an effect and false means didn't have an effect, e.g. Set.add() .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree it's semantically meaningless, just the result of hasty writing. This is something I can clean up!

var nextIndex = currentIndex + 1;

// left or up
if (event.which === 37 || event.which === 38) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic constants? Worth abstracting? Can they be referenced from somewhere?

Copy link
Contributor

@ChristianMurphy ChristianMurphy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Progress is progress

@thevoiceofzeke thevoiceofzeke merged commit 98aa1d0 into uPortal-Attic:master Mar 16, 2018
@davidmsibley davidmsibley added this to the 7.2.1 milestone Mar 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants