diff options
| author | Christian Weiske <cweiske@cweiske.de> | 2014-10-13 20:41:30 +0200 |
|---|---|---|
| committer | Christian Weiske <cweiske@cweiske.de> | 2014-10-13 20:41:30 +0200 |
| commit | ca442a803832c885af7835c5fcf7cd48cfe752ce (patch) | |
| tree | d58b2eb4e70223d56e981cd4c03cc8a331d67f40 | |
| parent | dab31d3882a398d5f459a0aca71b2e35ab641708 (diff) | |
| download | grauphel-ca442a803832c885af7835c5fcf7cd48cfe752ce.tar.gz grauphel-ca442a803832c885af7835c5fcf7cd48cfe752ce.zip | |
Token deletion with simple undo
Following the lines of
- http://alistapart.com/article/neveruseawarning
- https://github.com/owncloud/core/issues/9268
- https://github.com/owncloud/contacts/issues/107
I've added simple undo functionality to the "delete token" action.
The user has 5 seconds to click on the "restore" button to undo the
token deletion.
| -rw-r--r-- | js/grauphel.js | 126 | ||||
| -rw-r--r-- | templates/tokens.php | 11 |
2 files changed, 134 insertions, 3 deletions
diff --git a/js/grauphel.js b/js/grauphel.js new file mode 100644 index 0000000..d28e6c3 --- /dev/null +++ b/js/grauphel.js @@ -0,0 +1,126 @@ +/** + * Undo + * + * Single action: + * 1. User clicks "delete" + * 2. Notification appears for 5 seconds + * 3. Token row is faded out + * 4a User clicks on notification: + * - Action is cancelled + * - Token row is faded in + * 4b User does not click on notification: + * - Action gets executed 5 seconds after the delete click + * - Token row gets removed + * + * + * Multiple actions: + * 1. User clicks "delete" + * 2. Notification appears for 5 seconds + * 3. User clicks "delete" + * 4. Notification appears for 5 seconds + * 5a User clicks on notification: All pending actions are cancelled + * 5b User does not click on notification + * - Action 1 gets executed 5 seconds after the first click + * - Action 2 gets executed 5 seconds after the second click + */ +OC.grauphel = { + simpleUndo: function(undoTask) { + var notifier = $('#notification'); + var timeout = 5; + notifier.off('click'); + notifier.text('Token has been deleted. Click to undo.'); + notifier.fadeIn(); + + $('#' + undoTask.elementId).fadeOut(); + + OC.grauphel.startGuiTimer(timeout, notifier); + var timer = setTimeout( + function() { + var dataid = timer.toString(); + OC.grauphel.executeTask(notifier.data(dataid), true); + notifier.removeData(dataid); + }, + timeout * 1000 + ); + var dataid = timer.toString(); + notifier.data(dataid, undoTask); + + notifier.on('click', function() { + for (var id in notifier.data()) { + clearTimeout(parseInt(id)); + notifier.off('click'); + OC.grauphel.restore(notifier.data(id)); + notifier.removeData(id); + } + }); + }, + + executeTask: function(task, async) { + //console.log("execute task: ", task); + jQuery.ajax({ + url: task.url, + type: task.method, + async: async + }); + }, + + restore: function(undoTask) { + $('#' + undoTask.elementId).fadeIn(); + + var notifier = $('#notification'); + var timeout = 5; + notifier.off('click'); + notifier.text('Token has been restored.'); + + OC.grauphel.startGuiTimer(timeout, notifier); + notifier.on('click', function() { + clearTimeout(OC.grauphel.guiTimer); + notifier.fadeOut(); + }); + }, + + executeAllTasks: function() { + var notifier = $('#notification'); + for (var id in notifier.data()) { + clearTimeout(parseInt(id)); + OC.grauphel.executeTask(notifier.data(id), false); + notifier.removeData(id); + } + }, + + guiTimer: null, + + startGuiTimer: function(timeout, notifier) { + if (OC.grauphel.guiTimer !== null) { + clearTimeout(OC.grauphel.guiTimer); + } + OC.grauphel.guiTimer = setTimeout( + function() { + notifier.fadeOut(); + notifier.off('click'); + }, + timeout * 1000 + ); + } +}; + +$(document).ready(function() { + $('#grauphel-tokens .delete').click( + function (event) { + event.preventDefault(); + + var undoTask = { + 'method': 'DELETE', + 'url': $(this).parent('form').attr('action'), + 'elementId': $(this).data('token') + }; + OC.grauphel.simpleUndo(undoTask); + return false; + } + ); + + //in case a user deletes tokens and leaves the page within the 5 seconds + window.onbeforeunload = function(e) { + OC.grauphel.executeAllTasks(); + }; +}); diff --git a/templates/tokens.php b/templates/tokens.php index 9c1da6d..3aaabb7 100644 --- a/templates/tokens.php +++ b/templates/tokens.php @@ -3,6 +3,8 @@ <?php /** @var $l OC_L10N */ ?> <?php $_['appNavigation']->printPage(); ?> +<script type="text/javascript" src="<?php p(OCP\Util::linkTo('grauphel','js/grauphel.js')); ?>"></script> + <div id="app-content" class="list"> <h1>Manage access tokens</h1> <p> @@ -10,7 +12,7 @@ You can permanently revoke access by clicking the "delete" icon on the right side of each token row. </p> - <table class="table"> + <table class="table" id="grauphel-tokens"> <thead> <tr> <th>Token</th> @@ -20,14 +22,17 @@ </thead> <tbody> <?php foreach ($_['tokens'] as $token) { ?> - <tr> + <tr id="token-<?php p($token->tokenKey); ?>"> <td><?php p($token->tokenKey); ?></td> <td title="<?php p($token->client); ?>"><?php p($_['client']->getNiceName($token->client)); ?></td> <td> <?php p(\OCP\Util::formatDate($token->lastuse)); ?> <form method="POST" action="<?php p(OCP\Util::linkToRoute('grauphel.token.delete', array('username' => $_['username'], 'tokenKey' => $token->tokenKey))); ?>"> <input type="hidden" name="delete" value="1" /> - <button type="submit" class="icon-delete delete action" original-title="Delete"/> + <button type="submit" class="icon-delete delete action" + original-title="Delete" + data-token="token-<?php p($token->tokenKey); ?>" + /> </form> </td> </tr> |
