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

Add delete button to vanilla array control #1349

Merged
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
10 changes: 5 additions & 5 deletions packages/material/src/complex/MaterialArrayControlRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,20 @@ export class MaterialArrayControlRenderer extends RendererComponent<ArrayLayoutP
};
}

openDeleteDialog = (path: string, rowData: number) => {
openDeleteDialog = (path: string, rowIndex: number) => {
this.setState({
open: true,
path,
rowData
rowData: rowIndex
});
};
deleteCancel = () => this.setState({open: false});
deleteCancel = () => this.setState({ open: false });
deleteConfirm = () => {
const path = this.state.path.substring(0, this.state.path.lastIndexOf(('.')));
this.props.removeItems(path, [this.state.rowData])();
this.setState({open: false});
this.setState({ open: false });
};
deleteClose = () => this.setState({open: false});
deleteClose = () => this.setState({ open: false });
render() {
const { visible } = this.props;

Expand Down
50 changes: 25 additions & 25 deletions packages/material/src/complex/MaterialTableControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,12 @@ class NonEmptyCellInner extends React.Component<NonEmptyCellProps, any> {
path={path}
/>
) : (
<DispatchCell
schema={schema}
uischema={controlWithoutLabel('#')}
path={path}
/>
)}
<DispatchCell
schema={schema}
uischema={controlWithoutLabel('#')}
path={path}
/>
)}
<FormHelperText error={!isValid}>{!isValid && errors}</FormHelperText>
</NoBorderTableCell>
);
Expand All @@ -201,29 +201,29 @@ const NonEmptyCell = connect(mapStateToNonEmptyCellProps)(NonEmptyCellInner);
interface NonEmptyRowProps {
childPath: string;
schema: JsonSchema;
rowData: number;
rowIndex: number;
}

const NonEmptyRow = React.memo(({
childPath,
schema,
rowData,
rowIndex,
openDeleteDialog
}: NonEmptyRowProps & WithDeleteDialogSupport) => (
<TableRow key={childPath} hover>
{generateCells(NonEmptyCell, schema, childPath)}
<NoBorderTableCell style={styles.fixedCell}>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<IconButton
aria-label={`Delete`}
onClick={() => openDeleteDialog(childPath, rowData)}
>
<DeleteIcon />
</IconButton>
</div>
</NoBorderTableCell>
</TableRow>
));
<TableRow key={childPath} hover>
{generateCells(NonEmptyCell, schema, childPath)}
<NoBorderTableCell style={styles.fixedCell}>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<IconButton
aria-label={`Delete`}
onClick={() => openDeleteDialog(childPath, rowIndex)}
>
<DeleteIcon />
</IconButton>
</div>
</NoBorderTableCell>
</TableRow>
));
interface TableRowsProp {
data: number;
path: string;
Expand Down Expand Up @@ -253,7 +253,7 @@ const TableRows = ({
<NonEmptyRow
key={childPath}
childPath={childPath}
rowData={index}
rowIndex={index}
schema={schema}
openDeleteDialog={openDeleteDialog}
/>
Expand All @@ -264,9 +264,9 @@ const TableRows = ({
};

export class MaterialTableControl extends React.Component<
ArrayLayoutProps & WithDeleteDialogSupport,
ArrayLayoutProps & WithDeleteDialogSupport,
any
> {
> {
addItem = (path: string, value: any) => this.props.addItem(path, value);
render() {
const {
Expand Down
150 changes: 83 additions & 67 deletions packages/vanilla/src/complex/TableArrayControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ export const tableArrayControlTester: RankedTester = rankWith(
or(isObjectArrayControl, isPrimitiveArrayControl)
);

class TableArrayControl extends React.Component<
ArrayControlProps & VanillaRendererProps,
any
> {
class TableArrayControl extends React.Component<ArrayControlProps & VanillaRendererProps, any> {

confirmDelete = (path: string, index: number) => {
const p = path.substring(0, path.lastIndexOf(('.')));
this.props.removeItems(p, [index])();
};

render() {
const {
addItem,
Expand Down Expand Up @@ -124,9 +127,10 @@ class TableArrayControl extends React.Component<
fpmap(prop => <th key={prop}>{startCase(prop)}</th>)
)(schema.properties)
) : (
<th>Items</th>
)}
<th>Items</th>
)}
<th>Valid</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
Expand All @@ -135,72 +139,84 @@ class TableArrayControl extends React.Component<
<td>No data</td>
</tr>
) : (
data.map((_child, index) => {
const childPath = Paths.compose(
path,
`${index}`
);
// TODO
const errorsPerEntry: any[] = filter(childErrors, error =>
error.dataPath.startsWith(childPath)
);
data.map((_child, index) => {
const childPath = Paths.compose(
path,
`${index}`
);
// TODO
const errorsPerEntry: any[] = filter(childErrors, error =>
error.dataPath.startsWith(childPath)
);

return (
<tr key={childPath}>
{schema.properties ? (
fpflow(
fpkeys,
fpfilter(
prop => schema.properties[prop].type !== 'array'
),
fpmap(prop => {
const childPropPath = Paths.compose(
childPath,
prop.toString()
);
return (
<tr key={childPath}>
{schema.properties ? (
fpflow(
fpkeys,
fpfilter(
prop => schema.properties[prop].type !== 'array'
),
fpmap(prop => {
const childPropPath = Paths.compose(
childPath,
prop.toString()
);

return (
<td key={childPropPath}>
<DispatchCell
schema={Resolve.schema(schema, `#/properties/${prop}`, rootSchema)}
uischema={createControlElement(prop)}
path={childPath + '.' + prop}
/>
</td>
);
})
)(schema.properties)
) : (
<td
key={Paths.compose(
childPath,
index.toString()
return (
<td key={childPropPath}>
<DispatchCell
schema={Resolve.schema(schema, `#/properties/${prop}`, rootSchema)}
uischema={createControlElement(prop)}
path={childPath + '.' + prop}
/>
</td>
);
})
)(schema.properties)
) : (
<td
key={Paths.compose(
childPath,
index.toString()
)}
>
<DispatchCell
schema={schema}
uischema={createControlElement()}
path={childPath}
/>
</td>
)}
>
<DispatchCell
schema={schema}
uischema={createControlElement()}
path={childPath}
/>
</td>
)}
<td>
{errorsPerEntry ? (
<span
className={getStyleAsClassName(
'array.validation.error'
<td>
{errorsPerEntry ? (
<span
className={getStyleAsClassName(
'array.validation.error'
)}
>
{join(errorsPerEntry.map(e => e.message), ' and ')}
</span>
) : (
<span>OK</span>
)}
</td>
<td>
<button
aria-label={`Delete`}
onClick={() => {
if (window.confirm('Are you sure you wish to delete this item?')) {
this.confirmDelete(childPath, index);
}
}}
>
{join(errorsPerEntry.map(e => e.message), ' and ')}
</span>
) : (
<span>OK</span>
)}
</td>
</tr>
);
})
)}
Delete
</button>
</td>
</tr>
);
})
)}
</tbody>
</table>
</div>
Expand Down
28 changes: 14 additions & 14 deletions packages/vanilla/test/renderers/TableArrayControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ test('render two children', t => {
t.is(tHead.children.length, 1);
const headRow = tHead.children.item(0);
t.is(headRow.tagName, 'TR');
// two data columns + validation column
t.is(headRow.children.length, 3);
// two data columns + validation column + delete column
t.is(headRow.children.length, 4);

const headColumn1 = headRow.children.item(0);
t.is(headColumn1.tagName, 'TH');
Expand All @@ -125,11 +125,11 @@ test('render two children', t => {
t.is(tBody.children.length, 1);
const bodyRow = tBody.children.item(0);
t.is(bodyRow.tagName, 'TR');
// two data columns + validation column
t.is(bodyRow.children.length, 3);
// two data columns + validation column + delete column
t.is(bodyRow.children.length, 4);

const tds = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'td');
t.is(tds.length, 3);
t.is(tds.length, 4);
t.is(tds[0].children.length, 1);
t.is(tds[0].children[0].id, '');
t.is(tds[1].children.length, 1);
Expand Down Expand Up @@ -176,8 +176,8 @@ test('render empty data', t => {

const headRow = tHead.children.item(0);
t.is(headRow.tagName, 'TR');
// two data columns + validation column
t.is(headRow.children.length, 3);
// two data columns + validation column + delete column
t.is(headRow.children.length, 4);

const headColumn1 = headRow.children.item(0);
t.is(headColumn1.tagName, 'TH');
Expand Down Expand Up @@ -282,8 +282,8 @@ test('render new child', t => {
</Provider>
) as unknown as React.Component<any>;

const button = TestUtils.findRenderedDOMComponentWithTag(tree, 'button') as HTMLButtonElement;
TestUtils.Simulate.click(button);
const addButton = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'button')[0] as HTMLButtonElement;
TestUtils.Simulate.click(addButton);
t.is(getData(store.getState()).test.length, 2);
});

Expand Down Expand Up @@ -341,14 +341,14 @@ test('update via action', t => {
const children = TestUtils.findRenderedDOMComponentWithTag(tree, 'tbody');
t.is(children.childNodes.length, 1);

store.dispatch(update('test', () => [{x: 1, y: 3}, {x: 2, y: 3}]));
store.dispatch(update('test', () => [{ x: 1, y: 3 }, { x: 2, y: 3 }]));
t.is(children.childNodes.length, 2);

store.dispatch(update(undefined, () => [{x: 1, y: 3}, {x: 2, y: 3}, {x: 3, y: 3}]));
store.dispatch(update(undefined, () => [{ x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 3 }]));
t.is(children.childNodes.length, 2);
});

test('tester', t => t.is(tableArrayControlTester({type: 'Foo'}, null), -1));
test('tester', t => t.is(tableArrayControlTester({ type: 'Foo' }, null), -1));

test('tester with recursive document ref only', t => {
const control: ControlElement = {
Expand Down Expand Up @@ -578,7 +578,7 @@ test.skip('validation of nested schema', t => {
type: 'object',
properties: {
middleName: { type: 'string' },
lastName: { type: 'string' }
lastName: { type: 'string' }
},
required: ['middleName', 'lastName']
}
Expand Down Expand Up @@ -611,7 +611,7 @@ test.skip('validation of nested schema', t => {
});
const tree: React.Component<any> = TestUtils.renderIntoDocument(
<Provider store={store}>
<HorizontalLayoutRenderer schema={schema} uischema={uischema}/>
<HorizontalLayoutRenderer schema={schema} uischema={uischema} />
</Provider>
) as unknown as React.Component<any>;
const validation = TestUtils.scryRenderedDOMComponentsWithClass(tree, 'validation');
Expand Down