diff --git a/docs/docs-content/release-notes.md b/docs/docs-content/release-notes.md index 4a618fd60f..dd93b915d7 100644 --- a/docs/docs-content/release-notes.md +++ b/docs/docs-content/release-notes.md @@ -9,6 +9,8 @@ sidebar_custom_props: tags: ["release-notes"] --- + + ## Feb 26, 2024 - Release 4.2.13 ### Bug Fixes diff --git a/package-lock.json b/package-lock.json index 5d54c4cbe9..3acd7259b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "prism-react-renderer": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-select": "^5.8.0", "sass": "^1.64.1" }, "devDependencies": { @@ -3312,14 +3313,145 @@ "node": ">=18.0" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/@emotion/hash": { "version": "0.8.0", "license": "MIT" }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/serialize/node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, "node_modules/@emotion/unitless": { "version": "0.7.5", "license": "MIT" }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "devOptional": true, @@ -3441,6 +3573,28 @@ "version": "1.3.0", "license": "MIT" }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "6.5.1", "hasInstallScript": true, @@ -6682,6 +6836,14 @@ "@types/react-router": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/retry": { "version": "0.12.0", "license": "MIT" @@ -12953,6 +13115,15 @@ "utila": "~0.4" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "2.0.0", "license": "MIT", @@ -17277,6 +17448,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "license": "MIT", @@ -29010,6 +29186,11 @@ "node": ">= 4.0.0" } }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, "node_modules/meow": { "version": "8.1.2", "license": "MIT", @@ -54919,6 +55100,41 @@ "version": "16.13.1", "license": "MIT" }, + "node_modules/react-select": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz", + "integrity": "sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.1.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/react-waypoint": { "version": "10.3.0", "license": "MIT", @@ -64646,6 +64862,19 @@ "react": ">= 16.8.0" } }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/util": { "version": "0.12.5", "license": "MIT", diff --git a/package.json b/package.json index b3cec5d94e..a0b2765da1 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "prism-react-renderer": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-select": "^5.8.0", "sass": "^1.64.1" }, "devDependencies": { diff --git a/src/components/ReleaseNotesVersions/ReleaseNotesVersions.module.scss b/src/components/ReleaseNotesVersions/ReleaseNotesVersions.module.scss new file mode 100644 index 0000000000..f8d272fb0e --- /dev/null +++ b/src/components/ReleaseNotesVersions/ReleaseNotesVersions.module.scss @@ -0,0 +1,12 @@ +.dropdownContainer { + display: flex; + justify-content: center; +} + +.dropdownContainer > div:first-child { + width: 50%; + + @media (max-width: 768px) { + width: 100%; + } +} diff --git a/src/components/ReleaseNotesVersions/ReleaseNotesVersions.test.tsx b/src/components/ReleaseNotesVersions/ReleaseNotesVersions.test.tsx new file mode 100644 index 0000000000..cd455f989e --- /dev/null +++ b/src/components/ReleaseNotesVersions/ReleaseNotesVersions.test.tsx @@ -0,0 +1,25 @@ +import React from "react"; +import { render, screen, logRoles } from "@testing-library/react"; +import ReleaseNotesVersions from "./ReleaseNotesVersions"; + +// These test are pretty much useless. +// The only real purpose they show is catching simple issues, or component signature changes. + +jest.mock("./ReleaseNotesVersions", () => { + return jest.fn(() => { + return
; + }); +}); +// Mock any other dependencies here + +describe("ReleaseNotesVersions", () => { + it("renders without crashing", () => { + render(); + expect(screen.getByTestId("mock-rl-note-admn")).toBeVisible(); + expect(screen.getByTestId("mock-rl-note-admn")).toBeInTheDocument(); + }); +}); + +afterEach(() => { + jest.clearAllMocks(); +}); diff --git a/src/components/ReleaseNotesVersions/ReleaseNotesVersions.tsx b/src/components/ReleaseNotesVersions/ReleaseNotesVersions.tsx new file mode 100644 index 0000000000..182f27eb53 --- /dev/null +++ b/src/components/ReleaseNotesVersions/ReleaseNotesVersions.tsx @@ -0,0 +1,145 @@ +/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return */ + +import React, { useEffect, useState } from "react"; +import { useHistory } from "@docusaurus/router"; +import Admonition from "@theme/Admonition"; +import { useVersions } from "@docusaurus/plugin-content-docs/client"; +import styles from "./ReleaseNotesVersions.module.scss"; +import ArchivedVersions from "../../../archiveVersions.json"; +import Select, { components, OptionProps } from "react-select"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons"; +import useIsBrowser from "@docusaurus/useIsBrowser"; + +interface VersionOption { + label: string; + value: string; + url: string; + isExternal: boolean; +} + +const externalDomainURL = "legacy.docs.spectrocloud.com"; + +interface CustomOptionProps extends OptionProps {} + +const CustomOption: React.FC = (props) => { + const { + data: { label, isExternal }, + } = props; + + // Return the Option component with proper props spread and conditional rendering + return ( + + {label} + {isExternal && } + + ); +}; + +export function ReleaseNotesVersions(): JSX.Element | null { + const [selectedVersion, setSelectedVersion] = useState(null); + const history = useHistory(); + const isBrowser = useIsBrowser(); + const isExternal = isBrowser && isExternalDomain(externalDomainURL, isBrowser); + + const versionsList = useVersions("default"); + + const versions: VersionOption[] = [ + ...versionsList.map(({ label, path }) => ({ + label: label === "current" ? "latest" : label, + value: label, + url: path === "/" ? "/release-notes" : `${path}/release-notes`, + isExternal: path.startsWith("http"), + })), + ...Object.entries(ArchivedVersions).map(([versionName, versionUrl]) => ({ + label: `${versionName} `, + value: `${versionName} `, + url: versionUrl, + isExternal: versionUrl.startsWith("http"), + })), + ]; + + if (isExternal) { + return <>; + } + + useEffect(() => { + const savedVersion = localStorage.getItem("selectedVersion"); + if (savedVersion) { + const savedVersionObj: any = versions.find((v) => v.value === savedVersion); + if (savedVersionObj?.value !== selectedVersion?.value) { + setSelectedVersion(savedVersionObj); + } + } + }, [selectedVersion?.value]); + + const handleVersionChange = (selectedOption: VersionOption | null) => { + setSelectedVersion(selectedOption); + localStorage.setItem("selectedVersion", selectedOption?.value ?? ""); + + if (selectedOption?.isExternal) { + window.open(selectedOption.url, "_blank"); + } else { + history.push(selectedOption?.url ?? ""); + } + }; + + const customSelectStyles = { + control: (provided: any) => ({ + ...provided, + background: "var(--custom-release-notes-background-color)", + color: "var(--custom-release-notes-background-font-color)", + boxShadow: "none", + }), + menu: (provided: any) => ({ + ...provided, + marginTop: "0", + backgroundColor: "var(--custom-release-notes-menu-padding)", + }), + singleValue: (provided: any) => ({ + ...provided, + color: "var(--custom-release-notes-background-font-color)", + }), + option: (provided: any, state: any) => ({ + ...provided, + borderRadius: "0.25rem", + color: "var(--custom-release-notes-option-font-color)", + background: state.isSelected + ? "var(--custom-release-notes-selected-background)" + : state.isFocused + ? "var(--custom-release-notes-active-option-hover)" + : "var(--custom-release-notes-background-color)", + }), + }; + + return ( + +

+ Are you looking for the release notes to a specific version of Palette? Use the version selector below to + navigate to the release notes of the desired version. +

+
+