From c1882af738c3e23fe9c6e748c729bcf9e55e198e Mon Sep 17 00:00:00 2001 From: Cafer Elgin Date: Sun, 22 Dec 2024 23:05:23 +0200 Subject: [PATCH 1/9] feat: Confluence plugin supports multiple pages --- .../src/components/PageContent.tsx | 121 ++- .../confluence-plugin/src/lib/parseEntity.ts | 19 +- plugins/confluence-plugin/src/typings.d.ts | 5 + yarn.lock | 998 +++++++++++------- 4 files changed, 707 insertions(+), 436 deletions(-) diff --git a/plugins/confluence-plugin/src/components/PageContent.tsx b/plugins/confluence-plugin/src/components/PageContent.tsx index 88eeebf..fe9a06e 100644 --- a/plugins/confluence-plugin/src/components/PageContent.tsx +++ b/plugins/confluence-plugin/src/components/PageContent.tsx @@ -1,5 +1,5 @@ import type React from "react"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useCallback } from "react"; import { isEmpty, isNil } from "lodash"; import "../baseStyles.css"; import { @@ -13,6 +13,7 @@ import { getConfluenceDetailsFromEntity } from "../lib/parseEntity"; import Instructions from "./Instructions"; const PageContent: React.FC = () => { + const [entityPages, setEntityPages] = useState([]); const [pageContent, setPageContent] = useState(); const [pageTitle, setPageTitle] = useState(); const [entityPage, setEntityPage] = useState(); @@ -21,6 +22,49 @@ const PageContent: React.FC = () => { const context = usePluginContext(); + const fetchPageContent = useCallback( + async (pages: EntityPageI[], pageId: string | number): Promise => { + if (pages.length === 0) { + return; + } + setEntityPage(pageId); + const jiraURL = `${baseConfluenceUrl}/wiki/rest/api/content/${pageId}?expand=body.view`; + setErrorStr("loading"); + const contentResult = await fetch(jiraURL); + if (!contentResult.ok) { + let newErrorStr = ""; + // if the contentResult contains valid JSON, we can use it to display an error message + try { + if ( + contentResult.headers + .get("content-type") + ?.includes("application/json") + ) { + const contentJSON = await contentResult.json(); + const msg: string = + contentJSON.message || JSON.stringify(contentJSON); + newErrorStr = `Failed to fetch Confluence page with ID ${pageId}: ${msg}`; + } else { + // just get the text if it's not JSON + const contentText = await contentResult.text(); + newErrorStr = contentText; + } + } catch (e) { + // if we can't parse the content, just use the status text + newErrorStr = + contentResult.statusText || "Failed to fetch Confluence page"; + } + setErrorStr(newErrorStr); + return; + } + const contentJSON = await contentResult.json(); + setPageContent(contentJSON.body.view.value); + setPageTitle(contentJSON.title); + setErrorStr(""); + }, + [baseConfluenceUrl] + ); + useEffect(() => { if (!context?.apiBaseUrl) { return; @@ -55,46 +99,14 @@ const PageContent: React.FC = () => { if (!isNil(entityTag)) { try { const yaml = await getEntityYaml(context.apiBaseUrl, entityTag); - const pageID = isEmpty(yaml) - ? undefined + const fetchedEntityPages = isEmpty(yaml) + ? [] : getConfluenceDetailsFromEntity(yaml); - if (!pageID?.pageID) { + if (fetchedEntityPages.length === 0) { setErrorStr("No Confluence details exist on this entity."); return; } - setEntityPage(pageID?.pageID); - const jiraURL = `${baseConfluenceUrl}/wiki/rest/api/content/${pageID.pageID}?expand=body.view`; - const contentResult = await fetch(jiraURL); - if (!contentResult.ok) { - let newErrorStr = ""; - // if the contentResult contains valid JSON, we can use it to display an error message - try { - if ( - contentResult.headers - .get("content-type") - ?.includes("application/json") - ) { - const contentJSON = await contentResult.json(); - const msg: string = - contentJSON.message || JSON.stringify(contentJSON); - newErrorStr = `Failed to fetch Confluence page with ID ${pageID.pageID}: ${msg}`; - } else { - // just get the text if it's not JSON - const contentText = await contentResult.text(); - newErrorStr = contentText; - } - } catch (e) { - // if we can't parse the content, just use the status text - newErrorStr = - contentResult.statusText || "Failed to fetch Confluence page"; - } - setErrorStr(newErrorStr); - return; - } - const contentJSON = await contentResult.json(); - setPageContent(contentJSON.body.view.value); - setPageTitle(contentJSON.title); - setErrorStr(""); + setEntityPages(fetchedEntityPages); } catch (e) { // This will still result in a "We could not find any Confluence page" error in the UI, but may as well trap in console as well const msg: string = e.message || e.toString(); @@ -106,6 +118,16 @@ const PageContent: React.FC = () => { void fetchEntityYaml(); }, [context.apiBaseUrl, context.entity?.tag, baseConfluenceUrl]); + useEffect(() => { + const setFirstPageContent = async (): Promise => { + if (entityPages.length === 0) { + return; + } + await fetchPageContent(entityPages, entityPages[0].id); + }; + void setFirstPageContent(); + }, [baseConfluenceUrl, entityPages, fetchPageContent]); + if (errorStr === "loading") { return
Loading...
; } else if (errorStr === "instructions") { @@ -130,6 +152,31 @@ const PageContent: React.FC = () => { return (
+ {entityPages.length > 1 && ( +
+ +
+ )}

diff --git a/plugins/confluence-plugin/src/lib/parseEntity.ts b/plugins/confluence-plugin/src/lib/parseEntity.ts index 54584c0..427832a 100644 --- a/plugins/confluence-plugin/src/lib/parseEntity.ts +++ b/plugins/confluence-plugin/src/lib/parseEntity.ts @@ -1,11 +1,18 @@ export const getConfluenceDetailsFromEntity = ( entity: Record -): { pageID: string } | undefined => { - const pageID = entity.info["x-cortex-confluence"]?.pageID; - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (!pageID) { - return undefined; +): EntityPageI[] => { + const confluenceInfo = entity.info["x-cortex-confluence"]; + if (!confluenceInfo) { + return []; } - return { pageID }; + if (Array.isArray(confluenceInfo.pages) && confluenceInfo.pages.length > 0) { + return confluenceInfo.pages; + } + + if (typeof confluenceInfo.pageID !== "undefined") { + return [{ id: confluenceInfo.pageID }]; + } + + return []; }; diff --git a/plugins/confluence-plugin/src/typings.d.ts b/plugins/confluence-plugin/src/typings.d.ts index 1a3dd3c..ff6b93e 100644 --- a/plugins/confluence-plugin/src/typings.d.ts +++ b/plugins/confluence-plugin/src/typings.d.ts @@ -2,3 +2,8 @@ declare module "*.svg" { const content: any; export default content; } + +interface EntityPageI { + id: string | number; + title?: string; +} diff --git a/yarn.lock b/yarn.lock index 1ba3a62..88f0a9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32,7 +32,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz" integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.21.3", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.8.0": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.21.3": version "7.22.9" resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz" integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== @@ -999,21 +999,7 @@ resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.0.0": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.1.2": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.10.1": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.15.4", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.10", "@babel/runtime@^7.4.4", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3": version "7.22.15" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== @@ -1027,52 +1013,10 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/runtime@^7.15.4": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.21.0": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.22.10": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.4.4": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.6.0": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.7.6": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.8.3": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== +"@babel/runtime@^7.12.13": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== dependencies: regenerator-runtime "^0.14.0" @@ -1213,6 +1157,76 @@ resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@chakra-ui/anatomy@2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.3.5.tgz#41da569971ef7224aa2f01312c541469b69adbf8" + integrity sha512-3im33cUOxCbISjaBlINE2u8BOwJSCdzpjCX0H+0JxK2xz26UaVA5xeI3NYHUoxDnr/QIrgfrllGxS0szYwOcyg== + +"@chakra-ui/hooks@2.4.3": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-2.4.3.tgz#f28ebd749bbbea050fe750b526e0ec568374ff9e" + integrity sha512-Sr2zsoTZw3p7HbrUy4aLpTIkE2XXUelAUgg3NGwMzrmx75bE0qVyiuuTFOuyEzGxYVV2Fe8QtcKKilm6RwzTGg== + dependencies: + "@chakra-ui/utils" "2.2.3" + "@zag-js/element-size" "0.31.1" + copy-to-clipboard "3.3.3" + framesync "6.1.2" + +"@chakra-ui/icons@^2.2.4": + version "2.2.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/icons/-/icons-2.2.4.tgz#fc3f59a7e377d6e4efdbe8ee0a3aec7f29a4ab32" + integrity sha512-l5QdBgwrAg3Sc2BRqtNkJpfuLw/pWRDwwT58J6c4PqQT6wzXxyNa8Q0PForu1ltB5qEiFb1kxr/F/HO1EwNa6g== + +"@chakra-ui/react@2", "@chakra-ui/react@^2.10.2": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.10.4.tgz#3f9aa815d1f52e91961c22b0297d2fbe53fdcd99" + integrity sha512-XyRWnuZ1Uw7Mlj5pKUGO5/WhnIHP/EOrpy6lGZC1yWlkd0eIfIpYMZ1ALTZx4KPEdbBaes48dgiMT2ROCqLhkA== + dependencies: + "@chakra-ui/hooks" "2.4.3" + "@chakra-ui/styled-system" "2.12.1" + "@chakra-ui/theme" "3.4.7" + "@chakra-ui/utils" "2.2.3" + "@popperjs/core" "^2.11.8" + "@zag-js/focus-visible" "^0.31.1" + aria-hidden "^1.2.3" + react-fast-compare "3.2.2" + react-focus-lock "^2.9.6" + react-remove-scroll "^2.5.7" + +"@chakra-ui/styled-system@2.12.1": + version "2.12.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.12.1.tgz#3daeb48e77363db05d6737e8bf3257d8ceccf63b" + integrity sha512-DQph1nDiCPtgze7nDe0a36530ByXb5VpPosKGyWMvKocVeZJcDtYG6XM0+V5a0wKuFBXsViBBRIFUTiUesJAcg== + dependencies: + "@chakra-ui/utils" "2.2.3" + csstype "^3.1.2" + +"@chakra-ui/theme-tools@2.2.7": + version "2.2.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-2.2.7.tgz#cf3d47cd38615add61e9d5e7caed685303be7f29" + integrity sha512-K/VJd0QcnKik7m+qZTkggqNLep6+MPUu8IP5TUpHsnSM5R/RVjsJIR7gO8IZVAIMIGLLTIhGshHxeMekqv6LcQ== + dependencies: + "@chakra-ui/anatomy" "2.3.5" + "@chakra-ui/utils" "2.2.3" + color2k "^2.0.2" + +"@chakra-ui/theme@3.4.7": + version "3.4.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-3.4.7.tgz#3d52cd1c865f0a7f614f9dfa41fceb6934b7869a" + integrity sha512-pfewthgZTFNUYeUwGvhPQO/FTIyf375cFV1AT8N1y0aJiw4KDe7YTGm7p0aFy4AwAjH2ydMgeEx/lua4tx8qyQ== + dependencies: + "@chakra-ui/anatomy" "2.3.5" + "@chakra-ui/theme-tools" "2.2.7" + "@chakra-ui/utils" "2.2.3" + +"@chakra-ui/utils@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-2.2.3.tgz#4b08adcbb1a38078317fcce106f56b8c47b76ee5" + integrity sha512-cldoCQuexZ6e07/9hWHKD4l1QXXlM1Nax9tuQOBvVf/EgwNZt3nZu8zZRDFlhAOKCTQDkmpLTTu+eXXjChNQOw== + dependencies: + "@types/lodash.mergewith" "4.6.9" + lodash.mergewith "4.6.2" + "@cortexapps/plugin-core@^2.0.0": version "2.1.2" resolved "https://registry.npmjs.org/@cortexapps/plugin-core/-/plugin-core-2.1.2.tgz" @@ -1261,7 +1275,7 @@ react-toggle "^4.1.3" reactstrap "^9.2.0" -"@date-io/core@^1.3.13", "@date-io/core@1.x": +"@date-io/core@1.x", "@date-io/core@^1.3.13": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/core/-/core-1.3.13.tgz" integrity sha512-AlEKV7TxjeK+jxWVKcCFrfYAk8spX9aCyiToFIiLPtfQbsjmRGLIhb5VZgptQcJdHtLXo7+m0DuurwFgUToQuA== @@ -1295,6 +1309,23 @@ source-map "^0.5.7" stylis "4.2.0" +"@emotion/babel-plugin@^11.13.5": + version "11.13.5" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz#eab8d65dbded74e0ecfd28dc218e75607c4e7bc0" + integrity sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.2" + "@emotion/memoize" "^0.9.0" + "@emotion/serialize" "^1.3.3" + 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" + "@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0": version "11.11.0" resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz" @@ -1306,6 +1337,17 @@ "@emotion/weak-memoize" "^0.3.1" stylis "4.2.0" +"@emotion/cache@^11.14.0": + version "11.14.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.14.0.tgz#ee44b26986eeb93c8be82bb92f1f7a9b21b2ed76" + integrity sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA== + dependencies: + "@emotion/memoize" "^0.9.0" + "@emotion/sheet" "^1.4.0" + "@emotion/utils" "^1.4.2" + "@emotion/weak-memoize" "^0.4.0" + stylis "4.2.0" + "@emotion/hash@^0.8.0": version "0.8.0" resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz" @@ -1316,6 +1358,11 @@ resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz" integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== +"@emotion/hash@^0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b" + integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== + "@emotion/is-prop-valid@^1.2.1": version "1.2.1" resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz" @@ -1323,12 +1370,24 @@ dependencies: "@emotion/memoize" "^0.8.1" +"@emotion/is-prop-valid@^1.3.0": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz#8d5cf1132f836d7adbe42cf0b49df7816fc88240" + integrity sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw== + dependencies: + "@emotion/memoize" "^0.9.0" + "@emotion/memoize@^0.8.1": version "0.8.1" resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz" integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== -"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.10.5", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0", "@emotion/react@^11.8.1": +"@emotion/memoize@^0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.9.0.tgz#745969d649977776b43fc7648c556aaa462b4102" + integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== + +"@emotion/react@^11.10.5", "@emotion/react@^11.8.1": version "11.11.1" resolved "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz" integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== @@ -1342,6 +1401,20 @@ "@emotion/weak-memoize" "^0.3.1" hoist-non-react-statics "^3.3.1" +"@emotion/react@^11.13.3": + version "11.14.0" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.14.0.tgz#cfaae35ebc67dd9ef4ea2e9acc6cd29e157dd05d" + integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.13.5" + "@emotion/cache" "^11.14.0" + "@emotion/serialize" "^1.3.3" + "@emotion/use-insertion-effect-with-fallbacks" "^1.2.0" + "@emotion/utils" "^1.4.2" + "@emotion/weak-memoize" "^0.4.0" + hoist-non-react-statics "^3.3.1" + "@emotion/serialize@^1.1.2": version "1.1.2" resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz" @@ -1353,12 +1426,28 @@ "@emotion/utils" "^1.2.1" csstype "^3.0.2" +"@emotion/serialize@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.3.tgz#d291531005f17d704d0463a032fe679f376509e8" + integrity sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA== + dependencies: + "@emotion/hash" "^0.9.2" + "@emotion/memoize" "^0.9.0" + "@emotion/unitless" "^0.10.0" + "@emotion/utils" "^1.4.2" + csstype "^3.0.2" + "@emotion/sheet@^1.2.2": 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== -"@emotion/styled@^11.10.5", "@emotion/styled@^11.3.0": +"@emotion/sheet@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c" + integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== + +"@emotion/styled@^11.10.5": version "11.11.0" resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz" integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== @@ -1370,6 +1459,23 @@ "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" "@emotion/utils" "^1.2.1" +"@emotion/styled@^11.13.0": + version "11.14.0" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.14.0.tgz#f47ca7219b1a295186d7661583376fcea95f0ff3" + integrity sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.13.5" + "@emotion/is-prop-valid" "^1.3.0" + "@emotion/serialize" "^1.3.3" + "@emotion/use-insertion-effect-with-fallbacks" "^1.2.0" + "@emotion/utils" "^1.4.2" + +"@emotion/unitless@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.10.0.tgz#2af2f7c7e5150f497bdabd848ce7b218a27cf745" + integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg== + "@emotion/unitless@^0.8.1": version "0.8.1" resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz" @@ -1380,16 +1486,31 @@ 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== +"@emotion/use-insertion-effect-with-fallbacks@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz#8a8cb77b590e09affb960f4ff1e9a89e532738bf" + integrity sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg== + "@emotion/utils@^1.2.1": version "1.2.1" resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz" integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== +"@emotion/utils@^1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.2.tgz#6df6c45881fcb1c412d6688a311a98b7f59c1b52" + integrity sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA== + "@emotion/weak-memoize@^0.3.1": version "0.3.1" resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz" integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== +"@emotion/weak-memoize@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6" + integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -1679,19 +1800,7 @@ jest-mock "^29.6.2" jest-util "^29.6.2" -"@jest/fake-timers@^29.6.3": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz" - integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== - dependencies: - "@jest/types" "^29.6.3" - "@sinonjs/fake-timers" "^10.0.2" - "@types/node" "*" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -"@jest/fake-timers@^29.7.0": +"@jest/fake-timers@^29.6.3", "@jest/fake-timers@^29.7.0": version "29.7.0" resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz" integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== @@ -1938,16 +2047,16 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - "@jridgewell/sourcemap-codec@1.4.14": version "1.4.14" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": version "0.3.18" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz" @@ -1979,7 +2088,7 @@ react-double-scrollbar "0.0.15" uuid "^3.4.0" -"@material-ui/core@^4.0.0", "@material-ui/core@^4.11.2", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2", "@material-ui/core@^4.12.4": +"@material-ui/core@^4.12.2", "@material-ui/core@^4.12.4": version "4.12.4" resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.12.4.tgz" integrity sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ== @@ -2168,7 +2277,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -2257,7 +2366,7 @@ "@octokit/request-error" "^5.0.0" "@octokit/types" "^12.0.0" -"@octokit/core@^5.0.0", "@octokit/core@>=5": +"@octokit/core@^5.0.0": version "5.0.1" resolved "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz" integrity sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw== @@ -2447,17 +2556,17 @@ "@octokit/webhooks-types" "7.1.0" aggregate-error "^3.1.0" -"@phosphor-icons/react@^2.0.9": - version "2.0.13" - resolved "https://registry.npmjs.org/@phosphor-icons/react/-/react-2.0.13.tgz" - integrity sha512-lRjFfCv4pU8vDnPgZ8/QFzYmAJS08Vx+J2/+Ldh217pXaxvaayBZMC/3EinuMwmMylc97+XYCMPdH+y10I+f0g== - "@phosphor-icons/react@2.0.9": version "2.0.9" resolved "https://registry.npmjs.org/@phosphor-icons/react/-/react-2.0.9.tgz" integrity sha512-/dtQ0M9MXAr35wy8zPlwF684EvYRvGWZPAv+Bd0BR4vzIhjzfLBdHSovFxSP1rj3UOHvVR08qgRL04Kv90oqHA== -"@popperjs/core@^2.0.0", "@popperjs/core@^2.11.7", "@popperjs/core@^2.11.8", "@popperjs/core@^2.6.0": +"@phosphor-icons/react@^2.0.9": + version "2.0.13" + resolved "https://registry.npmjs.org/@phosphor-icons/react/-/react-2.0.13.tgz" + integrity sha512-lRjFfCv4pU8vDnPgZ8/QFzYmAJS08Vx+J2/+Ldh217pXaxvaayBZMC/3EinuMwmMylc97+XYCMPdH+y10I+f0g== + +"@popperjs/core@^2.11.8", "@popperjs/core@^2.6.0": version "2.11.8" resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== @@ -2503,7 +2612,52 @@ resolved "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.83.tgz" integrity sha512-Plz2IKeveVLivbXTSCC3OZjD2MojyKYllhPrn9RotkDIZEFRYJZtW5/Ik1tJW/2rzu5HVKuGYrDKdScVVTbOxQ== -"@swc/core@*", "@swc/core@^1.3.83": +"@swc/core-darwin-x64@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.83.tgz#45c2d73843e5e2e34e6e9b8e5fd6e19b419b75ae" + integrity sha512-FBGVg5IPF/8jQ6FbK60iDUHjv0H5+LwfpJHKH6wZnRaYWFtm7+pzYgreLu3NTsm3m7/1a7t0+7KURwBGUaJCCw== + +"@swc/core-linux-arm-gnueabihf@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.83.tgz#3dcee525f6667dd92db0640991a3f03764b76dea" + integrity sha512-EZcsuRYhGkzofXtzwDjuuBC/suiX9s7zeg2YYXOVjWwyebb6BUhB1yad3mcykFQ20rTLO9JUyIaiaMYDHGobqw== + +"@swc/core-linux-arm64-gnu@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.83.tgz#3521c8b2f05a5d0348e538af3a5742d607ad6a8d" + integrity sha512-khI41szLHrCD/cFOcN4p2SYvZgHjhhHlcMHz5BksRrDyteSJKu0qtWRZITVom0N/9jWoAleoFhMnFTUs0H8IWA== + +"@swc/core-linux-arm64-musl@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.83.tgz#2c16d47e036176591761187455d4c2c4d984c14c" + integrity sha512-zgT7yNOdbjHcGAwvys79mbfNLK65KBlPJWzeig+Yk7I8TVzmaQge7B6ZS/gwF9/p+8TiLYo/tZ5aF2lqlgdSVw== + +"@swc/core-linux-x64-gnu@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.83.tgz#2eb0222eafeb247b9d1715f106e312566160bca1" + integrity sha512-x+mH0Y3NC/G0YNlFmGi3vGD4VOm7IPDhh+tGrx6WtJp0BsShAbOpxtfU885rp1QweZe4qYoEmGqiEjE2WrPIdA== + +"@swc/core-linux-x64-musl@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.83.tgz#8c4edd4754410cfe662a112a92f0c71d4fbf070a" + integrity sha512-s5AYhAOmetUwUZwS5g9qb92IYgNHHBGiY2mTLImtEgpAeBwe0LPDj6WrujxCBuZnaS55mKRLLOuiMZE5TpjBNA== + +"@swc/core-win32-arm64-msvc@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.83.tgz#153ef6fc6e41e33a47f9f1524fe6bad2fc0158b3" + integrity sha512-yw2rd/KVOGs95lRRB+killLWNaO1dy4uVa8Q3/4wb5txlLru07W1m041fZLzwOg/1Sh0TMjJgGxj0XHGR3ZXhQ== + +"@swc/core-win32-ia32-msvc@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.83.tgz#7757277e8618a638cb89e51a1e0959417eec6441" + integrity sha512-POW+rgZ6KWqBpwPGIRd2/3pcf46P+UrKBm4HLt5IwbHvekJ4avIM8ixJa9kK0muJNVJcDpaZgxaU1ELxtJ1j8w== + +"@swc/core-win32-x64-msvc@1.3.83": + version "1.3.83" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.83.tgz#92da90b84a9b88fdd92b6d1256fd6608e668541f" + integrity sha512-CiWQtkFnZElXQUalaHp+Wacw0Jd+24ncRYhqaJ9YKnEQP1H82CxIIuQqLM8IFaLpn5dpY6SgzaeubWF46hjcLA== + +"@swc/core@^1.3.83": version "1.3.83" resolved "https://registry.npmjs.org/@swc/core/-/core-1.3.83.tgz" integrity sha512-PccHDgGQlFjpExgJxH91qA3a4aifR+axCFJ4RieCoiI0m5gURE4nBhxzTBY5YU/YKTBmPO8Gc5Q6inE3+NquWg== @@ -2800,6 +2954,18 @@ dependencies: "@types/node" "*" +"@types/lodash.mergewith@4.6.9": + version "4.6.9" + resolved "https://registry.yarnpkg.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.9.tgz#7093028a36de3cae4495d03b9d92c351cab1f8bf" + integrity sha512-fgkoCAOF47K7sxrQ7Mlud2TH023itugZs2bUg8h/KzT+BnZNrR2jAOmaokbLunHNnobXVWOezAeNn/lZqwxkcw== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb" + integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg== + "@types/lodash@^4.14.197": version "4.14.197" resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz" @@ -2897,7 +3063,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.13.1 || ^17.0.0", "@types/react@^16.8.6 || ^17.0.0", "@types/react@^17.0.0 || ^18.0.0", "@types/react@^18.0.28": +"@types/react@*", "@types/react@^18.0.28": version "18.2.16" resolved "https://registry.npmjs.org/@types/react/-/react-18.2.16.tgz" integrity sha512-LLFWr12ZhBJ4YVw7neWLe6Pk7Ey5R9OCydfuMsz1L8bZxzaawJj2p06Q8/EFEHDeTBQNFLF62X+CG7B2zIyu0Q== @@ -2906,8 +3072,10 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/react@>=16": - version "17.0.80" +"@types/react@^16.13.1 || ^17.0.0": + version "17.0.83" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.83.tgz#b477c56387b74279281149dcf5ba2a1e2216d131" + integrity sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw== dependencies: "@types/prop-types" "*" "@types/scheduler" "^0.16" @@ -2925,6 +3093,8 @@ "@types/scheduler@^0.16": version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== "@types/semver@^7.3.12": version "7.5.0" @@ -3022,7 +3192,7 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.0.0", "@typescript-eslint/eslint-plugin@^5.43.0": +"@typescript-eslint/eslint-plugin@^5.0.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz" integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== @@ -3038,7 +3208,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.43.0", "@typescript-eslint/parser@^5.55.0": +"@typescript-eslint/parser@^5.43.0", "@typescript-eslint/parser@^5.55.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz" integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== @@ -3106,7 +3276,7 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" -"@webassemblyjs/ast@^1.11.5", "@webassemblyjs/ast@1.11.6": +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": version "1.11.6" resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz" integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== @@ -3207,7 +3377,7 @@ "@webassemblyjs/wasm-gen" "1.11.6" "@webassemblyjs/wasm-parser" "1.11.6" -"@webassemblyjs/wasm-parser@^1.11.5", "@webassemblyjs/wasm-parser@1.11.6": +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": version "1.11.6" resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz" integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== @@ -3257,6 +3427,23 @@ resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +"@zag-js/dom-query@0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@zag-js/dom-query/-/dom-query-0.31.1.tgz#f40be43d0eb1eabdf51538abeeccad46c5b88ed6" + integrity sha512-oiuohEXAXhBxpzzNm9k2VHGEOLC1SXlXSbRPcfBZ9so5NRQUA++zCE7cyQJqGLTZR0t3itFLlZqDbYEXRrefwg== + +"@zag-js/element-size@0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.31.1.tgz#1b3d237618d12b00c0a7dd8e33e29fb8f8cd4f0c" + integrity sha512-4T3yvn5NqqAjhlP326Fv+w9RqMIBbNN9H72g5q2ohwzhSgSfZzrKtjL4rs9axY/cw9UfMfXjRjEE98e5CMq7WQ== + +"@zag-js/focus-visible@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.31.1.tgz#bd6b94e48eff0566c047b55a3c9ccd9890f5eaaa" + integrity sha512-dbLksz7FEwyFoANbpIlNnd3bVm0clQSUsnP8yUVQucStZPsuWjCrhL2jlAbGNrTrahX96ntUMXHb/sM68TibFg== + dependencies: + "@zag-js/dom-query" "0.31.1" + abab@^2.0.6: version "2.0.6" resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" @@ -3293,7 +3480,7 @@ acorn-walk@^8.0.2: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8, acorn@^8.1.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.1.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: version "8.10.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== @@ -3337,7 +3524,7 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.9.1: +ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3347,7 +3534,7 @@ ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.9.1: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.9.0: version "8.12.0" resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -3386,14 +3573,7 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -3425,12 +3605,12 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^5.0.0: - version "5.3.0" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== +aria-hidden@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522" + integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== dependencies: - dequal "^2.0.3" + tslib "^2.0.0" aria-query@5.1.3: version "5.1.3" @@ -3439,6 +3619,13 @@ aria-query@5.1.3: dependencies: deep-equal "^2.0.5" +aria-query@^5.0.0: + version "5.3.0" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + array-buffer-byte-length@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" @@ -3447,16 +3634,16 @@ array-buffer-byte-length@^1.0.0: call-bind "^1.0.2" is-array-buffer "^3.0.1" -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + array-includes@^3.1.6: version "3.1.6" resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz" @@ -3738,7 +3925,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.9, "browserslist@>= 4.21.0": +browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.9: version "4.21.9" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz" integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== @@ -3828,16 +4015,7 @@ ccount@^2.0.0: resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3986,15 +4164,20 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color2k@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/color2k/-/color2k-2.0.3.tgz#a771244f6b6285541c82aa65ff0a0c624046e533" + integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== colorette@^2.0.10, colorette@^2.0.14: version "2.0.20" @@ -4058,14 +4241,6 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -"confluence-plugin@file:/Users/justin/Development/cortex-plugins/plugins/confluence-plugin": - version "0.1.0" - resolved "file:plugins/confluence-plugin" - dependencies: - "@cortexapps/plugin-core" "^2.0.0" - react "^18.2.0" - react-dom "^18.2.0" - connect-history-api-fallback@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz" @@ -4103,7 +4278,7 @@ cookie@0.5.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -copy-to-clipboard@^3.3.1: +copy-to-clipboard@3.3.3, copy-to-clipboard@^3.3.1: version "3.3.3" resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz" integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== @@ -4316,7 +4491,7 @@ d3-path@^3.1.0: resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== -d3-selection@^3.0.0, "d3-selection@2 - 3", d3-selection@3: +"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== @@ -4372,7 +4547,7 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" -date-fns@^2.0.0, date-fns@^2.16.1: +date-fns@^2.16.1: version "2.30.0" resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz" integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== @@ -4384,33 +4559,26 @@ debounce@^1.2.0: resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@^2.6.0: +debug@2.6.9, debug@^2.6.0: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4: +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - ms "2.0.0" + ms "^2.1.1" decimal.js@^10.4.2: version "10.4.3" @@ -4488,16 +4656,16 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - depd@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz" @@ -4518,6 +4686,11 @@ detect-newline@^3.0.0: resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + detect-node@^2.0.4: version "2.1.0" resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" @@ -4912,7 +5085,7 @@ eslint-plugin-import@^2.25.2: semver "^6.3.0" tsconfig-paths "^3.14.1" -eslint-plugin-n@^15.0.0, eslint-plugin-n@^15.6.1: +eslint-plugin-n@^15.6.1: version "15.7.0" resolved "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz" integrity sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q== @@ -4957,7 +5130,7 @@ eslint-plugin-react@^7.32.2: semver "^6.3.1" string.prototype.matchall "^4.0.8" -eslint-scope@^5.1.1, eslint-scope@5.1.1: +eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -5002,7 +5175,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== -eslint@*, "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.0.1, "eslint@>= 6", eslint@>=4.19.1, eslint@>=5, eslint@>=7.0.0: +eslint@^8.0.1: version "8.45.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz" integrity sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw== @@ -5103,15 +5276,6 @@ events@^3.2.0: resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -"example@file:/Users/justin/Development/cortex-plugins/plugins/example": - version "1.0.0" - resolved "file:plugins/example" - dependencies: - "@cortexapps/plugin-core" "^2.1.0" - react "^18.2.0" - react-dom "^18.2.0" - reactstrap "9.1.9" - execa@^5.0.0: version "5.1.1" resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" @@ -5355,6 +5519,13 @@ flatted@^3.1.0: resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +focus-lock@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-1.3.5.tgz#aa644576e5ec47d227b57eb14e1efb2abf33914c" + integrity sha512-QFaHbhv9WPUeLYBDe/PAuLKJ4Dd9OPvKs9xZBr3yLXnUrDNaVXKu2baDBXe3naPY30hgHYSsf2JW4jzas2mDEQ== + dependencies: + tslib "^2.0.3" + follow-redirects@^1.0.0: version "1.15.2" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" @@ -5405,6 +5576,22 @@ forwarded@0.2.0: resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +framer-motion@^11.11.17, framer-motion@^11.11.7: + version "11.14.4" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.14.4.tgz#cb7197107d75ff4592444a83918e31827fcec3b3" + integrity sha512-NQuzr9JbeJDMQmy0FFLhLzk9h1kAjVC1tGE/HY4ubF02B95EBm2lpA21LE3Od/OpXqXgp0zl5Hdqu25hliBRsA== + dependencies: + motion-dom "^11.14.3" + motion-utils "^11.14.3" + tslib "^2.4.0" + +framesync@6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.1.2.tgz#755eff2fb5b8f3b4d2b266dd18121b300aefea27" + integrity sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g== + dependencies: + tslib "2.4.0" + fresh@0.5.2: version "0.5.2" resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" @@ -5475,6 +5662,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has-proto "^1.0.1" has-symbols "^1.0.3" +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" @@ -5487,53 +5679,11 @@ get-stream@^6.0.0: get-symbol-description@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -"github-actions@file:/Users/justin/Development/cortex-plugins/plugins/github-actions": - version "0.1.0" - resolved "file:plugins/github-actions" - dependencies: - "@backstage/core-components" "^0.13.4" - "@backstage/theme" "^0.4.1" - "@cortexapps/plugin-core" "^2.0.0" - "@material-ui/core" "^4.12.4" - "@material-ui/icons" "^4.11.3" - "@octokit/rest" "^20.0.1" - luxon "^3.4.3" - react "^18.2.0" - react-dom "^18.2.0" - react-router "^6.15.0" - react-router-dom "^6.15.0" - react-use "^17.4.0" - -"GitHub-Issues-Cortex-Plugin@file:/Users/justin/Development/cortex-plugins/plugins/github-issues": - version "0.1.0" - resolved "file:plugins/github-issues" - dependencies: - "@cortexapps/plugin-core" "^2.0.0" - react "^18.2.0" - react-dom "^18.2.0" - -"github-releases@file:/Users/justin/Development/cortex-plugins/plugins/github-releases": - version "0.1.0" - resolved "file:plugins/github-releases" - dependencies: - "@cortexapps/plugin-core" "^2.1.3" - octokit "^3.1.0" - react "^18.2.0" - react-dom "^18.2.0" - -"GitLabIssuesPlugin@file:/Users/justin/Development/cortex-plugins/plugins/gitlab-issues": - version "0.1.0" - resolved "file:plugins/gitlab-issues" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== dependencies: - "@cortexapps/plugin-core" "^2.0.0" - react "^18.2.0" - react-dom "^18.2.0" + call-bind "^1.0.2" + get-intrinsic "^1.1.1" glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" @@ -5811,16 +5961,6 @@ http-deceiver@^1.2.7: resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - http-errors@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" @@ -5832,6 +5972,16 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + http-parser-js@>=0.5.1: version "0.5.8" resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" @@ -5947,7 +6097,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -5989,16 +6139,16 @@ interpret@^3.1.1: resolved "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz" integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== -ipaddr.js@^2.0.1: - version "2.1.0" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz" - integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +ipaddr.js@^2.0.1: + version "2.1.0" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + is-alphabetical@^1.0.0: version "1.0.4" resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz" @@ -6763,7 +6913,7 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" -jest-resolve@*, jest-resolve@^29.6.2: +jest-resolve@^29.6.2: version "29.6.2" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.2.tgz" integrity sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw== @@ -7092,7 +7242,7 @@ jest@^29.6.1: import-local "^3.0.2" jest-cli "^29.6.1" -js-cookie@^2.2.1, js-cookie@^3.0.1: +js-cookie@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz" integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== @@ -7280,7 +7430,7 @@ jss-plugin-vendor-prefixer@^10.5.1: css-vendor "^2.0.8" jss "10.10.0" -jss@^10.5.1, jss@10.10.0: +jss@10.10.0, jss@^10.5.1: version "10.10.0" resolved "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz" integrity sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw== @@ -7363,7 +7513,7 @@ linkify-react@4.1.1: resolved "https://registry.npmjs.org/linkify-react/-/linkify-react-4.1.1.tgz" integrity sha512-2K9Y1cUdvq40dFWqCJ//X+WP19nlzIVITFGI93RjLnA0M7KbnxQ/ffC3AZIZaEIrLangF9Hjt3i0GQ9/anEG5A== -linkifyjs@^4.0.0, linkifyjs@4.1.1: +linkifyjs@4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.1.1.tgz" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== @@ -7429,6 +7579,11 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.mergewith@4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" @@ -7664,7 +7819,7 @@ memfs@^3.1.2, memfs@^3.4.3: dependencies: fs-monkey "^1.0.4" -memoize-one@^5.1.1, "memoize-one@>=3.1.1 <6": +"memoize-one@>=3.1.1 <6", memoize-one@^5.1.1: version "5.2.1" resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== @@ -7980,7 +8135,7 @@ micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -"mime-db@>= 1.43.0 < 2", mime-db@1.52.0: +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -8024,16 +8179,21 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +motion-dom@^11.14.3: + version "11.14.3" + resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-11.14.3.tgz#725c72c0f1d0b632e42fdd8d13b69ecf9fe202c0" + integrity sha512-lW+D2wBy5vxLJi6aCP0xyxTxlTfiu+b+zcpVbGVFUxotwThqhdpPRSmX8xztAgtZMPMeU0WGVn/k1w4I+TbPqA== + +motion-utils@^11.14.3: + version "11.14.3" + resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-11.14.3.tgz#cd4a413463739498411f82abb67b3dd58768b0f8" + integrity sha512-Xg+8xnqIJTpr0L/cidfTTBFkvRw26ZtGGuIhA94J9PQ2p4mEa06Xx7QVYZH0BP+EpMSaDlu+q0I0mmvwADPsaQ== + mri@^1.1.0: version "1.2.0" resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== -ms@^2.1.1, ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" @@ -8044,6 +8204,11 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + multicast-dns@^7.2.5: version "7.2.5" resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" @@ -8311,14 +8476,7 @@ optionator@^0.9.3: prelude-ls "^1.2.1" type-check "^0.4.0" -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^2.2.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -8568,7 +8726,7 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.1.0, postcss@^8.4.21: +postcss@^8.4.21: version "8.4.27" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz" integrity sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ== @@ -8659,7 +8817,7 @@ prompts@^2.0.1, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1, "prop-types@>= 15.3.0 < 19": +prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -8703,13 +8861,6 @@ pure-rand@^6.0.0: resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz" integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== -qs@^6.9.4: - version "6.11.2" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== - dependencies: - side-channel "^1.0.4" - qs@6.11.0: version "6.11.0" resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" @@ -8717,6 +8868,13 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +qs@^6.9.4: + version "6.11.2" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + querystringify@^2.1.1: version "2.2.0" resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" @@ -8784,6 +8942,13 @@ react-beautiful-dnd@^13.0.0: redux "^4.0.4" use-memo-one "^1.1.1" +react-clientside-effect@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.7.tgz#78eb62e3be36208d4d8d5b2668ae630a32deca73" + integrity sha512-gce9m0Pk/xYYMEojRI9bgvqQAkl6hm7ozQvqWPyQx+kULiatdHgkNM1QG4DQRx5N9BAzWSCJmt9mMV8/KsdgVg== + dependencies: + "@babel/runtime" "^7.12.13" + react-dev-utils@^12.0.1: version "12.0.1" resolved "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz" @@ -8814,7 +8979,7 @@ react-dev-utils@^12.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" -react-dom@*, "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc", "react-dom@^15.4.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.13.1 || ^17.0.0", "react-dom@^16.8 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.5 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0", react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 15.3.0 < 19", "react-dom@>= 16.8", react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.0, react-dom@>=16.9.0: +react-dom@^18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== @@ -8832,11 +8997,23 @@ react-error-overlay@^6.0.11: resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz" integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== -react-fast-compare@^3.0.1, react-fast-compare@^3.1.1: +react-fast-compare@3.2.2, react-fast-compare@^3.0.1, react-fast-compare@^3.1.1: version "3.2.2" resolved "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== +react-focus-lock@^2.9.6: + version "2.13.5" + resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.13.5.tgz#68b01618ef3a4717746a02e223afe9d86a69a95e" + integrity sha512-HjHuZFFk2+j6ZT3LDQpyqffue541HrxUG/OFchCEwis9nstgNg0rREVRAxHBcB1lHJ5Fsxtx1qya/5xFwxDb4g== + dependencies: + "@babel/runtime" "^7.0.0" + focus-lock "^1.3.5" + prop-types "^15.6.2" + react-clientside-effect "^1.2.6" + use-callback-ref "^1.3.2" + use-sidecar "^1.1.2" + react-helmet@6.1.0: version "6.1.0" resolved "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz" @@ -8852,37 +9029,17 @@ react-hook-form@^7.12.2: resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.46.1.tgz" integrity sha512-0GfI31LRTBd5tqbXMGXT1Rdsv3rnvy0FjEk8Gn9/4tp6+s77T7DPZuGEpBRXOauL+NhyGT5iaXzdIM2R6F/E+w== -react-is@^16.12.0: - version "16.13.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^16.13.1: - version "16.13.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^16.7.0: - version "16.13.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -"react-is@^16.8.0 || ^17.0.0": - version "17.0.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-icons@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.4.0.tgz#443000f6e5123ee1b21ea8c0a716f6e7797f7416" + integrity sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ== -react-is@^16.8.6: +react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.6: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -react-is@^17.0.2: +"react-is@^16.8.0 || ^17.0.0", react-is@^17.0.1, react-is@^17.0.2: version "17.0.2" resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== @@ -8945,7 +9102,26 @@ react-redux@^7.2.0: prop-types "^15.7.2" react-is "^17.0.2" -react-router-dom@^6.15.0, "react-router-dom@6.0.0-beta.0 || ^6.3.0": +react-remove-scroll-bar@^2.3.7: + version "2.3.8" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223" + integrity sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q== + dependencies: + react-style-singleton "^2.2.2" + tslib "^2.0.0" + +react-remove-scroll@^2.5.7: + version "2.6.1" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.6.1.tgz#9ea97abde971f17a59f299ccd247c3aee55975a9" + integrity sha512-jWEvWQidZ/C/FnFlUIB1mDLpY3r7uEb22WZ3uVeKj520caKDiaBsNDEB9J1gHJgpiLo+eTdPl2MVi0JitFTiFg== + dependencies: + react-remove-scroll-bar "^2.3.7" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-router-dom@^6.15.0: version "6.15.0" resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.15.0.tgz" integrity sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ== @@ -8953,7 +9129,7 @@ react-router-dom@^6.15.0, "react-router-dom@6.0.0-beta.0 || ^6.3.0": "@remix-run/router" "1.8.0" react-router "6.15.0" -react-router@^6.15.0, react-router@6.15.0: +react-router@6.15.0, react-router@^6.15.0: version "6.15.0" resolved "https://registry.npmjs.org/react-router/-/react-router-6.15.0.tgz" integrity sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg== @@ -8987,6 +9163,14 @@ react-sparklines@^1.7.0: dependencies: prop-types "^15.5.10" +react-style-singleton@^2.2.1, react-style-singleton@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.3.tgz#4265608be69a4d70cfe3047f2c6c88b2c3ace388" + integrity sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ== + dependencies: + get-nonce "^1.0.0" + tslib "^2.0.0" + react-syntax-highlighter@^15.4.5, react-syntax-highlighter@^15.5.0: version "15.5.0" resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz" @@ -9060,17 +9244,17 @@ react-window@^1.8.6: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" -react@*, "react@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc", "react@^15.4.1 || ^16.0.0 || ^17.0.0 || || ^18.0.0", "react@^16.13.1 || ^17.0.0", "react@^16.3.0 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.3 || ^17 || ^18", "react@^16.8.5 || ^17.0.0 || ^18.0.0", "react@^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, "react@>= 0.14.0", "react@>= 0.14.7", "react@>= 15.0.0", "react@>= 15.3.0 < 19", "react@>= 16.8", react@>=15.0.0, react@>=16, react@>=16.3.0, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=16.9.0: +react@^18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" -reactstrap@^9.1.9: - version "9.2.0" - resolved "https://registry.npmjs.org/reactstrap/-/reactstrap-9.2.0.tgz" - integrity sha512-WWLTEG00qYav0E55PorWHReYTkz5IqkVmQNy0h6U81yqjSp9fOLFGV5pYSVeAUz+yRhU/RTE0oAWy22zr6sOIw== +reactstrap@9.1.9: + version "9.1.9" + resolved "https://registry.npmjs.org/reactstrap/-/reactstrap-9.1.9.tgz" + integrity sha512-kcXHdYLmPK7rXzLotum7RI9uwvDZJ01VtjchAwzfKL8SHFZEvi7+JVsnBojf1ZIswRaTX/s8poAgZFgE8oF0zQ== dependencies: "@babel/runtime" "^7.12.5" "@popperjs/core" "^2.6.0" @@ -9079,7 +9263,7 @@ reactstrap@^9.1.9: react-popper "^2.2.4" react-transition-group "^4.4.2" -reactstrap@^9.2.0: +reactstrap@^9.1.9, reactstrap@^9.2.0: version "9.2.0" resolved "https://registry.npmjs.org/reactstrap/-/reactstrap-9.2.0.tgz" integrity sha512-WWLTEG00qYav0E55PorWHReYTkz5IqkVmQNy0h6U81yqjSp9fOLFGV5pYSVeAUz+yRhU/RTE0oAWy22zr6sOIw== @@ -9091,18 +9275,6 @@ reactstrap@^9.2.0: react-popper "^2.2.4" react-transition-group "^4.4.2" -reactstrap@9.1.9: - version "9.1.9" - resolved "https://registry.npmjs.org/reactstrap/-/reactstrap-9.1.9.tgz" - integrity sha512-kcXHdYLmPK7rXzLotum7RI9uwvDZJ01VtjchAwzfKL8SHFZEvi7+JVsnBojf1ZIswRaTX/s8poAgZFgE8oF0zQ== - dependencies: - "@babel/runtime" "^7.12.5" - "@popperjs/core" "^2.6.0" - classnames "^2.2.3" - prop-types "^15.5.8" - react-popper "^2.2.4" - react-transition-group "^4.4.2" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" @@ -9401,20 +9573,15 @@ safe-array-concat@^1.0.0: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-regex-test@^1.0.0: version "1.0.0" @@ -9444,6 +9611,15 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" @@ -9463,15 +9639,6 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" - screenfull@^5.1.0: version "5.2.0" resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz" @@ -9489,17 +9656,12 @@ selfsigned@^2.1.1: dependencies: node-forge "^1" -semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0: version "5.7.2" resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.3.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^6.3.1: +semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -9511,11 +9673,6 @@ semver@^7.0.0, semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8, semve dependencies: lru-cache "^6.0.0" -"semver@2 || 3 || 4 || 5": - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - send@0.18.0: version "0.18.0" resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" @@ -9661,6 +9818,14 @@ source-map-js@^1.0.2: resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" @@ -9669,13 +9834,10 @@ source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" + integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA== source-map@^0.5.7: version "0.5.7" @@ -9687,11 +9849,6 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@0.5.6: - version "0.5.6" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" - integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA== - sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" @@ -9797,16 +9954,16 @@ stacktrace-js@^2.0.2: stack-generator "^2.0.5" stacktrace-gps "^3.0.4" -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - statuses@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + stop-iteration-iterator@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" @@ -9814,20 +9971,6 @@ stop-iteration-iterator@^1.0.0: dependencies: internal-slot "^1.0.4" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - string-length@^4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -9895,6 +10038,20 @@ string.prototype.trimstart@^1.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -9941,16 +10098,16 @@ style-to-object@^0.4.0: dependencies: inline-style-parser "0.1.1" -stylis@^4.0.6: - version "4.3.0" - resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz" - integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ== - stylis@4.2.0: version "4.2.0" resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== +stylis@^4.0.6: + version "4.3.0" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz" + integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" @@ -10131,21 +10288,31 @@ tsconfig-paths@^3.14.1: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@*, tslib@^2.1.0: - version "2.6.2" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.0, tslib@^2.4.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tslib@^2.0.3: version "2.6.1" resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz" integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== +tslib@^2.1.0: + version "2.6.2" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" @@ -10153,11 +10320,36 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +turbo-darwin-64@1.10.11: + version "1.10.11" + resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.10.11.tgz#173b90bfb24f93f3fb75e566dc6f2dea12cfcbb0" + integrity sha512-pHNz6D5XUVB+bgZMKXIOegvH9GzPXucwgiHFatQcRoscAW1te1Zvn3fAWYo/mJ550AqPWQLmALZZel3z3lllLA== + turbo-darwin-arm64@1.10.11: version "1.10.11" resolved "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.10.11.tgz" integrity sha512-j3yGAvkBu0BqR+5nb9LiRs8UZsUQDOqpdP4S9OW3+W5jorJIxUxLawwk3XqoYVGhmPh84LWWOOrMgFQ/Y/3WSg== +turbo-linux-64@1.10.11: + version "1.10.11" + resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.10.11.tgz#7817ec2e977116fcb4ad5c86e197507621fdf7b7" + integrity sha512-FZ+/VT3Yt188VvPuvqIwIyvosYALzu7e8ewxpl8yiYDwQbLwxMOEt2UKACsL+D7wzNtIMPRDxNmnhNvTbx9Afw== + +turbo-linux-arm64@1.10.11: + version "1.10.11" + resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.10.11.tgz#4624b9853eb4130d9fd9d23dbbaa570283bfe9b7" + integrity sha512-IfxO8S1FiikunmUnlul1sd5piPlunU1QlnNNGFfhKJkMidkJ0rXsSbh2epn/pXO8RRPBnFRxYkp6gJz/FTUUTg== + +turbo-windows-64@1.10.11: + version "1.10.11" + resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.10.11.tgz#f401286db3cd82ee88873812891e74472693c45d" + integrity sha512-5qwTEk27duxYIsDycgZdpti1b41Xu2D3W+WRlg++sylwqhAgcPhfcppXMGd70h/SScgIh7IeLjzgTK7+YPE77g== + +turbo-windows-arm64@1.10.11: + version "1.10.11" + resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-1.10.11.tgz#06be0c520fa9be6bfb1e68741a36f606b41ae0e3" + integrity sha512-FGvWCWvii4PZqy+4VBoanKaMkqeRD146iHL67YpY5sp8z5H/Gkywtu8xxBbkgP14lBr6fAsyRarHBuR+c52cDg== + turbo@^1.10.11: version "1.10.11" resolved "https://registry.npmjs.org/turbo/-/turbo-1.10.11.tgz" @@ -10239,7 +10431,7 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typescript@*, typescript@^4.9.5, "typescript@>= 2.7", "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": +typescript@^4.9.5: version "4.9.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== @@ -10356,7 +10548,7 @@ universalify@^2.0.0: resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unpipe@~1.0.0, unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -10393,6 +10585,13 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" +use-callback-ref@^1.3.0, use-callback-ref@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693" + integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== + dependencies: + tslib "^2.0.0" + use-isomorphic-layout-effect@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz" @@ -10403,6 +10602,14 @@ use-memo-one@^1.1.1: resolved "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz" integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ== +use-sidecar@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.3.tgz#10e7fd897d130b896e2c546c63a5e8233d00efdb" + integrity sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -10524,7 +10731,7 @@ webidl-conversions@^7.0.0: resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== -webpack-cli@^5.0.1, webpack-cli@5.x.x: +webpack-cli@^5.0.1: version "5.1.4" resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz" integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg== @@ -10603,7 +10810,7 @@ webpack-sources@^3.2.3: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -"webpack@^4.0.0 || ^5.0.0", "webpack@^4.37.0 || ^5.0.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.20.0, webpack@^5.76.1, "webpack@>= 4", webpack@5.x.x: +webpack@^5.76.1: version "5.88.2" resolved "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz" integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== @@ -10633,7 +10840,7 @@ webpack-sources@^3.2.3: watchpack "^2.4.0" webpack-sources "^3.2.3" -websocket-driver@^0.7.4, websocket-driver@>=0.5.1: +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== @@ -10788,6 +10995,11 @@ yaml@^1.10.0, yaml@^1.7.2: resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.5.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773" + integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg== + yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" @@ -10824,4 +11036,4 @@ zod@^3.21.4: zwitch@^2.0.0: version "2.0.4" resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" - integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== \ No newline at end of file + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== From ef069f8d8a9cedb2b129a8c4748496002acc6a9e Mon Sep 17 00:00:00 2001 From: Cafer Elgin Date: Mon, 23 Dec 2024 04:00:35 +0200 Subject: [PATCH 2/9] feat: refactored page content component --- plugins/confluence-plugin/package.json | 4 + .../src/api/fetchConfluencePageContent.ts | 35 ++++ .../src/api/fetchConfluencePluginConfig.ts | 17 ++ .../confluence-plugin/src/components/App.tsx | 5 +- .../src/components/Loading.tsx | 18 ++ .../src/components/Notice.tsx | 14 ++ .../src/components/PageContent.tsx | 187 +++++++----------- .../src/components/PageSelector.tsx | 41 ++++ 8 files changed, 208 insertions(+), 113 deletions(-) create mode 100644 plugins/confluence-plugin/src/api/fetchConfluencePageContent.ts create mode 100644 plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts create mode 100644 plugins/confluence-plugin/src/components/Loading.tsx create mode 100644 plugins/confluence-plugin/src/components/Notice.tsx create mode 100644 plugins/confluence-plugin/src/components/PageSelector.tsx diff --git a/plugins/confluence-plugin/package.json b/plugins/confluence-plugin/package.json index 915ecdc..cb3c1d5 100644 --- a/plugins/confluence-plugin/package.json +++ b/plugins/confluence-plugin/package.json @@ -3,7 +3,11 @@ "version": "0.1.0", "license": "MIT", "dependencies": { + "@chakra-ui/react": "^2.10.2", "@cortexapps/plugin-core": "^2.0.0", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "framer-motion": "^11.15.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/plugins/confluence-plugin/src/api/fetchConfluencePageContent.ts b/plugins/confluence-plugin/src/api/fetchConfluencePageContent.ts new file mode 100644 index 0000000..fa10e71 --- /dev/null +++ b/plugins/confluence-plugin/src/api/fetchConfluencePageContent.ts @@ -0,0 +1,35 @@ +export const fetchConfluencePageContent = async ( + baseConfluenceUrl: string, + pageId: string | number +): Promise => { + const jiraURL = `${baseConfluenceUrl}/wiki/rest/api/content/${pageId}?expand=body.view`; + let contentResult; + try { + contentResult = await fetch(jiraURL); + } catch (error: any) { + throw new Error( + `Network error while fetching Confluence page with ID ${pageId}: ${ + (error as Error).message + }` + ); + } + if (!contentResult.ok) { + let errorStr = ""; + try { + if ( + contentResult.headers.get("content-type")?.includes("application/json") + ) { + const contentJSON: { message?: string } = await contentResult.json(); + errorStr = `Failed to fetch Confluence page with ID ${pageId}: ${ + contentJSON.message ?? JSON.stringify(contentJSON) + }`; + } else { + errorStr = await contentResult.text(); + } + } catch { + errorStr = contentResult.statusText || "Failed to fetch Confluence page"; + } + throw new Error(errorStr); + } + return contentResult.json(); +}; diff --git a/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts b/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts new file mode 100644 index 0000000..fdb2bb1 --- /dev/null +++ b/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts @@ -0,0 +1,17 @@ +export const fetchConfluencePluginConfig = async ( + apiBaseUrl: string +): Promise => { + try { + const response = await fetch( + `${apiBaseUrl}/catalog/confluence-plugin-config/openapi` + ); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + return data.info["x-cortex-definition"]["confluence-url"]; + } catch (error) { + console.error("Error fetching Confluence plugin config:", error); + throw error; + } +}; diff --git a/plugins/confluence-plugin/src/components/App.tsx b/plugins/confluence-plugin/src/components/App.tsx index 16c4bfc..01a91a4 100644 --- a/plugins/confluence-plugin/src/components/App.tsx +++ b/plugins/confluence-plugin/src/components/App.tsx @@ -3,12 +3,15 @@ import { PluginProvider } from "@cortexapps/plugin-core/components"; import "../baseStyles.css"; import ErrorBoundary from "./ErrorBoundary"; import PageContent from "./PageContent"; +import { ChakraProvider } from "@chakra-ui/react"; const App: React.FC = () => { return ( - + + + ); diff --git a/plugins/confluence-plugin/src/components/Loading.tsx b/plugins/confluence-plugin/src/components/Loading.tsx new file mode 100644 index 0000000..f925d68 --- /dev/null +++ b/plugins/confluence-plugin/src/components/Loading.tsx @@ -0,0 +1,18 @@ +import { Box, Spinner, Text } from "@chakra-ui/react"; + +export default function Loading(): JSX.Element { + return ( + + + Loading... + + ); +} diff --git a/plugins/confluence-plugin/src/components/Notice.tsx b/plugins/confluence-plugin/src/components/Notice.tsx new file mode 100644 index 0000000..7fecbb5 --- /dev/null +++ b/plugins/confluence-plugin/src/components/Notice.tsx @@ -0,0 +1,14 @@ +import { Box, Text } from "@chakra-ui/react"; +import type { ReactNode } from "react"; + +export default function Notice({ + children, +}: { + children: ReactNode; +}): JSX.Element { + return ( + + {children} + + ); +} diff --git a/plugins/confluence-plugin/src/components/PageContent.tsx b/plugins/confluence-plugin/src/components/PageContent.tsx index fe9a06e..7e48c47 100644 --- a/plugins/confluence-plugin/src/components/PageContent.tsx +++ b/plugins/confluence-plugin/src/components/PageContent.tsx @@ -2,21 +2,22 @@ import type React from "react"; import { useState, useEffect, useCallback } from "react"; import { isEmpty, isNil } from "lodash"; import "../baseStyles.css"; -import { - Box, - Text, - usePluginContext, -} from "@cortexapps/plugin-core/components"; +import { usePluginContext } from "@cortexapps/plugin-core/components"; import { getEntityYaml } from "../api/Cortex"; import { getConfluenceDetailsFromEntity } from "../lib/parseEntity"; - +import { Heading, Box } from "@chakra-ui/react"; import Instructions from "./Instructions"; +import Loading from "./Loading"; +import Notice from "./Notice"; +import PageSelector from "./PageSelector"; +import { fetchConfluencePageContent } from "../api/fetchConfluencePageContent"; +import { fetchConfluencePluginConfig } from "../api/fetchConfluencePluginConfig"; const PageContent: React.FC = () => { const [entityPages, setEntityPages] = useState([]); const [pageContent, setPageContent] = useState(); const [pageTitle, setPageTitle] = useState(); - const [entityPage, setEntityPage] = useState(); + const [entityPage, setEntityPage] = useState(); const [baseConfluenceUrl, setBaseConfluenceUrl] = useState(""); const [errorStr, setErrorStr] = useState(""); @@ -24,80 +25,58 @@ const PageContent: React.FC = () => { const fetchPageContent = useCallback( async (pages: EntityPageI[], pageId: string | number): Promise => { - if (pages.length === 0) { - return; - } + if (pages.length === 0) return; setEntityPage(pageId); - const jiraURL = `${baseConfluenceUrl}/wiki/rest/api/content/${pageId}?expand=body.view`; - setErrorStr("loading"); - const contentResult = await fetch(jiraURL); - if (!contentResult.ok) { - let newErrorStr = ""; - // if the contentResult contains valid JSON, we can use it to display an error message - try { - if ( - contentResult.headers - .get("content-type") - ?.includes("application/json") - ) { - const contentJSON = await contentResult.json(); - const msg: string = - contentJSON.message || JSON.stringify(contentJSON); - newErrorStr = `Failed to fetch Confluence page with ID ${pageId}: ${msg}`; - } else { - // just get the text if it's not JSON - const contentText = await contentResult.text(); - newErrorStr = contentText; - } - } catch (e) { - // if we can't parse the content, just use the status text - newErrorStr = - contentResult.statusText || "Failed to fetch Confluence page"; - } - setErrorStr(newErrorStr); - return; + setErrorStr("loading-content"); + try { + const contentJSON = await fetchConfluencePageContent( + baseConfluenceUrl, + pageId + ); + setPageContent(contentJSON.body.view.value); + setPageTitle(contentJSON.title); + setErrorStr(""); + } catch (error) { + setErrorStr(error.message); } - const contentJSON = await contentResult.json(); - setPageContent(contentJSON.body.view.value); - setPageTitle(contentJSON.title); - setErrorStr(""); }, [baseConfluenceUrl] ); useEffect(() => { - if (!context?.apiBaseUrl) { - return; - } - const getConfluencePluginConfig = async (): Promise => { + if (!context?.apiBaseUrl) return; + const getConfig = async (): Promise => { setErrorStr("loading"); - if (!context?.apiBaseUrl) { - return; - } - let newConfluenceUrl = ""; try { - const response = await fetch( - `${context?.apiBaseUrl}/catalog/confluence-plugin-config/openapi` + const newConfluenceUrl = await fetchConfluencePluginConfig( + context.apiBaseUrl ); - const data = await response.json(); - newConfluenceUrl = data.info["x-cortex-definition"]["confluence-url"]; - } catch (e) {} - setBaseConfluenceUrl(newConfluenceUrl); - if (!newConfluenceUrl) { + setBaseConfluenceUrl(newConfluenceUrl); + setErrorStr(!newConfluenceUrl ? "instructions" : ""); + } catch { setErrorStr("instructions"); } }; - void getConfluencePluginConfig(); + void getConfig(); }, [context?.apiBaseUrl]); useEffect(() => { - if (!context.apiBaseUrl || !context.entity?.tag || !baseConfluenceUrl) { + if (!context.entity?.tag) { + setErrorStr( + "This plugin is intended to be used within the entities. " + + "Go to an entity, then under Plugins, select Confluence to view the Confluence page(s)." + ); + } + + if (!context.apiBaseUrl || !baseConfluenceUrl) { return; } - const fetchEntityYaml = async (): Promise => { + + const fetchEntityYamlData = async (): Promise => { const entityTag = context.entity?.tag; if (!isNil(entityTag)) { try { + setErrorStr("loading"); const yaml = await getEntityYaml(context.apiBaseUrl, entityTag); const fetchedEntityPages = isEmpty(yaml) ? [] @@ -107,79 +86,63 @@ const PageContent: React.FC = () => { return; } setEntityPages(fetchedEntityPages); - } catch (e) { - // This will still result in a "We could not find any Confluence page" error in the UI, but may as well trap in console as well - const msg: string = e.message || e.toString(); - setErrorStr(`Error retrieving Confluence page: ${msg}`); - console.error("Error retrieving Confluence page: ", e); + } catch (error) { + setErrorStr( + `Error retrieving Confluence page: ${(error as Error).message}` + ); + console.error("Error retrieving Confluence page: ", error); } } }; - void fetchEntityYaml(); + void fetchEntityYamlData(); }, [context.apiBaseUrl, context.entity?.tag, baseConfluenceUrl]); useEffect(() => { const setFirstPageContent = async (): Promise => { - if (entityPages.length === 0) { - return; - } + if (entityPages.length === 0) return; await fetchPageContent(entityPages, entityPages[0].id); }; void setFirstPageContent(); }, [baseConfluenceUrl, entityPages, fetchPageContent]); - if (errorStr === "loading") { - return
Loading...
; - } else if (errorStr === "instructions") { - return ; - } else if (errorStr) { - return ( - - {errorStr} - - ); - } + if (errorStr === "loading") return ; + if (errorStr === "instructions") return ; + if (errorStr && errorStr !== "loading-content") + return {errorStr}; if (isNil(entityPage)) { return ( - - - We could not find any Confluence page associated with this entity. - - + + We could not find any Confluence page associated with this entity. + ); } return ( -
+ {entityPages.length > 1 && ( -
- -
+ + )} + {errorStr === "loading-content" ? ( + + ) : ( + + + + )} -

-

-
+ ); }; diff --git a/plugins/confluence-plugin/src/components/PageSelector.tsx b/plugins/confluence-plugin/src/components/PageSelector.tsx new file mode 100644 index 0000000..3eef707 --- /dev/null +++ b/plugins/confluence-plugin/src/components/PageSelector.tsx @@ -0,0 +1,41 @@ +import { Box, FormLabel, Select } from "@chakra-ui/react"; + +export default function PageSelector({ + currentPageId, + onChangeHandler, + pages, + disabled, +}: { + currentPageId: string | number; + onChangeHandler: CallableFunction; + pages: EntityPageI[]; + disabled: boolean; +}): JSX.Element { + return ( + + Select page: + + + ); +} From bfe1eec19f7e9142b88b717c80b26249d6a4f1e9 Mon Sep 17 00:00:00 2001 From: Cafer Elgin Date: Mon, 23 Dec 2024 04:59:30 +0200 Subject: [PATCH 3/9] styling: Loading text is bigger now --- plugins/confluence-plugin/src/components/Loading.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/confluence-plugin/src/components/Loading.tsx b/plugins/confluence-plugin/src/components/Loading.tsx index f925d68..4b4b23f 100644 --- a/plugins/confluence-plugin/src/components/Loading.tsx +++ b/plugins/confluence-plugin/src/components/Loading.tsx @@ -12,7 +12,7 @@ export default function Loading(): JSX.Element { gap={6} > - Loading... + Loading... ); } From a5b9f1cf3c04cd7ff1269f33da0327ffdf007b17 Mon Sep 17 00:00:00 2001 From: Cafer Elgin Date: Tue, 24 Dec 2024 21:45:53 +0200 Subject: [PATCH 4/9] test: added tests for notice and page selector components --- .../src/components/Notice.test.tsx | 11 ++ .../src/components/PageSelector.test.tsx | 101 ++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 plugins/confluence-plugin/src/components/Notice.test.tsx create mode 100644 plugins/confluence-plugin/src/components/PageSelector.test.tsx diff --git a/plugins/confluence-plugin/src/components/Notice.test.tsx b/plugins/confluence-plugin/src/components/Notice.test.tsx new file mode 100644 index 0000000..49997e2 --- /dev/null +++ b/plugins/confluence-plugin/src/components/Notice.test.tsx @@ -0,0 +1,11 @@ +import { render, waitFor } from "@testing-library/react"; +import Notice from "./Notice"; + +describe("Notice component", () => { + it("renders children correctly", async () => { + const { getByText } = render(Test Notice); + await waitFor(() => { + expect(getByText("Test Notice")).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/confluence-plugin/src/components/PageSelector.test.tsx b/plugins/confluence-plugin/src/components/PageSelector.test.tsx new file mode 100644 index 0000000..f2d93df --- /dev/null +++ b/plugins/confluence-plugin/src/components/PageSelector.test.tsx @@ -0,0 +1,101 @@ +import { render, screen, fireEvent, waitFor } from "@testing-library/react"; +import "@testing-library/jest-dom/extend-expect"; +import PageSelector from "./PageSelector"; + +const mockPages = [ + { id: 1, title: "Page One" }, + { id: 2, title: "Page Two" }, + { id: 3, title: "" }, +]; + +describe("PageSelector Component", () => { + it("renders without crashing", () => { + render( + + ); + }); + + it("displays the correct number of options", async () => { + render( + + ); + + const options = screen.getAllByRole("option"); + await waitFor(() => { + expect(options).toHaveLength(mockPages.length); + }); + }); + + it("displays the correct option text", async () => { + render( + + ); + await waitFor(() => { + expect(screen.getByText("Page One")).toBeInTheDocument(); + expect(screen.getByText("Page Two")).toBeInTheDocument(); + expect(screen.getByText("Page ID: 3")).toBeInTheDocument(); + }); + }); + + it("calls onChangeHandler with the correct arguments", async () => { + const mockOnChangeHandler = jest.fn(); + render( + + ); + + fireEvent.change(screen.getByRole("combobox"), { target: { value: "2" } }); + await waitFor(() => { + expect(mockOnChangeHandler).toHaveBeenCalledWith(mockPages, "2"); + }); + }); + + it("is disabled when the disabled prop is true", async () => { + render( + + ); + + await waitFor(() => { + expect(screen.getByRole("combobox")).toBeDisabled(); + }); + }); + + it("is not disabled when the disabled prop is false", async () => { + render( + + ); + + await waitFor(() => { + expect(screen.getByRole("combobox")).not.toBeDisabled(); + }); + }); +}); From 66cb7300f2c3355d43af3de3f59b066844d78f25 Mon Sep 17 00:00:00 2001 From: Cafer Elgin Date: Tue, 24 Dec 2024 22:46:49 +0200 Subject: [PATCH 5/9] fix: updated readme --- plugins/confluence-plugin/README.md | 46 ++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/plugins/confluence-plugin/README.md b/plugins/confluence-plugin/README.md index 6d6881d..dfe9960 100644 --- a/plugins/confluence-plugin/README.md +++ b/plugins/confluence-plugin/README.md @@ -14,20 +14,30 @@ Your Confluence instance URL should look like `https://something.atlassian.net`. ### Set your Confluence credentials -If you are using username and password authentication, type them in to a text editor with a colon (`:`) between them. If you are using SSO, use an API token in place of the password. To create an API token in Confluence, follow the [instructions provided by Atlassian](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/). Once you have your text in your text editor like `myusername@example.com:MySecretPassWordOrToken`, you need to base64 encode it. You can do this using an online tool like [this](https://www.base64encode.org). You will add the base64 encoded value to Cortex as a secret. Copy the base64 encoded value. In Cortex, click on Settings > Secrets > Add secret. In Secret name, type `confluence_secret`, paste the base64 encoded secret into Secret value, and click on Create secret. +1. If you are using username and password authentication, type them in to a text editor with a colon (`:`) between them. If you are using SSO, use an API token in place of the password. To create an API token in Confluence, follow the [instructions provided by Atlassian](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/). +2. Once you have your text in your text editor like `myusername@example.com:MySecretPassWordOrToken`, you need to base64 encode it. You can do this using an online tool like [this](https://www.base64encode.org). +3. You will add the base64 encoded value to Cortex as a secret. Copy the base64 encoded value. In Cortex, click on Settings > Secrets > Add secret. In Secret name, type `confluence_secret`, paste the base64 encoded secret into Secret value, and click on Create secret. ### Set up a Plugin Proxy -After you've saved the secret, we will set up a proxy to use that secret to communicate with Confluence. In Cortex, click on Plugins > Proxies > Create Proxy. In Name, type `Confluence Proxy`. Click on Add URL, and put in your Confluence Instance URL, like `https://something.atlassian.net`. Click Save. Next, click on "Add header to https://something.atlassian.net". In the dialog box that appears, type `Authorization` in the Name field, and in the Value field, type `Basic {{{secrets.confluence_secret}}}`. Make sure you include the three curly braces, and make sure the secret name matches the secret you created above, with `secrets.` in front of it. Click Save, then click on the Create Proxy button. +After you've saved the secret, we will set up a proxy to use that secret to communicate with Confluence. -### Associate the plugin with the plugin proxy +1. In Cortex, click on Plugins > Proxies > Create Proxy. +2. In Name, type `Confluence Proxy`. +3. Click on Add URL, and put in your Confluence Instance URL, like `https://something.atlassian.net`. Click Save. +4. Next, click on "Add header to https://something.atlassian.net". In the dialog box that appears, type `Authorization` in the Name field, and in the Value field, type `Basic {{{secrets.confluence_secret}}}`. Make sure you include the three curly braces, and make sure the secret name matches the secret you created above, with `secrets.` in front of it. Click Save, then click on the Create Proxy button. -Create or edit your Confluence Plugin. In the dropdown under the Associated Proxy heading, choose the Confluence proxy you created above. Next, click Save plugin at the bottom of the page. +### Associate the plugin with the plugin proxy and set entity types + +1. Create or edit your Confluence Plugin. +2. In the Plugin Context section, find the dropdown under the Associated Proxy heading, choose the Confluence proxy you created above. +3. At the bottom of Plugin Context section, click on **"Add another context"** and add the `entity types` you want to display your plugin. (eg. `service`) +4. Next, click Save plugin at the bottom of the page. ### Create a plugin configuration entity -- Consider creating a new entity type, so that any existing scorecards are not affected by ths configuration entity. In this example, we have created a new entity type called `plugin-configuration` -- Create a new entity with the tag `confluence-plugin-config` +- Consider creating a new **entity type**, so that any existing scorecards are not affected by ths configuration entity. In this example, we have created a new entity type called `plugin-configuration` +- Create a new **entity** with the tag `confluence-plugin-config` - Set `x-cortex-definition.confluence-url` to the value of your Confluence Instance URL. For example, if my Confluence Instance URL was `https://martindstone.service-now.com`, my `confluence-plugin-config` entity would look like this: ``` @@ -43,18 +53,38 @@ info: ### Adding Confluence content to entities -Entities can be associated with Confluence Page IDs by adding a PageID tag to the `x-cortex-confluence` object. In the Entity yaml for the entity to the Page ID that you'd like to view inside of Cortex, such as: +To associate confluence pages with entities you will require `id` for each page in which you can find by following the instructions on [here](https://confluence.atlassian.com/confkb/how-to-get-confluence-page-id-648380445.html). + +Entities can be associated with Confluence Page IDs in two ways: + +1. If there is only one confluence page, adding a PageID tag to the `x-cortex-confluence` object will be ok. In the Entity yaml for the entity to the Page ID that you'd like to view inside of Cortex, such as: ``` x-cortex-confluence: pageID: "123456" ``` +2. If there are multiple confluence pages, adding pages under `x-cortex-confluence` and then under `pages` you can enter multiple `id`s and `title`s as well to describe the corresponding confluence page. Entity yaml should look like this: + +``` +x-cortex-confluence: + pages: + - id: "327681" + title: Page Title 1 + - id: "65718" + title: Page Title 2 + - id: "1179675" + title: "" + - id: "1277954" +``` + +The `id` field is mandatory but `title` filed is optional for each page. + You can do this for Custom Entities, as well as any Service entity. ### Done! -Now when you load the Confluence plugin on an entity that has a Confluence page ID in `x-cortex-confluence.pageID`, you should see the content of that page in Cortex! +Now when you load the Confluence plugin on an entity, you should see the contents of associated pages in Cortex! ## Building the plugin From 797229e8e2036bd1de752739927974322b2f86f9 Mon Sep 17 00:00:00 2001 From: Cafer Elgin Date: Mon, 30 Dec 2024 18:40:54 +0200 Subject: [PATCH 6/9] feat: fills missing page titles from page contents --- .../src/components/PageContent.tsx | 47 ++++++++++++++++++- .../src/components/PageSelector.tsx | 4 +- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/plugins/confluence-plugin/src/components/PageContent.tsx b/plugins/confluence-plugin/src/components/PageContent.tsx index 7e48c47..9c5455d 100644 --- a/plugins/confluence-plugin/src/components/PageContent.tsx +++ b/plugins/confluence-plugin/src/components/PageContent.tsx @@ -43,6 +43,41 @@ const PageContent: React.FC = () => { [baseConfluenceUrl] ); + const fetchMissingPageTitles = useCallback( + async (pages: EntityPageI[]): Promise => { + if (pages.length === 0) return []; + const updatedPages = await Promise.all( + pages.map(async (page) => { + if (page.title && page.title.length > 0) { + return page; + } + try { + const contentJSON = await fetchConfluencePageContent( + baseConfluenceUrl, + page.id + ); + return { + ...page, + title: + page.title && page.title.length > 0 + ? page.title + : contentJSON.title, + }; + } catch (error) { + console.error( + `Error fetching page title for page with ID ${page.id}: ${ + (error as Error).message + }` + ); + return page; + } + }) + ); + return updatedPages; + }, + [baseConfluenceUrl] + ); + useEffect(() => { if (!context?.apiBaseUrl) return; const getConfig = async (): Promise => { @@ -85,7 +120,10 @@ const PageContent: React.FC = () => { setErrorStr("No Confluence details exist on this entity."); return; } - setEntityPages(fetchedEntityPages); + const pagesWithTitles = await fetchMissingPageTitles( + fetchedEntityPages + ); + setEntityPages(pagesWithTitles); } catch (error) { setErrorStr( `Error retrieving Confluence page: ${(error as Error).message}` @@ -95,7 +133,12 @@ const PageContent: React.FC = () => { } }; void fetchEntityYamlData(); - }, [context.apiBaseUrl, context.entity?.tag, baseConfluenceUrl]); + }, [ + context.apiBaseUrl, + context.entity?.tag, + baseConfluenceUrl, + fetchMissingPageTitles, + ]); useEffect(() => { const setFirstPageContent = async (): Promise => { diff --git a/plugins/confluence-plugin/src/components/PageSelector.tsx b/plugins/confluence-plugin/src/components/PageSelector.tsx index 3eef707..dc1968a 100644 --- a/plugins/confluence-plugin/src/components/PageSelector.tsx +++ b/plugins/confluence-plugin/src/components/PageSelector.tsx @@ -19,7 +19,7 @@ export default function PageSelector({ alignItems={"baseline"} w={"full"} > - Select page: + Select confluence page: From 2ea55deda7926f7383e3e9a6e0d540dd1ea889ad Mon Sep 17 00:00:00 2001 From: Martin Stone Date: Mon, 6 Jan 2025 11:09:27 -0500 Subject: [PATCH 7/9] fix a test, remove a log --- .../confluence-plugin/src/api/fetchConfluencePluginConfig.ts | 1 - plugins/confluence-plugin/src/components/PageSelector.test.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts b/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts index fdb2bb1..e915559 100644 --- a/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts +++ b/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts @@ -11,7 +11,6 @@ export const fetchConfluencePluginConfig = async ( const data = await response.json(); return data.info["x-cortex-definition"]["confluence-url"]; } catch (error) { - console.error("Error fetching Confluence plugin config:", error); throw error; } }; diff --git a/plugins/confluence-plugin/src/components/PageSelector.test.tsx b/plugins/confluence-plugin/src/components/PageSelector.test.tsx index f2d93df..5eeb650 100644 --- a/plugins/confluence-plugin/src/components/PageSelector.test.tsx +++ b/plugins/confluence-plugin/src/components/PageSelector.test.tsx @@ -48,7 +48,7 @@ describe("PageSelector Component", () => { await waitFor(() => { expect(screen.getByText("Page One")).toBeInTheDocument(); expect(screen.getByText("Page Two")).toBeInTheDocument(); - expect(screen.getByText("Page ID: 3")).toBeInTheDocument(); + expect(screen.getByText("Confluence Page 3")).toBeInTheDocument(); }); }); From c6ed6391e128e8d2999297dfcd0590b33f817e26 Mon Sep 17 00:00:00 2001 From: Martin Stone Date: Mon, 6 Jan 2025 16:28:10 -0500 Subject: [PATCH 8/9] move async stuff to hooks; change deprecated wiki endpoint; adjust tests --- plugins/confluence-plugin/src/api/Cortex.ts | 8 - .../src/api/fetchConfluencePageContent.ts | 35 --- .../src/api/fetchConfluencePluginConfig.ts | 16 -- .../src/components/PageContent.test.tsx | 4 +- .../src/components/PageContent.tsx | 232 +++++++--------- .../src/components/PageSelector.test.tsx | 2 +- .../src/components/PageSelector.tsx | 2 +- plugins/confluence-plugin/src/hooks.tsx | 251 ++++++++++++++++++ .../confluence-plugin/src/mocks/mockBodies.ts | 4 +- 9 files changed, 347 insertions(+), 207 deletions(-) delete mode 100644 plugins/confluence-plugin/src/api/Cortex.ts delete mode 100644 plugins/confluence-plugin/src/api/fetchConfluencePageContent.ts delete mode 100644 plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts create mode 100644 plugins/confluence-plugin/src/hooks.tsx diff --git a/plugins/confluence-plugin/src/api/Cortex.ts b/plugins/confluence-plugin/src/api/Cortex.ts deleted file mode 100644 index 2f72486..0000000 --- a/plugins/confluence-plugin/src/api/Cortex.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const getEntityYaml = async ( - baseUrl: string, - entityTag: string -): Promise => { - const res = await fetch(`${baseUrl}/catalog/${entityTag}/openapi`); - - return await res.json(); -}; diff --git a/plugins/confluence-plugin/src/api/fetchConfluencePageContent.ts b/plugins/confluence-plugin/src/api/fetchConfluencePageContent.ts deleted file mode 100644 index fa10e71..0000000 --- a/plugins/confluence-plugin/src/api/fetchConfluencePageContent.ts +++ /dev/null @@ -1,35 +0,0 @@ -export const fetchConfluencePageContent = async ( - baseConfluenceUrl: string, - pageId: string | number -): Promise => { - const jiraURL = `${baseConfluenceUrl}/wiki/rest/api/content/${pageId}?expand=body.view`; - let contentResult; - try { - contentResult = await fetch(jiraURL); - } catch (error: any) { - throw new Error( - `Network error while fetching Confluence page with ID ${pageId}: ${ - (error as Error).message - }` - ); - } - if (!contentResult.ok) { - let errorStr = ""; - try { - if ( - contentResult.headers.get("content-type")?.includes("application/json") - ) { - const contentJSON: { message?: string } = await contentResult.json(); - errorStr = `Failed to fetch Confluence page with ID ${pageId}: ${ - contentJSON.message ?? JSON.stringify(contentJSON) - }`; - } else { - errorStr = await contentResult.text(); - } - } catch { - errorStr = contentResult.statusText || "Failed to fetch Confluence page"; - } - throw new Error(errorStr); - } - return contentResult.json(); -}; diff --git a/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts b/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts deleted file mode 100644 index e915559..0000000 --- a/plugins/confluence-plugin/src/api/fetchConfluencePluginConfig.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const fetchConfluencePluginConfig = async ( - apiBaseUrl: string -): Promise => { - try { - const response = await fetch( - `${apiBaseUrl}/catalog/confluence-plugin-config/openapi` - ); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const data = await response.json(); - return data.info["x-cortex-definition"]["confluence-url"]; - } catch (error) { - throw error; - } -}; diff --git a/plugins/confluence-plugin/src/components/PageContent.test.tsx b/plugins/confluence-plugin/src/components/PageContent.test.tsx index 289a776..899b163 100644 --- a/plugins/confluence-plugin/src/components/PageContent.test.tsx +++ b/plugins/confluence-plugin/src/components/PageContent.test.tsx @@ -24,7 +24,9 @@ describe("PageContent", () => { await waitFor(() => { expect( - screen.getByText("No Confluence details exist on this entity.") + screen.getByText( + "We could not find any Confluence pages associated with this entity." + ) ).toBeInTheDocument(); }); }); diff --git a/plugins/confluence-plugin/src/components/PageContent.tsx b/plugins/confluence-plugin/src/components/PageContent.tsx index 9c5455d..1a42ec3 100644 --- a/plugins/confluence-plugin/src/components/PageContent.tsx +++ b/plugins/confluence-plugin/src/components/PageContent.tsx @@ -1,162 +1,92 @@ import type React from "react"; -import { useState, useEffect, useCallback } from "react"; -import { isEmpty, isNil } from "lodash"; -import "../baseStyles.css"; +import { useState, useEffect, useMemo } from "react"; +import { isNil } from "lodash"; import { usePluginContext } from "@cortexapps/plugin-core/components"; -import { getEntityYaml } from "../api/Cortex"; -import { getConfluenceDetailsFromEntity } from "../lib/parseEntity"; import { Heading, Box } from "@chakra-ui/react"; + import Instructions from "./Instructions"; import Loading from "./Loading"; import Notice from "./Notice"; import PageSelector from "./PageSelector"; -import { fetchConfluencePageContent } from "../api/fetchConfluencePageContent"; -import { fetchConfluencePluginConfig } from "../api/fetchConfluencePluginConfig"; + +import { + usePluginConfig, + useCortexEntityDefinition, + useConfluencePageContent, +} from "../hooks"; + +import "../baseStyles.css"; const PageContent: React.FC = () => { - const [entityPages, setEntityPages] = useState([]); - const [pageContent, setPageContent] = useState(); - const [pageTitle, setPageTitle] = useState(); - const [entityPage, setEntityPage] = useState(); - const [baseConfluenceUrl, setBaseConfluenceUrl] = useState(""); + const [entityPage, setEntityPage] = useState(); const [errorStr, setErrorStr] = useState(""); const context = usePluginContext(); - const fetchPageContent = useCallback( - async (pages: EntityPageI[], pageId: string | number): Promise => { - if (pages.length === 0) return; - setEntityPage(pageId); - setErrorStr("loading-content"); - try { - const contentJSON = await fetchConfluencePageContent( - baseConfluenceUrl, - pageId - ); - setPageContent(contentJSON.body.view.value); - setPageTitle(contentJSON.title); - setErrorStr(""); - } catch (error) { - setErrorStr(error.message); - } - }, - [baseConfluenceUrl] + const { isLoading: isPluginConfigLoading, pluginConfig } = usePluginConfig( + "confluence-plugin-config" ); - const fetchMissingPageTitles = useCallback( - async (pages: EntityPageI[]): Promise => { - if (pages.length === 0) return []; - const updatedPages = await Promise.all( - pages.map(async (page) => { - if (page.title && page.title.length > 0) { - return page; - } - try { - const contentJSON = await fetchConfluencePageContent( - baseConfluenceUrl, - page.id - ); - return { - ...page, - title: - page.title && page.title.length > 0 - ? page.title - : contentJSON.title, - }; - } catch (error) { - console.error( - `Error fetching page title for page with ID ${page.id}: ${ - (error as Error).message - }` - ); - return page; - } - }) - ); - return updatedPages; - }, - [baseConfluenceUrl] + const { isLoading: isEntityDefinitionLoading, entityDefinition } = + useCortexEntityDefinition(context.entity?.tag ?? ""); + + const baseConfluenceUrl = useMemo( + () => pluginConfig?.info?.["x-cortex-definition"]?.["confluence-url"] ?? "", + [pluginConfig] ); - useEffect(() => { - if (!context?.apiBaseUrl) return; - const getConfig = async (): Promise => { - setErrorStr("loading"); - try { - const newConfluenceUrl = await fetchConfluencePluginConfig( - context.apiBaseUrl - ); - setBaseConfluenceUrl(newConfluenceUrl); - setErrorStr(!newConfluenceUrl ? "instructions" : ""); - } catch { - setErrorStr("instructions"); + const entityPages = useMemo((): EntityPageI[] => { + if (!entityDefinition) return []; + const entityPages: EntityPageI[] = []; + if (Array.isArray(entityDefinition.info?.["x-cortex-confluence"]?.pages)) { + for (const page of entityDefinition.info["x-cortex-confluence"].pages) { + const id = page.id as string; + const title = page.title as string; + if (id) { + entityPages.push({ id, title }); + } } - }; - void getConfig(); - }, [context?.apiBaseUrl]); + } + if (entityDefinition.info?.["x-cortex-confluence"]?.pageID) { + entityPages.push({ + id: `${entityDefinition.info["x-cortex-confluence"].pageID as string}`, + }); + } + return entityPages; + }, [entityDefinition]); + + useEffect(() => { + if (entityPages.length > 0 && !entityPage) { + setEntityPage(entityPages[0]); + } + }, [entityPages, entityPage]); + + const { isLoading: isContentLoading, contents } = + useConfluencePageContent(entityPages); + + const isLoading = useMemo( + () => + isPluginConfigLoading || isEntityDefinitionLoading || isContentLoading, + [isPluginConfigLoading, isEntityDefinitionLoading, isContentLoading] + ); useEffect(() => { if (!context.entity?.tag) { setErrorStr( - "This plugin is intended to be used within the entities. " + + "This plugin is intended to be used within entities. " + "Go to an entity, then under Plugins, select Confluence to view the Confluence page(s)." ); } + }, [context.entity?.tag]); - if (!context.apiBaseUrl || !baseConfluenceUrl) { - return; - } - - const fetchEntityYamlData = async (): Promise => { - const entityTag = context.entity?.tag; - if (!isNil(entityTag)) { - try { - setErrorStr("loading"); - const yaml = await getEntityYaml(context.apiBaseUrl, entityTag); - const fetchedEntityPages = isEmpty(yaml) - ? [] - : getConfluenceDetailsFromEntity(yaml); - if (fetchedEntityPages.length === 0) { - setErrorStr("No Confluence details exist on this entity."); - return; - } - const pagesWithTitles = await fetchMissingPageTitles( - fetchedEntityPages - ); - setEntityPages(pagesWithTitles); - } catch (error) { - setErrorStr( - `Error retrieving Confluence page: ${(error as Error).message}` - ); - console.error("Error retrieving Confluence page: ", error); - } - } - }; - void fetchEntityYamlData(); - }, [ - context.apiBaseUrl, - context.entity?.tag, - baseConfluenceUrl, - fetchMissingPageTitles, - ]); - - useEffect(() => { - const setFirstPageContent = async (): Promise => { - if (entityPages.length === 0) return; - await fetchPageContent(entityPages, entityPages[0].id); - }; - void setFirstPageContent(); - }, [baseConfluenceUrl, entityPages, fetchPageContent]); - - if (errorStr === "loading") return ; - if (errorStr === "instructions") return ; - if (errorStr && errorStr !== "loading-content") - return {errorStr}; + if (isLoading) return ; + if (!baseConfluenceUrl) return ; + if (errorStr) return {errorStr}; if (isNil(entityPage)) { return ( - We could not find any Confluence page associated with this entity. + We could not find any Confluence pages associated with this entity. ); } @@ -165,26 +95,42 @@ const PageContent: React.FC = () => { {entityPages.length > 1 && ( { + const newEntityPage = entityPages.find( + (page) => `${page.id as string}` === pageId + ); + if (newEntityPage) setEntityPage(newEntityPage); + }} pages={entityPages} - disabled={errorStr === "loading-content"} + disabled={isContentLoading} /> )} - {errorStr === "loading-content" ? ( - - ) : ( - - + + + {contents[`${entityPage.id}`]?.body && ( - - )} + )} + {contents[`${entityPage.id}`]?.errors && ( + + {contents[`${entityPage.id}`]?.errors.map((error: any) => ( + + {error.title} + + ))} + + )} + ); }; diff --git a/plugins/confluence-plugin/src/components/PageSelector.test.tsx b/plugins/confluence-plugin/src/components/PageSelector.test.tsx index 5eeb650..a89e845 100644 --- a/plugins/confluence-plugin/src/components/PageSelector.test.tsx +++ b/plugins/confluence-plugin/src/components/PageSelector.test.tsx @@ -65,7 +65,7 @@ describe("PageSelector Component", () => { fireEvent.change(screen.getByRole("combobox"), { target: { value: "2" } }); await waitFor(() => { - expect(mockOnChangeHandler).toHaveBeenCalledWith(mockPages, "2"); + expect(mockOnChangeHandler).toHaveBeenCalledWith("2"); }); }); diff --git a/plugins/confluence-plugin/src/components/PageSelector.tsx b/plugins/confluence-plugin/src/components/PageSelector.tsx index dc1968a..f34383b 100644 --- a/plugins/confluence-plugin/src/components/PageSelector.tsx +++ b/plugins/confluence-plugin/src/components/PageSelector.tsx @@ -23,7 +23,7 @@ export default function PageSelector({