Skip to content

Commit

Permalink
feat(Table): support inline editing for collapsible rows in PF4
Browse files Browse the repository at this point in the history
  • Loading branch information
suomiy committed Mar 22, 2019
1 parent d548402 commit 931e249
Show file tree
Hide file tree
Showing 30 changed files with 2,737 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const buttonsTopPosition = (window, rowDimensions, bold) => {
const buttonsBottomPosition = (window, rowDimensions, bold) => {
const boldShift = bold ? -1 : 0;
return {
top: rowDimensions.bottom + boldShift,
top: rowDimensions.bottom - 1 + boldShift,
right: window.width - rowDimensions.right + 10
};
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { mount } from 'enzyme/build';

import { default as ConfirmButtons } from './ConfirmButtons';

const getConfirmButtons = () => (
<ConfirmButtons
onCancel={jest.fn()}
onConfirm={jest.fn()}
buttonsOnTop
boldBorder
messages={{
confirmButtonLabel: 'Confirm',
cancelButtonLabel: 'Discard'
}}
environment={{
window: {
width: 500,
height: 500
},
row: {
top: 100,
bottom: 90,
left: 30,
right: 40
}
}}
/>
);

describe('ConfirmButtons', () => {
test('renders correctly', () => {
const view = mount(getConfirmButtons());
expect(view).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import React from 'react';
import { mount } from 'enzyme';
import { Table, TableHeader, TableBody, RowWrapper } from '@patternfly/react-table';
import { TextInput } from '@patternfly/react-core';

import { default as editableRowWrapper } from './editableRowWrapper';
import { default as editableTableBody } from './editableTableBody';
import { inlineEditFormatterFactory } from './utils';
import { TableEditConfirmation } from './constants';
import { TableTextInput } from '../TableTextInput';

import { rows, columns } from '../../test-helpers/data-sets';
import { mockClosest, makeTableId } from '../../test-helpers/helpers';

const firstColTitle = 'editcolfirst';
const lastColTitle = 'editcollast';
const firstInputName = 'inputOne';
const secondInputName = 'inputTwo';

const editRowIndex = 2;

const firstColEditedRowInputId = {
rowIndex: editRowIndex,
columnIndex: 0,
column: {
property: firstColTitle
},
name: firstInputName
};

const lastColEditedRowInputId = {
rowIndex: editRowIndex,
columnIndex: columns.length + 2 - 1,
column: {
property: lastColTitle
},
name: secondInputName
};

describe('Editable table', () => {
let mountOptions;
let container;

beforeEach(() => {
container = mount(<div />);

mountOptions = {
attachTo: container.getDOMNode()
};

// mock closest for selecting the first column (firing onEditCellClicked) and resolving table for confirm buttons
mockClosest(
{
'[data-key]': {
getAttribute: () => firstColEditedRowInputId.columnIndex,
contains: elem => elem.getAttribute('id') === makeTableId(firstColEditedRowInputId)
},
'[id]': {
getAttribute: () => makeTableId(firstColEditedRowInputId)
}
},
selector => (selector === 'table' ? container.getDOMNode().getElementsByTagName('table')[0] : undefined),
true
);
});

afterEach(() => {
container.unmount();
});

test('should call correct function', () => {
const ComposedBody = editableTableBody(TableBody);
const ComposedRowWrapper = editableRowWrapper(RowWrapper);

const onBlur = jest.fn();

const inlineEditingFormatter = inlineEditFormatterFactory({
renderEdit: (value, { columnIndex, rowIndex, column }, { activeEditId }) => {
const firstInputId = makeTableId({
rowIndex,
columnIndex,
column,
name: firstInputName
});
const secondInputId = makeTableId({
rowIndex,
columnIndex,
column,
name: secondInputName
});
return (
<React.Fragment>
<TableTextInput
id={firstInputId}
defaultValue={value}
onBlur={onBlur}
autoFocus={activeEditId === firstInputId}
/>
<TableTextInput
id={secondInputId}
defaultValue={value}
onBlur={onBlur}
autoFocus={activeEditId === secondInputId}
/>
</React.Fragment>
);
}
});

const editableCols = [
{
title: firstColTitle,
cellFormatters: [inlineEditingFormatter]
},
...columns,
{
title: lastColTitle,
cellFormatters: [inlineEditingFormatter]
}
];

const editableRows = rows.map(row => ({
...row,
cells: ['', ...row.cells, ''] // add two new columns
}));
editableRows[editRowIndex].isEditing = true;

const editConfig = {
activeEditId: makeTableId(lastColEditedRowInputId),
onEditCellClicked: jest.fn(),
editConfirmationType: TableEditConfirmation.ROW,
onEditConfirmed: jest.fn(),
onEditCanceled: jest.fn()
};
const view = mount(
<Table caption="Editable table" cells={editableCols} rows={editableRows} rowWrapper={ComposedRowWrapper}>
<TableHeader />
<ComposedBody editConfig={editConfig} />
</Table>,
mountOptions
);

// calls onBlur properly
const editTextInputWrapper = view
.find(TextInput)
.find(`#${makeTableId(lastColEditedRowInputId)}`)
.first();
editTextInputWrapper.prop('onBlur')({ currentTarget: { value: 'water' } });

expect(onBlur).toHaveBeenCalled();
expect(onBlur.mock.calls).toHaveLength(1);
expect(onBlur.mock.calls[0][0]).toBe('water');

// responds to cell click
view
.find(`#${makeTableId(firstColEditedRowInputId)}`)
.hostNodes()
.simulate('mousedown');

// should immediately call onEditCellClicked
setTimeout(() => expect(editConfig.onEditCellClicked).toHaveBeenCalled(), 0);

// responds to confirmation button clicks
view.find('.pf-c-table__inline-edit-buttons button.pf-c-button.pf-m-primary').simulate('mouseup');
expect(editConfig.onEditConfirmed).toHaveBeenCalled();

view.find('.pf-c-table__inline-edit-buttons button.pf-c-button.pf-m-plain').simulate('mouseup');
expect(editConfig.onEditCanceled).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import EditableTable from './examples/EditableTable';
import EditableTableColumn from './examples/EditableTableColumn';
import CollapsibleEditableTable from './examples/CollapsibleEditableTable';

export default {
title: 'Inline Editing Table',
title: 'Inline Edit Table',
components: {},
examples: [
{ component: EditableTable, title: 'Editable table With Inline Edit Row' },
{ component: EditableTableColumn, title: 'Editable Table With Inline Edit Columns' }
{ component: EditableTableColumn, title: 'Editable Table With Inline Edit Columns' },
{ component: CollapsibleEditableTable, title: 'Editable Table With Collapsible Rows' }
]
};
Loading

0 comments on commit 931e249

Please sign in to comment.