SDA-4369: Ability to Cancel changes made on pod URL (#1987)

This commit is contained in:
NguyenTranHoangSym 2023-10-19 15:30:41 +07:00 committed by GitHub
parent 069d83711d
commit c6dbb20222
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 14 deletions

View File

@ -6,7 +6,7 @@ import { ipcRenderer } from './__mocks__/electron';
describe('about app', () => {
const aboutAppDataLabel = 'about-app-data';
const aboutDataMock = {
const aboutDataMockClipboard = {
sbeVersion: '1',
userConfig: {},
globalConfig: { isPodUrlEditable: true },
@ -31,6 +31,9 @@ describe('about app', () => {
httpParserVersion: '11.12',
swiftSearchVersion: '1.55.3-beta.1',
swiftSearchSupportedVersion: 'N/A',
};
const aboutDataMockState = {
...aboutDataMockClipboard,
updatedHostname: 'N/A',
};
const onLabelEvent = 'on';
@ -60,19 +63,19 @@ describe('about app', () => {
it('should call `updateState` when component is mounted', () => {
const spy = jest.spyOn(AboutApp.prototype, 'setState');
shallow(React.createElement(AboutApp));
ipcRenderer.send('about-app-data', aboutDataMock);
expect(spy).toBeCalledWith(aboutDataMock);
ipcRenderer.send('about-app-data', aboutDataMockState);
expect(spy).toBeCalledWith(aboutDataMockState);
});
it('should copy the correct data on to clipboard', () => {
const spyIpc = jest.spyOn(ipcRenderer, ipcSendEvent);
const wrapper = shallow(React.createElement(AboutApp));
ipcRenderer.send('about-app-data', aboutDataMock);
ipcRenderer.send('about-app-data', aboutDataMockClipboard);
const copyButtonSelector = `[data-testid="COPY_BUTTON"]`;
wrapper.find(copyButtonSelector).simulate('click');
const expectedData = {
cmd: apiCmds.aboutAppClipBoardData,
clipboard: aboutDataMock,
clipboard: aboutDataMockClipboard,
clipboardType: 'clipboard',
};
expect(spyIpc).toBeCalledWith('symphony-api', expectedData);
@ -80,7 +83,7 @@ describe('about app', () => {
it('should display input when triple clicked on pod', () => {
const wrapper = shallow(React.createElement(AboutApp));
ipcRenderer.send('about-app-data', aboutDataMock);
ipcRenderer.send('about-app-data', aboutDataMockState);
const pod = wrapper.find(`[data-testid="POD_INFO"]`);
pod.simulate('click', { detail: 1 });
pod.simulate('click', { detail: 2 });
@ -90,7 +93,7 @@ describe('about app', () => {
});
it('should not display input when triple clicked on pod', () => {
const cloneAboutDataMock = aboutDataMock;
const cloneAboutDataMock = aboutDataMockState;
cloneAboutDataMock.globalConfig = { isPodUrlEditable: false };
cloneAboutDataMock.userConfig = { isPodUrlEditable: true };
@ -106,7 +109,7 @@ describe('about app', () => {
});
it('should not display config based on global config only', () => {
const cloneAboutDataMock = aboutDataMock;
const cloneAboutDataMock = aboutDataMockState;
cloneAboutDataMock.globalConfig = { isPodUrlEditable: false };
cloneAboutDataMock.userConfig = { isPodUrlEditable: false };
@ -122,7 +125,7 @@ describe('about app', () => {
});
it('should display config based on global config only', () => {
const cloneAboutDataMock = aboutDataMock;
const cloneAboutDataMock = aboutDataMockState;
cloneAboutDataMock.globalConfig = { isPodUrlEditable: true };
cloneAboutDataMock.userConfig = { isPodUrlEditable: false };
@ -136,4 +139,21 @@ describe('about app', () => {
const podInput = wrapper.find('.AboutApp-pod-input');
expect(podInput.exists()).toEqual(true);
});
it('should display cancel button on triple click and behave correctly', () => {
const cloneAboutDataMock = aboutDataMockState;
cloneAboutDataMock.globalConfig = { isPodUrlEditable: true };
cloneAboutDataMock.userConfig = { isPodUrlEditable: false };
const wrapper = shallow(React.createElement(AboutApp));
ipcRenderer.send('about-app-data', cloneAboutDataMock);
const pod = wrapper.find(`[data-testid="POD_INFO"]`);
pod.simulate('click', { detail: 1 });
pod.simulate('click', { detail: 2 });
pod.simulate('click', { detail: 3 });
const podInput = wrapper.find('[data-testid="CANCEL_BUTTON"]');
podInput.simulate('click');
expect(wrapper.find(`[data-testid="POD_INFO"]`).exists()).toEqual(true);
});
});

View File

@ -1277,7 +1277,9 @@ export class WindowHandler {
...filteredConfig,
};
const host = parse(
(userConfig as IConfig).url || (globalConfig as IConfig).url,
this.url
? this.url
: (userConfig as IConfig).url || (globalConfig as IConfig).url,
);
const aboutInfo = {
userConfig,

View File

@ -10,7 +10,8 @@
"Close": "Close",
"Copyright": "Copyright",
"Desktop Application": "Desktop Application",
"Save and Restart": "Save and Restart"
"Save and Restart": "Save and Restart",
"Cancel": "Cancel"
},
"Actual Size": "Actual Size",
"Always on Top": "Always on Top",

View File

@ -10,7 +10,8 @@
"Close": "Close",
"Copyright": "Copyright",
"Desktop Application": "Desktop Application",
"Save and Restart": "Save and Restart"
"Save and Restart": "Save and Restart",
"Cancel": "Cancel"
},
"Actual Size": "Actual Size",
"Always on Top": "Always on Top",

View File

@ -37,7 +37,7 @@ interface IState {
swiftSearchVersion?: string;
swiftSearchSupportedVersion?: string;
client?: string;
updatedHostname: string;
updatedHostname?: string;
isPodEditing: boolean;
isValidHostname: boolean;
didUpdateHostname: boolean;
@ -57,6 +57,7 @@ export default class AboutApp extends React.Component<{}, IState> {
private readonly eventHandlers = {
onCopy: () => this.copy(),
onClose: () => this.close(),
onCancel: () => this.cancel(),
onPodClick: (event) => this.onPodClick(event),
onPodChange: (event) => this.handlePodChange(event),
onPodInputBlur: (event) => this.handlePodInputBlur(event),
@ -149,6 +150,7 @@ export default class AboutApp extends React.Component<{}, IState> {
isValidHostname && didUpdateHostname
? i18n.t('Save and Restart', ABOUT_SYMPHONY_NAMESPACE)()
: i18n.t('Close', ABOUT_SYMPHONY_NAMESPACE)();
const cancelText = i18n.t('Cancel', ABOUT_SYMPHONY_NAMESPACE)();
return (
<div className='AboutApp' lang={i18n.getLocale()}>
@ -186,6 +188,16 @@ export default class AboutApp extends React.Component<{}, IState> {
</button>
</div>
<div className='AboutApp-close-container'>
{this.state.isPodEditing && (
<button
className='AboutApp-cancel-button'
onClick={this.eventHandlers.onCancel}
title={cancelText}
data-testid={'CANCEL_BUTTON'}
>
{cancelText}
</button>
)}
<button
className='AboutApp-close-button'
onClick={this.eventHandlers.onClose}
@ -231,6 +243,7 @@ export default class AboutApp extends React.Component<{}, IState> {
...rest,
};
if (data) {
delete data.updatedHostname;
ipcRenderer.send(apiName.symphonyApi, {
cmd: apiCmds.aboutAppClipBoardData,
clipboard: data,
@ -250,6 +263,18 @@ export default class AboutApp extends React.Component<{}, IState> {
}
}
/**
* Cancel modal and restore old url
*/
public cancel(): void {
this.setState({
updatedHostname: this.previousUrl,
isPodEditing: false,
isValidHostname: true,
hostname: this.previousUrl,
});
}
/**
* Enables editing mode
*/
@ -298,7 +323,7 @@ export default class AboutApp extends React.Component<{}, IState> {
*/
public handlePodInputBlur = (_event) => {
const { updatedHostname, hostname } = this.state;
if (!HOSTNAME_REGEX.test(updatedHostname)) {
if (!HOSTNAME_REGEX.test(updatedHostname || '')) {
this.setState({
isPodEditing: false,
isValidHostname: false,

View File

@ -188,6 +188,31 @@ body {
}
}
&-cancel-button {
box-shadow: none;
border: none;
border-radius: 20px;
font-size: 0.875rem;
text-align: center;
display: inline-block;
text-decoration: none;
line-height: 12px;
background-color: @electricity-ui-50;
color: @electricity-ui-05;
cursor: pointer;
box-sizing: border-box;
text-transform: uppercase;
font-weight: 600;
width: 120px;
margin-right: 8px;
height: 36px;
&:focus {
box-shadow: 0 0 10px rgba(61, 162, 253, 1);
outline: none;
}
}
&-version-container {
width: 100%;
}