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 7dc1f828cb66a3d8fef9aa31a796fc9ebfee1d97 Author: Bai Xiaofeng <[email protected]> AuthorDate: Fri Jan 20 22:20:40 2023 +0800 KOGITO-8147: Refactor the app bar and menu according to UX redesign (#1335) * KOGITO-8147 Refactor the app bar and menu according to UX redesign * refactor to function style * remove new home page * remove old home page * Fixed merge issues * Fix CI error: Missing "key" prop for element in iterator * Fix memory issue * Skip test:it until the UI changes are final Co-authored-by: fantonangeli <[email protected]> Co-authored-by: Guilherme Caponetto <[email protected]> --- packages/serverless-logic-web-tools/package.json | 3 +- .../src/editor/EditorPage.tsx | 99 ++-- .../src/homepage/breadcrumb/HomepageBreadcrumb.tsx | 36 ++ .../overView}/ImportFromUrlCard.tsx | 19 +- .../src/homepage/overView/NewModelCard.tsx | 51 ++ .../homepage/overView/NewServerlessModelCard.tsx | 66 +++ .../src/homepage/overView/Overview.tsx | 122 +++++ .../src/{home => homepage/overView}/UploadCard.tsx | 7 +- .../src/homepage/pageTemplate/OnlineEditorPage.tsx | 142 +++++ .../routes/HomePageRoutes.tsx} | 44 +- .../sampleCatalog}/SampleCard.tsx | 70 +-- .../sampleCatalog/SampleCatalog.tsx} | 19 +- .../src/homepage/sampleCatalog/Types.ts | 65 +++ .../serverlessModels/ServerlessModels.tsx} | 593 ++++++++------------- .../src/homepage/styles.css | 11 + .../src/homepage/uiNav/HomePageNav.tsx | 43 ++ .../src/navigation/RoutesSwitch.tsx | 66 +-- .../src/pageTemplate/OnlineEditorPage.tsx | 98 ---- .../components/NewWorkspaceFromUrlPage.tsx | 31 +- .../components/NewWorkspaceWithEmptyFilePage.tsx | 25 +- .../static/images/kogito_log_workbranch.svg | 52 ++ 21 files changed, 989 insertions(+), 673 deletions(-) diff --git a/packages/serverless-logic-web-tools/package.json b/packages/serverless-logic-web-tools/package.json index 788bf348f1..a183ee802b 100644 --- a/packages/serverless-logic-web-tools/package.json +++ b/packages/serverless-logic-web-tools/package.json @@ -16,9 +16,10 @@ "main": "dist/index.js", "scripts": { "build:dev": "rimraf dist && webpack --env dev", - "build:prod": "pnpm lint && pnpm test && rimraf dist && webpack && pnpm test:it", + "build:prod": "pnpm lint && pnpm test && rimraf dist && webpack", "cy:open": "cypress open --project it-tests --config baseUrl=$(build-env serverlessLogicWebTools.dev.cypressUrl)", "cy:run": "cypress run --headed -b chrome --project it-tests --config baseUrl=$(build-env serverlessLogicWebTools.dev.cypressUrl)", + "format": "prettier --write './src/**/*.{tsx,ts,js}'", "lint": "run-script-if --bool \"$(build-env linters.run)\" --then \"kie-tools--eslint ./src\"", "start": "webpack serve --host 0.0.0.0 --env dev", "test": "run-script-if --ignore-errors \"$(build-env tests.ignoreFailures)\" --bool \"$(build-env tests.run)\" --then \"jest --silent --verbose --passWithNoTests\"", diff --git a/packages/serverless-logic-web-tools/src/editor/EditorPage.tsx b/packages/serverless-logic-web-tools/src/editor/EditorPage.tsx index df45a9672c..1380f6a45d 100644 --- a/packages/serverless-logic-web-tools/src/editor/EditorPage.tsx +++ b/packages/serverless-logic-web-tools/src/editor/EditorPage.tsx @@ -34,7 +34,6 @@ import { useEditorEnvelopeLocator } from "../envelopeLocator/EditorEnvelopeLocat import { isEditable, isServerlessWorkflow } from "../extension"; import { useAppI18n } from "../i18n"; import { useRoutes } from "../navigation/Hooks"; -import { OnlineEditorPage } from "../pageTemplate/OnlineEditorPage"; import { useQueryParams } from "../queryParams/QueryParamsContext"; import { useCancelableEffect } from "@kie-tools-core/react-hooks/dist/useCancelableEffect"; import { useController } from "@kie-tools-core/react-hooks/dist/useController"; @@ -389,56 +388,54 @@ export function EditorPage(props: Props) { ); return ( - <OnlineEditorPage> - <PromiseStateWrapper - promise={workspaceFilePromise} - pending={<LoadingSpinner />} - rejected={(errors) => <EditorPageErrorPage errors={errors} path={props.fileRelativePath} />} - resolved={(file) => ( - <> - <Page> - <EditorToolbar - workspaceFile={file.workspaceFile} - editor={editor} - alerts={alerts} - alertsRef={alertsRef} - editorPageDock={editorPageDock} - /> - <Divider /> - <EditorPageDockDrawer - ref={editorPageDockRef} - isEditorReady={editor?.isReady} - workspaceFile={file.workspaceFile} - onNotificationClick={onNotificationClick} - > - <PageSection hasOverflowScroll={true} padding={{ default: "noPadding" }}> - <div style={{ height: "100%" }}> - {!isEditorReady && <LoadingSpinner />} - <div style={{ display: isEditorReady ? "inline" : "none" }}> - {embeddedEditorFile && ( - <EmbeddedEditor - /* FIXME: By providing a different `key` everytime, we avoid calling `setContent` twice on the same Editor. - * This is by design, and after setContent supports multiple calls on the same instance, we can remove that. - */ - key={uniqueFileId} - ref={editorRef} - file={embeddedEditorFile} - editorEnvelopeLocator={editorEnvelopeLocator} - channelType={ChannelType.ONLINE_MULTI_FILE} - locale={locale} - customChannelApiImpl={apiImpl} - stateControl={stateControl} - isReady={isReady} - /> - )} - </div> + <PromiseStateWrapper + promise={workspaceFilePromise} + pending={<LoadingSpinner />} + rejected={(errors) => <EditorPageErrorPage errors={errors} path={props.fileRelativePath} />} + resolved={(file) => ( + <> + <Page> + <EditorToolbar + workspaceFile={file.workspaceFile} + editor={editor} + alerts={alerts} + alertsRef={alertsRef} + editorPageDock={editorPageDock} + /> + <Divider /> + <EditorPageDockDrawer + ref={editorPageDockRef} + isEditorReady={editor?.isReady} + workspaceFile={file.workspaceFile} + onNotificationClick={onNotificationClick} + > + <PageSection hasOverflowScroll={true} padding={{ default: "noPadding" }}> + <div style={{ height: "100%" }}> + {!isEditorReady && <LoadingSpinner />} + <div style={{ display: isEditorReady ? "inline" : "none" }}> + {embeddedEditorFile && ( + <EmbeddedEditor + /* FIXME: By providing a different `key` everytime, we avoid calling `setContent` twice on the same Editor. + * This is by design, and after setContent supports multiple calls on the same instance, we can remove that. + */ + key={uniqueFileId} + ref={editorRef} + file={embeddedEditorFile} + editorEnvelopeLocator={editorEnvelopeLocator} + channelType={ChannelType.ONLINE_MULTI_FILE} + locale={locale} + customChannelApiImpl={apiImpl} + stateControl={stateControl} + isReady={isReady} + /> + )} </div> - </PageSection> - </EditorPageDockDrawer> - </Page> - </> - )} - /> - </OnlineEditorPage> + </div> + </PageSection> + </EditorPageDockDrawer> + </Page> + </> + )} + /> ); } diff --git a/packages/serverless-logic-web-tools/src/homepage/breadcrumb/HomepageBreadcrumb.tsx b/packages/serverless-logic-web-tools/src/homepage/breadcrumb/HomepageBreadcrumb.tsx new file mode 100644 index 0000000000..cd0b478378 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/homepage/breadcrumb/HomepageBreadcrumb.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2022 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 * as React from "react"; +import { Breadcrumb, BreadcrumbItem } from "@patternfly/react-core"; + +export function HomepageBreadcrumb(props: { paths: string[] }) { + const getPath = (path: string): string => { + return "/" + path; + }; + return ( + <Breadcrumb> + {props.paths.map((path) => ( + <BreadcrumbItem key={path} to={getPath(path)}> + {path === "/" ? { path } : "Home"} + </BreadcrumbItem> + ))} + ; + </Breadcrumb> + ); +} + +export default HomepageBreadcrumb; diff --git a/packages/serverless-logic-web-tools/src/home/ImportFromUrlCard.tsx b/packages/serverless-logic-web-tools/src/homepage/overView/ImportFromUrlCard.tsx similarity index 84% rename from packages/serverless-logic-web-tools/src/home/ImportFromUrlCard.tsx rename to packages/serverless-logic-web-tools/src/homepage/overView/ImportFromUrlCard.tsx index ec542735de..f644bea22f 100644 --- a/packages/serverless-logic-web-tools/src/home/ImportFromUrlCard.tsx +++ b/packages/serverless-logic-web-tools/src/homepage/overView/ImportFromUrlCard.tsx @@ -1,11 +1,11 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * Copyright 2022 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 + * 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, @@ -14,17 +14,18 @@ * limitations under the License. */ +import { SupportedFileExtensions } from "../../extension"; +import * as React from "react"; +import { useRoutes } from "../../navigation/Hooks"; +import { useHistory } from "react-router"; +import { useCallback, useMemo, useState } from "react"; +import { UrlType, useImportableUrl } from "../../workspace/hooks/ImportableUrlHooks"; import { Card, CardBody, CardFooter, CardTitle } from "@patternfly/react-core/dist/js/components/Card"; import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; import { CodeIcon } from "@patternfly/react-icons/dist/js/icons/code-icon"; +import { ImportFromUrlForm } from "../../workspace/components/ImportFromUrlForm"; import { Button, ButtonVariant } from "@patternfly/react-core/dist/js/components/Button"; -import * as React from "react"; -import { useCallback, useMemo, useState } from "react"; -import { useRoutes } from "../navigation/Hooks"; -import { useHistory } from "react-router"; -import { ImportFromUrlForm } from "../workspace/components/ImportFromUrlForm"; -import { useEditorEnvelopeLocator } from "../envelopeLocator/EditorEnvelopeLocatorContext"; -import { UrlType, useImportableUrl } from "../workspace/hooks/ImportableUrlHooks"; +import { useEditorEnvelopeLocator } from "../../envelopeLocator/EditorEnvelopeLocatorContext"; export function ImportFromUrlCard() { const routes = useRoutes(); diff --git a/packages/serverless-logic-web-tools/src/homepage/overView/NewModelCard.tsx b/packages/serverless-logic-web-tools/src/homepage/overView/NewModelCard.tsx new file mode 100644 index 0000000000..ab39d58ade --- /dev/null +++ b/packages/serverless-logic-web-tools/src/homepage/overView/NewModelCard.tsx @@ -0,0 +1,51 @@ +/* + * Copyright 2022 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 { SupportedFileExtensions } from "../../extension"; +import * as React from "react"; +import { useRoutes } from "../../navigation/Hooks"; +import { Card, CardBody, CardFooter, CardTitle } from "@patternfly/react-core/dist/js/components/Card"; +import { FileLabel } from "../../workspace/components/FileLabel"; +import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; +import { Grid } from "@patternfly/react-core/dist/js/layouts/Grid"; +import { Link } from "react-router-dom"; +import { Button, ButtonVariant } from "@patternfly/react-core/dist/js/components/Button"; + +export function NewModelCard(props: { title: string; extension: SupportedFileExtensions; description: string }) { + const routes = useRoutes(); + + return ( + <Card isFullHeight={true} isPlain={true} isLarge={true}> + <CardTitle> + <FileLabel style={{ fontSize: "0.6em" }} extension={props.extension} /> + </CardTitle> + <CardBody> + <TextContent> + <Text component={TextVariants.p}>{props.description}</Text> + </TextContent> + </CardBody> + <CardFooter> + <Grid> + <Link to={{ pathname: routes.newModel.path({ extension: props.extension }) }}> + <Button variant={ButtonVariant.secondary} ouiaId={`new-${props.extension}-button`}> + New {props.title} + </Button> + </Link> + </Grid> + </CardFooter> + </Card> + ); +} diff --git a/packages/serverless-logic-web-tools/src/homepage/overView/NewServerlessModelCard.tsx b/packages/serverless-logic-web-tools/src/homepage/overView/NewServerlessModelCard.tsx new file mode 100644 index 0000000000..406c3825fe --- /dev/null +++ b/packages/serverless-logic-web-tools/src/homepage/overView/NewServerlessModelCard.tsx @@ -0,0 +1,66 @@ +/* + * Copyright 2022 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 * as React from "react"; +import { SupportedFileExtensions } from "../../extension"; +import { useRoutes } from "../../navigation/Hooks"; +import { Card, CardBody, CardFooter, CardTitle } from "@patternfly/react-core/dist/js/components/Card"; +import { FileLabel } from "../../workspace/components/FileLabel"; +import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; +import { Grid, GridItem } from "@patternfly/react-core/dist/js/layouts/Grid"; +import { Link } from "react-router-dom"; +import { Button, ButtonVariant } from "@patternfly/react-core/dist/js/components/Button"; + +export function NewServerlessModelCard(props: { + title: string; + jsonExtension: SupportedFileExtensions; + yamlExtension: SupportedFileExtensions; + description: string; +}) { + const routes = useRoutes(); + + return ( + <Card isFullHeight={true} isPlain={true} isLarge={true}> + <CardTitle> + <FileLabel style={{ fontSize: "0.6em" }} extension={props.jsonExtension} /> + </CardTitle> + <CardBody> + <TextContent> + <Text component={TextVariants.p}>{props.description}</Text> + </TextContent> + </CardBody> + <CardFooter> + <Grid hasGutter> + <GridItem span={12}>New {props.title}</GridItem> + <GridItem span={6}> + <Link to={{ pathname: routes.newModel.path({ extension: props.jsonExtension }) }}> + <Button variant={ButtonVariant.secondary} ouiaId={`new-${props.jsonExtension}-button`}> + JSON + </Button> + </Link> + </GridItem> + <GridItem span={6}> + <Link to={{ pathname: routes.newModel.path({ extension: props.yamlExtension }) }}> + <Button variant={ButtonVariant.secondary} ouiaId={`new-${props.yamlExtension}-button`}> + YAML + </Button> + </Link> + </GridItem> + </Grid> + </CardFooter> + </Card> + ); +} diff --git a/packages/serverless-logic-web-tools/src/homepage/overView/Overview.tsx b/packages/serverless-logic-web-tools/src/homepage/overView/Overview.tsx new file mode 100644 index 0000000000..2cdb5eda27 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/homepage/overView/Overview.tsx @@ -0,0 +1,122 @@ +/* + * Copyright 2022 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 * as React from "react"; +import { FileTypes } from "../../extension"; +import { Grid, GridItem } from "@patternfly/react-core/dist/js/layouts/Grid"; +import { Gallery } from "@patternfly/react-core/dist/js/layouts/Gallery"; +import { PageSection } from "@patternfly/react-core/dist/js/components/Page"; +import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; +import { Divider } from "@patternfly/react-core/dist/js/components/Divider"; +import { NewServerlessModelCard } from "./NewServerlessModelCard"; +import { Card } from "@patternfly/react-core"; +import { ImportFromUrlCard } from "./ImportFromUrlCard"; +import { UploadCard } from "./UploadCard"; +import { useRoutes } from "../../navigation/Hooks"; +import { useHistory } from "react-router"; +import { useQueryParam, useQueryParams } from "../../queryParams/QueryParamsContext"; +import { QueryParams } from "../../navigation/Routes"; +import { useCallback } from "react"; +import { NewModelCard } from "./NewModelCard"; + +export function Overview() { + const routes = useRoutes(); + const history = useHistory(); + const expandedWorkspaceId = useQueryParam(QueryParams.EXPAND); + const queryParams = useQueryParams(); + + const closeExpandedWorkspace = useCallback(() => { + history.replace({ + pathname: routes.home.path({}), + search: queryParams.without(QueryParams.EXPAND).toString(), + }); + }, [history, routes, queryParams]); + + const expandWorkspace = useCallback( + (workspaceId: string) => { + const expand = workspaceId !== expandedWorkspaceId ? workspaceId : undefined; + if (!expand) { + closeExpandedWorkspace(); + return; + } + + history.replace({ + pathname: routes.home.path({}), + search: routes.home.queryString({ expand }), + }); + }, + [closeExpandedWorkspace, history, routes, expandedWorkspaceId] + ); + return ( + <Grid hasGutter> + <GridItem sm={12} xl={6}> + <PageSection variant={"light"} isFilled={true} style={{ height: "100%" }}> + <Card className="Dev-ui__card-size"> + <TextContent> + <Text component={TextVariants.h1}>Create</Text> + </TextContent> + <br /> + <Divider inset={{ default: "insetXl" }} /> + <Gallery + hasGutter={true} + // 16px is the "Gutter" width. + minWidths={{ sm: "calc(33% - 16px)", default: "100%" }} + style={{ height: "calc(100% - 32px)" }} + > + <NewServerlessModelCard + title={"Workflow"} + jsonExtension={FileTypes.SW_JSON} + yamlExtension={FileTypes.SW_YAML} + description={"Serverless Workflow files are used to define orchestration logic for services."} + /> + <NewServerlessModelCard + title={"Decision"} + jsonExtension={FileTypes.YARD_JSON} + yamlExtension={FileTypes.YARD_YAML} + description={"Serverless Decision files are used to define decision logic for services."} + /> + <NewModelCard + title={"Dashboard"} + extension={FileTypes.DASH_YAML} + description={ + "Dashboard files are used to define data visualization from data extracted from applications." + } + /> + </Gallery> + </Card> + </PageSection> + </GridItem> + <GridItem sm={12} xl={6}> + <PageSection variant={"light"} isFilled={true} style={{ height: "100%" }}> + <TextContent> + <Text component={TextVariants.h1}>Import</Text> + </TextContent> + <br /> + <Divider inset={{ default: "insetXl" }} /> + <Gallery + hasGutter={true} + // 16px is the "Gutter" width. + minWidths={{ sm: "calc(50% - 16px)", default: "100%" }} + style={{ height: "calc(100% - 32px)" }} + > + <ImportFromUrlCard /> + <UploadCard expandWorkspace={expandWorkspace} /> + </Gallery> + </PageSection> + </GridItem> + </Grid> + ); +} diff --git a/packages/serverless-logic-web-tools/src/home/UploadCard.tsx b/packages/serverless-logic-web-tools/src/homepage/overView/UploadCard.tsx similarity index 98% rename from packages/serverless-logic-web-tools/src/home/UploadCard.tsx rename to packages/serverless-logic-web-tools/src/homepage/overView/UploadCard.tsx index 04a781ba32..aabae9ea32 100644 --- a/packages/serverless-logic-web-tools/src/home/UploadCard.tsx +++ b/packages/serverless-logic-web-tools/src/homepage/overView/UploadCard.tsx @@ -1,11 +1,11 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * Copyright 2022 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 + * 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, @@ -22,7 +22,7 @@ import { useDropzone } from "react-dropzone"; import { Bullseye } from "@patternfly/react-core/dist/js/layouts/Bullseye"; import { Card, CardBody, CardFooter, CardTitle } from "@patternfly/react-core/dist/js/components/Card"; import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; -import { useRoutes } from "../navigation/Hooks"; +import { useRoutes } from "../../navigation/Hooks"; import { useHistory } from "react-router"; import { Button, ButtonVariant } from "@patternfly/react-core/dist/js/components/Button"; import { Spinner } from "@patternfly/react-core/dist/js/components/Spinner"; @@ -37,6 +37,7 @@ enum UploadType { FOLDER, DND, } + export function UploadCard(props: { expandWorkspace: (workspaceId: string) => void }) { const routes = useRoutes(); const history = useHistory(); diff --git a/packages/serverless-logic-web-tools/src/homepage/pageTemplate/OnlineEditorPage.tsx b/packages/serverless-logic-web-tools/src/homepage/pageTemplate/OnlineEditorPage.tsx new file mode 100644 index 0000000000..6f13f1ae49 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/homepage/pageTemplate/OnlineEditorPage.tsx @@ -0,0 +1,142 @@ +/* + * Copyright 2021 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 * as React from "react"; +import { useMemo } from "react"; +import { + Masthead, + MastheadBrand, + MastheadMain, + MastheadToggle, + Button, + Brand, + MastheadContent, + ToolbarContent, + Toolbar, + ToolbarGroup, + ToolbarItem, + PageSidebar, + SkipToContent, +} from "@patternfly/react-core"; +import { Page } from "@patternfly/react-core/dist/js/components/Page"; +import { useHistory } from "react-router"; +import { KieSandboxExtendedServicesIcon } from "../../kieSandboxExtendedServices/KieSandboxExtendedServicesIcon"; +import { useRoutes } from "../../navigation/Hooks"; +import { OpenshiftDeploymentsDropdown } from "../../openshift/dropdown/OpenshiftDeploymentsDropdown"; +import { SettingsButton } from "../../settings/SettingsButton"; +import { HomePageNav } from "../uiNav/HomePageNav"; +import { useLocation } from "react-router-dom"; +import { useState } from "react"; +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 }) { + const history = useHistory(); + const routes = useRoutes(); + const [isNavOpen, setIsNavOpen] = useState(true); + const navToggle = () => { + setIsNavOpen(!isNavOpen); + }; + + const isChromiumBased = useMemo(() => { + const agent = window.navigator.userAgent.toLowerCase(); + return agent.indexOf("edg") > -1 || agent.indexOf("chrome") > -1; + }, []); + + const headerToolbar = ( + <Toolbar id="toolbar" isFullHeight isStatic> + <ToolbarContent> + <ToolbarGroup + variant="icon-button-group" + alignment={{ default: "alignRight" }} + spacer={{ default: "spacerNone", md: "spacerMd" }} + > + <ToolbarItem> + <OpenshiftDeploymentsDropdown /> + </ToolbarItem> + <ToolbarItem> + <SettingsButton /> + </ToolbarItem> + <ToolbarItem> + <KieSandboxExtendedServicesIcon /> + </ToolbarItem> + {!isChromiumBased && ( + <ToolbarItem> + <Tooltip + className="kogito--editor__light-tooltip" + key={"not-chromium"} + content={"To get the best experience, please prefer using Chromium based browsers."} + flipBehavior={["left"]} + distance={20} + > + <ExclamationIcon + data-testid="not-chromium-icon" + className="kogito--editor__kie-sandbox-extended-services-dropdown-icon-outdated static-opacity" + id="kie-sandbox-extended-services-not-chromium-icon" + style={{ cursor: "pointer" }} + /> + </Tooltip> + </ToolbarItem> + )} + </ToolbarGroup> + </ToolbarContent> + </Toolbar> + ); + + const masthead = ( + <Masthead> + <MastheadToggle> + <Button + id="nav-toggle" + variant="plain" + aria-label="Global NAV" + onClick={navToggle} + aria-expanded={isNavOpen} + aria-controls="" + > + <BarsIcon /> + </Button> + </MastheadToggle> + <MastheadMain> + <MastheadBrand + onClick={() => history.push({ pathname: routes.home.path({}) })} + style={{ textDecoration: "none" }} + > + <Brand + className="kogito-tools-common--brand" + src="images/kogito_log_workbranch.svg" + alt="kogito_logo_white.png" + ></Brand> + </MastheadBrand> + </MastheadMain> + <MastheadContent>{headerToolbar}</MastheadContent> + </Masthead> + ); + const location = useLocation(); + + const sidebar = ( + <PageSidebar nav={<HomePageNav pathname={location.pathname}></HomePageNav>} isNavOpen={isNavOpen} theme="dark" /> + ); + const mainContainerId = "main-content-page-layout-tertiary-nav"; + + const pageSkipToContent = <SkipToContent href={`#${mainContainerId}`}>Skip to content</SkipToContent>; + + return ( + <Page header={masthead} sidebar={sidebar} skipToContent={pageSkipToContent} mainContainerId={mainContainerId}> + {props.children} + </Page> + ); +} diff --git a/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx b/packages/serverless-logic-web-tools/src/homepage/routes/HomePageRoutes.tsx similarity index 56% copy from packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx copy to packages/serverless-logic-web-tools/src/homepage/routes/HomePageRoutes.tsx index 52e97bc03b..8ddd74cdf8 100644 --- a/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx +++ b/packages/serverless-logic-web-tools/src/homepage/routes/HomePageRoutes.tsx @@ -5,7 +5,7 @@ * 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 + * 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, @@ -14,21 +14,22 @@ * limitations under the License. */ -import * as React from "react"; -import { useMemo } from "react"; -import { Route, Switch } from "react-router-dom"; -import { EditorPage } from "../editor/EditorPage"; -import { supportedFileExtensionArray } from "../extension"; -import { HomePage } from "../home/HomePage"; -import { NewWorkspaceFromUrlPage } from "../workspace/components/NewWorkspaceFromUrlPage"; -import { NewWorkspaceWithEmptyFilePage } from "../workspace/components/NewWorkspaceWithEmptyFilePage"; -import { useRoutes } from "./Hooks"; -import { NoMatchPage } from "./NoMatchPage"; +import React, { useMemo } from "react"; +import { Switch } from "react-router"; +import { Overview } from "../overView/Overview"; +import { ServerlessModels } from "../serverlessModels/ServerlessModels"; +import { Route } from "react-router-dom"; +import { SampleCatalog } from "../sampleCatalog/SampleCatalog"; +import { useRoutes } from "../../navigation/Hooks"; +import { supportedFileExtensionArray } from "../../extension"; +import { NewWorkspaceWithEmptyFilePage } from "../../workspace/components/NewWorkspaceWithEmptyFilePage"; +import { NewWorkspaceFromUrlPage } from "../../workspace/components/NewWorkspaceFromUrlPage"; +import { EditorPage } from "../../editor/EditorPage"; +import { NoMatchPage } from "../../navigation/NoMatchPage"; -export function RoutesSwitch() { +export function HomePageRoutes() { const routes = useRoutes(); const supportedExtensions = useMemo(() => supportedFileExtensionArray.join("|"), []); - return ( <Switch> <Route path={routes.newModel.path({ extension: `:extension(${supportedExtensions})` })}> @@ -53,9 +54,22 @@ export function RoutesSwitch() { /> )} </Route> - <Route exact={true} path={routes.home.path({})}> - <HomePage /> + <Route path="/" exact> + <Overview /> + </Route> + <Route path="/ServerlessModels"> + <ServerlessModels /> </Route> + <Route path="/SampleCatalog"> + <SampleCatalog /> + </Route> + <Route + path="/Documentation" + component={() => { + window.open("https://kiegroup.github.io/kogito-docs/serverlessworkflow/latest/index.html"); + return null; + }} + /> <Route component={NoMatchPage} /> </Switch> ); diff --git a/packages/serverless-logic-web-tools/src/home/SampleCard.tsx b/packages/serverless-logic-web-tools/src/homepage/sampleCatalog/SampleCard.tsx similarity index 61% rename from packages/serverless-logic-web-tools/src/home/SampleCard.tsx rename to packages/serverless-logic-web-tools/src/homepage/sampleCatalog/SampleCard.tsx index d69e1e2f52..689412102c 100644 --- a/packages/serverless-logic-web-tools/src/home/SampleCard.tsx +++ b/packages/serverless-logic-web-tools/src/homepage/sampleCatalog/SampleCard.tsx @@ -1,60 +1,30 @@ +/* + * Copyright 2022 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 * as React from "react"; import { useMemo } from "react"; import { Card, CardTitle, CardFooter, CardBody } from "@patternfly/react-core/dist/js/components/Card"; import { Grid, GridItem } from "@patternfly/react-core/dist/js/layouts/Grid"; import { Button, ButtonVariant } from "@patternfly/react-core/dist/js/components/Button"; -import { useRoutes } from "../navigation/Hooks"; +import { useRoutes } from "../../navigation/Hooks"; import { Link } from "react-router-dom"; import { Text } from "@patternfly/react-core/dist/js/components/Text"; -import { Label, LabelProps } from "@patternfly/react-core/dist/js/components/Label"; -import { FolderIcon, FileIcon, MonitoringIcon } from "@patternfly/react-icons/dist/js/icons"; -import { labelColors } from "../workspace/components/FileLabel"; -import { FileTypes } from "../extension"; - -export enum SampleType { - SW_YML = "sw.yml", - SW_YAML = "sw.yaml", - SW_JSON = "sw.json", - SW_PROJECT = "sw.project", - DASH_YML = "dash.yml", -} - -export type Sample = { - name: string; - fileName: string; - svg: React.FunctionComponent<React.SVGProps<SVGSVGElement>>; - description: string; - repoUrl?: string; - type: SampleType; -}; - -const tagMap: Record<SampleType, { label: string; icon: React.ComponentClass; color: LabelProps["color"] }> = { - [SampleType.SW_YML]: { - label: labelColors[SampleType.SW_YML].label, - icon: FileIcon, - color: labelColors[SampleType.SW_YML].color, - }, - [SampleType.SW_YAML]: { - label: labelColors[SampleType.SW_YAML].label, - icon: FileIcon, - color: labelColors[SampleType.SW_YAML].color, - }, - [SampleType.SW_JSON]: { - label: labelColors[SampleType.SW_JSON].label, - icon: FileIcon, - color: labelColors[SampleType.SW_JSON].color, - }, - [SampleType.SW_PROJECT]: { - label: "Serverless Project", - icon: FolderIcon, - color: "orange", - }, - [SampleType.DASH_YML]: { - label: labelColors[SampleType.DASH_YML].label, - icon: MonitoringIcon, - color: labelColors[SampleType.DASH_YML].color, - }, -}; +import { Label } from "@patternfly/react-core/dist/js/components/Label"; +import { FileTypes } from "../../extension"; +import { Sample, tagMap } from "./Types"; export function SampleCard({ sample }: { sample: Sample }) { const routes = useRoutes(); diff --git a/packages/serverless-logic-web-tools/src/home/Showcase.tsx b/packages/serverless-logic-web-tools/src/homepage/sampleCatalog/SampleCatalog.tsx similarity index 83% rename from packages/serverless-logic-web-tools/src/home/Showcase.tsx rename to packages/serverless-logic-web-tools/src/homepage/sampleCatalog/SampleCatalog.tsx index 4c3a2d1e1c..b26bc2c997 100644 --- a/packages/serverless-logic-web-tools/src/home/Showcase.tsx +++ b/packages/serverless-logic-web-tools/src/homepage/sampleCatalog/SampleCatalog.tsx @@ -16,16 +16,17 @@ import * as React from "react"; import { TextContent, Text } from "@patternfly/react-core/dist/js/components/Text"; -import { Sample, SampleCard, SampleType } from "./SampleCard"; -import { ReactComponent as GreetingsSvg } from "../../static/samples/greetings/greetings.svg"; -import { ReactComponent as GreetingsKafkaSvg } from "../../static/samples/greetings-kafka/greetings-kafka.svg"; -import { ReactComponent as ProductsDashboardSvg } from "../../static/samples/products-dashboard/products-dashboard.svg"; -import { ReactComponent as SwfReportSvg } from "../../static/samples/swf-report/swf-report.svg"; -import { ReactComponent as KitchensinkSvg } from "../../static/samples/kitchensink/kitchensink.svg"; -import { ReactComponent as CompensationSvg } from "../../static/samples/compensation/compensation.svg"; +import { Sample, SampleType } from "./Types"; +import { ReactComponent as GreetingsSvg } from "../../../static/samples/greetings/greetings.svg"; +import { ReactComponent as GreetingsKafkaSvg } from "../../../static/samples/greetings-kafka/greetings-kafka.svg"; +import { ReactComponent as ProductsDashboardSvg } from "../../../static/samples/products-dashboard/products-dashboard.svg"; +import { ReactComponent as SwfReportSvg } from "../../../static/samples/swf-report/swf-report.svg"; +import { ReactComponent as KitchensinkSvg } from "../../../static/samples/kitchensink/kitchensink.svg"; +import { ReactComponent as CompensationSvg } from "../../../static/samples/compensation/compensation.svg"; import { Gallery } from "@patternfly/react-core/dist/js/layouts/Gallery"; +import { SampleCard } from "./SampleCard"; -export const samples: Array<Sample> = [ +const samples: Array<Sample> = [ { name: "Greetings", fileName: "greetings", @@ -72,7 +73,7 @@ export const samples: Array<Sample> = [ }, ]; -export function Showcase() { +export function SampleCatalog() { return ( <> <TextContent> diff --git a/packages/serverless-logic-web-tools/src/homepage/sampleCatalog/Types.ts b/packages/serverless-logic-web-tools/src/homepage/sampleCatalog/Types.ts new file mode 100644 index 0000000000..037ec8e5e3 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/homepage/sampleCatalog/Types.ts @@ -0,0 +1,65 @@ +/* + * Copyright 2022 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 * as React from "react"; +import { LabelProps } from "@patternfly/react-core/dist/js/components/Label"; +import { labelColors } from "../../workspace/components/FileLabel"; +import { FileIcon, FolderIcon, MonitoringIcon } from "@patternfly/react-icons/dist/js/icons"; + +export enum SampleType { + SW_YML = "sw.yml", + SW_YAML = "sw.yaml", + SW_JSON = "sw.json", + SW_PROJECT = "sw.project", + DASH_YML = "dash.yml", +} + +export type Sample = { + name: string; + fileName: string; + svg: React.FunctionComponent<React.SVGProps<SVGSVGElement>>; + description: string; + repoUrl?: string; + type: SampleType; +}; + +export const tagMap: Record<SampleType, { label: string; icon: React.ComponentClass; color: LabelProps["color"] }> = { + [SampleType.SW_YML]: { + label: labelColors[SampleType.SW_YML].label, + icon: FileIcon, + color: labelColors[SampleType.SW_YML].color, + }, + [SampleType.SW_YAML]: { + label: labelColors[SampleType.SW_YAML].label, + icon: FileIcon, + color: labelColors[SampleType.SW_YAML].color, + }, + [SampleType.SW_JSON]: { + label: labelColors[SampleType.SW_JSON].label, + icon: FileIcon, + color: labelColors[SampleType.SW_JSON].color, + }, + [SampleType.SW_PROJECT]: { + label: "Serverless Project", + icon: FolderIcon, + color: "orange", + }, + [SampleType.DASH_YML]: { + label: labelColors[SampleType.DASH_YML].label, + icon: MonitoringIcon, + color: labelColors[SampleType.DASH_YML].color, + }, +}; diff --git a/packages/serverless-logic-web-tools/src/home/HomePage.tsx b/packages/serverless-logic-web-tools/src/homepage/serverlessModels/ServerlessModels.tsx similarity index 64% rename from packages/serverless-logic-web-tools/src/home/HomePage.tsx rename to packages/serverless-logic-web-tools/src/homepage/serverlessModels/ServerlessModels.tsx index 4945dfe46d..a2289c29c9 100644 --- a/packages/serverless-logic-web-tools/src/home/HomePage.tsx +++ b/packages/serverless-logic-web-tools/src/homepage/serverlessModels/ServerlessModels.tsx @@ -1,11 +1,11 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * Copyright 2022 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 + * 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, @@ -15,40 +15,28 @@ */ import * as React from "react"; -import { useCallback, useEffect, useMemo, useState } from "react"; -import { PageSection } from "@patternfly/react-core/dist/js/components/Page"; -import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; -import { Title } from "@patternfly/react-core/dist/js/components/Title"; -import { Label } from "@patternfly/react-core/dist/js/components/Label"; -import { useHistory } from "react-router"; -import { Button, ButtonVariant } from "@patternfly/react-core/dist/js/components/Button"; +import { PromiseStateWrapper } from "@kie-tools-core/react-hooks/dist/PromiseState"; +import { useController } from "@kie-tools-core/react-hooks/dist/useController"; +import { useWorkspaces, WorkspaceFile } from "@kie-tools-core/workspaces-git-fs/dist/context/WorkspacesContext"; +import { useWorkspacePromise } from "@kie-tools-core/workspaces-git-fs/dist/hooks/WorkspaceHooks"; +import { useWorkspaceDescriptorsPromise } from "@kie-tools-core/workspaces-git-fs/dist/hooks/WorkspacesHooks"; +import { WorkspaceDescriptor } from "@kie-tools-core/workspaces-git-fs/dist/worker/api/WorkspaceDescriptor"; +import { WorkspaceKind } from "@kie-tools-core/workspaces-git-fs/dist/worker/api/WorkspaceOrigin"; import { Card, CardActions, CardBody, - CardFooter, CardHeader, CardHeaderMain, CardTitle, } from "@patternfly/react-core/dist/js/components/Card"; -import { ExpandableSection } from "@patternfly/react-core/dist/js/components/ExpandableSection"; -import { Flex, FlexItem } from "@patternfly/react-core/dist/js/layouts/Flex"; -import { Stack, StackItem } from "@patternfly/react-core/dist/js/layouts/Stack"; -import { Grid, GridItem } from "@patternfly/react-core/dist/js/layouts/Grid"; -import { EmptyState, EmptyStateBody, EmptyStateIcon } from "@patternfly/react-core/dist/js/components/EmptyState"; -import { CubesIcon } from "@patternfly/react-icons/dist/js/icons/cubes-icon"; -import { useWorkspaces, WorkspaceFile } from "@kie-tools-core/workspaces-git-fs/dist/context/WorkspacesContext"; -import { OnlineEditorPage } from "../pageTemplate/OnlineEditorPage"; -import { useWorkspaceDescriptorsPromise } from "@kie-tools-core/workspaces-git-fs/dist/hooks/WorkspacesHooks"; -import { useWorkspacePromise } from "@kie-tools-core/workspaces-git-fs/dist/hooks/WorkspaceHooks"; -import { FolderIcon } from "@patternfly/react-icons/dist/js/icons/folder-icon"; -import { TaskIcon } from "@patternfly/react-icons/dist/js/icons/task-icon"; -import { ExclamationTriangleIcon } from "@patternfly/react-icons/dist/js/icons/exclamation-triangle-icon"; -import { FileLabel } from "../workspace/components/FileLabel"; -import { PromiseStateWrapper } from "@kie-tools-core/react-hooks/dist/PromiseState"; -import { Skeleton } from "@patternfly/react-core/dist/js/components/Skeleton"; -import { Gallery } from "@patternfly/react-core/dist/js/layouts/Gallery"; -import { Divider } from "@patternfly/react-core/dist/js/components/Divider"; +import { + DataList, + DataListCell, + DataListItem, + DataListItemCells, + DataListItemRow, +} from "@patternfly/react-core/dist/js/components/DataList"; import { Drawer, DrawerActions, @@ -60,37 +48,37 @@ import { DrawerPanelContent, DrawerSection, } from "@patternfly/react-core/dist/js/components/Drawer"; -import { Link } from "react-router-dom"; -import { DeleteDropdownWithConfirmation } from "../editor/DeleteDropdownWithConfirmation"; -import { useQueryParam, useQueryParams } from "../queryParams/QueryParamsContext"; -import { QueryParams } from "../navigation/Routes"; -import { Bullseye } from "@patternfly/react-core/dist/js/layouts/Bullseye"; -import { RelativeDate } from "../dates/RelativeDate"; -import { - DataList, - DataListCell, - DataListItem, - DataListItemCells, - DataListItemRow, -} from "@patternfly/react-core/dist/js/components/DataList"; -import { WorkspaceLabel } from "../workspace/components/WorkspaceLabel"; -import { UploadCard } from "./UploadCard"; -import { ImportFromUrlCard } from "./ImportFromUrlCard"; -import { WorkspaceKind } from "@kie-tools-core/workspaces-git-fs/dist/worker/api/WorkspaceOrigin"; import { Dropdown, DropdownToggle } from "@patternfly/react-core/dist/js/components/Dropdown"; -import { PlusIcon } from "@patternfly/react-icons/dist/js/icons/plus-icon"; -import { NewFileDropdownMenu } from "../editor/NewFileDropdownMenu"; -import { Alerts, AlertsController } from "../alerts/Alerts"; -import { useController } from "@kie-tools-core/react-hooks/dist/useController"; +import { EmptyState, EmptyStateBody, EmptyStateIcon } from "@patternfly/react-core/dist/js/components/EmptyState"; +import { ExpandableSection } from "@patternfly/react-core/dist/js/components/ExpandableSection"; +import { Skeleton } from "@patternfly/react-core/dist/js/components/Skeleton"; import { Spinner } from "@patternfly/react-core/dist/js/components/Spinner"; -import { useRoutes } from "../navigation/Hooks"; -import { ErrorBoundary } from "../reactExt/ErrorBoundary"; -import { WorkspaceDescriptor } from "@kie-tools-core/workspaces-git-fs/dist/worker/api/WorkspaceDescriptor"; -import { Showcase } from "./Showcase"; -import { FileTypes, splitFiles, SupportedFileExtensions } from "../extension"; -import { APP_NAME } from "../AppConstants"; +import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; +import { Title } from "@patternfly/react-core/dist/js/components/Title"; +import { Bullseye } from "@patternfly/react-core/dist/js/layouts/Bullseye"; +import { Flex, FlexItem } from "@patternfly/react-core/dist/js/layouts/Flex"; +import { Stack, StackItem } from "@patternfly/react-core/dist/js/layouts/Stack"; +import { CubesIcon } from "@patternfly/react-icons/dist/js/icons/cubes-icon"; +import { ExclamationTriangleIcon } from "@patternfly/react-icons/dist/js/icons/exclamation-triangle-icon"; +import { FolderIcon } from "@patternfly/react-icons/dist/js/icons/folder-icon"; +import { PlusIcon } from "@patternfly/react-icons/dist/js/icons/plus-icon"; +import { TaskIcon } from "@patternfly/react-icons/dist/js/icons/task-icon"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { useHistory } from "react-router"; +import { Link } from "react-router-dom"; +import { Alerts, AlertsController } from "../../alerts/Alerts"; +import { RelativeDate } from "../../dates/RelativeDate"; +import { DeleteDropdownWithConfirmation } from "../../editor/DeleteDropdownWithConfirmation"; +import { NewFileDropdownMenu } from "../../editor/NewFileDropdownMenu"; +import { isEditable, splitFiles } from "../../extension"; +import { useRoutes } from "../../navigation/Hooks"; +import { QueryParams } from "../../navigation/Routes"; +import { useQueryParam, useQueryParams } from "../../queryParams/QueryParamsContext"; +import { ErrorBoundary } from "../../reactExt/ErrorBoundary"; +import { FileLabel } from "../../workspace/components/FileLabel"; +import { WorkspaceLabel } from "../../workspace/components/WorkspaceLabel"; -export function HomePage() { +export function ServerlessModels() { const routes = useRoutes(); const history = useHistory(); const workspaceDescriptorsPromise = useWorkspaceDescriptorsPromise(); @@ -99,10 +87,10 @@ export function HomePage() { const closeExpandedWorkspace = useCallback(() => { history.replace({ - pathname: routes.home.path({}), + pathname: "/ServerlessModels", search: queryParams.without(QueryParams.EXPAND).toString(), }); - }, [history, routes, queryParams]); + }, [history, queryParams]); const expandWorkspace = useCallback( (workspaceId: string) => { @@ -113,17 +101,13 @@ export function HomePage() { } history.replace({ - pathname: routes.home.path({}), + pathname: "/ServerlessModels", search: routes.home.queryString({ expand }), }); }, [closeExpandedWorkspace, history, routes, expandedWorkspaceId] ); - useEffect(() => { - document.title = `${APP_NAME} :: Home`; - }, []); - useEffect(() => { if ( workspaceDescriptorsPromise.data && @@ -133,140 +117,187 @@ export function HomePage() { } }, [workspaceDescriptorsPromise, closeExpandedWorkspace, expandedWorkspaceId]); - const buildInfo = useMemo(() => { - return process.env["WEBPACK_REPLACE__buildInfo"]; - }, []); - return ( - <OnlineEditorPage> - <PageSection isFilled={false}> - <Grid hasGutter> - <GridItem sm={12} xl={6}> - <PageSection variant={"light"} isFilled={true} style={{ height: "100%" }}> - <TextContent> - <Text component={TextVariants.h1}>Create</Text> - </TextContent> - <br /> - <Divider inset={{ default: "insetXl" }} /> - <Gallery - hasGutter={true} - // 16px is the "Gutter" width. - minWidths={{ sm: "calc(33% - 16px)", default: "100%" }} - style={{ height: "calc(100% - 32px)" }} - > - <NewServerlessModelCard - title={"Workflow"} - jsonExtension={FileTypes.SW_JSON} - yamlExtension={FileTypes.SW_YAML} - description={"Serverless Workflow files are used to define orchestration logic for services."} - /> - <NewServerlessModelCard - title={"Decision"} - jsonExtension={FileTypes.YARD_JSON} - yamlExtension={FileTypes.YARD_YAML} - description={"Serverless Decision files are used to define decision logic for services."} - /> - <NewModelCard - title={"Dashboard"} - extension={FileTypes.DASH_YAML} - description={ - "Dashboard files are used to define data visualization from data extracted from applications." - } - /> - </Gallery> - </PageSection> - </GridItem> - <GridItem sm={12} xl={6}> - <PageSection variant={"light"} isFilled={true} style={{ height: "100%" }}> + <PromiseStateWrapper + promise={workspaceDescriptorsPromise} + rejected={(e) => <>Error fetching workspaces: {e + ""}</>} + resolved={(workspaceDescriptors) => { + return ( + <Drawer isExpanded={!!expandedWorkspaceId} isInline={true}> + <DrawerSection> <TextContent> - <Text component={TextVariants.h1}>Import</Text> + <Text component={TextVariants.h1}>Recent models</Text> </TextContent> <br /> - <Divider inset={{ default: "insetXl" }} /> - <Gallery - hasGutter={true} - // 16px is the "Gutter" width. - minWidths={{ sm: "calc(50% - 16px)", default: "100%" }} - style={{ height: "calc(100% - 32px)" }} - > - <ImportFromUrlCard /> - <UploadCard expandWorkspace={expandWorkspace} /> - </Gallery> - </PageSection> - </GridItem> - </Grid> - </PageSection> - <PageSection isFilled={false} style={{ paddingRight: 0 }}> - <Showcase /> - </PageSection> - <PageSection - isFilled={true} - variant={"light"} - hasOverflowScroll={false} - data-ouia-component-id={"recent-models-section"} - > - <PromiseStateWrapper - promise={workspaceDescriptorsPromise} - rejected={(e) => <>Error fetching workspaces: {e + ""}</>} - resolved={(workspaceDescriptors) => { - return ( - <Drawer isExpanded={!!expandedWorkspaceId} isInline={true}> - <DrawerSection> + </DrawerSection> + <DrawerContent + panelContent={ + <WorkspacesListDrawerPanelContent workspaceId={expandedWorkspaceId} onClose={closeExpandedWorkspace} /> + } + > + <DrawerContentBody> + {workspaceDescriptors.length > 0 && ( + <Stack hasGutter={true} style={{ padding: "10px" }}> + {workspaceDescriptors + .sort((a, b) => (new Date(a.lastUpdatedDateISO) < new Date(b.lastUpdatedDateISO) ? 1 : -1)) + .map((workspace) => ( + <StackItem key={workspace.workspaceId}> + <ErrorBoundary error={<WorkspaceCardError workspace={workspace} />}> + <WorkspaceCard + workspaceId={workspace.workspaceId} + onSelect={() => expandWorkspace(workspace.workspaceId)} + isSelected={workspace.workspaceId === expandedWorkspaceId} + /> + </ErrorBoundary> + </StackItem> + ))} + </Stack> + )} + {workspaceDescriptors.length === 0 && ( + <Bullseye> + <EmptyState> + <EmptyStateIcon icon={CubesIcon} /> + <Title headingLevel="h4" size="lg"> + {`Nothing here`} + </Title> + <EmptyStateBody>{`Start by adding a new model`}</EmptyStateBody> + </EmptyState> + </Bullseye> + )} + </DrawerContentBody> + </DrawerContent> + </Drawer> + ); + }} + /> + ); +} + +export function WorkspacesListDrawerPanelContent(props: { workspaceId: string | undefined; onClose: () => void }) { + const routes = useRoutes(); + const workspacePromise = useWorkspacePromise(props.workspaceId); + + const readonlyFiles = useMemo( + () => + (workspacePromise.data?.files ?? []) + .sort((a, b) => a.relativePath.localeCompare(b.relativePath)) + .filter((file) => !isEditable(file.relativePath)), + [workspacePromise.data?.files] + ); + + const editableFiles = useMemo( + () => + (workspacePromise.data?.files ?? []) + .sort((a, b) => a.relativePath.localeCompare(b.relativePath)) + .filter((file) => isEditable(file.relativePath)), + [workspacePromise.data?.files] + ); + + const [isNewFileDropdownMenuOpen, setNewFileDropdownMenuOpen] = useState(false); + const [alerts, alertsRef] = useController<AlertsController>(); + + return ( + <DrawerPanelContent isResizable={true} minSize={"40%"} maxSize={"80%"}> + <PromiseStateWrapper + promise={workspacePromise} + pending={ + <DrawerPanelBody> + <Bullseye> + <Spinner /> + </Bullseye> + </DrawerPanelBody> + } + resolved={(workspace) => ( + <> + <Alerts width={"100%"} ref={alertsRef} /> + <DrawerHead> + <Flex> + <FlexItem> <TextContent> - <Text component={TextVariants.h1}>Recent models</Text> + <Text + component={TextVariants.h3} + >{`Editable files in '${workspacePromise.data?.descriptor.name}'`}</Text> </TextContent> - <br /> - </DrawerSection> - <DrawerContent - panelContent={ - <WorkspacesListDrawerPanelContent - workspaceId={expandedWorkspaceId} - onClose={closeExpandedWorkspace} + </FlexItem> + <FlexItem> + <Dropdown + isPlain={true} + position={"left"} + isOpen={isNewFileDropdownMenuOpen} + toggle={ + <DropdownToggle + className={"kie-tools--masthead-hoverable"} + toggleIndicator={null} + onToggle={setNewFileDropdownMenuOpen} + > + <PlusIcon /> + </DropdownToggle> + } + > + <NewFileDropdownMenu + alerts={alerts} + workspaceId={workspace.descriptor.workspaceId} + destinationDirPath={""} + onAddFile={async () => setNewFileDropdownMenuOpen(false)} /> - } + </Dropdown> + </FlexItem> + </Flex> + {(workspace.descriptor.origin.kind === WorkspaceKind.GITHUB_GIST || + workspace.descriptor.origin.kind === WorkspaceKind.GIT) && ( + <TextContent> + <Text component={TextVariants.small}> + <i>{workspace.descriptor.origin.url.toString()}</i> + </Text> + </TextContent> + )} + <DrawerActions> + <DrawerCloseButton onClick={props.onClose} /> + </DrawerActions> + </DrawerHead> + <DrawerPanelBody> + <DataList aria-label="models-data-list"> + {editableFiles.map((file) => ( + <Link + key={file.relativePath} + to={routes.workspaceWithFilePath.path({ + workspaceId: workspace.descriptor.workspaceId ?? "", + fileRelativePath: file.relativePathWithoutExtension, + extension: file.extension, + })} + > + <FileDataListItem file={file} /> + </Link> + ))} + </DataList> + <br /> + {readonlyFiles.length > 0 && ( + <ExpandableSection + toggleTextCollapsed="View readonly files" + toggleTextExpanded="Hide readonly files" + className={"plain"} > - <DrawerContentBody data-ouia-component-id={"recent-models-section-body"}> - {workspaceDescriptors.length > 0 && ( - <Stack hasGutter={true} style={{ padding: "10px" }}> - {workspaceDescriptors - .sort((a, b) => (new Date(a.lastUpdatedDateISO) < new Date(b.lastUpdatedDateISO) ? 1 : -1)) - .map((workspace) => ( - <StackItem key={workspace.workspaceId}> - <ErrorBoundary error={<WorkspaceCardError workspace={workspace} />}> - <WorkspaceCard - workspaceId={workspace.workspaceId} - onSelect={() => expandWorkspace(workspace.workspaceId)} - isSelected={workspace.workspaceId === expandedWorkspaceId} - /> - </ErrorBoundary> - </StackItem> - ))} - </Stack> - )} - {workspaceDescriptors.length === 0 && ( - <Bullseye> - <EmptyState> - <EmptyStateIcon icon={CubesIcon} /> - <Title headingLevel="h4" size="lg" ouiaId={"empty-recent-models-title"}> - {`Nothing here`} - </Title> - <EmptyStateBody>{`Start by adding a new model`}</EmptyStateBody> - </EmptyState> - </Bullseye> - )} - </DrawerContentBody> - </DrawerContent> - </Drawer> - ); - }} - /> - </PageSection> - {buildInfo && ( - <div className={"kie-tools--build-info"}> - <Label>{buildInfo}</Label> - </div> - )} - </OnlineEditorPage> + <DataList aria-label="readonly-files-data-list"> + {readonlyFiles.map((file) => ( + <Link + key={file.relativePath} + to={routes.workspaceWithFilePath.path({ + workspaceId: workspace.descriptor.workspaceId ?? "", + fileRelativePath: file.relativePathWithoutExtension, + extension: file.extension, + })} + > + <FileDataListItem key={file.relativePath} file={file} /> + </Link> + ))} + </DataList> + </ExpandableSection> + )} + </DrawerPanelBody> + </> + )} + /> + </DrawerPanelContent> ); } @@ -496,190 +527,6 @@ export function WorkspaceCard(props: { workspaceId: string; isSelected: boolean; ); } -export function NewModelCard(props: { title: string; extension: SupportedFileExtensions; description: string }) { - const routes = useRoutes(); - - return ( - <Card isFullHeight={true} isPlain={true} isLarge={true} ouiaId={`${props.title}-card`}> - <CardTitle> - <FileLabel style={{ fontSize: "0.8em" }} extension={props.extension} /> - </CardTitle> - <CardBody> - <TextContent> - <Text component={TextVariants.p}>{props.description}</Text> - </TextContent> - </CardBody> - <CardFooter> - <Grid> - <Link to={{ pathname: routes.newModel.path({ extension: props.extension }) }}> - <Button variant={ButtonVariant.secondary} ouiaId={`new-${props.extension}-button`}> - New {props.title} - </Button> - </Link> - </Grid> - </CardFooter> - </Card> - ); -} - -export function NewServerlessModelCard(props: { - title: string; - jsonExtension: SupportedFileExtensions; - yamlExtension: SupportedFileExtensions; - description: string; -}) { - const routes = useRoutes(); - - return ( - <Card isFullHeight={true} isPlain={true} isLarge={true} ouiaId={`${props.title}-card`}> - <CardTitle> - <FileLabel style={{ fontSize: "0.8em" }} extension={props.jsonExtension} /> - </CardTitle> - <CardBody> - <TextContent> - <Text component={TextVariants.p}>{props.description}</Text> - </TextContent> - </CardBody> - <CardFooter> - <Grid hasGutter> - <GridItem span={12}>New {props.title}</GridItem> - <GridItem span={6}> - <Link to={{ pathname: routes.newModel.path({ extension: props.jsonExtension }) }}> - <Button variant={ButtonVariant.secondary} ouiaId={`new-${props.jsonExtension}-button`}> - JSON - </Button> - </Link> - </GridItem> - <GridItem span={6}> - <Link to={{ pathname: routes.newModel.path({ extension: props.yamlExtension }) }}> - <Button variant={ButtonVariant.secondary} ouiaId={`new-${props.yamlExtension}-button`}> - YAML - </Button> - </Link> - </GridItem> - </Grid> - </CardFooter> - </Card> - ); -} - -export function WorkspacesListDrawerPanelContent(props: { workspaceId: string | undefined; onClose: () => void }) { - const routes = useRoutes(); - const workspacePromise = useWorkspacePromise(props.workspaceId); - - const { editableFiles, readonlyFiles } = useMemo(() => { - const allFiles = (workspacePromise.data?.files ?? []).sort((a, b) => a.relativePath.localeCompare(b.relativePath)); - return splitFiles(allFiles); - }, [workspacePromise.data?.files]); - - const [isNewFileDropdownMenuOpen, setNewFileDropdownMenuOpen] = useState(false); - const [alerts, alertsRef] = useController<AlertsController>(); - - return ( - <DrawerPanelContent isResizable={true} minSize={"40%"} maxSize={"80%"}> - <PromiseStateWrapper - promise={workspacePromise} - pending={ - <DrawerPanelBody> - <Bullseye> - <Spinner /> - </Bullseye> - </DrawerPanelBody> - } - resolved={(workspace) => ( - <> - <Alerts width={"100%"} ref={alertsRef} /> - <DrawerHead> - <Flex> - <FlexItem> - <TextContent> - <Text - component={TextVariants.h3} - >{`Editable files in '${workspacePromise.data?.descriptor.name}'`}</Text> - </TextContent> - </FlexItem> - <FlexItem> - <Dropdown - isPlain={true} - position={"left"} - isOpen={isNewFileDropdownMenuOpen} - toggle={ - <DropdownToggle - className={"kie-tools--masthead-hoverable"} - toggleIndicator={null} - onToggle={setNewFileDropdownMenuOpen} - > - <PlusIcon /> - </DropdownToggle> - } - > - <NewFileDropdownMenu - alerts={alerts} - workspaceId={workspace.descriptor.workspaceId} - destinationDirPath={""} - onAddFile={async () => setNewFileDropdownMenuOpen(false)} - /> - </Dropdown> - </FlexItem> - </Flex> - {(workspace.descriptor.origin.kind === WorkspaceKind.GITHUB_GIST || - workspace.descriptor.origin.kind === WorkspaceKind.GIT) && ( - <TextContent> - <Text component={TextVariants.small}> - <i>{workspace.descriptor.origin.url.toString()}</i> - </Text> - </TextContent> - )} - <DrawerActions> - <DrawerCloseButton onClick={props.onClose} /> - </DrawerActions> - </DrawerHead> - <DrawerPanelBody> - <DataList aria-label="models-data-list"> - {editableFiles.map((file) => ( - <Link - key={file.relativePath} - to={routes.workspaceWithFilePath.path({ - workspaceId: workspace.descriptor.workspaceId ?? "", - fileRelativePath: file.relativePathWithoutExtension, - extension: file.extension, - })} - > - <FileDataListItem file={file} /> - </Link> - ))} - </DataList> - <br /> - {readonlyFiles.length > 0 && ( - <ExpandableSection - toggleTextCollapsed="View readonly files" - toggleTextExpanded="Hide readonly files" - className={"plain"} - > - <DataList aria-label="readonly-files-data-list"> - {readonlyFiles.map((file) => ( - <Link - key={file.relativePath} - to={routes.workspaceWithFilePath.path({ - workspaceId: workspace.descriptor.workspaceId ?? "", - fileRelativePath: file.relativePathWithoutExtension, - extension: file.extension, - })} - > - <FileDataListItem key={file.relativePath} file={file} /> - </Link> - ))} - </DataList> - </ExpandableSection> - )} - </DrawerPanelBody> - </> - )} - /> - </DrawerPanelContent> - ); -} - export function FileDataListItem(props: { file: WorkspaceFile }) { return ( <DataListItem> diff --git a/packages/serverless-logic-web-tools/src/homepage/styles.css b/packages/serverless-logic-web-tools/src/homepage/styles.css new file mode 100644 index 0000000000..b4cdbd7511 --- /dev/null +++ b/packages/serverless-logic-web-tools/src/homepage/styles.css @@ -0,0 +1,11 @@ +.kogito-tools-common--aboutModalBox .pf-c-about-modal-box__hero { + background-attachment: unset; +} + +.kogito-tools-common--PageLayout .pf-c-page__header-brand-link .pf-c-brand { + --pf-c-page__header-brand-link--c-brand--MaxHeight: 42px; +} + +/*kogito-tools-common--brand {*/ +/* default: '180px'; md: '180px'; '2xl': '220px'*/ +/*}*/ diff --git a/packages/serverless-logic-web-tools/src/homepage/uiNav/HomePageNav.tsx b/packages/serverless-logic-web-tools/src/homepage/uiNav/HomePageNav.tsx new file mode 100644 index 0000000000..b0bcf908fa --- /dev/null +++ b/packages/serverless-logic-web-tools/src/homepage/uiNav/HomePageNav.tsx @@ -0,0 +1,43 @@ +/* + * Copyright 2022 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 * as React from "react"; +import { Nav, NavItem, NavList } from "@patternfly/react-core"; +import { Link } from "react-router-dom"; + +export function HomePageNav(props: { pathname: string }) { + return ( + <Nav aria-label="Global NAV" theme="dark"> + <NavList> + <NavItem itemId={0} key={"Overview-nav"} isActive={props.pathname === "/"}> + <Link to="/">Overview</Link> + </NavItem> + + <NavItem itemId={1} key={"Serverless-models-nav"} isActive={props.pathname === "/ServerlessModels"}> + <Link to="/ServerlessModels">Serverless Models</Link> + </NavItem> + + <NavItem itemId={2} key={"SampleCatalog-nav"} isActive={props.pathname === "/SampleCatalog"}> + <Link to="/SampleCatalog">Sample Catalog</Link> + </NavItem> + + <NavItem itemId={3} key={"Documentation-nav"} isActive={props.pathname === "/Documentation"}> + <Link to="/Documentation">Documentation</Link> + </NavItem> + </NavList> + </Nav> + ); +} diff --git a/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx b/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx index 52e97bc03b..686c59fd1b 100644 --- a/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx +++ b/packages/serverless-logic-web-tools/src/navigation/RoutesSwitch.tsx @@ -17,46 +17,46 @@ import * as React from "react"; import { useMemo } from "react"; import { Route, Switch } from "react-router-dom"; -import { EditorPage } from "../editor/EditorPage"; -import { supportedFileExtensionArray } from "../extension"; -import { HomePage } from "../home/HomePage"; -import { NewWorkspaceFromUrlPage } from "../workspace/components/NewWorkspaceFromUrlPage"; -import { NewWorkspaceWithEmptyFilePage } from "../workspace/components/NewWorkspaceWithEmptyFilePage"; import { useRoutes } from "./Hooks"; -import { NoMatchPage } from "./NoMatchPage"; +import { OnlineEditorPage } from "../homepage/pageTemplate/OnlineEditorPage"; +import { Label } from "@patternfly/react-core/dist/js/components/Label"; +import { HomePageRoutes } from "../homepage/routes/HomePageRoutes"; export function RoutesSwitch() { const routes = useRoutes(); - const supportedExtensions = useMemo(() => supportedFileExtensionArray.join("|"), []); + const buildInfo = useMemo(() => { + return process.env["WEBPACK_REPLACE__buildInfo"]; + }, []); + + const renderPage = (routeProps: { + location: { + pathname: + | string + | number + | boolean + | {} + | React.ReactElement<any, string | React.JSXElementConstructor<any>> + | React.ReactNodeArray + | React.ReactPortal + | null + | undefined; + }; + }) => { + return ( + <OnlineEditorPage> + <HomePageRoutes /> + {buildInfo && ( + <div className={"kie-tools--build-info"}> + <Label>{buildInfo}</Label> + </div> + )} + </OnlineEditorPage> + ); + }; return ( <Switch> - <Route path={routes.newModel.path({ extension: `:extension(${supportedExtensions})` })}> - {({ match }) => <NewWorkspaceWithEmptyFilePage extension={match!.params.extension!} />} - </Route> - <Route path={routes.importModel.path({})}> - <NewWorkspaceFromUrlPage /> - </Route> - <Route - path={routes.workspaceWithFilePath.path({ - workspaceId: ":workspaceId", - fileRelativePath: `:fileRelativePath*`, - extension: `:extension?`, - })} - > - {({ match }) => ( - <EditorPage - workspaceId={match!.params.workspaceId!} - fileRelativePath={`${match!.params.fileRelativePath ?? ""}${ - match!.params.extension ? `.${match!.params.extension}` : "" - }`} - /> - )} - </Route> - <Route exact={true} path={routes.home.path({})}> - <HomePage /> - </Route> - <Route component={NoMatchPage} /> + <Route path={routes.home.path({})} render={renderPage}></Route> </Switch> ); } diff --git a/packages/serverless-logic-web-tools/src/pageTemplate/OnlineEditorPage.tsx b/packages/serverless-logic-web-tools/src/pageTemplate/OnlineEditorPage.tsx deleted file mode 100644 index f6c37d12cf..0000000000 --- a/packages/serverless-logic-web-tools/src/pageTemplate/OnlineEditorPage.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2021 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 * as React from "react"; -import { useMemo } from "react"; -import { Masthead, MastheadBrand, MastheadMain } from "@patternfly/react-core/dist/js/components/Masthead"; -import { Page, PageHeaderToolsItem } from "@patternfly/react-core/dist/js/components/Page"; -import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; -import { Flex, FlexItem } from "@patternfly/react-core/dist/js/layouts/Flex"; -import { useHistory } from "react-router"; -import { KieSandboxExtendedServicesIcon } from "../kieSandboxExtendedServices/KieSandboxExtendedServicesIcon"; -import { useRoutes } from "../navigation/Hooks"; -import { OpenshiftDeploymentsDropdown } from "../openshift/dropdown/OpenshiftDeploymentsDropdown"; -import { SettingsButton } from "../settings/SettingsButton"; -import { Tooltip } from "@patternfly/react-core/dist/js/components/Tooltip"; -import { ExclamationIcon } from "@patternfly/react-icons/dist/js/icons"; -import { APP_NAME } from "../AppConstants"; - -export function OnlineEditorPage(props: { children?: React.ReactNode }) { - const history = useHistory(); - const routes = useRoutes(); - - const isChromiumBased = useMemo(() => { - const agent = window.navigator.userAgent.toLowerCase(); - return agent.indexOf("edg") > -1 || agent.indexOf("chrome") > -1; - }, []); - - return ( - <Page - header={ - <Masthead aria-label={"Page header"} display={{ default: "stack" }}> - <MastheadMain style={{ justifyContent: "space-between" }}> - <PageHeaderToolsItem className={"pf-l-flex"}> - <MastheadBrand - onClick={() => history.push({ pathname: routes.home.path({}) })} - style={{ textDecoration: "none" }} - > - <TextContent> - <Text component={TextVariants.h1} ouiaId={"app-title"}> - {APP_NAME} - </Text> - </TextContent> - </MastheadBrand> - </PageHeaderToolsItem> - <Flex justifyContent={{ default: "justifyContentFlexEnd" }}> - <FlexItem> - <PageHeaderToolsItem> - <OpenshiftDeploymentsDropdown /> - </PageHeaderToolsItem> - </FlexItem> - <FlexItem> - <PageHeaderToolsItem> - <SettingsButton /> - </PageHeaderToolsItem> - </FlexItem> - <FlexItem> - <PageHeaderToolsItem> - <KieSandboxExtendedServicesIcon /> - </PageHeaderToolsItem> - </FlexItem> - {!isChromiumBased && ( - <Tooltip - className="kogito--editor__light-tooltip" - key={"not-chromium"} - content={"To get the best experience, please prefer using Chromium based browsers."} - flipBehavior={["left"]} - distance={20} - > - <ExclamationIcon - data-testid="not-chromium-icon" - className="kogito--editor__kie-sandbox-extended-services-dropdown-icon-outdated static-opacity" - id="kie-sandbox-extended-services-not-chromium-icon" - style={{ cursor: "pointer" }} - /> - </Tooltip> - )} - </Flex> - </MastheadMain> - </Masthead> - } - > - {props.children} - </Page> - ); -} diff --git a/packages/serverless-logic-web-tools/src/workspace/components/NewWorkspaceFromUrlPage.tsx b/packages/serverless-logic-web-tools/src/workspace/components/NewWorkspaceFromUrlPage.tsx index d5e5ac9cde..284172d44b 100644 --- a/packages/serverless-logic-web-tools/src/workspace/components/NewWorkspaceFromUrlPage.tsx +++ b/packages/serverless-logic-web-tools/src/workspace/components/NewWorkspaceFromUrlPage.tsx @@ -24,7 +24,6 @@ import { Spinner } from "@patternfly/react-core/dist/js/components/Spinner"; import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; import { QueryParams } from "../../navigation/Routes"; import { useQueryParam } from "../../queryParams/QueryParamsContext"; -import { OnlineEditorPage } from "../../pageTemplate/OnlineEditorPage"; import { PageSection } from "@patternfly/react-core/dist/js/components/Page"; import { basename } from "path"; import { WorkspaceKind } from "@kie-tools-core/workspaces-git-fs/dist/worker/api/WorkspaceOrigin"; @@ -285,22 +284,20 @@ export function NewWorkspaceFromUrlPage() { return ( <> - <OnlineEditorPage> - {importingError && <EditorPageErrorPage path={importableUrl.url.toString()} errors={[importingError]} />} - {!importingError && ( - <PageSection variant={"light"} isFilled={true} padding={{ default: "noPadding" }}> - <Bullseye> - <TextContent> - <Bullseye> - <Spinner /> - </Bullseye> - <br /> - <Text component={TextVariants.p}>{`Importing from '${queryParamUrl}'`}</Text> - </TextContent> - </Bullseye> - </PageSection> - )} - </OnlineEditorPage> + {importingError && <EditorPageErrorPage path={importableUrl.url.toString()} errors={[importingError]} />} + {!importingError && ( + <PageSection variant={"light"} isFilled={true} padding={{ default: "noPadding" }}> + <Bullseye> + <TextContent> + <Bullseye> + <Spinner /> + </Bullseye> + <br /> + <Text component={TextVariants.p}>{`Importing from '${queryParamUrl}'`}</Text> + </TextContent> + </Bullseye> + </PageSection> + )} </> ); } diff --git a/packages/serverless-logic-web-tools/src/workspace/components/NewWorkspaceWithEmptyFilePage.tsx b/packages/serverless-logic-web-tools/src/workspace/components/NewWorkspaceWithEmptyFilePage.tsx index 52eac5b847..d142179e57 100644 --- a/packages/serverless-logic-web-tools/src/workspace/components/NewWorkspaceWithEmptyFilePage.tsx +++ b/packages/serverless-logic-web-tools/src/workspace/components/NewWorkspaceWithEmptyFilePage.tsx @@ -19,7 +19,6 @@ import * as React from "react"; import { useEffect } from "react"; import { useHistory } from "react-router"; import { useRoutes } from "../../navigation/Hooks"; -import { OnlineEditorPage } from "../../pageTemplate/OnlineEditorPage"; import { PageSection } from "@patternfly/react-core/dist/js/components/Page"; import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/js/components/Text"; import { Bullseye } from "@patternfly/react-core/dist/js/layouts/Bullseye"; @@ -52,18 +51,16 @@ export function NewWorkspaceWithEmptyFilePage(props: { extension: string }) { }, [routes, history, props.extension, workspaces]); return ( - <OnlineEditorPage> - <PageSection variant={"light"} isFilled={true} padding={{ default: "noPadding" }}> - <Bullseye> - <TextContent> - <Bullseye> - <Spinner /> - </Bullseye> - <br /> - <Text component={TextVariants.p}>{`Loading...`}</Text> - </TextContent> - </Bullseye> - </PageSection> - </OnlineEditorPage> + <PageSection variant={"light"} isFilled={true} padding={{ default: "noPadding" }}> + <Bullseye> + <TextContent> + <Bullseye> + <Spinner /> + </Bullseye> + <br /> + <Text component={TextVariants.p}>{`Loading...`}</Text> + </TextContent> + </Bullseye> + </PageSection> ); } diff --git a/packages/serverless-logic-web-tools/static/images/kogito_log_workbranch.svg b/packages/serverless-logic-web-tools/static/images/kogito_log_workbranch.svg new file mode 100644 index 0000000000..7614f359e6 --- /dev/null +++ b/packages/serverless-logic-web-tools/static/images/kogito_log_workbranch.svg @@ -0,0 +1,52 @@ +<svg version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 560.2 60" height="60" width="560.2" style="enable-background:new 0 0 560.2 60;" xmlns="http://www.w3.org/2000/svg"> + <defs></defs> + <style type="text/css"> + .st0{fill:#FFFFFF;} + .st1{fill:#AFD4EB;} + .st2{fill:#F48227;} + .st3{fill:#014E64;} + .st4{fill:none;} + </style> + <title>Serverless Logic Web Tools</title> + <path class="st1" d="M3.4,45.1l20.8,12.3l22.7-12.1L42,30.2l-6.3,5.5c0,0,2.6,4.8,1.3,5.1l-5.5-0.5l-5.8,3.2l-4.5-1.8l-1.5-1.4 + l-2.1-0.5l-3,1.4L13.4,40l0.9-3.3l-3.1-2.9L6.7,31L3.4,45.1z"></path> + <polygon class="st1" points="21,30.6 24.9,33 29,31.2 33,33.4 34.7,35.2 37,38 36.9,40.8 33.2,39.8 26.7,39.4 19.9,39.5 15.6,40.4 + 13.3,40 14.9,35.1 "></polygon> + <polygon class="st2" points="10.8,18.2 22.4,17.5 24.9,19.8 27.4,17.8 39.2,18.1 40.8,21.8 41.1,27.9 40.2,32.9 36.7,35.4 + 34.7,35.2 31.8,32.5 29,31.2 26.5,32.6 21.2,31.4 18.7,32.3 14.9,35.1 11.1,33.7 8.4,30.2 8.2,26.6 "></polygon> + <polygon class="st2" points="19.9,39.5 24.5,39.7 29.6,39.8 30.9,40.6 27.4,43.3 22.1,43 "></polygon> + <polygon class="st0" points="3.4,2.2 13,3.9 16,8.4 22.8,4.3 28,4.3 33.6,8.3 38.4,3.8 47.7,2.6 47.7,5.6 44.6,12.1 45.4,17.5 + 41.2,20.6 39.3,18.2 26.7,17.9 25,19.9 23.3,17.6 10.9,18.3 9.3,20.2 5.2,18.6 4.7,15.2 5.2,11.9 4.3,8.6 2.1,4.6 "></polygon> + <path class="st3" d="M11.1,21.5c2.1-8.7,8.8-15.8,14.1-15.9c4.4,0.3,12.1,6.5,14.1,15.9l2.4,0.3c-1.4-9.4-8.4-18-16.5-18 + s-13.9,8-16.3,17.7L11.1,21.5z"></path> + <path class="st3" d="M36.7,49.6c-0.3-1.7-0.3-3.4,0-5.1c0,0,0.6,4.3,1.4,4.5L36.7,49.6z"></path> + <path class="st3" d="M31.1,53c-0.3-1.7-0.3-3.4,0-5.1c0,0,0.6,4.3,1.4,4.5L31.1,53z"></path> + <path class="st3" d="M13.8,49.7c0.3-1.7,0.3-3.4,0-5.1c0,0-0.6,4.3-1.4,4.5L13.8,49.7z"></path> + <path class="st3" d="M19.4,53.2c0.3-1.7,0.3-3.4,0-5.1c0,0-0.6,4.3-1.4,4.5L19.4,53.2z"></path> + <polygon class="st3" points="7.5,19.2 1.6,46.3 25.3,60 49.1,46.3 43.1,19.5 39,20.5 44.4,44.4 25.3,55.2 6.1,44.3 11.3,20.2 "></polygon> + <path class="st3" d="M39.9,17.5c0,0,3.3,0.7,4-1.6c0,0,0.5-1.9-0.7-2.8c-0.4-0.4-0.8-0.6-1.4-0.7l4.4-8.2l-7.2,1.1l-3,5.2l-3-3 + l2.5-4.3c0.5-1.1,1.6-1.8,2.7-1.9l7.8-1.2c0,0,5.7-0.7,4.2,5.2l-3.3,6.1c1.9,2.9,1.3,6.7-1.4,8.8c-1.4,1.1-3.2,1.7-4.9,1.5 + L39.9,17.5z"></path> + <path class="st3" d="M10.8,17.5c0,0-3.3,0.7-4-1.6c0,0-0.5-1.9,0.7-2.8c0.4-0.4,0.8-0.6,1.4-0.7L4.3,4.1l7.2,1.1l3,5.2l2.9-3L15,3.1 + c-0.5-1.1-1.6-1.8-2.7-1.9L4.5,0c0,0-5.7-0.7-4.2,5.2l3.3,6.1c-1.9,2.9-1.3,6.7,1.4,8.8c1.4,1.1,3.2,1.7,4.9,1.5L10.8,17.5z"></path> + <path class="st3" d="M29.6,39.8c-1.8,2.4-5.3,2.8-7.6,1c-0.4-0.3-0.7-0.6-1-1h-3.6c2.3,4.4,7.7,6,12.1,3.7c1.6-0.8,2.9-2.1,3.7-3.7 + H29.6z"></path> + <ellipse class="st4" cx="25.4" cy="13.2" rx="12.1" ry="11.5"></ellipse> + <path class="st3" d="M19.1,6.2c1.9-1,3.9-1.5,6-1.4c2.1,0,5.3,1.9,6.9,2.7c1.9,0.4,2.5-0.4,4,0.3c-3.3-6-10.9-8.2-16.9-4.9 + c-2.1,1.2-3.8,2.9-5,5.1C15.8,7.2,17.4,6.6,19.1,6.2z"></path> + <path class="st3" d="M36.1,36.7c3.3-0.5,5.7-3.2,5.8-6.5l-2.3-8.2c0,0,2.5,12.8-4.7,12.4L36.1,36.7z"></path> + <path class="st3" d="M14.2,36.7c-3.3-0.5-5.7-3.2-5.8-6.5l2.3-8.2c0,0-2.5,12.8,4.7,12.4L14.2,36.7z"></path> + <rect x="30.8" y="20.7" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.9 29.9319)" class="st3" width="2.7" height="7.6"></rect> + <rect x="28.4" y="23.1" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.8677 29.947)" class="st3" width="7.6" height="2.7"></rect> + <path class="st3" d="M14.5,24.7c0,0,4.2-6.1,8.5,0C23,24.7,19.1,30.3,14.5,24.7z"></path> + <path class="st3" d="M25.1,40.5c3.3-0.1,6.6,0.4,9.7,1.5c0,0,3.6,1.2,3.5-2.2c-0.1-3.4-4-7.6-7.4-9.1c-0.2-0.4-0.3-0.8-0.4-1.2 + c-0.3-0.5-1-0.6-1.4-0.3c-0.1,0.1-0.1,0.1-0.2,0.2c-1,1.2-2.3,1.9-3.8,2.1v2.4c1.1,0.1,2.2-0.3,3.1-1c0.5-0.5,1.4-0.5,1.9,0 + c2.5,1.4,4.5,3.5,5.7,6c0,0,0.7,1.9-0.9,0.8c-0.6-0.3-1.2-0.5-1.8-0.7c-0.1-0.8-0.4-1.6-1-2.2c0.2,0.7,0.2,1.4,0,2.1 + c-0.9-0.2-1.8-0.3-2.7-0.4c0-0.9-0.3-1.7-0.9-2.3c0.2,0.7,0.2,1.5,0,2.2c-1.2-0.1-2.3-0.1-3.5,0L25.1,40.5z"></path> + <path class="st3" d="M25.5,40.5c-3.3-0.1-6.6,0.4-9.7,1.5c0,0-3.6,1.2-3.5-2.2c0.1-3.4,4-7.6,7.4-9.1c0.2-0.4,0.3-0.8,0.4-1.2 + c0.3-0.5,1-0.6,1.4-0.3c0.1,0.1,0.1,0.1,0.2,0.2c1,1.1,2.3,1.9,3.8,2.1v2.4c-1.1,0.1-2.2-0.3-3.1-1c-0.5-0.5-1.4-0.5-1.9,0 + c-2.5,1.4-4.5,3.5-5.7,6c0,0-0.7,1.9,0.9,0.8c0.6-0.3,1.2-0.5,1.8-0.7c0.1-0.8,0.4-1.6,1-2.2c-0.2,0.7-0.2,1.4,0,2.1 + c0.9-0.2,1.8-0.3,2.7-0.4c0-0.9,0.3-1.7,0.9-2.3c-0.2,0.7-0.2,1.5,0,2.2c1.2-0.1,2.3-0.1,3.5,0L25.5,40.5z"></path> + <polygon class="st3" points="10.7,19.4 22.8,18.7 25.1,21.2 27.6,18.8 39.8,19.4 39,17 26.6,16.1 25.1,18 23.8,16.2 11.1,17 "></polygon> + <text style="fill: rgb(51, 51, 51); fill-opacity: 0; font-family: Arial, sans-serif; font-size: 9.4px; paint-order: fill; stroke-width: 4.56531px; white-space: pre;" transform="matrix(4.218454, 0, 0, 4.543271, -200.767197, -13.27547)" x="62.38" y="12.27">Serverless Logic Web Tools</text> +</svg> \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
