Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

feat(panel): Adding a hook on close success. #9819

Merged
merged 1 commit into from Oct 24, 2016

Conversation

DerekLouie
Copy link
Contributor

Hello,

@ErinCoughlan @bradrich

Here is a small PR to add an "on close success" hook for users who want to run some code after a panel successfully closes.

It also adds an optional parameter to the "close" function which allows the user to specify a string describing why the close happened (standardized strings have been added to the "escapeToClose" and "clickOutsideToClose" functions.

Please Review.

@DerekLouie DerekLouie added the EOC label Oct 12, 2016
@DerekLouie DerekLouie self-assigned this Oct 12, 2016
@crisbeto
Copy link
Member

crisbeto commented Oct 12, 2016

@ErinCoughlan @DerekLouie wouldn't this be more appropriate to pass to the onClose interceptor? That way you could use the reason for closing to determine whether to block it.

@ErinCoughlan
Copy link
Contributor

@crisbeto Interceptors intercept the close events, so they are run before close is finished and can block the close from happening. The goal of this PR is to allow the user to run events after the panel is closed, similar to the animation hooks for onDomRemoved.

This already works for explicit close events because the user can chain off of the close call. But on pressing escape or clicking on the backdrop, we don't give the user any way to know these events happened or allow them to do work after it's closed. The most common use case of this is a dialog where when the panel is closed you need to reject/resolve the promise from open. This currently is not possible.

@crisbeto
Copy link
Member

Alright, that makes sense. Regarding the promise: didn't we have a task somewhere to have it be a part of the mdPanel API (returning a promise on init and then resolving/rejecting it)?

@@ -126,6 +126,9 @@ angular
* outside the panel to close it. Defaults to false.
* - `escapeToClose` - `{boolean=}`: Whether the user can press escape to
* close the panel. Defaults to false.
* - `postClose` - `{function=}`: Function that is called after close
Copy link
Contributor

@bradrich bradrich Oct 12, 2016

Choose a reason for hiding this comment

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

I think naming this onCloseSuccess would be more appropriate.

@@ -1153,20 +1156,24 @@ MdPanelRef.prototype.open = function() {

/**
* Closes the panel.
* @param {string} closeEvent The event type that triggered the close.
Copy link
Contributor

Choose a reason for hiding this comment

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

This parameter would most likely not be a string. Events are normally MouseEvent, or AngularEvent.

Copy link
Contributor

Choose a reason for hiding this comment

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

You should probably not mention "event" here, since that means something very different to most people, as @bradrich mentioned. Perhaps, closeReason, closeCause, or even just "reason" or "cause" would work.

Copy link
Contributor

Choose a reason for hiding this comment

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

@ErinCoughlan Good catch! I was thinking that it was going to be the event that the occurred to get there, not a string representation.

@@ -1043,6 +1043,7 @@ describe('$mdPanel', function() {
clickPanelContainer();

expect(myButton).toBeFocused();

Copy link
Contributor

Choose a reason for hiding this comment

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

Why the extra lines here?

});
});
});

describe('postClose logic:', function() {
it('postClose when provided', function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

These tests should have more descriptive names. See the rest of the it tests, they all have the form of should do something when something.... These tests are failing in Travis and it wasn't immediately apparent without reading the tests what the test was trying to accomplish.

Copy link
Contributor

Choose a reason for hiding this comment

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

Follow the same test naming as the other events we fire, like onOpenComplete or onRemoving.

@@ -126,6 +126,9 @@ angular
* outside the panel to close it. Defaults to false.
* - `escapeToClose` - `{boolean=}`: Whether the user can press escape to
* close the panel. Defaults to false.
* - `postClose` - `{function=}`: Function that is called after close
* is done. The first parameter passed into this function is the closeEvent
* and the 2nd is the current panelRef.
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought panelRef was first because that has to be defined and closeEvent is optional.

You should also mention the two events for pressEscapeToClose and clickBackdropToClose or no one will know how to use them.

@@ -126,6 +126,9 @@ angular
* outside the panel to close it. Defaults to false.
* - `escapeToClose` - `{boolean=}`: Whether the user can press escape to
* close the panel. Defaults to false.
* - `postClose` - `{function=}`: Function that is called after close
Copy link
Contributor

Choose a reason for hiding this comment

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

{function(panelRef, string)=} is the correct type, especially since this has params.

@@ -126,6 +126,9 @@ angular
* outside the panel to close it. Defaults to false.
* - `escapeToClose` - `{boolean=}`: Whether the user can press escape to
* close the panel. Defaults to false.
* - `postClose` - `{function=}`: Function that is called after close
* is done. The first parameter passed into this function is the closeEvent
Copy link
Contributor

Choose a reason for hiding this comment

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

Possible re-word to "after close has successfully finished". "done" is too vague for this, since it will not be called if the panel fails the close.

@@ -1153,20 +1156,24 @@ MdPanelRef.prototype.open = function() {

/**
* Closes the panel.
* @param {string} closeEvent The event type that triggered the close.
Copy link
Contributor

Choose a reason for hiding this comment

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

You should probably not mention "event" here, since that means something very different to most people, as @bradrich mentioned. Perhaps, closeReason, closeCause, or even just "reason" or "cause" would work.

@@ -1704,7 +1711,7 @@ MdPanelRef.prototype._configureEscapeToClose = function() {
ev.stopPropagation();
ev.preventDefault();

self.close();
self.close("escapeToClose");
Copy link
Contributor

Choose a reason for hiding this comment

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

There should be an enum that the user can access for the different close causes (like the enum for positioning or animations).

String values are dangerous because it allows for typos.

});
});
});

describe('postClose logic:', function() {
it('postClose when provided', function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

Follow the same test naming as the other events we fire, like onOpenComplete or onRemoving.

describe('postClose logic:', function() {
it('postClose when provided', function () {
var obj = {
postClose: function() {},
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you need to make an object here? Does it suffice to just create a spy, then pass it to the config?

var onCloseSuccess = jasmine.createSpy('onCloseSuccess');
var config = angular.extend({  'postClose': onCloseSuccess });

openPanel(config);
closePanel();

expect(onCloseSuccess).toHaveBeenCalledWith(panelRef, undefined);

@ThomasBurleson ThomasBurleson added in progress Mainly for in progress PRs, but may be used for issues that require multiple PRs needs: work labels Oct 12, 2016
@ThomasBurleson ThomasBurleson added this to the 1.1.3 milestone Oct 12, 2016
@DerekLouie
Copy link
Contributor Author

Hello! All the aforementioned comments have been addressed, please take another look at this PR at your earliest convenience :)

@bradrich
Copy link
Contributor

LGTM

@@ -126,6 +126,12 @@ angular
* outside the panel to close it. Defaults to false.
* - `escapeToClose` - `{boolean=}`: Whether the user can press escape to
* close the panel. Defaults to false.
* - `onCloseSuccess` - `{function(panelRef, string)=}`: Function that is
Copy link
Contributor

Choose a reason for hiding this comment

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

!panelRef

* - `onCloseSuccess` - `{function(panelRef, string)=}`: Function that is
* called after the close successfully finishes. The first parameter passed
* into this function is the current panelRef and the 2nd is an optional
* string explaining the close reason. Currently 'pressEscapeToClose' and
Copy link
Contributor

Choose a reason for hiding this comment

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

Aren't these enums? that the user can get access to?

* Possible default closeReasons for the close function.
* @enum {string}
*/
MdPanelRef.closeReasons = {
Copy link
Contributor

Choose a reason for hiding this comment

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

You'll want this to be exported on the mdPanel service as well so users can access them. (Follow what the other enums did.)

@@ -1059,6 +1059,77 @@ describe('$mdPanel', function() {
});
});

describe('onCloseSuccess logic:', function() {
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 think these tests should be it's own group. This functionality is part of the close logic, and therefore should be individual tests after the other close callback tests.
Like this:
https://github.com/angular/material/blob/master/src/components/panel/panel.spec.js#L877

clickPanelContainer();

expect(onCloseSuccessCalled).toBe(true);
expect(closeReason).toBe('clickOutsideToClose');
Copy link
Contributor

Choose a reason for hiding this comment

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

Use the enums in the tests too, not strings.

@DerekLouie DerekLouie force-pushed the panelAnimationHooks branch 2 times, most recently from d6dc99a to 40e534c Compare October 13, 2016 18:44
@DerekLouie
Copy link
Contributor Author

Fixed the enums / documentation comments. Please take another look at your earliest convenience :).

Copy link
Contributor

@ErinCoughlan ErinCoughlan left a comment

Choose a reason for hiding this comment

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

LGTM

@ErinCoughlan ErinCoughlan removed the EOC label Oct 13, 2016
@ErinCoughlan ErinCoughlan added needs: presubmit and removed in progress Mainly for in progress PRs, but may be used for issues that require multiple PRs needs: work labels Oct 18, 2016
@ThomasBurleson ThomasBurleson modified the milestones: 1.1.2, 1.1.3 Oct 18, 2016
@jelbourn jelbourn merged commit db90283 into angular:master Oct 24, 2016
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.

None yet

6 participants