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

feat(AnalyticalTable): Add onRowExpandChange prop and placeholder loading #207

Merged
merged 11 commits into from
Oct 28, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,7 @@ const styles = ({ parameters }: JSSTheme) => ({
}
},

propRowHeight: {
'&$tableContainer': {
height: (props) => `calc(100% - ${props.rowHeight}px)`
},
'& $tableHeaderRow': {
height: (theme) => (theme.contentDensity === 'Compact' ? '2rem' : '2.75rem')
},
'& $th': {
height: (theme) => (theme.contentDensity === 'Compact' ? '2rem' : '2.75rem')
},
modifiedRowHeight: {
'& $tableCell': {
height: (props) => `${props.rowHeight}px`
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Icon } from '@ui5/webcomponents-react/lib/Icon';
import React, { CSSProperties, FC, ReactNode, ReactNodeArray, useMemo } from 'react';
import { createUseStyles } from 'react-jss';
import { JSSTheme } from '../../../interfaces/JSSTheme';
import { Resizer } from '../Resizer';
import { Resizer } from './Resizer';
import { ColumnType } from '../types/ColumnType';
import { ColumnHeaderModal } from './ColumnHeaderModal';
import '@ui5/webcomponents/dist/icons/filter';
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { VerticalAlign } from '@ui5/webcomponents-react/lib/VerticalAlign';
import { DefaultFilterComponent } from '../FilterComponent';
import { Column } from 'react-table';

export const DEFAULT_COLUMN_WIDTH = 60;

const defaultFilterMethod = (filter, row) => {
return new RegExp(filter.value, 'gi').test(String(row[filter.id]));
};

export const DefaultColumn: Column = {
Filter: DefaultFilterComponent,
canResize: true,
minWidth: DEFAULT_COLUMN_WIDTH,
// @ts-ignore
width: '1fr',
vAlign: VerticalAlign.Middle,
Aggregated: () => null,
defaultFilter: defaultFilterMethod
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { CSSProperties, FC, useMemo } from 'react';
import ContentLoader from 'react-content-loader';
import { useTheme } from 'react-jss';
import { JSSTheme } from '../../../../interfaces/JSSTheme';

const getArrayOfLength = (len) => Array.from(Array(len).keys());

const TableRow: FC<{ columns: number; y: number; row: number }> = ({ columns, y, row }) => {
let columnOffset = 0;
return (
<>
{getArrayOfLength(columns).map((val, i) => {
const el = (
<rect key={`row-${row}-column-${i}`} x={columnOffset + 2} y={y} rx="2" ry="8" width="61" height="16" />
);
columnOffset += 65;
return el;
})}
</>
);
};

export const TablePlaceholder: FC<{ columns: number; rows: number; style: CSSProperties; rowHeight: number }> = (
props
) => {
const { columns, rows, style, rowHeight } = props;

const { parameters } = useTheme() as JSSTheme;

const height = rows * rowHeight;
const width = columns * 65;

const innerStyles = useMemo(() => {
return {
backgroundColor: parameters.sapUiListBackground,
width: '100%',
...style
};
}, [style, parameters.sapUiListBackground]);

return (
<ContentLoader
style={innerStyles}
height={height}
width={width}
speed={2}
primaryColor={parameters.sapUiContentImagePlaceholderBackground}
secondaryColor={parameters.sapUiFieldPlaceholderTextColor}
primaryOpacity={(parameters.sapUiContentDisabledOpacity as undefined) as number}
>
{getArrayOfLength(rows).map((_, index) => (
<TableRow key={index} columns={columns} y={rowHeight * index + rowHeight / 2} row={index} />
))}
</ContentLoader>
);
};

TablePlaceholder.defaultProps = {
rows: 5,
columns: 3
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Loader } from '@ui5/webcomponents-react/lib/Loader';
import { ContentDensity } from '@ui5/webcomponents-react/lib/ContentDensity';
import React, { CSSProperties, useMemo } from 'react';
import { useTheme } from 'react-jss';
import { JSSTheme } from '../../../../interfaces/JSSTheme';

const DefaultLoadingComponent = () => {
const { contentDensity } = useTheme() as JSSTheme;

const styles: CSSProperties = useMemo(() => {
return {
position: 'absolute',
top: contentDensity === ContentDensity.Compact ? '2rem' : '2.75rem',
left: 0,
right: 0,
zIndex: 1
};
}, [contentDensity]);

return <Loader delay={500} style={styles} />;
};

DefaultLoadingComponent.displayName = 'DefaultLoadingComponent';

export { DefaultLoadingComponent };
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';

// const style = {
MarcusNotheis marked this conversation as resolved.
Show resolved Hide resolved
// width: '100%',
// position: 'absolute',
// textAlign: 'center',
// marginTop: '1rem'
// };

export const DefaultNoDataComponent = ({ noDataText, className, style }) => {
return (
<div className={className} style={style}>
{noDataText}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AnalyticalTable } from '@ui5/webcomponents-react/lib/AnalyticalTable';
import { Button } from '@ui5/webcomponents-react/lib/Button';
import { TextAlign } from '@ui5/webcomponents-react/lib/TextAlign';
import { Title } from '@ui5/webcomponents-react/lib/Title';
import React from 'react';
import React, { useState, useEffect } from 'react';
MarcusNotheis marked this conversation as resolved.
Show resolved Hide resolved
import generateData from './generateData';

const columns = [
Expand Down Expand Up @@ -65,13 +65,14 @@ export const defaultTable = () => {
busyIndicatorEnabled={boolean('busyIndicatorEnabled', true)}
sortable={boolean('sortable', true)}
filterable={boolean('filterable', true)}
visibleRows={number('visibleRows', 15)}
visibleRows={number('visibleRows', 5)}
minRows={number('minRows', 5)}
groupable={boolean('groupable', true)}
selectable={boolean('selectable', true)}
onRowSelected={action('onRowSelected')}
onSort={action('onSort')}
onGroup={action('onGroup')}
onRowExpandChange={action('onRowExpandChange')}
groupBy={array('groupBy', [])}
rowHeight={number('rowHeight', 60)}
selectedRowKey={text('selectedRowKey', `row_5`)}
Expand Down Expand Up @@ -99,6 +100,7 @@ export const treeTable = () => {
selectable={boolean('selectable', true)}
onRowSelected={action('onRowSelected')}
onSort={action('onSort')}
onRowExpandChange={action('onRowExpandChange')}
subRowsKey={text('subRowsKey', 'subRows')}
selectedRowKey={text('selectedRowKey', `row_5`)}
isTreeTable={boolean('isTreeTable', true)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { TextAlign } from '@ui5/webcomponents-react/lib/TextAlign';
import { VerticalAlign } from '@ui5/webcomponents-react/lib/VerticalAlign';
import { CSSProperties } from 'react';

export const useCellStyling = ({ cellHeight }, classes) => ({ column }) => {
export const useCellStyling = ({ rowHeight }, classes) => ({ column }) => {
const style: CSSProperties = {};

if (cellHeight) {
style.height = cellHeight;
if (rowHeight) {
style.height = `${rowHeight}px`;
}
switch (column.hAlign) {
case TextAlign.Begin:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
import { useCallback, useState, useRef } from 'react';
import { useCallback, useState, useRef, useEffect } from 'react';

const comparePaths = (path1, path2) => {
return path1.length === path2.length && path1.every((item, i) => item === path2[i]);
Expand Down Expand Up @@ -36,5 +36,9 @@ export const useRowSelection = (onRowSelected, selectedRowKeyProp) => {
},
[selectedRowPath, setSelectedRowPath, selectedRowKeyProp, prevSelectedRowKeyProp.current]
);
useEffect(() => {
MarcusNotheis marked this conversation as resolved.
Show resolved Hide resolved
prevSelectedRowKeyProp.current = selectedRowKeyProp;
setSelectedRowPath(selectedRowPath);
}, [selectedRowKeyProp]);
return [selectedRowPath, onRowClicked];
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useCellStyling } from './useCellStyling';
import { useCallback } from 'react';

export const useTableCellStyling = (classes, cellHeight) =>
export const useTableCellStyling = (classes, rowHeight) =>
useCallback(
(instance) => {
instance.getCellProps.push(useCellStyling({ cellHeight }, classes));
instance.getCellProps.push(useCellStyling({ rowHeight }, classes));
return instance;
},
[cellHeight, classes]
[rowHeight, classes]
);
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useMemo, useRef } from 'react';

export const useTableRowStyling = (classes, resizedColumns, selectable, selectedRow, selectedRowKey) => {
export const useTableRowStyling = (classes, resizedColumns, selectable, selectedRow, selectedRowKey, onRowClicked) => {
const prevSelectedRow = useRef(null);
const prevSelectedRowKey = useRef(null);

Expand Down Expand Up @@ -46,11 +46,21 @@ export const useTableRowStyling = (classes, resizedColumns, selectable, selected
className += ` ${classes.selectedRow}`;
}
return {
className
className,
onClick: onRowClicked(row)
};
});
return instance;
},
[classes.tr, classes.tableGroupHeader, classes.selectedRow, resizedColumns, selectable, selectedRow, selectedRowKey]
[
classes.tr,
classes.tableGroupHeader,
classes.selectedRow,
resizedColumns,
selectable,
selectedRow,
selectedRowKey,
onRowClicked
]
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ export const useTableStyling = (classes) =>
},
[classes.table]
);

useTableStyling.pluginName = 'useTableStyling';
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
import { useCallback } from 'react';

export const useToggleRowExpand = (onRowExpandChange, isTreeTable) => {
return useCallback(
(instance) => {
instance.getExpandedToggleProps.push((row) => {
return {
onClick: (e) => {
e.stopPropagation();
e.persist();
row.toggleExpanded();
let column = null;
if (!isTreeTable) {
column = row.cells.find((cell) => cell.column.id === row.groupByID).column;
}

onRowExpandChange(Event.of(null, e, { row, column }));
}
};
});
},
[onRowExpandChange, isTreeTable]
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { Device } from '@ui5/webcomponents-react-base/lib/Device';

export const useWindowResize = () => {
const headerRef = useRef(null);
const [tableWidth, setTableWidth] = useState(0);
const onWindowResize = useCallback(() => {
if (headerRef.current) {
setTableWidth(headerRef.current.scrollWidth);
}
}, [setTableWidth, headerRef.current]);

const observer = useRef(new MutationObserver(onWindowResize));

useEffect(() => {
Device.resize.attachHandler(onWindowResize, null);
return () => {
Device.resize.detachHandler(onWindowResize, null);
};
}, [onWindowResize]);

useEffect(() => {
if (headerRef.current) {
observer.current.observe(headerRef.current, {
attributes: true,
subtree: true,
childList: true
});
}

return () => {
observer.current.disconnect();
};
}, [headerRef.current, observer.current]);

return [headerRef, tableWidth];
};
Loading