Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(CanvasForm): Scrollbar overlapping controls #871

Merged
merged 1 commit into from
Feb 26, 2024
Merged
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
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.canvas-form {
overflow: auto;
height: 100%;

&__body {
overflow: auto;
}
}
79 changes: 41 additions & 38 deletions packages/ui/src/components/Visualization/Canvas/CanvasForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Title } from '@patternfly/react-core';
import { Card, CardBody, CardHeader } from '@patternfly/react-core';
import isEmpty from 'lodash.isempty';
import { FunctionComponent, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
import { EntitiesContext } from '../../../providers/entities.provider';
import { setValue } from '../../../utils';
import { ErrorBoundary } from '../../ErrorBoundary';
import { SchemaService } from '../../Form';
import { CustomAutoForm, CustomAutoFormRef } from '../../Form/CustomAutoForm';
Expand All @@ -10,11 +11,12 @@ import { LoadBalancerEditor } from '../../Form/loadBalancer/LoadBalancerEditor';
import { StepExpressionEditor } from '../../Form/stepExpression/StepExpressionEditor';
import { UnknownNode } from '../Custom/UnknownNode';
import './CanvasForm.scss';
import { CanvasFormHeader } from './Form/CanvasFormHeader';
import { CanvasNode } from './canvas.models';
import { setValue } from '../../../utils';

interface CanvasFormProps {
selectedNode: CanvasNode;
onClose?: () => void;
}

export const CanvasForm: FunctionComponent<CanvasFormProps> = (props) => {
Expand All @@ -34,7 +36,7 @@ export const CanvasForm: FunctionComponent<CanvasFormProps> = (props) => {
return schemaServiceRef.current.getSchemaBridge(visualComponentSchema?.schema);
}, [visualComponentSchema?.schema]);
const model = visualComponentSchema?.definition;
const componentName = visualComponentSchema?.title;
const title = visualComponentSchema?.title;

useEffect(() => {
formRef.current?.form.reset();
Expand All @@ -54,45 +56,46 @@ export const CanvasForm: FunctionComponent<CanvasFormProps> = (props) => {
[entitiesContext, props.selectedNode.data?.vizNode],
);

const isExpressionAwareStep = useMemo(() => {
return schema?.schema && schema.schema['$comment']?.includes('expression');
}, [schema]);

const isDataFormatAwareStep = useMemo(() => {
return schema?.schema && schema.schema['$comment']?.includes('dataformat');
}, [schema]);

const isLoadBalanceAwareStep = useMemo(() => {
return schema?.schema && schema.schema['$comment']?.includes('loadbalance');
}, [schema]);

const isUnknownComponent = useMemo(() => {
return schema?.schema === undefined || Object.keys(schema?.schema).length === 0;
const stepFeatures = useMemo(() => {
const isExpressionAwareStep = schema?.schema && schema.schema['$comment']?.includes('expression');
const isDataFormatAwareStep = schema?.schema && schema.schema['$comment']?.includes('dataformat');
const isLoadBalanceAwareStep = schema?.schema && schema.schema['$comment']?.includes('loadbalance');
const isUnknownComponent = schema?.schema === undefined || Object.keys(schema?.schema).length === 0;
return { isExpressionAwareStep, isDataFormatAwareStep, isLoadBalanceAwareStep, isUnknownComponent };
}, [schema]);

return (
<ErrorBoundary key={props.selectedNode.id} fallback={<p>This node cannot be configured yet</p>}>
<Title headingLevel="h1">{componentName}</Title>
<div className="canvas-form">
{isUnknownComponent ? (
<UnknownNode model={model} />
) : (
<>
{isExpressionAwareStep && <StepExpressionEditor selectedNode={props.selectedNode} />}
{isDataFormatAwareStep && <DataFormatEditor selectedNode={props.selectedNode} />}
{isLoadBalanceAwareStep && <LoadBalancerEditor selectedNode={props.selectedNode} />}
<CustomAutoForm
ref={formRef}
schemaBridge={schema}
model={model}
onChange={handleOnChangeIndividualProp}
sortFields={false}
omitFields={SchemaService.OMIT_FORM_FIELDS}
data-testid="autoform"
/>
</>
)}
</div>
<Card className="canvas-form">
<CardHeader>
<CanvasFormHeader
nodeId={props.selectedNode.id}
title={title}
onClose={props.onClose}
nodeIcon={props.selectedNode.data?.vizNode?.data?.icon}
/>
</CardHeader>
<CardBody className="canvas-form__body">
{stepFeatures.isUnknownComponent ? (
<UnknownNode model={model} />
) : (
<>
{stepFeatures.isExpressionAwareStep && <StepExpressionEditor selectedNode={props.selectedNode} />}
{stepFeatures.isDataFormatAwareStep && <DataFormatEditor selectedNode={props.selectedNode} />}
{stepFeatures.isLoadBalanceAwareStep && <LoadBalancerEditor selectedNode={props.selectedNode} />}
<CustomAutoForm
ref={formRef}
schemaBridge={schema}
model={model}
onChange={handleOnChangeIndividualProp}
sortFields={false}
omitFields={SchemaService.OMIT_FORM_FIELDS}
data-testid="autoform"
/>
</>
)}
</CardBody>
</Card>
</ErrorBoundary>
);
};
14 changes: 0 additions & 14 deletions packages/ui/src/components/Visualization/Canvas/CanvasSideBar.scss

This file was deleted.

36 changes: 6 additions & 30 deletions packages/ui/src/components/Visualization/Canvas/CanvasSideBar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { Button, Card, CardBody, Grid, CardTitle, GridItem, CardHeader } from '@patternfly/react-core';
import { TopologySideBar } from '@patternfly/react-topology';
import { FunctionComponent } from 'react';
import { ErrorBoundary } from '../../ErrorBoundary';
import { CanvasForm } from './CanvasForm';
import { CanvasNode } from './canvas.models';
import { TimesIcon } from '@patternfly/react-icons';
import { ErrorBoundary } from '../../ErrorBoundary';
import './CanvasSideBar.scss';

interface CanvasSideBarProps {
selectedNode: CanvasNode | undefined;
Expand All @@ -19,32 +16,11 @@ export const CanvasSideBar: FunctionComponent<CanvasSideBarProps> = (props) => {
* and doesn't take into account the sidebar children.
*/
<TopologySideBar show={props.selectedNode !== undefined}>
<Card className="canvas-sidebar">
<CardHeader>
<Grid hasGutter>
<GridItem span={2}>
<img
className={'sidebar-icon-' + props.selectedNode?.id}
src={props.selectedNode?.data?.vizNode?.data.icon}
alt="icon"
/>
</GridItem>
<GridItem span={9}>
<CardTitle>{props.selectedNode?.id}</CardTitle>
</GridItem>
<GridItem span={1}>
<Button data-testid="close-side-bar" variant="plain" icon={<TimesIcon />} onClick={props.onClose} />
</GridItem>
</Grid>
</CardHeader>
<CardBody className="canvas-sidebar canvas-sidebar__body">
{props.selectedNode === undefined ? null : (
<ErrorBoundary key={props.selectedNode.id} fallback={<p>Something didn't work as expected</p>}>
<CanvasForm selectedNode={props.selectedNode} />
</ErrorBoundary>
)}
</CardBody>
</Card>
{props.selectedNode === undefined ? null : (
<ErrorBoundary key={props.selectedNode.id} fallback={<p>Something didn't work as expected</p>}>
<CanvasForm selectedNode={props.selectedNode} onClose={props.onClose} />
</ErrorBoundary>
)}
</TopologySideBar>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.form-header {
display: flex;
flex-flow: row nowrap;
align-items: center;

img[class^='form-header__icon-'] {
height: 40px;
margin-right: 10px;
}

&__title {
text-transform: capitalize;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { render } from '@testing-library/react';
import { CanvasFormHeader } from './CanvasFormHeader';

describe('CanvasFormHeader', () => {
it('renders correctly', () => {
const { asFragment } = render(<CanvasFormHeader nodeId="nodeId" nodeIcon="nodeIcon" title="title" />);
expect(asFragment()).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Button, Grid, GridItem, Title } from '@patternfly/react-core';
import { TimesIcon } from '@patternfly/react-icons';
import { FunctionComponent } from 'react';
import './CanvasFormHeader.scss';

interface CanvasFormHeaderProps {
nodeId: string;
title?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
nodeIcon: any;
onClose?: () => void;
}

export const CanvasFormHeader: FunctionComponent<CanvasFormHeaderProps> = (props) => {
return (
<Grid hasGutter>
<GridItem className="form-header" span={11}>
<img className={`form-header__icon-${props.nodeId}`} src={props.nodeIcon} alt="icon" />
<Title className="form-header__title" headingLevel="h2">
{props.title}
</Title>
</GridItem>
<GridItem span={1}>
<Button data-testid="close-side-bar" variant="plain" icon={<TimesIcon />} onClick={props.onClose} />
</GridItem>
</Grid>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`CanvasFormHeader renders correctly 1`] = `
<DocumentFragment>
<div
class="pf-v5-l-grid pf-m-gutter"
>
<div
class="pf-v5-l-grid__item pf-m-11-col form-header"
>
<img
alt="icon"
class="form-header__icon-nodeId"
src="nodeIcon"
/>
<h2
class="pf-v5-c-title pf-m-xl form-header__title"
data-ouia-component-id="OUIA-Generated-Title-1"
data-ouia-component-type="PF5/Title"
data-ouia-safe="true"
>
title
</h2>
</div>
<div
class="pf-v5-l-grid__item pf-m-1-col"
>
<button
aria-disabled="false"
class="pf-v5-c-button pf-m-plain"
data-ouia-component-id="OUIA-Generated-Button-plain-1"
data-ouia-component-type="PF5/Button"
data-ouia-safe="true"
data-testid="close-side-bar"
type="button"
>
<svg
aria-hidden="true"
class="pf-v5-svg"
fill="currentColor"
height="1em"
role="img"
viewBox="0 0 352 512"
width="1em"
>
<path
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
/>
</svg>
</button>
</div>
</div>
</DocumentFragment>
`;
Loading
Loading