From 21abed7f9a44831b1c5da12b2ad66e210de9c01a Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Tue, 29 Jul 2014 18:11:02 -0600 Subject: [PATCH] Add User Role Dropdown Closes #3402, Closes #3428 ------------------- ### Components - Added GhostSelectComponent to handle async select creation (h/t @rwjblue) - Added GhostRolesSelector (extends GhostSelect) for displaying user role options - Created StoreInjector for surgically inserting the store into things that normally wouldn't have them. ### Users Settings - InviteNewUserModal now uses GhostRolesSelector & defaults to Author - The role dropdown for user settings has permissions set per 3402 ### User Model - Added `role` property as an interface to getting and setting `roles` - Refactored anything that set `roles` to set `role` - isAdmin, isAuthor, isOwner and isEditor are all keyed off of `role` now ### Tests - Added functional tests for Settings.Users - updated settings.users and settings.users.user screens - fix spacing on screens ### Server Fixtures - Fixed owner fixture's roles --- Gruntfile.js | 4 +- core/client/components/gh-role-selector.js | 13 ++ core/client/components/gh-select.js | 69 +++++++++++ .../controllers/modals/invite-new-user.js | 50 +++----- .../client/controllers/settings/users/user.js | 10 +- core/client/initializers/store-injector.js | 10 ++ core/client/models/user.js | 20 +-- .../templates/components/gh-role-selector.hbs | 5 + .../templates/modals/invite-new-user.hbs | 14 +-- core/client/templates/settings/users/user.hbs | 23 ++-- core/client/views/settings/users/user.js | 13 ++ core/test/functional/base.js | 117 +++++++++--------- core/test/functional/client/settings_test.js | 47 ++++++- 13 files changed, 264 insertions(+), 131 deletions(-) create mode 100644 core/client/components/gh-role-selector.js create mode 100644 core/client/components/gh-select.js create mode 100644 core/client/initializers/store-injector.js create mode 100644 core/client/templates/components/gh-role-selector.hbs create mode 100644 core/client/views/settings/users/user.js diff --git a/Gruntfile.js b/Gruntfile.js index b2f7d28a8cd9..307e7bc3fcf6 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -748,9 +748,9 @@ var path = require('path'), // // You can use the `--target` argument to run any individual test file, or the admin or frontend tests: // - // `grunt test-functional --target=admin/editor_test.js` - run just the editor tests + // `grunt test-functional --target=client/editor_test.js` - run just the editor tests // - // `grunt test-functional --target=admin/` - run all of the tests in the admin directory + // `grunt test-functional --target=client/` - run all of the tests in the client directory // // Functional tests are run with [phantom.js](http://phantomjs.org/) and defined using the testing api from // [casper.js](http://docs.casperjs.org/en/latest/testing.html). diff --git a/core/client/components/gh-role-selector.js b/core/client/components/gh-role-selector.js new file mode 100644 index 000000000000..e08f94213f51 --- /dev/null +++ b/core/client/components/gh-role-selector.js @@ -0,0 +1,13 @@ +import GhostSelect from 'ghost/components/gh-select'; + +var RolesSelector = GhostSelect.extend({ + roles: Ember.computed.alias('options'), + options: Ember.computed(function () { + var rolesPromise = this.store.find('role', { permissions: 'assign' }); + + return Ember.ArrayProxy.extend(Ember.PromiseProxyMixin) + .create({promise: rolesPromise}); + }) +}); + +export default RolesSelector; diff --git a/core/client/components/gh-select.js b/core/client/components/gh-select.js new file mode 100644 index 000000000000..c085adea8951 --- /dev/null +++ b/core/client/components/gh-select.js @@ -0,0 +1,69 @@ +//GhostSelect is a solution to Ember.Select being evil and worthless. +// (Namely, this solves problems with async data in Ember.Select) +//Inspired by (that is, totally ripped off from) this JSBin +//http://emberjs.jsbin.com/rwjblue/40/edit + +//Usage: +//Extend this component and create a template for your component. +//Your component must define the `options` property. +//Optionally use `initialValue` to set the object +// you want to have selected to start with. +//Both options and initalValue are promise safe. +//Set onChange in your template to be the name +// of the action you want called in your +//For an example, see gh-roles-selector + +var GhostSelect = Ember.Component.extend({ + tagName: 'span', + classNames: ['gh-select'], + + options: null, + initialValue: null, + + resolvedOptions: null, + resolvedInitialValue: null, + + //Convert promises to their values + init: function () { + var self = this; + this._super.apply(this, arguments); + + Ember.RSVP.hash({ + resolvedOptions: this.get('options'), + resolvedInitialValue: this.get('initialValue') + }).then(function (resolvedHash) { + self.setProperties(resolvedHash); + + //Run after render to ensure the