[MM-52844] : Migrate "components/admin_console/push_settings.jsx" and tests to Typescript (#23616)

* migrate bleve_settings and tests to typescript

* fix linter issues

* update JobType type definition

* migrate push_settings to typescript

* add tests

* update to general type, fix test

* fix failing test

* Merge branch 'master' into fix-for-issue-23416

* update snapshot

* revert unwanted changes

* revert unwanted changes

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Nitin Suresh 2023-06-22 08:54:36 -07:00 committed by GitHub
parent 178dbb9f95
commit f333085f8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 422 additions and 13 deletions

View File

@ -312,6 +312,8 @@ const defaultServerConfig: AdminConfig = {
ConnectionSecurity: '',
SendPushNotifications: true,
PushNotificationServer: 'https://push-test.mattermost.com',
PushNotificationServerType: 'custom',
PushNotificationServerLocation: 'us',
PushNotificationContents: 'full',
PushNotificationBuffer: 1000,
EnableEmailBatching: false,

View File

@ -0,0 +1,330 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/PushSettings should match snapshot, licensed 1`] = `
<form
className="form-horizontal"
onSubmit={[Function]}
role="form"
>
<div
className="wrapper--fixed"
>
<AdminHeader>
<MemoizedFormattedMessage
defaultMessage="Push Notification Server"
id="admin.environment.pushNotificationServer"
/>
</AdminHeader>
<SettingsGroup>
<DropdownSetting
helpText={null}
id="pushNotificationServerType"
isDisabled={false}
label={
<Memo(MemoizedFormattedMessage)
defaultMessage="Enable Push Notifications: "
id="admin.email.pushTitle"
/>
}
onChange={[Function]}
setByEnv={false}
value="mhpns"
values={
Array [
Object {
"text": "Do not send push notifications",
"value": "off",
},
Object {
"text": "Use HPNS connection with uptime SLA to send notifications to iOS and Android apps",
"value": "mhpns",
},
Object {
"text": "Use TPNS connection to send notifications to iOS and Android apps",
"value": "mtpns",
},
Object {
"text": "Manually enter Push Notification Service location",
"value": "custom",
},
]
}
/>
<DropdownSetting
id="pushNotificationServerLocation"
isDisabled={false}
label={
<Memo(MemoizedFormattedMessage)
defaultMessage="Push Notification Server location:"
id="admin.email.pushServerLocationTitle"
/>
}
onChange={[Function]}
setByEnv={false}
value="us"
values={
Array [
Object {
"text": "US",
"value": "us",
},
Object {
"text": "Germany",
"value": "de",
},
]
}
/>
<div
className="form-group"
>
<div
className="col-sm-4"
/>
<div
className="col-sm-8"
>
<input
checked={false}
onChange={[Function]}
type="checkbox"
/>
<MemoizedFormattedMessage
defaultMessage=" I understand and accept the Mattermost Hosted Push Notification Service <linkTerms>Terms of Service</linkTerms> and <linkPrivacy>Privacy Policy</linkPrivacy>."
id="admin.email.agreeHPNS"
values={
Object {
"linkPrivacy": [Function],
"linkTerms": [Function],
}
}
/>
</div>
</div>
<AdminTextSetting
disabled={true}
helpText={
<Memo(MemoizedFormattedMessage)
defaultMessage="Download <linkIOS>Mattermost iOS app</linkIOS> from iTunes. Download <linkAndroid>Mattermost Android app</linkAndroid> from Google Play. Learn more about the <linkHPNS>Mattermost Hosted Push Notification Service</linkHPNS>."
id="admin.email.mhpnsHelp"
values={
Object {
"linkAndroid": [Function],
"linkHPNS": [Function],
"linkIOS": [Function],
}
}
/>
}
id="pushNotificationServer"
label={
<Memo(MemoizedFormattedMessage)
defaultMessage="Push Notification Server:"
id="admin.email.pushServerTitle"
/>
}
onChange={[Function]}
placeholder="E.g.: \\"https://push-test.mattermost.com\\""
setByEnv={false}
type="input"
value="https://push.mattermost.com"
/>
<AdminTextSetting
helpText={
<Memo(MemoizedFormattedMessage)
defaultMessage="Maximum total number of users in a channel before users typing messages, @all, @here, and @channel no longer send notifications because of performance."
id="admin.team.maxNotificationsPerChannelDescription"
/>
}
id="maxNotificationsPerChannel"
label={
<Memo(MemoizedFormattedMessage)
defaultMessage="Max Notifications Per Channel:"
id="admin.team.maxNotificationsPerChannelTitle"
/>
}
onChange={[Function]}
placeholder="E.g.: \\"1000\\""
setByEnv={false}
type="number"
value={1000}
/>
</SettingsGroup>
<div
className="admin-console-save"
>
<SaveButton
btnClass="btn-primary"
defaultMessage={
<Memo(MemoizedFormattedMessage)
defaultMessage="Save"
id="save_button.save"
/>
}
disabled={true}
extraClasses=""
onClick={[Function]}
saving={false}
savingMessage="Saving Config..."
/>
<div
className="error-message"
onMouseOut={[Function]}
onMouseOver={[Function]}
>
<FormError
error={null}
errors={Array []}
/>
</div>
<Overlay
animation={[Function]}
placement="top"
rootClose={false}
show={false}
target={null}
>
<Tooltip
id="error-tooltip"
/>
</Overlay>
</div>
</div>
</form>
`;
exports[`components/PushSettings should match snapshot, unlicensed 1`] = `
<form
className="form-horizontal"
onSubmit={[Function]}
role="form"
>
<div
className="wrapper--fixed"
>
<AdminHeader>
<MemoizedFormattedMessage
defaultMessage="Push Notification Server"
id="admin.environment.pushNotificationServer"
/>
</AdminHeader>
<SettingsGroup>
<DropdownSetting
helpText={null}
id="pushNotificationServerType"
isDisabled={false}
label={
<Memo(MemoizedFormattedMessage)
defaultMessage="Enable Push Notifications: "
id="admin.email.pushTitle"
/>
}
onChange={[Function]}
setByEnv={false}
value="custom"
values={
Array [
Object {
"text": "Do not send push notifications",
"value": "off",
},
Object {
"text": "Use TPNS connection to send notifications to iOS and Android apps",
"value": "mtpns",
},
Object {
"text": "Manually enter Push Notification Service location",
"value": "custom",
},
]
}
/>
<AdminTextSetting
disabled={false}
helpText={
<Memo(MemoizedFormattedMessage)
defaultMessage="Learn more about compiling and deploying your own mobile apps from an <link>Enterprise App Store</link>."
id="admin.email.easHelp"
values={
Object {
"link": [Function],
}
}
/>
}
id="pushNotificationServer"
label={
<Memo(MemoizedFormattedMessage)
defaultMessage="Push Notification Server:"
id="admin.email.pushServerTitle"
/>
}
onChange={[Function]}
placeholder="E.g.: \\"https://push-test.mattermost.com\\""
setByEnv={false}
type="input"
value="https://push.mattermost.com"
/>
<AdminTextSetting
helpText={
<Memo(MemoizedFormattedMessage)
defaultMessage="Maximum total number of users in a channel before users typing messages, @all, @here, and @channel no longer send notifications because of performance."
id="admin.team.maxNotificationsPerChannelDescription"
/>
}
id="maxNotificationsPerChannel"
label={
<Memo(MemoizedFormattedMessage)
defaultMessage="Max Notifications Per Channel:"
id="admin.team.maxNotificationsPerChannelTitle"
/>
}
onChange={[Function]}
placeholder="E.g.: \\"1000\\""
setByEnv={false}
type="number"
value={1000}
/>
</SettingsGroup>
<div
className="admin-console-save"
>
<SaveButton
btnClass="btn-primary"
defaultMessage={
<Memo(MemoizedFormattedMessage)
defaultMessage="Save"
id="save_button.save"
/>
}
disabled={true}
extraClasses=""
onClick={[Function]}
saving={false}
savingMessage="Saving Config..."
/>
<div
className="error-message"
onMouseOut={[Function]}
onMouseOver={[Function]}
>
<FormError
error={null}
errors={Array []}
/>
</div>
<Overlay
animation={[Function]}
placement="top"
rootClose={false}
show={false}
target={null}
>
<Tooltip
id="error-tooltip"
/>
</Overlay>
</div>
</div>
</form>
`;

View File

@ -56,7 +56,7 @@ import TeamDetails from './team_channel_settings/team/details';
import ChannelSettings from './team_channel_settings/channel';
import ChannelDetails from './team_channel_settings/channel/details';
import PasswordSettings from './password_settings.jsx';
import PushNotificationsSettings from './push_settings.jsx';
import PushNotificationsSettings from './push_settings';
import DataRetentionSettings from './data_retention_settings';
import GlobalDataRetentionForm from './data_retention_settings/global_policy_form';
import CustomDataRetentionForm from './data_retention_settings/custom_policy_form';

View File

@ -79,7 +79,7 @@ export default abstract class AdminSettings <Props extends BaseProps, State exte
}
};
protected handleChange = (id: string, value: boolean) => {
protected handleChange = (id: string, value: unknown) => {
this.setState((prevState) => ({
...prevState,
saveNeeded: true,

View File

@ -0,0 +1,61 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import PushSettings from 'components/admin_console/push_settings';
import {AdminConfig} from '@mattermost/types/config';
describe('components/PushSettings', () => {
test('should match snapshot, licensed', () => {
const config = {
EmailSettings: {
PushNotificationServer: 'https://push.mattermost.com',
PushNotificationServerType: 'mhpns',
SendPushNotifications: true,
},
TeamSettings: {
MaxNotificationsPerChannel: 1000,
},
} as AdminConfig;
const props = {
config,
license: {
IsLicensed: 'true',
MHPNS: 'true',
},
};
const wrapper = shallow(
<PushSettings {...props}/>,
);
wrapper.find('#pushNotificationServerType').simulate('change', 'pushNotificationServerType', 'mhpns');
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, unlicensed', () => {
const config = {
EmailSettings: {
PushNotificationServer: 'https://push.mattermost.com',
PushNotificationServerType: 'mhpns',
SendPushNotifications: true,
},
TeamSettings: {
MaxNotificationsPerChannel: 1000,
},
} as AdminConfig;
const props = {
config,
license: {},
};
const wrapper = shallow(
<PushSettings {...props}/>,
);
expect(wrapper).toMatchSnapshot();
});
});

View File

@ -9,16 +9,29 @@ import ExternalLink from 'components/external_link';
import {Constants, DocLinks} from 'utils/constants';
import * as Utils from 'utils/utils';
import AdminSettings from './admin_settings';
import AdminSettings, {BaseProps, BaseState} from './admin_settings';
import DropdownSetting from './dropdown_setting.jsx';
import SettingsGroup from './settings_group';
import TextSetting from './text_setting';
import {AdminConfig, ClientLicense, EmailSettings} from '@mattermost/types/config';
type Props = BaseProps & {
config: AdminConfig;
license: ClientLicense;
};
type State = BaseState & {
pushNotificationServer: string;
pushNotificationServerType: EmailSettings['PushNotificationServerType'];
pushNotificationServerLocation: EmailSettings['PushNotificationServerLocation'];
agree: boolean;
maxNotificationsPerChannel: number;
};
const PUSH_NOTIFICATIONS_OFF = 'off';
const PUSH_NOTIFICATIONS_MHPNS = 'mhpns';
const PUSH_NOTIFICATIONS_MTPNS = 'mtpns';
const PUSH_NOTIFICATIONS_CUSTOM = 'custom';
const PUSH_NOTIFICATIONS_LOCATION_US = 'us';
const PUSH_NOTIFICATIONS_LOCATION_DE = 'de';
@ -30,18 +43,18 @@ const PUSH_NOTIFICATIONS_SERVER_DIC = {
const DROPDOWN_ID_SERVER_TYPE = 'pushNotificationServerType';
const DROPDOWN_ID_SERVER_LOCATION = 'pushNotificationServerLocation';
export default class PushSettings extends AdminSettings {
export default class PushSettings extends AdminSettings<Props, State> {
canSave = () => {
return this.state.pushNotificationServerType !== PUSH_NOTIFICATIONS_MHPNS || this.state.agree;
};
handleAgreeChange = (e) => {
handleAgreeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({
agree: e.target.checked,
});
};
handleDropdownChange = (id, value) => {
handleDropdownChange = (id: string, value: EmailSettings['PushNotificationServerType'] | EmailSettings['PushNotificationServerLocation']) => {
if (id === DROPDOWN_ID_SERVER_TYPE) {
this.setState({
agree: false,
@ -66,15 +79,15 @@ export default class PushSettings extends AdminSettings {
if (id === DROPDOWN_ID_SERVER_LOCATION) {
this.setState({
pushNotificationServer: PUSH_NOTIFICATIONS_SERVER_DIC[value],
pushNotificationServerLocation: value,
pushNotificationServer: PUSH_NOTIFICATIONS_SERVER_DIC[value as EmailSettings['PushNotificationServerLocation']],
pushNotificationServerLocation: value as EmailSettings['PushNotificationServerLocation'],
});
}
this.handleChange(id, value);
};
getConfigFromState = (config) => {
getConfigFromState = (config: Props['config']) => {
config.EmailSettings.SendPushNotifications = this.state.pushNotificationServerType !== PUSH_NOTIFICATIONS_OFF;
config.EmailSettings.PushNotificationServer = this.state.pushNotificationServer.trim();
config.TeamSettings.MaxNotificationsPerChannel = this.state.maxNotificationsPerChannel;
@ -82,10 +95,10 @@ export default class PushSettings extends AdminSettings {
return config;
};
getStateFromConfig(config) {
let pushNotificationServerType = PUSH_NOTIFICATIONS_CUSTOM;
getStateFromConfig(config: Props['config']) {
let pushNotificationServerType: EmailSettings['PushNotificationServerType'] = PUSH_NOTIFICATIONS_CUSTOM;
let agree = false;
let pushNotificationServerLocation = PUSH_NOTIFICATIONS_LOCATION_US;
let pushNotificationServerLocation: EmailSettings['PushNotificationServerLocation'] = PUSH_NOTIFICATIONS_LOCATION_US;
if (!config.EmailSettings.SendPushNotifications) {
pushNotificationServerType = PUSH_NOTIFICATIONS_OFF;
} else if (config.EmailSettings.PushNotificationServer === Constants.MHPNS_US &&
@ -346,6 +359,7 @@ export default class PushSettings extends AdminSettings {
onChange={this.handleChange}
disabled={this.props.isDisabled || this.state.pushNotificationServerType !== PUSH_NOTIFICATIONS_CUSTOM}
setByEnv={this.isSetByEnv('EmailSettings.PushNotificationServer')}
type='input'
/>
<TextSetting
id='maxNotificationsPerChannel'

View File

@ -526,6 +526,8 @@ export type EmailSettings = {
ConnectionSecurity: string;
SendPushNotifications: boolean;
PushNotificationServer: string;
PushNotificationServerType: 'off' | 'mhpns' | 'mtpns' | 'custom';
PushNotificationServerLocation: 'us' | 'de';
PushNotificationContents: string;
PushNotificationBuffer: number;
EnableEmailBatching: boolean;