From 67816b55a96f3305fea8abdee6a42c1ec10a7bdf Mon Sep 17 00:00:00 2001 From: moijes12 <4566851+moijes12@users.noreply.github.com> Date: Tue, 7 Jul 2026 14:15:34 +0000 Subject: [PATCH] Bug 1150056 - Fix Job panel pinboard-count sync when using PinAll --- .../job-view/stores/pinnedJobsStore_test.jsx | 61 +++++++++++++++++++ ui/shared/stores/pinnedJobsStore.js | 33 ++++++---- 2 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 tests/ui/job-view/stores/pinnedJobsStore_test.jsx diff --git a/tests/ui/job-view/stores/pinnedJobsStore_test.jsx b/tests/ui/job-view/stores/pinnedJobsStore_test.jsx new file mode 100644 index 00000000000..48e73b4a851 --- /dev/null +++ b/tests/ui/job-view/stores/pinnedJobsStore_test.jsx @@ -0,0 +1,61 @@ +import { usePinnedJobsStore } from '../../../../ui/shared/stores/pinnedJobsStore'; +import { notify } from '../../../../ui/shared/stores/notificationStore'; + +// Mock the notification store +jest.mock('../../../../ui/shared/stores/notificationStore', () => ({ + notify: jest.fn(), +})); + +// Mock pulsePinCount as it touches the DOM +document.getElementById = jest.fn(); + +describe('pinnedJobsStore', () => { + beforeEach(() => { + usePinnedJobsStore.getState().unPinAll(); + jest.clearAllMocks(); + }); + + it('should pin jobs and handle max size correctly', () => { + const store = usePinnedJobsStore.getState(); + const jobs = Array.from({ length: 505 }, (_, i) => ({ id: i, name: `job-${i}` })); + + // Pin first 490 jobs + store.pinJobs(jobs.slice(0, 490)); + expect(Object.keys(usePinnedJobsStore.getState().pinnedJobs).length).toBe(490); + + // Try to pin all 505 jobs (including 490 already pinned) + // There are 15 new jobs (490 to 504). + // Remaining space is 500 - 490 = 10. + // So it should pin 10 more (490 to 499) and show an error for the remaining 5. + store.pinJobs(jobs); + + expect(Object.keys(usePinnedJobsStore.getState().pinnedJobs).length).toBe(500); + expect(notify).toHaveBeenCalledWith('Max pinboard size of 500 reached.', 'danger', { sticky: true }); + }); + + it('should not show error if all jobs to pin are already pinned', () => { + const store = usePinnedJobsStore.getState(); + const jobs = Array.from({ length: 10 }, (_, i) => ({ id: i, name: `job-${i}` })); + + store.pinJobs(jobs); + jest.clearAllMocks(); + + store.pinJobs(jobs); + expect(Object.keys(usePinnedJobsStore.getState().pinnedJobs).length).toBe(10); + expect(notify).not.toHaveBeenCalled(); + }); + + it('should only pin what fits and show error if some dont fit', () => { + const store = usePinnedJobsStore.getState(); + // Fill up to 495 + const existingJobs = Array.from({ length: 495 }, (_, i) => ({ id: i, name: `job-${i}` })); + store.pinJobs(existingJobs); + + // Try to add 10 more + const moreJobs = Array.from({ length: 10 }, (_, i) => ({ id: i + 500, name: `job-${i + 500}` })); + store.pinJobs(moreJobs); + + expect(Object.keys(usePinnedJobsStore.getState().pinnedJobs).length).toBe(500); + expect(notify).toHaveBeenCalledWith('Max pinboard size of 500 reached.', 'danger', { sticky: true }); + }); +}); diff --git a/ui/shared/stores/pinnedJobsStore.js b/ui/shared/stores/pinnedJobsStore.js index 9b264f5bdce..b322ed0bba4 100644 --- a/ui/shared/stores/pinnedJobsStore.js +++ b/ui/shared/stores/pinnedJobsStore.js @@ -67,21 +67,32 @@ export const usePinnedJobsStore = create( pinJobs: (jobsToPin) => { const { pinnedJobs } = get(); - const spaceRemaining = MAX_SIZE - Object.keys(pinnedJobs).length; - const showError = jobsToPin.length > spaceRemaining; - const newPinnedJobs = jobsToPin - .slice(0, spaceRemaining) - .reduce((acc, job) => ({ ...acc, [job.id]: job }), {}); + const newJobsToPin = jobsToPin.filter((job) => !pinnedJobs[job.id]); - if (!spaceRemaining || showError) { - notify(COUNT_ERROR, 'danger', { sticky: true }); + if (newJobsToPin.length === 0) { return; } - set({ - pinnedJobs: { ...pinnedJobs, ...newPinnedJobs }, - isPinBoardVisible: true, - }); + const spaceRemaining = MAX_SIZE - Object.keys(pinnedJobs).length; + const jobsToAdd = newJobsToPin.slice(0, spaceRemaining); + const showError = newJobsToPin.length > spaceRemaining; + + if (jobsToAdd.length > 0) { + const newPinnedJobsMap = jobsToAdd.reduce( + (acc, job) => ({ ...acc, [job.id]: job }), + {}, + ); + + set({ + pinnedJobs: { ...pinnedJobs, ...newPinnedJobsMap }, + isPinBoardVisible: true, + }); + pulsePinCount(); + } + + if (showError) { + notify(COUNT_ERROR, 'danger', { sticky: true }); + } }, addBug: (bug, job = null) => {