mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
C2-18497 Add Updated badge on updated message notification
This commit is contained in:
parent
7e495f037b
commit
0fb76420ee
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
node_modules
|
||||
dist
|
||||
.DS_Store
|
||||
js/preload/_*.js
|
||||
.idea/
|
||||
coverage/
|
||||
@ -35,3 +34,8 @@ out
|
||||
lib
|
||||
build
|
||||
|
||||
# Mac system file
|
||||
.DS_Store
|
||||
|
||||
# Local History plugin
|
||||
.history
|
||||
|
@ -22,6 +22,22 @@ describe('Toast notification component', () => {
|
||||
expect(container.text()).toBe(defaultProps.title);
|
||||
});
|
||||
|
||||
it('should close the notification when the close button is clicked', async () => {
|
||||
const spy = jest.spyOn(ipcRenderer, 'send');
|
||||
const closeButton = wrapper.find('.close-button img');
|
||||
expect(closeButton).toBeTruthy();
|
||||
closeButton.simulate('click', { stopPropagation: jest.fn() });
|
||||
expect(spy).toBeCalledWith('close-notification', 0);
|
||||
});
|
||||
|
||||
it('should click on the notification when use clicks on main container', async () => {
|
||||
const spy = jest.spyOn(ipcRenderer, 'send');
|
||||
const notificationContainer = wrapper.find('.main-container');
|
||||
expect(notificationContainer).toBeTruthy();
|
||||
notificationContainer.simulate('click', { stopPropagation: jest.fn() });
|
||||
expect(spy).toBeCalledWith('notification-clicked', 0);
|
||||
});
|
||||
|
||||
it('should render Symphony logo if no image provided', () => {
|
||||
const logo = '';
|
||||
ipcRenderer.send(IPC_RENDERER_NOTIFICATION_DATA_CHANNEL, {
|
||||
@ -151,4 +167,17 @@ describe('Toast notification component', () => {
|
||||
notificationContainer.simulate('mouseenter');
|
||||
expect(spy).toBeCalledWith('notification-mouseenter', 0);
|
||||
});
|
||||
|
||||
it('should display the updated badge when message is an update', async () => {
|
||||
let updatedBadge = wrapper.find('.updated-badge');
|
||||
expect(updatedBadge.exists()).toBeFalsy();
|
||||
const isUpdated = true;
|
||||
ipcRenderer.send(IPC_RENDERER_NOTIFICATION_DATA_CHANNEL, {
|
||||
...defaultProps,
|
||||
isUpdated,
|
||||
});
|
||||
|
||||
updatedBadge = wrapper.find('.updated-badge');
|
||||
expect(updatedBadge.exists()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -253,6 +253,7 @@ export interface INotificationData {
|
||||
company: string;
|
||||
displayTime: number;
|
||||
isExternal: boolean;
|
||||
isUpdated: boolean;
|
||||
theme: Theme;
|
||||
isElectronNotification?: boolean;
|
||||
callback?: () => void;
|
||||
|
@ -110,6 +110,10 @@
|
||||
<label for="isExternal">external:</label>
|
||||
<input type="checkbox" id="isExternal" />
|
||||
</p>
|
||||
<p>
|
||||
<label for="isUpdated">is updated:</label>
|
||||
<input type="checkbox" id="isUpdated" />
|
||||
</p>
|
||||
<p>
|
||||
<label for="hasMention">has mention:</label>
|
||||
<input type="checkbox" id="hasMention" />
|
||||
@ -359,13 +363,15 @@
|
||||
var imageUrl = document.getElementById('image').value;
|
||||
var shouldFlash = document.getElementById('flash').checked;
|
||||
var isExternal = document.getElementById('isExternal').checked;
|
||||
var isUpdated = document.getElementById('isUpdated').checked;
|
||||
var hasMention = document.getElementById('hasMention').checked;
|
||||
var shouldStick = document.getElementById('sticky').checked;
|
||||
var color = document.getElementById('color').value;
|
||||
var tag = document.getElementById('tag').value;
|
||||
var company = document.getElementById('company').value;
|
||||
var isNativeNotification = document.getElementById('isNativeNotification')
|
||||
.checked;
|
||||
var isNativeNotification = document.getElementById(
|
||||
'isNativeNotification',
|
||||
).checked;
|
||||
num++;
|
||||
|
||||
var theme = document.getElementById('select-theme').value;
|
||||
@ -379,6 +385,7 @@
|
||||
color: color,
|
||||
sticky: shouldStick,
|
||||
isExternal: isExternal,
|
||||
isUpdated,
|
||||
theme: theme,
|
||||
data: {
|
||||
hello: `Notification with id ${num} clicked')`,
|
||||
@ -1196,8 +1203,9 @@
|
||||
.join('');
|
||||
document.getElementById('text-window-handle').value = handleStr;
|
||||
};
|
||||
const windowName = document.getElementById('text-window-handle-name')
|
||||
.value;
|
||||
const windowName = document.getElementById(
|
||||
'text-window-handle-name',
|
||||
).value;
|
||||
if (window.ssf) {
|
||||
window.ssf.getNativeWindowHandle(windowName).then(resultCallback);
|
||||
} else if (window.manaSSF) {
|
||||
|
@ -214,6 +214,7 @@
|
||||
"Unable to generate crash reports due to ": "Unable to generate crash reports due to ",
|
||||
"Unable to generate logs due to ": "Unable to generate logs due to ",
|
||||
"Undo": "Undo",
|
||||
"Updated": "Updated",
|
||||
"Updating Title bar style requires Symphony to relaunch.": "Updating Title bar style requires Symphony to relaunch.",
|
||||
"View": "View",
|
||||
"Welcome": {
|
||||
|
@ -214,6 +214,7 @@
|
||||
"Unable to generate crash reports due to ": "Unable to generate crash reports due to ",
|
||||
"Unable to generate logs due to ": "Unable to generate logs due to ",
|
||||
"Undo": "Undo",
|
||||
"Updated": "Updated",
|
||||
"Updating Title bar style requires Symphony to relaunch.": "Updating Title bar style requires Symphony to relaunch.",
|
||||
"View": "View",
|
||||
"Welcome": {
|
||||
|
@ -214,6 +214,7 @@
|
||||
"Unable to generate crash reports due to ": "Impossible de générer le rapport de crash en raison de ",
|
||||
"Unable to generate logs due to ": "Impossible de générer le journal d'évènements en raison de ",
|
||||
"Undo": "Annuler la dernière opération",
|
||||
"Updated": "Modifié",
|
||||
"Updating Title bar style requires Symphony to relaunch.": "La mise à jour du style de la barre de titre nécessite le redémarrage de Symphony.",
|
||||
"View": "Visualiser",
|
||||
"Welcome": {
|
||||
|
@ -214,6 +214,7 @@
|
||||
"Unable to generate crash reports due to ": "Impossible de générer le rapport de crash en raison de ",
|
||||
"Unable to generate logs due to ": "Impossible de générer le journal d'évenements en raison de",
|
||||
"Undo": "Annuler la dernière opération",
|
||||
"Updated": "Modifié",
|
||||
"Updating Title bar style requires Symphony to relaunch.": "La mise à jour du style de la barre de titre nécessite le redémarrage de Symphony.",
|
||||
"View": "Visualiser",
|
||||
"Welcome": {
|
||||
|
@ -214,6 +214,7 @@
|
||||
"Unable to generate crash reports due to ": "クラッシュレポートを生成できません。理由: ",
|
||||
"Unable to generate logs due to ": "ログを生成できません。理由:",
|
||||
"Undo": "元に戻す",
|
||||
"Updated": "編集済み",
|
||||
"Updating Title bar style requires Symphony to relaunch.": "タイトルバーのスタイルを更新するには、Symphonyが再起動する必要があります。",
|
||||
"View": "ビュー",
|
||||
"Welcome": {
|
||||
|
@ -214,6 +214,7 @@
|
||||
"Unable to generate crash reports due to ": "クラッシュレポートを生成できません。理由: ",
|
||||
"Unable to generate logs due to ": "ログを生成できません。理由:",
|
||||
"Undo": "元に戻す",
|
||||
"Updated": "編集済み",
|
||||
"Updating Title bar style requires Symphony to relaunch.": "タイトルバーのスタイルを更新するには、Symphonyが再起動する必要があります。",
|
||||
"View": "ビュー",
|
||||
"Welcome": {
|
||||
|
@ -46,6 +46,7 @@ interface INotificationState {
|
||||
color: string;
|
||||
flash: boolean;
|
||||
isExternal: boolean;
|
||||
isUpdated: boolean;
|
||||
theme: Theme;
|
||||
hasIgnore: boolean;
|
||||
hasReply: boolean;
|
||||
@ -100,6 +101,7 @@ export default class NotificationComp extends React.Component<
|
||||
color: '',
|
||||
flash: false,
|
||||
isExternal: false,
|
||||
isUpdated: false,
|
||||
theme: '',
|
||||
isInputHidden: true,
|
||||
hasIgnore: false,
|
||||
@ -140,6 +142,7 @@ export default class NotificationComp extends React.Component<
|
||||
id,
|
||||
color,
|
||||
isExternal,
|
||||
isUpdated,
|
||||
theme,
|
||||
containerHeight,
|
||||
icon,
|
||||
@ -198,7 +201,10 @@ export default class NotificationComp extends React.Component<
|
||||
{this.renderReplyButton(id, themeClassName)}
|
||||
{this.renderIgnoreButton(id, themeClassName)}
|
||||
</div>
|
||||
<span className={`message-preview ${themeClassName}`}>{body}</span>
|
||||
<div className={`message-preview ${themeClassName}`}>
|
||||
{this.renderUpdatedBadge(isUpdated)}
|
||||
{body}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.renderRTE(themeClassName)}
|
||||
@ -247,6 +253,18 @@ export default class NotificationComp extends React.Component<
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the UPDATED badge
|
||||
* @param isUpdated
|
||||
* @returns the updated badge if the message is updated
|
||||
*/
|
||||
private renderUpdatedBadge(isUpdated: boolean) {
|
||||
if (!isUpdated) {
|
||||
return;
|
||||
}
|
||||
return <div className='updated-badge'>{i18n.t('Updated')()}</div>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders external badge if the content is from external
|
||||
* @param isExternal
|
||||
@ -504,12 +522,11 @@ export default class NotificationComp extends React.Component<
|
||||
if (isExternal) {
|
||||
if (!hasMention) {
|
||||
currentColors.notificationBorderColor = '#F7CA3B';
|
||||
currentColors.notificationBackgroundColor = externalFlashingBackgroundColor;
|
||||
currentColors.notificationBackgroundColor =
|
||||
externalFlashingBackgroundColor;
|
||||
if (this.isCustomColor(color)) {
|
||||
currentColors.notificationBorderColor = this.getThemedCustomBorderColor(
|
||||
theme,
|
||||
color,
|
||||
);
|
||||
currentColors.notificationBorderColor =
|
||||
this.getThemedCustomBorderColor(theme, color);
|
||||
currentColors.notificationBackgroundColor = color;
|
||||
}
|
||||
} else {
|
||||
|
@ -202,12 +202,10 @@ class Notification extends NotificationHandler {
|
||||
notificationWindow.notificationData = data;
|
||||
notificationWindow.winName = apiName.notificationWindowName;
|
||||
notificationWindow.once('closed', () => {
|
||||
const activeWindowIndex = this.activeNotifications.indexOf(
|
||||
notificationWindow,
|
||||
);
|
||||
const inactiveWindowIndex = this.inactiveWindows.indexOf(
|
||||
notificationWindow,
|
||||
);
|
||||
const activeWindowIndex =
|
||||
this.activeNotifications.indexOf(notificationWindow);
|
||||
const inactiveWindowIndex =
|
||||
this.inactiveWindows.indexOf(notificationWindow);
|
||||
|
||||
if (activeWindowIndex !== -1) {
|
||||
this.activeNotifications.splice(activeWindowIndex, 1);
|
||||
@ -275,6 +273,7 @@ class Notification extends NotificationHandler {
|
||||
color,
|
||||
flash,
|
||||
isExternal,
|
||||
isUpdated,
|
||||
theme,
|
||||
hasIgnore,
|
||||
hasReply,
|
||||
@ -290,6 +289,7 @@ class Notification extends NotificationHandler {
|
||||
color,
|
||||
flash,
|
||||
isExternal,
|
||||
isUpdated,
|
||||
theme,
|
||||
hasIgnore,
|
||||
hasReply,
|
||||
@ -507,7 +507,8 @@ class Notification extends NotificationHandler {
|
||||
* fullscreen state when notification is clicked
|
||||
*/
|
||||
public exitFullScreen(): void {
|
||||
const browserWindows: ICustomBrowserWindow[] = BrowserWindow.getAllWindows() as ICustomBrowserWindow[];
|
||||
const browserWindows: ICustomBrowserWindow[] =
|
||||
BrowserWindow.getAllWindows() as ICustomBrowserWindow[];
|
||||
for (const win in browserWindows) {
|
||||
if (Object.prototype.hasOwnProperty.call(browserWindows, win)) {
|
||||
const browserWin = browserWindows[win];
|
||||
|
@ -146,7 +146,21 @@ body {
|
||||
cursor: default;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--text-color);
|
||||
white-space: pre-line;
|
||||
|
||||
.updated-badge {
|
||||
float: left;
|
||||
display: inline-flex;
|
||||
font-weight: 600;
|
||||
padding: 0rem 0.25rem;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
color: #27292c;
|
||||
background-color: #cdcfd4;
|
||||
border-radius: 0.1875rem;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user