mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-11-22 00:47:29 -06:00
feat: SDA-2775: Notification Position Window New UI (#1164)
* SDA-2775: notification position window new ui - Create new user interface for notification position window - Add unit tests * SDA-2775: increase test coverage and format css
This commit is contained in:
parent
6fdb80857f
commit
8912c25003
133
spec/__snapshots__/notificationSettings.spec.ts.snap
Normal file
133
spec/__snapshots__/notificationSettings.spec.ts.snap
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Notification Settings should mount, unmount and render component should render the component 1`] = `
|
||||||
|
<div
|
||||||
|
className="content"
|
||||||
|
>
|
||||||
|
<header
|
||||||
|
className="header"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="header-title"
|
||||||
|
>
|
||||||
|
Set Notification Position
|
||||||
|
</span>
|
||||||
|
</header>
|
||||||
|
<div
|
||||||
|
className="form"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="display-label"
|
||||||
|
>
|
||||||
|
Show on display
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
className="display-container"
|
||||||
|
id="screens"
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
className="display-selector"
|
||||||
|
id="screen-selector"
|
||||||
|
onChange={[Function]}
|
||||||
|
title="position"
|
||||||
|
value={1}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<label
|
||||||
|
className="position-label"
|
||||||
|
>
|
||||||
|
Position
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
className="position-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="button-set-left"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="position-button-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="position-button upper-left"
|
||||||
|
id="upper-left"
|
||||||
|
name="position"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
value="upper-left"
|
||||||
|
>
|
||||||
|
Top Left
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="position-button-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="position-button lower-left"
|
||||||
|
id="lower-left"
|
||||||
|
name="position"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
value="lower-left"
|
||||||
|
>
|
||||||
|
Bottom Left
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="button-set-right"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="position-button-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="position-button position-button-selected upper-right"
|
||||||
|
id="upper-right"
|
||||||
|
name="position"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
value="upper-right"
|
||||||
|
>
|
||||||
|
Top Right
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="position-button-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="position-button lower-right"
|
||||||
|
id="lower-right"
|
||||||
|
name="position"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
value="lower-right"
|
||||||
|
>
|
||||||
|
Bottom Right
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer
|
||||||
|
className="footer"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="footer-button-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="footer-button footer-button-dismiss"
|
||||||
|
id="cancel"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
CANCEL
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="footer-button footer-button-ok"
|
||||||
|
id="ok-button"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
OK
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
`;
|
224
spec/notificationSettings.spec.ts
Normal file
224
spec/notificationSettings.spec.ts
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import * as React from 'react';
|
||||||
|
import NotificationSettings from '../src/renderer/components/notification-settings';
|
||||||
|
import { ipcRenderer } from './__mocks__/electron';
|
||||||
|
|
||||||
|
describe('Notification Settings', () => {
|
||||||
|
const notificationSettingsLabel = 'notification-settings-data';
|
||||||
|
const notificationSettingsMock = {
|
||||||
|
position: 'upper-right',
|
||||||
|
screens: [
|
||||||
|
{
|
||||||
|
id: '6713899',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '3512909',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
display: '6713899',
|
||||||
|
};
|
||||||
|
const onLabelEvent = 'on';
|
||||||
|
const sendEvent = 'send';
|
||||||
|
const removeListenerLabelEvent = 'removeListener';
|
||||||
|
|
||||||
|
describe('should mount, unmount and render component', () => {
|
||||||
|
it('should render the component', () => {
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call `notification-settings-data` event when component is mounted', () => {
|
||||||
|
const spy = jest.spyOn(ipcRenderer, onLabelEvent);
|
||||||
|
shallow(React.createElement(NotificationSettings));
|
||||||
|
expect(spy).toBeCalledWith(notificationSettingsLabel, expect.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call `updateState` when component is mounted', () => {
|
||||||
|
const spy = jest.spyOn(NotificationSettings.prototype, 'setState');
|
||||||
|
shallow(React.createElement(NotificationSettings));
|
||||||
|
|
||||||
|
ipcRenderer.send('notification-settings-data', notificationSettingsMock);
|
||||||
|
|
||||||
|
expect(spy).toBeCalledWith(notificationSettingsMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove listener `notification-settings-data` when component is unmounted', () => {
|
||||||
|
const spyMount = jest.spyOn(ipcRenderer, onLabelEvent);
|
||||||
|
const spyUnmount = jest.spyOn(ipcRenderer, removeListenerLabelEvent);
|
||||||
|
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
expect(spyMount).toBeCalledWith(notificationSettingsLabel, expect.any(Function));
|
||||||
|
|
||||||
|
wrapper.unmount();
|
||||||
|
expect(spyUnmount).toBeCalledWith(notificationSettingsLabel, expect.any(Function));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should select display', () => {
|
||||||
|
it('should select display from drop down', () => {
|
||||||
|
const notificationSettingsMock = {
|
||||||
|
position: 'upper-right',
|
||||||
|
screens: [],
|
||||||
|
display: '6713899',
|
||||||
|
};
|
||||||
|
|
||||||
|
const spy = jest.spyOn(NotificationSettings.prototype, 'setState');
|
||||||
|
const selectDisplaySpy = jest.spyOn(NotificationSettings.prototype, 'selectDisplay');
|
||||||
|
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
ipcRenderer.send('notification-settings-data', notificationSettingsMock);
|
||||||
|
|
||||||
|
const positionButton = `select.display-selector`;
|
||||||
|
const input = wrapper.find(positionButton);
|
||||||
|
|
||||||
|
input.simulate('change', { target: { value: '6713899' } });
|
||||||
|
|
||||||
|
expect(selectDisplaySpy).toBeCalled();
|
||||||
|
expect(spy).toBeCalledWith(notificationSettingsMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should set display position', () => {
|
||||||
|
it('should select top right position', () => {
|
||||||
|
const notificationSettingsMock = {
|
||||||
|
position: 'upper-right',
|
||||||
|
screens: [],
|
||||||
|
display: '6713899',
|
||||||
|
};
|
||||||
|
|
||||||
|
const spy = jest.spyOn(NotificationSettings.prototype, 'setState');
|
||||||
|
const togglePositionButtonSpy = jest.spyOn(NotificationSettings.prototype, 'togglePosition');
|
||||||
|
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
ipcRenderer.send('notification-settings-data', notificationSettingsMock);
|
||||||
|
|
||||||
|
const positionButton = `button.upper-right`;
|
||||||
|
const input = wrapper.find(positionButton);
|
||||||
|
|
||||||
|
input.simulate('click', { target: { value: 'upper-right' } });
|
||||||
|
|
||||||
|
expect(togglePositionButtonSpy).toBeCalled();
|
||||||
|
expect(spy).toBeCalledWith(notificationSettingsMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select bottom right position', () => {
|
||||||
|
const notificationSettingsMock = {
|
||||||
|
position: 'bottom-right',
|
||||||
|
screens: [],
|
||||||
|
display: '6713899',
|
||||||
|
};
|
||||||
|
|
||||||
|
const spy = jest.spyOn(NotificationSettings.prototype, 'setState');
|
||||||
|
const togglePositionButtonSpy = jest.spyOn(NotificationSettings.prototype, 'togglePosition');
|
||||||
|
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
ipcRenderer.send('notification-settings-data', notificationSettingsMock);
|
||||||
|
|
||||||
|
const positionButton = `button.lower-right`;
|
||||||
|
const input = wrapper.find(positionButton);
|
||||||
|
|
||||||
|
input.simulate('click', { target: { value: 'lower-right' } });
|
||||||
|
|
||||||
|
expect(togglePositionButtonSpy).toBeCalled();
|
||||||
|
expect(spy).toBeCalledWith(notificationSettingsMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select top left position', () => {
|
||||||
|
const notificationSettingsMock = {
|
||||||
|
position: 'upper-left',
|
||||||
|
screens: [],
|
||||||
|
display: '6713899',
|
||||||
|
};
|
||||||
|
|
||||||
|
const spy = jest.spyOn(NotificationSettings.prototype, 'setState');
|
||||||
|
const togglePositionButtonSpy = jest.spyOn(NotificationSettings.prototype, 'togglePosition');
|
||||||
|
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
ipcRenderer.send('notification-settings-data', notificationSettingsMock);
|
||||||
|
|
||||||
|
const positionButton = `button.upper-left`;
|
||||||
|
const input = wrapper.find(positionButton);
|
||||||
|
|
||||||
|
input.simulate('click', { target: { value: 'upper-left' } });
|
||||||
|
|
||||||
|
expect(togglePositionButtonSpy).toBeCalled();
|
||||||
|
expect(spy).toBeCalledWith(notificationSettingsMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select bottom left position', () => {
|
||||||
|
const notificationSettingsMock = {
|
||||||
|
position: 'lower-left',
|
||||||
|
screens: [],
|
||||||
|
display: '6713899',
|
||||||
|
};
|
||||||
|
|
||||||
|
const spy = jest.spyOn(NotificationSettings.prototype, 'setState');
|
||||||
|
const togglePositionButtonSpy = jest.spyOn(NotificationSettings.prototype, 'togglePosition');
|
||||||
|
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
ipcRenderer.send('notification-settings-data', notificationSettingsMock);
|
||||||
|
|
||||||
|
const positionButton = `button.lower-left`;
|
||||||
|
const input = wrapper.find(positionButton);
|
||||||
|
|
||||||
|
input.simulate('click', { target: { value: 'lower-left' } });
|
||||||
|
|
||||||
|
expect(togglePositionButtonSpy).toBeCalled();
|
||||||
|
expect(spy).toBeCalledWith(notificationSettingsMock);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should submit or cancel new preferences', () => {
|
||||||
|
it('should close window on pressing cancel button', () => {
|
||||||
|
const notificationSettingsMock = {
|
||||||
|
position: 'lower-left',
|
||||||
|
screens: [],
|
||||||
|
display: '6713899',
|
||||||
|
};
|
||||||
|
|
||||||
|
const spy = jest.spyOn(ipcRenderer, sendEvent);
|
||||||
|
const closeButtonSpy = jest.spyOn(NotificationSettings.prototype, 'close');
|
||||||
|
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
ipcRenderer.send('notification-settings-data', notificationSettingsMock);
|
||||||
|
|
||||||
|
const closeButton = `button.footer-button-dismiss`;
|
||||||
|
const input = wrapper.find(closeButton);
|
||||||
|
|
||||||
|
input.simulate('click');
|
||||||
|
|
||||||
|
expect(closeButtonSpy).toBeCalled();
|
||||||
|
expect(spy).toBeCalledWith('symphony-api', {
|
||||||
|
cmd: 'close-window',
|
||||||
|
windowType: 'notification-settings',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should submit new preferences on pressing ok button', () => {
|
||||||
|
const notificationSettingsMock = {
|
||||||
|
position: 'lower-left',
|
||||||
|
screens: [],
|
||||||
|
display: '6713899',
|
||||||
|
};
|
||||||
|
|
||||||
|
const spy = jest.spyOn(ipcRenderer, sendEvent);
|
||||||
|
const closeButtonSpy = jest.spyOn(NotificationSettings.prototype, 'close');
|
||||||
|
|
||||||
|
const wrapper = shallow(React.createElement(NotificationSettings));
|
||||||
|
ipcRenderer.send('notification-settings-data', notificationSettingsMock);
|
||||||
|
|
||||||
|
const closeButton = `button.footer-button-ok`;
|
||||||
|
const input = wrapper.find(closeButton);
|
||||||
|
|
||||||
|
input.simulate('click');
|
||||||
|
|
||||||
|
expect(closeButtonSpy).toBeCalled();
|
||||||
|
expect(spy).toBeCalledWith('notification-settings-update', {
|
||||||
|
position: 'lower-left',
|
||||||
|
display: '6713899',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -1336,8 +1336,8 @@ export class WindowHandler {
|
|||||||
public createNotificationSettingsWindow(windowName: string): void {
|
public createNotificationSettingsWindow(windowName: string): void {
|
||||||
const opts = this.getWindowOpts(
|
const opts = this.getWindowOpts(
|
||||||
{
|
{
|
||||||
width: 460,
|
width: 540,
|
||||||
height: 360,
|
height: 440,
|
||||||
show: false,
|
show: false,
|
||||||
modal: true,
|
modal: true,
|
||||||
minimizable: false,
|
minimizable: false,
|
||||||
|
@ -107,7 +107,9 @@
|
|||||||
"Position": "Position",
|
"Position": "Position",
|
||||||
"Symphony - Configure Notification Position": "Symphony - Configure Notification Position",
|
"Symphony - Configure Notification Position": "Symphony - Configure Notification Position",
|
||||||
"Top Left": "Top Left",
|
"Top Left": "Top Left",
|
||||||
"Top Right": "Top Right"
|
"Top Right": "Top Right",
|
||||||
|
"Show on display": "Show on display",
|
||||||
|
"Set Notification Position": "Set Notification Position"
|
||||||
},
|
},
|
||||||
"Oops! Looks like we have had a crash.": "Oops! Looks like we have had a crash.",
|
"Oops! Looks like we have had a crash.": "Oops! Looks like we have had a crash.",
|
||||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! Looks like we have had a crash. Please reload or close this window.",
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! Looks like we have had a crash. Please reload or close this window.",
|
||||||
|
@ -107,7 +107,9 @@
|
|||||||
"Position": "Position",
|
"Position": "Position",
|
||||||
"Symphony - Configure Notification Position": "Symphony - Configure Notification Position",
|
"Symphony - Configure Notification Position": "Symphony - Configure Notification Position",
|
||||||
"Top Left": "Top Left",
|
"Top Left": "Top Left",
|
||||||
"Top Right": "Top Right"
|
"Top Right": "Top Right",
|
||||||
|
"Show on display": "Show on display",
|
||||||
|
"Set Notification Position": "Set Notification Position"
|
||||||
},
|
},
|
||||||
"Oops! Looks like we have had a crash.": "Oops! Looks like we have had a crash.",
|
"Oops! Looks like we have had a crash.": "Oops! Looks like we have had a crash.",
|
||||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! Looks like we have had a crash. Please reload or close this window.",
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! Looks like we have had a crash. Please reload or close this window.",
|
||||||
|
@ -107,7 +107,9 @@
|
|||||||
"Position": "Position",
|
"Position": "Position",
|
||||||
"Symphony - Configure Notification Position": "Symphony - Configurer la position des notifications",
|
"Symphony - Configure Notification Position": "Symphony - Configurer la position des notifications",
|
||||||
"Top Left": "Gauche supérieure",
|
"Top Left": "Gauche supérieure",
|
||||||
"Top Right": "Droite supérieure"
|
"Top Right": "Droite supérieure",
|
||||||
|
"Show on display": "Afficher sur écran",
|
||||||
|
"Set Notification Position": "Définir la position de notification"
|
||||||
},
|
},
|
||||||
"Oops! Looks like we have had a crash.": "Oops! On dirait que nous avons eu un crash.",
|
"Oops! Looks like we have had a crash.": "Oops! On dirait que nous avons eu un crash.",
|
||||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! On dirait que nous avons eu un crash. Veuillez recharger ou fermer cette fenêtre.",
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! On dirait que nous avons eu un crash. Veuillez recharger ou fermer cette fenêtre.",
|
||||||
|
@ -107,7 +107,9 @@
|
|||||||
"Position": "Position",
|
"Position": "Position",
|
||||||
"Symphony - Configure Notification Position": "Symphony - Configurer la position des notifications",
|
"Symphony - Configure Notification Position": "Symphony - Configurer la position des notifications",
|
||||||
"Top Left": "Gauche supérieure",
|
"Top Left": "Gauche supérieure",
|
||||||
"Top Right": "Droite supérieure"
|
"Top Right": "Droite supérieure",
|
||||||
|
"Show on display": "Afficher sur écran",
|
||||||
|
"Set Notification Position": "Définir la position de notification"
|
||||||
},
|
},
|
||||||
"Oops! Looks like we have had a crash.": "Oops! On dirait que nous avons eu un crash.",
|
"Oops! Looks like we have had a crash.": "Oops! On dirait que nous avons eu un crash.",
|
||||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! On dirait que nous avons eu un crash. Veuillez recharger ou fermer cette fenêtre.",
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! On dirait que nous avons eu un crash. Veuillez recharger ou fermer cette fenêtre.",
|
||||||
|
@ -107,7 +107,9 @@
|
|||||||
"Position": "位置",
|
"Position": "位置",
|
||||||
"Symphony - Configure Notification Position": "Symphony - 通知位置の設定",
|
"Symphony - Configure Notification Position": "Symphony - 通知位置の設定",
|
||||||
"Top Left": "左上",
|
"Top Left": "左上",
|
||||||
"Top Right": "右上"
|
"Top Right": "右上",
|
||||||
|
"Show on display": "ディスプレイに表示",
|
||||||
|
"Set Notification Position": "通知位置を設定する"
|
||||||
},
|
},
|
||||||
"Oops! Looks like we have had a crash.": "おっと!クラッシュしたようです。",
|
"Oops! Looks like we have had a crash.": "おっと!クラッシュしたようです。",
|
||||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "おっと!クラッシュしたようです。このウィンドウを再度読み込むか閉じてください。",
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "おっと!クラッシュしたようです。このウィンドウを再度読み込むか閉じてください。",
|
||||||
|
@ -107,7 +107,9 @@
|
|||||||
"Position": "位置",
|
"Position": "位置",
|
||||||
"Symphony - Configure Notification Position": "Symphony - 通知位置の設定",
|
"Symphony - Configure Notification Position": "Symphony - 通知位置の設定",
|
||||||
"Top Left": "左上",
|
"Top Left": "左上",
|
||||||
"Top Right": "右上"
|
"Top Right": "右上",
|
||||||
|
"Show on display": "ディスプレイに表示",
|
||||||
|
"Set Notification Position": "通知位置を設定する"
|
||||||
},
|
},
|
||||||
"Oops! Looks like we have had a crash.": "おっと!クラッシュしたようです。",
|
"Oops! Looks like we have had a crash.": "おっと!クラッシュしたようです。",
|
||||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "おっと!クラッシュしたようです。このウィンドウを再度読み込むか閉じてください。",
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "おっと!クラッシュしたようです。このウィンドウを再度読み込むか閉じてください。",
|
||||||
|
@ -15,17 +15,10 @@ interface IState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Window that display app version and copyright info
|
* Notification Window component
|
||||||
*/
|
*/
|
||||||
export default class NotificationSettings extends React.Component<{}, IState> {
|
export default class NotificationSettings extends React.Component<{}, IState> {
|
||||||
|
|
||||||
private readonly eventHandlers = {
|
|
||||||
onTogglePosition: (e: React.ChangeEvent<HTMLInputElement>) => this.togglePosition(e),
|
|
||||||
onDisplaySelect: (e: React.ChangeEvent<HTMLSelectElement>) => this.selectDisplay(e),
|
|
||||||
onClose: () => this.close(),
|
|
||||||
onSubmit: () => this.submit(),
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
@ -37,128 +30,98 @@ export default class NotificationSettings extends React.Component<{}, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* main render function
|
* Renders the notification settings window
|
||||||
*/
|
*/
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className='content'>
|
<div className='content'>
|
||||||
|
|
||||||
<header className='header'>
|
<header className='header'>
|
||||||
<span className='header__title'>
|
<span className='header-title'>
|
||||||
{i18n.t('Notification Settings', NOTIFICATION_SETTINGS_NAMESPACE)()}
|
{i18n.t('Set Notification Position', NOTIFICATION_SETTINGS_NAMESPACE)()}
|
||||||
</span>
|
</span>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className='form'>
|
<div className='form'>
|
||||||
<form>
|
<label className='display-label'>{i18n.t('Show on display', NOTIFICATION_SETTINGS_NAMESPACE)()}</label>
|
||||||
<label className='label'>{i18n.t('Monitor', NOTIFICATION_SETTINGS_NAMESPACE)()}</label>
|
<div id='screens' className='display-container'>
|
||||||
<div id='screens' className='main'>
|
<select
|
||||||
<label>
|
className='display-selector'
|
||||||
{i18n.t('Notification shown on Monitor: ', NOTIFICATION_SETTINGS_NAMESPACE)()}
|
id='screen-selector'
|
||||||
</label>
|
title='position'
|
||||||
<select
|
value={this.state.display}
|
||||||
className='selector'
|
onChange={this.selectDisplay.bind(this)}
|
||||||
id='screen-selector'
|
>
|
||||||
title='position'
|
{this.renderScreens()}
|
||||||
value={this.state.display}
|
</select>
|
||||||
onChange={this.eventHandlers.onDisplaySelect}
|
</div>
|
||||||
>
|
|
||||||
{this.renderScreens()}
|
<label className='position-label'>{i18n.t('Position', NOTIFICATION_SETTINGS_NAMESPACE)()}</label>
|
||||||
</select>
|
<div className='position-container'>
|
||||||
|
<div className='button-set-left'>
|
||||||
|
{this.renderPositionButton('upper-left', 'Top Left')}
|
||||||
|
{this.renderPositionButton('lower-left', 'Bottom Left')}
|
||||||
</div>
|
</div>
|
||||||
<label className='label'>{i18n.t('Position', NOTIFICATION_SETTINGS_NAMESPACE)()}</label>
|
<div className='button-set-right'>
|
||||||
<div className='main'>
|
{this.renderPositionButton('upper-right', 'Top Right')}
|
||||||
<div className='first-set'>
|
{this.renderPositionButton('lower-right', 'Bottom Right')}
|
||||||
{this.renderRadioButtons('upper-left', 'Top Left')}
|
|
||||||
{this.renderRadioButtons('lower-left', 'Bottom Left')}
|
|
||||||
</div>
|
|
||||||
<div className='second-set'>
|
|
||||||
{this.renderRadioButtons('upper-right', 'Top Right')}
|
|
||||||
{this.renderRadioButtons('lower-right', 'Bottom Right')}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer className='footer'>
|
<footer className='footer'>
|
||||||
<div className='buttonLayout'>
|
<div className='footer-button-container'>
|
||||||
<button id='cancel' className='buttonDismiss' onClick={this.eventHandlers.onClose}>
|
<button id='cancel' className='footer-button footer-button-dismiss' onClick={this.close.bind(this)}>
|
||||||
{i18n.t('CANCEL', NOTIFICATION_SETTINGS_NAMESPACE)()}
|
{i18n.t('CANCEL', NOTIFICATION_SETTINGS_NAMESPACE)()}
|
||||||
</button>
|
</button>
|
||||||
<button id='ok-button' className='button' onClick={this.eventHandlers.onSubmit}>
|
<button id='ok-button' className='footer-button footer-button-ok' onClick={this.submit.bind(this)}>
|
||||||
{i18n.t('OK', NOTIFICATION_SETTINGS_NAMESPACE)()}
|
{i18n.t('OK', NOTIFICATION_SETTINGS_NAMESPACE)()}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles event when the component is mounted
|
||||||
|
*/
|
||||||
public componentDidMount(): void {
|
public componentDidMount(): void {
|
||||||
ipcRenderer.on('notification-settings-data', this.updateState);
|
ipcRenderer.on('notification-settings-data', this.updateState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles event when the component is unmounted
|
||||||
|
*/
|
||||||
public componentWillUnmount(): void {
|
public componentWillUnmount(): void {
|
||||||
ipcRenderer.removeListener('notification-settings-data', this.updateState);
|
ipcRenderer.removeListener('notification-settings-data', this.updateState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders all 4 different notification position options
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @param content
|
|
||||||
*/
|
|
||||||
private renderRadioButtons(id: startCorner, content: string): JSX.Element {
|
|
||||||
return (
|
|
||||||
<div className='radio'>
|
|
||||||
<label className='radio__label' htmlFor={id}>
|
|
||||||
{i18n.t(`${content}`, NOTIFICATION_SETTINGS_NAMESPACE)()}
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
onChange={this.eventHandlers.onTogglePosition}
|
|
||||||
className={id}
|
|
||||||
id={id}
|
|
||||||
type='radio'
|
|
||||||
name='position'
|
|
||||||
checked={this.state.position === id}
|
|
||||||
value={id} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the drop down list of available screen
|
|
||||||
*/
|
|
||||||
private renderScreens(): JSX.Element[] {
|
|
||||||
const { screens } = this.state;
|
|
||||||
return screens.map((screen, index) => {
|
|
||||||
return (
|
|
||||||
<option id={String(screen.id)} key={screen.id} value={screen.id}>{index + 1}</option>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the selected display state
|
* Updates the selected display state
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
private selectDisplay(event): void {
|
public selectDisplay(event): void {
|
||||||
this.setState({ display: event.target.value });
|
this.setState({ display: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updated the selected notification position
|
* Updates the selected notification position
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
private togglePosition(event): void {
|
public togglePosition(event): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
position: event.currentTarget.value,
|
position: event.target.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the user selected notification settings options
|
* Submits the new settings to the main process
|
||||||
*/
|
*/
|
||||||
private submit(): void {
|
public submit(): void {
|
||||||
const { position, display } = this.state;
|
const { position, display } = this.state;
|
||||||
ipcRenderer.send('notification-settings-update', { position, display });
|
ipcRenderer.send('notification-settings-update', { position, display });
|
||||||
}
|
}
|
||||||
@ -166,13 +129,49 @@ export default class NotificationSettings extends React.Component<{}, IState> {
|
|||||||
/**
|
/**
|
||||||
* Closes the notification settings window
|
* Closes the notification settings window
|
||||||
*/
|
*/
|
||||||
private close(): void {
|
public close(): void {
|
||||||
ipcRenderer.send(apiName.symphonyApi, {
|
ipcRenderer.send(apiName.symphonyApi, {
|
||||||
cmd: apiCmds.closeWindow,
|
cmd: apiCmds.closeWindow,
|
||||||
windowType: 'notification-settings',
|
windowType: 'notification-settings',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the position buttons
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param content
|
||||||
|
*/
|
||||||
|
private renderPositionButton(id: startCorner, content: string): JSX.Element {
|
||||||
|
const style = this.state.position === id ? `position-button position-button-selected ${id}` : `position-button ${id}`;
|
||||||
|
return (
|
||||||
|
<div className='position-button-container'>
|
||||||
|
<button
|
||||||
|
onClick={this.togglePosition.bind(this)}
|
||||||
|
className={style}
|
||||||
|
id={id} type='button'
|
||||||
|
name='position'
|
||||||
|
value={id}
|
||||||
|
>
|
||||||
|
{i18n.t(`${content}`, NOTIFICATION_SETTINGS_NAMESPACE)()}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the drop down list of available screens
|
||||||
|
*/
|
||||||
|
private renderScreens(): JSX.Element[] {
|
||||||
|
const { screens } = this.state;
|
||||||
|
return screens.map((screen, index) => {
|
||||||
|
const screenId = screen.id;
|
||||||
|
return (
|
||||||
|
<option id={String(screenId)} key={screenId} value={screenId}>{index + 1}/{screens.length}</option>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the component state
|
* Sets the component state
|
||||||
*
|
*
|
||||||
|
@ -30,8 +30,8 @@ body {
|
|||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__title {
|
.header-title {
|
||||||
font-weight: 500;
|
font-weight: 300;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
margin: 0 0 0 4px;
|
margin: 0 0 0 4px;
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
@ -49,51 +49,104 @@ body {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.selector {
|
.display-label {
|
||||||
padding: 0 9px 0 16px;
|
width: 304px;
|
||||||
cursor: pointer;
|
height: 16px;
|
||||||
margin-left: 10px;
|
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
|
||||||
|
color: #525760;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.display-container {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-selector {
|
||||||
|
padding: 0 20px 0 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
width: 304px;
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
border: 2px solid #7C7F86;
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-label {
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
width: 304px;
|
||||||
|
height: 16px;
|
||||||
|
color: #525760;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin-bottom: 20px;
|
|
||||||
height: 100%;
|
|
||||||
border: 1px solid #ccc !important;
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
.first-set {
|
width: 304px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
left: 8px;
|
||||||
|
top: 102px;
|
||||||
|
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
background: #F8F8F9;
|
||||||
|
|
||||||
|
.button-set-left {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.second-set {
|
.button-set-right {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio {
|
.position-button-container {
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
|
|
||||||
.upper-right, .lower-right {
|
.position-button {
|
||||||
float: right;
|
width: 116px;
|
||||||
margin-top: 6px;
|
height: 32px;
|
||||||
|
|
||||||
|
top: 1px;
|
||||||
|
|
||||||
|
margin: 20px 20px 20px 20px;
|
||||||
|
|
||||||
|
border: 2px solid #7C7F86;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
align-items: center;
|
||||||
|
color: #17181B;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upper-left, .lower-left {
|
.position-button-selected {
|
||||||
|
background-color: #008EFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upper-left,
|
||||||
|
.lower-left {
|
||||||
float: left;
|
float: left;
|
||||||
margin-top: 6px;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.radio__label {
|
.upper-right,
|
||||||
cursor: pointer;
|
.lower-right {
|
||||||
padding: 5px;
|
float: right;
|
||||||
|
|
||||||
input {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
@ -103,12 +156,28 @@ body {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttonLayout {
|
.footer-button-container {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
|
||||||
|
|
||||||
.buttonDismiss {
|
.footer-button {
|
||||||
margin-right: 10px;
|
border: 2px solid #7C7F86;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-button-ok {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-button-dismiss {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user