From 1c1397b15c7f83d43fa65a2086384d2f43bb32d7 Mon Sep 17 00:00:00 2001 From: Mohamed Khelif Date: Tue, 19 Dec 2023 12:37:28 -0500 Subject: [PATCH 01/22] DEVPROD-794 Split out ETATimer and RuntimeTimer into their own components (#2189) --- src/hooks/index.ts | 1 + src/hooks/useRunningTime/index.ts | 31 ++++++++++ .../useRunningTime/useRunningTime.test.ts | 49 +++++++++++++++ src/pages/task/metadata/ETATimer.tsx | 62 ------------------- .../task/metadata/ETATimer/ETATimer.test.tsx | 50 +++++++++++++++ src/pages/task/metadata/ETATimer/index.tsx | 30 +++++++++ src/pages/task/metadata/Metadata.test.tsx | 6 +- .../RuntimeTimer/RuntimeTimer.test.tsx | 32 ++++++++++ .../task/metadata/RuntimeTimer/index.tsx | 22 +++++++ src/pages/task/metadata/index.tsx | 6 +- src/utils/string/index.ts | 3 + 11 files changed, 226 insertions(+), 66 deletions(-) create mode 100644 src/hooks/useRunningTime/index.ts create mode 100644 src/hooks/useRunningTime/useRunningTime.test.ts delete mode 100644 src/pages/task/metadata/ETATimer.tsx create mode 100644 src/pages/task/metadata/ETATimer/ETATimer.test.tsx create mode 100644 src/pages/task/metadata/ETATimer/index.tsx create mode 100644 src/pages/task/metadata/RuntimeTimer/RuntimeTimer.test.tsx create mode 100644 src/pages/task/metadata/RuntimeTimer/index.tsx diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 540a59753b..9afda3ba11 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -25,3 +25,4 @@ export { useDateFormat } from "./useDateFormat"; export { useFirstDistro } from "./useFirstDistro"; export { useBreadcrumbRoot } from "./useBreadcrumbRoot"; export { useResize } from "./useResize"; +export { useRunningTime } from "./useRunningTime"; diff --git a/src/hooks/useRunningTime/index.ts b/src/hooks/useRunningTime/index.ts new file mode 100644 index 0000000000..9eb23f5c61 --- /dev/null +++ b/src/hooks/useRunningTime/index.ts @@ -0,0 +1,31 @@ +import { useState, useEffect, useRef } from "react"; +import differenceInMilliseconds from "date-fns/differenceInMilliseconds"; + +/** + * `useRunningTime` is a hook that returns the time elapsed since the start time. It refreshes every second. + * @param startTime - The start time of the timer + * @returns + * - `runningTime` - The running time in milliseconds + * - `endTimer` - A function that clears the timer + */ +export const useRunningTime = (startTime: Date) => { + const [runningTime, setRunningTime] = useState( + differenceInMilliseconds(Date.now(), startTime) + ); + + const timerRef = useRef(null); + + useEffect(() => { + timerRef.current = setInterval(() => { + const newRunningTime = differenceInMilliseconds(Date.now(), startTime); + setRunningTime(newRunningTime > 0 ? newRunningTime : 0); + }, 1000); + + return () => clearInterval(timerRef.current); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [startTime]); + + const endTimer = () => clearInterval(timerRef.current); + + return { runningTime, endTimer }; +}; diff --git a/src/hooks/useRunningTime/useRunningTime.test.ts b/src/hooks/useRunningTime/useRunningTime.test.ts new file mode 100644 index 0000000000..83207bf98d --- /dev/null +++ b/src/hooks/useRunningTime/useRunningTime.test.ts @@ -0,0 +1,49 @@ +import { renderHook, act } from "test_utils"; +import { useRunningTime } from "."; // Make sure to adjust the import path + +describe("useRunningTime", () => { + beforeAll(() => { + jest.useFakeTimers(); + }); + afterAll(() => { + jest.useRealTimers(); + }); + + it("should initialize runningTime based on the provided startTime", () => { + const startTime = new Date(); + const { result } = renderHook(() => useRunningTime(startTime)); + + expect(result.current.runningTime).toBe(0); + }); + it("should update runningTime at intervals", () => { + const startTime = new Date(); + const { result } = renderHook(() => useRunningTime(startTime)); + + act(() => { + jest.advanceTimersByTime(1000); + }); + + expect(result.current.runningTime).toBe(1000); + }); + + it("should stop the timer when endTimer is called", () => { + const startTime = new Date(); + const { result } = renderHook(() => useRunningTime(startTime)); + + act(() => { + jest.advanceTimersByTime(1000); + }); + + expect(result.current.runningTime).toBe(1000); + + act(() => { + result.current.endTimer(); + }); + + act(() => { + jest.advanceTimersByTime(1000); + }); + + expect(result.current.runningTime).toBe(1000); // Should not have changed after stopping the timer + }); +}); diff --git a/src/pages/task/metadata/ETATimer.tsx b/src/pages/task/metadata/ETATimer.tsx deleted file mode 100644 index fbe531ed97..0000000000 --- a/src/pages/task/metadata/ETATimer.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useState, useEffect } from "react"; -import { addMilliseconds, differenceInMilliseconds } from "date-fns"; -import { MetadataItem } from "components/MetadataCard"; -import { string } from "utils"; - -const { msToDuration } = string; -interface ETATimerProps { - startTime: Date; - expectedDuration: number; -} -export const ETATimer: React.FC = ({ - expectedDuration, - startTime, -}) => { - const parsedStartTime = new Date(startTime); - const estimatedCompletionTime = addMilliseconds( - parsedStartTime, - expectedDuration - ); - - const currentTime = Date.now(); - const [eta, setEta] = useState( - differenceInMilliseconds(currentTime, estimatedCompletionTime) - ); - - const [runningTime, setRunningTime] = useState( - differenceInMilliseconds(parsedStartTime, currentTime) - ); - - useEffect(() => { - const timer = setInterval(() => { - const newEta = differenceInMilliseconds( - estimatedCompletionTime, - currentTime - ); - const newRunningTime = differenceInMilliseconds( - currentTime, - parsedStartTime - ); - setEta(newEta > 0 ? newEta : 0); - setRunningTime(newRunningTime > 0 ? newRunningTime : 0); - }, 1000); - if (eta === 0 || runningTime === 0) { - clearInterval(timer); - } - return () => clearInterval(timer); - }); - - return ( - <> - - Running Time:{" "} - {msToDuration(runningTime)} - - {eta >= 0 && ( - - ETA: {msToDuration(eta)} - - )} - - ); -}; diff --git a/src/pages/task/metadata/ETATimer/ETATimer.test.tsx b/src/pages/task/metadata/ETATimer/ETATimer.test.tsx new file mode 100644 index 0000000000..57f174e155 --- /dev/null +++ b/src/pages/task/metadata/ETATimer/ETATimer.test.tsx @@ -0,0 +1,50 @@ +import { render, screen, waitFor, act } from "test_utils"; +import ETATimer from "."; + +describe("etaTimer", () => { + beforeEach(() => { + jest.useFakeTimers(); + jest.spyOn(global, "setInterval"); + jest.spyOn(global, "clearInterval"); + }); + afterEach(() => { + jest.useRealTimers(); + jest.restoreAllMocks(); + }); + it("counts down", async () => { + const startTime = new Date(); + const expectedDuration = 10000; + render( + + ); + expect(screen.getByText("ETA: 10s")).toBeInTheDocument(); + act(() => { + jest.runOnlyPendingTimers(); + }); + await waitFor(() => { + expect(screen.getByText("ETA: 9s")).toBeInTheDocument(); + }); + act(() => { + jest.runOnlyPendingTimers(); + }); + await waitFor(() => { + expect(screen.getByText("ETA: 8s")).toBeInTheDocument(); + }); + }); + it("stops counting down when it reaches 0", async () => { + const startTime = new Date(); + const expectedDuration = 1000; + render( + + ); + expect(screen.getByText("ETA: 1s")).toBeInTheDocument(); + act(() => { + jest.runOnlyPendingTimers(); + }); + await waitFor(() => { + expect(screen.getByText("ETA: 0s")).toBeInTheDocument(); + }); + expect(global.clearInterval).toHaveBeenCalledWith(expect.any(Number)); + expect(jest.getTimerCount()).toBe(0); + }); +}); diff --git a/src/pages/task/metadata/ETATimer/index.tsx b/src/pages/task/metadata/ETATimer/index.tsx new file mode 100644 index 0000000000..438a4e72d0 --- /dev/null +++ b/src/pages/task/metadata/ETATimer/index.tsx @@ -0,0 +1,30 @@ +import { useEffect } from "react"; +import { MetadataItem } from "components/MetadataCard"; +import { useRunningTime } from "hooks"; +import { string } from "utils"; + +const { msToDuration } = string; + +interface ETATimerProps { + startTime: Date; + expectedDuration: number; +} +const ETATimer: React.FC = ({ expectedDuration, startTime }) => { + const parsedStartTime = new Date(startTime); + const { endTimer, runningTime } = useRunningTime(parsedStartTime); + + useEffect(() => { + if (runningTime >= expectedDuration) { + endTimer(); + } + }, [runningTime, expectedDuration, endTimer]); + + const eta = expectedDuration - runningTime; + return ( + + ETA: {msToDuration(eta)} + + ); +}; + +export default ETATimer; diff --git a/src/pages/task/metadata/Metadata.test.tsx b/src/pages/task/metadata/Metadata.test.tsx index 2fb2685a9a..eea9e28287 100644 --- a/src/pages/task/metadata/Metadata.test.tsx +++ b/src/pages/task/metadata/Metadata.test.tsx @@ -26,7 +26,7 @@ describe("metadata", () => { expect( screen.queryByDataCy("task-metadata-estimated_start") ).toHaveTextContent("1s"); - expect(screen.queryByDataCy("metadata-eta-timer")).toBeNull(); + expect(screen.queryByDataCy("task-metadata-eta")).toBeNull(); expect(screen.queryByDataCy("task-metadata-started")).toBeNull(); expect(screen.queryByDataCy("task-metadata-finished")).toBeNull(); }); @@ -45,7 +45,7 @@ describe("metadata", () => { } ); expect(screen.queryByDataCy("task-metadata-estimated_start")).toBeNull(); - expect(screen.getByDataCy("metadata-eta-timer")).toBeInTheDocument(); + expect(screen.getByDataCy("task-metadata-eta")).toBeInTheDocument(); expect(screen.getByDataCy("task-metadata-started")).toBeInTheDocument(); expect(screen.queryByDataCy("task-metadata-finished")).toBeNull(); expect(screen.queryByDataCy("task-trace-link")).toBeNull(); @@ -69,7 +69,7 @@ describe("metadata", () => { ); expect(screen.queryByDataCy("task-metadata-estimated_start")).toBeNull(); - expect(screen.queryByDataCy("metadata-eta-timer")).toBeNull(); + expect(screen.queryByDataCy("task-metadata-eta")).toBeNull(); expect(screen.getByDataCy("task-metadata-started")).toBeInTheDocument(); expect(screen.getByDataCy("task-metadata-finished")).toBeInTheDocument(); expect(screen.getByDataCy("task-trace-link")).toBeInTheDocument(); diff --git a/src/pages/task/metadata/RuntimeTimer/RuntimeTimer.test.tsx b/src/pages/task/metadata/RuntimeTimer/RuntimeTimer.test.tsx new file mode 100644 index 0000000000..fa330fee81 --- /dev/null +++ b/src/pages/task/metadata/RuntimeTimer/RuntimeTimer.test.tsx @@ -0,0 +1,32 @@ +import { render, screen, waitFor, act } from "test_utils"; +import RuntimeTimer from "."; + +describe("runtimeTimer", () => { + beforeEach(() => { + jest.useFakeTimers(); + jest.spyOn(global, "setInterval"); + jest.spyOn(global, "clearInterval"); + }); + afterEach(() => { + jest.useRealTimers(); + jest.restoreAllMocks(); + }); + it("counts up as the run time progresses", async () => { + // 10 seconds ago + const startTime = new Date(Date.now() - 10000); + render(); + expect(screen.getByText("Running Time: 10s")).toBeInTheDocument(); + act(() => { + jest.runOnlyPendingTimers(); + }); + await waitFor(() => { + expect(screen.getByText("Running Time: 11s")).toBeInTheDocument(); + }); + act(() => { + jest.runOnlyPendingTimers(); + }); + await waitFor(() => { + expect(screen.getByText("Running Time: 12s")).toBeInTheDocument(); + }); + }); +}); diff --git a/src/pages/task/metadata/RuntimeTimer/index.tsx b/src/pages/task/metadata/RuntimeTimer/index.tsx new file mode 100644 index 0000000000..a241da9ecc --- /dev/null +++ b/src/pages/task/metadata/RuntimeTimer/index.tsx @@ -0,0 +1,22 @@ +import { MetadataItem } from "components/MetadataCard"; +import { useRunningTime } from "hooks"; +import { string } from "utils"; + +const { msToDuration } = string; + +interface RuntimeTimerProps { + startTime: Date; +} +const RuntimeTimer: React.FC = ({ startTime }) => { + const parsedStartTime = new Date(startTime); + + const { runningTime } = useRunningTime(parsedStartTime); + + return ( + + Running Time: {msToDuration(runningTime)} + + ); +}; + +export default RuntimeTimer; diff --git a/src/pages/task/metadata/index.tsx b/src/pages/task/metadata/index.tsx index ddb1bdebcb..0843f9dcb0 100644 --- a/src/pages/task/metadata/index.tsx +++ b/src/pages/task/metadata/index.tsx @@ -36,7 +36,8 @@ import { TaskStatus } from "types/task"; import { string } from "utils"; import { AbortMessage } from "./AbortMessage"; import { DependsOn } from "./DependsOn"; -import { ETATimer } from "./ETATimer"; +import ETATimer from "./ETATimer"; +import RuntimeTimer from "./RuntimeTimer"; const { applyStrictRegex, msToDuration, shortenGithash } = string; const { red } = palette; @@ -165,6 +166,9 @@ export const Metadata: React.FC = ({ error, loading, task, taskId }) => { {status === TaskStatus.Started && expectedDuration > 0 && ( )} + {status === TaskStatus.Started && startTime && ( + + )} {startTime && ( Started:{" "} diff --git a/src/utils/string/index.ts b/src/utils/string/index.ts index 423024e5ee..cd9d4b2e59 100644 --- a/src/utils/string/index.ts +++ b/src/utils/string/index.ts @@ -9,6 +9,9 @@ export { githubPRLinkify } from "./githubPRLinkify"; * @returns - a string representing the duration in the format of "1d 2h 3m 4s" */ export const msToDuration = (ms: number): string => { + if (ms === 0) { + return "0s"; + } const days = Math.floor(ms / (24 * 60 * 60 * 1000)); const daysMilli = ms % (24 * 60 * 60 * 1000); const hours = Math.floor(daysMilli / (60 * 60 * 1000)); From 494651f4204f9c72b90cb60078cf01b3c3b2f902 Mon Sep 17 00:00:00 2001 From: Arjun Patel Date: Tue, 19 Dec 2023 13:14:17 -0500 Subject: [PATCH 02/22] v3.0.185 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 35ebe76697..563beb4778 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "spruce", - "version": "3.0.184", + "version": "3.0.185", "private": true, "scripts": { "bootstrap-logkeeper": "./scripts/bootstrap-logkeeper.sh", From d72fd8b008f20abede20036b048e1b9916b1ead0 Mon Sep 17 00:00:00 2001 From: SupaJoon Date: Tue, 19 Dec 2023 14:17:15 -0500 Subject: [PATCH 03/22] DEVPROD-1905: Upgrade @leafygreen-ui/select to v11.1.1 (#2192) --- cypress/integration/spawn/host.ts | 2 +- cypress/integration/spawn/volume.ts | 2 +- package.json | 2 +- src/components/Hosts/UpdateStatusModal.tsx | 1 - src/components/PageSizeSelector/index.tsx | 1 - src/components/TupleSelect/index.tsx | 1 - .../spawnVolume/SpawnVolumeModal.test.tsx | 5 +- yarn.lock | 53 ++++++------------- 8 files changed, 24 insertions(+), 43 deletions(-) diff --git a/cypress/integration/spawn/host.ts b/cypress/integration/spawn/host.ts index 432b063564..94aaeaac21 100644 --- a/cypress/integration/spawn/host.ts +++ b/cypress/integration/spawn/host.ts @@ -174,7 +174,7 @@ describe("Navigating to Spawn Host page", () => { cy.dataCy("distro-option-ubuntu1804-workstation") .should("be.visible") .click(); - cy.dataCy("volume-select").should("be.disabled"); + cy.dataCy("volume-select").should("have.attr", "aria-disabled", "true"); }); it("Clicking 'Add new key' hides the key name dropdown and shows the key value text area", () => { diff --git a/cypress/integration/spawn/volume.ts b/cypress/integration/spawn/volume.ts index 6578a58f88..f117857230 100644 --- a/cypress/integration/spawn/volume.ts +++ b/cypress/integration/spawn/volume.ts @@ -270,7 +270,7 @@ describe("Spawn volume page", () => { ).click(); cy.dataCy("distro-input").click(); cy.dataCy("distro-option-ubuntu1804-workstation").click(); - cy.dataCy("region-select").should("be.disabled"); + cy.dataCy("region-select").should("have.attr", "aria-disabled", "true"); cy.dataCy("migrate-modal").contains("Next").click({ force: true }); cy.dataCy("migrate-modal") .contains("Migrate Volume") diff --git a/package.json b/package.json index 563beb4778..59cb26db7e 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@leafygreen-ui/radio-group": "10.1.1", "@leafygreen-ui/search-input": "2.0.8", "@leafygreen-ui/segmented-control": "8.2.6", - "@leafygreen-ui/select": "10.2.0", + "@leafygreen-ui/select": "11.1.1", "@leafygreen-ui/side-nav": "14.0.3", "@leafygreen-ui/skeleton-loader": "1.1.0", "@leafygreen-ui/table": "12.1.4", diff --git a/src/components/Hosts/UpdateStatusModal.tsx b/src/components/Hosts/UpdateStatusModal.tsx index cdbe810d82..8cd2332d97 100644 --- a/src/components/Hosts/UpdateStatusModal.tsx +++ b/src/components/Hosts/UpdateStatusModal.tsx @@ -113,7 +113,6 @@ export const UpdateStatusModal: React.FC = ({ ); }; -// @ts-expect-error const StyledSelect = styled(Select)` margin-bottom: ${size.xs}; `; diff --git a/src/components/PageSizeSelector/index.tsx b/src/components/PageSizeSelector/index.tsx index c4b762fdbe..ce91e5175e 100644 --- a/src/components/PageSizeSelector/index.tsx +++ b/src/components/PageSizeSelector/index.tsx @@ -33,7 +33,6 @@ const PageSizeSelector: React.FC = ({ onChange, value, ...rest }) => ( ); -// @ts-expect-error const StyledSelect = styled(Select)` width: 120px; `; diff --git a/src/components/TupleSelect/index.tsx b/src/components/TupleSelect/index.tsx index 3a9140b092..5713090199 100644 --- a/src/components/TupleSelect/index.tsx +++ b/src/components/TupleSelect/index.tsx @@ -89,7 +89,6 @@ const LabelContainer = styled.div` flex-direction: row; `; -// @ts-expect-error const GroupedSelect = styled(Select)` width: 30%; /* overwrite lg borders https://jira.mongodb.org/browse/PD-1995 */ diff --git a/src/pages/spawn/spawnVolume/SpawnVolumeModal.test.tsx b/src/pages/spawn/spawnVolume/SpawnVolumeModal.test.tsx index dd4b686c30..565c3a1edc 100644 --- a/src/pages/spawn/spawnVolume/SpawnVolumeModal.test.tsx +++ b/src/pages/spawn/spawnVolume/SpawnVolumeModal.test.tsx @@ -59,7 +59,10 @@ describe("spawnVolumeModal", () => { ); expect(screen.queryByDataCy("type-select")).toHaveTextContent("gp2"); expect(screen.queryByLabelText("Never expire")).not.toBeChecked(); - expect(screen.queryByDataCy("host-select")).toBeDisabled(); + expect(screen.queryByDataCy("host-select")).toHaveAttribute( + "aria-disabled", + "true" + ); expect(screen.queryByText("No hosts available.")).toBeVisible(); }); diff --git a/yarn.lock b/yarn.lock index b8a67bf571..e8dec19340 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3229,7 +3229,7 @@ "@leafygreen-ui/tokens" "^2.1.4" polished "^4.2.2" -"@leafygreen-ui/button@^19.0.1", "@leafygreen-ui/button@^19.0.4": +"@leafygreen-ui/button@^19.0.1": version "19.0.4" resolved "https://registry.yarnpkg.com/@leafygreen-ui/button/-/button-19.0.4.tgz#f94ea61608e56020358ac3f8cd66669f125dff64" integrity sha512-T72lmAHS63cvhyAKaO53tNysL3xDsjnmIoaP0I55eOFOYlEy522U7vf0RMi/BsOePyAJak+x9yZ4uj8AWMCsbg== @@ -3863,24 +3863,25 @@ lodash "^4.17.21" polished "^4.2.2" -"@leafygreen-ui/select@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/select/-/select-10.2.0.tgz#d5c9dd7ca6ec4f043cda45c07c7c5fad89505543" - integrity sha512-w0/XSmN0O85jIahBxgpqGncR0b7R9As4+TNenHe0ULmEwsV1cKpNGt5qXlRyzh6dO7vYKcuSGGhvZW9fCuU/xQ== +"@leafygreen-ui/select@11.1.1", "@leafygreen-ui/select@^11.1.0": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@leafygreen-ui/select/-/select-11.1.1.tgz#b4d03071837feca1d5c206b36a1018b7d936f43f" + integrity sha512-aH0RNrIF3EU+5ChHJxVVjzlmFGkYRTq9DTRqm9eWgWcZIT3+ggIJCOwBNMr/8rD72NhyXm+RD8Gp2wwk8XJJrg== dependencies: - "@leafygreen-ui/button" "^19.0.4" - "@leafygreen-ui/emotion" "^4.0.3" - "@leafygreen-ui/hooks" "^7.3.3" - "@leafygreen-ui/icon" "^11.12.4" - "@leafygreen-ui/lib" "^10.0.0" - "@leafygreen-ui/palette" "^3.4.7" - "@leafygreen-ui/popover" "^11.0.4" - "@leafygreen-ui/tokens" "^2.0.0" - "@leafygreen-ui/typography" "^16.0.0" - "@types/react-is" "^17.0.0" + "@leafygreen-ui/button" "^21.0.10" + "@leafygreen-ui/emotion" "^4.0.7" + "@leafygreen-ui/hooks" "^8.0.1" + "@leafygreen-ui/icon" "^11.25.0" + "@leafygreen-ui/input-option" "^1.0.13" + "@leafygreen-ui/lib" "^13.0.0" + "@leafygreen-ui/palette" "^4.0.7" + "@leafygreen-ui/popover" "^11.1.1" + "@leafygreen-ui/tokens" "^2.2.0" + "@leafygreen-ui/typography" "^18.0.1" + "@types/react-is" "^18.0.0" lodash "^4.17.21" polished "^4.1.3" - react-is "^17.0.1" + react-is "^18.0.1" "@leafygreen-ui/select@^10.1.0", "@leafygreen-ui/select@^10.3.12": version "10.3.12" @@ -3901,26 +3902,6 @@ polished "^4.1.3" react-is "^17.0.1" -"@leafygreen-ui/select@^11.1.0": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/select/-/select-11.1.1.tgz#b4d03071837feca1d5c206b36a1018b7d936f43f" - integrity sha512-aH0RNrIF3EU+5ChHJxVVjzlmFGkYRTq9DTRqm9eWgWcZIT3+ggIJCOwBNMr/8rD72NhyXm+RD8Gp2wwk8XJJrg== - dependencies: - "@leafygreen-ui/button" "^21.0.10" - "@leafygreen-ui/emotion" "^4.0.7" - "@leafygreen-ui/hooks" "^8.0.1" - "@leafygreen-ui/icon" "^11.25.0" - "@leafygreen-ui/input-option" "^1.0.13" - "@leafygreen-ui/lib" "^13.0.0" - "@leafygreen-ui/palette" "^4.0.7" - "@leafygreen-ui/popover" "^11.1.1" - "@leafygreen-ui/tokens" "^2.2.0" - "@leafygreen-ui/typography" "^18.0.1" - "@types/react-is" "^18.0.0" - lodash "^4.17.21" - polished "^4.1.3" - react-is "^18.0.1" - "@leafygreen-ui/side-nav@14.0.3": version "14.0.3" resolved "https://registry.yarnpkg.com/@leafygreen-ui/side-nav/-/side-nav-14.0.3.tgz#cf356dc7733e80bef88c4e33a5623c1ea028f748" From cc5b5510ab81c2de5122cf036f50035c06a93196 Mon Sep 17 00:00:00 2001 From: Mohamed Khelif Date: Tue, 19 Dec 2023 17:27:24 -0500 Subject: [PATCH 04/22] DEVPROD-2637 Add Guide Cue for Parsley viewable log files (#2193) --- cypress/integration/task/files_tables.ts | 2 +- package.json | 2 +- src/constants/cookies.ts | 2 + .../GroupedFileTable.stories.tsx | 2 + .../FileTable/GroupedFileTable/index.tsx | 70 +++++++++++++++++-- yarn.lock | 20 +++--- 6 files changed, 81 insertions(+), 17 deletions(-) diff --git a/cypress/integration/task/files_tables.ts b/cypress/integration/task/files_tables.ts index fea7593da7..f4eacf1e2e 100644 --- a/cypress/integration/task/files_tables.ts +++ b/cypress/integration/task/files_tables.ts @@ -1,7 +1,7 @@ describe("files table", () => { const FILES_ROUTE = "/task/evergreen_ubuntu1604_89/files"; const FILES_ROUTE_WITHOUT_FILES = - "/task/evergreen_ubuntu1604_test_model_commitqueue_patch_5e823e1f28baeaa22ae00823d83e03082cd148ab_5e4ff3abe3c3317e352062e4_20_02_21_15_13_48/files "; + "/task/evergreen_ubuntu1604_test_model_commitqueue_patch_5e823e1f28baeaa22ae00823d83e03082cd148ab_5e4ff3abe3c3317e352062e4_20_02_21_15_13_48/files"; it("File names under name column should link to a new tab", () => { cy.visit(FILES_ROUTE); diff --git a/package.json b/package.json index 59cb26db7e..cda3a8b6e9 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "@leafygreen-ui/confirmation-modal": "5.0.6", "@leafygreen-ui/emotion": "4.0.7", "@leafygreen-ui/expandable-card": "3.0.5", - "@leafygreen-ui/guide-cue": "5.0.4", + "@leafygreen-ui/guide-cue": "5.0.5", "@leafygreen-ui/icon": "11.12.1", "@leafygreen-ui/icon-button": "15.0.5", "@leafygreen-ui/inline-definition": "6.0.14", diff --git a/src/constants/cookies.ts b/src/constants/cookies.ts index 1a7379954b..7bfabd058c 100644 --- a/src/constants/cookies.ts +++ b/src/constants/cookies.ts @@ -16,5 +16,7 @@ export const INCLUDE_COMMIT_QUEUE_USER_PATCHES = "include-commit-queue-user-patches"; export const INCLUDE_HIDDEN_PATCHES = "include-hidden-patches"; export const SEEN_HONEYCOMB_GUIDE_CUE = "seen-honeycomb-guide-cue"; +export const SEEN_PARSLEY_FILES_GUIDE_CUE = "seen-parsley-files-guide-cue"; +export const SEEN_MIGRATE_GUIDE_CUE = "seen-migrate-guide-cue"; export const SLACK_NOTIFICATION_BANNER = "has-closed-slack-banner"; export const SUBSCRIPTION_METHOD = "subscription-method"; diff --git a/src/pages/task/taskTabs/FileTable/GroupedFileTable/GroupedFileTable.stories.tsx b/src/pages/task/taskTabs/FileTable/GroupedFileTable/GroupedFileTable.stories.tsx index b8a6627cca..9a58e08c7b 100644 --- a/src/pages/task/taskTabs/FileTable/GroupedFileTable/GroupedFileTable.stories.tsx +++ b/src/pages/task/taskTabs/FileTable/GroupedFileTable/GroupedFileTable.stories.tsx @@ -5,10 +5,12 @@ const files = [ { name: "some_file", link: "some_link", + urlParsley: null, }, { name: "another_file", link: "another_link", + urlParsley: "parsley_link", }, ]; diff --git a/src/pages/task/taskTabs/FileTable/GroupedFileTable/index.tsx b/src/pages/task/taskTabs/FileTable/GroupedFileTable/index.tsx index 35a26c46ea..0da68b9e01 100644 --- a/src/pages/task/taskTabs/FileTable/GroupedFileTable/index.tsx +++ b/src/pages/task/taskTabs/FileTable/GroupedFileTable/index.tsx @@ -1,12 +1,15 @@ -import { useMemo, useRef } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import styled from "@emotion/styled"; import Button from "@leafygreen-ui/button"; +import { GuideCue } from "@leafygreen-ui/guide-cue"; import { useLeafyGreenTable, LGColumnDef } from "@leafygreen-ui/table"; import Tooltip from "@leafygreen-ui/tooltip"; import { Subtitle } from "@leafygreen-ui/typography"; +import Cookies from "js-cookie"; import { useTaskAnalytics } from "analytics"; import { StyledLink } from "components/styles"; import { BaseTable } from "components/Table/BaseTable"; +import { SEEN_PARSLEY_FILES_GUIDE_CUE } from "constants/cookies"; import { size } from "constants/tokens"; import { Unpacked } from "types/utils"; import { GroupedFiles } from "../types"; @@ -14,7 +17,11 @@ import { GroupedFiles } from "../types"; type GroupedFilesFile = Unpacked; const columns = ( - taskAnalytics: ReturnType + taskAnalytics: ReturnType, + options: { + gudeCueTriggerRef: React.RefObject; + firstParsleyFileIndex: number; + } ): LGColumnDef[] => [ { accessorKey: "name", @@ -47,6 +54,11 @@ const columns = ( target="_blank" disabled={value.row.original.urlParsley === null} size="small" + ref={ + options && options.firstParsleyFileIndex === value.row.index + ? options.gudeCueTriggerRef + : null + } onClick={() => { taskAnalytics.sendEvent({ name: "Click Task File Parsley Link", @@ -79,11 +91,39 @@ const GroupedFileTable: React.FC = ({ }) => { const tableContainerRef = useRef(null); const taskAnalytics = useTaskAnalytics(); - + const [openGuideCue, setOpenGuideCue] = useState( + Cookies.get(SEEN_PARSLEY_FILES_GUIDE_CUE) !== "true" + ); + const firstParsleyFileIndex = useMemo( + () => files.findIndex((file) => file.urlParsley !== null), + [files] + ); + const parsleyLinkRef = useRef(null); const memoizedColumns = useMemo( - () => columns(taskAnalytics), - [taskAnalytics] + () => + columns( + taskAnalytics, + firstParsleyFileIndex !== -1 + ? { + gudeCueTriggerRef: parsleyLinkRef, + firstParsleyFileIndex, + } + : { + gudeCueTriggerRef: null, + firstParsleyFileIndex: -1, + } + ), + [taskAnalytics, firstParsleyFileIndex] ); + useEffect(() => { + // Scroll to the first file that can be opened in parsley on initial render. + // Since the button may not always be in view, we need to scroll to it. + if (firstParsleyFileIndex !== -1 && openGuideCue) { + parsleyLinkRef.current?.scrollIntoView(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const table = useLeafyGreenTable({ containerRef: tableContainerRef, data: files, @@ -93,6 +133,26 @@ const GroupedFileTable: React.FC = ({ return ( {taskName && {taskName}} + {parsleyLinkRef.current !== null && ( + { + Cookies.set(SEEN_PARSLEY_FILES_GUIDE_CUE, "true", { + expires: 365, + }); + setOpenGuideCue(false); + }} + > + Open your file in Parsley to view it with Parsley's rich text + formatting capabilities. + + )} ); diff --git a/yarn.lock b/yarn.lock index e8dec19340..ecb0a8cc3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3242,7 +3242,7 @@ "@leafygreen-ui/tokens" "^2.0.0" polished "^4.2.2" -"@leafygreen-ui/button@^21.0.10", "@leafygreen-ui/button@^21.0.3", "@leafygreen-ui/button@^21.0.5", "@leafygreen-ui/button@^21.0.9": +"@leafygreen-ui/button@^21.0.10", "@leafygreen-ui/button@^21.0.3", "@leafygreen-ui/button@^21.0.5": version "21.0.11" resolved "https://registry.yarnpkg.com/@leafygreen-ui/button/-/button-21.0.11.tgz#a1cfa56226d9ccdf43945441340013ff02c55fbe" integrity sha512-NJhllsXO7jAJoAou9kPIk/B8ODYUrGxr4l4TceoAwAM3cW0kZ5kys9KA+0TOmG2AxNKLcElLu+wCg3TbssFk+Q== @@ -3426,22 +3426,22 @@ "@leafygreen-ui/typography" "^16.0.0" react-transition-group "^4.4.1" -"@leafygreen-ui/guide-cue@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/guide-cue/-/guide-cue-5.0.4.tgz#272b47f62f0957b153284a359aa423d62a8bcfe6" - integrity sha512-L+k1EZNfvpixoMSkzds6Qr4rNkFL6f+yiKRq+2XF/lPDRHnohf06VULp0qmHs1UcUNICmMj8SP6qOYy3LyagKw== +"@leafygreen-ui/guide-cue@5.0.5": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@leafygreen-ui/guide-cue/-/guide-cue-5.0.5.tgz#bff9651b81d8c47d380280a9a5a01cf00bb9cf2e" + integrity sha512-E8SqC/UTypkTuxP0HHSh+AG9FpPHwgDvBb+qBYZ8xHNLODVDI81nuRSoEDZx4AUajziRQNOrIbGYnq2hjW02xw== dependencies: "@leafygreen-ui/a11y" "^1.4.11" - "@leafygreen-ui/button" "^21.0.9" + "@leafygreen-ui/button" "^21.0.10" "@leafygreen-ui/emotion" "^4.0.7" - "@leafygreen-ui/hooks" "^8.0.0" - "@leafygreen-ui/icon" "^11.23.0" + "@leafygreen-ui/hooks" "^8.0.1" + "@leafygreen-ui/icon" "^11.25.0" "@leafygreen-ui/icon-button" "^15.0.19" "@leafygreen-ui/lib" "^13.0.0" "@leafygreen-ui/palette" "^4.0.7" "@leafygreen-ui/popover" "^11.1.1" - "@leafygreen-ui/tooltip" "^10.1.0" - "@leafygreen-ui/typography" "^18.0.0" + "@leafygreen-ui/tooltip" "^11.0.0" + "@leafygreen-ui/typography" "^18.0.1" focus-trap "6.9.4" focus-trap-react "9.0.2" polished "^4.2.2" From 6d24d2f11e0c99b01d42797fdada8d0264ede65c Mon Sep 17 00:00:00 2001 From: Zackary Santana <64446617+ZackarySantana@users.noreply.github.com> Date: Thu, 21 Dec 2023 13:46:39 -0500 Subject: [PATCH 05/22] DEVPROD-977 Add stepback bisect to project settings page (#2177) --- .../projectSettings/stepback_bisect.ts | 61 +++++++++++++++++++ .../fragments/projectSettings/general.graphql | 2 + src/gql/generated/types.ts | 11 ++++ .../projectSettings/CopyProjectModal.test.tsx | 1 + .../tabs/EventLogTab/EventLogTab.test.tsx | 2 + .../tabs/GeneralTab/getFormSchema.tsx | 14 +++++ .../tabs/GeneralTab/transformers.test.ts | 4 ++ .../tabs/GeneralTab/transformers.ts | 2 + .../projectSettings/tabs/GeneralTab/types.ts | 1 + src/pages/projectSettings/tabs/testData.ts | 2 + 10 files changed, 100 insertions(+) create mode 100644 cypress/integration/projectSettings/stepback_bisect.ts diff --git a/cypress/integration/projectSettings/stepback_bisect.ts b/cypress/integration/projectSettings/stepback_bisect.ts new file mode 100644 index 0000000000..d75b0dc18e --- /dev/null +++ b/cypress/integration/projectSettings/stepback_bisect.ts @@ -0,0 +1,61 @@ +import { clickSave } from "../../utils"; +import { getGeneralRoute, project, projectUseRepoEnabled } from "./constants"; + +describe("Stepback bisect setting", () => { + describe("Repo project present", () => { + const destination = getGeneralRoute(projectUseRepoEnabled); + + beforeEach(() => { + cy.visit(destination); + }); + + it("Starts as default to repo", () => { + cy.dataCy("stepback-bisect-group") + .contains("Default to repo") + .find("input") + .should("have.attr", "aria-checked", "true"); + }); + + it("Clicking on enabled and then save shows a success toast", () => { + cy.dataCy("stepback-bisect-group").contains("Enable").click(); + clickSave(); + cy.validateToast("success", "Successfully updated project"); + + cy.reload(); + + cy.dataCy("stepback-bisect-group") + .contains("Enable") + .find("input") + .should("have.attr", "aria-checked", "true"); + }); + }); + + describe("Repo project not present", () => { + const destination = getGeneralRoute(project); + + beforeEach(() => { + cy.visit(destination); + }); + + it("Starts as disabled", () => { + cy.dataCy("stepback-bisect-group") + .contains("Disable") + .find("input") + .should("have.attr", "aria-checked", "true"); + }); + + it("Clicking on enabled and then save shows a success toast", () => { + cy.dataCy("stepback-bisect-group").contains("Enable").click(); + + clickSave(); + cy.validateToast("success", "Successfully updated project"); + + cy.reload(); + + cy.dataCy("stepback-bisect-group") + .contains("Enable") + .find("input") + .should("have.attr", "aria-checked", "true"); + }); + }); +}); diff --git a/src/gql/fragments/projectSettings/general.graphql b/src/gql/fragments/projectSettings/general.graphql index 632f9a6df0..17051d8573 100644 --- a/src/gql/fragments/projectSettings/general.graphql +++ b/src/gql/fragments/projectSettings/general.graphql @@ -12,6 +12,7 @@ fragment ProjectGeneralSettings on Project { repo repotrackerDisabled spawnHostScriptPath + stepbackBisect stepbackDisabled taskSync { configEnabled @@ -32,6 +33,7 @@ fragment RepoGeneralSettings on RepoRef { repo repotrackerDisabled spawnHostScriptPath + stepbackBisect stepbackDisabled taskSync { configEnabled diff --git a/src/gql/generated/types.ts b/src/gql/generated/types.ts index 83873f335a..3af7bd17b3 100644 --- a/src/gql/generated/types.ts +++ b/src/gql/generated/types.ts @@ -3459,6 +3459,7 @@ export type ProjectGeneralSettingsFragment = { repo: string; repotrackerDisabled?: boolean | null; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled?: boolean | null; versionControlEnabled?: boolean | null; taskSync: { @@ -3481,6 +3482,7 @@ export type RepoGeneralSettingsFragment = { repo: string; repotrackerDisabled: boolean; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled: boolean; versionControlEnabled: boolean; taskSync: { @@ -3628,6 +3630,7 @@ export type ProjectSettingsFieldsFragment = { repo: string; repotrackerDisabled?: boolean | null; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled?: boolean | null; versionControlEnabled?: boolean | null; notifyOnBuildFailure?: boolean | null; @@ -3834,6 +3837,7 @@ export type RepoSettingsFieldsFragment = { repo: string; repotrackerDisabled: boolean; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled: boolean; versionControlEnabled: boolean; notifyOnBuildFailure: boolean; @@ -4235,6 +4239,7 @@ export type ProjectEventSettingsFragment = { repo: string; repotrackerDisabled?: boolean | null; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled?: boolean | null; notifyOnBuildFailure?: boolean | null; githubTriggerAliases?: Array | null; @@ -6698,6 +6703,7 @@ export type ProjectEventLogsQuery = { repo: string; repotrackerDisabled?: boolean | null; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled?: boolean | null; notifyOnBuildFailure?: boolean | null; githubTriggerAliases?: Array | null; @@ -6910,6 +6916,7 @@ export type ProjectEventLogsQuery = { repo: string; repotrackerDisabled?: boolean | null; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled?: boolean | null; notifyOnBuildFailure?: boolean | null; githubTriggerAliases?: Array | null; @@ -7197,6 +7204,7 @@ export type ProjectSettingsQuery = { repo: string; repotrackerDisabled?: boolean | null; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled?: boolean | null; versionControlEnabled?: boolean | null; notifyOnBuildFailure?: boolean | null; @@ -7455,6 +7463,7 @@ export type RepoEventLogsQuery = { repo: string; repotrackerDisabled?: boolean | null; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled?: boolean | null; notifyOnBuildFailure?: boolean | null; githubTriggerAliases?: Array | null; @@ -7667,6 +7676,7 @@ export type RepoEventLogsQuery = { repo: string; repotrackerDisabled?: boolean | null; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled?: boolean | null; notifyOnBuildFailure?: boolean | null; githubTriggerAliases?: Array | null; @@ -7883,6 +7893,7 @@ export type RepoSettingsQuery = { repo: string; repotrackerDisabled: boolean; spawnHostScriptPath: string; + stepbackBisect?: boolean | null; stepbackDisabled: boolean; versionControlEnabled: boolean; notifyOnBuildFailure: boolean; diff --git a/src/pages/projectSettings/CopyProjectModal.test.tsx b/src/pages/projectSettings/CopyProjectModal.test.tsx index cd959f13ed..65aadbc0fd 100644 --- a/src/pages/projectSettings/CopyProjectModal.test.tsx +++ b/src/pages/projectSettings/CopyProjectModal.test.tsx @@ -290,6 +290,7 @@ const projectSettingsMock: ApolloMock< deactivatePrevious: true, repotrackerDisabled: false, stepbackDisabled: null, + stepbackBisect: null, patchingDisabled: false, taskSync: { configEnabled: false, diff --git a/src/pages/projectSettings/tabs/EventLogTab/EventLogTab.test.tsx b/src/pages/projectSettings/tabs/EventLogTab/EventLogTab.test.tsx index b461a90b11..c5ff25f416 100644 --- a/src/pages/projectSettings/tabs/EventLogTab/EventLogTab.test.tsx +++ b/src/pages/projectSettings/tabs/EventLogTab/EventLogTab.test.tsx @@ -100,6 +100,7 @@ const projectEventsQuery: ProjectEventLogsQuery = { deactivatePrevious: true, repotrackerDisabled: false, stepbackDisabled: null, + stepbackBisect: null, patchingDisabled: false, taskSync: { configEnabled: false, @@ -186,6 +187,7 @@ const projectEventsQuery: ProjectEventLogsQuery = { deactivatePrevious: true, repotrackerDisabled: false, stepbackDisabled: null, + stepbackBisect: null, patchingDisabled: false, taskSync: { configEnabled: false, diff --git a/src/pages/projectSettings/tabs/GeneralTab/getFormSchema.tsx b/src/pages/projectSettings/tabs/GeneralTab/getFormSchema.tsx index 3e5d7d5c92..40cb116420 100644 --- a/src/pages/projectSettings/tabs/GeneralTab/getFormSchema.tsx +++ b/src/pages/projectSettings/tabs/GeneralTab/getFormSchema.tsx @@ -165,6 +165,14 @@ export const getFormSchema = ( true ), }, + stepbackBisection: { + type: ["boolean", "null"], + title: "Stepback Bisection", + oneOf: radioBoxOptions( + ["Enabled", "Disabled"], + repoData?.projectFlags?.scheduling?.stepbackBisection + ), + }, deactivateStepback: { type: "null" as "null", }, @@ -342,6 +350,12 @@ export const getFormSchema = ( "ui:description": "Disabling this setting will override all enabled stepback settings for the project. Disabling stepback won't cancel any active stepback tasks, but it will prevent any future ones.", }, + stepbackBisection: { + "ui:widget": widgets.RadioBoxWidget, + "ui:description": + "Bisection will cause your stepback to activate the midway task between the last failing task and last passing task.", + "ui:data-cy": "stepback-bisect-group", + }, deactivateStepback: { "ui:field": "deactivateStepbackTask", "ui:showLabel": false, diff --git a/src/pages/projectSettings/tabs/GeneralTab/transformers.test.ts b/src/pages/projectSettings/tabs/GeneralTab/transformers.test.ts index 9372a65bfa..8c2f41bd0f 100644 --- a/src/pages/projectSettings/tabs/GeneralTab/transformers.test.ts +++ b/src/pages/projectSettings/tabs/GeneralTab/transformers.test.ts @@ -47,6 +47,7 @@ const repoForm: GeneralFormState = { scheduling: { deactivatePrevious: true, stepbackDisabled: true, + stepbackBisection: true, deactivateStepback: null, }, repotracker: { @@ -81,6 +82,7 @@ const repoResult: Pick = { repotrackerDisabled: false, patchingDisabled: false, stepbackDisabled: true, + stepbackBisect: true, taskSync: { configEnabled: true, patchEnabled: true, @@ -111,6 +113,7 @@ const projectForm: GeneralFormState = { scheduling: { deactivatePrevious: null, stepbackDisabled: null, + stepbackBisection: null, deactivateStepback: null, }, repotracker: { @@ -148,6 +151,7 @@ const projectResult: Pick = { repotrackerDisabled: null, patchingDisabled: null, stepbackDisabled: null, + stepbackBisect: null, taskSync: { configEnabled: null, patchEnabled: null, diff --git a/src/pages/projectSettings/tabs/GeneralTab/transformers.ts b/src/pages/projectSettings/tabs/GeneralTab/transformers.ts index 9f0307256a..f859e0fc98 100644 --- a/src/pages/projectSettings/tabs/GeneralTab/transformers.ts +++ b/src/pages/projectSettings/tabs/GeneralTab/transformers.ts @@ -41,6 +41,7 @@ export const gqlToForm = ((data, options = {}) => { scheduling: { deactivatePrevious: projectRef.deactivatePrevious, stepbackDisabled: projectRef.stepbackDisabled, + stepbackBisection: projectRef.stepbackBisect, deactivateStepback: null, }, repotracker: { @@ -91,6 +92,7 @@ export const formToGql = (( deactivatePrevious: projectFlags.scheduling.deactivatePrevious, repotrackerDisabled: projectFlags.repotracker.repotrackerDisabled, stepbackDisabled: projectFlags.scheduling.stepbackDisabled, + stepbackBisect: projectFlags.scheduling.stepbackBisection, patchingDisabled: projectFlags.patch.patchingDisabled, taskSync: { configEnabled: projectFlags.taskSync.configEnabled, diff --git a/src/pages/projectSettings/tabs/GeneralTab/types.ts b/src/pages/projectSettings/tabs/GeneralTab/types.ts index 296c36da6b..04a4d92143 100644 --- a/src/pages/projectSettings/tabs/GeneralTab/types.ts +++ b/src/pages/projectSettings/tabs/GeneralTab/types.ts @@ -22,6 +22,7 @@ export interface GeneralFormState { scheduling: { deactivatePrevious: boolean | null; stepbackDisabled: boolean | null; + stepbackBisection: boolean | null; deactivateStepback: null; }; repotracker: { diff --git a/src/pages/projectSettings/tabs/testData.ts b/src/pages/projectSettings/tabs/testData.ts index 217141a0d6..9621b17e2b 100644 --- a/src/pages/projectSettings/tabs/testData.ts +++ b/src/pages/projectSettings/tabs/testData.ts @@ -46,6 +46,7 @@ const projectBase: ProjectSettingsQuery["projectSettings"] = { repotrackerDisabled: null, patchingDisabled: null, stepbackDisabled: null, + stepbackBisect: null, taskSync: { configEnabled: null, patchEnabled: null, @@ -174,6 +175,7 @@ const repoBase: RepoSettingsQuery["repoSettings"] = { notifyOnBuildFailure: false, patchingDisabled: false, stepbackDisabled: true, + stepbackBisect: true, taskSync: { configEnabled: true, patchEnabled: true, From 2b33d3044006d54ddfb97616ecc6fbd0164cb956 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Dec 2023 11:57:51 -0500 Subject: [PATCH 06/22] CHORE(NPM) - bump @types/prompts from 2.4.6 to 2.4.9 (#2200) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cda3a8b6e9..8bcca3e1bf 100644 --- a/package.json +++ b/package.json @@ -158,7 +158,7 @@ "@types/new-relic-browser": "0.1212.2", "@types/node": "^16.11.47", "@types/pluralize": "0.0.29", - "@types/prompts": "2.4.6", + "@types/prompts": "2.4.9", "@types/react": "18.2.0", "@types/react-dom": "18.2.0", "@typescript-eslint/eslint-plugin": "5.57.1", diff --git a/yarn.lock b/yarn.lock index ecb0a8cc3b..13adcd12c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6123,10 +6123,10 @@ resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601" integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ== -"@types/prompts@2.4.6": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@types/prompts/-/prompts-2.4.6.tgz#5c14794e7c8850b1d633a17a052b724bd2b019a3" - integrity sha512-hIwnDhvsTV6XwAPo1zNy2MTelR0JmCxklIRsVxwROHLGaf6LfB+sGDkB9n+aqV4gXDz8z5MnlAz4CEC9wQDRsw== +"@types/prompts@2.4.9": + version "2.4.9" + resolved "https://registry.yarnpkg.com/@types/prompts/-/prompts-2.4.9.tgz#8775a31e40ad227af511aa0d7f19a044ccbd371e" + integrity sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA== dependencies: "@types/node" "*" kleur "^3.0.3" From 054203da08284f39ffefdcc6ef64b7124f1fbd5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Dec 2023 11:59:34 -0500 Subject: [PATCH 07/22] CHORE(NPM) - bump @leafygreen-ui/icon from 11.12.1 to 11.26.0 (#2202) --- package.json | 2 +- yarn.lock | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 8bcca3e1bf..01b440c1b5 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@leafygreen-ui/emotion": "4.0.7", "@leafygreen-ui/expandable-card": "3.0.5", "@leafygreen-ui/guide-cue": "5.0.5", - "@leafygreen-ui/icon": "11.12.1", + "@leafygreen-ui/icon": "11.26.0", "@leafygreen-ui/icon-button": "15.0.5", "@leafygreen-ui/inline-definition": "6.0.14", "@leafygreen-ui/interaction-ring": "7.0.2", diff --git a/yarn.lock b/yarn.lock index 13adcd12c1..61a59c198c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3512,17 +3512,10 @@ "@leafygreen-ui/palette" "^4.0.7" "@leafygreen-ui/tokens" "^2.1.4" -"@leafygreen-ui/icon@11.12.1": - version "11.12.1" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon/-/icon-11.12.1.tgz#8ec2a8cd209c07e5e9a3b5a8f42b74afa4364573" - integrity sha512-TOnECGHs3honiuy7JdbGXLYi7mgOzX7mJtO8Ius63pG4D0gTZZrJPE4JhXPmdOgYtZ22/pGxSCHcOHvIBYYjvw== - dependencies: - "@leafygreen-ui/emotion" "^4.0.3" - -"@leafygreen-ui/icon@^11.12.1", "@leafygreen-ui/icon@^11.12.3", "@leafygreen-ui/icon@^11.12.4", "@leafygreen-ui/icon@^11.12.5", "@leafygreen-ui/icon@^11.15.0", "@leafygreen-ui/icon@^11.17.0", "@leafygreen-ui/icon@^11.22.1", "@leafygreen-ui/icon@^11.22.2", "@leafygreen-ui/icon@^11.23.0", "@leafygreen-ui/icon@^11.25.0": - version "11.25.0" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon/-/icon-11.25.0.tgz#a6cc0d54e7988cb39d3a2b1e947715b6af8f1ca2" - integrity sha512-54nEMSj/g8cfKsh2iQ9qVr7oYSSbdpZbzrgQ/tExDuaG90UR0FJeWHzPiNbUI7hrRuLYuokn7WafsxqX6Sfr2A== +"@leafygreen-ui/icon@11.26.0", "@leafygreen-ui/icon@^11.12.1", "@leafygreen-ui/icon@^11.12.3", "@leafygreen-ui/icon@^11.12.4", "@leafygreen-ui/icon@^11.12.5", "@leafygreen-ui/icon@^11.15.0", "@leafygreen-ui/icon@^11.17.0", "@leafygreen-ui/icon@^11.22.1", "@leafygreen-ui/icon@^11.22.2", "@leafygreen-ui/icon@^11.23.0", "@leafygreen-ui/icon@^11.25.0": + version "11.26.0" + resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon/-/icon-11.26.0.tgz#2093df50445bd15758925aae9c0f40813eb817a8" + integrity sha512-2+sexm+uLqPC3XxQ8xDky3UhcxwGIuiWnkcG2JImNNMJSnrk87BEG0z7DdCXIpJ46+RtGDYa4B3ADxKSl9M9oQ== dependencies: "@leafygreen-ui/emotion" "^4.0.7" lodash "^4.17.21" From 723543ddf347615728af012c90ade1122d67c2b3 Mon Sep 17 00:00:00 2001 From: Zackary Santana <64446617+ZackarySantana@users.noreply.github.com> Date: Thu, 28 Dec 2023 12:28:13 -0500 Subject: [PATCH 08/22] DEVPROD-1122 Add stepback information to task metadata (#2206) --- src/analytics/task/useTaskAnalytics.ts | 4 ++ src/gql/generated/types.ts | 16 +++++++ src/gql/queries/task.graphql | 6 +++ src/pages/task/metadata/index.tsx | 61 ++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) diff --git a/src/analytics/task/useTaskAnalytics.ts b/src/analytics/task/useTaskAnalytics.ts index dbb7057dd2..1d78d77f9b 100644 --- a/src/analytics/task/useTaskAnalytics.ts +++ b/src/analytics/task/useTaskAnalytics.ts @@ -70,6 +70,10 @@ type Action = } | { name: "Click Trace Link" } | { name: "Click Trace Metrics Link" } + | { name: "Click Last Passing Stepback Task Link" } + | { name: "Click Last Failing Stepback Task Link" } + | { name: "Click Previous Stepback Task Link" } + | { name: "Click Next Stepback Task Link" } | { name: "Submit Previous Commit Selector"; type: CommitType }; export const useTaskAnalytics = () => { diff --git a/src/gql/generated/types.ts b/src/gql/generated/types.ts index 3af7bd17b3..ae8b0f91b9 100644 --- a/src/gql/generated/types.ts +++ b/src/gql/generated/types.ts @@ -2418,6 +2418,14 @@ export type StatusCount = { status: Scalars["String"]["output"]; }; +export type StepbackInfo = { + __typename?: "StepbackInfo"; + lastFailingStepbackTaskId?: Maybe; + lastPassingStepbackTaskId?: Maybe; + nextStepbackTaskId?: Maybe; + previousStepbackTaskId?: Maybe; +}; + export type Subscriber = { __typename?: "Subscriber"; emailSubscriber?: Maybe; @@ -2526,6 +2534,7 @@ export type Task = { spawnHostLink?: Maybe; startTime?: Maybe; status: Scalars["String"]["output"]; + stepbackInfo?: Maybe; /** @deprecated Use files instead */ taskFiles: TaskFiles; taskGroup?: Maybe; @@ -8562,6 +8571,13 @@ export type TaskQuery = { }; pod?: { __typename?: "Pod"; id: string } | null; project?: { __typename?: "Project"; id: string; identifier: string } | null; + stepbackInfo?: { + __typename?: "StepbackInfo"; + lastFailingStepbackTaskId?: string | null; + lastPassingStepbackTaskId?: string | null; + nextStepbackTaskId?: string | null; + previousStepbackTaskId?: string | null; + } | null; versionMetadata: { __typename?: "Version"; author: string; diff --git a/src/gql/queries/task.graphql b/src/gql/queries/task.graphql index 742884fa45..b2338dc62d 100644 --- a/src/gql/queries/task.graphql +++ b/src/gql/queries/task.graphql @@ -107,6 +107,12 @@ query Task($taskId: String!, $execution: Int) { resetWhenFinished spawnHostLink startTime + stepbackInfo { + lastFailingStepbackTaskId + lastPassingStepbackTaskId + nextStepbackTaskId + previousStepbackTaskId + } timeTaken totalTestCount versionMetadata { diff --git a/src/pages/task/metadata/index.tsx b/src/pages/task/metadata/index.tsx index 0843f9dcb0..11e151533a 100644 --- a/src/pages/task/metadata/index.tsx +++ b/src/pages/task/metadata/index.tsx @@ -79,6 +79,7 @@ export const Metadata: React.FC = ({ error, loading, task, taskId }) => { spawnHostLink, startTime, status, + stepbackInfo, timeTaken, versionMetadata, } = task || {}; @@ -403,6 +404,66 @@ export const Metadata: React.FC = ({ error, loading, task, taskId }) => { )} + {stepbackInfo?.lastPassingStepbackTaskId && ( + <> + + Last Passing Stepback Task:{" "} + + taskAnalytics.sendEvent({ + name: "Click Last Passing Stepback Task Link", + }) + } + > + {stepbackInfo.lastPassingStepbackTaskId} + + + + Last Failing Stepback Task:{" "} + + taskAnalytics.sendEvent({ + name: "Click Last Failing Stepback Task Link", + }) + } + > + {stepbackInfo.lastFailingStepbackTaskId} + + + + )} + {stepbackInfo?.previousStepbackTaskId && ( + + Previous Stepback Task:{" "} + + taskAnalytics.sendEvent({ + name: "Click Previous Stepback Task Link", + }) + } + > + {stepbackInfo.previousStepbackTaskId} + + + )} + {stepbackInfo?.nextStepbackTaskId && ( + + Next Stepback Task:{" "} + + taskAnalytics.sendEvent({ + name: "Click Next Stepback Task Link", + }) + } + > + {stepbackInfo.nextStepbackTaskId} + + + )} ); }; From 3a7170f70fe8ffae6b657f582b80877a2246a881 Mon Sep 17 00:00:00 2001 From: Mohamed Khelif Date: Tue, 2 Jan 2024 14:39:15 -0500 Subject: [PATCH 09/22] v3.0.186 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 01b440c1b5..e082dc3722 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "spruce", - "version": "3.0.185", + "version": "3.0.186", "private": true, "scripts": { "bootstrap-logkeeper": "./scripts/bootstrap-logkeeper.sh", From de16b230af73361a3251be78019fd261d05aa6b1 Mon Sep 17 00:00:00 2001 From: Arjun Patel Date: Wed, 3 Jan 2024 11:50:14 -0500 Subject: [PATCH 10/22] update quotations --- .evergreen.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.evergreen.yml b/.evergreen.yml index 36ae9a03b8..b548e2421f 100644 --- a/.evergreen.yml +++ b/.evergreen.yml @@ -243,7 +243,7 @@ functions: if [[ "${requester}" == "github_pr" || "${requester}" == "commit" ]]; then yarn cy:run --record --key "${cypress_record_key}" --reporter junit elif [[ "${requester}" == "patch" ]]; then - yarn cy:run --record --key "${cypress_record_key}" --reporter junit --spec ${cypress_spec} + yarn cy:run --record --key "${cypress_record_key}" --reporter junit --spec "${cypress_spec}" else yarn cy:run --reporter junit fi @@ -524,5 +524,5 @@ buildvariants: parameters: - key: cypress_spec - value: "cypress/integration/**/*" + value: cypress/integration/**/* description: Specify the Cypress spec files to run for user submitted patches running the e2e_test task. From 7e24fdd6b22269ea0785c44f458e438e5e2dd739 Mon Sep 17 00:00:00 2001 From: Arjun Patel Date: Wed, 3 Jan 2024 11:50:58 -0500 Subject: [PATCH 11/22] Revert "update quotations" This reverts commit de16b230af73361a3251be78019fd261d05aa6b1. --- .evergreen.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.evergreen.yml b/.evergreen.yml index b548e2421f..36ae9a03b8 100644 --- a/.evergreen.yml +++ b/.evergreen.yml @@ -243,7 +243,7 @@ functions: if [[ "${requester}" == "github_pr" || "${requester}" == "commit" ]]; then yarn cy:run --record --key "${cypress_record_key}" --reporter junit elif [[ "${requester}" == "patch" ]]; then - yarn cy:run --record --key "${cypress_record_key}" --reporter junit --spec "${cypress_spec}" + yarn cy:run --record --key "${cypress_record_key}" --reporter junit --spec ${cypress_spec} else yarn cy:run --reporter junit fi @@ -524,5 +524,5 @@ buildvariants: parameters: - key: cypress_spec - value: cypress/integration/**/* + value: "cypress/integration/**/*" description: Specify the Cypress spec files to run for user submitted patches running the e2e_test task. From 68c9bb58b718ac167597f0fe572599984a122538 Mon Sep 17 00:00:00 2001 From: minnakt <47064971+minnakt@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:14:43 -0500 Subject: [PATCH 12/22] DEVPROD-2227: Remove family triggers from trigger definitions (#2203) --- .../projectSettings/notifications.ts | 6 +- cypress/integration/subscription_modal.ts | 8 +-- src/components/Notifications/utils.test.ts | 2 +- src/constants/triggers.ts | 70 ++++++++++--------- .../notificationTab/useSubscriptionData.tsx | 4 +- .../NotificationsTab/getGqlPayload.test.ts | 4 +- .../NotificationsTab/transformers.test.ts | 6 +- .../tabs/NotificationsTab/transformers.ts | 7 +- src/types/triggers.ts | 8 ++- 9 files changed, 60 insertions(+), 55 deletions(-) diff --git a/cypress/integration/projectSettings/notifications.ts b/cypress/integration/projectSettings/notifications.ts index 4a37adef07..cd02e23dbc 100644 --- a/cypress/integration/projectSettings/notifications.ts +++ b/cypress/integration/projectSettings/notifications.ts @@ -16,7 +16,7 @@ describe("Notifications", () => { cy.dataCy("add-button").contains("Add Subscription").should("be.visible"); cy.dataCy("add-button").click(); cy.dataCy("expandable-card").should("contain.text", "New Subscription"); - cy.selectLGOption("Event", "Any Version Finishes"); + cy.selectLGOption("Event", "Any version finishes"); cy.selectLGOption("Notification Method", "Email"); cy.getInputByLabel("Email").type("mohamed.khelif@mongodb.com"); cy.dataCy("save-settings-button").scrollIntoView(); @@ -43,7 +43,7 @@ describe("Notifications", () => { cy.dataCy("expandable-card") .should("be.visible") .should("contain.text", "New Subscription"); - cy.selectLGOption("Event", "Any Task Finishes"); + cy.selectLGOption("Event", "Any task finishes"); cy.selectLGOption("Notification Method", "Comment on a JIRA issue"); cy.getInputByLabel("JIRA Issue").type("JIRA-123"); cy.contains("Subscription type not allowed for tasks in a project.").should( @@ -58,7 +58,7 @@ describe("Notifications", () => { cy.dataCy("expandable-card") .should("be.visible") .should("contain.text", "New Subscription"); - cy.selectLGOption("Event", "Any Version Finishes"); + cy.selectLGOption("Event", "Any version finishes"); cy.selectLGOption("Notification Method", "Email"); cy.getInputByLabel("Email").type("Not a real email"); cy.contains("Value should be a valid email.").should("be.visible"); diff --git a/cypress/integration/subscription_modal.ts b/cypress/integration/subscription_modal.ts index e8dedf3f3f..901a6564a9 100644 --- a/cypress/integration/subscription_modal.ts +++ b/cypress/integration/subscription_modal.ts @@ -146,7 +146,7 @@ describe("Waterfall subscription modal", () => { cy.dataCy("add-notification").click(); cy.dataCy(dataCyModal).should("be.visible"); - cy.selectLGOption("Event", "Any Version Finishes"); + cy.selectLGOption("Event", "Any version finishes"); cy.selectLGOption("Notification Method", "JIRA issue"); cy.dataCy("jira-comment-input").type("EVG-2000"); @@ -160,7 +160,7 @@ describe("Waterfall subscription modal", () => { cy.dataCy("add-notification").click(); cy.dataCy(dataCyModal).should("be.visible"); - cy.selectLGOption("Event", "Any Build Finishes"); + cy.selectLGOption("Event", "Any build finishes"); cy.dataCy("add-button").click(); saveButtonEnabled(false); @@ -179,7 +179,7 @@ describe("Waterfall subscription modal", () => { cy.dataCy("add-notification").click(); cy.dataCy(dataCyModal).should("be.visible"); - cy.selectLGOption("Event", "Any Version Finishes"); + cy.selectLGOption("Event", "Any version finishes"); cy.dataCy("jira-comment-input").type("EVG-2000"); mockErrorResponse({ path: "SaveSubscription", @@ -207,7 +207,7 @@ describe("Waterfall subscription modal", () => { cy.dataCy("waterfall-menu").click(); cy.dataCy("add-notification").click(); cy.dataCy(dataCyModal).should("be.visible"); - cy.contains("Any Build Fails").should("be.visible"); + cy.contains("Any build fails").should("be.visible"); cy.contains("Slack").should("be.visible"); cy.clearCookie(subscriptionCookie); diff --git a/src/components/Notifications/utils.test.ts b/src/components/Notifications/utils.test.ts index f2e79664c9..e76a3c9e66 100644 --- a/src/components/Notifications/utils.test.ts +++ b/src/components/Notifications/utils.test.ts @@ -106,7 +106,7 @@ describe("getGqlPayload", () => { type: "email", target: "fake.user@mongodb.com", }, - trigger: "family-outcome", + trigger: "outcome", trigger_data: {}, }); }); diff --git a/src/constants/triggers.ts b/src/constants/triggers.ts index 67f81fab53..13bdc45cec 100644 --- a/src/constants/triggers.ts +++ b/src/constants/triggers.ts @@ -135,19 +135,19 @@ export const taskTriggers: Trigger = { // VERSION TRIGGERS export const versionTriggers: Trigger = { [VersionTriggers.VERSION_FINISHES]: { - trigger: TriggerType.FAMILY_OUTCOME, + trigger: TriggerType.OUTCOME, label: "This version finishes", resourceType: ResourceType.Version, payloadResourceIdKey: "id", }, [VersionTriggers.VERSION_FAILS]: { - trigger: TriggerType.FAMILY_FAILURE, + trigger: TriggerType.FAILURE, label: "This version fails", resourceType: ResourceType.Version, payloadResourceIdKey: "id", }, [VersionTriggers.VERSION_SUCCEEDS]: { - trigger: TriggerType.FAMILY_SUCCESS, + trigger: TriggerType.SUCCESS, label: "This version succeeds", resourceType: ResourceType.Version, payloadResourceIdKey: "id", @@ -207,70 +207,70 @@ export const versionTriggers: Trigger = { export const projectTriggers: Trigger = { [ProjectTriggers.ANY_VERSION_FINISHES]: { - trigger: TriggerType.FAMILY_OUTCOME, + trigger: TriggerType.OUTCOME, resourceType: ResourceType.Version, - label: "Any Version Finishes", + label: "Any version finishes", extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_VERSION_FAILS]: { - trigger: TriggerType.FAMILY_FAILURE, + trigger: TriggerType.FAILURE, resourceType: ResourceType.Version, - label: "Any Version Fails", + label: "Any version fails", extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_BUILD_FINISHES]: { trigger: TriggerType.OUTCOME, resourceType: ResourceType.Build, - label: "Any Build Finishes", + label: "Any build finishes", regexSelectors: buildRegexSelectors, extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_BUILD_FAILS]: { trigger: TriggerType.FAILURE, resourceType: ResourceType.Build, - label: "Any Build Fails", + label: "Any build fails", regexSelectors: buildRegexSelectors, extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_TASK_FINISHES]: { trigger: TriggerType.OUTCOME, resourceType: ResourceType.Task, - label: "Any Task Finishes", + label: "Any task finishes", regexSelectors: taskRegexSelectors, extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_TASK_FAILS]: { trigger: TriggerType.FAILURE, resourceType: ResourceType.Task, - label: "Any Task Fails", + label: "Any task fails", regexSelectors: taskRegexSelectors, extraFields: [failureTypeSubscriberConfig, requesterSubscriberConfig], }, [ProjectTriggers.FIRST_FAILURE_VERSION]: { trigger: TriggerType.FIRST_FAILURE_VERSION, resourceType: ResourceType.Task, - label: "The First Failure In a Version Occurs", + label: "The first failure in a version occurs", regexSelectors: taskRegexSelectors, extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.FIRST_FAILURE_BUILD]: { trigger: TriggerType.FIRST_FAILURE_BUILD, resourceType: ResourceType.Task, - label: "The First Failure In Each Build Occurs", + label: "The first failure in each build occurs", regexSelectors: taskRegexSelectors, extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.FIRST_FAILURE_TASK]: { trigger: TriggerType.FIRST_FAILURE_VERSION_NAME, resourceType: ResourceType.Task, - label: "The First Failure In Each Version For Each Task Name Occurs", + label: "The first failure in each version for each task name occurs", regexSelectors: taskRegexSelectors, extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.PREVIOUS_PASSING_TASK_FAILS]: { trigger: TriggerType.REGRESSION, resourceType: ResourceType.Task, - label: "A Previously Passing Task Fails", + label: "A previously passing task fails", regexSelectors: taskRegexSelectors, extraFields: [ { @@ -286,7 +286,7 @@ export const projectTriggers: Trigger = { [ProjectTriggers.PREVIOUS_PASSING_TEST_FAILS]: { trigger: TriggerType.TEST_REGRESSION, resourceType: ResourceType.Task, - label: "A Previously Passing Test In a Task Fails", + label: "A previously passing test in a task fails", regexSelectors: taskRegexSelectors, extraFields: [ { @@ -309,7 +309,7 @@ export const projectTriggers: Trigger = { [ProjectTriggers.SUCCESSFUL_TASK_EXCEEDS_DURATION]: { trigger: TriggerType.SUCCESSFUL_EXCEEDS_DURATION, resourceType: ResourceType.Task, - label: "The Runtime For a Successful Task Exceeds Some Duration", + label: "The runtime for a successful task exceeds some duration", regexSelectors: taskRegexSelectors, extraFields: [ { @@ -324,7 +324,7 @@ export const projectTriggers: Trigger = { [ProjectTriggers.TASK_EXCEEDS_DURATION]: { trigger: TriggerType.EXCEEDS_DURATION, resourceType: ResourceType.Task, - label: "The Runtime For Any Task Exceeds Some Duration", + label: "The runtime for any task exceeds some duration", regexSelectors: taskRegexSelectors, extraFields: [ { @@ -339,7 +339,7 @@ export const projectTriggers: Trigger = { [ProjectTriggers.SUCCESSFUL_TASK_RUNTIME_CHANGES]: { trigger: TriggerType.RUNTIME_CHANGE, resourceType: ResourceType.Task, - label: "The Runtime For a Successful Task Changes By Some Percentage", + label: "The runtime for a successful task changes by some percentage", regexSelectors: taskRegexSelectors, extraFields: [ { @@ -355,41 +355,41 @@ export const projectTriggers: Trigger = { export const waterfallTriggers: Trigger = { [ProjectTriggers.ANY_VERSION_FINISHES]: { - trigger: TriggerType.FAMILY_OUTCOME, + trigger: TriggerType.OUTCOME, resourceType: ResourceType.Version, - label: "Any Version Finishes", + label: "Any version finishes", extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_VERSION_FAILS]: { - trigger: TriggerType.FAMILY_FAILURE, + trigger: TriggerType.FAILURE, resourceType: ResourceType.Version, - label: "Any Version Fails", + label: "Any version fails", extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_VERSION_SUCCEEDS]: { - trigger: TriggerType.FAMILY_SUCCESS, + trigger: TriggerType.SUCCESS, resourceType: ResourceType.Version, - label: "Any Version Succeeds", + label: "Any version succeeds", extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_BUILD_FINISHES]: { trigger: TriggerType.OUTCOME, resourceType: ResourceType.Build, - label: "Any Build Finishes", + label: "Any build finishes", regexSelectors: buildRegexSelectors, extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_BUILD_FAILS]: { trigger: TriggerType.FAILURE, resourceType: ResourceType.Build, - label: "Any Build Fails", + label: "Any build fails", regexSelectors: buildRegexSelectors, extraFields: [requesterSubscriberConfig], }, [ProjectTriggers.ANY_BUILD_SUCCEEDS]: { trigger: TriggerType.SUCCESS, resourceType: ResourceType.Build, - label: "Any Build Succeeds", + label: "Any build succeeds", regexSelectors: buildRegexSelectors, extraFields: [requesterSubscriberConfig], }, @@ -418,9 +418,6 @@ export const triggerToCopy = { [TriggerType.OUTCOME]: "Outcome", [TriggerType.FAILURE]: "Failure", [TriggerType.SUCCESS]: "Success", - [TriggerType.FAMILY_OUTCOME]: "Outcome", - [TriggerType.FAMILY_FAILURE]: "Failure", - [TriggerType.FAMILY_SUCCESS]: "Success", [TriggerType.RUNTIME_CHANGE]: "Runtime changes by %", [TriggerType.EXCEEDS_DURATION]: "Runtime exceeds duration", [TriggerType.SUCCESSFUL_EXCEEDS_DURATION]: "Runtime exceeds duration", @@ -428,14 +425,21 @@ export const triggerToCopy = { [TriggerType.TASK_FAILED_OR_BLOCKED]: "Task failed or blocked", [TriggerType.REGRESSION]: "Regression", [TriggerType.TEST_REGRESSION]: "Test regression", - [TriggerType.FIRST_FAILURE_BUILD]: "First failure", [TriggerType.FIRST_FAILURE_BUILD]: "First failure in build", [TriggerType.FIRST_FAILURE_VERSION]: "First failure in version", [TriggerType.FIRST_FAILURE_VERSION_NAME]: "First failure in version with name", + [TriggerType.FAMILY_OUTCOME]: "Outcome", + [TriggerType.FAMILY_FAILURE]: "Failure", + [TriggerType.FAMILY_SUCCESS]: "Success", }; -export const convertFamilyTrigger = (trigger: string) => { +/** + * Converts a family trigger into a non-family trigger. + * @param trigger - string representing a trigger. It may or may not be a family trigger. + * @returns string representing a non-family trigger + */ +export const convertFromFamilyTrigger = (trigger: string) => { switch (trigger) { case TriggerType.FAMILY_OUTCOME: return TriggerType.OUTCOME; diff --git a/src/pages/preferences/preferencesTabs/notificationTab/useSubscriptionData.tsx b/src/pages/preferences/preferencesTabs/notificationTab/useSubscriptionData.tsx index a7cd7ea8d0..f91ab0a5bc 100644 --- a/src/pages/preferences/preferencesTabs/notificationTab/useSubscriptionData.tsx +++ b/src/pages/preferences/preferencesTabs/notificationTab/useSubscriptionData.tsx @@ -3,7 +3,7 @@ import { useQuery } from "@apollo/client"; import styled from "@emotion/styled"; import { LeafyGreenTableRow } from "@leafygreen-ui/table"; import { size } from "constants/tokens"; -import { convertFamilyTrigger } from "constants/triggers"; +import { convertFromFamilyTrigger } from "constants/triggers"; import { UserSubscriptionsQuery, UserSubscriptionsQueryVariables, @@ -61,7 +61,7 @@ const processSubscriptionData = ( // For this table's purposes, FAMILY_TRIGGER = TRIGGER. Convert all family triggers to their base type. .map(({ trigger, ...subscription }) => ({ ...subscription, - trigger: convertFamilyTrigger(trigger), + trigger: convertFromFamilyTrigger(trigger), })) // For subscriptions that contain regex selectors or additional trigger data, append an expandable section .map((subscription) => { diff --git a/src/pages/projectSettings/tabs/NotificationsTab/getGqlPayload.test.ts b/src/pages/projectSettings/tabs/NotificationsTab/getGqlPayload.test.ts index 5fef7a091a..fc8a8aa958 100644 --- a/src/pages/projectSettings/tabs/NotificationsTab/getGqlPayload.test.ts +++ b/src/pages/projectSettings/tabs/NotificationsTab/getGqlPayload.test.ts @@ -38,7 +38,7 @@ describe("getGqlPayload", () => { webhookSubscriber: undefined, jiraIssueSubscriber: undefined, }, - trigger: "family-outcome", + trigger: "outcome", trigger_data: { requester: "gitter_request" }, }, ]); @@ -150,7 +150,7 @@ describe("getGqlPayload", () => { webhookSubscriber: undefined, jiraIssueSubscriber: undefined, }, - trigger: "family-failure", + trigger: "failure", trigger_data: { requester: "ad_hoc" }, }); }); diff --git a/src/pages/projectSettings/tabs/NotificationsTab/transformers.test.ts b/src/pages/projectSettings/tabs/NotificationsTab/transformers.test.ts index cc0703722f..c9bfdf1085 100644 --- a/src/pages/projectSettings/tabs/NotificationsTab/transformers.test.ts +++ b/src/pages/projectSettings/tabs/NotificationsTab/transformers.test.ts @@ -80,7 +80,7 @@ describe("project data", () => { jiraIssueSubscriber: undefined, webhookSubscriber: undefined, }, - trigger: "family-outcome", + trigger: "outcome", trigger_data: { requester: "gitter_request", }, @@ -143,7 +143,7 @@ describe("project data", () => { }, webhookSubscriber: undefined, }, - trigger: "family-outcome", + trigger: "outcome", trigger_data: { requester: "gitter_request", }, @@ -222,7 +222,7 @@ describe("project data", () => { ], }, }, - trigger: "family-outcome", + trigger: "outcome", trigger_data: { requester: "gitter_request", }, diff --git a/src/pages/projectSettings/tabs/NotificationsTab/transformers.ts b/src/pages/projectSettings/tabs/NotificationsTab/transformers.ts index 9f016cc019..aca919f48f 100644 --- a/src/pages/projectSettings/tabs/NotificationsTab/transformers.ts +++ b/src/pages/projectSettings/tabs/NotificationsTab/transformers.ts @@ -1,6 +1,6 @@ import { ProjectSettingsTabRoutes } from "constants/routes"; import { getSubscriberText } from "constants/subscription"; -import { convertFamilyTrigger, projectTriggers } from "constants/triggers"; +import { convertFromFamilyTrigger, projectTriggers } from "constants/triggers"; import { BannerTheme, ProjectInput, @@ -16,10 +16,9 @@ type Tab = ProjectSettingsTabRoutes.Notifications; const { toSentenceCase } = string; const getTriggerText = (trigger: string, resourceType: string) => { - const convertedTrigger = convertFamilyTrigger(trigger); const triggerText = resourceType && trigger - ? `${toSentenceCase(resourceType)} ${convertedTrigger} ` + ? `${toSentenceCase(resourceType)} ${convertFromFamilyTrigger(trigger)} ` : ""; return triggerText; }; @@ -27,7 +26,7 @@ const getTriggerText = (trigger: string, resourceType: string) => { const getTriggerEnum = (trigger: string, resourceType: string) => { const triggerEnum = Object.keys(projectTriggers).find( (t) => - projectTriggers[t].trigger === trigger && + projectTriggers[t].trigger === convertFromFamilyTrigger(trigger) && projectTriggers[t].resourceType === resourceType ); return triggerEnum; diff --git a/src/types/triggers.ts b/src/types/triggers.ts index 6af2bcdf85..be7c3a3b65 100644 --- a/src/types/triggers.ts +++ b/src/types/triggers.ts @@ -17,9 +17,6 @@ export enum TriggerType { OUTCOME = "outcome", FAILURE = "failure", SUCCESS = "success", - FAMILY_OUTCOME = "family-outcome", - FAMILY_FAILURE = "family-failure", - FAMILY_SUCCESS = "family-success", RUNTIME_CHANGE = "runtime-change", EXCEEDS_DURATION = "exceeds-duration", SUCCESSFUL_EXCEEDS_DURATION = "successful-exceeds-duration", @@ -30,6 +27,11 @@ export enum TriggerType { FIRST_FAILURE_BUILD = "first-failure-in-build", FIRST_FAILURE_VERSION = "first-failure-in-version", FIRST_FAILURE_VERSION_NAME = "first-failure-in-version-with-name", + + // Family triggers are for patches only. + FAMILY_OUTCOME = "family-outcome", + FAMILY_FAILURE = "family-failure", + FAMILY_SUCCESS = "family-success", } export enum TaskTriggers { From 05625705a7bf807ecf9d0687c93de64f3c89bd18 Mon Sep 17 00:00:00 2001 From: Sophie Stadler Date: Fri, 5 Jan 2024 11:51:34 -0500 Subject: [PATCH 13/22] v3.0.187 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e082dc3722..e02774b734 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "spruce", - "version": "3.0.186", + "version": "3.0.187", "private": true, "scripts": { "bootstrap-logkeeper": "./scripts/bootstrap-logkeeper.sh", From 98686edfd3fb55cb80a79d581a781c56c003593b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:00:21 -0500 Subject: [PATCH 14/22] CHORE(NPM) - bump @leafygreen-ui/code from 14.0.1 to 14.2.18 (#2207) --- package.json | 2 +- yarn.lock | 118 ++++++++++++++++++++------------------------------- 2 files changed, 48 insertions(+), 72 deletions(-) diff --git a/package.json b/package.json index e02774b734..2ed7049c1b 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@leafygreen-ui/callout": "9.0.13", "@leafygreen-ui/card": "10.0.5", "@leafygreen-ui/checkbox": "12.0.5", - "@leafygreen-ui/code": "14.0.1", + "@leafygreen-ui/code": "14.2.18", "@leafygreen-ui/combobox": "7.0.1", "@leafygreen-ui/confirmation-modal": "5.0.6", "@leafygreen-ui/emotion": "4.0.7", diff --git a/yarn.lock b/yarn.lock index 61a59c198c..e4ba48bafa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3169,7 +3169,7 @@ resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== -"@leafygreen-ui/a11y@^1.3.4", "@leafygreen-ui/a11y@^1.4.10", "@leafygreen-ui/a11y@^1.4.11", "@leafygreen-ui/a11y@^1.4.2", "@leafygreen-ui/a11y@^1.4.3", "@leafygreen-ui/a11y@^1.4.7", "@leafygreen-ui/a11y@^1.4.8": +"@leafygreen-ui/a11y@^1.3.4", "@leafygreen-ui/a11y@^1.4.10", "@leafygreen-ui/a11y@^1.4.11", "@leafygreen-ui/a11y@^1.4.2", "@leafygreen-ui/a11y@^1.4.3": version "1.4.11" resolved "https://registry.yarnpkg.com/@leafygreen-ui/a11y/-/a11y-1.4.11.tgz#5ebaa4a4a1bf99e2c3d6d9cb08f6b4983f2b2d59" integrity sha512-mzNMR4ci3ExdCY3Ec1kr7xH4nV02uamoohbWxcI9qSd41TFskaDAZSXO9PL9S8JosQXjpRkt0f470XvVE0kEXQ== @@ -3206,11 +3206,6 @@ resolved "https://registry.yarnpkg.com/@leafygreen-ui/box/-/box-3.1.4.tgz#6ff56c8c205f83018373c9c0fe8f49681097dc0a" integrity sha512-cdEXGEafHuaH4zGx3NTX1bMOQ52EpoWA595BC1hh4/8BmXL+H4NFMGywuhZnvYjC4lyVGauX6sCspxrunbmfMQ== -"@leafygreen-ui/box@^3.1.7": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/box/-/box-3.1.7.tgz#830150ed836cd941cfb2787264a3d1c16f1fe648" - integrity sha512-7uW6pxJaxKES8/ijQOcNSL0HpRAiBfaBdFamUAP+TaU9vvllG4cnzZlAfLdNKTWufJy5uWp7eNoE//7KPFLj+w== - "@leafygreen-ui/box@^3.1.8": version "3.1.8" resolved "https://registry.yarnpkg.com/@leafygreen-ui/box/-/box-3.1.8.tgz#33e6dedbe3ee510ce88ffade0a3a9e68a96103a9" @@ -3229,20 +3224,7 @@ "@leafygreen-ui/tokens" "^2.1.4" polished "^4.2.2" -"@leafygreen-ui/button@^19.0.1": - version "19.0.4" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/button/-/button-19.0.4.tgz#f94ea61608e56020358ac3f8cd66669f125dff64" - integrity sha512-T72lmAHS63cvhyAKaO53tNysL3xDsjnmIoaP0I55eOFOYlEy522U7vf0RMi/BsOePyAJak+x9yZ4uj8AWMCsbg== - dependencies: - "@leafygreen-ui/box" "^3.1.1" - "@leafygreen-ui/emotion" "^4.0.3" - "@leafygreen-ui/lib" "^10.0.0" - "@leafygreen-ui/palette" "^3.4.7" - "@leafygreen-ui/ripple" "^1.1.8" - "@leafygreen-ui/tokens" "^2.0.0" - polished "^4.2.2" - -"@leafygreen-ui/button@^21.0.10", "@leafygreen-ui/button@^21.0.3", "@leafygreen-ui/button@^21.0.5": +"@leafygreen-ui/button@^21.0.10", "@leafygreen-ui/button@^21.0.11", "@leafygreen-ui/button@^21.0.3", "@leafygreen-ui/button@^21.0.5": version "21.0.11" resolved "https://registry.yarnpkg.com/@leafygreen-ui/button/-/button-21.0.11.tgz#a1cfa56226d9ccdf43945441340013ff02c55fbe" integrity sha512-NJhllsXO7jAJoAou9kPIk/B8ODYUrGxr4l4TceoAwAM3cW0kZ5kys9KA+0TOmG2AxNKLcElLu+wCg3TbssFk+Q== @@ -3343,21 +3325,23 @@ "@leafygreen-ui/palette" "^4.0.7" "@leafygreen-ui/tokens" "^2.2.0" -"@leafygreen-ui/code@14.0.1": - version "14.0.1" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/code/-/code-14.0.1.tgz#1959bb07bb98a428d63afb8753c31b6ce7a0c772" - integrity sha512-ZzZIbM6tMDmkNHkQuQIUk4oBV5Mgq8RzO35V2R33sVA/sZFGom5iN/IW/U3c61FNuRHEptfH7Y2+3aOcWPOrAA== +"@leafygreen-ui/code@14.2.18": + version "14.2.18" + resolved "https://registry.yarnpkg.com/@leafygreen-ui/code/-/code-14.2.18.tgz#7ade044ca8c9ff1c5bb9332021a57278d56b5292" + integrity sha512-vtAEzURQ/Or8G9vBjsjN4aCWoysHr/Ny/3ewEcLRpz66vkC0kplArdnmG5dVSmklzImU4jKa+QOeM74l3DTHUQ== dependencies: - "@leafygreen-ui/a11y" "^1.3.4" - "@leafygreen-ui/button" "^19.0.1" - "@leafygreen-ui/emotion" "^4.0.3" - "@leafygreen-ui/hooks" "^7.3.3" - "@leafygreen-ui/icon" "^11.12.1" - "@leafygreen-ui/icon-button" "^15.0.1" - "@leafygreen-ui/lib" "^10.0.0" - "@leafygreen-ui/palette" "^3.4.4" - "@leafygreen-ui/select" "^10.1.0" - "@leafygreen-ui/tokens" "^1.4.0" + "@leafygreen-ui/a11y" "^1.4.11" + "@leafygreen-ui/button" "^21.0.11" + "@leafygreen-ui/emotion" "^4.0.7" + "@leafygreen-ui/hooks" "^8.0.0" + "@leafygreen-ui/icon" "^11.25.1" + "@leafygreen-ui/icon-button" "^15.0.19" + "@leafygreen-ui/lib" "^13.1.0" + "@leafygreen-ui/palette" "^4.0.7" + "@leafygreen-ui/select" "^11.0.1" + "@leafygreen-ui/tokens" "^2.2.0" + "@types/facepaint" "^1.2.1" + "@types/highlight.js" "^10.1.0" clipboard "^2.0.6" facepaint "^1.2.1" highlight.js "~11.5.0" @@ -3473,33 +3457,7 @@ "@leafygreen-ui/palette" "^3.4.7" "@leafygreen-ui/tokens" "^2.0.0" -"@leafygreen-ui/icon-button@^15.0.1", "@leafygreen-ui/icon-button@^15.0.10", "@leafygreen-ui/icon-button@^15.0.12", "@leafygreen-ui/icon-button@^15.0.16", "@leafygreen-ui/icon-button@^15.0.4", "@leafygreen-ui/icon-button@^15.0.7": - version "15.0.16" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon-button/-/icon-button-15.0.16.tgz#3e6d4b1433f72ecec416c43426a687234cb6096b" - integrity sha512-j/y60X+At8tm1uKj2LWfppxuH3lCB1Mwa99PFhmVVD9ohNFjjqY6m5Vll7NTq10AelUimWOYk+uCzh4A96x4kQ== - dependencies: - "@leafygreen-ui/a11y" "^1.4.7" - "@leafygreen-ui/box" "^3.1.7" - "@leafygreen-ui/emotion" "^4.0.7" - "@leafygreen-ui/icon" "^11.22.1" - "@leafygreen-ui/lib" "^10.4.3" - "@leafygreen-ui/palette" "^4.0.7" - "@leafygreen-ui/tokens" "^2.1.4" - -"@leafygreen-ui/icon-button@^15.0.17": - version "15.0.17" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon-button/-/icon-button-15.0.17.tgz#58e1dc09dcca00793efc5d02d652945bc8717fef" - integrity sha512-2gKZKLwGDoyhOmiYvSDRssk1OU/jSraIU4prT40lLgqZFCmA2nqDr7Hfb+W62QNvEGchoXNOXzm8KG/yrJBl2Q== - dependencies: - "@leafygreen-ui/a11y" "^1.4.8" - "@leafygreen-ui/box" "^3.1.8" - "@leafygreen-ui/emotion" "^4.0.7" - "@leafygreen-ui/icon" "^11.22.2" - "@leafygreen-ui/lib" "^11.0.0" - "@leafygreen-ui/palette" "^4.0.7" - "@leafygreen-ui/tokens" "^2.1.4" - -"@leafygreen-ui/icon-button@^15.0.19": +"@leafygreen-ui/icon-button@^15.0.10", "@leafygreen-ui/icon-button@^15.0.12", "@leafygreen-ui/icon-button@^15.0.16", "@leafygreen-ui/icon-button@^15.0.17", "@leafygreen-ui/icon-button@^15.0.19", "@leafygreen-ui/icon-button@^15.0.4", "@leafygreen-ui/icon-button@^15.0.7": version "15.0.19" resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon-button/-/icon-button-15.0.19.tgz#4c9bd36358c6568605bb76cd2477f6930d4039fc" integrity sha512-TXNFHpfuMXIcMQHW/D31GEFby63qhBLyeI5CLL8KQjD5Xom3Q6fqviu/eyXE097jTzQtd1dO/2IIiqyyLRW30g== @@ -3512,7 +3470,7 @@ "@leafygreen-ui/palette" "^4.0.7" "@leafygreen-ui/tokens" "^2.1.4" -"@leafygreen-ui/icon@11.26.0", "@leafygreen-ui/icon@^11.12.1", "@leafygreen-ui/icon@^11.12.3", "@leafygreen-ui/icon@^11.12.4", "@leafygreen-ui/icon@^11.12.5", "@leafygreen-ui/icon@^11.15.0", "@leafygreen-ui/icon@^11.17.0", "@leafygreen-ui/icon@^11.22.1", "@leafygreen-ui/icon@^11.22.2", "@leafygreen-ui/icon@^11.23.0", "@leafygreen-ui/icon@^11.25.0": +"@leafygreen-ui/icon@11.26.0": version "11.26.0" resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon/-/icon-11.26.0.tgz#2093df50445bd15758925aae9c0f40813eb817a8" integrity sha512-2+sexm+uLqPC3XxQ8xDky3UhcxwGIuiWnkcG2JImNNMJSnrk87BEG0z7DdCXIpJ46+RtGDYa4B3ADxKSl9M9oQ== @@ -3520,6 +3478,14 @@ "@leafygreen-ui/emotion" "^4.0.7" lodash "^4.17.21" +"@leafygreen-ui/icon@^11.12.1", "@leafygreen-ui/icon@^11.12.3", "@leafygreen-ui/icon@^11.12.4", "@leafygreen-ui/icon@^11.12.5", "@leafygreen-ui/icon@^11.15.0", "@leafygreen-ui/icon@^11.17.0", "@leafygreen-ui/icon@^11.22.1", "@leafygreen-ui/icon@^11.22.2", "@leafygreen-ui/icon@^11.23.0", "@leafygreen-ui/icon@^11.25.0", "@leafygreen-ui/icon@^11.25.1": + version "11.27.0" + resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon/-/icon-11.27.0.tgz#12163437a5e02289d4e40142fb0aa049bb6a5b98" + integrity sha512-Dk9ELFRG1DIM/3xXKeG44yU3x3G8PCyUL3+ptq0pCaClRQIdQvxSgr873bV8Mq7NNu8IcK/bjQKQ5sLAMpWChg== + dependencies: + "@leafygreen-ui/emotion" "^4.0.7" + lodash "^4.17.21" + "@leafygreen-ui/inline-definition@6.0.14": version "6.0.14" resolved "https://registry.yarnpkg.com/@leafygreen-ui/inline-definition/-/inline-definition-6.0.14.tgz#fd0ba775a2ff88520ed31d0489e57fd90416bad3" @@ -3813,13 +3779,6 @@ dependencies: "@leafygreen-ui/tokens" "^2.1.4" -"@leafygreen-ui/ripple@^1.1.8": - version "1.1.9" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/ripple/-/ripple-1.1.9.tgz#a923bebc2182fc034ce56950302794351490775e" - integrity sha512-0sAyvOu8Tva9LYgpkMTvcP9XKyrS8i57hUq+QGpT9b3s4UrfHHtDD3TaDGll08GYViIwqQDEzLQLk3H3O3we8Q== - dependencies: - "@leafygreen-ui/tokens" "^2.0.2" - "@leafygreen-ui/search-input@2.0.8": version "2.0.8" resolved "https://registry.yarnpkg.com/@leafygreen-ui/search-input/-/search-input-2.0.8.tgz#353bf12b9fc1a1c6f22afe92e6de2a37760c4dc0" @@ -3856,7 +3815,7 @@ lodash "^4.17.21" polished "^4.2.2" -"@leafygreen-ui/select@11.1.1", "@leafygreen-ui/select@^11.1.0": +"@leafygreen-ui/select@11.1.1", "@leafygreen-ui/select@^11.0.1", "@leafygreen-ui/select@^11.1.0": version "11.1.1" resolved "https://registry.yarnpkg.com/@leafygreen-ui/select/-/select-11.1.1.tgz#b4d03071837feca1d5c206b36a1018b7d936f43f" integrity sha512-aH0RNrIF3EU+5ChHJxVVjzlmFGkYRTq9DTRqm9eWgWcZIT3+ggIJCOwBNMr/8rD72NhyXm+RD8Gp2wwk8XJJrg== @@ -3876,7 +3835,7 @@ polished "^4.1.3" react-is "^18.0.1" -"@leafygreen-ui/select@^10.1.0", "@leafygreen-ui/select@^10.3.12": +"@leafygreen-ui/select@^10.3.12": version "10.3.12" resolved "https://registry.yarnpkg.com/@leafygreen-ui/select/-/select-10.3.12.tgz#4546392fd578fe52d5912fea9a2944b7b2cd387d" integrity sha512-r3WchfA1CMgz2Efd7Ccm6v8nFVF6vzAqleaEudTJ09XXtVmV9Df1v1kY/90F+GKij74OjUEOft7RgCkh0SB6/A== @@ -5918,6 +5877,11 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/facepaint@^1.2.1": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/facepaint/-/facepaint-1.2.5.tgz#dbb8b1d04579ebcb59d73b3791770407540122dd" + integrity sha512-fi9kvwtC3IQ6Y3QVDkYEZsqEcetAdWD0zqqk8pEHlDXWkgS2WzolWN8Z5PGPT7YJ7ga71CCI0fVKVnVKqV+P6Q== + "@types/find-cache-dir@^3.2.1": version "3.2.1" resolved "https://registry.yarnpkg.com/@types/find-cache-dir/-/find-cache-dir-3.2.1.tgz#7b959a4b9643a1e6a1a5fe49032693cc36773501" @@ -5938,6 +5902,13 @@ dependencies: "@types/node" "*" +"@types/highlight.js@^10.1.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-10.1.0.tgz#89bb0c202997d7a90a07bd2ec1f7d00c56bb90b4" + integrity sha512-77hF2dGBsOgnvZll1vymYiNUtqJ8cJfXPD6GG/2M0aLRc29PkvB7Au6sIDjIEFcSICBhCh2+Pyq6WSRS7LUm6A== + dependencies: + highlight.js "*" + "@types/http-errors@*": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65" @@ -10229,6 +10200,11 @@ header-case@^2.0.4: capital-case "^1.0.4" tslib "^2.0.3" +highlight.js@*: + version "11.9.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.9.0.tgz#04ab9ee43b52a41a047432c8103e2158a1b8b5b0" + integrity sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw== + highlight.js@~11.5.0: version "11.5.1" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.5.1.tgz#027c24e4509e2f4dcd00b4a6dda542ce0a1f7aea" From ca169b8de4e1202f3557ffba7bb96691f5b3155b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:08:03 -0500 Subject: [PATCH 15/22] CHORE(NPM) - bump eslint-plugin-jsdoc from 46.4.6 to 48.0.2 (#2214) --- package.json | 2 +- yarn.lock | 42 +++++++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 2ed7049c1b..2780f296c3 100644 --- a/package.json +++ b/package.json @@ -178,7 +178,7 @@ "eslint-plugin-cypress": "^2.12.1", "eslint-plugin-import": "2.26.0", "eslint-plugin-jest": "27.2.1", - "eslint-plugin-jsdoc": "^46.2.6", + "eslint-plugin-jsdoc": "48.0.2", "eslint-plugin-jsx-a11y": "6.7.1", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-react": "7.30.1", diff --git a/yarn.lock b/yarn.lock index e4ba48bafa..aa872e46d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1958,12 +1958,12 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== -"@es-joy/jsdoccomment@~0.40.1": - version "0.40.1" - resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz#13acd77fb372ed1c83b7355edd865a3b370c9ec4" - integrity sha512-YORCdZSusAlBrFpZ77pJjc5r1bQs5caPWtAu+WWmiSo+8XaUzseapVrfAtiRFbQWnrBxxLLEwF6f6ZG/UgCQCg== +"@es-joy/jsdoccomment@~0.41.0": + version "0.41.0" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz#4a2f7db42209c0425c71a1476ef1bdb6dcd836f6" + integrity sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw== dependencies: - comment-parser "1.4.0" + comment-parser "1.4.1" esquery "^1.5.0" jsdoc-type-pratt-parser "~4.0.0" @@ -7759,10 +7759,10 @@ commander@^9.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== -comment-parser@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.0.tgz#0f8c560f59698193854f12884c20c0e39a26d32c" - integrity sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw== +comment-parser@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.1.tgz#bdafead37961ac079be11eb7ec65c4d021eaf9cc" + integrity sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg== common-path-prefix@^3.0.0: version "3.0.0" @@ -9009,20 +9009,20 @@ eslint-plugin-jest@27.2.1: dependencies: "@typescript-eslint/utils" "^5.10.0" -eslint-plugin-jsdoc@^46.2.6: - version "46.4.6" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.6.tgz#5226461eda61b5920297cbe02c3b17bc9423cf0b" - integrity sha512-z4SWYnJfOqftZI+b3RM9AtWL1vF/sLWE/LlO9yOKDof9yN2+n3zOdOJTGX/pRE/xnPsooOLG2Rq6e4d+XW3lNw== +eslint-plugin-jsdoc@48.0.2: + version "48.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.0.2.tgz#b843107e8caec57b8b463f04797be3b30d6a52da" + integrity sha512-CBFl5Jc7+jlV36RwDm+PQ8Uw5r28pn2/uW/OaB+Gw5bFwn4Py/1eYMZ3hGf9S4meUFZ/sRvS+hVif2mRAp6WqQ== dependencies: - "@es-joy/jsdoccomment" "~0.40.1" + "@es-joy/jsdoccomment" "~0.41.0" are-docs-informative "^0.0.2" - comment-parser "1.4.0" + comment-parser "1.4.1" debug "^4.3.4" escape-string-regexp "^4.0.0" esquery "^1.5.0" is-builtin-module "^3.2.1" semver "^7.5.4" - spdx-expression-parse "^3.0.1" + spdx-expression-parse "^4.0.0" eslint-plugin-jsx-a11y@6.7.1: version "6.7.1" @@ -14498,7 +14498,7 @@ spdx-exceptions@^2.1.0: resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== -spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: +spdx-expression-parse@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== @@ -14506,6 +14506,14 @@ spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" +spdx-expression-parse@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz#a23af9f3132115465dac215c099303e4ceac5794" + integrity sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + spdx-license-ids@^3.0.0: version "3.0.13" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" From cafd9b2d5e4bf8ffd877c7df9d1045d88c5fcbed Mon Sep 17 00:00:00 2001 From: minnakt Date: Tue, 9 Jan 2024 11:47:27 -0500 Subject: [PATCH 16/22] v3.0.188 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2780f296c3..960ac3c75d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "spruce", - "version": "3.0.187", + "version": "3.0.188", "private": true, "scripts": { "bootstrap-logkeeper": "./scripts/bootstrap-logkeeper.sh", From 7a77eb3baeba6d15b38300aca5b95870215db128 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:11:18 -0500 Subject: [PATCH 17/22] CHORE(NPM) - bump @leafygreen-ui/text-area from 8.0.4 to 8.0.21 (#2215) --- package.json | 2 +- yarn.lock | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 960ac3c75d..1ed84c3f53 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "@leafygreen-ui/skeleton-loader": "1.1.0", "@leafygreen-ui/table": "12.1.4", "@leafygreen-ui/tabs": "11.0.4", - "@leafygreen-ui/text-area": "8.0.4", + "@leafygreen-ui/text-area": "8.0.21", "@leafygreen-ui/text-input": "12.1.0", "@leafygreen-ui/toast": "6.1.4", "@leafygreen-ui/toggle": "10.0.17", diff --git a/yarn.lock b/yarn.lock index aa872e46d9..b51c49e556 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3478,7 +3478,7 @@ "@leafygreen-ui/emotion" "^4.0.7" lodash "^4.17.21" -"@leafygreen-ui/icon@^11.12.1", "@leafygreen-ui/icon@^11.12.3", "@leafygreen-ui/icon@^11.12.4", "@leafygreen-ui/icon@^11.12.5", "@leafygreen-ui/icon@^11.15.0", "@leafygreen-ui/icon@^11.17.0", "@leafygreen-ui/icon@^11.22.1", "@leafygreen-ui/icon@^11.22.2", "@leafygreen-ui/icon@^11.23.0", "@leafygreen-ui/icon@^11.25.0", "@leafygreen-ui/icon@^11.25.1": +"@leafygreen-ui/icon@^11.12.1", "@leafygreen-ui/icon@^11.12.3", "@leafygreen-ui/icon@^11.12.4", "@leafygreen-ui/icon@^11.12.5", "@leafygreen-ui/icon@^11.15.0", "@leafygreen-ui/icon@^11.17.0", "@leafygreen-ui/icon@^11.22.1", "@leafygreen-ui/icon@^11.22.2", "@leafygreen-ui/icon@^11.23.0", "@leafygreen-ui/icon@^11.25.0", "@leafygreen-ui/icon@^11.25.1", "@leafygreen-ui/icon@^11.27.0": version "11.27.0" resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon/-/icon-11.27.0.tgz#12163437a5e02289d4e40142fb0aa049bb6a5b98" integrity sha512-Dk9ELFRG1DIM/3xXKeG44yU3x3G8PCyUL3+ptq0pCaClRQIdQvxSgr873bV8Mq7NNu8IcK/bjQKQ5sLAMpWChg== @@ -3921,18 +3921,18 @@ "@leafygreen-ui/portal" "^4.0.9" "@leafygreen-ui/tokens" "^2.0.0" -"@leafygreen-ui/text-area@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/text-area/-/text-area-8.0.4.tgz#57d4d4eaad5210b90baa24ec1980afb24923c989" - integrity sha512-NnhVINOpf5TdlEikxAHM1k6TiJOpSCTuqRr5eQcTYnelyiStYiVhHqXqfPgQ4M5YZqYSyEVpyNqWz/li9c7o1w== +"@leafygreen-ui/text-area@8.0.21": + version "8.0.21" + resolved "https://registry.yarnpkg.com/@leafygreen-ui/text-area/-/text-area-8.0.21.tgz#098a434d45d6092e1e54f0e1f0d3603477848e37" + integrity sha512-1gzzGt3dvNWzT3mhOrmjs3oKt+wruGs6Yq3Ij0gYwEzosSQc81dNwlPimN5S1Lzsu5aCbn4cgaQPuYi47QcLcw== dependencies: - "@leafygreen-ui/emotion" "^4.0.3" - "@leafygreen-ui/hooks" "^7.4.0" - "@leafygreen-ui/icon" "^11.12.4" - "@leafygreen-ui/lib" "^10.0.0" - "@leafygreen-ui/palette" "^3.4.7" - "@leafygreen-ui/tokens" "^2.0.0" - "@leafygreen-ui/typography" "^16.0.0" + "@leafygreen-ui/emotion" "^4.0.7" + "@leafygreen-ui/hooks" "^8.0.0" + "@leafygreen-ui/icon" "^11.27.0" + "@leafygreen-ui/lib" "^13.0.0" + "@leafygreen-ui/palette" "^4.0.7" + "@leafygreen-ui/tokens" "^2.2.0" + "@leafygreen-ui/typography" "^18.0.0" "@leafygreen-ui/text-input@12.1.0": version "12.1.0" From d5f65c899e4a6e15e4d56d2d11feb0df69d1a2bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:02:22 -0500 Subject: [PATCH 18/22] CHORE(NPM) - bump @leafygreen-ui/icon-button from 15.0.5 to 15.0.19 (#2216) --- package.json | 2 +- yarn.lock | 22 ++-------------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 1ed84c3f53..2c4f8ff075 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@leafygreen-ui/expandable-card": "3.0.5", "@leafygreen-ui/guide-cue": "5.0.5", "@leafygreen-ui/icon": "11.26.0", - "@leafygreen-ui/icon-button": "15.0.5", + "@leafygreen-ui/icon-button": "15.0.19", "@leafygreen-ui/inline-definition": "6.0.14", "@leafygreen-ui/interaction-ring": "7.0.2", "@leafygreen-ui/leafygreen-provider": "3.1.10", diff --git a/yarn.lock b/yarn.lock index b51c49e556..5bc1bdc6ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3201,12 +3201,7 @@ "@leafygreen-ui/tokens" "^2.0.1" "@leafygreen-ui/typography" "^16.1.0" -"@leafygreen-ui/box@^3.1.1", "@leafygreen-ui/box@^3.1.4": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/box/-/box-3.1.4.tgz#6ff56c8c205f83018373c9c0fe8f49681097dc0a" - integrity sha512-cdEXGEafHuaH4zGx3NTX1bMOQ52EpoWA595BC1hh4/8BmXL+H4NFMGywuhZnvYjC4lyVGauX6sCspxrunbmfMQ== - -"@leafygreen-ui/box@^3.1.8": +"@leafygreen-ui/box@^3.1.1", "@leafygreen-ui/box@^3.1.4", "@leafygreen-ui/box@^3.1.8": version "3.1.8" resolved "https://registry.yarnpkg.com/@leafygreen-ui/box/-/box-3.1.8.tgz#33e6dedbe3ee510ce88ffade0a3a9e68a96103a9" integrity sha512-qfjwhrie+mUrS2H+Qp98iQKBPoZtNpFmlGBYgg59sVOzotFvyvqwxlf/JcaNGo+v7nyOhC2XAHui0ywf9cScKw== @@ -3444,20 +3439,7 @@ dependencies: lodash "^4.17.21" -"@leafygreen-ui/icon-button@15.0.5": - version "15.0.5" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon-button/-/icon-button-15.0.5.tgz#4c9e6a8388c471262c98bcb52b2d95c061625eea" - integrity sha512-8zWWqInWVvG2399FeyoQcvuzdEt0aongqZi06eGEQOpXwRCaIxUXOqeEmAHPjFy2K3jAUs2KtMFVlrdZZnWNbg== - dependencies: - "@leafygreen-ui/a11y" "^1.3.4" - "@leafygreen-ui/box" "^3.1.1" - "@leafygreen-ui/emotion" "^4.0.3" - "@leafygreen-ui/icon" "^11.12.4" - "@leafygreen-ui/lib" "^10.0.0" - "@leafygreen-ui/palette" "^3.4.7" - "@leafygreen-ui/tokens" "^2.0.0" - -"@leafygreen-ui/icon-button@^15.0.10", "@leafygreen-ui/icon-button@^15.0.12", "@leafygreen-ui/icon-button@^15.0.16", "@leafygreen-ui/icon-button@^15.0.17", "@leafygreen-ui/icon-button@^15.0.19", "@leafygreen-ui/icon-button@^15.0.4", "@leafygreen-ui/icon-button@^15.0.7": +"@leafygreen-ui/icon-button@15.0.19", "@leafygreen-ui/icon-button@^15.0.10", "@leafygreen-ui/icon-button@^15.0.12", "@leafygreen-ui/icon-button@^15.0.16", "@leafygreen-ui/icon-button@^15.0.17", "@leafygreen-ui/icon-button@^15.0.19", "@leafygreen-ui/icon-button@^15.0.4", "@leafygreen-ui/icon-button@^15.0.7": version "15.0.19" resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon-button/-/icon-button-15.0.19.tgz#4c9bd36358c6568605bb76cd2477f6930d4039fc" integrity sha512-TXNFHpfuMXIcMQHW/D31GEFby63qhBLyeI5CLL8KQjD5Xom3Q6fqviu/eyXE097jTzQtd1dO/2IIiqyyLRW30g== From e4ff330d142883e992b0a2d889ddf6f25aacb8c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:11:04 -0500 Subject: [PATCH 19/22] CHORE(NPM) - bump @leafygreen-ui/modal from 16.0.1 to 16.0.3 (#2217) --- package.json | 2 +- yarn.lock | 34 +++++++++------------------------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 2c4f8ff075..e8291e3c00 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "@leafygreen-ui/leafygreen-provider": "3.1.10", "@leafygreen-ui/loading-indicator": "2.0.6", "@leafygreen-ui/menu": "20.0.1", - "@leafygreen-ui/modal": "16.0.1", + "@leafygreen-ui/modal": "16.0.3", "@leafygreen-ui/number-input": "1.0.18", "@leafygreen-ui/pagination": "1.0.12", "@leafygreen-ui/palette": "4.0.7", diff --git a/yarn.lock b/yarn.lock index 5bc1bdc6ae..38ae66ba17 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3439,7 +3439,7 @@ dependencies: lodash "^4.17.21" -"@leafygreen-ui/icon-button@15.0.19", "@leafygreen-ui/icon-button@^15.0.10", "@leafygreen-ui/icon-button@^15.0.12", "@leafygreen-ui/icon-button@^15.0.16", "@leafygreen-ui/icon-button@^15.0.17", "@leafygreen-ui/icon-button@^15.0.19", "@leafygreen-ui/icon-button@^15.0.4", "@leafygreen-ui/icon-button@^15.0.7": +"@leafygreen-ui/icon-button@15.0.19", "@leafygreen-ui/icon-button@^15.0.10", "@leafygreen-ui/icon-button@^15.0.12", "@leafygreen-ui/icon-button@^15.0.16", "@leafygreen-ui/icon-button@^15.0.19", "@leafygreen-ui/icon-button@^15.0.4", "@leafygreen-ui/icon-button@^15.0.7": version "15.0.19" resolved "https://registry.yarnpkg.com/@leafygreen-ui/icon-button/-/icon-button-15.0.19.tgz#4c9bd36358c6568605bb76cd2477f6930d4039fc" integrity sha512-TXNFHpfuMXIcMQHW/D31GEFby63qhBLyeI5CLL8KQjD5Xom3Q6fqviu/eyXE097jTzQtd1dO/2IIiqyyLRW30g== @@ -3597,18 +3597,18 @@ lodash "^4.17.21" react-transition-group "^4.4.1" -"@leafygreen-ui/modal@16.0.1", "@leafygreen-ui/modal@^16.0.0": - version "16.0.1" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/modal/-/modal-16.0.1.tgz#ce0a233c9efd814db9359e605aed5ec204b7becc" - integrity sha512-sdHr+u8DFwZBG7MIA2rQnYy1FcOWqREivpFJpLoXrqDEjpqxfdXDCTLtT0U+OTtOL4f9LHmu+9/j0d3YWHNxJA== +"@leafygreen-ui/modal@16.0.3", "@leafygreen-ui/modal@^16.0.0": + version "16.0.3" + resolved "https://registry.yarnpkg.com/@leafygreen-ui/modal/-/modal-16.0.3.tgz#36483aa1642fab9e2955001c4b1adb54e15135fc" + integrity sha512-JvHV4Yy5KCaH3snnG19aYS1d0suslPTWXcPZqySCil+pruCMwCDVdf/21KqQSM/JmyJVwoHlVxHegQlFAMAWEg== dependencies: "@leafygreen-ui/emotion" "^4.0.7" "@leafygreen-ui/hooks" "^8.0.0" "@leafygreen-ui/icon" "^11.23.0" - "@leafygreen-ui/icon-button" "^15.0.17" - "@leafygreen-ui/lib" "^11.0.0" + "@leafygreen-ui/icon-button" "^15.0.19" + "@leafygreen-ui/lib" "^13.0.0" "@leafygreen-ui/palette" "^4.0.7" - "@leafygreen-ui/portal" "^5.0.1" + "@leafygreen-ui/portal" "^5.0.3" "@leafygreen-ui/tokens" "^2.2.0" focus-trap "6.9.4" focus-trap-react "^9.0.2" @@ -3707,23 +3707,7 @@ "@leafygreen-ui/hooks" "^7.7.5" "@leafygreen-ui/lib" "^10.4.0" -"@leafygreen-ui/portal@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/portal/-/portal-5.0.1.tgz#a5b6962210bca1809cd2dc67ae4c767e755a0f34" - integrity sha512-SL+Kw2088aopilmzKOTfzWE4tVKyRyClr1nnOaX+xplQ+6gu22C+LDFL4cJZkkWyP8WlqAE+2s1C631W3uHbPg== - dependencies: - "@leafygreen-ui/hooks" "^8.0.0" - "@leafygreen-ui/lib" "^11.0.0" - -"@leafygreen-ui/portal@^5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@leafygreen-ui/portal/-/portal-5.0.2.tgz#abf03843deef4aa997bfb97ecdfc22e459207d3c" - integrity sha512-vLLB8wGmEtQHhIJ753KbO3zJDBP3idd9h965CPYWdRHHWP0A2QwIRhPr148SbH0/VxFVO6zXVBcTeqPGHhrXZw== - dependencies: - "@leafygreen-ui/hooks" "^8.0.0" - "@leafygreen-ui/lib" "^12.0.0" - -"@leafygreen-ui/portal@^5.0.3": +"@leafygreen-ui/portal@^5.0.1", "@leafygreen-ui/portal@^5.0.2", "@leafygreen-ui/portal@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@leafygreen-ui/portal/-/portal-5.0.3.tgz#062ec8710afcee4c2f4cf3aa78b1f9a3bc25c86e" integrity sha512-vwoZHtdrMzR5uBsfxAvl1kdB/xtQwtfpRTuCqC5Q3X+DsLg9JReDl+5dsGMegwDwkqwzsndYVGpq0BcFuDITXQ== From 7eb85f7e4e599b70949904fc6c6119dea1787f38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:13:58 -0500 Subject: [PATCH 20/22] CHORE(NPM) - bump follow-redirects from 1.15.2 to 1.15.4 (#2219) --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 38ae66ba17..fe81c105a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9619,9 +9619,9 @@ focus-trap@6.9.4, focus-trap@^6.9.4: tabbable "^5.3.3" follow-redirects@^1.0.0, follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + version "1.15.4" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" + integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== for-each@^0.3.3: version "0.3.3" From 5858fa73d71949d619418b43eda2919e6edbad1a Mon Sep 17 00:00:00 2001 From: Mohamed Khelif Date: Tue, 9 Jan 2024 15:56:00 -0500 Subject: [PATCH 21/22] DEVPROD-823 Remove terminated status from hosts table filters (#2218) --- src/constants/hosts.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/constants/hosts.ts b/src/constants/hosts.ts index 182e6fd3df..e85d6bf186 100644 --- a/src/constants/hosts.ts +++ b/src/constants/hosts.ts @@ -12,11 +12,6 @@ export const hostStatuses: Status[] = [ value: HostStatus.Running, key: HostStatus.Running, }, - { - title: "Terminated", - value: HostStatus.Terminated, - key: HostStatus.Terminated, - }, { title: "Uninitialized", value: HostStatus.Uninitialized, From 1a766b108304537fc82bc98b1fc59d0f8b281c0c Mon Sep 17 00:00:00 2001 From: Mohamed Khelif Date: Wed, 10 Jan 2024 15:41:24 -0500 Subject: [PATCH 22/22] DEVPROD-3283 Support virtualization for BaseTable component (#2205) --- src/components/Table/BaseTable.stories.tsx | 42 +++- src/components/Table/BaseTable.tsx | 259 ++++++++++++--------- src/gql/generated/types.ts | 5 + 3 files changed, 180 insertions(+), 126 deletions(-) diff --git a/src/components/Table/BaseTable.stories.tsx b/src/components/Table/BaseTable.stories.tsx index 1d1f2834a2..700ee890cd 100644 --- a/src/components/Table/BaseTable.stories.tsx +++ b/src/components/Table/BaseTable.stories.tsx @@ -1,4 +1,5 @@ -import { useRef } from "react"; +import { useRef, useState } from "react"; +import { css } from "@leafygreen-ui/emotion"; import { LGColumnDef, useLeafyGreenTable } from "@leafygreen-ui/table"; import { WordBreak } from "components/styles"; import { CustomStoryObj, CustomMeta } from "test_utils/types"; @@ -9,7 +10,7 @@ export default { } satisfies CustomMeta; export const Default: CustomStoryObj = { - render: (args) => , + render: (args) => , args: { shouldAlternateRowColor: true, darkMode: false, @@ -39,6 +40,23 @@ export const LongContent: CustomStoryObj = { darkMode: false, }, }; +const virtualScrollingContainerHeight = css` + height: 500px; +`; +export const VirtualTable: CustomStoryObj = { + render: (args) => ( + + ), + args: { + shouldAlternateRowColor: true, + darkMode: false, + }, +}; export const Loading: CustomStoryObj = { render: (args) => , @@ -55,11 +73,12 @@ interface DataShape { size: string; } -const defaultRows: DataShape[] = Array.from({ length: 100 }, (_, i) => ({ - name: `name ${i}`, - type: `type ${i}`, - size: `size ${i}`, -})); +const makeDefaultRows = (count: number): DataShape[] => + Array.from({ length: count }, (_, i) => ({ + name: `name ${i}`, + type: `type ${i}`, + size: `size ${i}`, + })); const nestedRows: DataShape[] = Array.from({ length: 50 }, (_, i) => ({ name: `name ${i}`, @@ -115,17 +134,20 @@ const columns: LGColumnDef[] = [ const TemplateComponent: React.FC< React.ComponentProps & { data: DataShape[]; + useVirtualScrolling?: boolean; } > = (args) => { - const { data, ...rest } = args; + const { data, useVirtualScrolling, ...rest } = args; const tableContainerRef = useRef(null); + const tableData = useState(() => data)[0]; const table = useLeafyGreenTable({ - data, + data: tableData, columns, containerRef: tableContainerRef, + useVirtualScrolling, }); - return ; + return ; }; interface CellProps { diff --git a/src/components/Table/BaseTable.tsx b/src/components/Table/BaseTable.tsx index 06fb85aa67..afb823447f 100644 --- a/src/components/Table/BaseTable.tsx +++ b/src/components/Table/BaseTable.tsx @@ -1,3 +1,4 @@ +import { ForwardedRef, forwardRef } from "react"; import styled from "@emotion/styled"; import { css } from "@leafygreen-ui/emotion"; import { @@ -12,6 +13,8 @@ import { TableBody, type TableProps, TableHead, + VirtualItem, + LeafyGreenTableRow, } from "@leafygreen-ui/table"; import { RowData } from "@tanstack/react-table"; import { @@ -53,125 +56,149 @@ type SpruceTableProps = { loadingRows?: number; }; -export const BaseTable = ({ - "data-cy-row": dataCyRow, - "data-cy-table": dataCyTable, - emptyComponent, - loading, - loadingRows = 5, - table, - ...args -}: SpruceTableProps & TableProps) => ( - <> - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - const { columnDef } = header.column ?? {}; - const { meta } = columnDef; - return ( - - {flexRender(columnDef.header, header.getContext())} - {header.column.getCanFilter() && - (meta?.treeSelect ? ( - - header.column.setFilterValue(value) - } - options={ - meta.treeSelect?.filterOptions - ? meta.treeSelect.options.filter( - ({ value }) => - !!header.column - .getFacetedUniqueValues() - .get(value) - ) - : meta.treeSelect.options - } - value={ - (header?.column?.getFilterValue() as string[]) ?? [] - } - /> - ) : ( - - header.column.setFilterValue(value) - } - placeholder={meta?.search?.placeholder} - value={ - (header?.column?.getFilterValue() as string) ?? "" - } - /> - ))} - - ); - })} - - ))} - - - {loading && ( - - )} - {table.getRowModel().rows.map((row) => ( - div { - max-height: unset; - } - `} - > - {row.getVisibleCells().map((cell) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} - +export const BaseTable = forwardRef( + ( + { + "data-cy-row": dataCyRow, + "data-cy-table": dataCyTable, + emptyComponent, + loading, + loadingRows = 5, + table, + ...args + }: SpruceTableProps & TableProps, + ref: ForwardedRef + ) => { + const { virtualRows } = table; + const { rows } = table.getRowModel(); + const hasVirtualRows = virtualRows && virtualRows.length > 0; + + return ( + <> + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + const { columnDef } = header.column ?? {}; + const { meta } = columnDef; + return ( + + {flexRender(columnDef.header, header.getContext())} + {header.column.getCanFilter() && + (meta?.treeSelect ? ( + + header.column.setFilterValue(value) + } + options={ + meta.treeSelect?.filterOptions + ? meta.treeSelect.options.filter( + ({ value }) => + !!header.column + .getFacetedUniqueValues() + .get(value) + ) + : meta.treeSelect.options + } + value={ + (header?.column?.getFilterValue() as string[]) ?? + [] + } + /> + ) : ( + + header.column.setFilterValue(value) + } + placeholder={meta?.search?.placeholder} + value={ + (header?.column?.getFilterValue() as string) ?? "" + } + /> + ))} + + ); + })} + ))} - {row.original.renderExpandedContent && ( - + + + {loading && ( + )} - {row.subRows && - row.subRows.map((subRow) => ( - div[data-state="entered"] { - max-height: unset; - } - `} - > - {subRow.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} - - ))} - - ))} - - ))} - - + {hasVirtualRows + ? virtualRows.map((vr) => { + const row = rows[vr.index]; + return ( + + ); + }) + : rows.map((row) => ( + + ))} + + + {!loading && + rows.length === 0 && + (emptyComponent || "No data to display")} + + ); + } +); - {!loading && - table.getRowModel().rows.length === 0 && - (emptyComponent || "No data to display")} - +const RenderableRow = ({ + row, + virtualRow, +}: { + row: LeafyGreenTableRow; + virtualRow: VirtualItem; +}) => ( + div { + max-height: unset; + } + `} + virtualRow={virtualRow} + > + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + {row.original.renderExpandedContent && } + {row.subRows && + row.subRows.map((subRow) => ( + div[data-state="entered"] { + max-height: unset; + } + `} + virtualRow={virtualRow} + > + {subRow.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + ))} + ); const StyledTable = styled(Table)` diff --git a/src/gql/generated/types.ts b/src/gql/generated/types.ts index ae8b0f91b9..1e9c899952 100644 --- a/src/gql/generated/types.ts +++ b/src/gql/generated/types.ts @@ -364,6 +364,7 @@ export type DisplayTask = { /** Distro models an environment configuration for a host. */ export type Distro = { __typename?: "Distro"; + adminOnly: Scalars["Boolean"]["output"]; aliases: Array; arch: Arch; authorizedKeysFile: Scalars["String"]["output"]; @@ -429,6 +430,8 @@ export type DistroInfo = { }; export type DistroInput = { + /** TODO: require adminOnly field upon completion of DEVPROD-3533 */ + adminOnly?: InputMaybe; aliases: Array; arch: Arch; authorizedKeysFile: Scalars["String"]["input"]; @@ -2786,11 +2789,13 @@ export type TestFilterOptions = { export type TestLog = { __typename?: "TestLog"; lineNum?: Maybe; + renderingType?: Maybe; url?: Maybe; /** @deprecated Use urlParsley instead */ urlLobster?: Maybe; urlParsley?: Maybe; urlRaw?: Maybe; + version?: Maybe; }; export type TestResult = {