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

Commit

Permalink
Add metric warning support (announcement bar and DM) (#5447)
Browse files Browse the repository at this point in the history
* Admin Advisory: Add warning for number of active users metric status

Co-authored-by: Catalin Tomai <[email protected]>
  • Loading branch information
catalintomai and catalintomai committed Jul 23, 2020
1 parent 0b27dbf commit 1376ff7
Show file tree
Hide file tree
Showing 32 changed files with 1,004 additions and 32 deletions.
25 changes: 25 additions & 0 deletions actions/websocket_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,14 @@ export function handleEvent(msg) {
handleGroupNotAssociatedToChannelEvent(msg);
break;

case SocketEvents.WARN_METRIC_STATUS_RECEIVED:
handleWarnMetricStatusReceivedEvent(msg);
break;

case SocketEvents.WARN_METRIC_STATUS_REMOVED:
handleWarnMetricStatusRemovedEvent(msg);
break;

default:
}

Expand Down Expand Up @@ -1220,3 +1228,20 @@ function handleGroupNotAssociatedToChannelEvent(msg) {
data: {channelID: msg.broadcast.channel_id, groups: [{id: msg.data.group_id}]},
});
}

function handleWarnMetricStatusReceivedEvent(msg) {
store.dispatch(batchActions([
{
type: GeneralTypes.WARN_METRIC_STATUS_RECEIVED,
data: JSON.parse(msg.data.warnMetricStatus),
},
{
type: ActionTypes.SHOW_NOTICE,
data: [AnnouncementBarMessages.NUMBER_OF_ACTIVE_USERS_WARN_METRIC_STATUS],
},
]));
}

function handleWarnMetricStatusRemovedEvent(msg) {
store.dispatch({type: GeneralTypes.WARN_METRIC_STATUS_REMOVED, data: {id: msg.data.warnMetricId}});
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ exports[`components/AnnouncementBar should match snapshot, bar not showing 1`] =
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -67,6 +70,9 @@ exports[`components/AnnouncementBar should match snapshot, bar showing 1`] = `
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -103,6 +109,9 @@ exports[`components/AnnouncementBar should match snapshot, bar showing, no dismi
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -139,6 +148,9 @@ exports[`components/AnnouncementBar should match snapshot, dismissal 1`] = `
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -175,6 +187,9 @@ exports[`components/AnnouncementBar should match snapshot, dismissal 2`] = `
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -211,6 +226,9 @@ exports[`components/AnnouncementBar should match snapshot, dismissal 3`] = `
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -247,6 +265,9 @@ exports[`components/AnnouncementBar should match snapshot, props change 1`] = `
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -283,6 +304,9 @@ exports[`components/AnnouncementBar should match snapshot, props change 2`] = `
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -319,6 +343,9 @@ exports[`components/AnnouncementBar should match snapshot, props change 3`] = `
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down Expand Up @@ -355,6 +382,9 @@ exports[`components/AnnouncementBar should match snapshot, props change 4`] = `
<injectIntl(FormattedMarkdownMessage)
id="text"
/>
<span
className="announcement-bar__link"
/>
</span>
</OverlayTrigger>
</div>
Expand Down
2 changes: 2 additions & 0 deletions components/announcement_bar/announcement_bar_controller.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default class AnnouncementBarController extends React.PureComponent {
canViewSystemErrors: PropTypes.bool.isRequired,
latestError: PropTypes.object,
totalUsers: PropTypes.number,
warnMetricsStatus: PropTypes.object,
actions: PropTypes.shape({
dismissError: PropTypes.func.isRequired,
}).isRequired,
Expand Down Expand Up @@ -61,6 +62,7 @@ export default class AnnouncementBarController extends React.PureComponent {
canViewSystemErrors={this.props.canViewSystemErrors}
totalUsers={this.props.totalUsers}
user={this.props.user}
warnMetricsStatus={this.props.warnMetricsStatus}
/>
</React.Fragment>
);
Expand Down
100 changes: 99 additions & 1 deletion components/announcement_bar/configuration_bar/configuration_bar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
import {FormattedMessage, injectIntl} from 'react-intl';

import {isLicenseExpired, isLicenseExpiring, isLicensePastGracePeriod} from 'utils/license_utils.jsx';
import {AnnouncementBarTypes, AnnouncementBarMessages} from 'utils/constants';
import {AnnouncementBarTypes, AnnouncementBarMessages, WarnMetricTypes} from 'utils/constants';
import {intlShape} from 'utils/react_intl';

import {t} from 'utils/i18n';
Expand All @@ -17,6 +17,9 @@ import FormattedMarkdownMessage from 'components/formatted_markdown_message';
import AnnouncementBar from '../default_announcement_bar';
import TextDismissableBar from '../text_dismissable_bar';

import ackIcon from 'images/icons/check-circle-outline.svg';
import alertIcon from 'images/icons/round-white-info-icon.svg';

const RENEWAL_LINK = 'https://mattermost.com/renew/';

class ConfigurationAnnouncementBar extends React.PureComponent {
Expand All @@ -28,7 +31,10 @@ class ConfigurationAnnouncementBar extends React.PureComponent {
canViewSystemErrors: PropTypes.bool.isRequired,
totalUsers: PropTypes.number,
dismissedExpiringLicense: PropTypes.bool,
dismissedNumberOfActiveUsersWarnMetricStatus: PropTypes.bool,
dismissedNumberOfActiveUsersWarnMetricStatusAck: PropTypes.bool,
siteURL: PropTypes.string.isRequired,
warnMetricsStatus: PropTypes.object,
actions: PropTypes.shape({
dismissNotice: PropTypes.func.isRequired,
}).isRequired,
Expand All @@ -38,6 +44,77 @@ class ConfigurationAnnouncementBar extends React.PureComponent {
this.props.actions.dismissNotice(AnnouncementBarMessages.LICENSE_EXPIRING);
}

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

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

getNoticeForWarnMetric = (warnMetricStatus) => {
if (!warnMetricStatus) {
return null;
}

var message = '';
var type = '';
var showModal = false;
var dismissFunc = null;
var isDismissed = null;

switch (warnMetricStatus.id) {
case WarnMetricTypes.SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500:
if (warnMetricStatus.acked) {
message = (
<React.Fragment>
<img
className='advisor-icon'
src={ackIcon}
/>
<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.'}
/>
</React.Fragment>
);
type = AnnouncementBarTypes.ADVISOR_ACK;
showModal = false;
dismissFunc = this.dismissNumberOfActiveUsersWarnMetricAck;
isDismissed = this.props.dismissedNumberOfActiveUsersWarnMetricStatusAck;
} else {
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 that you upgrade to our Enterprise edition.'}
values={{
limit: warnMetricStatus.limit,
}}
/>
</React.Fragment>
);
type = AnnouncementBarTypes.ADVISOR;
showModal = true;
dismissFunc = this.dismissNumberOfActiveUsersWarnMetric;
isDismissed = this.props.dismissedNumberOfActiveUsersWarnMetricStatus;
}
return {
Message: message,
DismissFunc: dismissFunc,
IsDismissed: isDismissed,
Type: type,
ShowModal: showModal,
};
default:
return null;
}
}

render() {
// System administrators
if (this.props.canViewSystemErrors) {
Expand Down Expand Up @@ -95,6 +172,27 @@ class ConfigurationAnnouncementBar extends React.PureComponent {
/>
);
}
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) {
continue;
}

return (
<AnnouncementBar
showCloseButton={true}
handleClose={notice.DismissFunc}
type={notice.Type}
showModal={notice.ShowModal}
modalButtonText={t('announcement_bar.error.warn_metric_status.link')}
modalButtonDefaultText={'Learn More'}
warnMetricStatus={status}
message={notice.Message}
/>
);
}
}
} else {
// Regular users
if (isLicensePastGracePeriod(this.props.license)) { //eslint-disable-line no-lonely-if
Expand Down
2 changes: 2 additions & 0 deletions components/announcement_bar/configuration_bar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ 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]),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@
// See LICENSE.txt for license information.

import React from 'react';

import {FormattedMessage} from 'react-intl';

import PropTypes from 'prop-types';
import {Tooltip} from 'react-bootstrap';

import {Constants, AnnouncementBarTypes} from 'utils/constants';
import {Constants, AnnouncementBarTypes, ModalIdentifiers} from 'utils/constants';

import FormattedMarkdownMessage from 'components/formatted_markdown_message';
import OverlayTrigger from 'components/overlay_trigger';
import WarnMetricAckModal from 'components/warn_metric_ack_modal';
import ToggleModalButtonRedux from 'components/toggle_modal_button_redux';

import {trackEvent} from 'actions/diagnostics_actions.jsx';

export default class AnnouncementBar extends React.PureComponent {
static propTypes = {
Expand All @@ -18,6 +26,10 @@ export default class AnnouncementBar extends React.PureComponent {
message: PropTypes.node.isRequired,
handleClose: PropTypes.func,
announcementBarCount: PropTypes.number.isRequired,
showModal: PropTypes.bool,
modalButtonText: PropTypes.string,
modalButtonDefaultText: PropTypes.string,
warnMetricStatus: PropTypes.object,
actions: PropTypes.shape({
incrementAnnouncementBarCount: PropTypes.func.isRequired,
decrementAnnouncementBarCount: PropTypes.func.isRequired,
Expand Down Expand Up @@ -71,6 +83,10 @@ export default class AnnouncementBar extends React.PureComponent {
barClass = 'announcement-bar announcement-bar-critical';
} else if (this.props.type === AnnouncementBarTypes.SUCCESS) {
barClass = 'announcement-bar announcement-bar-success';
} else if (this.props.type === AnnouncementBarTypes.ADVISOR) {
barClass = 'announcement-bar announcement-bar-advisor';
} else if (this.props.type === AnnouncementBarTypes.ADVISOR_ACK) {
barClass = 'announcement-bar announcement-bar-advisor-ack';
}

let closeButton;
Expand All @@ -93,7 +109,6 @@ export default class AnnouncementBar extends React.PureComponent {
<FormattedMarkdownMessage id={this.props.message}/>
);
}

const announcementTooltip = (
<Tooltip id='announcement-bar__tooltip'>
{message}
Expand All @@ -112,6 +127,30 @@ export default class AnnouncementBar extends React.PureComponent {
>
<span>
{message}
<span className='announcement-bar__link'>
{this.props.showModal &&
<FormattedMessage
id={this.props.modalButtonText}
defaultMessage={this.props.modalButtonDefaultText}
>
{(linkmessage) => (
<ToggleModalButtonRedux
accessibilityLabel={linkmessage}
className={'color--link--adminack'}
dialogType={WarnMetricAckModal}
onClick={() => trackEvent('admin', 'click_warn_metric_learn_more')}
modalId={ModalIdentifiers.WARN_METRIC_ACK}
dialogProps={{
warnMetricStatus: this.props.warnMetricStatus,
closeParentComponent: this.props.handleClose,
}}
>
{linkmessage}
</ToggleModalButtonRedux>
)}
</FormattedMessage>
}
</span>
</span>
</OverlayTrigger>
{closeButton}
Expand Down
Loading

0 comments on commit 1376ff7

Please sign in to comment.