Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsaved changes modal #252

Merged
merged 71 commits into from
Dec 18, 2018
Merged
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
6656a2b
Modal interaction works
parostatkiem-zz Nov 22, 2018
ccc8157
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Nov 23, 2018
a0c8f0e
Implement the prompt
parostatkiem-zz Nov 23, 2018
38afc97
Improve code & add comments
parostatkiem-zz Nov 23, 2018
6670654
Add support for custom title and text
parostatkiem-zz Nov 26, 2018
6b83b17
Fix obsolete import
parostatkiem-zz Nov 26, 2018
259a587
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Nov 27, 2018
19146ee
Handle potential errors
parostatkiem-zz Nov 27, 2018
eb1a472
Add unit test
parostatkiem-zz Nov 27, 2018
0f1f65e
Add demo to Angular example & add e2e tests
parostatkiem-zz Nov 27, 2018
6c91d1d
Update comment in e2e
parostatkiem-zz Nov 27, 2018
d7b3b8b
Undo temporary change
parostatkiem-zz Nov 27, 2018
1686dae
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Nov 28, 2018
ae77b09
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Nov 28, 2018
242c90f
Merge branch 'master' into Unsaved-changes-modal
jesusreal Nov 29, 2018
87d0060
Remove unnecessary css imports
jesusreal Nov 30, 2018
84fc378
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Nov 30, 2018
22779f3
Add missing dependency
parostatkiem-zz Nov 30, 2018
d3293e3
Remove unnecessary changes
parostatkiem-zz Nov 30, 2018
4a51b86
Refactor state structure in app.html
jesusreal Nov 30, 2018
8165408
extract checking if component is able to handle modal
parostatkiem-zz Nov 30, 2018
488c767
Merge branch 'Unsaved-changes-modal' of https://github.com/parostatki…
parostatkiem-zz Nov 30, 2018
70fd297
shorten promise handling
parostatkiem-zz Nov 30, 2018
3c5820f
Remove obsolete changes
parostatkiem-zz Nov 30, 2018
9de58aa
Improve dirty page example in Angular app
parostatkiem-zz Nov 30, 2018
46ceedd
Improve solution
parostatkiem-zz Dec 3, 2018
4c7b559
Improve history handling
parostatkiem-zz Dec 3, 2018
ebf539c
Fix typo
parostatkiem-zz Dec 3, 2018
597f33f
Add missing dependency
parostatkiem-zz Dec 3, 2018
fa4943b
Improve e2e & use dedicated `data-cy` attribute
parostatkiem-zz Dec 3, 2018
13bcf62
Remove unnecessary e2e comment
parostatkiem-zz Dec 3, 2018
5852ca4
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Dec 3, 2018
216c667
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Dec 5, 2018
0c014fe
Remove obsolete comment
parostatkiem-zz Dec 5, 2018
2bf41d9
rename 'changeDirtyStatus' method & generate proper docu
parostatkiem-zz Dec 5, 2018
1e51dfc
Rename e2e tests
parostatkiem-zz Dec 5, 2018
04f046a
Polish the language
parostatkiem-zz Dec 5, 2018
9c5f6cb
Remove unnecessary comment
parostatkiem-zz Dec 5, 2018
ad5b55d
Center the modal when side nav is collapsed
parostatkiem-zz Dec 5, 2018
9e698c9
center the modal in the iframe
parostatkiem-zz Dec 5, 2018
eecd8a1
Improve modal responsiveness with side Nav
parostatkiem-zz Dec 5, 2018
a690e56
Remove unwanted history entry when user declines redirecting
parostatkiem-zz Dec 5, 2018
131bf8c
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Dec 5, 2018
7806a56
Avoid unwanted history entry when redirecting
parostatkiem-zz Dec 5, 2018
07fe6e6
Remove unnecessary example from docu
parostatkiem-zz Dec 5, 2018
ac311a9
Focus "Yes" button on modal
parostatkiem-zz Dec 5, 2018
77b76c7
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Dec 6, 2018
8997828
Improve modal positioning
parostatkiem-zz Dec 6, 2018
dbdd6d2
Merge branch 'master' of https://github.com/kyma-project/luigi into U…
parostatkiem-zz Dec 7, 2018
47673ed
Improve responsiveness
parostatkiem-zz Dec 7, 2018
8d1d9fa
Update unsaved changes modal trigger to support external links on top…
jesusreal Dec 12, 2018
3885d0b
Support unsaved changes modal trigger on logout
jesusreal Dec 12, 2018
ae830d0
Refactorings to minimize code duplication
jesusreal Dec 12, 2018
ff6f493
Add error handler for showUnsavedChangesModal on handleRouteClick mehtod
jesusreal Dec 12, 2018
71c8798
For navigation from luigi client, apply unsaved changes logic without…
jesusreal Dec 13, 2018
402f60e
Avoid needing to click twice in the modal when clicking history back …
jesusreal Dec 13, 2018
583356e
Fix unit tests
jesusreal Dec 13, 2018
d00da70
Merge remote-tracking branch 'upstream/master' into Unsaved-changes-m…
jesusreal Dec 13, 2018
2446b8f
Merge remote-tracking branch 'upstream/master' into Unsaved-changes-m…
jesusreal Dec 13, 2018
7e658c8
Support unsaved changes modal for preserved views
jesusreal Dec 14, 2018
cb010e2
Add backdrop to unsaved changes modal
jesusreal Dec 14, 2018
8ee233c
Refactor by removing inside app navigation handler
jesusreal Dec 14, 2018
ba7cd48
Undo unimportant cosmetic changes to avoid massive merge conflicts wi…
jesusreal Dec 14, 2018
2022b6d
Merge branch 'master' into Unsaved-changes-modal
jesusreal Dec 14, 2018
efd78e1
Add unsaved modal changes support and pointer cursor to logo title co…
jesusreal Dec 17, 2018
1d35d3e
Merge branch 'master' of github.com:kyma-project/luigi into Unsaved-c…
jesusreal Dec 17, 2018
2bd5f2e
Fix e2e tests
jesusreal Dec 17, 2018
5cb0ebb
small improvement in luigi client docu
jesusreal Dec 18, 2018
a82ae71
More docu changes
jesusreal Dec 18, 2018
e128b07
improve docu for text added on last commit
jesusreal Dec 18, 2018
7d7cdf4
Update description for isDirty parameter
jesusreal Dec 18, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions client/luigi-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@
return {
/** @lends linkManager */
/**
* Navigates to the given path in application hosted by Luigi. It contains either a full absolute path or a relative path without a leading slash that uses the active route as a base. This is the standard navigation.
* Navigates to the given path in the application hosted by Luigi. It contains either a full absolute path or a relative path without a leading slash that uses the active route as a base. This is the standard navigation.
* @param {string} path path to be navigated to
* @param {string} sessionId current Luigi **sessionId**
* @param {boolean} preserveView Preserve a view by setting it to `true`. It keeps the current view opened in the background and opens the new route in a new frame. Use the {@link #goBack goBack()} function to navigate back. You can use this feature across different levels. Preserved views are discarded as soon as the standard {@link #navigate navigate()} function is used instead of {@link #goBack goBack()}.
Expand Down Expand Up @@ -336,7 +336,7 @@

/** @lends linkManager */
/**
* Checks if the path you can navigate to exists in the main application. For example, you can use this helper method conditionally display a DOM element like a button.
* Checks if the path you can navigate to exists in the main application. For example, you can use this helper method conditionally to display a DOM element like a button.
* @param {string} path path which existence you want to check
* @returns {promise} A promise which resolves to a Boolean variable specifying whether the path exists or not.
* @example
Expand Down Expand Up @@ -431,6 +431,16 @@
*/
removeBackdrop: function removeBackdrop() {
window.parent.postMessage({ msg: 'luigi.remove-backdrop' }, '*');
},
/**
* This method informs the main application that the current view in the iframe has unsaved changes, like for example a view with form fields which have been edited but not yet submitted.
* @param {boolean} isDirty tells if the current page or component has any unsaved changes at the moment
*/
setDirtyStatus: function setDirtyStatus(isDirty) {
window.parent.postMessage(
{ msg: 'luigi.set-page-dirty', dirty: isDirty },
'*'
);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,5 +229,59 @@ describe('Luigi client features', () => {
cy.get('.spinnerContainer .fd-spinner').should('not.exist');
});
});
it("Unsaved changes - shouldn't proceed when 'No' was pressed in modal", () => {
cy.get('iframe').then($iframe => {
const $iframeBody = $iframe.contents().find('body');

cy.wrap($iframeBody)
.find('[data-cy=toggle-dirty-state]')
.check();

cy.get('button')
.contains('Projects')
.click();

cy.get('[data-cy=confirmation-modal]').should('be.visible');

cy.location().should(loc => {
expect(loc.pathname).to.eq('/overview'); //the location is unchanged
});

cy.get('[data-cy=modal-no]').click();

cy.get('[data-cy=confirmation-modal]').should('not.be.visible');

cy.location().should(loc => {
expect(loc.pathname).to.eq('/overview'); //the location is still unchanged after "No" clicked
});
});
});
it("Unsaved changes - should proceed when 'Yes' was pressed in modal", () => {
cy.get('iframe').then($iframe => {
const $iframeBody = $iframe.contents().find('body');

cy.wrap($iframeBody)
.find('[data-cy=toggle-dirty-state]')
.check();

cy.get('button')
.contains('Projects')
.click();

cy.get('[data-cy=confirmation-modal]').should('be.visible');

cy.location().should(loc => {
expect(loc.pathname).to.eq('/overview'); //the location is unchanged
});

cy.get('[data-cy=modal-yes]').click();

cy.get('[data-cy=confirmation-modal]').should('not.be.visible');

cy.location().should(loc => {
expect(loc.pathname).to.eq('/projects'); //the location is changed after "Yes" clicked
});
});
});
});
});
Original file line number Diff line number Diff line change
@@ -1,36 +1,58 @@
<header class="fd-page__header">
<div class="fd-action-bar">
<div class="fd-action-bar__header">
<h1 class="fd-action-bar__title">
Luigi Angular Example
</h1>
<p class="fd-action-bar__description">Follow the links below to the Luigi feature demos.</p>
</div>
</div>
<div class="fd-action-bar">
<div class="fd-action-bar__header">
<h1 class="fd-action-bar__title">
Luigi Angular Example
</h1>
<p class="fd-action-bar__description">Follow the links below to the Luigi feature demos.</p>
</div>
</div>
</header>

<section class="fd-section">
<div class="fd-section__header">
<h1 class="fd-section__title">LuigiClient Features</h1>
</div>
<div class="fd-panel">
<ul class="fd-list-group">
<li class="fd-list-group__item clickable" *ngFor="let item of luigiClientLinks" (click)="luigiClient.linkManager().navigate(item.link)">
<strong>{{item.text}}</strong> &nbsp;&ndash; {{item.description}}
</li>
</ul>
</div>
<div class="fd-section__header">
<h1 class="fd-section__title">LuigiClient Features</h1>
</div>
<div class="fd-panel">
<ul class="fd-list-group">
<li class="fd-list-group__item clickable" *ngFor="let item of luigiClientLinks" (click)="luigiClient.linkManager().navigate(item.link)">
<strong>{{item.text}}</strong> &nbsp;&ndash; {{item.description}}
</li>
</ul>
</div>
</section>

<section class="fd-section">
<div class="fd-section__header">
<h1 class="fd-section__title">Luigi Core Features</h1>
</div>
<div class="fd-panel">
<ul class="fd-list-group">
<li class="fd-list-group__item clickable" *ngFor="let item of luigiCoreLinks" (click)="luigiClient.linkManager().navigate(item.link)">
<strong>{{item.text}}</strong> &nbsp;&ndash; {{item.description}}
</li>
</ul>
</div>
</section>
<div class="fd-section__header">
<h1 class="fd-section__title">Luigi Core Features</h1>
</div>
<div class="fd-panel">
<ul class="fd-list-group">
<li class="fd-list-group__item clickable" *ngFor="let item of luigiCoreLinks" (click)="luigiClient.linkManager().navigate(item.link)">
<strong>{{item.text}}</strong> &nbsp;&ndash; {{item.description}}
</li>
<li class="fd-list-group__item ">
<div class="fd-form__item fd-form__item--check">
<label class="fd-form__label" for="ImBw4551">
<span class="fd-toggle fd-toggle--xs fd-form__control">
<input type="checkbox" [(ngModel)]="isDirty" (change)="sendDirtyEvent()" id="ImBw4551" data-cy="toggle-dirty-state" >
<span class="fd-toggle__switch" role="presentation"></span>
</span>

</label>
</div>
<span *ngIf="!isDirty">
<strong>There are no unsaved changes</strong>
&nbsp;&ndash; toggle this to be asked for confirmation when you leave this page
</span>
<span *ngIf="isDirty">
<strong>There are unsaved changes</strong>
&nbsp;&ndash; a confirmation modal will appear when you navigate
<a title="Navigate to /projects/pr2 as an example" (click)="luigiClient.linkManager().navigate('/projects/pr2')">
somewhere else
</a>
</span>
</li>
</ul>
</div>
</section>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
import LuigiClient from '@kyma-project/luigi-client';

@Component({
Expand Down Expand Up @@ -57,4 +57,9 @@ export class OverviewComponent {
description: 'navigation node configuration to redirect to another path'
}
];

private isDirty: boolean = false;
private sendDirtyEvent = () => {
maxmarkus marked this conversation as resolved.
Show resolved Hide resolved
LuigiClient.uxManager().setDirtyStatus(this.isDirty);
};
}
Loading