Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15,685 changes: 15,685 additions & 0 deletions debezium-platform-stage/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion debezium-platform-stage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@
"chromatic": "^13.3.5",
"cypress": "^15.7.1",
"eslint": "^8.57.0",
"start-server-and-test": "^2.1.3",
"eslint-plugin-react": "^7.35.0",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.26",
"eslint-plugin-storybook": "^9.0.7",
"jsdom": "^27.4.0",
"msw": "^2.12.7",
"start-server-and-test": "^2.1.3",
"storybook": "^8.6.15",
"typescript": "^5.2.2",
"vite": "^5.4.21",
Expand Down
6 changes: 5 additions & 1 deletion debezium-platform-stage/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,9 @@
"type": "Type",
"usedIn": "Used in",
"vaults": "Vaults",
"verify": "Verify"
"verify": "Verify",
"helpTopic": {
"readMoreInDocs": "Read more in docs",
"openInNewTab": "Open in new tab"
}
}
6 changes: 5 additions & 1 deletion debezium-platform-stage/public/locales/it/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,9 @@
"trademarkWarking": "Tutti i loghi e i marchi sono di proprietà dei rispettivi titolari",
"type": "Tipo",
"vaults": "Vault",
"verify": "Verifica"
"verify": "Verifica",
"helpTopic": {
"readMoreInDocs": "Leggi di più nella documentazione",
"openInNewTab": "Apri in una nuova scheda"
}
}
100 changes: 64 additions & 36 deletions debezium-platform-stage/src/appLayout/AppLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {
AlertGroup,
Drawer,
DrawerContent,
DrawerContentBody,
NotificationBadgeVariant,
Page,
} from "@patternfly/react-core";
Expand All @@ -18,14 +21,16 @@ import {
selectedDestinationAtom,
selectedTransformAtom,
} from "../pages/Pipeline/PipelineDesigner";
import { DocDrawerProvider, DocDrawerPanel, useDocDrawer } from "../components/DocDrawer";

interface IAppLayout {
children: React.ReactNode;
}

const AppLayout: React.FunctionComponent<IAppLayout> = ({ children }) => {
const AppLayoutInner: React.FunctionComponent<IAppLayout> = ({ children }) => {
const location = useLocation();
const pageId = "primary-app-container";
const { isOpen: isDocDrawerOpen, closeDoc } = useDocDrawer();

const [sidebarOpen, setSidebarOpen] = useState(() => {
const savedPreference = localStorage.getItem("side-nav-collapsed");
Expand All @@ -44,7 +49,6 @@ const AppLayout: React.FunctionComponent<IAppLayout> = ({ children }) => {

const { updateNavigationCollapsed } = useData();


const setSelectedSource = useSetAtom(selectedSourceAtom);
const setSelectedDestination = useSetAtom(selectedDestinationAtom);
const setSelectedTransform = useSetAtom(selectedTransformAtom);
Expand Down Expand Up @@ -86,7 +90,7 @@ const AppLayout: React.FunctionComponent<IAppLayout> = ({ children }) => {

// Clear pipeline atoms when navigating away from pipeline designer
useEffect(() => {
const isPipelineDesignerPage =
const isPipelineDesignerPage =
location.pathname.startsWith("/pipeline/pipeline_designer");

if (!isPipelineDesignerPage) {
Expand All @@ -110,41 +114,57 @@ const AppLayout: React.FunctionComponent<IAppLayout> = ({ children }) => {
setDrawerExpanded(!isDrawerExpanded);
};

useEffect(() => {
closeDoc();
}, [location.pathname, closeDoc]);

const page = (
<Page
className={sidebarOpen ? "" : "custom-app-page"}
mainContainerId={pageId}
masthead={
<AppHeader
toggleSidebar={toggleSidebar}
handleNotificationBadgeClick={onNotificationBadgeClick}
getNotificationBadgeVariant={getNotificationBadgeVariant}
addNotification={addNotification}
/>
}
sidebar={<AppSideNavigation isSidebarOpen={sidebarOpen} />}
isManagedSidebar
isContentFilled
breadcrumb={
location.pathname.split("/").length <= 2 ? undefined : (
<AppBreadcrumb />
)
}
groupProps={{
stickyOnBreakpoint: { default: "top" },
}}
notificationDrawer={
<AppNotification
notifications={notifications}
setNotifications={setNotifications}
setDrawerExpanded={setDrawerExpanded}
/>
}
isNotificationDrawerExpanded={isDrawerExpanded}
>
{children}
</Page>
);

return (
<>
<Page
className={sidebarOpen ? "" : "custom-app-page"}
mainContainerId={pageId}
masthead={
<AppHeader
toggleSidebar={toggleSidebar}
handleNotificationBadgeClick={onNotificationBadgeClick}
getNotificationBadgeVariant={getNotificationBadgeVariant}
addNotification={addNotification}
/>
}
sidebar={<AppSideNavigation isSidebarOpen={sidebarOpen} />}
isManagedSidebar
isContentFilled
breadcrumb={
location.pathname.split("/").length <= 2 ? undefined : (
<AppBreadcrumb />
)
}
groupProps={{
stickyOnBreakpoint: { default: "top" },
}}
notificationDrawer={
<AppNotification
notifications={notifications}
setNotifications={setNotifications}
setDrawerExpanded={setDrawerExpanded}
/>
}
isNotificationDrawerExpanded={isDrawerExpanded}
>
{children}
</Page>
{isDocDrawerOpen ? (
<Drawer isExpanded position="end">
<DrawerContent panelContent={<DocDrawerPanel />}>
<DrawerContentBody>{page}</DrawerContentBody>
</DrawerContent>
</Drawer>
) : (
page
)}
<AlertGroup
isToast
isLiveRegion
Expand All @@ -157,4 +177,12 @@ const AppLayout: React.FunctionComponent<IAppLayout> = ({ children }) => {
);
};

const AppLayout: React.FunctionComponent<IAppLayout> = ({ children }) => {
return (
<DocDrawerProvider>
<AppLayoutInner>{children}</AppLayoutInner>
</DocDrawerProvider>
);
};

export { AppLayout };
30 changes: 30 additions & 0 deletions debezium-platform-stage/src/components/ContextualHelp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Button } from "@patternfly/react-core";
import { ExternalLinkAltIcon } from "@patternfly/react-icons";
import { useTranslation } from "react-i18next";
import { useDocDrawer } from "./DocDrawer";

interface ContextualHelpProps {
href: string;
label?: string;
}

const ContextualHelp: React.FC<ContextualHelpProps> = ({ href, label }) => {
const { t } = useTranslation();
const { openDoc } = useDocDrawer();

const displayLabel = label || t("helpTopic.readMoreInDocs");

return (
<Button
variant="link"
isInline
icon={<ExternalLinkAltIcon />}
iconPosition="end"
onClick={() => openDoc(href, displayLabel)}
>
{displayLabel}
</Button>
);
};

export default ContextualHelp;
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { createContext, useCallback, useContext, useState } from "react";

interface DocDrawerState {
isOpen: boolean;
url: string | null;
title: string | null;
openDoc: (url: string, title?: string) => void;
closeDoc: () => void;
}

const DocDrawerContext = createContext<DocDrawerState>({
isOpen: false,
url: null,
title: null,
openDoc: () => {},
closeDoc: () => {},
});

export const useDocDrawer = () => useContext(DocDrawerContext);

Check warning on line 19 in debezium-platform-stage/src/components/DocDrawer/DocDrawerContext.tsx

View workflow job for this annotation

GitHub Actions / TypeScript Type and Lint Check (25.x)

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components

export const DocDrawerProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [isOpen, setIsOpen] = useState(false);
const [url, setUrl] = useState<string | null>(null);
const [title, setTitle] = useState<string | null>(null);

const openDoc = useCallback((docUrl: string, docTitle?: string) => {
setUrl(docUrl);
setTitle(docTitle || "Documentation");
setIsOpen(true);
}, []);

const closeDoc = useCallback(() => {
setIsOpen(false);
}, []);

return (
<DocDrawerContext.Provider value={{ isOpen, url, title, openDoc, closeDoc }}>
{children}
</DocDrawerContext.Provider>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.doc-drawer-panel {
border-left: 1px solid var(--pf-t--global--border--color--default);
}

.doc-drawer-header {
width: 100%;
padding-right: var(--pf-t--global--spacer--xl);
}

.doc-drawer-body {
height: 100%;
}

.doc-drawer-iframe {
width: 100%;
height: 100%;
border: none;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import {
DrawerActions,
DrawerCloseButton,
DrawerHead,
DrawerPanelBody,
DrawerPanelContent,
Title,
Button,
Flex,
FlexItem,
} from "@patternfly/react-core";
import { ExternalLinkAltIcon } from "@patternfly/react-icons";
import { useDocDrawer } from "./DocDrawerContext";
import { useTranslation } from "react-i18next";
import "./DocDrawerPanel.css";

const DocDrawerPanel: React.FC = () => {
const { url, title, closeDoc } = useDocDrawer();
const { t } = useTranslation();

return (
<DrawerPanelContent
className="doc-drawer-panel"
defaultSize="35%"
minSize="300px"
isResizable
>
<DrawerHead>
<Flex
justifyContent={{ default: "justifyContentSpaceBetween" }}
alignItems={{ default: "alignItemsCenter" }}
className="doc-drawer-header"
>
<FlexItem>
<Title headingLevel="h3" size="lg">
{title}
</Title>
</FlexItem>
<FlexItem>
<Button
variant="link"
component="a"
href={url || "#"}
target="_blank"
rel="noopener noreferrer"
icon={<ExternalLinkAltIcon />}
iconPosition="end"
isSmall
>
{t("helpTopic.openInNewTab")}
</Button>
</FlexItem>
</Flex>
<DrawerActions>
<DrawerCloseButton onClick={closeDoc} />
</DrawerActions>
</DrawerHead>
<DrawerPanelBody className="doc-drawer-body" hasNoPadding>
{url && (
<iframe
src={url}
title={title || "Documentation"}
className="doc-drawer-iframe"
/>
)}
</DrawerPanelBody>
</DrawerPanelContent>
);
};

export default DocDrawerPanel;
2 changes: 2 additions & 0 deletions debezium-platform-stage/src/components/DocDrawer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { DocDrawerProvider, useDocDrawer } from "./DocDrawerContext";
export { default as DocDrawerPanel } from "./DocDrawerPanel";
Loading
Loading