Skip to content

Commit

Permalink
Honor property titles in Table renderers
Browse files Browse the repository at this point in the history
We now check for property titles when rendering table
headers in React Material and Vanilla renderers.

Includes testcases.
  • Loading branch information
sarahtrefethen committed Oct 29, 2020
1 parent 8a3a800 commit 08c6b93
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 4 deletions.
7 changes: 4 additions & 3 deletions packages/material/src/complex/MaterialTableControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const generateCells = (
const props = {
propName: prop,
schema,
title: schema.properties?.[prop]?.title ?? startCase(prop),
rowPath,
cellPath,
enabled,
Expand Down Expand Up @@ -138,11 +139,11 @@ const EmptyTable = ({ numColumns }: EmptyTableProps) => (
);

interface TableHeaderCellProps {
propName: string;
title: string;
}

const TableHeaderCell = React.memo(({ propName }: TableHeaderCellProps) => (
<TableCell>{startCase(propName)}</TableCell>
const TableHeaderCell = React.memo(({ title }: TableHeaderCellProps) => (
<TableCell>{title}</TableCell>
));

interface NonEmptyCellProps extends OwnPropsOfNonEmptyCell {
Expand Down
49 changes: 49 additions & 0 deletions packages/material/test/renderers/MaterialArrayControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,55 @@ describe('Material array control', () => {
expect(headerColumns).toHaveLength(2);
});

it('should use title as a header if it exists', () => {
const store = initJsonFormsStore();
// re-init
const data: any = { test: [] };
const schema: JsonSchema = {
type: 'object',
properties: {
test: {
type: 'array',
items: {
type: 'object',
properties: {
test1: {
type: 'string',
title: 'first test'
},
test_2: {
type: 'string',
}
}
}
}
}
};
const uischema: ControlElement = {
type: 'Control',
scope: '#/properties/test'
};
store.dispatch(Actions.init(data, schema, uischema));

wrapper = mount(
<Provider store={store}>
<JsonFormsReduxContext>
<MaterialArrayControlRenderer schema={schema} uischema={uischema} />
</JsonFormsReduxContext>
</Provider>
);

//column headings are in the second row of the table, wrapped in <th>
const headers = wrapper.find('tr').at(1).find('th');

// the first property has a title, so we expect it to be rendered as the first column heading
expect(headers.at(0).text()).toEqual("first test");

// the second property has no title, so we expect to see the property name in start case
expect(headers.at(1).text()).toEqual("Test 2");

});

it('should render empty primitives', () => {
const store = initJsonFormsStore();
// re-init
Expand Down
2 changes: 1 addition & 1 deletion packages/vanilla/src/complex/TableArrayControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class TableArrayControl extends React.Component<ArrayControlProps & VanillaRende
fpflow(
fpkeys,
fpfilter(prop => schema.properties[prop].type !== 'array'),
fpmap(prop => <th key={prop}>{fpstartCase(prop)}</th>)
fpmap(prop => <th key={prop}>{schema.properties[prop].title ?? fpstartCase(prop)}</th>)
)(schema.properties)
) : (
<th>Items</th>
Expand Down
64 changes: 64 additions & 0 deletions packages/vanilla/test/renderers/TableArrayControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,40 @@ const fixture = {
]
};

const fixture2 = {
schema: {
type: 'object',
properties: {
test: {
type: 'array',
items: {
type: 'object',
properties: {
x: {
type: 'integer',
title: 'Column X',
},
y: { type: 'integer' }
}
}
}
}
},
uischema: {
type: 'Control',
scope: '#/properties/test'
},
data: {
test: [{ x: 1, y: 3 }]
},
styles: [
{
name: 'array.table',
classNames: ['array-table-layout', 'control']
}
]
};

describe('Tabe array tester', () => {
test('tester with recursive document ref only', () => {
const control: ControlElement = {
Expand Down Expand Up @@ -311,6 +345,36 @@ describe('Tabe array control', () => {
expect(noDataColumn.textContent).toBe('No data');
});

test('use property title as a column header if it exists', () => {
const store = initJsonFormsVanillaStore({
data: fixture2.data,
schema: fixture2.schema,
uischema: fixture2.uischema,
cells: [
{ tester: integerCellTester, cell: IntegerCell }
]
});
wrapper = mount(
<Provider store={store}>
<JsonFormsReduxContext>
<TableArrayControl
schema={fixture2.schema}
uischema={fixture2.uischema}
/>
</JsonFormsReduxContext>
</Provider>
);

//column headings are wrapped in a <thead> tag
const headers = wrapper.find('thead').find('th');

// the first property has a title, so we expect it to be rendered as the first column heading
expect(headers.at(0).text()).toEqual("Column X");

// the second property has no title, so we expect to see the property name in start case
expect(headers.at(1).text()).toEqual("Y");
});

test('render new child (empty init data)', () => {
const store = initJsonFormsVanillaStore({
data: { test: [] },
Expand Down

0 comments on commit 08c6b93

Please sign in to comment.