Skip to content

Commit

Permalink
fix alignment issues with MultiColumnField in Traffic Splitting modal
Browse files Browse the repository at this point in the history
  • Loading branch information
vikram-raj committed May 5, 2020
1 parent b19ffe0 commit 5869b05
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ValidatedOptions, TextInputTypes } from '@patternfly/react-core';
import { ValidatedOptions, TextInputTypes, gridItemSpanValueShape } from '@patternfly/react-core';
import { K8sResourceKind } from '@console/internal/module/k8s';

export interface FieldProps {
Expand Down Expand Up @@ -79,6 +79,7 @@ export interface MultiColumnFieldProps extends FieldProps {
emptyMessage?: string;
headers: string[];
children: React.ReactNode;
spans?: gridItemSpanValueShape[];
}

export interface YAMLEditorFieldProps extends FieldProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
.odc-multi-column-field {
&__row {
display: flex;
flex-direction: row;
position: relative;
margin-right: var(--pf-global--spacer--lg);
margin-bottom: var(--pf-global--spacer--lg);
max-height: var(--pf-global--spacer--xl);
}

&__col {
flex: 1 0 0;
margin-right: var(--pf-global--spacer--md);
}

&__col--button {
cursor: pointer;
line-height: var(--pf-global--spacer--xl);
position: absolute;
right: -30px;
top: 50%;
transform: translateY(-50%);
button:not(:disabled) {
cursor: pointer;
}
}
&__empty-message {
margin-bottom: var(--pf-global--spacer--sm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { MultiColumnFieldProps } from '../field-types';
import MultiColumnFieldHeader from './MultiColumnFieldHeader';
import MultiColumnFieldRow from './MultiColumnFieldRow';
import MultiColumnFieldFooter from './MultiColumnFieldFooter';
import { getSpans } from './multicolumn-field-utils';
import './MultiColumnField.scss';

const MultiColumnField: React.FC<MultiColumnFieldProps> = ({
Expand All @@ -23,9 +24,11 @@ const MultiColumnField: React.FC<MultiColumnFieldProps> = ({
disableDeleteRow,
disableAddRow,
toolTip,
spans,
}) => {
const { values } = useFormikContext<FormikValues>();
const fieldValue = _.get(values, name, []);
const fieldSpans = spans || getSpans(React.Children.count(children));
useFormikValidationFix(fieldValue);
return (
<FieldArray
Expand All @@ -45,7 +48,7 @@ const MultiColumnField: React.FC<MultiColumnFieldProps> = ({
</div>
)
) : (
<MultiColumnFieldHeader headers={headers} />
<MultiColumnFieldHeader headers={headers} spans={fieldSpans} />
)}
{fieldValue.length > 0 &&
fieldValue.map((value, index) => (
Expand All @@ -57,6 +60,7 @@ const MultiColumnField: React.FC<MultiColumnFieldProps> = ({
onDelete={() => remove(index)}
isReadOnly={isReadOnly}
disableDeleteRow={disableDeleteRow}
spans={fieldSpans}
>
{children}
</MultiColumnFieldRow>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import * as React from 'react';
import { Grid, GridItem, gridItemSpanValueShape } from '@patternfly/react-core';
import './MultiColumnField.scss';

export interface MultiColumnFieldHeaderProps {
headers: string[];
spans: gridItemSpanValueShape[];
}

const MultiColumnFieldHeader: React.FC<MultiColumnFieldHeaderProps> = ({ headers }) => (
const MultiColumnFieldHeader: React.FC<MultiColumnFieldHeaderProps> = ({ headers, spans }) => (
<div className="odc-multi-column-field__row">
{headers.map((header) => (
<div className="odc-multi-column-field__col" key={header}>
{header}
</div>
))}
<Grid className="odc-multi-column-field__row">
{headers.map((header, i) => (
<GridItem span={spans[i]} key={header}>
<div className="odc-multi-column-field__col">{header}</div>
</GridItem>
))}
</Grid>
<div className="odc-multi-column-field__col--button" />
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import * as React from 'react';
import { MinusCircleIcon } from '@patternfly/react-icons';
import { Tooltip, Button, ButtonVariant, ButtonType } from '@patternfly/react-core';
import {
Tooltip,
Button,
ButtonVariant,
ButtonType,
GridItem,
Grid,
gridItemSpanValueShape,
} from '@patternfly/react-core';
import './MultiColumnField.scss';

export interface MultiColumnFieldRowProps {
Expand All @@ -11,6 +19,7 @@ export interface MultiColumnFieldRowProps {
onDelete: () => void;
isReadOnly?: boolean;
disableDeleteRow?: boolean;
spans: gridItemSpanValueShape[];
}

const minusCircleIcon = (onDelete: () => void, disableDeleteRow?: boolean, toolTip?: string) => {
Expand Down Expand Up @@ -51,17 +60,20 @@ const MultiColumnFieldRow: React.FC<MultiColumnFieldRowProps> = ({
children,
isReadOnly,
disableDeleteRow,
spans,
}) => (
<div className="odc-multi-column-field__row">
{React.Children.map(children, (child: React.ReactElement) => {
const fieldName = `${name}.${rowIndex}.${child.props.name}`;
const newProps = { ...child.props, name: fieldName };
return (
<div key={fieldName} className="odc-multi-column-field__col">
{React.cloneElement(child, newProps)}
</div>
);
})}
<Grid>
{React.Children.map(children, (child: React.ReactElement, i) => {
const fieldName = `${name}.${rowIndex}.${child.props.name}`;
const newProps = { ...child.props, name: fieldName };
return (
<GridItem span={spans[i]} key={fieldName}>
<div className="odc-multi-column-field__col">{React.cloneElement(child, newProps)}</div>
</GridItem>
);
})}
</Grid>
{!isReadOnly && renderMinusCircleIcon(onDelete, toolTip, disableDeleteRow)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { getSpans } from '../multicolumn-field-utils';

describe('Multicolumn field utils', () => {
it('should return single spans value', () => {
const spans = getSpans(1);
expect(spans).toEqual([12]);
});
it('should return 12 spans equally sized', () => {
const spans = getSpans(12);
expect(spans).toEqual([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
});
it('should return spans [3, 3, 2, 2, 2]', () => {
const spans = getSpans(5);
expect(spans).toEqual([3, 3, 2, 2, 2]);
});
it('should return spans [2, 2, 2, 2, 2, 1, 1]', () => {
const spans = getSpans(7);
expect(spans).toEqual([2, 2, 2, 2, 2, 1, 1]);
});
it('should return spans [2, 2, 2, 1, 1, 1, 1, 1, 1]', () => {
const spans = getSpans(9);
expect(spans).toEqual([2, 2, 2, 1, 1, 1, 1, 1, 1]);
});
it('should return spans [4, 4, 4]', () => {
const spans = getSpans(3);
expect(spans).toEqual([4, 4, 4]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as _ from 'lodash';
import { gridItemSpanValueShape } from '@patternfly/react-core';

export const getSpans = (totalFieldCount: number): gridItemSpanValueShape[] => {
const spans: gridItemSpanValueShape[] = _.fill(Array(totalFieldCount), 1);
if (totalFieldCount === 1) {
return [12];
}
if (totalFieldCount === 12) {
return _.fill(Array(12), 1);
}
while (_.sum(spans) !== 12) {
for (let i = 0; i < totalFieldCount; i++) {
spans[i]++;
if (_.sum(spans) === 12) {
break;
}
}
}
return spans;
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const TrafficSplittingModal: React.FC<Props> = ({
headers={['Split', 'Tag', 'Revision']}
emptyValues={{ percent: '', tag: '', revisionName: '' }}
disableDeleteRow={values.trafficSplitting.length === 1}
spans={[2, 3, 7]}
>
<InputField
name="percent"
Expand Down

0 comments on commit 5869b05

Please sign in to comment.