mirror of
https://github.com/mattermost/mattermost.git
synced 2026-05-28 04:35:04 -04:00
Refactor admin settings to functional components (#28931)
* Refactor admin settings to functional components * Address feedback * Fix types
This commit is contained in:
parent
89ea59f590
commit
b276fbc809
20 changed files with 643 additions and 33 deletions
|
|
@ -0,0 +1,39 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AdminSettings should match snapshot 1`] = `
|
||||
<div>
|
||||
<form
|
||||
class="form-horizontal"
|
||||
role="form"
|
||||
>
|
||||
<div
|
||||
class="wrapper--fixed"
|
||||
>
|
||||
<div
|
||||
class="admin-console__header"
|
||||
>
|
||||
Some title
|
||||
</div>
|
||||
Some settings
|
||||
<div
|
||||
class="admin-console-save"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
data-testid="saveSetting"
|
||||
disabled=""
|
||||
id="saveSetting"
|
||||
type="submit"
|
||||
>
|
||||
<span>
|
||||
Save
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="error-message"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {ComponentProps} from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import AdminSettings from './admin_settings';
|
||||
|
||||
function getProps(): ComponentProps<typeof AdminSettings> {
|
||||
return {
|
||||
doSubmit: jest.fn(),
|
||||
renderSettings: () => <>{'Some settings'}</>,
|
||||
renderTitle: () => <>{'Some title'}</>,
|
||||
saveNeeded: false,
|
||||
saving: false,
|
||||
isDisabled: false,
|
||||
serverError: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
describe('AdminSettings', () => {
|
||||
it('should match snapshot', () => {
|
||||
const props = getProps();
|
||||
const {container} = renderWithContext(<AdminSettings {...props}/>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('save button should be disabled if there is no save needed', () => {
|
||||
const props = getProps();
|
||||
props.saveNeeded = false;
|
||||
const {rerender} = renderWithContext(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.getByTestId('saveSetting')).toBeDisabled();
|
||||
|
||||
props.saveNeeded = true;
|
||||
|
||||
rerender(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.getByTestId('saveSetting')).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('save button should be disabled if the component is disabled', () => {
|
||||
const props = getProps();
|
||||
props.saveNeeded = true;
|
||||
props.isDisabled = true;
|
||||
const {rerender} = renderWithContext(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.getByTestId('saveSetting')).toBeDisabled();
|
||||
|
||||
props.isDisabled = false;
|
||||
|
||||
rerender(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.getByTestId('saveSetting')).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('should call doSubmit when the save button is pressed', () => {
|
||||
const props = getProps();
|
||||
props.saveNeeded = true;
|
||||
|
||||
const {rerender} = renderWithContext(<AdminSettings {...props}/>);
|
||||
|
||||
expect(props.doSubmit).not.toHaveBeenCalled();
|
||||
screen.getByTestId('saveSetting').click();
|
||||
expect(props.doSubmit).toHaveBeenCalled();
|
||||
|
||||
props.doSubmit = jest.fn();
|
||||
rerender(<AdminSettings {...props}/>);
|
||||
|
||||
expect(props.doSubmit).not.toHaveBeenCalled();
|
||||
screen.getByTestId('saveSetting').click();
|
||||
expect(props.doSubmit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('show saving message while saving', () => {
|
||||
const props = getProps();
|
||||
props.saving = true;
|
||||
const {rerender} = renderWithContext(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.getByText('Saving Config...')).toBeInTheDocument();
|
||||
|
||||
props.saving = false;
|
||||
|
||||
rerender(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.queryByText('Saving Config...')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render the specified title and settings', () => {
|
||||
const titleTestId = 'some test id for the title';
|
||||
const settingsTestId = 'some test id for the settings';
|
||||
const props = getProps();
|
||||
props.renderTitle = () => <span data-testid={titleTestId}>{'hello world'}</span>;
|
||||
props.renderSettings = () => <span data-testid={settingsTestId}>{'hello world'}</span>;
|
||||
|
||||
renderWithContext(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.getByTestId(titleTestId)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(settingsTestId)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show the error message', () => {
|
||||
const serverError = 'some error';
|
||||
const props = getProps();
|
||||
props.serverError = serverError;
|
||||
const {rerender} = renderWithContext(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.getByText(serverError)).toBeInTheDocument();
|
||||
|
||||
props.serverError = undefined;
|
||||
rerender(<AdminSettings {...props}/>);
|
||||
|
||||
expect(screen.queryByText(serverError)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
/* eslint-disable react/require-optimization */
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import FormError from 'components/form_error';
|
||||
import SaveButton from 'components/save_button';
|
||||
import AdminHeader from 'components/widgets/admin_console/admin_header';
|
||||
import WithTooltip from 'components/with_tooltip';
|
||||
|
||||
type Props = {
|
||||
isDisabled?: boolean;
|
||||
renderTitle: () => JSX.Element;
|
||||
renderSettings: () => React.ReactNode;
|
||||
doSubmit: () => void;
|
||||
saving: boolean;
|
||||
saveNeeded: boolean;
|
||||
serverError?: React.ReactNode;
|
||||
}
|
||||
|
||||
const AdminSettings = ({
|
||||
doSubmit,
|
||||
renderSettings,
|
||||
renderTitle,
|
||||
isDisabled,
|
||||
saving,
|
||||
saveNeeded,
|
||||
serverError,
|
||||
}: Props) => {
|
||||
const handleSubmit = useCallback((e: React.FormEvent<HTMLFormElement> | React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
|
||||
doSubmit();
|
||||
}, [doSubmit]);
|
||||
|
||||
return (
|
||||
<form
|
||||
className='form-horizontal'
|
||||
role='form'
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<div className='wrapper--fixed'>
|
||||
<AdminHeader>
|
||||
{renderTitle()}
|
||||
</AdminHeader>
|
||||
{renderSettings()}
|
||||
<div className='admin-console-save'>
|
||||
<SaveButton
|
||||
saving={saving}
|
||||
disabled={isDisabled || !saveNeeded}
|
||||
onClick={handleSubmit}
|
||||
savingMessage={
|
||||
<FormattedMessage
|
||||
id='admin.saving'
|
||||
defaultMessage='Saving Config...'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<WithTooltip
|
||||
id='error-tooltip'
|
||||
placement='top'
|
||||
title={serverError ?? ''}
|
||||
>
|
||||
<div
|
||||
className='error-message'
|
||||
>
|
||||
<FormError error={serverError}/>
|
||||
</div>
|
||||
</WithTooltip>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default AdminSettings;
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {useCallback, useState} from 'react';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import type {AdminConfig} from '@mattermost/types/config';
|
||||
|
||||
import {patchConfig} from 'mattermost-redux/actions/admin';
|
||||
import {getConfig, getEnvironmentConfig} from 'mattermost-redux/selectors/entities/admin';
|
||||
import {getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||
|
||||
import {setNavigationBlocked} from 'actions/admin_actions';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import type {GetConfigFromStateFunction, GetStateFromConfigFunction, HandleSaveFunction} from './types';
|
||||
import {isSetByEnv} from './utils';
|
||||
|
||||
export function useIsSetByEnv(path: string) {
|
||||
return useSelector((state: GlobalState) => isSetByEnv(getEnvironmentConfig(state), path));
|
||||
}
|
||||
|
||||
export const useAdminSettingState = <T extends Record<string, any>>(
|
||||
getConfigFromState: GetConfigFromStateFunction<T>,
|
||||
getStateFromConfig: GetStateFromConfigFunction<T>,
|
||||
preSave?: (values: T) => Promise<string>,
|
||||
handleSaved?: HandleSaveFunction,
|
||||
) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const license = useSelector(getLicense);
|
||||
const config = useSelector(getConfig) as AdminConfig;
|
||||
|
||||
const [saveNeeded, setSaveNeeded] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [serverError, setServerError] = useState<string | undefined>(undefined);
|
||||
const [settingValues, setSettingValues] = useState<T>(() => getStateFromConfig(config, license));
|
||||
|
||||
const handleChange = useCallback((id: string, value: unknown) => {
|
||||
setSaveNeeded(true);
|
||||
setSettingValues((prev) => ({
|
||||
...prev,
|
||||
[id]: value,
|
||||
}));
|
||||
dispatch(setNavigationBlocked(true));
|
||||
}, [dispatch]);
|
||||
|
||||
const doSubmit = useCallback(async () => {
|
||||
setSaving(true);
|
||||
setServerError(undefined);
|
||||
|
||||
const configToPatch = getConfigFromState(settingValues);
|
||||
|
||||
if (preSave) {
|
||||
const preSaveError = await preSave(settingValues);
|
||||
if (preSaveError) {
|
||||
setSaving(false);
|
||||
setServerError(preSaveError);
|
||||
handleSaved?.(configToPatch, handleChange);
|
||||
}
|
||||
}
|
||||
|
||||
const {data, error} = await dispatch(patchConfig(configToPatch));
|
||||
|
||||
if (data) {
|
||||
setSettingValues(getStateFromConfig(data, license));
|
||||
setSaveNeeded(false);
|
||||
setSaving(false);
|
||||
|
||||
dispatch(setNavigationBlocked(false));
|
||||
handleSaved?.(configToPatch, handleChange);
|
||||
} else if (error) {
|
||||
setSaving(false);
|
||||
setServerError(error.message);
|
||||
|
||||
handleSaved?.(configToPatch, handleChange);
|
||||
}
|
||||
}, [dispatch, getConfigFromState, getStateFromConfig, handleChange, handleSaved, license, preSave, settingValues]);
|
||||
|
||||
return {handleChange, doSubmit, saveNeeded, saving, serverError, settingValues};
|
||||
};
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {AdminConfig, ClientLicense} from '@mattermost/types/config';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
export type HandleSaveFunction = (config: DeepPartial<AdminConfig>, updateSettings: (id: string, value: unknown) => void) => void;
|
||||
export type GetStateFromConfigFunction<State extends Record<string, any>> = (config: AdminConfig, license: ClientLicense) => State;
|
||||
export type GetConfigFromStateFunction<State extends Record<string, any>> = (state: State) => DeepPartial<AdminConfig>;
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {isSetByEnv, parseIntNonNegative, parseIntNonZero, parseIntZeroOrMin} from './utils';
|
||||
|
||||
describe('isSetByEnv', () => {
|
||||
it('properly returns true when the environment set the path', () => {
|
||||
const result = isSetByEnv({
|
||||
AnalyticsSettings: {
|
||||
MaxUsersForStatistics: true,
|
||||
},
|
||||
}, 'AnalyticsSettings.MaxUsersForStatistics');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('properly returns false when the environment does not set the path', () => {
|
||||
const result = isSetByEnv({
|
||||
AnalyticsSettings: {
|
||||
MaxUsersForStatistics: false,
|
||||
},
|
||||
}, 'AnalyticsSettings.MaxUsersForStatistics');
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('properly returns false when the path does not exist', () => {
|
||||
let result = isSetByEnv({}, 'AnalyticsSettings.MaxUsersForStatistics');
|
||||
expect(result).toBe(false);
|
||||
|
||||
result = isSetByEnv({
|
||||
AnalyticsSettings: {
|
||||
MaxUsersForStatistics: true,
|
||||
},
|
||||
}, 'not.available.path');
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseIntNonNegative', () => {
|
||||
it('properly parse a positive number', () => {
|
||||
let result = parseIntNonNegative('123');
|
||||
expect(result).toBe(123);
|
||||
|
||||
result = parseIntNonNegative(123);
|
||||
expect(result).toBe(123);
|
||||
});
|
||||
|
||||
it('properly defaults to default value if negative', () => {
|
||||
let result = parseIntNonNegative('-1', 100);
|
||||
expect(result).toBe(100);
|
||||
|
||||
result = parseIntNonNegative(-1, 100);
|
||||
expect(result).toBe(100);
|
||||
});
|
||||
|
||||
it('properly defaults to default value if not a number', () => {
|
||||
const result = parseIntNonNegative('hello world', 100);
|
||||
expect(result).toBe(100);
|
||||
});
|
||||
|
||||
it('string float values are rounded down', () => {
|
||||
let result = parseIntNonNegative('1.99999', 100);
|
||||
expect(result).toBe(1);
|
||||
|
||||
result = parseIntNonNegative(199.99999, 100);
|
||||
expect(result).toBe(199.99999);
|
||||
});
|
||||
|
||||
it('properly defaults to 0 if no default is given', () => {
|
||||
let result = parseIntNonNegative('-123');
|
||||
expect(result).toBe(0);
|
||||
|
||||
result = parseIntNonNegative(-123);
|
||||
expect(result).toBe(0);
|
||||
|
||||
result = parseIntNonNegative('hello world');
|
||||
expect(result).toBe(0);
|
||||
|
||||
result = parseIntNonNegative('-1.9999999');
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseIntZeroOrMin', () => {
|
||||
it('parse a positive number', () => {
|
||||
let result = parseIntZeroOrMin('123', 100);
|
||||
expect(result).toBe(123);
|
||||
|
||||
result = parseIntZeroOrMin(123, 100);
|
||||
expect(result).toBe(123);
|
||||
});
|
||||
|
||||
it('defaults to 0 if the value is negative or 0', () => {
|
||||
let result = parseIntZeroOrMin('-1', 100);
|
||||
expect(result).toBe(0);
|
||||
|
||||
result = parseIntZeroOrMin(-1, 100);
|
||||
expect(result).toBe(0);
|
||||
|
||||
result = parseIntZeroOrMin('0', 100);
|
||||
expect(result).toBe(0);
|
||||
|
||||
result = parseIntZeroOrMin(0, 100);
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
|
||||
it('defaults to minimum value if lower', () => {
|
||||
let result = parseIntZeroOrMin('99', 100);
|
||||
expect(result).toBe(100);
|
||||
|
||||
result = parseIntZeroOrMin(99, 100);
|
||||
expect(result).toBe(100);
|
||||
});
|
||||
|
||||
it('defaults to 0 value if not a number', () => {
|
||||
const result = parseIntZeroOrMin('hello world', 100);
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
|
||||
it('string float values are rounded down', () => {
|
||||
let result = parseIntZeroOrMin('199.99999', 100);
|
||||
expect(result).toBe(199);
|
||||
|
||||
result = parseIntZeroOrMin(199.99999, 100);
|
||||
expect(result).toBe(199.99999);
|
||||
});
|
||||
|
||||
it('defaults to 1 if no min is given', () => {
|
||||
let result = parseIntZeroOrMin('2');
|
||||
expect(result).toBe(2);
|
||||
|
||||
result = parseIntZeroOrMin(0.00000000001);
|
||||
expect(result).toBe(1);
|
||||
|
||||
result = parseIntZeroOrMin(1.00000000001);
|
||||
expect(result).toBe(1.00000000001);
|
||||
});
|
||||
|
||||
it('minimum allow float numbers', () => {
|
||||
let result = parseIntZeroOrMin('1', 1.9999);
|
||||
expect(result).toBe(1.9999);
|
||||
|
||||
result = parseIntZeroOrMin(1.9998, 1.9999);
|
||||
expect(result).toBe(1.9999);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseIntNonZero', () => {
|
||||
it('parse a positive number', () => {
|
||||
let result = parseIntNonZero('123', 100, 50);
|
||||
expect(result).toBe(123);
|
||||
|
||||
result = parseIntNonZero(123, 100, 50);
|
||||
expect(result).toBe(123);
|
||||
});
|
||||
|
||||
it('defaults to default value if the value lower than mininum value', () => {
|
||||
let result = parseIntNonZero('-1', 100, 0);
|
||||
expect(result).toBe(100);
|
||||
|
||||
result = parseIntNonZero(-1, 100, 0);
|
||||
expect(result).toBe(100);
|
||||
|
||||
result = parseIntNonZero('150', 100, 200);
|
||||
expect(result).toBe(100);
|
||||
|
||||
result = parseIntNonZero(150, 100, 200);
|
||||
expect(result).toBe(100);
|
||||
});
|
||||
|
||||
it('minimum value defaults to 1', () => {
|
||||
let result = parseIntNonZero('1', 100);
|
||||
expect(result).toBe(1);
|
||||
|
||||
result = parseIntNonZero('0', 100);
|
||||
expect(result).toBe(100);
|
||||
|
||||
result = parseIntNonZero(1, 100);
|
||||
expect(result).toBe(1);
|
||||
|
||||
result = parseIntNonZero(0.999999999, 100);
|
||||
expect(result).toBe(100);
|
||||
});
|
||||
|
||||
it('default value defaults to 1', () => {
|
||||
let result = parseIntNonZero('99', undefined, 100);
|
||||
expect(result).toBe(1);
|
||||
|
||||
result = parseIntNonZero('hello world');
|
||||
expect(result).toBe(1);
|
||||
|
||||
result = parseIntNonZero(99.9999, undefined, 100);
|
||||
expect(result).toBe(1);
|
||||
});
|
||||
|
||||
it('defaults to default value if not a number', () => {
|
||||
const result = parseIntNonZero('hello world', 100);
|
||||
expect(result).toBe(100);
|
||||
});
|
||||
|
||||
it('string float values are rounded down', () => {
|
||||
let result = parseIntNonZero('199.99999', 100);
|
||||
expect(result).toBe(199);
|
||||
|
||||
result = parseIntNonZero(199.99999, 100);
|
||||
expect(result).toBe(199.99999);
|
||||
});
|
||||
|
||||
it('default and minimum allow float numbers', () => {
|
||||
let result = parseIntNonZero('1', 1.9999, 2);
|
||||
expect(result).toBe(1.9999);
|
||||
|
||||
result = parseIntNonZero(1.9998, 10, 1.9999);
|
||||
expect(result).toBe(10);
|
||||
});
|
||||
|
||||
it('minimum and default allow negative numbers', () => {
|
||||
let result = parseIntNonZero('1', -10, 2);
|
||||
expect(result).toBe(-10);
|
||||
|
||||
result = parseIntNonZero('-5', 10, -2);
|
||||
expect(result).toBe(10);
|
||||
|
||||
result = parseIntNonZero('-5', 10, -6);
|
||||
expect(result).toBe(-5);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {AdminConfig, EnvironmentConfig} from '@mattermost/types/config';
|
||||
|
||||
function getConfigValue(config: AdminConfig | Partial<EnvironmentConfig>, path: string) {
|
||||
const pathParts = path.split('.');
|
||||
|
||||
return pathParts.reduce((obj: object | null, pathPart) => {
|
||||
if (!obj) {
|
||||
return null;
|
||||
}
|
||||
return obj[(pathPart as keyof object)];
|
||||
}, config);
|
||||
}
|
||||
|
||||
export function isSetByEnv(environmentConfig: Partial<EnvironmentConfig>, path: string) {
|
||||
return Boolean(getConfigValue(environmentConfig, path));
|
||||
}
|
||||
|
||||
export const parseIntNonNegative = (str: string | number, defaultValue?: number) => {
|
||||
const n = typeof str === 'string' ? parseInt(str, 10) : str;
|
||||
|
||||
if (isNaN(n) || n < 0) {
|
||||
if (defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
export const parseIntZeroOrMin = (str: string | number, minimumValue = 1) => {
|
||||
const n = typeof str === 'string' ? parseInt(str, 10) : str;
|
||||
|
||||
if (isNaN(n) || n < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (n > 0 && n < minimumValue) {
|
||||
return minimumValue;
|
||||
}
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
export const parseIntNonZero = (str: string | number, defaultValue?: number, minimumValue = 1) => {
|
||||
const n = typeof str === 'string' ? parseInt(str, 10) : str;
|
||||
|
||||
if (isNaN(n) || n < minimumValue) {
|
||||
if (defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
};
|
||||
|
|
@ -13,10 +13,10 @@ import ExternalLink from 'components/external_link';
|
|||
|
||||
import {JobStatuses, JobTypes} from 'utils/constants';
|
||||
|
||||
import AdminSettings from './admin_settings';
|
||||
import type {BaseProps, BaseState} from './admin_settings';
|
||||
import BooleanSetting from './boolean_setting';
|
||||
import JobsTable from './jobs';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import type {BaseProps, BaseState} from './old_admin_settings';
|
||||
import RequestButton from './request_button/request_button';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
|
@ -60,7 +60,7 @@ export const searchableStrings = [
|
|||
messages.enableSearchingDescription,
|
||||
];
|
||||
|
||||
export default class BleveSettings extends AdminSettings<Props, State> {
|
||||
export default class BleveSettings extends OLDAdminSettings<Props, State> {
|
||||
getConfigFromState = (config: Props['config']) => {
|
||||
if (config && config.BleveSettings) {
|
||||
config.BleveSettings.IndexDir = this.state.indexDir;
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ import WarningIcon from 'components/widgets/icons/fa_warning_icon';
|
|||
|
||||
import {DocLinks} from 'utils/constants';
|
||||
|
||||
import type {BaseProps, BaseState} from './admin_settings';
|
||||
import AdminSettings from './admin_settings';
|
||||
import BooleanSetting from './boolean_setting';
|
||||
import ClusterTableContainer from './cluster_table_container';
|
||||
import type {BaseProps, BaseState} from './old_admin_settings';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ export const searchableStrings = [
|
|||
messages.gossipPortDesc,
|
||||
];
|
||||
|
||||
export default class ClusterSettings extends AdminSettings<Props, State> {
|
||||
export default class ClusterSettings extends OLDAdminSettings<Props, State> {
|
||||
getConfigFromState = (config: AdminConfig) => {
|
||||
config.ClusterSettings.Enable = this.state.Enable;
|
||||
config.ClusterSettings.ClusterName = this.state.ClusterName;
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ import type {TermsOfService} from '@mattermost/types/terms_of_service';
|
|||
|
||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||
|
||||
import AdminSettings from 'components/admin_console/admin_settings';
|
||||
import type {BaseProps, BaseState} from 'components/admin_console/admin_settings';
|
||||
import BooleanSetting from 'components/admin_console/boolean_setting';
|
||||
import OLDAdminSettings from 'components/admin_console/old_admin_settings';
|
||||
import type {BaseProps, BaseState} from 'components/admin_console/old_admin_settings';
|
||||
import SettingsGroup from 'components/admin_console/settings_group';
|
||||
import TextSetting from 'components/admin_console/text_setting';
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
|
|
@ -66,7 +66,7 @@ export const searchableStrings = [
|
|||
messages.termsOfServiceReAcceptanceHelp,
|
||||
];
|
||||
|
||||
export default class CustomTermsOfServiceSettings extends AdminSettings<Props, State> {
|
||||
export default class CustomTermsOfServiceSettings extends OLDAdminSettings<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ import ExternalLink from 'components/external_link';
|
|||
|
||||
import {DocLinks} from 'utils/constants';
|
||||
|
||||
import type {BaseState} from './admin_settings';
|
||||
import AdminSettings from './admin_settings';
|
||||
import BooleanSetting from './boolean_setting';
|
||||
import MigrationsTable from './database';
|
||||
import type {BaseState} from './old_admin_settings';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import RequestButton from './request_button/request_button';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
|
@ -98,7 +98,7 @@ export const searchableStrings: Array<string|MessageDescriptor|[MessageDescripto
|
|||
messages.traceDescription,
|
||||
];
|
||||
|
||||
export default class DatabaseSettings extends AdminSettings<Props, State> {
|
||||
export default class DatabaseSettings extends OLDAdminSettings<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ import ExternalLink from 'components/external_link';
|
|||
|
||||
import {DocLinks, JobStatuses, JobTypes} from 'utils/constants';
|
||||
|
||||
import AdminSettings from './admin_settings';
|
||||
import type {BaseProps, BaseState} from './admin_settings';
|
||||
import BooleanSetting from './boolean_setting';
|
||||
import JobsTable from './jobs';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import type {BaseProps, BaseState} from './old_admin_settings';
|
||||
import RequestButton from './request_button/request_button';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
|
@ -98,7 +98,7 @@ export const searchableStrings: Array<string|MessageDescriptor|[MessageDescripto
|
|||
messages.enableSearchingDescription,
|
||||
];
|
||||
|
||||
export default class ElasticsearchSettings extends AdminSettings<Props, State> {
|
||||
export default class ElasticsearchSettings extends OLDAdminSettings<Props, State> {
|
||||
getConfigFromState = (config: AdminConfig) => {
|
||||
config.ElasticsearchSettings.ConnectionURL = this.state.connectionUrl;
|
||||
config.ElasticsearchSettings.Backend = this.state.backend;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import type {MessageExportSettings as MessageExportSettingsClass} from 'componen
|
|||
|
||||
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
|
||||
import type {BaseProps} from './admin_settings';
|
||||
import type {BaseProps} from './old_admin_settings';
|
||||
|
||||
describe('components/MessageExportSettings', () => {
|
||||
test('should match snapshot, disabled, actiance', () => {
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ import ExternalLink from 'components/external_link';
|
|||
|
||||
import {DocLinks, JobTypes, exportFormats} from 'utils/constants';
|
||||
|
||||
import type {BaseProps, BaseState} from './admin_settings';
|
||||
import AdminSettings from './admin_settings';
|
||||
import BooleanSetting from './boolean_setting';
|
||||
import DropdownSetting from './dropdown_setting';
|
||||
import JobsTable from './jobs';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import type {BaseProps, BaseState} from './old_admin_settings';
|
||||
import RadioSetting from './radio_setting';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
|
@ -82,7 +82,7 @@ string | MessageDescriptor | [MessageDescriptor, { [key: string]: any }]
|
|||
messages.globalRelayEmailAddress_description,
|
||||
];
|
||||
|
||||
export class MessageExportSettings extends AdminSettings<BaseProps & WrappedComponentProps, State> {
|
||||
export class MessageExportSettings extends OLDAdminSettings<BaseProps & WrappedComponentProps, State> {
|
||||
getConfigFromState = (config: AdminConfig) => {
|
||||
config.MessageExportSettings.EnableExport = this.state.enableComplianceExport;
|
||||
config.MessageExportSettings.ExportFormat = this.state.exportFormat;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ type ClientErrorPlaceholder = {
|
|||
server_error_id: string;
|
||||
}
|
||||
|
||||
export default abstract class AdminSettings <Props extends BaseProps, State extends BaseState> extends React.Component<Props, State> {
|
||||
export default abstract class OLDAdminSettings <Props extends BaseProps, State extends BaseState> extends React.Component<Props, State> {
|
||||
public constructor(props: Props) {
|
||||
super(props);
|
||||
const stateInit = {
|
||||
|
|
@ -9,7 +9,7 @@ import type {DeepPartial} from '@mattermost/types/utilities';
|
|||
|
||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||
|
||||
import type {BaseProps} from 'components/admin_console/admin_settings';
|
||||
import type {BaseProps} from 'components/admin_console/old_admin_settings';
|
||||
import ExternalLink from 'components/external_link';
|
||||
import FormError from 'components/form_error';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import type {DeepPartial} from '@mattermost/types/utilities';
|
|||
import Constants from 'utils/constants';
|
||||
import {passwordErrors} from 'utils/password';
|
||||
|
||||
import AdminSettings from './admin_settings';
|
||||
import type {BaseProps, BaseState} from './admin_settings';
|
||||
import BlockableLink from './blockable_link';
|
||||
import BooleanSetting from './boolean_setting';
|
||||
import CheckboxSetting from './checkbox_setting';
|
||||
import type {BaseProps, BaseState} from './old_admin_settings';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import Setting from './setting';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
|
@ -84,7 +84,7 @@ function getPasswordErrorsMessage(lowercase?: boolean, uppercase?: boolean, numb
|
|||
|
||||
return passwordErrors[key as KeyType];
|
||||
}
|
||||
export default class PasswordSettings extends AdminSettings<Props, State> {
|
||||
export default class PasswordSettings extends OLDAdminSettings<Props, State> {
|
||||
sampleErrorMsg: React.ReactNode;
|
||||
|
||||
constructor(props: Props) {
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import {appsPluginID} from 'utils/apps';
|
|||
import {DeveloperLinks} from 'utils/constants';
|
||||
import * as Utils from 'utils/utils';
|
||||
|
||||
import AdminSettings from '../admin_settings';
|
||||
import type {BaseProps, BaseState} from '../admin_settings';
|
||||
import BooleanSetting from '../boolean_setting';
|
||||
import OLDAdminSettings from '../old_admin_settings';
|
||||
import type {BaseProps, BaseState} from '../old_admin_settings';
|
||||
import SettingsGroup from '../settings_group';
|
||||
import TextSetting from '../text_setting';
|
||||
|
||||
|
|
@ -495,7 +495,7 @@ type State = BaseState & {
|
|||
requirePluginSignature: boolean;
|
||||
removing: string | null;
|
||||
}
|
||||
class PluginManagement extends AdminSettings<Props, State> {
|
||||
class PluginManagement extends OLDAdminSettings<Props, State> {
|
||||
private fileInput: React.RefObject<HTMLInputElement>;
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import ExternalLink from 'components/external_link';
|
|||
|
||||
import {Constants, DocLinks} from 'utils/constants';
|
||||
|
||||
import AdminSettings from './admin_settings';
|
||||
import type {BaseProps, BaseState} from './admin_settings';
|
||||
import DropdownSetting from './dropdown_setting';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import type {BaseProps, BaseState} from './old_admin_settings';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ export const searchableStrings = [
|
|||
messages.pushServerTitle,
|
||||
];
|
||||
|
||||
class PushSettings extends AdminSettings<Props, State> {
|
||||
class PushSettings extends OLDAdminSettings<Props, State> {
|
||||
canSave = () => {
|
||||
return this.state.pushNotificationServerType !== PUSH_NOTIFICATIONS_MHPNS || this.state.agree;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import {FormattedMessage, defineMessage, defineMessages} from 'react-intl';
|
|||
|
||||
import type {AdminConfig, ClientLicense, ServiceSettings} from '@mattermost/types/config';
|
||||
|
||||
import AdminSettings from './admin_settings';
|
||||
import type {BaseState, BaseProps} from './admin_settings';
|
||||
import BooleanSetting from './boolean_setting';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import type {BaseState, BaseProps} from './old_admin_settings';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ export const searchableStrings = [
|
|||
messages.sessionIdleTimeoutDesc,
|
||||
];
|
||||
|
||||
export default class SessionLengthSettings extends AdminSettings<Props, State> {
|
||||
export default class SessionLengthSettings extends OLDAdminSettings<Props, State> {
|
||||
getConfigFromState = (config: AdminConfig) => {
|
||||
const MINIMUM_IDLE_TIMEOUT = 5;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue