Only show edit/delete buttons for integrations if the user should have permissions to them (#4719)
Этот коммит содержится в:
коммит произвёл
enahum
родитель
6ae028d2c6
Коммит
83a2bbe67a
@@ -13,8 +13,8 @@ import ErrorBar from 'components/error_bar.jsx';
|
|||||||
export default class BackstageController extends React.Component {
|
export default class BackstageController extends React.Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
children: React.PropTypes.node.isRequired,
|
user: React.PropTypes.object,
|
||||||
params: React.PropTypes.object.isRequired
|
children: React.PropTypes.node.isRequired
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,9 +23,12 @@ export default class BackstageController extends React.Component {
|
|||||||
|
|
||||||
this.onTeamChange = this.onTeamChange.bind(this);
|
this.onTeamChange = this.onTeamChange.bind(this);
|
||||||
|
|
||||||
|
const team = TeamStore.getCurrent();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
user: UserStore.getCurrentUser(),
|
team,
|
||||||
team: props.params.team ? TeamStore.getByName(props.params.team) : TeamStore.getCurrent()
|
isAdmin: UserStore.isSystemAdminForCurrentUser(this.props.user) ||
|
||||||
|
TeamStore.isTeamAdminForCurrentTeam(team)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,8 +41,12 @@ export default class BackstageController extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTeamChange() {
|
onTeamChange() {
|
||||||
|
const team = TeamStore.getCurrent();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
team: this.props.params.team ? TeamStore.getByName(this.props.params.team) : TeamStore.getCurrent()
|
team,
|
||||||
|
isAdmin: UserStore.isSystemAdminForCurrentUser(this.props.user) ||
|
||||||
|
TeamStore.isTeamAdminForCurrentTeam(team)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +58,7 @@ export default class BackstageController extends React.Component {
|
|||||||
<div className='backstage-body'>
|
<div className='backstage-body'>
|
||||||
<BackstageSidebar
|
<BackstageSidebar
|
||||||
team={this.state.team}
|
team={this.state.team}
|
||||||
user={this.state.user}
|
user={this.props.user}
|
||||||
/>
|
/>
|
||||||
{
|
{
|
||||||
React.Children.map(this.props.children, (child) => {
|
React.Children.map(this.props.children, (child) => {
|
||||||
@@ -61,7 +68,8 @@ export default class BackstageController extends React.Component {
|
|||||||
|
|
||||||
return React.cloneElement(child, {
|
return React.cloneElement(child, {
|
||||||
team: this.state.team,
|
team: this.state.team,
|
||||||
user: this.state.user
|
user: this.props.user,
|
||||||
|
isAdmin: this.state.isAdmin
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ export default class CommandsContainer extends React.Component {
|
|||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
team: React.PropTypes.object,
|
team: React.PropTypes.object,
|
||||||
children: React.PropTypes.node
|
user: React.PropTypes.object,
|
||||||
|
children: React.PropTypes.node.isRequired,
|
||||||
|
isAdmin: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +67,9 @@ export default class CommandsContainer extends React.Component {
|
|||||||
commands: this.state.commands,
|
commands: this.state.commands,
|
||||||
users: this.state.users,
|
users: this.state.users,
|
||||||
loading: this.state.loading,
|
loading: this.state.loading,
|
||||||
team: this.props.team
|
team: this.props.team,
|
||||||
|
user: this.props.user,
|
||||||
|
isAdmin: this.props.isAdmin
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ export default class InstalledCommand extends React.Component {
|
|||||||
onRegenToken: React.PropTypes.func.isRequired,
|
onRegenToken: React.PropTypes.func.isRequired,
|
||||||
onDelete: React.PropTypes.func.isRequired,
|
onDelete: React.PropTypes.func.isRequired,
|
||||||
filter: React.PropTypes.string,
|
filter: React.PropTypes.string,
|
||||||
creator: React.PropTypes.object.isRequired
|
creator: React.PropTypes.object.isRequired,
|
||||||
|
canChange: React.PropTypes.bool.isRequired
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +85,40 @@ export default class InstalledCommand extends React.Component {
|
|||||||
trigger += ' ' + command.auto_complete_hint;
|
trigger += ' ' + command.auto_complete_hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let actions = null;
|
||||||
|
if (this.props.canChange) {
|
||||||
|
actions = (
|
||||||
|
<div className='item-actions'>
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
onClick={this.handleRegenToken}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='installed_integrations.regenToken'
|
||||||
|
defaultMessage='Regenerate Token'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
{' - '}
|
||||||
|
<Link to={`/${this.props.team.name}/integrations/commands/edit?id=${command.id}`}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='installed_integrations.edit'
|
||||||
|
defaultMessage='Edit'
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
{' - '}
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
onClick={this.handleDelete}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='installed_integrations.delete'
|
||||||
|
defaultMessage='Delete'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='backstage-list__item'>
|
<div className='backstage-list__item'>
|
||||||
<div className='item-details'>
|
<div className='item-details'>
|
||||||
@@ -120,36 +155,7 @@ export default class InstalledCommand extends React.Component {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='item-actions'>
|
{actions}
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
onClick={this.handleRegenToken}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='installed_integrations.regenToken'
|
|
||||||
defaultMessage='Regenerate Token'
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
{' - '}
|
|
||||||
<Link
|
|
||||||
to={`/${this.props.team.name}/integrations/commands/edit?id=${command.id}`}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='installed_integrations.edit'
|
|
||||||
defaultMessage='Edit'
|
|
||||||
/>
|
|
||||||
</Link>
|
|
||||||
{' - '}
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
onClick={this.handleDelete}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='installed_integrations.delete'
|
|
||||||
defaultMessage='Delete'
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ export default class InstalledCommands extends React.Component {
|
|||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
team: React.PropTypes.object,
|
team: React.PropTypes.object,
|
||||||
|
user: React.PropTypes.object,
|
||||||
users: React.PropTypes.object,
|
users: React.PropTypes.object,
|
||||||
commands: React.PropTypes.array,
|
commands: React.PropTypes.array,
|
||||||
loading: React.PropTypes.bool
|
loading: React.PropTypes.bool,
|
||||||
|
isAdmin: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +39,8 @@ export default class InstalledCommands extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const commands = this.props.commands.map((command) => {
|
const commands = this.props.commands.map((command) => {
|
||||||
|
const canChange = this.props.isAdmin || this.props.user.id === command.creator_id;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InstalledCommand
|
<InstalledCommand
|
||||||
key={command.id}
|
key={command.id}
|
||||||
@@ -45,6 +49,7 @@ export default class InstalledCommands extends React.Component {
|
|||||||
onRegenToken={this.regenCommandToken}
|
onRegenToken={this.regenCommandToken}
|
||||||
onDelete={this.deleteCommand}
|
onDelete={this.deleteCommand}
|
||||||
creator={this.props.users[command.creator_id] || {}}
|
creator={this.props.users[command.creator_id] || {}}
|
||||||
|
canChange={canChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ export default class InstalledIncomingWebhook extends React.Component {
|
|||||||
incomingWebhook: React.PropTypes.object.isRequired,
|
incomingWebhook: React.PropTypes.object.isRequired,
|
||||||
onDelete: React.PropTypes.func.isRequired,
|
onDelete: React.PropTypes.func.isRequired,
|
||||||
filter: React.PropTypes.string,
|
filter: React.PropTypes.string,
|
||||||
creator: React.PropTypes.object.isRequired
|
creator: React.PropTypes.object.isRequired,
|
||||||
|
canChange: React.PropTypes.bool.isRequired
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +84,23 @@ export default class InstalledIncomingWebhook extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let actions = null;
|
||||||
|
if (this.props.canChange) {
|
||||||
|
actions = (
|
||||||
|
<div className='item-actions'>
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
onClick={this.handleDelete}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='installed_integrations.delete'
|
||||||
|
defaultMessage='Delete'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='backstage-list__item'>
|
<div className='backstage-list__item'>
|
||||||
<div className='item-details'>
|
<div className='item-details'>
|
||||||
@@ -116,17 +134,7 @@ export default class InstalledIncomingWebhook extends React.Component {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='item-actions'>
|
{actions}
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
onClick={this.handleDelete}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='installed_integrations.delete'
|
|
||||||
defaultMessage='Delete'
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import {FormattedMessage} from 'react-intl';
|
|||||||
export default class InstalledIncomingWebhooks extends React.Component {
|
export default class InstalledIncomingWebhooks extends React.Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
team: React.PropTypes.object
|
team: React.PropTypes.object,
|
||||||
|
user: React.PropTypes.object,
|
||||||
|
isAdmin: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,12 +76,15 @@ export default class InstalledIncomingWebhooks extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const incomingWebhooks = this.state.incomingWebhooks.map((incomingWebhook) => {
|
const incomingWebhooks = this.state.incomingWebhooks.map((incomingWebhook) => {
|
||||||
|
const canChange = this.props.isAdmin || this.props.user.id === incomingWebhook.user_id;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InstalledIncomingWebhook
|
<InstalledIncomingWebhook
|
||||||
key={incomingWebhook.id}
|
key={incomingWebhook.id}
|
||||||
incomingWebhook={incomingWebhook}
|
incomingWebhook={incomingWebhook}
|
||||||
onDelete={this.deleteIncomingWebhook}
|
onDelete={this.deleteIncomingWebhook}
|
||||||
creator={this.state.users[incomingWebhook.user_id] || {}}
|
creator={this.state.users[incomingWebhook.user_id] || {}}
|
||||||
|
canChange={canChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ export default class InstalledOutgoingWebhook extends React.Component {
|
|||||||
onRegenToken: React.PropTypes.func.isRequired,
|
onRegenToken: React.PropTypes.func.isRequired,
|
||||||
onDelete: React.PropTypes.func.isRequired,
|
onDelete: React.PropTypes.func.isRequired,
|
||||||
filter: React.PropTypes.string,
|
filter: React.PropTypes.string,
|
||||||
creator: React.PropTypes.object.isRequired
|
creator: React.PropTypes.object.isRequired,
|
||||||
|
canChange: React.PropTypes.bool.isRequired
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +147,33 @@ export default class InstalledOutgoingWebhook extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let actions = null;
|
||||||
|
if (this.props.canChange) {
|
||||||
|
actions = (
|
||||||
|
<div className='item-actions'>
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
onClick={this.handleRegenToken}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='installed_integrations.regenToken'
|
||||||
|
defaultMessage='Regen Token'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
{' - '}
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
onClick={this.handleDelete}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='installed_integrations.delete'
|
||||||
|
defaultMessage='Delete'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='backstage-list__item'>
|
<div className='backstage-list__item'>
|
||||||
<div className='item-details'>
|
<div className='item-details'>
|
||||||
@@ -203,27 +231,7 @@ export default class InstalledOutgoingWebhook extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
{urls}
|
{urls}
|
||||||
</div>
|
</div>
|
||||||
<div className='item-actions'>
|
{actions}
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
onClick={this.handleRegenToken}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='installed_integrations.regenToken'
|
|
||||||
defaultMessage='Regen Token'
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
{' - '}
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
onClick={this.handleDelete}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='installed_integrations.delete'
|
|
||||||
defaultMessage='Delete'
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import {FormattedMessage} from 'react-intl';
|
|||||||
export default class InstalledOutgoingWebhooks extends React.Component {
|
export default class InstalledOutgoingWebhooks extends React.Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
team: React.PropTypes.object
|
team: React.PropTypes.object,
|
||||||
|
user: React.PropTypes.object,
|
||||||
|
isAdmin: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +79,8 @@ export default class InstalledOutgoingWebhooks extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const outgoingWebhooks = this.state.outgoingWebhooks.map((outgoingWebhook) => {
|
const outgoingWebhooks = this.state.outgoingWebhooks.map((outgoingWebhook) => {
|
||||||
|
const canChange = this.props.isAdmin || this.props.user.id === outgoingWebhook.creator_id;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InstalledOutgoingWebhook
|
<InstalledOutgoingWebhook
|
||||||
key={outgoingWebhook.id}
|
key={outgoingWebhook.id}
|
||||||
@@ -84,6 +88,7 @@ export default class InstalledOutgoingWebhooks extends React.Component {
|
|||||||
onRegenToken={this.regenOutgoingWebhookToken}
|
onRegenToken={this.regenOutgoingWebhookToken}
|
||||||
onDelete={this.deleteOutgoingWebhook}
|
onDelete={this.deleteOutgoingWebhook}
|
||||||
creator={this.state.users[outgoingWebhook.creator_id] || {}}
|
creator={this.state.users[outgoingWebhook.creator_id] || {}}
|
||||||
|
canChange={canChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user