Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Hide bots and apps UI when managed by Apps Framework #7850

Merged
merged 9 commits into from
Apr 30, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion actions/integration_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import request from 'superagent';
import * as IntegrationActions from 'mattermost-redux/actions/integrations';
import {getProfilesByIds} from 'mattermost-redux/actions/users';
import {getUser} from 'mattermost-redux/selectors/entities/users';
import {appsEnabled} from 'mattermost-redux/selectors/entities/apps';

const DEFAULT_PAGE_SIZE = 100;

Expand Down Expand Up @@ -97,7 +98,10 @@ export function loadProfilesForCommands(commands) {
}

export function loadOAuthAppsAndProfiles(page = 0, perPage = DEFAULT_PAGE_SIZE) {
return async (dispatch) => {
return async (dispatch, getState) => {
if (appsEnabled(getState())) {
dispatch(IntegrationActions.getAppsOAuthAppIDs());
}
const {data} = await dispatch(IntegrationActions.getOAuthApps(page, perPage));
if (data) {
dispatch(loadProfilesForOAuthApps(data));
Expand Down
51 changes: 51 additions & 0 deletions components/integrations/bots/bot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ describe('components/integrations/bots/Bot', () => {
accessTokens={{}}
team={team}
actions={actions}
fromApp={false}
/>,
);

Expand Down Expand Up @@ -67,6 +68,52 @@ describe('components/integrations/bots/Bot', () => {
)).toEqual(false);
});

it('app bot', () => {
const bot = UtilsTestHelper.getBotMock({user_id: '1'});
const user = UtilsTestHelper.getUserMock({id: bot.user_id});
const wrapper = shallow(
<Bot
bot={bot}
user={user}
owner={undefined}
accessTokens={{}}
team={team}
actions={actions}
fromApp={true}
/>,
);

expect(wrapper.contains(bot.display_name + ' (@' + bot.username + ')')).toEqual(true);
expect(wrapper.contains(<Markdown message={bot.description}/>)).toEqual(true);
expect(wrapper.contains('Apps Framework')).toEqual(true);

// if bot managed by plugin, remove ability to edit from UI
expect(wrapper.contains(
<FormattedMessage
id='bot.manage.create_token'
defaultMessage='Create New Token'
/>,
)).toEqual(false);
expect(wrapper.contains(
<FormattedMessage
id='bots.manage.edit'
defaultMessage='Edit'
/>,
)).toEqual(false);
expect(wrapper.contains(
<FormattedMessage
id='bot.manage.disable'
defaultMessage='Disable'
/>,
)).toEqual(false);
expect(wrapper.contains(
<FormattedMessage
id='bot.manage.enable'
defaultMessage='Enable'
/>,
)).toEqual(false);
});

it('disabled bot', () => {
const bot = UtilsTestHelper.getBotMock({user_id: '1'});
bot.delete_at = 100; // disabled
Expand All @@ -79,6 +126,7 @@ describe('components/integrations/bots/Bot', () => {
accessTokens={{}}
team={team}
actions={actions}
fromApp={false}
/>,
);
expect(wrapper.contains(bot.display_name + ' (@' + bot.username + ')')).toEqual(true);
Expand Down Expand Up @@ -122,6 +170,7 @@ describe('components/integrations/bots/Bot', () => {
accessTokens={{}}
team={team}
actions={actions}
fromApp={false}
/>,
);
expect(wrapper.contains(owner.username)).toEqual(true);
Expand Down Expand Up @@ -167,6 +216,7 @@ describe('components/integrations/bots/Bot', () => {
accessTokens={accessTokens}
team={team}
actions={actions}
fromApp={false}
/>,
);

Expand Down Expand Up @@ -206,6 +256,7 @@ describe('components/integrations/bots/Bot', () => {
accessTokens={accessTokens}
team={team}
actions={actions}
fromApp={false}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test for a bot that has fromApp={true}?

/>,
);

Expand Down
191 changes: 100 additions & 91 deletions components/integrations/bots/bot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ type Props = {
*/
filter?: string;

/**
* Determine whether this bot is managed by the app framework
*/
fromApp: boolean;

actions: {

/**
Expand Down Expand Up @@ -193,7 +198,9 @@ export default class Bot extends React.PureComponent<Props, State> {
const displayName = this.props.bot.display_name || '';

let ownerUsername = 'plugin';
if (this.props.owner && this.props.owner.username) {
if (this.props.fromApp) {
ownerUsername = 'Apps Framework';
} else if (this.props.owner && this.props.owner.username) {
ownerUsername = this.props.owner.username;
}
const filter = this.props.filter ? this.props.filter.toLowerCase() : '';
Expand All @@ -202,104 +209,106 @@ export default class Bot extends React.PureComponent<Props, State> {
}

const tokenList = [];
Object.values(this.props.accessTokens).forEach((token) => {
let activeLink;
let disableClass = '';
let disabledText;

if (token.is_active) {
activeLink = (
<a
id={token.id + '_deactivate'}
href='#'
onClick={(e) => {
e.preventDefault();
this.disableUserAccessToken(token.id);
}}
>
<FormattedMessage
id='user.settings.tokens.deactivate'
defaultMessage='Disable'
/>
</a>);
} else {
disableClass = 'light';
disabledText = (
<span className='mr-2 light'>
<FormattedMessage
id='user.settings.tokens.deactivatedWarning'
defaultMessage='(Disabled)'
/>
</span>
);
activeLink = (
<a
id={token.id + '_activate'}
href='#'
onClick={(e) => {
e.preventDefault();
this.enableUserAccessToken(token.id);
}}
if (!this.props.fromApp) {
Object.values(this.props.accessTokens).forEach((token) => {
let activeLink;
let disableClass = '';
let disabledText;

if (token.is_active) {
activeLink = (
<a
id={token.id + '_deactivate'}
href='#'
onClick={(e) => {
e.preventDefault();
this.disableUserAccessToken(token.id);
}}
>
<FormattedMessage
id='user.settings.tokens.deactivate'
defaultMessage='Disable'
/>
</a>);
} else {
disableClass = 'light';
disabledText = (
<span className='mr-2 light'>
<FormattedMessage
id='user.settings.tokens.deactivatedWarning'
defaultMessage='(Disabled)'
/>
</span>
);
activeLink = (
<a
id={token.id + '_activate'}
href='#'
onClick={(e) => {
e.preventDefault();
this.enableUserAccessToken(token.id);
}}
>
<FormattedMessage
id='user.settings.tokens.activate'
defaultMessage='Enable'
/>
</a>
);
}

tokenList.push(
<div
key={token.id}
className='bot-list__item'
>
<FormattedMessage
id='user.settings.tokens.activate'
defaultMessage='Enable'
/>
</a>
);
}

tokenList.push(
<div
key={token.id}
className='bot-list__item'
>
<div className='item-details__row d-flex justify-content-between'>
<div className={disableClass}>
<div className='whitespace--nowrap overflow--ellipsis'>
<b>
<FormattedMessage
id='user.settings.tokens.tokenDesc'
defaultMessage='Token Description: '
/>
</b>
{token.description}
<div className='item-details__row d-flex justify-content-between'>
<div className={disableClass}>
<div className='whitespace--nowrap overflow--ellipsis'>
<b>
<FormattedMessage
id='user.settings.tokens.tokenDesc'
defaultMessage='Token Description: '
/>
</b>
{token.description}
</div>
<div className='setting-box__token-id whitespace--nowrap overflow--ellipsis'>
<b>
<FormattedMessage
id='user.settings.tokens.tokenId'
defaultMessage='Token ID: '
/>
</b>
{token.id}
</div>
</div>
<div className='setting-box__token-id whitespace--nowrap overflow--ellipsis'>
<b>
<div>
{disabledText}
{activeLink}
{' - '}
<a
id={token.id + '_delete'}
href='#'
onClick={(e) => {
e.preventDefault();
this.confirmRevokeToken(token.id);
}}
>
<FormattedMessage
id='user.settings.tokens.tokenId'
defaultMessage='Token ID: '
id='user.settings.tokens.delete'
defaultMessage='Delete'
/>
</b>
{token.id}
</a>
</div>
</div>
<div>
{disabledText}
{activeLink}
{' - '}
<a
id={token.id + '_delete'}
href='#'
onClick={(e) => {
e.preventDefault();
this.confirmRevokeToken(token.id);
}}
>
<FormattedMessage
id='user.settings.tokens.delete'
defaultMessage='Delete'
/>
</a>
</div>
</div>
</div>,
);
});
</div>,
);
});
}

let options;
if (ownerUsername !== 'plugin') {
if (ownerUsername !== 'plugin' && !this.props.fromApp) {
options = (
<div className='item-actions'>
<button
Expand Down
Loading