Skip to content
This repository has been archived by the owner on May 19, 2020. It is now read-only.

Commit

Permalink
Create the space check and remove handling
Browse files Browse the repository at this point in the history
  • Loading branch information
rememberlenny committed Jul 25, 2017
2 parents 1c9a47d + a0bec59 commit ff7fe55
Show file tree
Hide file tree
Showing 14 changed files with 374 additions and 319 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"build-style": "cd node_modules/cloudgov-style && npm install && npm run build",
"check-style": "/bin/bash -c '[[ $(npm ls cloudgov-style) =~ \"git://github.com\" ]] && npm run build-style || exit 0'",
"clean": "rm -rf ./static/assets/*",
"dev-start": "cf dev start && docker-compose up -d app frontend watch",
"dev-stop": "cf dev stop && docker-compose stop",
"lint": "eslint --ext .js --ext .jsx ./static_src",
"test": "npm run lint && npm run test-unit && npm run test-functional",
"test-functional": "NODE_ENV=test npm run testing-server-run -- wdio wdio.conf.js",
Expand Down
75 changes: 40 additions & 35 deletions static_src/actions/user_actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ const userActions = {

addUserRoles(roles, apiKey, userGuid, entityGuid, entityType) {
const apiMethodMap = {
org: cfApi.putOrgUserPermissions,
organization: cfApi.putOrgUserPermissions,
space: cfApi.putSpaceUserPermissions
};
const api = apiMethodMap[entityType];
Expand Down Expand Up @@ -186,7 +186,7 @@ const userActions = {

deleteUserRoles(roles, apiKey, userGuid, entityGuid, entityType) {
const apiMethodMap = {
org: cfApi.deleteOrgUserPermissions,
organization: cfApi.deleteOrgUserPermissions,
space: cfApi.deleteSpaceUserPermissions
};
const api = apiMethodMap[entityType];
Expand Down Expand Up @@ -319,52 +319,55 @@ const userActions = {
},

createUserAndAssociate(userGuid) {
let entityGuid;
const entityType = UserStore.currentlyViewedType;
const orgGuid = OrgStore.currentOrgGuid;
let cfApiRequest;
let entityGuid;

if (entityType === ORG_NAME) {
entityGuid = OrgStore.currentOrgGuid;
entityGuid = orgGuid;
cfApiRequest = cfApi.putAssociateUserToOrganization.bind(cfApi, userGuid, entityGuid);

AppDispatcher.handleViewAction({
type: userActionTypes.USER_ORG_ASSOCIATE,
userGuid,
entityType,
entityGuid
});
} else {
entityGuid = SpaceStore.currentSpaceGuid;
cfApiRequest = cfApi.putAssociateUserToSpace.bind(cfApi, userGuid, orgGuid, entityGuid);
}

AppDispatcher.handleViewAction({
type: userActionTypes.USER_ORG_ASSOCIATE,
userGuid,
entityType,
entityGuid
});

return cfApi.putAssociateUserToEntity(userGuid, entityGuid, entityType)
return cfApiRequest()
.then(() => userActions.fetchEntityUsers(entityGuid, entityType))
.then(entityUsers => userActions.createdUserAndAssociated(userGuid, entityGuid, entityUsers));
.then(entityUsers => {
userActions.createdUserAndAssociated(userGuid, entityGuid, entityUsers, entityType);
});
},

fetchEntityUsers(entityGuid, entityType) {
let entityUsers;
if (entityType === ORG_NAME) {
entityUsers = cfApi.fetchOrgUsers(entityGuid);
} else {
entityUsers = cfApi.fetchSpaceUserRoles(entityGuid);
}
return Promise.resolve(entityUsers);
return cfApi[(entityType === ORG_NAME) ? 'fetchOrgUsers' : 'fetchSpaceUserRoles'](entityGuid);
},

createdUserAndAssociated(userGuid, entityGuid, entityUsers) {
const user = entityUsers.filter((entityUser) => entityUser.guid === userGuid);
createdUserAndAssociated(userGuid, entityGuid, entityUsers, entityType) {
const user = entityUsers.filter(entityUser => entityUser.guid === userGuid)[0];

if (!user[0]) {
if (!user) {
const err = new Error('User was not associated');
const message = `The user ${userGuid} was not associated in ${entityGuid}.`;
return Promise.resolve(userActions.userInviteCreateError(err, message));
}

AppDispatcher.handleViewAction({
type: userActionTypes.USER_ORG_ASSOCIATED,
userGuid,
entityGuid,
user
});
if (entityType === ORG_NAME) {
AppDispatcher.handleViewAction({
type: userActionTypes.USER_ORG_ASSOCIATED,
userGuid,
entityGuid,
user
});
}

return Promise.resolve(user);
},

Expand Down Expand Up @@ -456,12 +459,14 @@ const userActions = {
// TODO add error action
return userActions
.fetchCurrentUserInfo()
.then(userInfo =>
Promise.all([
userActions.fetchUser(userInfo.user_id),
userActions.fetchCurrentUserUaaInfo(userInfo.user_id)
])
)
.then(userInfo => {
const userId = userInfo.user_id;

return Promise.all([
userActions.fetchUser(userId),
userActions.fetchCurrentUserUaaInfo(userId)
]);
})
// Grab user from store with all merged properties
.then(() => UserStore.currentUser)
.then(userActions.receivedCurrentUser);
Expand Down
1 change: 1 addition & 0 deletions static_src/components/user_list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export default class UserList extends React.Component {
</ElasticLineItem>
);
}

return (
<ElasticLine key={ user.guid }>
<ElasticLineItem>{ user.username }</ElasticLineItem>
Expand Down
173 changes: 100 additions & 73 deletions static_src/components/users.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ import UserList from './user_list.jsx';
import UsersInvite from './users_invite.jsx';
import Notification from './notification.jsx';
import UserStore from '../stores/user_store.js';

import ErrorMessage from './error_message.jsx';
import PanelDocumentation from './panel_documentation.jsx';

const propTypes = {};
const SPACE_NAME = SpaceStore.cfName;
const ORG_NAME = OrgStore.cfName;
const ORG_MANAGER = 'org_manager';
const SPACE_MANAGER = 'space_manager';
const ORG_ENTITY = 'organization';
const SPACE_ENTITY = 'space';

function stateSetter() {
const currentOrgGuid = OrgStore.currentOrgGuid;
Expand All @@ -35,15 +40,16 @@ function stateSetter() {
users = UserStore.getAllInSpace(currentSpaceGuid);
entityGuid = currentSpaceGuid;
currentUserAccess = UserStore.hasRole(currentUser.guid, currentSpaceGuid,
'space_manager');
SPACE_MANAGER);
} else {
users = UserStore.getAllInOrg(currentOrgGuid);
entityGuid = currentOrgGuid;
currentUserAccess = UserStore.hasRole(currentUser.guid, currentOrgGuid,
'org_manager');
ORG_MANAGER);
}

return {
currentUser,
error: UserStore.getError(),
inviteDisabled,
currentUserAccess,
Expand All @@ -67,7 +73,7 @@ export default class Users extends React.Component {
this.state = stateSetter();

this._onChange = this._onChange.bind(this);
this.handleRemove = this.handleRemove.bind(this);
this.handleRemoveUser = this.handleRemoveUser.bind(this);
this.handleAddPermissions = this.handleAddPermissions.bind(this);
this.handleRemovePermissions = this.handleRemovePermissions.bind(this);
}
Expand All @@ -86,22 +92,26 @@ export default class Users extends React.Component {
}

handleAddPermissions(roleKey, apiKey, userGuid) {
userActions.addUserRoles(roleKey,
apiKey,
userGuid,
this.entityGuid,
this.entityType);
userActions.addUserRoles(
roleKey,
apiKey,
userGuid,
this.entityGuid,
this.entityType
);
}

handleRemovePermissions(roleKey, apiKey, userGuid) {
userActions.deleteUserRoles(roleKey,
apiKey,
userGuid,
this.entityGuid,
this.entityType);
userActions.deleteUserRoles(
roleKey,
apiKey,
userGuid,
this.entityGuid,
this.entityType
);
}

handleRemove(userGuid, ev) {
handleRemoveUser(userGuid, ev) {
ev.preventDefault();
userActions.deleteUser(userGuid, this.state.currentOrgGuid);
}
Expand All @@ -112,86 +122,103 @@ export default class Users extends React.Component {
}

get entityType() {
return this.state.currentType === ORG_NAME ? 'org' : 'space';
return this.isOrganization ? ORG_ENTITY : SPACE_ENTITY;
}

get isOrganization() {
return this.state.currentType === ORG_NAME;
}

get isSpace() {
return this.state.currentType === SPACE_NAME;
}

get entityGuid() {
const entityGuid = this.state.currentType === ORG_NAME ?
const entityGuid = this.isOrganization ?
this.state.currentOrgGuid : this.state.currentSpaceGuid;
return entityGuid;
}

get currentUserIsOrgManager() {
const { currentUser } = this.state;
const { currentOrgGuid } = OrgStore;

return UserStore.hasRole(currentUser.guid, currentOrgGuid, ORG_MANAGER);
}

get notification() {
const { userListNotices } = this.state;

if (!userListNotices.description) return null;

return (
<Notification
message={ userListNotices.description }
actions={ [] }
onDismiss={ this.onNotificationDismiss }
status="finish"
/>
);
}

get userInvite() {
if (!this.currentUserIsOrgManager) {
const cfAPILink = 'https://cloud.gov/docs/getting-started/setup/#set-up-the-command-line';

return (
<PanelDocumentation>
{`Currently, only an org manager can invite users to this ${this.entityType}
via the dashboard. If the user you want to add is already a cloud.gov member,
you can invite them using the <a href=${cfAPILink}>cloud foundry api. </a>
Speak to your org manager if you need to add a user to this ${this.entityType} who
is not a member of cloud.gov`}
</PanelDocumentation>
);
}

return (
<UsersInvite
inviteEntityType={ this.entityType }
inviteDisabled={ this.state.inviteDisabled }
currentUserAccess={ this.state.currentUserAccess }
error={ this.state.userListNoticeError }
/>
);
}

_onChange() {
this.setState(stateSetter());
}

render() {
let removeHandler;

if (this.state.currentType === ORG_NAME) {
removeHandler = this.handleRemove;
} else if (this.state.currentType === SPACE_NAME) {
if (this.isOrganization) {
removeHandler = this.handleRemoveUser;
} else if (this.isSpace) {
removeHandler = this.handleRemoveSpaceRoles;
}

let content = (<UserList
users={ this.state.users }
userType= { this.state.currentType }
entityGuid={ this.state.entityGuid }
currentUserAccess={ this.state.currentUserAccess }
empty={ this.state.empty }
loading={ this.state.loading }
saving={ this.state.isSaving }
onRemove={ removeHandler }
onAddPermissions={ this.handleAddPermissions }
onRemovePermissions={ this.handleRemovePermissions }
/>);

let notification;
let userInvite;

if (this.state.userListNotices.description) {
const notice = this.state.userListNotices;
notification = (
<Notification
message={ notice.description }
actions={ [] }
onDismiss={ this.onNotificationDismiss }
status={ notice.noticeType }
/>
);
} else {
// If there's nothing, let's reset the notification to null.
notification = null;
}

if (this.state.currentType === ORG_NAME) {
userInvite = (
<div className="test-users">
<UsersInvite
inviteDisabled={ this.state.inviteDisabled }
currentUserAccess={ this.state.currentUserAccess }
error={ this.state.userListNoticeError }
/>
</div>
);
}

return (
<div className="test-users">
<ErrorMessage error={this.state.error} />
{ userInvite }
{ notification }
<div>
<div>
{ content }
</div>
</div>
{ this.userInvite }
{ this.notification }
<UserList
users={ this.state.users }
userType= { this.state.currentType }
entityGuid={ this.state.entityGuid }
currentUserAccess={ this.state.currentUserAccess }
empty={ this.state.empty }
loading={ this.state.loading }
saving={ this.state.isSaving }
onRemove={ removeHandler }
onAddPermissions={ this.handleAddPermissions }
onRemovePermissions={ this.handleRemovePermissions }
/>
</div>
);
}
}

Users.propTypes = {};

Users.defaultProps = {};
Users.propTypes = propTypes;
Loading

0 comments on commit ff7fe55

Please sign in to comment.