Skip to content

Commit

Permalink
chore(permissions): updates
Browse files Browse the repository at this point in the history
  • Loading branch information
polonel committed Feb 17, 2019
1 parent 479c23f commit 0a8f0cb
Show file tree
Hide file tree
Showing 25 changed files with 697 additions and 176 deletions.
6 changes: 5 additions & 1 deletion src/client/actions/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ import {
CHANGE_DELETED_TICKETS_PAGE,
BACKUP_NOW,
RESTORE_DELETED_TICKET,
UPDATE_PERMISSIONS
UPDATE_PERMISSIONS,
CREATE_ROLE,
DELETE_ROLE
} from './types'

export const fetchSettings = createAction(FETCH_SETTINGS.ACTION)
Expand All @@ -49,4 +51,6 @@ export const restoreDeletedTicket = createAction(RESTORE_DELETED_TICKET.ACTION)
export const changeDeletedTicketsPage = createAction(CHANGE_DELETED_TICKETS_PAGE.ACTION, pageIndex => ({
pageIndex
}))
export const createRole = createAction(CREATE_ROLE.ACTION)
export const updatePermissions = createAction(UPDATE_PERMISSIONS.ACTION)
export const deleteRole = createAction(DELETE_ROLE.ACTION)
2 changes: 2 additions & 0 deletions src/client/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ export const FETCH_DELETED_TICKETS = defineAction('FETCH_DELETED_TICKETS', [PEND
export const RESTORE_DELETED_TICKET = defineAction('RESTORE_DELETED_TICKET', [SUCCESS, ERROR])
export const CHANGE_DELETED_TICKETS_PAGE = defineAction('CHANGE_DELETED_TICKETS_PAGE')
export const UPDATE_PERMISSIONS = defineAction('UPDATE_PERMISSIONS', [PENDING, SUCCESS, ERROR])
export const CREATE_ROLE = defineAction('CREATE_ROLE', [SUCCESS, ERROR])
export const DELETE_ROLE = defineAction('DELETE_ROLE', [SUCCESS, ERROR])
10 changes: 10 additions & 0 deletions src/client/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,16 @@ api.settings.updatePermissions = payload => {
return res.data
})
}
api.settings.createRole = ({ name }) => {
return axios.post('/api/v1/roles', { name }).then(res => {
return res.data
})
}
api.settings.deleteRole = ({ _id, newRoleId }) => {
return axios.delete(`/api/v1/roles/${_id}`, { data: { newRoleId } }).then(res => {
return res.data
})
}

api.common = {}
api.common.fetchRoles = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class SplitSettingsPanel extends React.Component {
<div className='uk-grid uk-grid-collapse'>
<div
className='split-panel-categories uk-width-1-4 scrollable br'
style={{ minHeight: '300px', maxHeight: '2000px', overflow: 'hidden auto' }}
style={{ minHeight: '300px', overflow: 'hidden auto' }}
>
<Menu hideBorders={true} draggable={this.props.menuDraggable} onMenuDrag={this.props.menuOnDrag}>
{menuItems.map(item => {
Expand Down
84 changes: 84 additions & 0 deletions src/client/containers/Modals/CreateRoleModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* . .o8 oooo
* .o8 "888 `888
* .o888oo oooo d8b oooo oooo .oooo888 .ooooo. .oooo.o 888 oooo
* 888 `888""8P `888 `888 d88' `888 d88' `88b d88( "8 888 .8P'
* 888 888 888 888 888 888 888ooo888 `"Y88b. 888888.
* 888 . 888 888 888 888 888 888 .o o. )88b 888 `88b.
* "888" d888b `V88V"V8P' `Y8bod88P" `Y8bod8P' 8""888P' o888o o888o
* ========================================================================
* Author: Chris Brame
* Updated: 2/16/19 4:29 PM
* Copyright (c) 2014-2019. All rights reserved.
*/

import React from 'react'
import PropTypes from 'prop-types'
import { observer } from 'mobx-react'
import { observable } from 'mobx'
import { connect } from 'react-redux'

import { createRole } from 'actions/settings'

import Button from 'components/Button'
import BaseModal from './BaseModal'

@observer
class CreateRoleModal extends React.Component {
@observable name = ''

onNameChange (e) {
this.name = e.target.value
}

onCreateRoleClicked (e) {
e.preventDefault()

this.props.createRole({ name: this.name })
}

render () {
return (
<BaseModal>
<div className={'uk-form-stacked'}>
<div>
<h2 className={'nomargin mb-5'}>Create Role</h2>
<p className='uk-text-muted'>Once created, the role will become editable in the permission editor</p>

<label>Role Name</label>
<input
type='text'
className={'md-input'}
name={'name'}
data-validation='length'
data-validation-length='min3'
data-validation-error-msg='Please enter a valid role name. Role name must contain at least 3 characters.'
value={this.name}
onChange={e => this.onNameChange(e)}
/>
</div>
<div className='uk-modal-footer uk-text-right'>
<Button text={'Close'} extraClass={'uk-modal-close'} flat={true} waves={true} />
<Button
text={'Create'}
type={'button'}
flat={true}
waves={true}
style={'success'}
onClick={e => this.onCreateRoleClicked(e)}
/>
</div>
</div>
</BaseModal>
)
}
}

CreateRoleModal.propTypes = {
createRole: PropTypes.func.isRequired
}

export default connect(
null,
{ createRole }
)(CreateRoleModal)
108 changes: 108 additions & 0 deletions src/client/containers/Modals/DeleteRoleModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* . .o8 oooo
* .o8 "888 `888
* .o888oo oooo d8b oooo oooo .oooo888 .ooooo. .oooo.o 888 oooo
* 888 `888""8P `888 `888 d88' `888 d88' `88b d88( "8 888 .8P'
* 888 888 888 888 888 888 888ooo888 `"Y88b. 888888.
* 888 . 888 888 888 888 888 888 .o o. )88b 888 `88b.
* "888" d888b `V88V"V8P' `Y8bod88P" `Y8bod8P' 8""888P' o888o o888o
* ========================================================================
* Author: Chris Brame
* Updated: 2/16/19 5:49 PM
* Copyright (c) 2014-2019. All rights reserved.
*/

import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { observer } from 'mobx-react'
import { observable } from 'mobx'

import { deleteRole } from 'actions/settings'

import BaseModal from './BaseModal'
import Button from 'components/Button'
import SingleSelect from 'components/SingleSelect'

@observer
class DeleteRoleModal extends React.Component {
@observable selectedRole = ''

onSelectChanged (e) {
this.selectedRole = e.target.value
}

onFormSubmit (e) {
e.preventDefault()

this.props.deleteRole({ _id: this.props.role.get('_id'), newRoleId: this.selectedRole })
}

render () {
const { role } = this.props
const mappedRoles = this.props.shared.roles
.filter(obj => {
return obj.get('_id') !== role.get('_id')
})
.map(r => {
return { text: r.get('name'), value: r.get('_id') }
})
.toArray()
return (
<BaseModal {...this.props} options={{ bgclose: false }}>
<form className={'uk-form-stacked'} onSubmit={e => this.onFormSubmit(e)}>
<div className='uk-margin-medium-bottom uk-clearfix'>
<h2>Remove Role</h2>
<span>Please select the role you wish to assign ALL users to</span>
{/*<hr style={{ margin: '10px 0' }} />*/}
</div>
<div className='uk-margin-medium-bottom uk-clearfix'>
<div className='uk-float-left' style={{ width: '100%' }}>
<label className={'uk-form-label nopadding nomargin'}>Type</label>
<SingleSelect
showTextbox={false}
items={mappedRoles}
onSelectChange={e => this.onSelectChanged(e)}
value={this.selectedRole}
/>
</div>
</div>
<div className='uk-margin-medium-bottom uk-clearfix'>
<span className='uk-text-danger'>
WARNING: This will change all accounts with role <strong>{role.get('name')}</strong> to the selected role
above.
{role.get('isAdmin') && (
<span className={'uk-text-danger'}>
The role you are about to remove is an admin role. Please ensure there is another Admin role or you
could be locked out!
</span>
)}
<br />
<br />
<strong style={{ fontSize: '18px' }}>This is permanent!</strong>
</span>
</div>
<div className='uk-modal-footer uk-text-right'>
<Button text={'Cancel'} flat={true} waves={true} extraClass={'uk-modal-close'} />
<Button text={'Delete'} style={'danger'} flat={true} type={'submit'} />
</div>
</form>
</BaseModal>
)
}
}

DeleteRoleModal.propTypes = {
role: PropTypes.object,
deleteRole: PropTypes.func.isRequired,
shared: PropTypes.object.isRequired
}

const mapStateToProps = state => ({
shared: state.shared
})

export default connect(
mapStateToProps,
{ deleteRole }
)(DeleteRoleModal)
8 changes: 6 additions & 2 deletions src/client/containers/Modals/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import AddPriorityToTypeModal from './AddPriorityToTypeModal'
import CreatePriorityModal from './CreatePriorityModal'
import DeletePriorityModal from './DeletePriorityModal'
import CreateTagModal from './CreateTagModal'
import CreateTicketModal from 'containers/Modals/CreateTicketModal'
import CreateTicketModal from './CreateTicketModal'
import CreateRoleModal from './CreateRoleModal'
import DeleteRoleModal from './DeleteRoleModal'

const MODAL_COMPONENTS = {
CREATE_TICKET: CreateTicketModal,
Expand All @@ -32,7 +34,9 @@ const MODAL_COMPONENTS = {
ADD_PRIORITY_TO_TYPE: AddPriorityToTypeModal,
CREATE_PRIORITY: CreatePriorityModal,
DELETE_PRIORITY: DeletePriorityModal,
CREATE_TAG: CreateTagModal
CREATE_TAG: CreateTagModal,
CREATE_ROLE: CreateRoleModal,
DELETE_ROLE: DeleteRoleModal
}

const ModalRoot = ({ modalType, modalProps }) => {
Expand Down
23 changes: 19 additions & 4 deletions src/client/containers/Settings/Permissions/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'

import { fetchRoles, updateRoleOrder } from 'actions/common'
import { showModal, fetchRoles, updateRoleOrder } from 'actions/common'

import Button from 'components/Button'
import SplitSettingsPanel from 'components/Settings/SplitSettingsPanel'
Expand Down Expand Up @@ -51,14 +51,28 @@ class PermissionsSettingsContainer extends React.Component {
return []
}

onCreateRoleClicked (e) {
e.preventDefault()

this.props.showModal('CREATE_ROLE')
}

render () {
return (
<div className={this.props.active ? '' : 'hide'}>
<SplitSettingsPanel
title={'Permissions'}
tooltip={'Permission order is top down. ex: Admins at top; Users at bottom.'}
subtitle={'Create/Modify Role Permissions'}
rightComponent={<Button text={'Create'} style={'success'} flat={true} waves={true} />}
rightComponent={
<Button
text={'Create'}
style={'success'}
flat={true}
waves={true}
onClick={e => this.onCreateRoleClicked(e)}
/>
}
menuItems={this.getRoleMenu().map(role => {
return { key: role.get('_id'), title: role.get('name'), bodyComponent: <PermissionBody role={role} /> }
})}
Expand All @@ -77,7 +91,8 @@ PermissionsSettingsContainer.propTypes = {
roles: PropTypes.object.isRequired,
roleOrder: PropTypes.object.isRequired,
fetchRoles: PropTypes.func.isRequired,
updateRoleOrder: PropTypes.func.isRequired
updateRoleOrder: PropTypes.func.isRequired,
showModal: PropTypes.func.isRequired
}

const mapStateToProps = state => ({
Expand All @@ -87,5 +102,5 @@ const mapStateToProps = state => ({

export default connect(
mapStateToProps,
{ fetchRoles, updateRoleOrder }
{ fetchRoles, updateRoleOrder, showModal }
)(PermissionsSettingsContainer)
Loading

0 comments on commit 0a8f0cb

Please sign in to comment.