Only show edit/delete buttons for integrations if the user should have permissions to them (#4719)

Этот коммит содержится в:
Harrison Healey
2016-12-06 07:35:24 -05:00
коммит произвёл enahum
родитель 6ae028d2c6
Коммит 83a2bbe67a
8 изменённых файлов: 126 добавлений и 77 удалений

Просмотреть файл

@@ -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}
/> />
); );
}); });