From 07e4dcbf88fe3b331eb83c222053b5f7f71ad927 Mon Sep 17 00:00:00 2001 From: firelemons Date: Tue, 17 Oct 2023 19:07:10 -0500 Subject: [PATCH 01/23] notifier scrolls when there are too many notifications to display --- app/assets/stylesheets/shared/notifier.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/shared/notifier.scss b/app/assets/stylesheets/shared/notifier.scss index 8c59976327..b649986c95 100644 --- a/app/assets/stylesheets/shared/notifier.scss +++ b/app/assets/stylesheets/shared/notifier.scss @@ -8,10 +8,12 @@ } #notifications { - bottom: 2em; + bottom: 0; display: flex; flex-direction: column; font-weight: 900; + max-height: 100vh; + overflow-y: auto; position: fixed; right: 2em; z-index: 100; From f917202d71cab39b031ac9ba4df260884d3e25f2 Mon Sep 17 00:00:00 2001 From: firelemons Date: Tue, 17 Oct 2023 19:26:00 -0500 Subject: [PATCH 02/23] notifier keeps track of how many of each kind of notification there are --- app/javascript/src/notifier.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/app/javascript/src/notifier.js b/app/javascript/src/notifier.js index eeaee48903..b9247a33de 100644 --- a/app/javascript/src/notifier.js +++ b/app/javascript/src/notifier.js @@ -21,9 +21,13 @@ const levels = { } class Notification { - constructor (notificationElementAsJQuery) { + constructor (notificationElementAsJQuery, parentNotifier) { TypeChecker.checkNonEmptyJQueryObject(notificationElementAsJQuery, 'notificationElementAsJQuery') + if (!(parentNotifier instanceof Notifier)) { + throw new TypeError('Param parentNotifier must be an instance of Notifier') + } + const levelCapturedViaClassNames = notificationElementAsJQuery.attr('class').match(/(warn|failure|success)-indicator/) if (!levelCapturedViaClassNames) { @@ -38,13 +42,19 @@ class Notification { this.level = 'info' } + notificationElementAsJQuery.children('button').on('click', () => { + this.dismiss() + }) + this.notificationElement = notificationElementAsJQuery + this.parentNotifier = parentNotifier } dismiss () { this.#throwErrorIfDismissed() this.notificationElement.remove() + this.parentNotifier.notificationsCount[this.level]-- } getText () { @@ -100,8 +110,8 @@ class Notification { const dismissButton = $(``) this.notificationElement.append(dismissButton) - dismissButton.on('click', function () { - $(this).parent().remove() + dismissButton.on('click', () => { + this.dismiss() }) } } @@ -112,6 +122,11 @@ class Notifier { TypeChecker.checkNonEmptyJQueryObject(notificationsElement, 'notificationsElement') this.loadingToast = notificationsElement.find('#async-waiting-indicator') + this.notificationsCount = { + error: 0, + info: 0, + warn: 0 + } this.notificationsElement = notificationsElement this.savedToast = notificationsElement.find('#async-success-indicator') this.savedToastTimeouts = [] @@ -148,13 +163,9 @@ class Notifier { this.notificationsElement.append(newNotificationAsJQuery) - if (isDismissable) { - newNotificationAsJQuery.children('button').on('click', function () { - $(this).parent().remove() - }) - } + const newNotification = new Notification(newNotificationAsJQuery, this) - const newNotification = new Notification(newNotificationAsJQuery) + this.notificationsCount[level]++ return newNotification } From 75e0515be7530e75bb82f29efbed5a71a0282c6f Mon Sep 17 00:00:00 2001 From: firelemons Date: Tue, 17 Oct 2023 19:40:39 -0500 Subject: [PATCH 03/23] added toggle notification minimize button, styled it --- app/assets/stylesheets/shared/notifier.scss | 8 ++++++++ app/views/layouts/_notifier.erb | 1 + 2 files changed, 9 insertions(+) diff --git a/app/assets/stylesheets/shared/notifier.scss b/app/assets/stylesheets/shared/notifier.scss index b649986c95..adcf28162e 100644 --- a/app/assets/stylesheets/shared/notifier.scss +++ b/app/assets/stylesheets/shared/notifier.scss @@ -60,4 +60,12 @@ width: 1em } } + + #toggle-minimize-notifications { + background-color: #333; + border: 0; + border-radius: 10px 10px 0 0; + color: white; + padding: 0.25em 1em; + } } diff --git a/app/views/layouts/_notifier.erb b/app/views/layouts/_notifier.erb index 88036b5c04..bed504abc1 100644 --- a/app/views/layouts/_notifier.erb +++ b/app/views/layouts/_notifier.erb @@ -5,4 +5,5 @@ + From 705311c3332ab598d5c883d606196614ef658038 Mon Sep 17 00:00:00 2001 From: firelemons Date: Tue, 17 Oct 2023 19:43:21 -0500 Subject: [PATCH 04/23] alphabetize notifier methods --- app/javascript/src/notifier.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/javascript/src/notifier.js b/app/javascript/src/notifier.js index b9247a33de..5c59051b59 100644 --- a/app/javascript/src/notifier.js +++ b/app/javascript/src/notifier.js @@ -170,12 +170,6 @@ class Notifier { return newNotification } - // Shows a loading indicator until all operations resolve - waitForAsyncOperation () { - this.loadingToast.show() - this.waitingAsyncOperationCount++ - } - // Shows the saved toast for 2 seconds and hides the loading indicator if no more async operations are pending // @param {string=} error The error to be displayed(optional) // @throws {Error} for trying to resolve more async operations than the amount currently awaiting @@ -211,6 +205,12 @@ class Notifier { this.notify(errorMsg, 'error') } } + + // Shows a loading indicator until all operations resolve + waitForAsyncOperation () { + this.loadingToast.show() + this.waitingAsyncOperationCount++ + } } module.exports = { Notifier, Notification } From 87c9fdb49c8229da8a60b5b61f5b6b54a3e2ed65 Mon Sep 17 00:00:00 2001 From: firelemons Date: Tue, 17 Oct 2023 22:25:47 -0500 Subject: [PATCH 05/23] notifier automatically shows/hides minimize button depending on presence of notifications --- app/javascript/src/notifier.js | 32 ++++++++++++++++++++++++++++++-- app/views/layouts/_notifier.erb | 2 +- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/app/javascript/src/notifier.js b/app/javascript/src/notifier.js index 5c59051b59..31aae00e3c 100644 --- a/app/javascript/src/notifier.js +++ b/app/javascript/src/notifier.js @@ -121,12 +121,26 @@ class Notifier { constructor (notificationsElement) { TypeChecker.checkNonEmptyJQueryObject(notificationsElement, 'notificationsElement') + const outer = this + this.loadingToast = notificationsElement.find('#async-waiting-indicator') - this.notificationsCount = { + this.notificationsCount = new Proxy({ error: 0, info: 0, warn: 0 - } + }, { + set(target, propertyKey, value) { + const defaultSet = Reflect.set(target, propertyKey, value) + + if (outer.totalNotificationCount()) { + outer.setMinimizeButtonVisibility(true) + } else { + outer.setMinimizeButtonVisibility(false) + } + + return defaultSet + } + }) this.notificationsElement = notificationsElement this.savedToast = notificationsElement.find('#async-success-indicator') this.savedToastTimeouts = [] @@ -206,6 +220,20 @@ class Notifier { } } + setMinimizeButtonVisibility (visible) { + if (visible) { + this.notificationsElement.children('button').show() + } else { + this.notificationsElement.children('button').hide() + } + } + + totalNotificationCount () { + return Object.values(this.notificationsCount).reduce((acc, currentValue) => { + return acc + currentValue + }, 0) + } + // Shows a loading indicator until all operations resolve waitForAsyncOperation () { this.loadingToast.show() diff --git a/app/views/layouts/_notifier.erb b/app/views/layouts/_notifier.erb index bed504abc1..9256183ba1 100644 --- a/app/views/layouts/_notifier.erb +++ b/app/views/layouts/_notifier.erb @@ -5,5 +5,5 @@ - + From 9d81575fb908f3251f5c9f6d862962f9b77eba77 Mon Sep 17 00:00:00 2001 From: firelemons Date: Tue, 17 Oct 2023 22:32:58 -0500 Subject: [PATCH 06/23] block stubs for tests --- app/javascript/__tests__/notifier.test.js | 47 +++++++++++++++-------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/app/javascript/__tests__/notifier.test.js b/app/javascript/__tests__/notifier.test.js index acdce50ae1..414f964788 100644 --- a/app/javascript/__tests__/notifier.test.js +++ b/app/javascript/__tests__/notifier.test.js @@ -15,6 +15,7 @@ beforeEach(() => { + ` $(() => { // JQuery's callback for the DOM loading @@ -155,23 +156,8 @@ describe('Notifier', () => { }) }) - describe('waitForAsyncOperation', () => { - test('displays the loading indicator', (done) => { - $(() => { - const loadingToast = $('#async-waiting-indicator') - - try { - expect(loadingToast.css('display')).toBe('none') - - notifier.waitForAsyncOperation() - expect(loadingToast.attr('style')).toEqual(expect.not.stringContaining('display: none')) - - done() - } catch (error) { - done(error) - } - }) - }) + describe('notificationsCount', () => { + }) describe('resolveAsyncOperation', () => { @@ -282,6 +268,33 @@ describe('Notifier', () => { }) }) }) + + describe('setMinimizeButtonVisibility', () => { + + }) + + describe('totalNotificationCount', () => { + + }) + + describe('waitForAsyncOperation', () => { + test('displays the loading indicator', (done) => { + $(() => { + const loadingToast = $('#async-waiting-indicator') + + try { + expect(loadingToast.css('display')).toBe('none') + + notifier.waitForAsyncOperation() + expect(loadingToast.attr('style')).toEqual(expect.not.stringContaining('display: none')) + + done() + } catch (error) { + done(error) + } + }) + }) + }) }) describe('Notifications', () => { From b642730fb17e6631551603d4be45d698f8ecd63e Mon Sep 17 00:00:00 2001 From: firelemons Date: Wed, 18 Oct 2023 10:09:09 -0500 Subject: [PATCH 07/23] wrote test for minimize button hiding --- app/javascript/__tests__/notifier.test.js | 68 ++++++++++++++++++++++- app/javascript/src/notifier.js | 2 +- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/app/javascript/__tests__/notifier.test.js b/app/javascript/__tests__/notifier.test.js index 414f964788..5f15d5b1f7 100644 --- a/app/javascript/__tests__/notifier.test.js +++ b/app/javascript/__tests__/notifier.test.js @@ -157,7 +157,32 @@ describe('Notifier', () => { }) describe('notificationsCount', () => { - + it('automatically shows the minimize button when going from 0 to 1 notifications', (done) => { + $(() => { + try { + } catch (error) { + done(error) + } + }) + }) + + it('automatically hides the minimize button when going from 1 to 0 notifications', (done) => { + $(() => { + try { + } catch (error) { + done(error) + } + }) + }) + + it('increments the correct', (done) => { + $(() => { + try { + } catch (error) { + done(error) + } + }) + }) }) describe('resolveAsyncOperation', () => { @@ -270,11 +295,34 @@ describe('Notifier', () => { }) describe('setMinimizeButtonVisibility', () => { + it('hides the mimimize button when passed false', (done) => { + $(() => { + try { + } catch (error) { + done(error) + } + }) + }) + it('shows the mimimize button when passed true', (done) => { + $(() => { + try { + } catch (error) { + done(error) + } + }) + }) }) describe('totalNotificationCount', () => { - + it('returns the number of notifications the notifier currently has displayed', (done) => { + $(() => { + try { + } catch (error) { + done(error) + } + }) + }) }) describe('waitForAsyncOperation', () => { @@ -369,6 +417,22 @@ describe('Notifications', () => { } }) }) + + test('causes the notifier to hide the minimize button if it dismisses the last notification', (done) => { + $(() => { + try { + expect(notificationsElement[0].innerHTML).toContain(notificationDefaultMessage) + expect($('#toggle-minimize-notifications').css('display')).not.toContain('none') + + notification.dismiss() + expect(notificationsElement[0].innerHTML).not.toContain(notificationDefaultMessage) + expect($('#toggle-minimize-notifications').css('display')).toContain('none') + done() + } catch (error) { + done(error) + } + }) + }) }) describe('getText', () => { diff --git a/app/javascript/src/notifier.js b/app/javascript/src/notifier.js index 31aae00e3c..0d243b70c8 100644 --- a/app/javascript/src/notifier.js +++ b/app/javascript/src/notifier.js @@ -129,7 +129,7 @@ class Notifier { info: 0, warn: 0 }, { - set(target, propertyKey, value) { + set (target, propertyKey, value) { const defaultSet = Reflect.set(target, propertyKey, value) if (outer.totalNotificationCount()) { From d3dc7e34a726d0aa6c98d146d82900573704625a Mon Sep 17 00:00:00 2001 From: firelemons Date: Thu, 19 Oct 2023 10:45:54 -0500 Subject: [PATCH 08/23] make setMinimizeButtonVisibility private --- app/javascript/__tests__/notifier.test.js | 20 -------------------- app/javascript/src/notifier.js | 6 +++--- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/app/javascript/__tests__/notifier.test.js b/app/javascript/__tests__/notifier.test.js index 5f15d5b1f7..ec1d138d16 100644 --- a/app/javascript/__tests__/notifier.test.js +++ b/app/javascript/__tests__/notifier.test.js @@ -294,26 +294,6 @@ describe('Notifier', () => { }) }) - describe('setMinimizeButtonVisibility', () => { - it('hides the mimimize button when passed false', (done) => { - $(() => { - try { - } catch (error) { - done(error) - } - }) - }) - - it('shows the mimimize button when passed true', (done) => { - $(() => { - try { - } catch (error) { - done(error) - } - }) - }) - }) - describe('totalNotificationCount', () => { it('returns the number of notifications the notifier currently has displayed', (done) => { $(() => { diff --git a/app/javascript/src/notifier.js b/app/javascript/src/notifier.js index 0d243b70c8..a2df682c7a 100644 --- a/app/javascript/src/notifier.js +++ b/app/javascript/src/notifier.js @@ -133,9 +133,9 @@ class Notifier { const defaultSet = Reflect.set(target, propertyKey, value) if (outer.totalNotificationCount()) { - outer.setMinimizeButtonVisibility(true) + outer.#setMinimizeButtonVisibility(true) } else { - outer.setMinimizeButtonVisibility(false) + outer.#setMinimizeButtonVisibility(false) } return defaultSet @@ -220,7 +220,7 @@ class Notifier { } } - setMinimizeButtonVisibility (visible) { + #setMinimizeButtonVisibility (visible) { if (visible) { this.notificationsElement.children('button').show() } else { From 91c870b6268c721c1f560d835f0276be862d79a5 Mon Sep 17 00:00:00 2001 From: firelemons Date: Thu, 19 Oct 2023 21:20:47 -0500 Subject: [PATCH 09/23] filled out notificationsCount tests --- app/javascript/__tests__/notifier.test.js | 60 ++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/app/javascript/__tests__/notifier.test.js b/app/javascript/__tests__/notifier.test.js index ec1d138d16..eb5f087a4e 100644 --- a/app/javascript/__tests__/notifier.test.js +++ b/app/javascript/__tests__/notifier.test.js @@ -157,9 +157,27 @@ describe('Notifier', () => { }) describe('notificationsCount', () => { + const initialNotificationsCountState = { + error: 0, + info: 0, + warn: 0 + } + it('automatically shows the minimize button when going from 0 to 1 notifications', (done) => { $(() => { try { + expect(notifier.notificationsCount).toEqual(initialNotificationsCountState) + expect($('#toggle-minimize-notifications').css('display')).toBe('none') + + notifier.notify('message', 'warn') + + expect(notifier.notificationsCount).toEqual({ + error: 0, + info: 0, + warn: 1 + }) + expect($('#toggle-minimize-notifications').css('display')).not.toBe('none') + done() } catch (error) { done(error) } @@ -169,15 +187,55 @@ describe('Notifier', () => { it('automatically hides the minimize button when going from 1 to 0 notifications', (done) => { $(() => { try { + const notification = notifier.notify('message', 'warn') + + expect(notifier.notificationsCount).toEqual({ + error: 0, + info: 0, + warn: 1 + }) + expect($('#toggle-minimize-notifications').css('display')).not.toBe('none') + + notification.dismiss() + + expect(notifier.notificationsCount).toEqual(initialNotificationsCountState) + expect($('#toggle-minimize-notifications').css('display')).toBe('none') + done() } catch (error) { done(error) } }) }) - it('increments the correct', (done) => { + it('increments the correct level after creating a new notification', (done) => { $(() => { try { + expect(notifier.notificationsCount).toEqual(initialNotificationsCountState) + + notifier.notify('message', 'info') + + expect(notifier.notificationsCount).toEqual({ + error: 0, + info: 1, + warn: 0 + }) + + notifier.notify('message', 'error') + + expect(notifier.notificationsCount).toEqual({ + error: 1, + info: 1, + warn: 0 + }) + + notifier.notify('message', 'warn') + + expect(notifier.notificationsCount).toEqual({ + error: 1, + info: 1, + warn: 1 + }) + done() } catch (error) { done(error) } From 1f51d5d9e502ccd43bba31e038140debd746093d Mon Sep 17 00:00:00 2001 From: firelemons Date: Fri, 20 Oct 2023 01:05:33 -0500 Subject: [PATCH 10/23] wrote test for totalNotificationCount --- app/javascript/__tests__/notifier.test.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/javascript/__tests__/notifier.test.js b/app/javascript/__tests__/notifier.test.js index eb5f087a4e..562af2c532 100644 --- a/app/javascript/__tests__/notifier.test.js +++ b/app/javascript/__tests__/notifier.test.js @@ -356,6 +356,26 @@ describe('Notifier', () => { it('returns the number of notifications the notifier currently has displayed', (done) => { $(() => { try { + expect(notifier.totalNotificationCount()).toBe(0) + + const notificationCount = Math.floor(Math.random() * 10) + 1 + const notifications = [] + + for (let i = 0; i < notificationCount; i++) { + notifications.push(notifier.notify('message', 'error')) + } + + expect(notifier.totalNotificationCount()).toBe(notificationCount) + + const aboutHalfNotificationCount = Math.floor(notificationCount / 2) + + for (let i = 0; i < aboutHalfNotificationCount; i++) { + notifications.pop().dismiss() + } + + expect(notifier.totalNotificationCount()).toBe(notificationCount - aboutHalfNotificationCount) + + done() } catch (error) { done(error) } From 159b64c009c0b6bde2ab23e91cbbe2b2d1fa6102 Mon Sep 17 00:00:00 2001 From: firelemons Date: Fri, 20 Oct 2023 09:32:42 -0500 Subject: [PATCH 11/23] fixed notification positioning --- app/assets/stylesheets/shared/notifier.scss | 2 +- app/javascript/src/notifier.js | 2 +- app/views/layouts/_notifier.erb | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/shared/notifier.scss b/app/assets/stylesheets/shared/notifier.scss index adcf28162e..ff9f4975b9 100644 --- a/app/assets/stylesheets/shared/notifier.scss +++ b/app/assets/stylesheets/shared/notifier.scss @@ -20,7 +20,7 @@ div { border-radius: .25em; - margin: .25em; + margin-bottom: .5em; margin-left: auto; margin-right: 0; padding: .5em; diff --git a/app/javascript/src/notifier.js b/app/javascript/src/notifier.js index a2df682c7a..4ec2600300 100644 --- a/app/javascript/src/notifier.js +++ b/app/javascript/src/notifier.js @@ -175,7 +175,7 @@ class Notifier { ` ) - this.notificationsElement.append(newNotificationAsJQuery) + this.notificationsElement.prepend(newNotificationAsJQuery) const newNotification = new Notification(newNotificationAsJQuery, this) diff --git a/app/views/layouts/_notifier.erb b/app/views/layouts/_notifier.erb index 9256183ba1..2aacd83774 100644 --- a/app/views/layouts/_notifier.erb +++ b/app/views/layouts/_notifier.erb @@ -5,5 +5,11 @@ - + From caba9c7bc541776297f6d3ce6f40fd1a17a0fdc5 Mon Sep 17 00:00:00 2001 From: firelemons Date: Fri, 20 Oct 2023 16:29:42 -0500 Subject: [PATCH 12/23] added badges for minimized notification display --- app/javascript/__tests__/notifier.test.js | 26 ++++++++++++++--------- app/views/layouts/_notifier.erb | 6 +++--- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/javascript/__tests__/notifier.test.js b/app/javascript/__tests__/notifier.test.js index 562af2c532..1e23fc8360 100644 --- a/app/javascript/__tests__/notifier.test.js +++ b/app/javascript/__tests__/notifier.test.js @@ -9,14 +9,20 @@ let notifier beforeEach(() => { document.body.innerHTML = `
- - - -
` + + + +` $(() => { // JQuery's callback for the DOM loading notificationsElement = $('#notifications') @@ -37,7 +43,7 @@ describe('Notifier', () => { // Notifications contain the hidden "Saved" message and the new message expect(successMessages.length).toBe(2) - expect(successMessages[1].innerHTML).toContain(notificationMessage) + expect(successMessages[0].innerHTML).toContain(notificationMessage) done() } catch (error) { done(error) @@ -80,7 +86,7 @@ describe('Notifier', () => { expect(failureMessages.length).toBe(0) - $(successMessages[1]).children('button').click() + $(successMessages[0]).children('button').click() successMessages = notificationsElement.find('.success-indicator') expect(successMessages.length).toBe(1) diff --git a/app/views/layouts/_notifier.erb b/app/views/layouts/_notifier.erb index 2aacd83774..06586fb02c 100644 --- a/app/views/layouts/_notifier.erb +++ b/app/views/layouts/_notifier.erb @@ -7,9 +7,9 @@ From 9389f958e57936a160c1458ee90768dc0726a205 Mon Sep 17 00:00:00 2001 From: firelemons Date: Fri, 20 Oct 2023 19:51:07 -0500 Subject: [PATCH 13/23] moved notification messages to own div --- app/assets/stylesheets/shared/notifier.scss | 5 +++++ app/javascript/__tests__/notifier.test.js | 16 +++++++++------- app/javascript/src/notifier.js | 2 +- app/views/layouts/_notifier.erb | 2 ++ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/shared/notifier.scss b/app/assets/stylesheets/shared/notifier.scss index ff9f4975b9..faf582c0bf 100644 --- a/app/assets/stylesheets/shared/notifier.scss +++ b/app/assets/stylesheets/shared/notifier.scss @@ -35,6 +35,11 @@ color: white } + .messages { + margin-bottom: 0; + padding: 0; + } + .success-indicator { background-color: #28a745; color: white diff --git a/app/javascript/__tests__/notifier.test.js b/app/javascript/__tests__/notifier.test.js index 1e23fc8360..3b07c4900e 100644 --- a/app/javascript/__tests__/notifier.test.js +++ b/app/javascript/__tests__/notifier.test.js @@ -9,6 +9,8 @@ let notifier beforeEach(() => { document.body.innerHTML = `
+
+
@@ -39,10 +41,9 @@ describe('Notifier', () => { try { notifier.notify(notificationMessage, 'info') - const successMessages = notificationsElement.find('.success-indicator') + const successMessages = notificationsElement.children('.messages').find('.success-indicator') - // Notifications contain the hidden "Saved" message and the new message - expect(successMessages.length).toBe(2) + expect(successMessages.length).toBe(1) expect(successMessages[0].innerHTML).toContain(notificationMessage) done() } catch (error) { @@ -75,11 +76,12 @@ describe('Notifier', () => { notifier.notify('', 'error') notifier.notify('', 'info') - let failureMessages = notificationsElement.find('.failure-indicator') - let successMessages = notificationsElement.find('.success-indicator') + const messagesContainer = notificationsElement.children('.messages') + let failureMessages = messagesContainer.find('.failure-indicator') + let successMessages = messagesContainer.find('.success-indicator') expect(failureMessages.length).toBe(1) - expect(successMessages.length).toBe(2) + expect(successMessages.length).toBe(1) failureMessages.children('button').click() failureMessages = notificationsElement.find('.failure-indicator') @@ -151,7 +153,7 @@ describe('Notifier', () => { $(() => { try { const notification = notifier.notify('test', 'info') - const onlyNotification = notificationsElement.children('.success-indicator') + const onlyNotification = notificationsElement.children('.messages').children('.success-indicator') expect(notification.notificationElement.is(onlyNotification)).toBe(true) done() diff --git a/app/javascript/src/notifier.js b/app/javascript/src/notifier.js index 4ec2600300..ce5d57ae86 100644 --- a/app/javascript/src/notifier.js +++ b/app/javascript/src/notifier.js @@ -175,7 +175,7 @@ class Notifier {
` ) - this.notificationsElement.prepend(newNotificationAsJQuery) + this.notificationsElement.children('.messages').append(newNotificationAsJQuery) const newNotification = new Notification(newNotificationAsJQuery, this) diff --git a/app/views/layouts/_notifier.erb b/app/views/layouts/_notifier.erb index 06586fb02c..51383df57a 100644 --- a/app/views/layouts/_notifier.erb +++ b/app/views/layouts/_notifier.erb @@ -1,4 +1,6 @@
+
+
From b63937321c5a1a815f90d9c3229c72d9bfe40e68 Mon Sep 17 00:00:00 2001 From: firelemons Date: Fri, 20 Oct 2023 21:23:13 -0500 Subject: [PATCH 14/23] created toggleMinimize --- app/assets/stylesheets/shared/notifier.scss | 4 ++ app/javascript/src/notifier.js | 52 +++++++++++++++++---- app/views/layouts/_notifier.erb | 8 ++-- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/shared/notifier.scss b/app/assets/stylesheets/shared/notifier.scss index faf582c0bf..bdb43b40c0 100644 --- a/app/assets/stylesheets/shared/notifier.scss +++ b/app/assets/stylesheets/shared/notifier.scss @@ -72,5 +72,9 @@ border-radius: 10px 10px 0 0; color: white; padding: 0.25em 1em; + + span { + display: inline; + } } } diff --git a/app/javascript/src/notifier.js b/app/javascript/src/notifier.js index ce5d57ae86..62982b72ca 100644 --- a/app/javascript/src/notifier.js +++ b/app/javascript/src/notifier.js @@ -5,18 +5,18 @@ const TypeChecker = require('./type_checker.js') const levels = { error: { - classPrefixMessage: 'failure', - classSuffixDismissButton: 'danger' + classBootstrap: 'danger', + classPrefixMessage: 'failure' }, info: { - classPrefixMessage: 'success', - classSuffixDismissButton: 'success' + classBootstrap: 'success', + classPrefixMessage: 'success' }, warn: { - classPrefixMessage: 'warn', - classSuffixDismissButton: 'warning' + classBootstrap: 'warning', + classPrefixMessage: 'warn' } } @@ -107,7 +107,7 @@ class Notification { } #userDismissableEnable () { - const dismissButton = $(``) + const dismissButton = $(``) this.notificationElement.append(dismissButton) dismissButton.on('click', () => { @@ -138,6 +138,16 @@ class Notifier { outer.#setMinimizeButtonVisibility(false) } + const levelBadge = $('#toggle-minimize-notifications').children(`.bg-${levels[propertyKey].classBootstrap}`) + + levelBadge.text(value) + + if (value && outer.notificationsElement.children('.messages').css('display') === 'none') { + levelBadge.show() + } else { + levelBadge.hide() + } + return defaultSet } }) @@ -166,7 +176,7 @@ class Notifier { throw new RangeError('Unsupported option for param level') } - const dismissButtonAsHTML = isDismissable ? `` : '' + const dismissButtonAsHTML = isDismissable ? `` : '' const newNotificationAsJQuery = $( `
@@ -228,6 +238,32 @@ class Notifier { } } + toggleMinimize () { + const messagesContainer = this.notificationsElement.children('.messages') + const minimizeButton = this.notificationsElement.children('#toggle-minimize-notifications') + + if (messagesContainer.css('display') === 'none') { + messagesContainer.show() + minimizeButton.children('span').first().show() + minimizeButton.children('.badge').hide() + minimizeButton.children('.fa-solid').removeClass('fa-plus').addClass('fa-minus') + } else { + messagesContainer.hide() + + for (const level in this.notificationsCount) { + const levelMessageCount = this.notificationsCount[level] + + if (levelMessageCount) { + const levelBadge = minimizeButton.children(`.bg-${levels[level].classBootstrap}`) + levelBadge.show() + } + } + + minimizeButton.children('span').first().hide() + minimizeButton.children('.fa-solid').removeClass('fa-minus').addClass('fa-plus') + } + } + totalNotificationCount () { return Object.values(this.notificationsCount).reduce((acc, currentValue) => { return acc + currentValue diff --git a/app/views/layouts/_notifier.erb b/app/views/layouts/_notifier.erb index 51383df57a..7379bb3a2e 100644 --- a/app/views/layouts/_notifier.erb +++ b/app/views/layouts/_notifier.erb @@ -8,10 +8,10 @@ Saved
From 973b7639d37f01875e332cc6801dc5ead243efae Mon Sep 17 00:00:00 2001 From: firelemons Date: Sat, 21 Oct 2023 16:23:55 -0500 Subject: [PATCH 15/23] reduced jQuery lookups, made code simpler --- app/assets/stylesheets/shared/notifier.scss | 6 +- app/javascript/__tests__/notifier.test.js | 22 +++--- app/javascript/src/notifier.js | 86 +++++++++++---------- app/views/layouts/_notifier.erb | 2 +- 4 files changed, 60 insertions(+), 56 deletions(-) diff --git a/app/assets/stylesheets/shared/notifier.scss b/app/assets/stylesheets/shared/notifier.scss index bdb43b40c0..7e3f89d648 100644 --- a/app/assets/stylesheets/shared/notifier.scss +++ b/app/assets/stylesheets/shared/notifier.scss @@ -30,7 +30,7 @@ } } - .failure-indicator { + .danger-notification { background-color: #b71c1c; color: white } @@ -40,12 +40,12 @@ padding: 0; } - .success-indicator { + .success-notification { background-color: #28a745; color: white } - .warn-indicator { + .warning-notification { background-color: #ffc107; } diff --git a/app/javascript/__tests__/notifier.test.js b/app/javascript/__tests__/notifier.test.js index 3b07c4900e..7b5c31a0a7 100644 --- a/app/javascript/__tests__/notifier.test.js +++ b/app/javascript/__tests__/notifier.test.js @@ -14,7 +14,7 @@ beforeEach(() => { -