Skip to content

Commit

Permalink
DBZ-8388: Add Transform Edit and Delete functionality (#26)
Browse files Browse the repository at this point in the history
* DBZ-8388: Add Transfrom Edit

* DBZ-8388: Add Transform Edit and Delete functionality
  • Loading branch information
indraraj authored Nov 12, 2024
1 parent 1b98a5e commit 965ede2
Show file tree
Hide file tree
Showing 10 changed files with 870 additions and 70 deletions.
9 changes: 6 additions & 3 deletions src/appLayout/AppHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
ToolbarContent,
ToolbarGroup,
ToolbarItem,
Avatar,
// Avatar,
NotificationBadge,
NotificationBadgeVariant,
PageToggleButton,
Expand All @@ -19,7 +19,7 @@ import { BarsIcon } from "@patternfly/react-icons";
import React from "react";
import dbz_logo_black from "../assets/color_black_debezium.svg";
import dbz_svg from "../assets/debezium_logo.png";
import imgAvatar from "@patternfly/react-core/src/components/assets/avatarImg.svg";
// import imgAvatar from "@patternfly/react-core/src/components/assets/avatarImg.svg";
import { useNavigate } from "react-router-dom";
import { useData } from "./AppContext";
import { NotificationProps } from "./AppNotificationContext";
Expand Down Expand Up @@ -95,11 +95,14 @@ const AppHeader: React.FC<AppHeaderProps> = ({
></NotificationBadge>
</ToolbarItem>
</ToolbarGroup>

{/*
// TODO: Add user avatar when multi tenancy is implemented
<ToolbarItem variant="separator" />
<ToolbarItem>
<Avatar src={imgAvatar} alt="user avatar" />
</ToolbarItem>
</ToolbarItem> */}
</ToolbarContent>
</Toolbar>
</MastheadContent>
Expand Down
8 changes: 1 addition & 7 deletions src/pages/Destination/CreateDestination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import _ from "lodash";
import { createPost, Destination } from "../../apis/apis";
import { API_URL } from "../../utils/constants";
import { convertMapToObject } from "../../utils/helpers";
import { useData } from "../../appLayout/AppContext";
import { useNotification } from "../../appLayout/AppNotificationContext";
import PageHeader from "@components/PageHeader";
import SourceSinkForm from "@components/SourceSinkForm";
Expand Down Expand Up @@ -50,8 +49,6 @@ const CreateDestination: React.FunctionComponent<CreateDestinationProps> = ({
navigate(url);
};

const { navigationCollapsed } = useData();

const { addNotification } = useNotification();

const [editorSelected, setEditorSelected] = React.useState("form-editor");
Expand Down Expand Up @@ -192,10 +189,7 @@ const CreateDestination: React.FunctionComponent<CreateDestinationProps> = ({
isCenterAligned
isFilled
className={
(modelLoaded && editorSelected === "form-editor") ||
(!modelLoaded &&
navigationCollapsed &&
editorSelected === "form-editor")
editorSelected === "form-editor"
? "custom-page-section create_destination-page_section"
: "create_destination-page_section"
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Destination/EditDestination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ const EditDestination: React.FunctionComponent = () => {
}
}}
>
Save change
Save changes
</Button>
<Button
variant="link"
Expand Down
16 changes: 6 additions & 10 deletions src/pages/Pipeline/ConfigurePipeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ import {
Source,
} from "../../apis/apis";
import { API_URL } from "../../utils/constants";
import { useData } from "../../appLayout/AppContext";
import PageHeader from "@components/PageHeader";
import { useAtom } from 'jotai';
import { useAtom } from "jotai";
import { selectedTransformAtom } from "./PipelineDesigner";

const ConfigurePipeline: React.FunctionComponent = () => {
Expand All @@ -58,7 +57,7 @@ const ConfigurePipeline: React.FunctionComponent = () => {

const [selectedTransform] = useAtom(selectedTransformAtom);

console.log("selectedTransform", selectedTransform)
console.log("selectedTransform", selectedTransform);

const navigateTo = (url: string) => {
navigate(url);
Expand All @@ -68,10 +67,6 @@ const ConfigurePipeline: React.FunctionComponent = () => {
navigate(-1);
};



const { navigationCollapsed } = useData();

const [editorSelected, setEditorSelected] = useState("form-editor");

const [isLoading, setIsLoading] = useState(false);
Expand Down Expand Up @@ -226,11 +221,12 @@ const ConfigurePipeline: React.FunctionComponent = () => {
{({ setValue, getValue, setError, values, errors }) => (
<>
<PageSection
isWidthLimited={editorSelected === "form-editor"}
isWidthLimited={true}
isCenterAligned
isFilled
// To do: Add custom class to the pf-v6-c-page__main-body for center alignment in collapsed navigation
className={navigationCollapsed ? "pipeline-page-section" : ""}
className={
editorSelected === "form-editor" ? "pipeline-page-section" : ""
}
>
{editorSelected === "form-editor" ? (
<Card className="pipeline-card-body">
Expand Down
39 changes: 17 additions & 22 deletions src/pages/Source/CreateSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { API_URL } from "../../utils/constants";
import { convertMapToObject } from "../../utils/helpers";
import sourceCatalog from "../../__mocks__/data/SourceCatalog.json";
import _ from "lodash";
import { useData } from "../../appLayout/AppContext";
import { useNotification } from "../../appLayout/AppNotificationContext";
import SourceSinkForm from "@components/SourceSinkForm";
import PageHeader from "@components/PageHeader";
Expand All @@ -34,7 +33,7 @@ interface CreateSourceProps {
onSelection?: (selection: Source) => void;
}

const CreateSource: React.FunctionComponent<CreateSourceProps> = ({
const CreateSource: React.FunctionComponent<CreateSourceProps> = ({
modelLoaded,
selectedId,
selectSource,
Expand All @@ -44,16 +43,12 @@ const CreateSource: React.FunctionComponent<CreateSourceProps> = ({

const sourceIdParam = useParams<{ sourceId: string }>();
const sourceIdModel = selectedId;
const sourceId = modelLoaded
? sourceIdModel
: sourceIdParam.sourceId;
const sourceId = modelLoaded ? sourceIdModel : sourceIdParam.sourceId;

const navigateTo = (url: string) => {
navigate(url);
};

const { navigationCollapsed } = useData();

const { addNotification } = useNotification();

const [editorSelected, setEditorSelected] = React.useState("form-editor");
Expand Down Expand Up @@ -146,17 +141,18 @@ const CreateSource: React.FunctionComponent<CreateSourceProps> = ({

return (
<>
{ !modelLoaded && <PageHeader
{!modelLoaded && (
<PageHeader
title="Create source"
description="To configure and create a connector fill out the below form or use the
smart editor to setup a new source connector. If you already have a
configuration file, you can setup a new source connector by uploading
it in the smart editor."
/>}
/>
)}
<PageSection className="create_source-toolbar">

<Toolbar id="create-editor-toggle">
<ToolbarContent >
<ToolbarContent>
<ToolbarItem>
<ToggleGroup aria-label="Toggle between form editor and smart editor">
<ToggleGroupItem
Expand Down Expand Up @@ -193,10 +189,7 @@ const CreateSource: React.FunctionComponent<CreateSourceProps> = ({
isCenterAligned
isFilled
className={
(modelLoaded && editorSelected === "form-editor") ||
(!modelLoaded &&
navigationCollapsed &&
editorSelected === "form-editor")
editorSelected === "form-editor"
? "custom-page-section create_source-page_section"
: "create_source-page_section"
}
Expand Down Expand Up @@ -246,18 +239,20 @@ const CreateSource: React.FunctionComponent<CreateSourceProps> = ({
Create source
</Button>
{modelLoaded ? (
<Button variant="link" onClick={() => selectSource && selectSource("")}>
<Button
variant="link"
onClick={() => selectSource && selectSource("")}
>
Back
</Button>
) : (
<Button
variant="link"
onClick={() => navigateTo("/source/catalog")}
>
Back to catalog
</Button>
variant="link"
onClick={() => navigateTo("/source/catalog")}
>
Back to catalog
</Button>
)}

</ActionGroup>
</PageSection>
</>
Expand Down
5 changes: 2 additions & 3 deletions src/pages/Source/EditSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,9 @@ const EditSource: React.FunctionComponent = () => {
)}
</PageSection>
<PageSection className="pf-m-sticky-bottom" isFilled={false}>
<ActionGroup>
<ActionGroup className="create_destination-footer">
<Button
variant="primary"
// onClick={handleCreateSource}
isLoading={isLoading}
isDisabled={isLoading}
type={ButtonType.submit}
Expand All @@ -271,7 +270,7 @@ const EditSource: React.FunctionComponent = () => {
}
}}
>
Save change
Save changes
</Button>
<Button variant="link" onClick={() => navigateTo("/source")}>
Cancel
Expand Down
55 changes: 33 additions & 22 deletions src/pages/Transforms/CreateTransforms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { useNavigate } from "react-router-dom";
import { createPost, TransformData } from "src/apis";
import { API_URL } from "@utils/constants";
import { useNotification } from "@appContext/AppNotificationContext";
import { find } from "lodash";

export interface ICreateTransformsProps {
modelLoaded?: boolean;
Expand Down Expand Up @@ -126,7 +127,6 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
setIsOpen(true);
}
}

setSelectOptions(newSelectOptions);
}, [filterValue, isOpen]);

Expand Down Expand Up @@ -192,23 +192,19 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({

const handleMenuArrowKeys = (key: string) => {
let indexToFocus = 0;

if (!isOpen) {
setIsOpen(true);
}

if (selectOptions!.every((option) => option.isDisabled)) {
return;
}

if (key === "ArrowUp") {
// When no index is set or at the first index, focus to the last, otherwise decrement focus index
if (focusedItemIndex === null || focusedItemIndex === 0) {
indexToFocus = selectOptions!.length - 1;
} else {
indexToFocus = focusedItemIndex - 1;
}

// Skip disabled options
while (selectOptions![indexToFocus].isDisabled) {
indexToFocus--;
Expand All @@ -217,7 +213,6 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
}
}
}

if (key === "ArrowDown") {
// When no index is set or at the last index, focus to the first, otherwise increment focus index
if (
Expand All @@ -236,14 +231,12 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
}
}
}

setActiveAndFocusedItem(indexToFocus);
};

const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
const focusedItem =
focusedItemIndex !== null ? selectOptions![focusedItemIndex] : null;

switch (event.key) {
case "Enter":
if (
Expand All @@ -254,11 +247,9 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
) {
selectOption(focusedItem.value, focusedItem.children as string);
}

if (!isOpen) {
setIsOpen(true);
}

break;
case "ArrowUp":
case "ArrowDown":
Expand Down Expand Up @@ -305,7 +296,6 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
isExpanded={isOpen}
aria-controls="select-typeahead-listbox"
/>

<TextInputGroupUtilities
{...(!inputValue ? { style: { display: "none" } } : {})}
>
Expand Down Expand Up @@ -335,7 +325,6 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
name: transformName,
};
const response = await createPost(`${API_URL}/api/transforms`, payload);

if (response.error) {
addNotification(
"danger",
Expand All @@ -353,6 +342,21 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
}
};

const dynamicFormDefaultValues = Object.entries(
find(transforms, { transform: selected })?.properties || {}
).reduce((acc: Record<string, string>, [key, value]) => {
if (value.defaultValue) {
acc[`debezium.transforms.transform-name.${key}`] = value.defaultValue;
}
return acc;
}, {});

const initialValues = {
"transform-name": "",
description: "",
...dynamicFormDefaultValues,
};

const handleItemClick = (
event:
| MouseEvent
Expand Down Expand Up @@ -398,16 +402,16 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
</ToolbarContent>
</Toolbar>
</PageSection>

<FormContextProvider initialValues={{}}>
<FormContextProvider initialValues={initialValues}>
{({ setValue, getValue, setError, values, errors }) => (
<>
<PageSection
isWidthLimited={editorSelected === "form-editor"}
isWidthLimited={true}
isCenterAligned
isFilled
// To do: Add custom class to the pf-v6-c-page__main-body for center alignment in collapsed navigation
className={"pipeline-page-section"}
className={
editorSelected === "form-editor" ? "pipeline-page-section" : ""
}
>
{editorSelected === "form-editor" ? (
<Card className="pipeline-card-body">
Expand Down Expand Up @@ -524,11 +528,18 @@ const CreateTransforms: React.FunctionComponent<ICreateTransformsProps> = ({
id: `field-group-${selected}-id`,
}}
titleDescription={
<>
Configuration properties passed to the
transformation with name{" "}
<i>"{values["transform-name"]}"</i>
</>
!values["transform-name"] ? (
<>
Enter <i>transform name</i> to enable
configuration properties.
</>
) : (
<>
Configuration properties passed to the
transformation with name
<i>"{values["transform-name"]}"</i>
</>
)
}
/>
}
Expand Down
Loading

0 comments on commit 965ede2

Please sign in to comment.