WiP on permissions
Table of shares per user
This commit is contained in:
parent
89c9615592
commit
89256d62bd
20 changed files with 354 additions and 171 deletions
|
@ -110,19 +110,18 @@ export default class Share extends Component {
|
|||
|
||||
render() {
|
||||
const t = this.props.t;
|
||||
const roles = mailtrainConfig.roles[this.props.entityTypeId];
|
||||
|
||||
const actions = data => [
|
||||
{
|
||||
label: 'Delete',
|
||||
action: () => this.deleteShare(data[4])
|
||||
action: () => this.deleteShare(data[3])
|
||||
}
|
||||
];
|
||||
|
||||
const sharesColumns = [
|
||||
{ data: 1, title: t('Username') },
|
||||
{ data: 2, title: t('Name') },
|
||||
{ data: 3, title: t('Role'), render: data => roles[data] ? roles[data].name : data }
|
||||
{ data: 0, title: t('Username') },
|
||||
{ data: 1, title: t('Name') },
|
||||
{ data: 2, title: t('Role') }
|
||||
];
|
||||
|
||||
|
||||
|
@ -144,13 +143,6 @@ export default class Share extends Component {
|
|||
];
|
||||
|
||||
|
||||
const rolesData = [];
|
||||
for (const key in roles) {
|
||||
const role = roles[key];
|
||||
rolesData.push([ key, role.name, role.description ]);
|
||||
}
|
||||
|
||||
|
||||
if (this.state.entity) {
|
||||
return (
|
||||
<div>
|
||||
|
@ -158,8 +150,8 @@ export default class Share extends Component {
|
|||
|
||||
<h3 className="legend">{t('Add User')}</h3>
|
||||
<Form stateOwner={this} onSubmitAsync={::this.submitHandler}>
|
||||
<TableSelect ref={node => this.usersTableSelect = node} id="userId" label={t('User')} withHeader dropdown dataUrl={`/rest/shares-users-table/${this.props.entityTypeId}/${this.state.entityId}`} columns={usersColumns} selectionLabelIndex={usersLabelIndex}/>
|
||||
<TableSelect id="role" label={t('Role')} withHeader dropdown data={rolesData} columns={rolesColumns} selectionLabelIndex={1}/>
|
||||
<TableSelect ref={node => this.usersTableSelect = node} id="userId" label={t('User')} withHeader dropdown dataUrl={`/rest/shares-unassigned-users-table/${this.props.entityTypeId}/${this.state.entityId}`} columns={usersColumns} selectionLabelIndex={usersLabelIndex}/>
|
||||
<TableSelect id="role" label={t('Role')} withHeader dropdown dataUrl={`/rest/shares-roles-table/${this.props.entityTypeId}`} columns={rolesColumns} selectionLabelIndex={1}/>
|
||||
|
||||
<ButtonRow>
|
||||
<Button type="submit" className="btn-primary" icon="ok" label={t('Share')}/>
|
||||
|
@ -169,7 +161,7 @@ export default class Share extends Component {
|
|||
<hr/>
|
||||
<h3 className="legend">{t('Existing Users')}</h3>
|
||||
|
||||
<Table ref={node => this.sharesTable = node} withHeader dataUrl={`/rest/shares-table/${this.props.entityTypeId}/${this.state.entityId}`} columns={sharesColumns} actions={actions}/>
|
||||
<Table ref={node => this.sharesTable = node} withHeader dataUrl={`/rest/shares-table-by-entity/${this.props.entityTypeId}/${this.state.entityId}`} columns={sharesColumns} actions={actions}/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
|
|
93
client/src/shares/UserShares.js
Normal file
93
client/src/shares/UserShares.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { translate } from 'react-i18next';
|
||||
import { requiresAuthenticatedUser, withPageHelpers, Title } from '../lib/page';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import { Table } from '../lib/table';
|
||||
import axios from '../lib/axios';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@translate()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
export default class UserShares extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.sharesTables = {};
|
||||
|
||||
this.state = {
|
||||
userId: parseInt(props.match.params.id)
|
||||
};
|
||||
}
|
||||
|
||||
@withAsyncErrorHandler
|
||||
async loadEntity() {
|
||||
const response = await axios.get(`/rest/users/${this.state.userId}`);
|
||||
this.setState({
|
||||
username: response.data.username
|
||||
});
|
||||
}
|
||||
|
||||
@withAsyncErrorHandler
|
||||
async deleteShare(entityTypeId, entityId) {
|
||||
const data = {
|
||||
entityTypeId,
|
||||
entityId,
|
||||
userId: this.state.userId
|
||||
};
|
||||
|
||||
await axios.put('/rest/shares', data);
|
||||
for (const key in this.sharesTables) {
|
||||
this.sharesTables[key].refresh();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.loadEntity();
|
||||
}
|
||||
|
||||
render() {
|
||||
const renderSharesTable = (entityTypeId, title) => {
|
||||
const actions = data => {
|
||||
const actions = [];
|
||||
const perms = data[3];
|
||||
|
||||
if (perms.includes('share')) {
|
||||
actions.push({
|
||||
label: 'Delete',
|
||||
action: () => this.deleteShare(entityTypeId, data[2])
|
||||
});
|
||||
}
|
||||
|
||||
return actions;
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ data: 0, title: t('Name') },
|
||||
{ data: 1, title: t('Role') }
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3>{title}</h3>
|
||||
<Table ref={node => this.sharesTables[entityTypeId] = node} withHeader dataUrl={`/rest/shares-table-by-user/${entityTypeId}/${this.state.userId}`} columns={columns} actions={actions}/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const t = this.props.t;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Title>{t('Shares for user "{{username}}"', {username: this.state.username})}</Title>
|
||||
|
||||
{renderSharesTable('namespace', t('Namespaces'))}
|
||||
{renderSharesTable('reportTemplate', t('Report Templates'))}
|
||||
{renderSharesTable('report', t('Reports'))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -24,9 +24,7 @@ export default class CUD extends Component {
|
|||
|
||||
this.passwordValidator = passwordValidator(props.t);
|
||||
|
||||
this.state = {
|
||||
globalRoles: []
|
||||
};
|
||||
this.state = {};
|
||||
|
||||
if (props.edit) {
|
||||
this.state.entityId = parseInt(props.match.params.id);
|
||||
|
@ -49,14 +47,6 @@ export default class CUD extends Component {
|
|||
return this.props.match.params.action === 'delete';
|
||||
}
|
||||
|
||||
@withAsyncErrorHandler
|
||||
async fetchGlobalRoles() {
|
||||
const result = await axios.get('/rest/users-global-roles');
|
||||
this.setState({
|
||||
globalRoles: result.data
|
||||
});
|
||||
}
|
||||
|
||||
@withAsyncErrorHandler
|
||||
async loadFormValues() {
|
||||
await this.getFormValuesFromURL(`/rest/users/${this.state.entityId}`, data => {
|
||||
|
@ -221,20 +211,12 @@ export default class CUD extends Component {
|
|||
const userId = this.getFormValue('id');
|
||||
const canDelete = userId !== 1 && mailtrainConfig.userId !== userId;
|
||||
|
||||
const roles = mailtrainConfig.roles.global;
|
||||
|
||||
const rolesColumns = [
|
||||
{ data: 1, title: "Name" },
|
||||
{ data: 2, title: "Description" },
|
||||
];
|
||||
|
||||
|
||||
const rolesData = [];
|
||||
for (const key in roles) {
|
||||
const role = roles[key];
|
||||
rolesData.push([ key, role.name, role.description ]);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{edit && canDelete &&
|
||||
|
@ -258,7 +240,7 @@ export default class CUD extends Component {
|
|||
<InputField id="password2" label={t('Repeat Password')} type="password"/>
|
||||
</div>
|
||||
}
|
||||
<TableSelect id="role" label={t('Role')} withHeader dropdown data={rolesData} columns={rolesColumns} selectionLabelIndex={1}/>
|
||||
<TableSelect id="role" label={t('Role')} withHeader dropdown dataUrl={'/rest/shares-roles-table/global'} columns={rolesColumns} selectionLabelIndex={1}/>
|
||||
<NamespaceSelect/>
|
||||
|
||||
<ButtonRow>
|
||||
|
|
|
@ -21,6 +21,10 @@ export default class List extends Component {
|
|||
{
|
||||
label: 'Edit',
|
||||
link: '/users/edit/' + data[0]
|
||||
},
|
||||
{
|
||||
label: 'Shares',
|
||||
link: '/users/shares/' + data[0]
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -34,6 +38,7 @@ export default class List extends Component {
|
|||
}
|
||||
|
||||
columns.push({ data: 3, title: "Namespace" });
|
||||
columns.push({ data: 4, title: "Role" });
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
|
@ -8,24 +8,9 @@ import i18n from '../lib/i18n';
|
|||
import { Section } from '../lib/page';
|
||||
import CUD from './CUD';
|
||||
import List from './List';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import UserShares from '../shares/UserShares';
|
||||
|
||||
const getStructure = t => {
|
||||
const subPaths = {};
|
||||
|
||||
if (mailtrainConfig.isAuthMethodLocal) {
|
||||
subPaths.edit = {
|
||||
title: t('Edit User'),
|
||||
params: [':id', ':action?'],
|
||||
render: props => (<CUD edit {...props} />)
|
||||
};
|
||||
|
||||
subPaths.create = {
|
||||
title: t('Create User'),
|
||||
render: props => (<CUD {...props} />)
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
'': {
|
||||
title: t('Home'),
|
||||
|
@ -35,7 +20,22 @@ const getStructure = t => {
|
|||
title: t('Users'),
|
||||
link: '/users',
|
||||
component: List,
|
||||
children: subPaths
|
||||
children: {
|
||||
edit: {
|
||||
title: t('Edit User'),
|
||||
params: [':id', ':action?'],
|
||||
render: props => (<CUD edit {...props} />)
|
||||
},
|
||||
create: {
|
||||
title: t('Create User'),
|
||||
render: props => (<CUD {...props} />)
|
||||
},
|
||||
shares: {
|
||||
title: t('User Shares'),
|
||||
params: [':id' ],
|
||||
component: UserShares
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue