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

GH-14 BaseTable selection sometimes did not indicated properly #24

Merged
merged 9 commits into from
Sep 29, 2021
1 change: 1 addition & 0 deletions src/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export interface RenderProps extends FormsDispatchProps {

id: string;
schema: JsonSchema7;
readOnly?: boolean;
}
export interface RenderCellProps extends RenderProps {
data: any;
Expand Down
3 changes: 2 additions & 1 deletion src/controls/AntdInputControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const AntdInputControl: React.FC<ControlComponent & WithInput> = (props)
const InnerComponent = input;

const formatterId = uiOptions.formatter || 'base';
const readOnly = uiOptions.readOnly;
const query = uiOptions.query;
const specialProps: any = {};
if (uiOptions.dataToFormatter) {
Expand All @@ -61,7 +62,7 @@ export const AntdInputControl: React.FC<ControlComponent & WithInput> = (props)
}
validateStatus={validateObj.validateStatus}
help={validateObj.help}>
{editing ? (
{editing && !readOnly ? (
<InnerComponent
{...props}
onValidation={onValidation}
Expand Down
4 changes: 3 additions & 1 deletion src/layouts/AntdFormLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,13 @@ export const AntdFormLayout: React.FC<any> = ({
onEdit,
editing,
}) => {
const { readOnly } = viewKindElement.options;
return (
<AutoSizer>
{({ width, height }: any) => (
<div style={{ width, height, overflow: 'auto' }} onClick={() => onEdit()}>
<span style={{ padding: '7px', fontSize: '2em' }}>{title}</span>
<LogicalButton form={id} onSave={onSave} onCancel={onCancel} />
{readOnly ? null : <LogicalButton form={id} onSave={onSave} onCancel={onCancel} />}
<Form labelAlign={'left'}>
<AntdVerticalLayoutWithStore
id={`${id}Layout`}
Expand All @@ -94,6 +95,7 @@ export const AntdFormLayout: React.FC<any> = ({
schema={{}}
enabled={enabled}
form={id}
readOnly={readOnly}
/>
</Form>
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/layouts/AntdVerticalLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const AntdVerticalLayoutRenderer: React.FC<LayoutComponent> = ({
enabled,
visible,
form,
readOnly,
}) => {
const Render: React.FC<FormsDispatchProps & Idx> = ({ idx, viewKind, viewKindElement, viewDescr, enabled }) => {
const options = viewKindElement.options || {};
Expand All @@ -51,7 +52,7 @@ export const AntdVerticalLayoutRenderer: React.FC<LayoutComponent> = ({
return (
<React.Fragment>
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
{renderLayoutElements({ viewKind, viewKindElement, viewDescr, enabled, Render })}
{renderLayoutElements({ viewKind, viewKindElement, viewDescr, enabled, Render, readOnly })}
</div>
</React.Fragment>
);
Expand Down
1 change: 1 addition & 0 deletions src/table/BaseTableControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export const BaseTableControl: React.FC<JsonSchemaTableProps> = React.memo(
dataSource={dataSource}
loadExpandedData={loadExpandedData}
tableMenu={tableMenu}
multiSelect={uiSchemaOptions['multiSelect']}
isMenu={uiSchemaOptions['columnMenu']}
parsedSchema={parsedSchema}
onSelect={onSelect}
Expand Down
2 changes: 1 addition & 1 deletion src/table/basetable/BaseTable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ $table-prefix: BaseTable !default;
$border: 1px solid #eeeeee !default;
$header-background-color: #f8f8f8 !default;
$header-font-weight: 700 !default;
$row-hovered-background-color: #ffffff !default;
$row-hovered-background-color: #f3f3f3 !default;
$header-cell-hovered-background-color: #f3f3f3 !default;
$sort-indicator-hovered-color: #888888 !default;
$column-resizer-color: #cccccc !default;
Expand Down
66 changes: 38 additions & 28 deletions src/table/basetable/ReactBaseTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ export const EditableTable: React.FC<EditableTableProps<any>> = React.memo(
options = {},
addDataToTarget,
onSelect,
multiSelect,
...props
}) => {
const [data, setData] = useState<any[]>([]);
const [popupVisible, setPopupVisible] = useState<boolean>(false);
const [popupCoords, setPopupCoords] = useState<{ x: number; y: number }>({ x: 0, y: 0 });
const [popupRecord, setPopupRecord] = useState<any>({});
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([]);
const sortColumns = createSortColumnsObject(sortDir);
const [loadingMore, setLoadingMore] = useState(false);
Expand All @@ -135,30 +135,42 @@ export const EditableTable: React.FC<EditableTableProps<any>> = React.memo(
),
headerRenderer: ({ columns, column, columnIndex, headerIndex, container }: any) => <Test />,
};
const onAddDataToTarget = (data: any) => {
setSelection([]);
addDataToTarget(data);
};

const handleSelectChange = ({ selected, rowData, rowIndex }: any) => {
const newSelectedRowKeys = [...selectedRowKeys];
const key = rowData[rowKey];

if (selected) {
if (!newSelectedRowKeys.includes(key)) newSelectedRowKeys.push(key);
let newSelection = [...selection];
const index = newSelection.indexOf(rowData);
if (multiSelect) {
if (selected) {
if (index === -1) newSelection.push(rowData);
} else {
if (index !== -1) {
newSelection.splice(index, 1);
}
}
} else {
const index = newSelectedRowKeys.indexOf(key);
if (index > -1) {
newSelectedRowKeys.splice(index, 1);
if (selected) {
newSelection = [rowData];
} else {
if (index !== -1) {
newSelection = [];
}
}
}
setSelectedRowKeys(newSelectedRowKeys);
setSelection(newSelection);
};

const handleSelectHeaderChange = ({ selected }: any) => {
let newSelectedRowKeys;
const handleSelectHeaderChange = ({ selected, data }: any) => {
let newSelection;
if (selected) {
newSelectedRowKeys = dataSource.map((e: any) => e[rowKey]);
newSelection = data;
} else {
newSelectedRowKeys = [];
newSelection = [];
}
setSelectedRowKeys(newSelectedRowKeys);
setSelection(newSelection);
};
const selectionColumn = {
key: '__selection__',
Expand All @@ -171,7 +183,8 @@ export const EditableTable: React.FC<EditableTableProps<any>> = React.memo(
cellRenderer: SelectionCell,
headerRenderer: SelectionHeaderCell,
dataSize: dataSource.length,
selectedRowKeys: selectedRowKeys,
multiSelect,
selection,
onChange: handleSelectChange,
onHeaderChange: handleSelectHeaderChange,
};
Expand Down Expand Up @@ -224,17 +237,9 @@ export const EditableTable: React.FC<EditableTableProps<any>> = React.memo(
setPopupRecord(rowData);
setPopupCoords({ x: event.clientX, y: event.clientY });
},
onClick: ({ rowData, event }: any) => {
onClick: ({ rowData, event, ...props }: any) => {
const idx = selection.indexOf(rowData);
let newSelection = [...selection];
if (idx !== -1) {
if (newSelection.length === 1) newSelection = [];
else newSelection.splice(idx, 1);
} else {
newSelection.push(rowData);
}
setSelection(newSelection);
onSelect(newSelection);
handleSelectChange({ selected: idx === -1, rowData, rowIndex: null });
},
};

Expand Down Expand Up @@ -313,6 +318,11 @@ export const EditableTable: React.FC<EditableTableProps<any>> = React.memo(
});
}*/
};

const rowClassName = ({ rowData, rowIndex }: any): string => {
return selection.includes(rowData) ? 'row-selected' : '';
};

const renderOverlay = () => {
if (loadingMore)
return (
Expand All @@ -333,7 +343,6 @@ export const EditableTable: React.FC<EditableTableProps<any>> = React.memo(
setData(newData);
};
useEffect(() => {
setSelectedRowKeys([]);
setExpandedRowKeys([]);
setSelection([]);
onSelect([]);
Expand All @@ -359,6 +368,7 @@ export const EditableTable: React.FC<EditableTableProps<any>> = React.memo(
fixed
useIsScrolling
rowRenderer={rowRenderer}
rowClassName={rowClassName}
width={width}
height={height}
sortColumns={sortColumns}
Expand Down Expand Up @@ -396,7 +406,7 @@ export const EditableTable: React.FC<EditableTableProps<any>> = React.memo(
visible={popupVisible}
onCreateArtifactBefore={() => {}}
target={target}
addDataToTarget={addDataToTarget}
addDataToTarget={onAddDataToTarget}
onCreateArtifactAfter={() => {}}
onDeleteArtifacts={() => {
onDeleteRows(selection);
Expand Down
12 changes: 8 additions & 4 deletions src/table/basetable/TableCellsAndRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import isEqual from 'lodash-es/isEqual';
import React from 'react';
import styled from 'styled-components';
import { Checkbox } from 'antd';
import { Checkbox, Radio } from 'antd';
import { SortableElement } from 'react-sortable-hoc';

const DraggableElement = SortableElement(({ children }: any) => children);
Expand Down Expand Up @@ -42,11 +42,15 @@ export const rowProps = ({ rowData, ...rest }: any) => ({

export const SelectionCell: React.FC<any> = (props: any) => {
const { rowData, rowIndex, column } = props;
const { rowKey, onChange, selectedRowKeys } = column;
const checked = rowData ? selectedRowKeys.includes(rowData[rowKey]) : false;
const { onChange, selection, multiSelect } = column;
const checked = rowData ? selection.includes(rowData) : false;
const handleChange = (e: any) => onChange({ selected: e.target.checked, rowData, rowIndex });

return <Checkbox checked={checked} onChange={handleChange} />;
return multiSelect ? (
<Checkbox checked={checked} onChange={handleChange} />
) : (
<Radio checked={checked} onChange={handleChange} />
);
};

export const Handle = styled.div`
Expand Down
10 changes: 5 additions & 5 deletions src/table/basetable/TableHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import { Checkbox } from 'antd';
import './TableHeader.css';

export const SelectionHeaderCell: React.FC<any> = (props: any) => {
const { column } = props;
const { dataSize, onHeaderChange, selectedRowKeys } = column;
const checked = selectedRowKeys.length === dataSize && dataSize !== 0;
const handleChange = (e: any) => onHeaderChange({ selected: e.target.checked });
const { column, container } = props;
const { dataSize, onHeaderChange, selection, multiSelect } = column;
const checked = selection.length === dataSize && dataSize !== 0;
const handleChange = (e: any) => onHeaderChange({ selected: e.target.checked, data: container._data });

return <Checkbox checked={checked} onChange={handleChange} />;
return multiSelect ? <Checkbox checked={checked} onChange={handleChange} /> : null;
};

export const HeaderCell = ({ column, onSort, container }: any): JSX.Element => {
Expand Down
3 changes: 3 additions & 0 deletions src/table/basetable/table.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@
.handler:hover {
color: #1890ff;
}
.row-selected {
background-color: #e6f7ff;
}
47 changes: 25 additions & 22 deletions src/util/ContextToProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -534,28 +534,31 @@ export const withStoreToArrayProps = (Component: React.FC<any>): React.FC<any> =
});

export const withLayoutProps = (Component: React.FC<LayoutComponent>): React.FC<RenderProps> =>
observer<RenderProps>(({ viewKind, viewKindElement, viewDescr, viewDescrElement, schema, enabled, form }) => {
const id = viewKindElement['@id'] || '';
const enabledLayout = enabled && checkProperty('editable', id, viewKindElement, viewKind);
const visible = checkProperty('visible', id, viewKindElement, viewKind);
const { store } = useContext(MstContext);
if (viewKindElement.options && viewKindElement.options.connections) {
viewKindElement.options.connections.forEach((e: any) => store.setSaveLogic(e.from, e.to));
}
return (
<Component
viewKind={viewKind}
viewKindElement={viewKindElement}
viewDescr={viewDescr}
viewDescrElement={viewDescrElement}
id={id}
schema={schema}
enabled={enabledLayout}
visible={visible}
form={form}
/>
);
});
observer<RenderProps>(
({ viewKind, viewKindElement, viewDescr, viewDescrElement, schema, enabled, form, readOnly }) => {
const id = viewKindElement['@id'] || '';
const enabledLayout = enabled && checkProperty('editable', id, viewKindElement, viewKind);
const visible = checkProperty('visible', id, viewKindElement, viewKind);
const { store } = useContext(MstContext);
if (viewKindElement.options && viewKindElement.options.connections) {
viewKindElement.options.connections.forEach((e: any) => store.setSaveLogic(e.from, e.to));
}
return (
<Component
viewKind={viewKind}
viewKindElement={viewKindElement}
viewDescr={viewDescr}
viewDescrElement={viewDescrElement}
id={id}
schema={schema}
enabled={enabledLayout}
visible={visible}
form={form}
readOnly={readOnly}
/>
);
},
);

export const withStoreToSaveButtonProps = (Component: React.FC<ButtonComponent>): React.FC<RenderProps> =>
observer<RenderProps>(({ viewKindElement, enabled }) => {
Expand Down
11 changes: 8 additions & 3 deletions src/util/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export declare type Idx = {
export interface RenderLayoutProps extends FormsDispatchProps {
viewKindElement: IViewKindElement;
Render: React.FC<FormsDispatchProps & Idx>;
readOnly?: boolean;
}

export const renderLayoutElements = ({
Expand All @@ -27,12 +28,16 @@ export const renderLayoutElements = ({
viewDescr,
enabled,
Render,
readOnly,
}: RenderLayoutProps): JSX.Element | JSX.Element[] => {
const elements = viewKindElement.elements;
//const id = viewKind['@id'];
//const sort = id ? viewKind.properties && viewKind.properties[id] && viewKind.properties[id].order : undefined;
if (!elements || elements.length === 0) return <></>;
return elements.map((el: IViewKindElement, idx: number) => (
<Render key={idx} idx={idx} viewKind={viewKind} viewKindElement={el} viewDescr={viewDescr} enabled={enabled} />
));
return elements.map((el: IViewKindElement, idx: number) => {
el = { ...el, options: { ...el.options, readOnly } };
return (
<Render key={idx} idx={idx} viewKind={viewKind} viewKindElement={el} viewDescr={viewDescr} enabled={enabled} />
);
});
};
Loading