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

MM-28733 : Admin Advisor v2 #6461

Merged
merged 25 commits into from
Sep 25, 2020
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d608ef5
temp work
catalintomai Sep 12, 2020
cef507b
Merge branch 'master' into OCTO-6
catalintomai Sep 16, 2020
1fa0814
cleanup + make check-style fixes
catalintomai Sep 16, 2020
1f34c72
add support for 500k banner warning
catalintomai Sep 17, 2020
5a97f51
remove ContextUs texts from the StartTrial version of the modal
catalintomai Sep 17, 2020
2e04eb4
fix localization file
catalintomai Sep 17, 2020
0ccfee7
address CR comments
catalintomai Sep 17, 2020
d9cce21
address CR comments
catalintomai Sep 17, 2020
951a887
address CR comments
catalintomai Sep 17, 2020
35b3e35
addressed CR comments
catalintomai Sep 18, 2020
ecbbc9f
addressed CR comments
catalintomai Sep 18, 2020
a984fab
Merge branch 'master' into OCTO-6
catalintomai Sep 19, 2020
a5b096f
removed StartTrial from webapp following PR spec update
catalintomai Sep 20, 2020
7d70359
refactor multiple warn metric banners handling
catalintomai Sep 20, 2020
da1c74d
remove enterpriseReady references
catalintomai Sep 20, 2020
c6972b7
clean up i18n file
catalintomai Sep 20, 2020
fb5878c
updated mailto strings
catalintomai Sep 20, 2020
8c33ee5
addressed CR comments
catalintomai Sep 22, 2020
154758f
Merge branch 'master' into OCTO-6
catalintomai Sep 22, 2020
e5f1a91
updated ack banner text
catalintomai Sep 23, 2020
305c792
fix Jest test
catalintomai Sep 23, 2020
3dfbab3
address PM spec updates
catalintomai Sep 24, 2020
e89862f
make sure we don't display banner if warn metric is invalid
catalintomai Sep 24, 2020
85ca2b6
Merge branch 'master' into OCTO-6
catalintomai Sep 24, 2020
a2512d9
Merge branch 'master' into OCTO-6
catalintomai Sep 25, 2020
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
13 changes: 10 additions & 3 deletions actions/websocket_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import {loadProfilesForSidebar} from 'actions/user_actions.jsx';
import store from 'stores/redux_store.jsx';
import WebSocketClient from 'client/web_websocket_client.jsx';
import {loadPlugin, loadPluginsIfNecessary, removePlugin} from 'plugins';
import {ActionTypes, Constants, AnnouncementBarMessages, SocketEvents, UserStatuses, ModalIdentifiers} from 'utils/constants';
import {ActionTypes, Constants, AnnouncementBarMessages, SocketEvents, UserStatuses, ModalIdentifiers, WarnMetricTypes} from 'utils/constants';
import {getSiteURL} from 'utils/url';
import {isGuest} from 'utils/utils';
import RemovedFromChannelModal from 'components/removed_from_channel_modal';
Expand Down Expand Up @@ -1256,14 +1256,21 @@ function handleGroupNotAssociatedToChannelEvent(msg) {
}

function handleWarnMetricStatusReceivedEvent(msg) {
var receivedData = JSON.parse(msg.data.warnMetricStatus);
let bannerData;
if (receivedData.id === WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500) {
bannerData = AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_USERS;
} else if (receivedData.id === WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_POSTS_2M) {
bannerData = AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_POSTS;
}
store.dispatch(batchActions([
{
type: GeneralTypes.WARN_METRIC_STATUS_RECEIVED,
data: JSON.parse(msg.data.warnMetricStatus),
data: receivedData,
},
{
type: ActionTypes.SHOW_NOTICE,
data: [AnnouncementBarMessages.NUMBER_OF_ACTIVE_USERS_WARN_METRIC_STATUS],
data: [bannerData],
},
]));
}
Expand Down
103 changes: 69 additions & 34 deletions components/announcement_bar/configuration_bar/configuration_bar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class ConfigurationAnnouncementBar extends React.PureComponent {
dismissedExpiringLicense: PropTypes.bool,
dismissedNumberOfActiveUsersWarnMetricStatus: PropTypes.bool,
dismissedNumberOfActiveUsersWarnMetricStatusAck: PropTypes.bool,
dismissedNumberOfPostsWarnMetricStatus: PropTypes.bool,
dismissedNumberOfPostsWarnMetricStatusAck: PropTypes.bool,
siteURL: PropTypes.string.isRequired,
warnMetricsStatus: PropTypes.object,
actions: PropTypes.shape({
Expand All @@ -45,15 +47,25 @@ class ConfigurationAnnouncementBar extends React.PureComponent {
}

dismissNumberOfActiveUsersWarnMetric = () => {
this.props.actions.dismissNotice(AnnouncementBarMessages.NUMBER_OF_ACTIVE_USERS_WARN_METRIC_STATUS);
this.props.actions.dismissNotice(AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_USERS);
}

dismissNumberOfPostsWarnMetric = () => {
this.props.actions.dismissNotice(AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_POSTS);
}

dismissNumberOfActiveUsersWarnMetricAck = () => {
this.props.actions.dismissNotice(AnnouncementBarMessages.NUMBER_OF_ACTIVE_USERS_WARN_METRIC_STATUS_ACK);
this.props.actions.dismissNotice(AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_USERS_ACK);
}

dismissNumberOfPostsWarnMetricAck = () => {
this.props.actions.dismissNotice(AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_POSTS_ACK);
}

getNoticeForWarnMetric = (warnMetricStatus) => {
if (!warnMetricStatus) {
if (!warnMetricStatus ||
(warnMetricStatus.id !== WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500 &&
warnMetricStatus.id !== WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_POSTS_2M)) {
return null;
}

Expand All @@ -64,59 +76,81 @@ class ConfigurationAnnouncementBar extends React.PureComponent {
var isDismissed = null;
var canCloseBar = false;

switch (warnMetricStatus.id) {
case WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500:
if (warnMetricStatus.acked) {
if (warnMetricStatus.acked) {
message = (
<React.Fragment>
<img
className='advisor-icon'
src={ackIcon}
/>
<FormattedMessage
id='announcement_bar.warn_metric_status_ack.text'
defaultMessage='Thank you for contacting Mattermost. We will follow up with you soon.'
/>
</React.Fragment>
);

if (warnMetricStatus.id === WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500) {
dismissFunc = this.dismissNumberOfActiveUsersWarnMetricAck;
isDismissed = this.props.dismissedNumberOfActiveUsersWarnMetricStatusAck;
} else if (warnMetricStatus.id === WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_POSTS_2M) {
dismissFunc = this.dismissNumberOfPostsWarnMetricAck;
isDismissed = this.props.dismissedNumberOfPostsWarnMetricStatusAck;
}

type = AnnouncementBarTypes.ADVISOR_ACK;
showModal = false;
canCloseBar = true;
} else {
if (warnMetricStatus.id === WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500) {
message = (
<React.Fragment>
<img
className='advisor-icon'
src={ackIcon}
src={alertIcon}
/>
<FormattedMarkdownMessage
id={t('announcement_bar.error.number_active_users_warn_metric_status_ack.text')}
defaultMessage={'Your trial has started! Go to the [System Console](/admin_console/environment/web_server) to check out the new features.'}
id='announcement_bar.number_active_users_warn_metric_status.text'
defaultMessage='You now have over {limit} users. We strongly recommend using advanced features for large-scale servers.'
values={{
limit: warnMetricStatus.limit,
}}
/>
</React.Fragment>
);
type = AnnouncementBarTypes.ADVISOR_ACK;
showModal = false;
dismissFunc = this.dismissNumberOfActiveUsersWarnMetricAck;
isDismissed = this.props.dismissedNumberOfActiveUsersWarnMetricStatusAck;
canCloseBar = true;
} else {
dismissFunc = this.dismissNumberOfActiveUsersWarnMetric;
isDismissed = this.props.dismissedNumberOfActiveUsersWarnMetricStatus;
} else if (warnMetricStatus.id === WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_POSTS_2M) {
message = (
<React.Fragment>
<img
className='advisor-icon'
src={alertIcon}
/>
<FormattedMarkdownMessage
id={t('announcement_bar.error.number_active_users_warn_metric_status.text')}
defaultMessage={'You now have over {limit} users. We strongly recommend using advanced features for large-scale servers.'}
id='announcement_bar.number_of_posts_warn_metric_status.text'
defaultMessage='You now have over {limit} posts. We strongly recommend using advanced features for large-scale servers.'
values={{
limit: warnMetricStatus.limit,
}}
/>
</React.Fragment>
);
type = AnnouncementBarTypes.ADVISOR;
showModal = true;
dismissFunc = this.dismissNumberOfActiveUsersWarnMetric;
isDismissed = this.props.dismissedNumberOfActiveUsersWarnMetricStatus;
canCloseBar = false;
dismissFunc = this.dismissNumberOfPostsWarnMetric;
isDismissed = this.props.dismissedNumberOfPostsWarnMetricStatus;
}
return {
Message: message,
DismissFunc: dismissFunc,
IsDismissed: isDismissed,
Type: type,
ShowModal: showModal,
CanCloseBar: canCloseBar,
};
default:
return null;
type = AnnouncementBarTypes.ADVISOR;
showModal = true;
canCloseBar = false;
}
return {
Message: message,
DismissFunc: dismissFunc,
IsDismissed: isDismissed,
Type: type,
ShowModal: showModal,
CanCloseBar: canCloseBar,
};
}

render() {
Expand Down Expand Up @@ -176,7 +210,8 @@ class ConfigurationAnnouncementBar extends React.PureComponent {
/>
);
}
if (this.props.license.IsLicensed === 'false' && this.props.warnMetricsStatus) {
if (this.props.license?.IsLicensed === 'false' &&
this.props.warnMetricsStatus) {
for (const status of Object.values(this.props.warnMetricsStatus)) {
var notice = this.getNoticeForWarnMetric(status);
if (!notice || notice.IsDismissed) {
Expand All @@ -190,7 +225,7 @@ class ConfigurationAnnouncementBar extends React.PureComponent {
type={notice.Type}
showModal={notice.ShowModal}
modalButtonText={t('announcement_bar.error.warn_metric_status.link')}
modalButtonDefaultText={'Learn More'}
modalButtonDefaultText='Learn more'
warnMetricStatus={status}
message={notice.Message}
/>
Expand Down
6 changes: 4 additions & 2 deletions components/announcement_bar/configuration_bar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ function mapStateToProps(state) {
return {
siteURL: getSiteURL(state),
dismissedExpiringLicense: Boolean(state.views.notice.hasBeenDismissed[AnnouncementBarMessages.LICENSE_EXPIRING]),
dismissedNumberOfActiveUsersWarnMetricStatus: Boolean(state.views.notice.hasBeenDismissed[AnnouncementBarMessages.NUMBER_OF_ACTIVE_USERS_WARN_METRIC_STATUS]),
dismissedNumberOfActiveUsersWarnMetricStatusAck: Boolean(state.views.notice.hasBeenDismissed[AnnouncementBarMessages.NUMBER_OF_ACTIVE_USERS_WARN_METRIC_STATUS_ACK]),
dismissedNumberOfActiveUsersWarnMetricStatus: Boolean(state.views.notice.hasBeenDismissed[AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_USERS]),
dismissedNumberOfActiveUsersWarnMetricStatusAck: Boolean(state.views.notice.hasBeenDismissed[AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_USERS_ACK]),
dismissedNumberOfPostsWarnMetricStatus: Boolean(state.views.notice.hasBeenDismissed[AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_POSTS]),
dismissedNumberOfPostsWarnMetricStatusAck: Boolean(state.views.notice.hasBeenDismissed[AnnouncementBarMessages.WARN_METRIC_STATUS_NUMBER_OF_POSTS_ACK]),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,13 @@ exports[`components/WarnMetricAckModal error display 1`] = `
bsClass="modal-title"
componentClass="h1"
id="warnMetricAckHeaderModalLabel"
>
<FormattedMessage
defaultMessage="Scaling with Mattermost"
id="warn_metric_ack_modal.header.title"
/>
</ModalTitle>
/>
</ModalHeader>
<ModalBody
bsClass="modal-body"
componentClass="div"
>
<div>
<FormattedMessage
defaultMessage="Mattermost strongly recommends that deployments of over {limit} users upgrade to Mattermost Enterprise Edition, which offers features such as user management, server clustering, and performance monitoring"
id="warn_metric_ack_modal.number_of_active_users.description"
values={
Object {
"limit": 500,
}
}
/>
<br />
<div
className="form-group has-error"
Expand All @@ -78,7 +64,7 @@ exports[`components/WarnMetricAckModal error display 1`] = `
forceAck={true}
messageId="warn_metric_ack_modal.mailto.link"
onClickHandler={[Function]}
url="mailto:[email protected][email protected]&subject=Mattermost%20Contact%20Us%20request&body=Mattermost%20Contact%20Us%20request.%20My%20team%20now%20has%20500%20users%20and%20I%20am%20considering%20Mattermost%20Enterprise%20Edition.%0D%0AContact%20Fake%20Person%0D%0AEmail%20a%40test.com%0D%0ASite%20URL%20http%3A%2F%2Flocalhost%3A8065%0D%0ADiagnostic%20Id%20diag_0%0D%0AIf%20you%20have%20any%20additional%20inquiries%2C%20please%20contact%20support%40mattermost.com"
url="mailto:[email protected][email protected]&subject=Mattermost%20Contact%20Us%20request&body=Mattermost%20Contact%20Us%20request.%0D%0AContact%20Fake%20Person%0D%0AEmail%20a%40test.com%0D%0ASite%20URL%20http%3A%2F%2Flocalhost%3A8065%0D%0ADiagnostic%20Id%20diag_0%0D%0AIf%20you%20have%20any%20additional%20inquiries%2C%20please%20contact%20support%40mattermost.com"
/>,
}
}
Expand All @@ -97,12 +83,12 @@ exports[`components/WarnMetricAckModal error display 1`] = `
}
>
<FormattedMessage
defaultMessage="By clicking Acknowledge, you will be sharing your information with Mattermost Inc., to learn more about upgrading. {link}"
id="warn_metric_ack_modal.number_of_active_users.subtext"
defaultMessage="By clicking Acknowledge, you will be sharing your information with Mattermost Inc. {link}"
id="warn_metric_ack_modal.subtext"
values={
Object {
"link": <ErrorLink
defaultMessage="Learn More"
defaultMessage="Learn more"
messageId="warn_metric_ack_modal.learn_more.link"
url="https://mattermost.com/pl/default-admin-advisory"
/>,
Expand Down Expand Up @@ -176,27 +162,13 @@ exports[`components/WarnMetricAckModal should match snapshot, init 1`] = `
bsClass="modal-title"
componentClass="h1"
id="warnMetricAckHeaderModalLabel"
>
<FormattedMessage
defaultMessage="Scaling with Mattermost"
id="warn_metric_ack_modal.header.title"
/>
</ModalTitle>
/>
</ModalHeader>
<ModalBody
bsClass="modal-body"
componentClass="div"
>
<div>
<FormattedMessage
defaultMessage="Mattermost strongly recommends that deployments of over {limit} users upgrade to Mattermost Enterprise Edition, which offers features such as user management, server clustering, and performance monitoring"
id="warn_metric_ack_modal.number_of_active_users.description"
values={
Object {
"limit": 500,
}
}
/>
<br />
<br />
<div
Expand All @@ -210,12 +182,12 @@ exports[`components/WarnMetricAckModal should match snapshot, init 1`] = `
}
>
<FormattedMessage
defaultMessage="By clicking Acknowledge, you will be sharing your information with Mattermost Inc., to learn more about upgrading. {link}"
id="warn_metric_ack_modal.number_of_active_users.subtext"
defaultMessage="By clicking Acknowledge, you will be sharing your information with Mattermost Inc. {link}"
id="warn_metric_ack_modal.subtext"
values={
Object {
"link": <ErrorLink
defaultMessage="Learn More"
defaultMessage="Learn more"
messageId="warn_metric_ack_modal.learn_more.link"
url="https://mattermost.com/pl/default-admin-advisory"
/>,
Expand Down
3 changes: 1 addition & 2 deletions components/warn_metric_ack_modal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {ActionFunc} from 'mattermost-redux/types/actions';
import {getStandardAnalytics, sendWarnMetricAck} from 'mattermost-redux/actions/admin';

import {getCurrentUser} from 'mattermost-redux/selectors/entities/common';
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
import {getConfig} from 'mattermost-redux/selectors/entities/general';

import {closeModal} from 'actions/views/modals';

Expand All @@ -28,7 +28,6 @@ function mapStateToProps(state: GlobalState, ownProps: Props) {
return {
stats: state.entities.admin.analytics,
user: getCurrentUser(state),
license: getLicense(state),
diagnosticId: config.DiagnosticId,
show: isModalOpen(state, ModalIdentifiers.WARN_METRIC_ACK),
closeParentComponent: ownProps.closeParentComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,15 @@ describe('components/WarnMetricAckModal', () => {
});

test('send ack on acknowledge button click', () => {
const props = {...baseProps};

const wrapper = shallow<WarnMetricAckModal>(
<WarnMetricAckModal {...baseProps}/>,
<WarnMetricAckModal {...props}/>,
);

wrapper.setState({saving: false});
wrapper.find('.save-button').simulate('click');
expect(baseProps.actions.sendWarnMetricAck).toHaveBeenCalledTimes(1);
expect(props.actions.sendWarnMetricAck).toHaveBeenCalledTimes(1);
});

test('should have called props.onHide when Modal.onExited is called', () => {
Expand Down
Loading