This is an automated email from the ASF dual-hosted git repository. porcelli pushed a commit to branch KOGITO-8015-feature-preview in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools-temporary-rnd-do-not-use.git
commit 0702883c2cf707f431712196861f1a2569c45fdd Author: Fabrizio Antonangeli <[email protected]> AuthorDate: Tue Jan 31 14:43:30 2023 +0100 KOGITO-8426: Implement a quickstart guide component in the settings section (#1431) * KOGITO-8147 Refactor the app bar and menu according to UX redesign * refactor to function style * remove new home page * remove old home page * Updated OnlineEditorPage.tsx * Add Settings routes and Settings Nav sidebar * GitHubSettings page wip * Rename packages/serverless-logic-sandbox/src/settings/github/GitHubSettingsTab.tsx -> packages/serverless-logic-sandbox/src/settings/github/GitHubSettings.tsx * GitHubSettings page * QuickStart implementation * Removed quickstart link after branching * add KieSandboxExtendedServicesSettings route * Fix expand content when sidebar is collapsed * Moved new settings routes to src/newSettings * Completing the new settings folder * WIP OpenShiftSettings * OpenShiftSettings page * Fix "setup" modal hidden by "add connection" modal * Fix: Can't perform a React state update on an unmounted component * Mv ServiceAccountSettingsTab -> ServiceAccountSettings * ServiceAccountSettings * R packages/serverless-logic-sandbox/src/newSettings/serviceRegistry/ServiceRegistrySettingsTab.tsx -> packages/serverless-logic-sandbox/src/newSettings/serviceRegistry/ServiceRegistrySettings.tsx * Refactor ServiceRegistrySettings * R packages/serverless-logic-sandbox/src/newSettings/kafka/ApacheKafkaSettingsTab.tsx -> packages/serverless-logic-sandbox/src/newSettings/kafka/ApacheKafkaSettings.tsx * Refactor ApacheKafkaSettings * R packages/serverless-logic-sandbox/src/newSettings/featurePreview/FeaturePreviewSettingsTab.tsx -> packages/serverless-logic-sandbox/src/newSettings/featurePreview/FeaturePreviewSettings.tsx * Refactor FeaturePreviewSettings * Sidebar title same as OpenShift Console * deleted: packages/serverless-logic-sandbox/src/newSettings/SettingsModalBody.tsx removed settings modal related code * Fix Copyright * Add check not to show the loading in modal if we are in settings route * Removed unnecessary code for input focus * Code review * Fixed issues after merge conflicts * Fix issue: mocal backdrop goes under quickstart when they are both open * Add missing peer dependencies as for patternfly-quickstarts README * Add GitHubTokenQuickStart * Fix issue after merge * add OpenShiftIntegrationQuickStart * disabled use of querystring and created SettingsPageProps type * Rewrite GitHubTokenQuickStart and OpenShiftIntegrationQuickStart in html for better rendering * Add ApplicationServicesIntegrationQuickStart * Add all quickstarts and improved integration * Content review and html code formatting * Fix merge issue --------- Co-authored-by: Xaiofeng Bai <[email protected]> --- packages/serverless-logic-web-tools/package.json | 2 + .../src/homepage/pageTemplate/OnlineEditorPage.tsx | 54 ++- packages/serverless-logic-web-tools/src/index.tsx | 1 + .../src/navigation/RoutesSwitch.tsx | 7 +- .../KieSandboxExtendedServicesSettings.tsx | 282 +++++++------- .../src/newSettings/github/GitHubSettings.tsx | 108 +++--- .../src/newSettings/kafka/ApacheKafkaSettings.tsx | 291 +++++++------- .../newSettings/openshift/OpenShiftSettings.tsx | 32 +- .../openshift/OpenShiftSettingsSimpleConfig.tsx | 17 +- .../src/newSettings/routes/SettingsPageRoutes.tsx | 19 +- .../serviceAccount/ServiceAccountSettings.tsx | 267 +++++++------ .../serviceRegistry/ServiceRegistrySettings.tsx | 287 +++++++------- .../src/newSettings/types.ts | 17 + .../ApplicationServicesIntegrationQuickStart.ts | 421 +++++++++++++++++++++ .../src/quickstarts-data/GitHubTokenQuickStart.ts | 222 +++++++++++ .../OpenShiftIntegrationQuickStart.ts | 194 ++++++++++ .../src/quickstarts-data/index.ts | 27 ++ .../serverless-logic-web-tools-github-repo.png | Bin 0 -> 55617 bytes .../serverless-logic-web-tools-openshift-info.png | Bin 0 -> 129890 bytes ...erverless-logic-web-tools-openshift-project.png | Bin 0 -> 166585 bytes .../static/resources/style.css | 8 + pnpm-lock.yaml | 319 ++++++++++++++-- 22 files changed, 1941 insertions(+), 634 deletions(-) diff --git a/packages/serverless-logic-web-tools/package.json b/packages/serverless-logic-web-tools/package.json index a183ee802b..f023e2d7a8 100644 --- a/packages/serverless-logic-web-tools/package.json +++ b/packages/serverless-logic-web-tools/package.json @@ -49,6 +49,7 @@ "@kie-tools/text-editor": "workspace:*", "@octokit/plugin-rest-endpoint-methods": "^5.0.1", "@octokit/rest": "^18.5.3", + "@patternfly/quickstarts": "^2.3.2", "@patternfly/react-core": "^4.157.3", "@patternfly/react-icons": "^4.11.17", "@patternfly/react-tokens": "^4.33.1", @@ -67,6 +68,7 @@ "react-dropzone": "^11.4.2", "react-router": "^5.2.1", "react-router-dom": "^5.2.1", + "showdown": "^2.1.0", "vscode-languageserver-types": "^3.16.0", "yaml": "^2.0.1" }, diff --git a/packages/serverless-logic-web-tools/src/homepage/pageTemplate/OnlineEditorPage.tsx b/packages/serverless-logic-web-tools/src/homepage/pageTemplate/OnlineEditorPage.tsx index 7f55b5605a..a6bf24d405 100644 --- a/packages/serverless-logic-web-tools/src/homepage/pageTemplate/OnlineEditorPage.tsx +++ b/packages/serverless-logic-web-tools/src/homepage/pageTemplate/OnlineEditorPage.tsx @@ -15,36 +15,43 @@ */ import * as React from "react"; -import { useMemo } from "react"; +import { QuickStartContainer, QuickStartContainerProps } from "@patternfly/quickstarts"; import { + Brand, + Button, Masthead, MastheadBrand, + MastheadContent, MastheadMain, MastheadToggle, - Button, - Brand, - MastheadContent, - ToolbarContent, + PageSidebar, + SkipToContent, Toolbar, + ToolbarContent, ToolbarGroup, ToolbarItem, - PageSidebar, - SkipToContent, } from "@patternfly/react-core"; import { Page } from "@patternfly/react-core/dist/js/components/Page"; +import { Tooltip } from "@patternfly/react-core/dist/js/components/Tooltip"; +import { BarsIcon, ExclamationIcon } from "@patternfly/react-icons/dist/js/icons"; +import { useMemo, useState } from "react"; import { useHistory, useRouteMatch } from "react-router"; +import { useLocation } from "react-router-dom"; import { KieSandboxExtendedServicesIcon } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesIcon"; import { useRoutes } from "../../navigation/Hooks"; +import { SettingsPageNav } from "../../newSettings/uiNav/SettingsPageNav"; import { OpenshiftDeploymentsDropdown } from "../../openshift/dropdown/OpenshiftDeploymentsDropdown"; +import { + ApplicationServicesIntegrationQuickStart, + GitHubTokenQuickStart, + OpenShiftIntegrationQuickStart, +} from "../../quickstarts-data"; import { SettingsButton } from "../../settings/SettingsButton"; import { HomePageNav } from "../uiNav/HomePageNav"; -import { useLocation } from "react-router-dom"; -import { useState } from "react"; -import { SettingsPageNav } from "../../newSettings/uiNav/SettingsPageNav"; -import { Tooltip } from "@patternfly/react-core/dist/js/components/Tooltip"; -import { ExclamationIcon, BarsIcon } from "@patternfly/react-icons/dist/js/icons"; -export function OnlineEditorPage(props: { children?: React.ReactNode }) { +export type OnlineEditorPageProps = { children?: React.ReactNode; pageContainerRef: React.RefObject<HTMLDivElement> }; + +export function OnlineEditorPage(props: OnlineEditorPageProps) { const history = useHistory(); const routes = useRoutes(); const [isNavOpen, setIsNavOpen] = useState(true); @@ -52,6 +59,17 @@ export function OnlineEditorPage(props: { children?: React.ReactNode }) { const navToggle = () => { setIsNavOpen(!isNavOpen); }; + const [activeQuickStartID, setActiveQuickStartID] = useState(""); + const [allQuickStartStates, setAllQuickStartStates] = useState({}); + + const drawerProps: QuickStartContainerProps = { + quickStarts: [GitHubTokenQuickStart, OpenShiftIntegrationQuickStart, ApplicationServicesIntegrationQuickStart], + activeQuickStartID, + allQuickStartStates, + setActiveQuickStartID, + setAllQuickStartStates, + useQueryParams: false, + }; const isChromiumBased = useMemo(() => { const agent = window.navigator.userAgent.toLowerCase(); @@ -145,8 +163,12 @@ export function OnlineEditorPage(props: { children?: React.ReactNode }) { const pageSkipToContent = <SkipToContent href={`#${mainContainerId}`}>Skip to content</SkipToContent>; return ( - <Page header={masthead} sidebar={sidebar} skipToContent={pageSkipToContent} mainContainerId={mainContainerId}> - {props.children} - </Page> + <QuickStartContainer {...drawerProps}> + <div id="page-container" ref={props.pageContainerRef}> + <Page header={masthead} sidebar={sidebar} skipToContent={pageSkipToContent} mainContainerId={mainContainerId}> + {props.children} + </Page> + </div> + </QuickStartContainer> ); } diff --git a/packages/serverless-logic-web-tools/src/index.tsx b/packages/serverless-logic-web-tools/src/index.tsx index 6a601443be..d23a1dc5e6 100644 --- a/packages/serverless-logic-web-tools/src/index.tsx +++ b/packages/serverless-logic-web-tools/src/index.tsx @@ -15,6 +15,7 @@ */ import "@patternfly/react-core/dist/styles/base.css"; +import "@patternfly/quickstarts/dist/quickstarts.min.css"; import * as React from "react"; import * as ReactDOM from "react-dom"; import { App } from "./App"; diff --git a/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx b/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx index 004b9837b9..ad68babfe9 100644 --- a/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx +++ b/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx @@ -15,7 +15,7 @@ */ import * as React from "react"; -import { useMemo } from "react"; +import { useMemo, useRef } from "react"; import { Route, Switch, useRouteMatch } from "react-router-dom"; import { useRoutes } from "./Hooks"; import { OnlineEditorPage } from "../homepage/pageTemplate/OnlineEditorPage"; @@ -29,6 +29,7 @@ export function RoutesSwitch() { const buildInfo = useMemo(() => { return process.env["WEBPACK_REPLACE__buildInfo"]; }, []); + const pageContainerRef = useRef<HTMLDivElement>(null); const renderPage = (routeProps: { location: { @@ -45,8 +46,8 @@ export function RoutesSwitch() { }; }) => { return ( - <OnlineEditorPage> - {!isRouteInSettingsSection ? <HomePageRoutes /> : <SettingsPageRoutes />} + <OnlineEditorPage pageContainerRef={pageContainerRef}> + {!isRouteInSettingsSection ? <HomePageRoutes /> : <SettingsPageRoutes pageContainerRef={pageContainerRef} />} {buildInfo && ( <div className={"kie-tools--build-info"}> <Label>{buildInfo}</Label> diff --git a/packages/serverless-logic-web-tools/src/newSettings/extendedServices/KieSandboxExtendedServicesSettings.tsx b/packages/serverless-logic-web-tools/src/newSettings/extendedServices/KieSandboxExtendedServicesSettings.tsx index 4e163afd88..37a1a2382d 100644 --- a/packages/serverless-logic-web-tools/src/newSettings/extendedServices/KieSandboxExtendedServicesSettings.tsx +++ b/packages/serverless-logic-web-tools/src/newSettings/extendedServices/KieSandboxExtendedServicesSettings.tsx @@ -29,17 +29,21 @@ import { CheckCircleIcon } from "@patternfly/react-icons/dist/js/icons/check-cir import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon"; import { TimesIcon } from "@patternfly/react-icons/dist/js/icons/times-icon"; import * as React from "react"; -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useMemo, useState, useContext } from "react"; import { useKieSandboxExtendedServices } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesContext"; import { KieSandboxExtendedServicesStatus } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesStatus"; import { ExtendedServicesConfig, useSettings, useSettingsDispatch } from "../../settings/SettingsContext"; +import { QuickStartContext, QuickStartContextValues } from "@patternfly/quickstarts"; +import { QuickStartIds } from "../../quickstarts-data"; +import { SettingsPageProps } from "../types"; -export function KieSandboxExtendedServicesSettings() { +export function KieSandboxExtendedServicesSettings(props: SettingsPageProps) { const settings = useSettings(); const settingsDispatch = useSettingsDispatch(); const kieSandboxExtendedServices = useKieSandboxExtendedServices(); const [config, setConfig] = useState(settings.kieSandboxExtendedServices.config); const [isModalOpen, setIsModalOpen] = useState(false); + const qsContext = useContext<QuickStartContextValues>(QuickStartContext); const isCurrentConfigValid = useMemo( () => config.host.trim().length > 0 && config.buildUrl().trim().length > 0, @@ -138,136 +142,154 @@ export function KieSandboxExtendedServicesSettings() { </PageSection> </PageSection> - <Modal - title="Add connection" - isOpen={ - isModalOpen && - kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.RUNNING && - !kieSandboxExtendedServices.isModalOpen - } - onClose={handleModalToggle} - variant={ModalVariant.large} - > - <Form> - <FormAlert> - <Alert - variant="danger" - title={ - <Text> - You are not connected to KIE Sandbox Extended Services.{" "} - <a - onClick={() => { - kieSandboxExtendedServices.setInstallTriggeredBy(undefined); - kieSandboxExtendedServices.setModalOpen(true); - }} - > - Click to setup - </a> - </Text> - } - aria-live="polite" - isInline - /> - </FormAlert> - <PageSection variant={"light"} isFilled={true} style={{ height: "100%" }}> - <FormGroup - label={"Host"} - labelIcon={ - <Popover bodyContent={"The host associated with the KIE Sandbox Extended Services URL instance."}> - <button - type="button" - aria-label="More info for host field" - onClick={(e) => e.preventDefault()} - aria-describedby="host-server-field" - className="pf-c-form__group-label-help" - > - <HelpIcon noVerticalAlign /> - </button> - </Popover> - } - isRequired - fieldId="host-server-field" - > - <InputGroup className="pf-u-mt-sm"> - <TextInput - autoComplete={"off"} - isRequired - type="text" - id="host-server-field" - name="host-server-field" - aria-label="Host field" - aria-describedby="host-server-field-helper" - value={config.host} - onChange={onHostChanged} - tabIndex={1} - data-testid="host-text-field" - /> - <InputGroupText> - <Button isSmall variant="plain" aria-label="Clear host button" onClick={onClearHost}> - <TimesIcon /> - </Button> - </InputGroupText> - </InputGroup> - </FormGroup> - <FormGroup - label={"Port"} - labelIcon={ - <Popover - bodyContent={"The port number associated with the KIE Sandbox Extended Services URL instance."} - > - <button - type="button" - aria-label="More info for port field" - onClick={(e) => e.preventDefault()} - aria-describedby="port-field" - className="pf-c-form__group-label-help" + {props.pageContainerRef.current && ( + <Modal + title="Add connection" + isOpen={ + isModalOpen && + kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.RUNNING && + !kieSandboxExtendedServices.isModalOpen + } + onClose={handleModalToggle} + variant={ModalVariant.large} + appendTo={props.pageContainerRef.current || document.body} + > + <Form> + <FormAlert> + <Alert + variant="danger" + title={ + <Text> + You are not connected to KIE Sandbox Extended Services.{" "} + <a + onClick={() => { + kieSandboxExtendedServices.setInstallTriggeredBy(undefined); + kieSandboxExtendedServices.setModalOpen(true); + }} + > + Click to setup + </a> + </Text> + } + aria-live="polite" + isInline + /> + </FormAlert> + <PageSection variant={"light"} isFilled={true} style={{ height: "100%" }}> + <FormGroup + label={"Host"} + labelIcon={ + <Popover bodyContent={"The host associated with the KIE Sandbox Extended Services URL instance."}> + <button + type="button" + aria-label="More info for host field" + onClick={(e) => e.preventDefault()} + aria-describedby="host-server-field" + className="pf-c-form__group-label-help" + > + <HelpIcon noVerticalAlign /> + </button> + </Popover> + } + isRequired + fieldId="host-server-field" + > + <InputGroup className="pf-u-mt-sm"> + <TextInput + autoComplete={"off"} + isRequired + type="text" + id="host-server-field" + name="host-server-field" + aria-label="Host field" + aria-describedby="host-server-field-helper" + value={config.host} + onChange={onHostChanged} + tabIndex={1} + data-testid="host-text-field" + /> + <InputGroupText> + <Button isSmall variant="plain" aria-label="Clear host button" onClick={onClearHost}> + <TimesIcon /> + </Button> + </InputGroupText> + </InputGroup> + </FormGroup> + <FormGroup + label={"Port"} + labelIcon={ + <Popover + bodyContent={"The port number associated with the KIE Sandbox Extended Services URL instance."} > - <HelpIcon noVerticalAlign /> - </button> - </Popover> - } - isRequired - fieldId="port-field" - > - <InputGroup className="pf-u-mt-sm"> - <TextInput - autoComplete={"off"} - isRequired - type="text" - id="port-field" - name="port-field" - aria-label="Port field" - aria-describedby="port-field-helper" - value={config.port} - onChange={onPortChanged} - tabIndex={2} - data-testid="port-text-field" - /> - <InputGroupText> - <Button isSmall variant="plain" aria-label="Clear port button" onClick={onClearPort}> - <TimesIcon /> - </Button> - </InputGroupText> - </InputGroup> - </FormGroup> - <ActionGroup> - <Button - isDisabled={!isCurrentConfigValid} - id="kie-sandbox-extended-services-config-connect-button" - key="connect" - variant="primary" - onClick={onConnect} - data-testid="connect-config-button" + <button + type="button" + aria-label="More info for port field" + onClick={(e) => e.preventDefault()} + aria-describedby="port-field" + className="pf-c-form__group-label-help" + > + <HelpIcon noVerticalAlign /> + </button> + </Popover> + } + isRequired + fieldId="port-field" > - Connect - </Button> - <Button key="cancel" variant="link" onClick={handleModalToggle} data-testid="connect-cancel-button"> - Connect - </Button> - </ActionGroup> - </PageSection> - </Form> - </Modal> + <InputGroup className="pf-u-mt-sm"> + <TextInput + autoComplete={"off"} + isRequired + type="text" + id="port-field" + name="port-field" + aria-label="Port field" + aria-describedby="port-field-helper" + value={config.port} + onChange={onPortChanged} + tabIndex={2} + data-testid="port-text-field" + /> + <InputGroupText> + <Button isSmall variant="plain" aria-label="Clear port button" onClick={onClearPort}> + <TimesIcon /> + </Button> + </InputGroupText> + </InputGroup> + <br /> + <Button + isInline={true} + key="quickstart" + variant="link" + onClick={() => { + qsContext.setActiveQuickStartID?.(QuickStartIds.OpenShiftIntegrationQuickStart); + setTimeout( + () => qsContext.setQuickStartTaskNumber?.(QuickStartIds.OpenShiftIntegrationQuickStart, 0), + 0 + ); + }} + > + Need help getting started? Follow our quickstart guide. + </Button> + </FormGroup> + <ActionGroup> + <Button + isDisabled={!isCurrentConfigValid} + id="kie-sandbox-extended-services-config-connect-button" + key="connect" + variant="primary" + onClick={onConnect} + data-testid="connect-config-button" + > + Connect + </Button> + <Button key="cancel" variant="link" onClick={handleModalToggle} data-testid="connect-cancel-button"> + Connect + </Button> + </ActionGroup> + </PageSection> + </Form> + </Modal> + )} </Page> ); } diff --git a/packages/serverless-logic-web-tools/src/newSettings/github/GitHubSettings.tsx b/packages/serverless-logic-web-tools/src/newSettings/github/GitHubSettings.tsx index bd3be0578f..2a13d4dbc7 100644 --- a/packages/serverless-logic-web-tools/src/newSettings/github/GitHubSettings.tsx +++ b/packages/serverless-logic-web-tools/src/newSettings/github/GitHubSettings.tsx @@ -14,6 +14,7 @@ * limitations under the License. */ +import { QuickStartContext, QuickStartContextValues } from "@patternfly/quickstarts"; import { Modal, ModalVariant } from "@patternfly/react-core"; import { Button, ButtonVariant } from "@patternfly/react-core/dist/js/components/Button"; import { EmptyState, EmptyStateBody, EmptyStateIcon } from "@patternfly/react-core/dist/js/components/EmptyState"; @@ -23,15 +24,16 @@ import { Page, PageSection } from "@patternfly/react-core/dist/js/components/Pag import { Spinner } from "@patternfly/react-core/dist/js/components/Spinner"; import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; import { TextInput } from "@patternfly/react-core/dist/js/components/TextInput"; -import { AddCircleOIcon } from "@patternfly/react-icons"; -import { CheckCircleIcon } from "@patternfly/react-icons/dist/js/icons/check-circle-icon"; +import { AddCircleOIcon, CheckCircleIcon } from "@patternfly/react-icons"; import { ExclamationTriangleIcon } from "@patternfly/react-icons/dist/js/icons/exclamation-triangle-icon"; import { ExternalLinkAltIcon } from "@patternfly/react-icons/dist/js/icons/external-link-alt-icon"; import { GithubIcon } from "@patternfly/react-icons/dist/js/icons/github-icon"; import * as React from "react"; -import { useCallback, useMemo, useRef, useState } from "react"; +import { useCallback, useContext, useMemo, useRef, useState } from "react"; import { makeCookieName } from "../../cookies"; +import { QuickStartIds } from "../../quickstarts-data"; import { AuthStatus, useSettings, useSettingsDispatch } from "../../settings/SettingsContext"; +import { SettingsPageProps } from "../types"; export const GITHUB_OAUTH_TOKEN_SIZE = 40; export const GITHUB_TOKENS_URL = "https://github.com/settings/tokens"; @@ -49,9 +51,10 @@ enum GitHubTokenScope { REPO = "repo", } -export function GitHubSettings() { +export function GitHubSettings(props: SettingsPageProps) { const settings = useSettings(); const settingsDispatch = useSettingsDispatch(); + const qsContext = useContext<QuickStartContextValues>(QuickStartContext); const [potentialGitHubToken, setPotentialGitHubToken] = useState<string | undefined>(undefined); const [isGitHubTokenValid, setIsGitHubTokenValid] = useState(true); @@ -180,46 +183,63 @@ export function GitHubSettings() { </PageSection> </PageSection> - <Modal - title="Create new token" - isOpen={isModalOpen && settings.github.authStatus !== AuthStatus.LOADING} - onClose={handleModalToggle} - variant={ModalVariant.large} - > - <Form onSubmit={(e) => e.preventDefault()}> - <h3> - <a href={GITHUB_TOKENS_URL} target={"_blank"} rel="noopener noreferrer"> - Create a new token - <ExternalLinkAltIcon /> - </a> - </h3> - <FormGroup - isRequired={true} - helperTextInvalid={githubTokenHelperText} - validated={githubTokenValidated} - label={"Token"} - fieldId={"github-pat"} - helperText={"Your token must include the 'repo' scope."} - > - <InputGroup> - <TextInput - ref={tokenInput} - autoComplete={"off"} - id="token-input" - name="tokenInput" - aria-describedby="token-text-input-helper" - placeholder={"Paste your GitHub token here"} - maxLength={GITHUB_OAUTH_TOKEN_SIZE} - validated={githubTokenValidated} - value={githubTokenToDisplay} - onPaste={onPasteGitHubToken} - tabIndex={1} - /> - </InputGroup> - </FormGroup> - <br /> - </Form> - </Modal> + {props.pageContainerRef.current && ( + <Modal + title="Create new token" + isOpen={isModalOpen && settings.github.authStatus !== AuthStatus.LOADING} + onClose={handleModalToggle} + variant={ModalVariant.large} + appendTo={props.pageContainerRef.current} + > + <Form onSubmit={(e) => e.preventDefault()}> + <h3> + <a href={GITHUB_TOKENS_URL} target={"_blank"} rel="noopener noreferrer"> + Create a new token + <ExternalLinkAltIcon /> + </a> + </h3> + <FormGroup + isRequired={true} + helperTextInvalid={githubTokenHelperText} + validated={githubTokenValidated} + label={"Token"} + fieldId={"github-pat"} + helperText={"Your token must include the 'repo' scope."} + > + <InputGroup> + <TextInput + ref={tokenInput} + autoComplete={"off"} + id="token-input" + name="tokenInput" + aria-describedby="token-text-input-helper" + placeholder={"Paste your GitHub token here"} + maxLength={GITHUB_OAUTH_TOKEN_SIZE} + validated={githubTokenValidated} + value={githubTokenToDisplay} + onPaste={onPasteGitHubToken} + tabIndex={1} + /> + </InputGroup> + </FormGroup> + <TextContent> + <Text> + <Button + isInline={true} + key="quickstart" + variant="link" + onClick={() => { + qsContext.setActiveQuickStartID?.(QuickStartIds.GitHubTokenQuickStart); + setTimeout(() => qsContext.setQuickStartTaskNumber?.(QuickStartIds.GitHubTokenQuickStart, 0), 0); + }} + > + Need help getting started? Follow our quickstart guide. + </Button> + </Text> + </TextContent> + </Form> + </Modal> + )} </Page> ); } diff --git a/packages/serverless-logic-web-tools/src/newSettings/kafka/ApacheKafkaSettings.tsx b/packages/serverless-logic-web-tools/src/newSettings/kafka/ApacheKafkaSettings.tsx index 7df8cb63dd..241cdbc1a6 100644 --- a/packages/serverless-logic-web-tools/src/newSettings/kafka/ApacheKafkaSettings.tsx +++ b/packages/serverless-logic-web-tools/src/newSettings/kafka/ApacheKafkaSettings.tsx @@ -29,20 +29,24 @@ import { CheckCircleIcon } from "@patternfly/react-icons/dist/js/icons/check-cir import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon"; import { TimesIcon } from "@patternfly/react-icons/dist/js/icons/times-icon"; import * as React from "react"; -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useMemo, useState, useContext } from "react"; import { Link } from "react-router-dom"; import { useKieSandboxExtendedServices } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesContext"; import { KieSandboxExtendedServicesStatus } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesStatus"; import { routes } from "../../navigation/Routes"; import { useSettings, useSettingsDispatch } from "../SettingsContext"; import { EMPTY_CONFIG, isKafkaConfigValid, resetConfigCookie, saveConfigCookie } from "./KafkaSettingsConfig"; +import { QuickStartContext, QuickStartContextValues } from "@patternfly/quickstarts"; +import { QuickStartIds } from "../../quickstarts-data"; +import { SettingsPageProps } from "../types"; -export function ApacheKafkaSettings() { +export function ApacheKafkaSettings(props: SettingsPageProps) { const settings = useSettings(); const settingsDispatch = useSettingsDispatch(); const [config, setConfig] = useState(settings.apacheKafka.config); const kieSandboxExtendedServices = useKieSandboxExtendedServices(); const [isModalOpen, setIsModalOpen] = useState(false); + const qsContext = useContext<QuickStartContextValues>(QuickStartContext); const handleModalToggle = useCallback(() => { setIsModalOpen((prevIsModalOpen) => !prevIsModalOpen); @@ -159,139 +163,158 @@ export function ApacheKafkaSettings() { </PageSection> </PageSection> - <Modal - title="Add Streams for Apache Kafka" - isOpen={ - isModalOpen && - kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.STOPPED && - !isStoredConfigValid - } - onClose={handleModalToggle} - variant={ModalVariant.large} - > - <Form> - {!isExtendedServicesRunning && ( - <FormAlert> - <Alert - variant="danger" - title={ - <Text> - Connect to{" "} - <Link to={routes.settings.kie_sandbox_extended_services.path({})}> - KIE Sandbox Extended Services - </Link>{" "} - before configuring your Streams for Apache Kafka instance - </Text> - } - aria-live="polite" - isInline - /> - </FormAlert> - )} - <FormGroup - label={"Bootstrap Server"} - labelIcon={ - <Popover bodyContent={"The bootstrap server associated with your Streams for Apache Kafka instance."}> - <button - type="button" - aria-label="More info for bootstrap server field" - onClick={(e) => e.preventDefault()} - aria-describedby="bootstrap-server-field" - className="pf-c-form__group-label-help" - > - <HelpIcon noVerticalAlign /> - </button> - </Popover> - } - isRequired - fieldId="bootstrap-server-field" - > - <InputGroup className="pf-u-mt-sm"> - <TextInput - autoComplete={"off"} - isRequired - type="text" - id="bootstrap-server-field" - name="bootstrap-server-field" - aria-label="Bootstrap server field" - aria-describedby="bootstrap-server-field-helper" - value={config.bootstrapServer} - onChange={onBootstrapServerChanged} - tabIndex={1} - data-testid="bootstrap-server-text-field" - /> - <InputGroupText> - <Button - isSmall - variant="plain" - aria-label="Clear bootstrap server button" - onClick={onClearBootstraServer} - > - <TimesIcon /> - </Button> - </InputGroupText> - </InputGroup> - </FormGroup> - <FormGroup - label={"Topic"} - labelIcon={ - <Popover bodyContent={"The topic that messages will flow in."}> - <button - type="button" - aria-label="More info for topic field" - onClick={(e) => e.preventDefault()} - aria-describedby="topic-field" - className="pf-c-form__group-label-help" - > - <HelpIcon noVerticalAlign /> - </button> - </Popover> - } - isRequired - fieldId="topic-field" - > - <InputGroup className="pf-u-mt-sm"> - <TextInput - autoComplete={"off"} - isRequired - type="text" - id="topic-field" - name="topic-field" - aria-label="Topic field" - aria-describedby="topic-field-helper" - value={config.topic} - onChange={onTopicChanged} - tabIndex={2} - data-testid="topic-text-field" - /> - <InputGroupText> - <Button isSmall variant="plain" aria-label="Clear topic button" onClick={onClearTopic}> - <TimesIcon /> - </Button> - </InputGroupText> - </InputGroup> - </FormGroup> - <TextContent> - <Text component={TextVariants.p}> - <b>Note</b>: You must also provide{" "} - <Link to={routes.settings.service_account.path({})}>Service Account</Link> so the connection with your - Streams for Apache Kafka instance can be properly established. - </Text> - </TextContent> - <ActionGroup> - <Button - isDisabled={!isCurrentConfigValid} - id="apache-kafka-config-apply-button" - key="save" - variant="primary" - onClick={onApply} - data-testid="apply-config-button" + {props.pageContainerRef.current && ( + <Modal + title="Add Streams for Apache Kafka" + isOpen={ + isModalOpen && + kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.STOPPED && + !isStoredConfigValid + } + onClose={handleModalToggle} + variant={ModalVariant.large} + appendTo={props.pageContainerRef.current || document.body} + > + <Form> + {!isExtendedServicesRunning && ( + <FormAlert> + <Alert + variant="danger" + title={ + <Text> + Connect to{" "} + <Link to={routes.settings.kie_sandbox_extended_services.path({})}> + KIE Sandbox Extended Services + </Link>{" "} + before configuring your Streams for Apache Kafka instance + </Text> + } + aria-live="polite" + isInline + /> + </FormAlert> + )} + <FormGroup + label={"Bootstrap Server"} + labelIcon={ + <Popover bodyContent={"The bootstrap server associated with your Streams for Apache Kafka instance."}> + <button + type="button" + aria-label="More info for bootstrap server field" + onClick={(e) => e.preventDefault()} + aria-describedby="bootstrap-server-field" + className="pf-c-form__group-label-help" + > + <HelpIcon noVerticalAlign /> + </button> + </Popover> + } + isRequired + fieldId="bootstrap-server-field" + > + <InputGroup className="pf-u-mt-sm"> + <TextInput + autoComplete={"off"} + isRequired + type="text" + id="bootstrap-server-field" + name="bootstrap-server-field" + aria-label="Bootstrap server field" + aria-describedby="bootstrap-server-field-helper" + value={config.bootstrapServer} + onChange={onBootstrapServerChanged} + tabIndex={1} + data-testid="bootstrap-server-text-field" + /> + <InputGroupText> + <Button + isSmall + variant="plain" + aria-label="Clear bootstrap server button" + onClick={onClearBootstraServer} + > + <TimesIcon /> + </Button> + </InputGroupText> + </InputGroup> + </FormGroup> + <FormGroup + label={"Topic"} + labelIcon={ + <Popover bodyContent={"The topic that messages will flow in."}> + <button + type="button" + aria-label="More info for topic field" + onClick={(e) => e.preventDefault()} + aria-describedby="topic-field" + className="pf-c-form__group-label-help" + > + <HelpIcon noVerticalAlign /> + </button> + </Popover> + } + isRequired + fieldId="topic-field" > - Apply - </Button> - </ActionGroup> - </Form> - </Modal> + <InputGroup className="pf-u-mt-sm"> + <TextInput + autoComplete={"off"} + isRequired + type="text" + id="topic-field" + name="topic-field" + aria-label="Topic field" + aria-describedby="topic-field-helper" + value={config.topic} + onChange={onTopicChanged} + tabIndex={2} + data-testid="topic-text-field" + /> + <InputGroupText> + <Button isSmall variant="plain" aria-label="Clear topic button" onClick={onClearTopic}> + <TimesIcon /> + </Button> + </InputGroupText> + </InputGroup> + </FormGroup> + <TextContent> + <Text component={TextVariants.p}> + <b>Note</b>: You must also provide{" "} + <Link to={routes.settings.service_account.path({})}>Service Account</Link> so the connection with your + Streams for Apache Kafka instance can be properly established. + </Text> + <br /> + <Button + isInline={true} + key="quickstart" + variant="link" + onClick={() => { + qsContext.setActiveQuickStartID?.(QuickStartIds.ApplicationServicesIntegrationQuickStart); + setTimeout( + () => + qsContext.setQuickStartTaskNumber?.(QuickStartIds.ApplicationServicesIntegrationQuickStart, 2), + 0 + ); + }} + > + Need help getting started? Follow our quickstart guide. + </Button> + </TextContent> + <ActionGroup> + <Button + isDisabled={!isCurrentConfigValid} + id="apache-kafka-config-apply-button" + key="save" + variant="primary" + onClick={onApply} + data-testid="apply-config-button" + > + Apply + </Button> + </ActionGroup> + </Form> + </Modal> + )} </Page> ); } diff --git a/packages/serverless-logic-web-tools/src/newSettings/openshift/OpenShiftSettings.tsx b/packages/serverless-logic-web-tools/src/newSettings/openshift/OpenShiftSettings.tsx index 8454b667cd..3accf80c6a 100644 --- a/packages/serverless-logic-web-tools/src/newSettings/openshift/OpenShiftSettings.tsx +++ b/packages/serverless-logic-web-tools/src/newSettings/openshift/OpenShiftSettings.tsx @@ -32,10 +32,11 @@ import { routes } from "../../navigation/Routes"; import { OpenShiftInstanceStatus } from "../../openshift/OpenShiftInstanceStatus"; import { obfuscate } from "../github/GitHubSettings"; import { useSettings, useSettingsDispatch } from "../SettingsContext"; +import { SettingsPageProps } from "../types"; import { saveConfigCookie } from "./OpenShiftSettingsConfig"; import { OpenShiftSettingsSimpleConfig } from "./OpenShiftSettingsSimpleConfig"; -export function OpenShiftSettings() { +export function OpenShiftSettings(props: SettingsPageProps) { const settings = useSettings(); const settingsDispatch = useSettingsDispatch(); const [isModalOpen, setIsModalOpen] = useState(false); @@ -133,19 +134,22 @@ export function OpenShiftSettings() { </PageSection> </PageSection> - <Modal - title="Add connection" - isOpen={ - isModalOpen && - kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.STOPPED && - (settings.openshift.status === OpenShiftInstanceStatus.DISCONNECTED || - settings.openshift.status === OpenShiftInstanceStatus.EXPIRED) - } - onClose={handleModalToggle} - variant={ModalVariant.large} - > - <OpenShiftSettingsSimpleConfig /> - </Modal> + {props.pageContainerRef.current && ( + <Modal + title="Add connection" + isOpen={ + isModalOpen && + kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.STOPPED && + (settings.openshift.status === OpenShiftInstanceStatus.DISCONNECTED || + settings.openshift.status === OpenShiftInstanceStatus.EXPIRED) + } + onClose={handleModalToggle} + variant={ModalVariant.large} + appendTo={props.pageContainerRef.current || document.body} + > + <OpenShiftSettingsSimpleConfig /> + </Modal> + )} </Page> ); } diff --git a/packages/serverless-logic-web-tools/src/newSettings/openshift/OpenShiftSettingsSimpleConfig.tsx b/packages/serverless-logic-web-tools/src/newSettings/openshift/OpenShiftSettingsSimpleConfig.tsx index 4069b01132..b652885b4f 100644 --- a/packages/serverless-logic-web-tools/src/newSettings/openshift/OpenShiftSettingsSimpleConfig.tsx +++ b/packages/serverless-logic-web-tools/src/newSettings/openshift/OpenShiftSettingsSimpleConfig.tsx @@ -18,6 +18,7 @@ import { isOpenShiftConnectionValid, OpenShiftConnection, } from "@kie-tools-core/openshift/dist/service/OpenShiftConnection"; +import { QuickStartContext, QuickStartContextValues } from "@patternfly/quickstarts"; import { Alert } from "@patternfly/react-core/dist/js/components/Alert"; import { Button } from "@patternfly/react-core/dist/js/components/Button"; import { ActionGroup, Form, FormAlert, FormGroup } from "@patternfly/react-core/dist/js/components/Form"; @@ -28,13 +29,14 @@ import { TextInput } from "@patternfly/react-core/dist/js/components/TextInput"; import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon"; import { TimesIcon } from "@patternfly/react-icons/dist/js/icons/times-icon"; import * as React from "react"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useState, useContext } from "react"; import { Link } from "react-router-dom"; import { useAppI18n } from "../../i18n"; import { useKieSandboxExtendedServices } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesContext"; import { KieSandboxExtendedServicesStatus } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesStatus"; import { routes } from "../../navigation/Routes"; import { OpenShiftInstanceStatus } from "../../openshift/OpenShiftInstanceStatus"; +import { QuickStartIds } from "../../quickstarts-data"; import { useSettings, useSettingsDispatch } from "../SettingsContext"; import { EMPTY_CONFIG, saveConfigCookie } from "./OpenShiftSettingsConfig"; @@ -53,6 +55,7 @@ export function OpenShiftSettingsSimpleConfig() { const [isConfigValidated, setConfigValidated] = useState(FormValiationOptions.INITIAL); const [isConnecting, setConnecting] = useState(false); const kieSandboxExtendedServices = useKieSandboxExtendedServices(); + const qsContext = useContext<QuickStartContextValues>(QuickStartContext); useEffect(() => { setConfig(settings.openshift.config); @@ -298,6 +301,18 @@ export function OpenShiftSettingsSimpleConfig() { </Button> </InputGroupText> </InputGroup> + <br /> + <Button + isInline={true} + key="quickstart" + variant="link" + onClick={() => { + qsContext.setActiveQuickStartID?.(QuickStartIds.OpenShiftIntegrationQuickStart); + setTimeout(() => qsContext.setQuickStartTaskNumber?.(QuickStartIds.OpenShiftIntegrationQuickStart, 1), 0); + }} + > + Need help getting started? Follow our quickstart guide. + </Button> </FormGroup> <ActionGroup> <Button diff --git a/packages/serverless-logic-web-tools/src/newSettings/routes/SettingsPageRoutes.tsx b/packages/serverless-logic-web-tools/src/newSettings/routes/SettingsPageRoutes.tsx index 56f678e3b0..f7b7c9f7a4 100644 --- a/packages/serverless-logic-web-tools/src/newSettings/routes/SettingsPageRoutes.tsx +++ b/packages/serverless-logic-web-tools/src/newSettings/routes/SettingsPageRoutes.tsx @@ -25,28 +25,33 @@ import { ApacheKafkaSettings } from "../kafka/ApacheKafkaSettings"; import { OpenShiftSettings } from "../openshift/OpenShiftSettings"; import { ServiceAccountSettings } from "../serviceAccount/ServiceAccountSettings"; import { ServiceRegistrySettings } from "../serviceRegistry/ServiceRegistrySettings"; +import { SettingsPageProps } from "../types"; -export function SettingsPageRoutes() { +export function SettingsPageRoutes(props: {} & SettingsPageProps) { const routes = useRoutes(); + const settingsPageProps: SettingsPageProps = { + pageContainerRef: props.pageContainerRef, + }; + return ( <Switch> <Route path={routes.settings.github.path({})}> - <GitHubSettings /> + <GitHubSettings {...settingsPageProps} /> </Route> <Route path={routes.settings.kie_sandbox_extended_services.path({})}> - <KieSandboxExtendedServicesSettings /> + <KieSandboxExtendedServicesSettings {...settingsPageProps} /> </Route> <Route path={routes.settings.openshift.path({})}> - <OpenShiftSettings /> + <OpenShiftSettings {...settingsPageProps} /> </Route> <Route path={routes.settings.service_account.path({})}> - <ServiceAccountSettings /> + <ServiceAccountSettings {...settingsPageProps} /> </Route> <Route path={routes.settings.service_registry.path({})}> - <ServiceRegistrySettings /> + <ServiceRegistrySettings {...settingsPageProps} /> </Route> <Route path={routes.settings.kafka.path({})}> - <ApacheKafkaSettings /> + <ApacheKafkaSettings {...settingsPageProps} /> </Route> <Route path={routes.settings.feature_preview.path({})}> <FeaturePreviewSettings /> diff --git a/packages/serverless-logic-web-tools/src/newSettings/serviceAccount/ServiceAccountSettings.tsx b/packages/serverless-logic-web-tools/src/newSettings/serviceAccount/ServiceAccountSettings.tsx index 5b7ebde91e..eab5c20a0e 100644 --- a/packages/serverless-logic-web-tools/src/newSettings/serviceAccount/ServiceAccountSettings.tsx +++ b/packages/serverless-logic-web-tools/src/newSettings/serviceAccount/ServiceAccountSettings.tsx @@ -29,20 +29,24 @@ import { CheckCircleIcon } from "@patternfly/react-icons/dist/js/icons/check-cir import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon"; import { TimesIcon } from "@patternfly/react-icons/dist/js/icons/times-icon"; import * as React from "react"; -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useMemo, useState, useContext } from "react"; import { Link } from "react-router-dom"; import { useKieSandboxExtendedServices } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesContext"; import { KieSandboxExtendedServicesStatus } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesStatus"; import { routes } from "../../navigation/Routes"; import { useSettings, useSettingsDispatch } from "../SettingsContext"; +import { SettingsPageProps } from "../types"; import { EMPTY_CONFIG, isServiceAccountConfigValid, resetConfigCookie, saveConfigCookie } from "./ServiceAccountConfig"; +import { QuickStartContext, QuickStartContextValues } from "@patternfly/quickstarts"; +import { QuickStartIds } from "../../quickstarts-data"; -export function ServiceAccountSettings() { +export function ServiceAccountSettings(props: SettingsPageProps) { const settings = useSettings(); const settingsDispatch = useSettingsDispatch(); const [config, setConfig] = useState(settings.serviceAccount.config); const kieSandboxExtendedServices = useKieSandboxExtendedServices(); const [isModalOpen, setIsModalOpen] = useState(false); + const qsContext = useContext<QuickStartContextValues>(QuickStartContext); const handleModalToggle = useCallback(() => { setIsModalOpen((prevIsModalOpen) => !prevIsModalOpen); @@ -167,127 +171,146 @@ export function ServiceAccountSettings() { </PageSection> </PageSection> - <Modal - title="Add Service Account" - isOpen={ - isModalOpen && - kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.STOPPED && - !isStoredConfigValid - } - onClose={handleModalToggle} - variant={ModalVariant.large} - > - <Form> - {!isExtendedServicesRunning && ( - <FormAlert> - <Alert - variant="danger" - title={ - <Text> - Connect to{" "} - <Link to={routes.settings.kie_sandbox_extended_services.path({})}> - KIE Sandbox Extended Services - </Link>{" "} - before configuring your Service Account - </Text> - } - aria-live="polite" - isInline - /> - </FormAlert> - )} - <FormGroup - label={"Client ID"} - labelIcon={ - <Popover bodyContent={"Client ID"}> - <button - type="button" - aria-label="More info for client id field" - onClick={(e) => e.preventDefault()} - aria-describedby="client-id-field" - className="pf-c-form__group-label-help" - > - <HelpIcon noVerticalAlign /> - </button> - </Popover> - } - isRequired - fieldId="client-id-field" - > - <InputGroup className="pf-u-mt-sm"> - <TextInput - autoComplete={"off"} - isRequired - type="text" - id="client-id-field" - name="client-id-field" - aria-label="Client ID field" - aria-describedby="client-id-field-helper" - value={config.clientId} - onChange={onClientIdChanged} - tabIndex={1} - data-testid="client-id-text-field" - /> - <InputGroupText> - <Button isSmall variant="plain" aria-label="Clear client id button" onClick={onClearClientId}> - <TimesIcon /> - </Button> - </InputGroupText> - </InputGroup> - </FormGroup> - <FormGroup - label={"Client Secret"} - labelIcon={ - <Popover bodyContent={"Client Secret"}> - <button - type="button" - aria-label="More info for client secret field" - onClick={(e) => e.preventDefault()} - aria-describedby="client-secret-field" - className="pf-c-form__group-label-help" - > - <HelpIcon noVerticalAlign /> - </button> - </Popover> - } - isRequired - fieldId="client-secret-field" - > - <InputGroup className="pf-u-mt-sm"> - <TextInput - autoComplete={"off"} - isRequired - type="text" - id="client-secret-field" - name="client-secret-field" - aria-label="Client secret field" - aria-describedby="client-secret-field-helper" - value={config.clientSecret} - onChange={onClientSecretChanged} - tabIndex={2} - data-testid="client-secret-text-field" - /> - <InputGroupText> - <Button isSmall variant="plain" aria-label="Clear client secret button" onClick={onClearClientSecret}> - <TimesIcon /> - </Button> - </InputGroupText> - </InputGroup> - </FormGroup> - <ActionGroup> - <Button - isDisabled={!isCurrentConfigValid} - id="service-account-config-apply-button" - key="save" - variant="primary" - onClick={onApply} - data-testid="apply-config-button" + {props.pageContainerRef.current && ( + <Modal + title="Add Service Account" + isOpen={ + isModalOpen && + kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.STOPPED && + !isStoredConfigValid + } + onClose={handleModalToggle} + variant={ModalVariant.large} + appendTo={props.pageContainerRef.current || document.body} + > + <Form> + {!isExtendedServicesRunning && ( + <FormAlert> + <Alert + variant="danger" + title={ + <Text> + Connect to{" "} + <Link to={routes.settings.kie_sandbox_extended_services.path({})}> + KIE Sandbox Extended Services + </Link>{" "} + before configuring your Service Account + </Text> + } + aria-live="polite" + isInline + /> + </FormAlert> + )} + <FormGroup + label={"Client ID"} + labelIcon={ + <Popover bodyContent={"Client ID"}> + <button + type="button" + aria-label="More info for client id field" + onClick={(e) => e.preventDefault()} + aria-describedby="client-id-field" + className="pf-c-form__group-label-help" + > + <HelpIcon noVerticalAlign /> + </button> + </Popover> + } + isRequired + fieldId="client-id-field" + > + <InputGroup className="pf-u-mt-sm"> + <TextInput + autoComplete={"off"} + isRequired + type="text" + id="client-id-field" + name="client-id-field" + aria-label="Client ID field" + aria-describedby="client-id-field-helper" + value={config.clientId} + onChange={onClientIdChanged} + tabIndex={1} + data-testid="client-id-text-field" + /> + <InputGroupText> + <Button isSmall variant="plain" aria-label="Clear client id button" onClick={onClearClientId}> + <TimesIcon /> + </Button> + </InputGroupText> + </InputGroup> + </FormGroup> + <FormGroup + label={"Client Secret"} + labelIcon={ + <Popover bodyContent={"Client Secret"}> + <button + type="button" + aria-label="More info for client secret field" + onClick={(e) => e.preventDefault()} + aria-describedby="client-secret-field" + className="pf-c-form__group-label-help" + > + <HelpIcon noVerticalAlign /> + </button> + </Popover> + } + isRequired + fieldId="client-secret-field" > - Apply - </Button> - </ActionGroup> - </Form> - </Modal> + <InputGroup className="pf-u-mt-sm"> + <TextInput + autoComplete={"off"} + isRequired + type="text" + id="client-secret-field" + name="client-secret-field" + aria-label="Client secret field" + aria-describedby="client-secret-field-helper" + value={config.clientSecret} + onChange={onClientSecretChanged} + tabIndex={2} + data-testid="client-secret-text-field" + /> + <InputGroupText> + <Button isSmall variant="plain" aria-label="Clear client secret button" onClick={onClearClientSecret}> + <TimesIcon /> + </Button> + </InputGroupText> + </InputGroup> + <br /> + <Button + isInline={true} + key="quickstart" + variant="link" + onClick={() => { + qsContext.setActiveQuickStartID?.(QuickStartIds.ApplicationServicesIntegrationQuickStart); + setTimeout( + () => + qsContext.setQuickStartTaskNumber?.(QuickStartIds.ApplicationServicesIntegrationQuickStart, 0), + 0 + ); + }} + > + Need help getting started? Follow our quickstart guide. + </Button> + </FormGroup> + <ActionGroup> + <Button + isDisabled={!isCurrentConfigValid} + id="service-account-config-apply-button" + key="save" + variant="primary" + onClick={onApply} + data-testid="apply-config-button" + > + Apply + </Button> + </ActionGroup> + </Form> + </Modal> + )} </Page> ); } diff --git a/packages/serverless-logic-web-tools/src/newSettings/serviceRegistry/ServiceRegistrySettings.tsx b/packages/serverless-logic-web-tools/src/newSettings/serviceRegistry/ServiceRegistrySettings.tsx index 2a4f4e5bfc..0954800caa 100644 --- a/packages/serverless-logic-web-tools/src/newSettings/serviceRegistry/ServiceRegistrySettings.tsx +++ b/packages/serverless-logic-web-tools/src/newSettings/serviceRegistry/ServiceRegistrySettings.tsx @@ -29,7 +29,7 @@ import { CheckCircleIcon } from "@patternfly/react-icons/dist/js/icons/check-cir import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon"; import { TimesIcon } from "@patternfly/react-icons/dist/js/icons/times-icon"; import * as React from "react"; -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useMemo, useState, useContext } from "react"; import { Link } from "react-router-dom"; import { useKieSandboxExtendedServices } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesContext"; import { KieSandboxExtendedServicesStatus } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesStatus"; @@ -41,13 +41,17 @@ import { resetConfigCookie, saveConfigCookie, } from "./ServiceRegistryConfig"; +import { QuickStartContext, QuickStartContextValues } from "@patternfly/quickstarts"; +import { QuickStartIds } from "../../quickstarts-data"; +import { SettingsPageProps } from "../types"; -export function ServiceRegistrySettings() { +export function ServiceRegistrySettings(props: SettingsPageProps) { const settings = useSettings(); const settingsDispatch = useSettingsDispatch(); const [config, setConfig] = useState(settings.serviceRegistry.config); const kieSandboxExtendedServices = useKieSandboxExtendedServices(); const [isModalOpen, setIsModalOpen] = useState(false); + const qsContext = useContext<QuickStartContextValues>(QuickStartContext); const handleModalToggle = useCallback(() => { setIsModalOpen((prevIsModalOpen) => !prevIsModalOpen); @@ -165,141 +169,158 @@ export function ServiceRegistrySettings() { </PageSection> </PageSection> - <Modal - title="Add Service Registry" - isOpen={ - isModalOpen && - kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.STOPPED && - !isStoredConfigValid - } - onClose={handleModalToggle} - variant={ModalVariant.large} - > - <Form> - {!isExtendedServicesRunning && ( - <FormAlert> - <Alert - variant="danger" - title={ - <Text> - Connect to{" "} - <Link to={routes.settings.kie_sandbox_extended_services.path({})}> - KIE Sandbox Extended Services - </Link>{" "} - before configuring your Service Registry instance - </Text> - } - aria-live="polite" - isInline - /> - </FormAlert> - )} - <FormGroup - label={"Name"} - labelIcon={ - <Popover - bodyContent={"Name to identify your Service Registry instance across the Serverless Logic Web Tools."} - > - <button - type="button" - aria-label="More info for name field" - onClick={(e) => e.preventDefault()} - aria-describedby="name-field" - className="pf-c-form__group-label-help" - > - <HelpIcon noVerticalAlign /> - </button> - </Popover> - } - isRequired - fieldId="name-field" - > - <InputGroup className="pf-u-mt-sm"> - <TextInput - autoComplete={"off"} - isRequired - type="text" - id="name-field" - name="name-field" - aria-label="Name field" - aria-describedby="name-field-helper" - value={config.name} - onChange={onNameChanged} - tabIndex={1} - data-testid="name-text-field" - /> - <InputGroupText> - <Button isSmall variant="plain" aria-label="Clear name button" onClick={onClearName}> - <TimesIcon /> - </Button> - </InputGroupText> - </InputGroup> - </FormGroup> - <FormGroup - label={"Core Registry API"} - labelIcon={ - <Popover bodyContent={"Core Registry API URL associated with your Service Registry instance."}> - <button - type="button" - aria-label="More info for core registry api field" - onClick={(e) => e.preventDefault()} - aria-describedby="core-registry-api-field" - className="pf-c-form__group-label-help" - > - <HelpIcon noVerticalAlign /> - </button> - </Popover> - } - isRequired - fieldId="core-registry-api-field" - > - <InputGroup className="pf-u-mt-sm"> - <TextInput - autoComplete={"off"} - isRequired - type="text" - id="core-registry-api-field" - name="core-registry-api-field" - aria-label="Core Registry API field" - aria-describedby="core-registry-api-field-helper" - value={config.coreRegistryApi} - onChange={onCoreRegistryApiChanged} - tabIndex={2} - data-testid="core-registry-api-text-field" - /> - <InputGroupText> - <Button - isSmall - variant="plain" - aria-label="Clear core registry api button" - onClick={onClearCoreRegistryApi} + {props.pageContainerRef.current && ( + <Modal + title="Add Service Registry" + isOpen={ + isModalOpen && + kieSandboxExtendedServices.status !== KieSandboxExtendedServicesStatus.STOPPED && + !isStoredConfigValid + } + onClose={handleModalToggle} + variant={ModalVariant.large} + appendTo={props.pageContainerRef.current || document.body} + > + <Form> + {!isExtendedServicesRunning && ( + <FormAlert> + <Alert + variant="danger" + title={ + <Text> + Connect to{" "} + <Link to={routes.settings.kie_sandbox_extended_services.path({})}> + KIE Sandbox Extended Services + </Link>{" "} + before configuring your Service Registry instance + </Text> + } + aria-live="polite" + isInline + /> + </FormAlert> + )} + <FormGroup + label={"Name"} + labelIcon={ + <Popover + bodyContent={"Name to identify your Service Registry instance across the Serverless Logic Web Tools."} > - <TimesIcon /> - </Button> - </InputGroupText> - </InputGroup> - </FormGroup> - <TextContent> - <Text component={TextVariants.p}> - <b>Note</b>: You must also provide{" "} - <Link to={routes.settings.service_account.path({})}>Service Account</Link> so the connection with your - Service Registry instance can be properly established. - </Text> - </TextContent> - <ActionGroup> + <button + type="button" + aria-label="More info for name field" + onClick={(e) => e.preventDefault()} + aria-describedby="name-field" + className="pf-c-form__group-label-help" + > + <HelpIcon noVerticalAlign /> + </button> + </Popover> + } + isRequired + fieldId="name-field" + > + <InputGroup className="pf-u-mt-sm"> + <TextInput + autoComplete={"off"} + isRequired + type="text" + id="name-field" + name="name-field" + aria-label="Name field" + aria-describedby="name-field-helper" + value={config.name} + onChange={onNameChanged} + tabIndex={1} + data-testid="name-text-field" + /> + <InputGroupText> + <Button isSmall variant="plain" aria-label="Clear name button" onClick={onClearName}> + <TimesIcon /> + </Button> + </InputGroupText> + </InputGroup> + </FormGroup> + <FormGroup + label={"Core Registry API"} + labelIcon={ + <Popover bodyContent={"Core Registry API URL associated with your Service Registry instance."}> + <button + type="button" + aria-label="More info for core registry api field" + onClick={(e) => e.preventDefault()} + aria-describedby="core-registry-api-field" + className="pf-c-form__group-label-help" + > + <HelpIcon noVerticalAlign /> + </button> + </Popover> + } + isRequired + fieldId="core-registry-api-field" + > + <InputGroup className="pf-u-mt-sm"> + <TextInput + autoComplete={"off"} + isRequired + type="text" + id="core-registry-api-field" + name="core-registry-api-field" + aria-label="Core Registry API field" + aria-describedby="core-registry-api-field-helper" + value={config.coreRegistryApi} + onChange={onCoreRegistryApiChanged} + tabIndex={2} + data-testid="core-registry-api-text-field" + /> + <InputGroupText> + <Button + isSmall + variant="plain" + aria-label="Clear core registry api button" + onClick={onClearCoreRegistryApi} + > + <TimesIcon /> + </Button> + </InputGroupText> + </InputGroup> + </FormGroup> + <TextContent> + <Text component={TextVariants.p}> + <b>Note</b>: You must also provide{" "} + <Link to={routes.settings.service_account.path({})}>Service Account</Link> so the connection with your + Service Registry instance can be properly established. + </Text> + </TextContent> <Button - isDisabled={!isCurrentConfigValid} - id="service-registry-config-apply-button" - key="save" - variant="primary" - onClick={onApply} - data-testid="apply-config-button" + isInline={true} + key="quickstart" + variant="link" + onClick={() => { + qsContext.setActiveQuickStartID?.(QuickStartIds.ApplicationServicesIntegrationQuickStart); + setTimeout( + () => qsContext.setQuickStartTaskNumber?.(QuickStartIds.ApplicationServicesIntegrationQuickStart, 1), + 0 + ); + }} > - Apply + Need help getting started? Follow our quickstart guide. </Button> - </ActionGroup> - </Form> - </Modal> + <ActionGroup> + <Button + isDisabled={!isCurrentConfigValid} + id="service-registry-config-apply-button" + key="save" + variant="primary" + onClick={onApply} + data-testid="apply-config-button" + > + Apply + </Button> + </ActionGroup> + </Form> + </Modal> + )} </Page> ); } diff --git a/packages/serverless-logic-web-tools/src/newSettings/types.ts b/packages/serverless-logic-web-tools/src/newSettings/types.ts new file mode 100644 index 0000000000..a0c1c94881 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/newSettings/types.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type SettingsPageProps = { pageContainerRef: React.RefObject<HTMLDivElement> }; diff --git a/packages/serverless-logic-web-tools/src/quickstarts-data/ApplicationServicesIntegrationQuickStart.ts b/packages/serverless-logic-web-tools/src/quickstarts-data/ApplicationServicesIntegrationQuickStart.ts new file mode 100644 index 0000000000..38e0974f29 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/quickstarts-data/ApplicationServicesIntegrationQuickStart.ts @@ -0,0 +1,421 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { QuickStart } from "@patternfly/quickstarts"; + +export const ApplicationServicesIntegrationQuickStart: QuickStart = { + metadata: { + name: "serverless-logic-web-tools-redhat-application-services-integration", + instructional: true, + }, + spec: { + icon: null, + displayName: "Integrating with Red Hat OpenShift Application and Data Services", + durationMinutes: 30, + prerequisites: ["You have access to the Red Hat OpenShift Application and Data Services console."], + description: "", + introduction: ` Some of the features in Serverless Logic Web Tools require integration with Red Hat OpenShift Application and Data Services. Consider uploading OpenAPI specifications to a service registry and deploying Serverless Workflow that requires Apache Kafka as examples of integration with Red Hat OpenShift Application and Data Services. + +This document describes how you can configure the required settings to complete the integration with Red Hat OpenShift Application and Data Services. `, + + conclusion: `**Found an issue?** + +If you find an issue or any misleading information, please feel free to report it [here](https://github.com/kiegroup/kogito-docs/issues/new). We really appreciate it!`, + + tasks: [ + { + title: "Creating a service account in Red Hat OpenShift application and Data Services", + description: `<div class="sectionbody"> + <div class="paragraph"> + <p>You can create or use a service account from your Red Hat OpenShift Application and Data Services console and add the service account to the Serverless Logic Web Tools.</p> + </div> + <div class="ulist"> + <div class="title"> + <strong> + <em>Prerequisites</em> + </strong> + </div> + <ul> + <li> + <p>You have access to the Red Hat OpenShift Application and Data Services console.</p> + </li> + </ul> + </div> + <div class="olist arabic"> + <div class="title"> + <strong> + <em>Procedure</em> + </strong> + </div> + <ol class="arabic"> + <li> + <p>To create a service account in Red Hat Openshift Application and Data Services, perform the following steps:</p> + <div class="openblock"> + <div class="content"> + <div class="admonitionblock note"> + <table> + <tbody> + <tr> + <td class="icon"> + <i class="fa icon-note" title="Note"></i> + </td> + <td class="content"> + <div class="paragraph"> + <p> + <b>NOTE</b> + <br />You can skip this step if you already have a service account. + </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + <div class="olist loweralpha"> + <ol class="loweralpha" type="a"> + <li> + <p>Go to <a href="https://console.redhat.com/application-services/service-accounts">Service Accounts | Red Hat OpenShift Application and Data Services</a>. </p> + </li> + <li> + <p>Click <strong>Create service account</strong>. </p> + </li> + <li> + <p>In the <strong>Create a service account</strong> window, enter a service account name in the <strong>Short description</strong> field. </p> + </li> + <li> + <p>Click <strong>Create</strong>. </p> + <div class="paragraph"> + <p>A modal displaying your <strong>Client ID</strong> and <strong>Client Secret</strong> appears. </p> + </div> + </li> + <li> + <p>Copy and save the Client ID and Client Secret.</p> + </li> + <li> + <p>Check the <strong>I have copied the client ID and secret</strong> checkbox and click <strong>Close</strong>. </p> + </li> + </ol> + </div> + </div> + </div> + </li> + <li> + <p>If you already have a service account, find your <strong>Client ID</strong> and <strong>Client Secret</strong>. </p> + </li> + <li> + <p>In the Serverless Logic Web Tools, click on the <strong>Cog wheel</strong> (⚙️) on the top-right corner and go to the <strong>Service Account</strong> tab. </p> + </li> + <li> + <p>Enter your <strong>Client ID</strong> and <strong>Client Secret</strong> in the respective fields. </p> + </li> + <li> + <p>Click <strong>Apply</strong>. </p> + <div class="paragraph"> + <p>The content in the <strong>Service Account</strong> tab updates and displays <strong>Your Service Account information is set</strong> message. </p> + </div> + </li> + </ol> + </div> + </div>`, + }, + { + title: "Creating a Service Registry in Red Hat OpenShift application and Data Services", + description: `<div class="sectionbody"> + <div class="paragraph"> + <p>You can create or use a Service Registry instance from your Red Hat OpenShift Application and Data Services console and add the Service Registry to Serverless Logic Web Tools.</p> + </div> + <div class="ulist"> + <div class="title"> + <em> + <strong>Prerequisites</strong> + </em> + </div> + <ul> + <li> + <p>You have access to the Red Hat OpenShift Application and Data Services console.</p> + </li> + <li> + <p>You have created a service account.</p> + <div class="paragraph"> + <p>For information about creating a service account, see <a href="https://kiegroup.github.io/kogito-docs/serverlessworkflow/latest/tooling/serverless-logic-web-tools/serverless-logic-web-tools-redhat-application-services-integration.html#proc-create-service-account-serverless-logic-web-tools">Creating a service account in Red Hat OpenShift application and Data Services</a>. </p> + </div> + </li> + </ul> + </div> + <div class="olist arabic"> + <div class="title"> + <em> + <strong>Procedure</strong> + </em> + </div> + <ol class="arabic"> + <li> + <p>To create a Service Registry instance in Red Hat Openshift Application and Data Services console, perform the following steps:</p> + <div class="openblock"> + <div class="content"> + <div class="admonitionblock note"> + <table> + <tbody> + <tr> + <td class="icon"> </td> + <td class="content"> + <div class="paragraph"> + <p> + <strong>NOTE</strong> + <br>You can skip this step if you already have a Service Registry instance. + </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + <div class="olist loweralpha"> + <ol class="loweralpha" type="a"> + <li> + <p>Go to <a href="https://console.redhat.com/application-services/service-registry">Service Registry | Red Hat OpenShift Application and Data Services</a>. </p> + </li> + <li> + <p>Click <strong>Create Service Registry instance</strong> button. </p> + </li> + <li> + <p>In the <strong>Create a Service Registry instance</strong> window, enter a Service Registry instance name and click <strong>Create</strong>. </p> + <div class="paragraph"> + <p>The list of Service Registry instances updates with your instance.</p> + </div> + </li> + <li> + <p>Find the Service Registry instance you created in the list and click on the instance.</p> + </li> + <li> + <p>Go to the <strong>Settings</strong> tab and click on <strong>Grant access</strong>. </p> + </li> + <li> + <p>In the drop-down, select the service account you created in the previous procedure.</p> + </li> + <li> + <p>Select a role for your service account.</p> + <div class="admonitionblock important"> + <table> + <tbody> + <tr> + <td class="icon"> </td> + <td class="content"> + <div class="paragraph"> + <p> + <strong>IMPORTANT <br> + </strong>You must select the role as Manager or Administrator to have the read and write access. + </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + </li> + <li> + <p>Click <strong>Save</strong>. </p> + </li> + <li> + <p>Click on the menu on the top-right corner of the screen.</p> + </li> + <li> + <p>Click <strong>Connection</strong>. </p> + <div class="paragraph"> + <p>A drawer opens containing the required connection and authentication information.</p> + </div> + </li> + <li> + <p>Copy the value of <strong>Core Registry API</strong>. </p> + </li> + </ol> + </div> + </div> + </div> + </li> + <li> + <p>If you already have a Service Registry, find the value of <strong>Core Registry API</strong> of your Service Registry. </p> + </li> + <li> + <p>In the Serverless Logic Web Tools web application, click on the <strong>Cog wheel</strong> (⚙️) on the top-right corner and go to the <strong>Service Registry</strong> tab. </p> + </li> + <li> + <p>Enter a name for your registry.</p> + <div class="paragraph"> + <p>You can enter the same name that you used while creating the Service Registry instance.</p> + </div> + </li> + <li> + <p>Enter the value of <strong>Core Registry API</strong> and click <strong>Apply</strong>. </p> + <div class="paragraph"> + <p>The content in the <strong>Service Registry</strong> tab updates and displays <strong>Your Service Registry information is set</strong> message. </p> + </div> + </li> + </ol> + </div> + </div>`, + }, + { + title: "Creating Streams for Apache Kafka in Red Hat OpenShift application and Data Services", + description: `<div class="sectionbody"> + <div class="paragraph"> + <p>You can create or use a Kafka instance from Red Hat OpenShift Application and Data Services console and add the instance to the Serverless Logic Web Tools.</p> + </div> + <div class="ulist"> + <div class="title"> + <em> + <strong>Prerequisites</strong> + </em> + </div> + <ul> + <li> + <p>You have access to the Red Hat OpenShift Application and Data Services console.</p> + </li> + <li> + <p>You have created a service account.</p> + <div class="paragraph"> + <p>For information about creating a service account, see <a href="https://kiegroup.github.io/kogito-docs/serverlessworkflow/latest/tooling/serverless-logic-web-tools/serverless-logic-web-tools-redhat-application-services-integration.html#proc-create-service-account-serverless-logic-web-tools">Creating a service account in Red Hat OpenShift application and Data Services</a>. </p> + </div> + </li> + </ul> + </div> + <div class="olist arabic"> + <div class="title"> + <em> + <strong>Procedure</strong> + </em> + </div> + <ol class="arabic"> + <li> + <p>To create an Apache Kafka instance in Red Hat Openshift Application and Data Services console, perform the following steps:</p> + <div class="openblock"> + <div class="content"> + <div class="admonitionblock note"> + <table> + <tbody> + <tr> + <td class="icon"> </td> + <td class="content"> + <div class="paragraph"> + <p> + <strong>NOTE <br> + </strong>You can skip this step if you already have an Apache Kafka instance. + </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + <div class="olist loweralpha"> + <ol class="loweralpha" type="a"> + <li> + <p>Go to <a href="https://console.redhat.com/application-services/streams/kafkas">Streams for Apache Kafka | Red Hat OpenShift Application and Data Services</a>. </p> + </li> + <li> + <p>Click <strong>Create Kafka instance</strong>. </p> + </li> + <li> + <p>In the <strong>Create a Kafka instance</strong> window, enter the name for a Kafka instance. </p> + <div class="paragraph"> + <p>You can also fill the other fields or leave those fields with default values.</p> + </div> + </li> + <li> + <p>Click <strong>Create instance</strong>. </p> + </li> + <li> + <p>Reload the <strong>Kafka instances</strong> page for the list of instances to reflect the instance you created. </p> + </li> + <li> + <p>Once the status of the Kafka instance you created is updated as <strong>Ready</strong>, click on the instance. </p> + </li> + <li> + <p>Go to the <strong>Topics</strong> tab and create a new topic. </p> + </li> + <li> + <p>Go to the <strong>Access</strong> tab, click <strong>Manage Access</strong>, and select <strong>All Accounts</strong> or the service account you created. </p> + </li> + <li> + <p>Add the following permissions:</p> + <div class="ulist"> + <ul> + <li> + <p> + <em>Consumer group is " * " | Allow All | All Accounts</em>; + </p> + </li> + <li> + <p> + <em>Topic is " * " | Allow All | All Accounts</em>; + </p> + </li> + </ul> + </div> + </li> + <li> + <p>Click on the menu on the top-right corner of the screen.</p> + </li> + <li> + <p>Click <strong>Connection</strong>. </p> + </li> + <li> + <p>Copy the value of <strong>Bootstrap server</strong>. </p> + </li> + </ol> + </div> + </div> + </div> + </li> + <li> + <p>If you already have a Kafka instance, find the value of <strong>Bootstrap server</strong> of your Kafka instance. </p> + </li> + <li> + <p>In the Serverless Logic Web Tools web application, click on the <strong>Cog wheel</strong> (⚙️) on the top-right corner and go to the <strong>Streams for Apache Kafka</strong> tab. </p> + </li> + <li> + <p>Enter the value of <strong>Bootstrap server</strong>. </p> + </li> + <li> + <p>Enter the name of topic you created in the <strong>Topic</strong> field and click <strong>Apply</strong>. </p> + <div class="paragraph"> + <p>The content in the <strong>Streams for Apache Kafka</strong> tab updates and displays <strong>Your Streams for Apache Kafka information is set</strong> message. </p> + </div> + </li> + </ol> + </div> + <div class="admonitionblock note"> + <table> + <tbody> + <tr> + <td class="icon"> </td> + <td class="content"> + <div class="paragraph"> + <p> + <strong>NOTE <br> + </strong>The procedures in this document make the integration easy for you. However, you can also create specific service accounts, topics, and consumer groups. + </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + </div>`, + }, + ], + }, +}; diff --git a/packages/serverless-logic-web-tools/src/quickstarts-data/GitHubTokenQuickStart.ts b/packages/serverless-logic-web-tools/src/quickstarts-data/GitHubTokenQuickStart.ts new file mode 100644 index 0000000000..de085f745f --- /dev/null +++ b/packages/serverless-logic-web-tools/src/quickstarts-data/GitHubTokenQuickStart.ts @@ -0,0 +1,222 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { QuickStart } from "@patternfly/quickstarts"; + +export const GitHubTokenQuickStart: QuickStart = { + metadata: { + name: "serverless-logic-web-tools-github-integration", + instructional: true, + }, + spec: { + icon: null, + displayName: "Integrating your Serverless Workflow project in GitHub using Serverless Logic Web Tools", + durationMinutes: 10, + prerequisites: ["You have an account in GitHub."], + description: "", + introduction: `The Serverless Logic Web Tools implements a web version of a Git client, enabling you to clone, create, commit, push, and pull repositories. This process synchronizes your workspaces remotely. + +This document describes how you can configure the integration and sychronize your projects.`, + + conclusion: `**Found an issue?** + +If you find an issue or any misleading information, please feel free to report it [here](https://github.com/kiegroup/kogito-docs/issues/new). We really appreciate it!`, + + tasks: [ + { + title: "Setting your GitHub token in Serverless Logic Web Tools", + description: `<div class="sectionbody"> + <div class="paragraph"> + <p>You can generate a token from your GitHub account and add the token to the Serverless Logic Web Tools.</p> + </div> + <div class="ulist"> + <div class="title"> + <em> + <strong>Prerequisites</strong> + </em> + </div> + <ul> + <li> + <p>You have an account in GitHub.</p> + </li> + </ul> + </div> + <div class="olist arabic"> + <div class="title"> + <em> + <strong>Procedure</strong> + </em> + </div> + <ol class="arabic"> + <li> + <p>Go to <a href="https://start.kubesmarts.org/">Serverless Logic Web Tools</a> web application, and click on the <strong>Cog wheel</strong> (⚙️) on the top-right corner of the screen. </p> + </li> + <li> + <p>Go to the <strong>GitHub</strong> tab. </p> + </li> + <li> + <p>In the <strong>GitHub</strong> tab, click <strong>Create a new token</strong> option. </p> + <div class="openblock"> + <div class="content"> + <div class="paragraph"> + <p>Ensure that you select the <strong>repo</strong> option. </p> + </div> + </div> + </div> + </li> + <li> + <p>Optionally, select <strong>gist</strong>, which enables you to import and update gists. </p> + </li> + <li> + <p>Copy the generated token and paste it into the <strong>Token</strong> field in Serverless Logic Web Tools GitHub <strong>Settings</strong>. </p> + <div class="paragraph"> + <p>The contents of the tab are updated and displays that you are signed into the GitHub and contains all the required permissions.</p> + </div> + </li> + </ol> + </div> + </div>`, + }, + { + title: "Synchronizing your workspaces with GitHub", + description: `<div class="sectionbody"> + <div class="paragraph"> + <p>After your GitHub token is set, you can synchronize your workspaces with remote repositories.</p> + </div> + <div class="ulist"> + <div class="title"> + <em> + <strong>Prerequisites</strong> + </em> + </div> + <ul> + <li> + <p>Your GitHub token is configured in the Serverless Logic Web Tools.</p> + <div class="paragraph"> + <p>For more information, see <a href="https://kiegroup.github.io/kogito-docs/serverlessworkflow/latest/tooling/serverless-logic-web-tools/serverless-logic-web-tools-github-integration.html#proc-setting-github-token-serverless-logic-web-tools">Setting your GitHub token in Serverless Logic Web Tools</a>. </p> + </div> + </li> + </ul> + </div> + <div class="olist arabic"> + <div class="title"> + <strong> + <em>Procedure</em> + </strong> + </div> + <ol class="arabic"> + <li> + <p>In the Serverless Logic Web Tools web application, create or open a workspace.</p> + </li> + <li> + <p>Add or edit the existing files in the workspace.</p> + </li> + <li> + <p>Click <strong>Share → Github: Create Repository</strong>. </p> + </li> + <li> + <p>Name your repository and set the repository as <strong>Public</strong> or <strong>Private</strong>. </p> + </li> + <li> + <p>(Optional) Select the <strong>Use Quarkus Accelerator</strong> to create a repository with a base Quarkus project and move the workspace files to <code>src/main/resources</code> folder. </p> + <div class="openblock"> + <div class="content"> + <div class="imageblock"> + <div class="content"> + <img src="images/quickstarts/serverless-logic-web-tools-github-repo.png" alt="serverless logic web tools github repo"> + </div> + <div class="title">Figure 1. Create a repository for your workspace</div> + </div> + </div> + </div> + </li> + <li> + <p>Click <strong>Sync → Push</strong> to update the remote repository with your local changes. </p> + </li> + <li> + <p>To get new updates from the remote repository, click <strong>Sync → Pull</strong>. </p> + <div class="admonitionblock note"> + <table> + <tbody> + <tr> + <td class="icon"> </td> + <td class="content"> + <div class="paragraph"> + <p> + <strong>NOTE</strong> + <br>Currently, Serverless Logic Web Tools cannot resolve the merge conflicts. Therefore, ensure that you always pull changes before working on your files. + </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + </li> + </ol> + </div> + </div>`, + }, + { + title: "Importing a workspace from GitHub", + description: `<div class="sectionbody"> + <div class="paragraph"> + <p>You can import a workspace from GitHub in Serverless Logic Web Tools when you need to work from another computer or need to use someone else’s workspace.</p> + </div> + <div class="ulist"> + <div class="title"> + <strong> + <em>Prerequisites</em> + </strong> + </div> + <ul> + <li> + <p>Your GitHub token is configured in the Serverless Logic Web Tools.</p> + <div class="paragraph"> + <p>For more information, see <a href="https://kiegroup.github.io/kogito-docs/serverlessworkflow/latest/tooling/serverless-logic-web-tools/serverless-logic-web-tools-github-integration.html#proc-setting-github-token-serverless-logic-web-tools">Setting your GitHub token in Serverless Logic Web Tools</a>. </p> + </div> + </li> + <li> + <p>You have a repository containing workflow files.</p> + </li> + </ul> + </div> + <div class="olist arabic"> + <div class="title"> + <strong> + <em>Procedure</em> + </strong> + </div> + <ol class="arabic"> + <li> + <p>Go to GitHub, find the repository with your project, and copy the repository URL.</p> + </li> + <li> + <p>In Serverless Logic Web Tools web application, paste the repository URL in the <strong>Import → From URL</strong> field and click <strong>Clone</strong>. </p> + <div class="paragraph"> + <p>The page loads your imported project, defaulting to a workflow file, if present.</p> + </div> + </li> + <li> + <p>If applicable, you can push to the imported repository by clicking on the <strong>Sync → Push</strong>. </p> + </li> + </ol> + </div> + </div>`, + }, + ], + }, +}; diff --git a/packages/serverless-logic-web-tools/src/quickstarts-data/OpenShiftIntegrationQuickStart.ts b/packages/serverless-logic-web-tools/src/quickstarts-data/OpenShiftIntegrationQuickStart.ts new file mode 100644 index 0000000000..441c9c93e1 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/quickstarts-data/OpenShiftIntegrationQuickStart.ts @@ -0,0 +1,194 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { QuickStart } from "@patternfly/quickstarts"; + +export const OpenShiftIntegrationQuickStart: QuickStart = { + metadata: { + name: "serverless-logic-web-tools-openshift-integration", + instructional: true, + }, + spec: { + icon: null, + displayName: "Integrating your Serverless Workflow project with OpenShift using Serverless Logic Web Tools", + durationMinutes: 15, + prerequisites: [], + description: "", + introduction: `You can integrate your Serverless Workflow project with Red Hat OpenShift. OpenShift is an enterprise-ready Kubernetes container platform, enabling your Serverless Workflow projects to be deployed and tested online.`, + + conclusion: `**Found an issue?** + +If you find an issue or any misleading information, please feel free to report it [here](https://github.com/kiegroup/kogito-docs/issues/new). We really appreciate it!`, + + tasks: [ + { + title: "Setting KIE Sandbox Extended Services", + description: `<div class="sectionbody"> + <div class="paragraph"> + <p>The KIE Sandbox Extended Services tool is required to proxy requests to an OpenShift instance. Therefore, setting the KIE Sandbox Extended Services enables you to deploy and monitor your Serverless Workflow projects.</p> + </div> + <div class="olist arabic"> + <div class="title"> + <em> + <strong>Procedure</strong> + </em> + </div> + <ol class="arabic"> + <li> + <p>In the Serverless Logic Web Tools web application, click on the <strong>Cog wheel</strong> (⚙️) on the top-right corner and go to the <strong>KIE Sandbox Extended Services</strong> tab. </p> + </li> + <li> + <p>In case you are not connected to KIE Sandbox Extended Services, you see <strong>You are not connected to KIE Sandbox Extended Services. Click to setup</strong> mesaage along with <strong>Host</strong> and <strong>Port</strong> fields, containing the values as <code> + <a class="bare" href="http://localhost" aria-invalid="true">http://localhost</a> + </code> and <code>21345</code> respectively. </p> + </li> + <li> + <p>Click on the link in the message.</p> + <div class="paragraph"> + <p>A window appears containing your current operating system as selected and a link to download to the latest version of KIE Sandbox Extended Services.</p> + </div> + </li> + <li> + <p>Download the KIE Sandbox Extended Services and execute it.</p> + <div class="openblock"> + <div class="content"> + <div class="paragraph"> + <p>You might need to grant permissions to run the file depending on your operating system and settings.</p> + </div> + <div class="paragraph"> + <p>After executing the KIE Sandbox Extended Services the content in the <strong>KIE Sandbox Extended Services</strong> is updated and displays that you are connected to the KIE Sandbox Extended Services. </p> + </div> + </div> + </div> + </li> + </ol> + </div> + </div>`, + }, + { + title: "Connecting to OpenShift instance using Serverless Logic Web Tools", + description: `<div class="sect1"> + <h2 id="proc-connecting-openshift-instance-serverless-logic-web-tools">Connecting to OpenShift instance using Serverless Logic Web Tools</h2> + <div class="sectionbody"> + <div class="paragraph"> + <p>After setting the KIE Sandbox Extended Services, you can connect to your OpenShift instance to deploy your Serverless Workflow projects with Serverless Logic Web Tools.</p> + </div> + <div class="ulist"> + <div class="title"> + <em> + <strong>Prerequisites</strong> + </em> + </div> + <ul> + <li> + <p>KIE Sandbox Extended Services tool installed and running.</p> + </li> + <li> + <p>OpenShift instance is active.</p> + <div class="paragraph"> + <p>You can create a free developer sandbox. For more information, see <a href="https://developers.redhat.com/developer-sandbox">OpenShift Developer Sandbox</a>. </p> + </div> + </li> + </ul> + </div> + <div class="olist arabic"> + <div class="title"> + <em> + <strong>Procedure</strong> + </em> + </div> + <ol class="arabic"> + <li> + <p>Log in to your OpenShift instance console interface.</p> + </li> + <li> + <p>In the OpenShift instance console interface, you need your OpenShift project name (also known as namespace), API server, and an access token.</p> + <div class="openblock"> + <div class="content"> + <div class="ulist"> + <ul> + <li> + <p>For the OpenShift project name, go to the <strong>Topology</strong> tab and in the top-left corner you see your project name. </p> + <div class="imageblock"> + <div class="content"> + <img src="images/quickstarts/serverless-logic-web-tools-openshift-project.png" alt="serverless logic web tools openshift project"> + </div> + <div class="title">Figure 1. OpenShift project name in OpenShift instance console</div> + </div> + </li> + <li> + <p>To obtain the API server and access token, click on your username and <strong>Copy login command</strong>. </p> + <div class="paragraph"> + <p>A new page opens containing your new API token along with <code>oc cli</code> login command. From the <code>oc cli</code> command, copy the value of <code>--server=</code>. </p> + </div> + <div class="imageblock"> + <div class="content"> + <img src="images/quickstarts/serverless-logic-web-tools-openshift-info.png" alt="serverless logic web tools openshift info"> + </div> + <div class="title">Figure 2. OpenShift access token and API server</div> + </div> + </li> + </ul> + </div> + </div> + </div> + </li> + <li> + <p>Go to the Serverless Logic Web Tools web application, click on the <strong>Cog wheel</strong> (⚙️) on the top-right corner and go to the <strong>OpenShift</strong> tab. </p> + </li> + <li> + <p>Enter your OpenShift project name in the <strong>Namespace (project)</strong> field. </p> + </li> + <li> + <p>Enter the value copied value of <code>--server</code> flag in the <strong>Host</strong> field. </p> + </li> + <li> + <p>Enter the value of API token in the <strong>Token</strong> field. </p> + </li> + <li> + <p>Click <strong>Connect</strong>. </p> + <div class="paragraph"> + <p>If the entered values are correct, then the tab updates and displays <strong>You’re connected to OpenShift</strong> message. </p> + </div> + </li> + </ol> + </div> + <div class="paragraph"> + <p>After connecting to OpenShift, you are ready to deploy your Serverless Workflow projects using Serverless Logic Web Tools. For more information about deploying your projects, see <a class="xref page" href="serverless-logic-web-tools-deploy-projects.html" aria-invalid="true">Deploying your Serverless Workflow projects using Serverless Logic Web Tools</a>. </p> + </div> + <div class="admonitionblock note"> + <table> + <tbody> + <tr> + <td class="icon"> </td> + <td class="content"> + <div class="paragraph"> + <p> + <b>NOTE</b> + <br />If your OpenShift instance uses self-signed certificates, then you might need to enable <code>InsecureSkipVerify</code> on KIE Sandbox Extended Services. + </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>`, + }, + ], + }, +}; diff --git a/packages/serverless-logic-web-tools/src/quickstarts-data/index.ts b/packages/serverless-logic-web-tools/src/quickstarts-data/index.ts new file mode 100644 index 0000000000..c04f6b1e35 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/quickstarts-data/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApplicationServicesIntegrationQuickStart } from "./ApplicationServicesIntegrationQuickStart"; +import { GitHubTokenQuickStart } from "./GitHubTokenQuickStart"; +import { OpenShiftIntegrationQuickStart } from "./OpenShiftIntegrationQuickStart"; + +export const QuickStartIds: { [key: string]: string } = { + GitHubTokenQuickStart: GitHubTokenQuickStart.metadata.name, + OpenShiftIntegrationQuickStart: OpenShiftIntegrationQuickStart.metadata.name, + ApplicationServicesIntegrationQuickStart: ApplicationServicesIntegrationQuickStart.metadata.name, +}; + +export { GitHubTokenQuickStart, OpenShiftIntegrationQuickStart, ApplicationServicesIntegrationQuickStart }; diff --git a/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-github-repo.png b/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-github-repo.png new file mode 100644 index 0000000000..7f76f5dd65 Binary files /dev/null and b/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-github-repo.png differ diff --git a/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-openshift-info.png b/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-openshift-info.png new file mode 100644 index 0000000000..89dc0beabd Binary files /dev/null and b/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-openshift-info.png differ diff --git a/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-openshift-project.png b/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-openshift-project.png new file mode 100644 index 0000000000..d1e9686bff Binary files /dev/null and b/packages/serverless-logic-web-tools/static/images/quickstarts/serverless-logic-web-tools-openshift-project.png differ diff --git a/packages/serverless-logic-web-tools/static/resources/style.css b/packages/serverless-logic-web-tools/static/resources/style.css index b54a7c8b6e..a75c5b5755 100644 --- a/packages/serverless-logic-web-tools/static/resources/style.css +++ b/packages/serverless-logic-web-tools/static/resources/style.css @@ -664,3 +664,11 @@ section.kie-tools--settings-tab { text-align: left; font-size: 17px; } + +#page-container { + height: 100%; +} + +#page-container .pf-c-backdrop { + position: absolute !important; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb9db5a476..72a47a3011 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3625,6 +3625,7 @@ importers: "@kie-tools/tsconfig": workspace:* "@octokit/plugin-rest-endpoint-methods": ^5.0.1 "@octokit/rest": ^18.5.3 + "@patternfly/quickstarts": ^2.3.2 "@patternfly/react-core": ^4.157.3 "@patternfly/react-icons": ^4.11.17 "@patternfly/react-tokens": ^4.33.1 @@ -3666,6 +3667,7 @@ importers: react-router: ^5.2.1 react-router-dom: ^5.2.1 rimraf: ^3.0.2 + showdown: ^2.1.0 start-server-and-test: ^1.12.1 ts-jest: ^26.5.6 typescript: ^4.4.2 @@ -3699,6 +3701,7 @@ importers: "@kie-tools/text-editor": link:../text-editor "@octokit/plugin-rest-endpoint-methods": 5.0.1 "@octokit/rest": 18.5.3 + "@patternfly/quickstarts": 2.3.2_t7grzltpjbpsxy6z3ftyagoq7i "@patternfly/react-core": 4.168.8_sfoxds7t5ydpegc3knd667wn6m "@patternfly/react-icons": 4.19.8_sfoxds7t5ydpegc3knd667wn6m "@patternfly/react-tokens": 4.33.1 @@ -3717,7 +3720,8 @@ importers: react-dropzone: [email protected] react-router: [email protected] react-router-dom: [email protected] - vscode-languageserver-types: 3.17.2 + showdown: 2.1.0 + vscode-languageserver-types: 3.16.0 yaml: 2.0.1 devDependencies: "@babel/core": 7.16.12 @@ -8601,6 +8605,43 @@ packages: engines: { node: ">=8.0" } dev: true + /@patternfly/patternfly/4.122.2: + resolution: + { integrity: sha512-kSoW8mt9eEJcAZX2lX4r/SYvFd44GGb8PUSDjMrpKDZqgn9/9VFh1rSChG4v5kCK6cpS99/gdTapZc3ylf8Rpw== } + dev: false + + /@patternfly/quickstarts/2.3.2_t7grzltpjbpsxy6z3ftyagoq7i: + resolution: + { integrity: sha512-mnmg2DFGf50R6+2V9UVo5yKUYoewjK36VVe3+FTkYizlqLlOBGR+RQ8XL9apy07FOgYsAzHmiKOPM9NyzU9YUg== } + peerDependencies: + "@patternfly/react-core": ">=4.115.2" + react: ">=16.8.0" + react-dom: ">=16.8.0" + dependencies: + "@patternfly/react-catalog-view-extension": 4.12.15_sfoxds7t5ydpegc3knd667wn6m + "@patternfly/react-core": 4.168.8_sfoxds7t5ydpegc3knd667wn6m + dompurify: 2.4.0 + history: 5.3.0 + react: 17.0.2 + react-dom: [email protected] + showdown: 1.8.6 + dev: false + + /@patternfly/react-catalog-view-extension/4.12.15_sfoxds7t5ydpegc3knd667wn6m: + resolution: + { integrity: sha512-1mp+Ogi7fJfgh5wV9q+PolmplbMj3Tcias8xs0eeD5GCirdzOQxG+wihEM5k6CAGhBAr7jHg5fRSgO8QLTt3UQ== } + peerDependencies: + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + dependencies: + "@patternfly/patternfly": 4.122.2 + "@patternfly/react-core": 4.168.8_sfoxds7t5ydpegc3knd667wn6m + "@patternfly/react-styles": 4.18.8 + classnames: 2.3.1 + react: 17.0.2 + react-dom: [email protected] + dev: false + /@patternfly/react-charts/6.15.23_sfoxds7t5ydpegc3knd667wn6m: resolution: { integrity: sha512-X8ou27onHXrkpcvv9AZhyinlw8vXzd9MFesDIKuXRwaQESdaPEznKIVg55ciVBj3tdAYBk5mQmxegh4UJFWSig== } @@ -11706,13 +11747,11 @@ packages: resolution: { integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== } engines: { node: ">=0.10.0" } - dev: true /ansi-regex/3.0.1: resolution: { integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== } engines: { node: ">=4" } - dev: true /ansi-regex/5.0.1: resolution: @@ -12091,7 +12130,7 @@ packages: resolution: { integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== } dependencies: - follow-redirects: [email protected] + follow-redirects: 1.14.9 transitivePeerDependencies: - debug dev: true @@ -12100,7 +12139,7 @@ packages: resolution: { integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== } dependencies: - follow-redirects: [email protected] + follow-redirects: 1.14.9 form-data: 4.0.0 transitivePeerDependencies: - debug @@ -12783,6 +12822,12 @@ packages: tslib: 2.3.1 dev: true + /camelcase/4.1.0: + resolution: + { integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== } + engines: { node: ">=4" } + dev: false + /camelcase/5.3.1: resolution: { integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== } @@ -13123,6 +13168,15 @@ packages: is-wsl: 2.2.0 dev: true + /cliui/4.1.0: + resolution: + { integrity: sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== } + dependencies: + string-width: 2.1.1 + strip-ansi: 4.0.0 + wrap-ansi: 2.1.0 + dev: false + /cliui/6.0.0: resolution: { integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== } @@ -13203,7 +13257,6 @@ packages: resolution: { integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== } engines: { node: ">=0.10.0" } - dev: true /collect-v8-coverage/1.0.1: resolution: @@ -13314,7 +13367,6 @@ packages: resolution: { integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== } engines: { node: ^12.20.0 || >=14 } - dev: true /common-tags/1.8.0: resolution: @@ -13509,7 +13561,7 @@ packages: normalize-path: 3.0.0 schema-utils: 4.0.0 serialize-javascript: 6.0.0 - webpack: 5.70.0 + webpack: [email protected] dev: true /copyfiles/2.4.1: @@ -13657,6 +13709,14 @@ packages: - encoding dev: true + /cross-spawn/5.1.0: + resolution: + { integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== } + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + /cross-spawn/6.0.5: resolution: { integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== } @@ -14712,7 +14772,6 @@ packages: resolution: { integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== } engines: { node: ">=0.10.0" } - dev: true /decamelize/4.0.0: resolution: @@ -16197,6 +16256,20 @@ packages: { integrity: sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== } dev: true + /execa/0.7.0: + resolution: + { integrity: sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw== } + engines: { node: ">=4" } + dependencies: + cross-spawn: 5.1.0 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.3 + strip-eof: 1.0.0 + dev: false + /execa/1.0.0: resolution: { integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== } @@ -16723,6 +16796,13 @@ packages: p-filter: 2.1.0 dev: true + /find-up/2.1.0: + resolution: + { integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== } + engines: { node: ">=4" } + dependencies: + locate-path: 2.0.0 + /find-up/3.0.0: resolution: { integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== } @@ -16796,7 +16876,7 @@ packages: tabbable: 5.1.5 dev: false - /follow-redirects/[email protected]: + /follow-redirects/1.14.9: resolution: { integrity: sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== } engines: { node: ">=4.0" } @@ -16805,8 +16885,6 @@ packages: peerDependenciesMeta: debug: optional: true - dependencies: - debug: 4.3.1 /for-in/1.0.2: resolution: @@ -17017,6 +17095,11 @@ packages: engines: { node: ">=6.9.0" } dev: true + /get-caller-file/1.0.3: + resolution: + { integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== } + dev: false + /get-caller-file/2.0.5: resolution: { integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== } @@ -17073,6 +17156,12 @@ packages: pinkie-promise: 2.0.1 dev: true + /get-stream/3.0.0: + resolution: + { integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== } + engines: { node: ">=4" } + dev: false + /get-stream/4.1.0: resolution: { integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== } @@ -17505,6 +17594,13 @@ packages: tiny-warning: 1.0.3 value-equal: 1.0.1 + /history/5.3.0: + resolution: + { integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== } + dependencies: + "@babel/runtime": 7.16.7 + dev: false + /hoist-non-react-statics/3.3.2: resolution: { integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== } @@ -17731,7 +17827,7 @@ packages: engines: { node: ">=8.0.0" } dependencies: eventemitter3: 4.0.7 - follow-redirects: [email protected] + follow-redirects: 1.14.9 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -18048,6 +18144,12 @@ packages: loose-envify: 1.4.0 dev: false + /invert-kv/1.0.0: + resolution: + { integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== } + engines: { node: ">=0.10.0" } + dev: false + /ip/1.1.5: resolution: { integrity: sha512-rBtCAQAJm8A110nbwn6YdveUnuZH3WrC36IwkRXxDnq53JvXA2NVQvB7IHyKomxK1MJ4VDNw3UtFDdXQ+AvLYA== } @@ -18239,7 +18341,12 @@ packages: engines: { node: ">=0.10.0" } dependencies: number-is-nan: 1.0.1 - dev: true + + /is-fullwidth-code-point/2.0.0: + resolution: + { integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== } + engines: { node: ">=4" } + dev: false /is-fullwidth-code-point/3.0.0: resolution: @@ -18392,7 +18499,6 @@ packages: resolution: { integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== } engines: { node: ">=0.10.0" } - dev: true /is-stream/2.0.0: resolution: @@ -18481,7 +18587,6 @@ packages: /isexe/2.0.0: resolution: { integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== } - dev: true /isobject/2.1.0: resolution: @@ -19921,6 +20026,14 @@ packages: readable-stream: 2.3.7 dev: true + /lcid/1.0.0: + resolution: + { integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== } + engines: { node: ">=0.10.0" } + dependencies: + invert-kv: 1.0.0 + dev: false + /less-loader/[email protected][email protected]: resolution: { integrity: sha512-AV5KHWvCezW27GT90WATaDnfXBv99llDbtaj4bshq6DvAihMdNjaPDcUMa6EXKLRF+P2opFenJp89BXg91XLYg== } @@ -20079,6 +20192,14 @@ packages: engines: { node: ">= 12.13.0" } dev: true + /locate-path/2.0.0: + resolution: + { integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== } + engines: { node: ">=4" } + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + /locate-path/3.0.0: resolution: { integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== } @@ -20237,7 +20358,13 @@ packages: resolution: { integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== } engines: { node: ">=8" } - dev: true + + /lru-cache/4.1.5: + resolution: + { integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== } + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 /lru-cache/6.0.0: resolution: @@ -20398,6 +20525,14 @@ packages: engines: { node: ">= 0.6" } dev: true + /mem/1.1.0: + resolution: + { integrity: sha512-nOBDrc/wgpkd3X/JOhMqYR+/eLqlfLP4oQfoBA6QExIxEl+GU01oyEkwWyueyO8110pUKijtiHGhEmYoOn88oQ== } + engines: { node: ">=4" } + dependencies: + mimic-fn: 1.2.0 + dev: false + /mem/6.1.1: resolution: { integrity: sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q== } @@ -20555,6 +20690,12 @@ packages: hasBin: true dev: true + /mimic-fn/1.2.0: + resolution: + { integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== } + engines: { node: ">=4" } + dev: false + /mimic-fn/2.1.0: resolution: { integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== } @@ -21376,7 +21517,6 @@ packages: engines: { node: ">=4" } dependencies: path-key: 2.0.1 - dev: true /npm-run-path/4.0.1: resolution: @@ -21418,7 +21558,6 @@ packages: resolution: { integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== } engines: { node: ">=0.10.0" } - dev: true /numeral/2.0.6: resolution: @@ -21646,6 +21785,22 @@ packages: { integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== } dev: true + /os-homedir/1.0.2: + resolution: + { integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== } + engines: { node: ">=0.10.0" } + dev: true + + /os-locale/2.1.0: + resolution: + { integrity: sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== } + engines: { node: ">=4" } + dependencies: + execa: 0.7.0 + lcid: 1.0.0 + mem: 1.1.0 + dev: false + /os-tmpdir/1.0.2: resolution: { integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== } @@ -21700,7 +21855,6 @@ packages: resolution: { integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== } engines: { node: ">=4" } - dev: true /p-finally/2.0.1: resolution: @@ -21714,6 +21868,19 @@ packages: engines: { node: ">=8" } dev: true + /p-iteration/1.1.8: + resolution: + { integrity: sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ== } + engines: { node: ">=8.0.0" } + dev: true + + /p-limit/1.3.0: + resolution: + { integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== } + engines: { node: ">=4" } + dependencies: + p-try: 1.0.0 + /p-limit/2.3.0: resolution: { integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== } @@ -21730,6 +21897,13 @@ packages: yocto-queue: 0.1.0 dev: true + /p-locate/2.0.0: + resolution: + { integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== } + engines: { node: ">=4" } + dependencies: + p-limit: 1.3.0 + /p-locate/3.0.0: resolution: { integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== } @@ -21818,6 +21992,11 @@ packages: p-finally: 1.0.0 dev: true + /p-try/1.0.0: + resolution: + { integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== } + engines: { node: ">=4" } + /p-try/2.2.0: resolution: { integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== } @@ -22014,7 +22193,6 @@ packages: resolution: { integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== } engines: { node: ">=4" } - dev: true /path-exists/4.0.0: resolution: @@ -22032,7 +22210,6 @@ packages: resolution: { integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== } engines: { node: ">=4" } - dev: true /path-key/3.1.1: resolution: @@ -22987,6 +23164,10 @@ packages: event-stream: 3.3.4 dev: true + /pseudomap/1.0.2: + resolution: + { integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== } + /psl/1.8.0: resolution: { integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== } @@ -23823,6 +24004,11 @@ packages: { integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== } engines: { node: ">=0.10.0" } + /require-main-filename/1.0.1: + resolution: + { integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== } + dev: false + /require-main-filename/2.0.0: resolution: { integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== } @@ -24350,7 +24536,6 @@ packages: /set-blocking/2.0.0: resolution: { integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== } - dev: true /set-immediate-shim/1.0.1: resolution: @@ -24417,7 +24602,6 @@ packages: engines: { node: ">=0.10.0" } dependencies: shebang-regex: 1.0.0 - dev: true /shebang-command/2.0.0: resolution: @@ -24431,7 +24615,6 @@ packages: resolution: { integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== } engines: { node: ">=0.10.0" } - dev: true /shebang-regex/3.0.0: resolution: @@ -24445,6 +24628,22 @@ packages: dev: true optional: true + /showdown/1.8.6: + resolution: + { integrity: sha512-cOmS+LUIiyMxFo7OU3cgV+zTv43GItwlTwUPrpUd5dqdlZh8CJMVb8KxAMhr42J6exQwKTCHMxUiG74vamV1kA== } + hasBin: true + dependencies: + yargs: 10.1.2 + dev: false + + /showdown/2.1.0: + resolution: + { integrity: sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ== } + hasBin: true + dependencies: + commander: 9.4.1 + dev: false + /side-channel/1.0.4: resolution: { integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== } @@ -25005,7 +25204,15 @@ packages: code-point-at: 1.1.0 is-fullwidth-code-point: 1.0.0 strip-ansi: 3.0.1 - dev: true + + /string-width/2.1.1: + resolution: + { integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== } + engines: { node: ">=4" } + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + dev: false /string-width/4.2.3: resolution: @@ -25068,7 +25275,14 @@ packages: engines: { node: ">=0.10.0" } dependencies: ansi-regex: 2.1.1 - dev: true + + /strip-ansi/4.0.0: + resolution: + { integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== } + engines: { node: ">=4" } + dependencies: + ansi-regex: 3.0.1 + dev: false /strip-ansi/6.0.1: resolution: @@ -25102,7 +25316,6 @@ packages: resolution: { integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== } engines: { node: ">=0.10.0" } - dev: true /strip-final-newline/2.0.0: resolution: @@ -27325,7 +27538,6 @@ packages: /which-module/2.0.0: resolution: { integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== } - dev: true /which/1.3.1: resolution: @@ -27333,7 +27545,6 @@ packages: hasBin: true dependencies: isexe: 2.0.0 - dev: true /which/2.0.2: resolution: @@ -27375,6 +27586,15 @@ packages: { integrity: sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== } dev: true + /wrap-ansi/2.1.0: + resolution: + { integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== } + engines: { node: ">=0.10.0" } + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + dev: false + /wrap-ansi/6.2.0: resolution: { integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== } @@ -27547,6 +27767,11 @@ packages: engines: { node: ">=0.4" } dev: true + /y18n/3.2.2: + resolution: + { integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== } + dev: false + /y18n/4.0.3: resolution: { integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== } @@ -27557,6 +27782,15 @@ packages: { integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== } engines: { node: ">=10" } + /yallist/2.1.2: + resolution: + { integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== } + + /yallist/3.1.1: + resolution: + { integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== } + dev: true + /yallist/4.0.0: resolution: { integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== } @@ -27626,6 +27860,13 @@ packages: { integrity: sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA== } engines: { node: ">=12" } + /yargs-parser/8.1.0: + resolution: + { integrity: sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ== } + dependencies: + camelcase: 4.1.0 + dev: false + /yargs-unparser/2.0.0: resolution: { integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== } @@ -27637,6 +27878,24 @@ packages: is-plain-obj: 2.1.0 dev: true + /yargs/10.1.2: + resolution: + { integrity: sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig== } + dependencies: + cliui: 4.1.0 + decamelize: 1.2.0 + find-up: 2.1.0 + get-caller-file: 1.0.3 + os-locale: 2.1.0 + require-directory: 2.1.1 + require-main-filename: 1.0.1 + set-blocking: 2.0.0 + string-width: 2.1.1 + which-module: 2.0.0 + y18n: 3.2.2 + yargs-parser: 8.1.0 + dev: false + /yargs/15.4.1: resolution: { integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
