diff options
author | diosmosis <diosmosis@users.noreply.github.com> | 2018-08-07 01:20:32 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-07 01:20:32 +0300 |
commit | 2e006803ee17a8d1a992085c6425eddaa84a25f5 (patch) | |
tree | 6798441780992ff6e1b3010aa98519c2c2af1f5b /plugins/CoreHome/javascripts | |
parent | bb1b1b4b068fc40da896e7eedbad3b2914dc2468 (diff) |
Scalable UX for user management (#13158)
* Create empty components.
* Mock up users list pagination.
* Finish initial version of mockup.
* Tweak to UI
* More UI changes to new users manager screen.
* More UI changes
* Mock up user permission edits.
* More tweaks to user permission editing (on both edit form & in users table).
* add options
* Another iteration on the UsersManager UI.
* Update UsersManager UI again.
* Implementing parts of the UI, fixing issue w/ overlapping material selects, creating dropdown directives for dropdown w/ submenu using materializecss, change bulk actions to be dropdown button.
* Merge menu/submenu directives.
* More superuser UI only functionality.
* Fill out more logic of users manager UI + merging extra unneeded components/directives.
* More users manager UI only changes.
* Incomplete API method for new users list page.
* Fill in server side pagination logic w/ tests & generally get to work in UI.
* Make sure selects w/ placeholders can be unset.
* Add loading state to users list + fix pagination issues + resize pagination in case the numbers are large.
* Add last seen time to getUsersPlusAccessLevel() so it displays in UI.
* Add permission edit pagination AJAX query + server side code.
* Add "add access" button to user permission component.
* Change permissions column to role + remove superuser checkbox & merge w/ Role column.
* Delete user + bulk delete functionality.
* Get delete users to work when entire search is selected.
* Ask for confirmation before setting access in users list & implement access change logic.
* Get bulk access functionality on users list to work (w/ tests).
* Fix a bug in user table filtering + get permissions edit search to work.
* Complete logic for permissions edit.
* Change add user workflow so we do not have to save each permission edit in memory before saving whole user.
* Add/edit user functionality.
* Toggle superuser access functionality + some modal fixes.
* in users list display ajax loading notification so counter is not changed visibly before rows are loaded.
* initial review changes, disable functionality when viewing user is not superuser and some UI tweaks.
* Redo top controls for user permission edit and add slide up toast notification for when a site is added.
* Display warning in user permission edit if user has no access at all.
* Do not reload users after going back from user edit form.
* Force giving a new user access to a site when creating a user and make sure user list reloads if a user is modified, but does not realod if no user is modified.
* Add form help to the non-straightforward fields.
* Remove old usersmanager code & fix pagination bug.
* Add help icon explaining roles to users list + permission edit.
* Allow admin users to create other users + fix some regressions when making page-users-list not reload every time.
* Apply self review changes.
* Do not allow editing user details when an admin user edits a user.
* Starting on UI tests.
* Limit users displayed in page list to those that already have access to sites the current user is an admin of.
* Refactor bulk/single AJAX calls & redraw component boundaries (users manager component owns user search state, paged users list owns table/control state).
* Get add existing user modal to work.
* write most UI tests + modify fixture
* Fill out rest of UI test suite & get the rest to pass.
* fix couple regressions
* Get UI tests to pass and start on translation.
* adding translations
* try to fix some tests
* Fixing API tests.
* Fixing UsersManager tests.
* Fix UI tests.
* Add capabilities to new API output.
* remove non-existant file references.
* Add Write role to dropdowns.
* Select from proper join.
* tweak test
* Updating UI tests.
* Change styling of user permissions edit.
* Update screenshots
* Apply some PR feedback.
* apply some review feedback
* more review changes
* update file headers
* remove some TODOs
* fix some tests
* some more review fixes
* update test files
* Fix failing tests.
Diffstat (limited to 'plugins/CoreHome/javascripts')
-rw-r--r-- | plugins/CoreHome/javascripts/notification.js | 92 |
1 files changed, 80 insertions, 12 deletions
diff --git a/plugins/CoreHome/javascripts/notification.js b/plugins/CoreHome/javascripts/notification.js index b5dbceaee6..f0563c203e 100644 --- a/plugins/CoreHome/javascripts/notification.js +++ b/plugins/CoreHome/javascripts/notification.js @@ -41,14 +41,8 @@ * wherever you want. */ Notification.prototype.show = function (message, options) { - if (!message) { - throw new Error('No message given, cannot display notification'); - } - if (options && !$.isPlainObject(options)) { - throw new Error('Options has the wrong format, cannot display notification'); - } else if (!options) { - options = {}; - } + checkMessage(message); + options = checkOptions(options); var template = generateNotificationHtmlMarkup(options, message); this.$node = placeNotification(template, options); @@ -70,6 +64,59 @@ } }; + /** + * Shows a notification at a certain point with a quick upwards animation. + * + * TODO: if the materializecss version matomo uses is updated, should use their toasts. + * + * @type {Notification} + * @param {string} message The actual message that will be displayed. Must be set. + * @param {Object} options + * @param {string} options.placeat Where to place the notification. Required. + * @param {string} [options.id] Only needed for persistent notifications. The id will be sent to the + * frontend once the user closes the notifications. The notification has to + * be registered/notified under this name + * @param {string} [options.title] The title of the notification. For instance the plugin name. + * @param {string} [options.context=warning] Context of the notification: 'info', 'warning', 'success' or + * 'error' + * @param {string} [options.type=transient] The type of the notification: Either 'toast' or 'transitent' + * @param {bool} [options.noclear=false] If set, the close icon is not displayed. + * @param {object} [options.style] Optional style/css dictionary. For instance {'display': 'inline-block'} + */ + Notification.prototype.toast = function (message, options) { + checkMessage(message); + options = checkOptions(options); + + var $placeat = $(options.placeat); + if (!$placeat.length) { + throw new Error("A valid selector is required for the placeat option when using Notification.toast()."); + } + + var $template = $(generateNotificationHtmlMarkup(options, message)).hide(); + $('body').append($template); + + compileNotification($template); + + $template.css({ + position: 'absolute', + left: $placeat.offset().left, + top: $placeat.offset().top + }); + setTimeout(function () { + $template.animate( + { + top: $placeat.offset().top - $template.height() + }, + { + duration: 300, + start: function () { + $template.show(); + } + } + ); + }); + }; + exports.Notification = Notification; function generateNotificationHtmlMarkup(options, message) { @@ -78,7 +125,9 @@ title: 'notification-title', context: 'context', type: 'type', - noclear: 'noclear' + noclear: 'noclear', + class: 'class', + toastLength: 'toast-length' }, html = '<div piwik-notification'; @@ -95,13 +144,17 @@ return html; } + function compileNotification($node) { + angular.element(document).injector().invoke(function ($compile, $rootScope) { + $compile($node)($rootScope.$new(true)); + }); + } + function placeNotification(template, options) { var $notificationNode = $(template); // compile the template in angular - angular.element(document).injector().invoke(function ($compile, $rootScope) { - $compile($notificationNode)($rootScope.$new(true)); - }); + compileNotification($notificationNode); if (options.style) { $notificationNode.css(options.style); @@ -133,4 +186,19 @@ return $notificationNode; } + function checkMessage(message) { + if (!message) { + throw new Error('No message given, cannot display notification'); + } + } + + function checkOptions(options) { + if (options && !$.isPlainObject(options)) { + throw new Error('Options has the wrong format, cannot display notification'); + } else if (!options) { + options = {}; + } + return options; + } + })(jQuery, require);
\ No newline at end of file |