* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { noop } from 'lodash';
import * as React from 'react';
import { setNewCodePeriod } from '../../../api/newCodePeriod';
import Modal from '../../../components/controls/Modal';
import { getNumberOfDaysDefaultValue } from '../../../helpers/new-code-definition';
import { Branch, BranchWithNewCodePeriod } from '../../../types/branch-like';
import { NewCodeDefinition, NewCodeDefinitionType } from '../../../types/new-code-definition';
-import { ParsedAnalysis } from '../../../types/project-activity';
import { getSettingValue, validateSetting } from '../utils';
import BaselineSettingAnalysis from './BaselineSettingAnalysis';
import BaselineSettingReferenceBranch from './BaselineSettingReferenceBranch';
analysis: string;
analysisDate?: Date;
days: string;
+ isChanged: boolean;
referenceBranch: string;
saving: boolean;
selected?: NewCodeDefinitionType;
days:
this.getValueFromProps(NewCodeDefinitionType.NumberOfDays) ||
getNumberOfDaysDefaultValue(generalSetting, inheritedSetting),
+ isChanged: false,
referenceBranch:
this.getValueFromProps(NewCodeDefinitionType.ReferenceBranch) || defaultBranch,
saving: false,
if (this.mounted) {
this.setState({
saving: false,
+ isChanged: false,
});
this.props.onClose(branch.name, {
type,
requestClose = () => this.props.onClose();
- handleSelectAnalysis = (analysis: ParsedAnalysis) =>
- this.setState({ analysis: analysis.key, analysisDate: analysis.date });
+ handleSelectDays = (days: string) => this.setState({ days, isChanged: true });
- handleSelectDays = (days: string) => this.setState({ days });
+ handleSelectReferenceBranch = (referenceBranch: string) =>
+ this.setState({ referenceBranch, isChanged: true });
- handleSelectReferenceBranch = (referenceBranch: string) => this.setState({ referenceBranch });
-
- handleSelectSetting = (selected: NewCodeDefinitionType) => this.setState({ selected });
+ handleSelectSetting = (selected: NewCodeDefinitionType) => {
+ this.setState((currentState) => ({ selected, isChanged: selected !== currentState.selected }));
+ };
render() {
const { branch, branchList } = this.props;
- const { analysis, days, referenceBranch, saving, selected } = this.state;
+ const { analysis, days, isChanged, referenceBranch, saving, selected } = this.state;
const header = translateWithParameters('baseline.new_code_period_for_branch_x', branch.name);
const currentSetting = branch.newCodePeriod?.type;
const currentSettingValue = branch.newCodePeriod?.value;
- const { isChanged, isValid } = validateSetting({
- analysis,
- currentSetting,
- currentSettingValue,
+ const isValid = validateSetting({
days,
referenceBranch,
selected,
/>
{currentSetting === NewCodeDefinitionType.SpecificAnalysis && (
<BaselineSettingAnalysis
- onSelect={() => {}}
+ onSelect={noop}
selected={selected === NewCodeDefinitionType.SpecificAnalysis}
/>
)}
analysis={analysis}
branch={branch.name}
component={this.props.component}
- onSelectAnalysis={this.handleSelectAnalysis}
+ onSelectAnalysis={noop}
/>
)}
</div>
import { Branch, BranchLike } from '../../../types/branch-like';
import { Feature } from '../../../types/features';
import { NewCodeDefinition, NewCodeDefinitionType } from '../../../types/new-code-definition';
-import { ParsedAnalysis } from '../../../types/project-activity';
import { Component } from '../../../types/types';
import '../styles.css';
import { getSettingValue } from '../utils';
currentSettingValue?: string;
days: string;
generalSetting?: NewCodeDefinition;
+ isChanged: boolean;
loading: boolean;
overrideGeneralSetting?: boolean;
referenceBranch?: string;
state: State = {
branchList: [],
days: getNumberOfDaysDefaultValue(),
+ isChanged: false,
loading: true,
saving: false,
};
currentSetting,
currentSettingValue,
generalSetting,
+ isChanged: false,
selected: currentSetting || generalSetting.type,
overrideGeneralSetting: Boolean(currentSetting),
days:
this.setState({
saving: false,
currentSetting: undefined,
+ isChanged: false,
selected: undefined,
success: true,
});
);
};
- handleSelectAnalysis = (analysis: ParsedAnalysis) => this.setState({ analysis: analysis.key });
-
- handleSelectDays = (days: string) => this.setState({ days });
+ handleSelectDays = (days: string) => this.setState({ days, isChanged: true });
handleSelectReferenceBranch = (referenceBranch: string) => {
- this.setState({ referenceBranch });
+ this.setState({ referenceBranch, isChanged: true });
};
handleCancel = () =>
}) => this.getUpdatedState({ generalSetting, currentSetting, currentSettingValue })
);
- handleSelectSetting = (selected?: NewCodeDefinitionType) => this.setState({ selected });
+ handleSelectSetting = (selected?: NewCodeDefinitionType) => {
+ this.setState((currentState) => ({
+ selected,
+ isChanged: selected !== currentState.selected,
+ }));
+ };
handleToggleSpecificSetting = (overrideGeneralSetting: boolean) =>
- this.setState({ overrideGeneralSetting });
+ this.setState((currentState) => ({
+ overrideGeneralSetting,
+ isChanged: currentState.overrideGeneralSetting !== overrideGeneralSetting,
+ }));
handleSubmit = (e: React.SyntheticEvent<HTMLFormElement>) => {
e.preventDefault();
const { component } = this.props;
- const { analysis, days, selected: type, referenceBranch, overrideGeneralSetting } = this.state;
+ const { days, selected: type, referenceBranch, overrideGeneralSetting } = this.state;
if (!overrideGeneralSetting) {
this.resetSetting();
return;
}
- const value = getSettingValue({ type, analysis, days, referenceBranch });
+ const value = getSettingValue({ type, days, referenceBranch });
if (type) {
this.setState({ saving: true });
saving: false,
currentSetting: type,
currentSettingValue: value || undefined,
+ isChanged: false,
success: true,
});
this.resetSuccess();
currentSetting,
days,
generalSetting,
+ isChanged,
loading,
currentSettingValue,
overrideGeneralSetting,
currentSettingValue={currentSettingValue}
days={days}
generalSetting={generalSetting}
+ isChanged={isChanged}
onCancel={this.handleCancel}
- onSelectAnalysis={this.handleSelectAnalysis}
onSelectDays={this.handleSelectDays}
onSelectReferenceBranch={this.handleSelectReferenceBranch}
onSelectSetting={this.handleSelectSetting}
*/
import classNames from 'classnames';
import { RadioButton } from 'design-system';
+import { noop } from 'lodash';
import * as React from 'react';
import Tooltip from '../../../components/controls/Tooltip';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import { isNewCodeDefinitionCompliant } from '../../../helpers/new-code-definition';
import { Branch } from '../../../types/branch-like';
import { NewCodeDefinition, NewCodeDefinitionType } from '../../../types/new-code-definition';
-import { ParsedAnalysis } from '../../../types/project-activity';
import { validateSetting } from '../utils';
import BaselineSettingAnalysis from './BaselineSettingAnalysis';
import BaselineSettingReferenceBranch from './BaselineSettingReferenceBranch';
currentSettingValue?: string;
days: string;
generalSetting: NewCodeDefinition;
+ isChanged: boolean;
onCancel: () => void;
- onSelectAnalysis: (analysis: ParsedAnalysis) => void;
onSelectDays: (value: string) => void;
onSelectReferenceBranch: (value: string) => void;
onSelectSetting: (value?: NewCodeDefinitionType) => void;
currentSettingValue,
days,
generalSetting,
+ isChanged,
overrideGeneralSetting,
referenceBranch,
saving,
const isGlobalNcdCompliant = isNewCodeDefinitionCompliant(generalSetting);
- const { isChanged, isValid } = validateSetting({
- analysis,
- currentSetting,
- currentSettingValue,
+ const isValid = validateSetting({
days,
overrideGeneralSetting,
referenceBranch,
)}
{!branchesEnabled && currentSetting === NewCodeDefinitionType.SpecificAnalysis && (
<BaselineSettingAnalysis
- onSelect={() => {}}
+ onSelect={noop}
selected={
overrideGeneralSetting && selected === NewCodeDefinitionType.SpecificAnalysis
}
analysis={analysis || ''}
branch={branch.name}
component={component}
- onSelectAnalysis={props.onSelectAnalysis}
+ onSelectAnalysis={noop}
/>
)}
</div>
await ui.setBranchReferenceToBranchSetting('main', 'feature');
- expect(
- within(byRole('table').get()).getByText('baseline.reference_branch: feature')
- ).toBeInTheDocument();
+ expect(byRole('table').byText('baseline.reference_branch: feature').get()).toBeInTheDocument();
});
function renderProjectBaselineApp(context: RenderContext = {}) {
describe('validateSettings', () => {
it('should validate at branch level', () => {
- expect(validateSetting({ days: '' })).toEqual({ isChanged: false, isValid: false });
+ expect(validateSetting({ days: '' })).toEqual(false);
expect(
validateSetting({
- currentSetting: NewCodeDefinitionType.PreviousVersion,
days: '12',
selected: NewCodeDefinitionType.NumberOfDays,
})
- ).toEqual({ isChanged: true, isValid: true });
+ ).toEqual(true);
expect(
validateSetting({
- currentSetting: NewCodeDefinitionType.PreviousVersion,
days: 'nope',
selected: NewCodeDefinitionType.NumberOfDays,
})
- ).toEqual({ isChanged: true, isValid: false });
+ ).toEqual(false);
expect(
validateSetting({
- currentSetting: NewCodeDefinitionType.NumberOfDays,
- currentSettingValue: '15',
- days: '15',
- selected: NewCodeDefinitionType.NumberOfDays,
- })
- ).toEqual({ isChanged: false, isValid: true });
- expect(
- validateSetting({
- currentSetting: NewCodeDefinitionType.NumberOfDays,
- currentSettingValue: '15',
- days: '13',
- selected: NewCodeDefinitionType.NumberOfDays,
- })
- ).toEqual({ isChanged: true, isValid: true });
- expect(
- validateSetting({
- analysis: 'analysis1',
- currentSetting: NewCodeDefinitionType.SpecificAnalysis,
- currentSettingValue: 'analysis1',
days: '',
selected: NewCodeDefinitionType.SpecificAnalysis,
})
- ).toEqual({ isChanged: false, isValid: false });
+ ).toEqual(false);
expect(
validateSetting({
- analysis: 'analysis2',
- currentSetting: NewCodeDefinitionType.SpecificAnalysis,
- currentSettingValue: 'analysis1',
- days: '',
- selected: NewCodeDefinitionType.SpecificAnalysis,
- })
- ).toEqual({ isChanged: true, isValid: false });
- expect(
- validateSetting({
- currentSetting: NewCodeDefinitionType.ReferenceBranch,
- currentSettingValue: 'master',
days: '',
referenceBranch: 'master',
selected: NewCodeDefinitionType.ReferenceBranch,
})
- ).toEqual({ isChanged: false, isValid: true });
+ ).toEqual(true);
expect(
validateSetting({
- currentSetting: NewCodeDefinitionType.ReferenceBranch,
- currentSettingValue: 'master',
days: '',
referenceBranch: '',
selected: NewCodeDefinitionType.ReferenceBranch,
})
- ).toEqual({ isChanged: true, isValid: false });
+ ).toEqual(false);
});
it('should validate at project level', () => {
- expect(validateSetting({ days: '', overrideGeneralSetting: false })).toEqual({
- isChanged: false,
- isValid: true,
- });
- expect(validateSetting({ days: '', overrideGeneralSetting: true })).toEqual({
- isChanged: true,
- isValid: false,
- });
+ expect(validateSetting({ days: '', overrideGeneralSetting: false })).toEqual(true);
+ expect(
+ validateSetting({
+ selected: NewCodeDefinitionType.PreviousVersion,
+ days: '',
+ overrideGeneralSetting: true,
+ })
+ ).toEqual(true);
expect(
validateSetting({
- currentSetting: NewCodeDefinitionType.PreviousVersion,
+ selected: NewCodeDefinitionType.NumberOfDays,
days: '',
- overrideGeneralSetting: false,
+ overrideGeneralSetting: true,
+ })
+ ).toEqual(false);
+ expect(
+ validateSetting({
+ selected: NewCodeDefinitionType.NumberOfDays,
+ days: '12',
+ overrideGeneralSetting: true,
})
- ).toEqual({
- isChanged: true,
- isValid: true,
- });
+ ).toEqual(true);
});
});
}
export function validateSetting(state: {
- analysis?: string;
- currentSetting?: NewCodeDefinitionType;
- currentSettingValue?: string;
days: string;
overrideGeneralSetting?: boolean;
referenceBranch?: string;
selected?: NewCodeDefinitionType;
}) {
- const {
- analysis = '',
- currentSetting,
- currentSettingValue,
- days,
- overrideGeneralSetting,
- referenceBranch = '',
- selected,
- } = state;
-
- let isChanged;
- if (!currentSetting && overrideGeneralSetting !== undefined) {
- isChanged = overrideGeneralSetting;
- } else {
- isChanged =
- overrideGeneralSetting === false ||
- selected !== currentSetting ||
- (selected === NewCodeDefinitionType.NumberOfDays && days !== currentSettingValue) ||
- (selected === NewCodeDefinitionType.SpecificAnalysis && analysis !== currentSettingValue) ||
- (selected === NewCodeDefinitionType.ReferenceBranch &&
- referenceBranch !== currentSettingValue);
- }
+ const { days, overrideGeneralSetting, referenceBranch = '', selected } = state;
- const isValid =
+ return (
overrideGeneralSetting === false ||
(!!selected &&
isNewCodeDefinitionCompliant({
type: selected,
value: days,
}) &&
- (selected !== NewCodeDefinitionType.SpecificAnalysis || analysis.length > 0) &&
- (selected !== NewCodeDefinitionType.ReferenceBranch || referenceBranch.length > 0));
-
- return { isChanged, isValid };
+ (selected !== NewCodeDefinitionType.ReferenceBranch || referenceBranch.length > 0))
+ );
}
days: string;
loading: boolean;
currentSettingValue?: string;
+ isChanged: boolean;
saving: boolean;
selected?: NewCodeDefinitionType;
success: boolean;
state: State = {
loading: true,
days: getNumberOfDaysDefaultValue(),
+ isChanged: false,
saving: false,
success: false,
};
}
onSelectDays = (days: string) => {
- this.setState({ days, success: false });
+ this.setState({ days, success: false, isChanged: true });
};
onSelectSetting = (selected: NewCodeDefinitionType) => {
- this.setState({ selected, success: false });
+ this.setState((currentState) => ({
+ selected,
+ success: false,
+ isChanged: selected !== currentState.selected,
+ }));
};
onCancel = () => {
this.setState(({ currentSetting, currentSettingValue, days }) => ({
+ isChanged: false,
selected: currentSetting,
days:
currentSetting === NewCodeDefinitionType.NumberOfDays ? String(currentSettingValue) : days,
saving: false,
currentSetting: type,
currentSettingValue: value || undefined,
+ isChanged: false,
success: true,
});
}
};
render() {
- const { currentSetting, days, loading, currentSettingValue, saving, selected, success } =
- this.state;
-
- const isChanged =
- selected !== currentSetting ||
- (selected === NewCodeDefinitionType.NumberOfDays && String(days) !== currentSettingValue);
+ const {
+ currentSetting,
+ days,
+ loading,
+ isChanged,
+ currentSettingValue,
+ saving,
+ selected,
+ success,
+ } = this.state;
const isValid =
selected !== NewCodeDefinitionType.NumberOfDays ||
const [globalNcd, setGlobalNcd] = React.useState<NewCodeDefinition | null>(null);
const [selectedNcdType, setSelectedNcdType] = React.useState<NewCodeDefinitionType | null>(null);
const [days, setDays] = React.useState<string>('');
+ const [isChanged, setIsChanged] = React.useState<boolean>(false);
const isGlobalNcdCompliant = React.useMemo(
() => Boolean(globalNcd && isNewCodeDefinitionCompliant(globalNcd)),
[globalNcd]
);
- const initialNumberOfDays = React.useMemo(() => {
+ React.useEffect(() => {
const numberOfDays = getNumberOfDaysDefaultValue(globalNcd);
setDays(numberOfDays);
-
- return numberOfDays;
}, [globalNcd]);
- const isChanged = React.useMemo(
- () => selectedNcdType === NewCodeDefinitionType.NumberOfDays && days !== initialNumberOfDays,
- [selectedNcdType, days, initialNumberOfDays]
- );
-
const isCompliant = React.useMemo(
() =>
!!selectedNcdType &&
[selectedNcdType, days]
);
+ const handleNcdChanged = React.useCallback(
+ (newNcdType: NewCodeDefinitionType) => {
+ if (newNcdType && newNcdType !== selectedNcdType) {
+ setSelectedNcdType(newNcdType);
+ setIsChanged(true);
+ }
+ },
+ [selectedNcdType]
+ );
+
React.useEffect(() => {
function fetchGlobalNcd() {
getNewCodePeriod().then(setGlobalNcd, noop);
checked={selectedNcdType === NewCodeDefinitionType.Inherited}
className="big-spacer-bottom"
disabled={!isGlobalNcdCompliant}
- onCheck={() => setSelectedNcdType(NewCodeDefinitionType.Inherited)}
+ onCheck={() => handleNcdChanged(NewCodeDefinitionType.Inherited)}
value="general"
>
<Tooltip
aria-label={translate('new_code_definition.specific_setting')}
checked={Boolean(selectedNcdType && selectedNcdType !== NewCodeDefinitionType.Inherited)}
className="huge-spacer-top"
- onCheck={() => setSelectedNcdType(NewCodeDefinitionType.PreviousVersion)}
+ onCheck={() => handleNcdChanged(NewCodeDefinitionType.PreviousVersion)}
value="specific"
>
{translate('new_code_definition.specific_setting')}
disabled={Boolean(
!selectedNcdType || selectedNcdType === NewCodeDefinitionType.Inherited
)}
- onSelect={setSelectedNcdType}
+ onSelect={handleNcdChanged}
selected={selectedNcdType === NewCodeDefinitionType.PreviousVersion}
/>
isChanged={isChanged}
isValid={isCompliant}
onChangeDays={setDays}
- onSelect={setSelectedNcdType}
+ onSelect={handleNcdChanged}
selected={selectedNcdType === NewCodeDefinitionType.NumberOfDays}
/>
disabled={Boolean(
!selectedNcdType || selectedNcdType === NewCodeDefinitionType.Inherited
)}
- onClick={() => setSelectedNcdType(NewCodeDefinitionType.ReferenceBranch)}
+ onClick={() => handleNcdChanged(NewCodeDefinitionType.ReferenceBranch)}
selected={selectedNcdType === NewCodeDefinitionType.ReferenceBranch}
title={translate('new_code_definition.reference_branch')}
>