aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/framework/src/components/material-table
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wt/odlux/framework/src/components/material-table')
-rw-r--r--sdnr/wt/odlux/framework/src/components/material-table/index.tsx44
-rw-r--r--sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx4
-rw-r--r--sdnr/wt/odlux/framework/src/components/material-table/utilities.ts64
3 files changed, 73 insertions, 39 deletions
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/index.tsx b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx
index 7d4633bc6..c74fd1a38 100644
--- a/sdnr/wt/odlux/framework/src/components/material-table/index.tsx
+++ b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx
@@ -32,13 +32,14 @@ import { EnhancedTableHead } from './tableHead';
import { EnhancedTableFilter } from './tableFilter';
import { ColumnModel, ColumnType } from './columnModel';
-import { Omit, Menu } from '@material-ui/core';
+import { Omit, Menu, makeStyles } from '@material-ui/core';
import { SvgIconProps } from '@material-ui/core/SvgIcon/SvgIcon';
import { DividerTypeMap } from '@material-ui/core/Divider';
import { MenuItemProps } from '@material-ui/core/MenuItem';
import { flexbox } from '@material-ui/system';
+import { RowDisabled } from './utilities';
export { ColumnModel, ColumnType } from './columnModel';
type propType = string | number | null | undefined | (string | number)[];
@@ -103,6 +104,34 @@ const styles = (theme: Theme) => createStyles({
}
});
+const useTableRowExtStyles = makeStyles((theme: Theme) => createStyles({
+ disabled: {
+ color: "rgba(180, 180, 180, 0.7)",
+ },
+}));
+
+type GetStatelessComponentProps<T> = T extends (props: infer P & { children?: React.ReactNode }) => any ? P : any;
+type TableRowExtProps = GetStatelessComponentProps<typeof TableRow> & { disabled: boolean };
+const TableRowExt : React.FC<TableRowExtProps> = (props) => {
+ const [disabled, setDisabled] = React.useState(true);
+ const classes = useTableRowExtStyles();
+
+ const onMouseDown = (ev: React.MouseEvent<HTMLElement>) => {
+ if (ev.button ===1){
+ setDisabled(!disabled);
+ ev.preventDefault();
+ ev.stopPropagation();
+ } else if (props.disabled && disabled) {
+ ev.preventDefault();
+ ev.stopPropagation();
+ }
+ };
+
+ return (
+ <TableRow {...{...props, color: props.disabled && disabled ? '#a0a0a0' : undefined , className: props.disabled && disabled ? classes.disabled : '', onMouseDown, onContextMenu: props.disabled && disabled ? onMouseDown : props.onContextMenu } } />
+ );
+};
+
export type MaterialTableComponentState<TData = {}> = {
order: 'asc' | 'desc';
orderBy: string | null;
@@ -130,7 +159,7 @@ type MaterialTableComponentBaseProps<TData> = WithStyles<typeof styles> & {
enableSelection?: boolean;
disableSorting?: boolean;
disableFilter?: boolean;
- customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void }[];
+ customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void, disabled?: boolean }[];
onHandleClick?(event: React.MouseEvent<HTMLTableRowElement>, rowData: TData): void;
createContextMenu?: (row: TData) => React.ReactElement<MenuItemProps | DividerTypeMap<{}, "hr">, React.ComponentType<MenuItemProps | DividerTypeMap<{}, "hr">>>[];
};
@@ -222,12 +251,12 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
<TableBody>
{showFilter && <EnhancedTableFilter columns={columns} filter={filter} onFilterChanged={this.onFilterChanged} enableSelection={this.props.enableSelection} /> || null}
{rows // may need ordering here
- .map((entry: TData & { [key: string]: any }, index) => {
+ .map((entry: TData & { [RowDisabled]?: boolean, [kex: string]: any }, index) => {
const entryId = getId(entry);
const isSelected = this.isSelected(entryId);
const contextMenu = (this.props.createContextMenu && this.state.contextMenuInfo.index === index && this.props.createContextMenu(entry)) || null;
return (
- <TableRow
+ <TableRowExt
hover
onClick={event => {
if (this.props.createContextMenu) {
@@ -252,9 +281,10 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
tabIndex={-1}
key={entryId}
selected={isSelected}
+ disabled={entry[RowDisabled] || false}
>
{this.props.enableSelection
- ? <TableCell padding="checkbox" style={{ width: "50px" }}>
+ ? <TableCell padding="checkbox" style={{ width: "50px", color: entry[RowDisabled] || false ? "inherit" : undefined } }>
<Checkbox checked={isSelected} />
</TableCell>
: null
@@ -264,7 +294,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
col => {
const style = col.width ? { width: col.width } : {};
return (
- <TableCell aria-label={col.title? col.title.toLowerCase().replace(/\s/g, "-") : col.property.toLowerCase().replace(/\s/g, "-")} key={col.property} align={col.type === ColumnType.numeric && !col.align ? "right" : col.align} style={style}>
+ <TableCell style={ entry[RowDisabled] || false ? { ...style, color: "inherit" } : style } aria-label={col.title? col.title.toLowerCase().replace(/\s/g, "-") : col.property.toLowerCase().replace(/\s/g, "-")} key={col.property} align={col.type === ColumnType.numeric && !col.align ? "right" : col.align} >
{col.type === ColumnType.custom && col.customControl
? <col.customControl className={col.className} style={col.style} rowData={entry} />
: col.type === ColumnType.boolean
@@ -280,7 +310,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
anchorPosition={this.state.contextMenuInfo.mouseY != null && this.state.contextMenuInfo.mouseX != null ? { top: this.state.contextMenuInfo.mouseY, left: this.state.contextMenuInfo.mouseX } : undefined}>
{contextMenu}
</Menu> || null}
- </TableRow>
+ </TableRowExt>
);
})}
{emptyRows > 0 && (
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
index 3b2f8e0a8..f7de0a062 100644
--- a/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
+++ b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
@@ -67,7 +67,7 @@ interface ITableToolbarComponentProps extends WithStyles<typeof styles> {
numSelected: number | null;
title?: string;
tableId?: string;
- customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void }[];
+ customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void, disabled?: boolean }[];
onToggleFilter: () => void;
onExportToCsv: () => void;
}
@@ -110,7 +110,7 @@ class TableToolbarComponent extends React.Component<ITableToolbarComponentProps,
{this.props.customActionButtons
? this.props.customActionButtons.map((action, ind) => (
<Tooltip key={`custom-action-${ind}`} title={action.tooltip || ''}>
- <IconButton aria-label={buttonPrefix + `custom-action-${ind}`} onClick={() => action.onClick()}>
+ <IconButton disabled={action.disabled} aria-label={buttonPrefix + `custom-action-${ind}`} onClick={() => action.onClick()}>
<action.icon />
</IconButton>
</Tooltip>
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts
index 07ffe2ff5..544e14e01 100644
--- a/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts
+++ b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts
@@ -21,12 +21,14 @@ import { Dispatch } from '../../flux/store';
import { AddErrorInfoAction } from '../../actions/errorActions';
import { IApplicationStoreState } from '../../store/applicationStore';
+export const RowDisabled = Symbol("RowDisabled");
import { DataCallback } from ".";
+
export interface IExternalTableState<TData> {
order: 'asc' | 'desc';
orderBy: string | null;
selected: any[] | null;
- rows: TData[];
+ rows: (TData & { [RowDisabled]?: boolean })[];
total: number;
page: number;
rowsPerPage: number;
@@ -36,8 +38,31 @@ export interface IExternalTableState<TData> {
preFilter: { [property: string]: string };
}
+export type ExternalMethodes<TData> = {
+ reloadAction: (dispatch: Dispatch, getAppState: () => IApplicationStoreState) => Promise<void | AddErrorInfoAction>;
+ createActions: (dispatch: Dispatch, skipRefresh?: boolean) => {
+ onRefresh: () => void;
+ onHandleRequestSort: (orderBy: string) => void;
+ onHandleExplicitRequestSort: (property: string, sortOrder: "asc" | "desc") => void;
+ onToggleFilter: (refresh?: boolean | undefined) => void;
+ onFilterChanged: (property: string, filterTerm: string) => void;
+ onHandleChangePage: (page: number) => void;
+ onHandleChangeRowsPerPage: (rowsPerPage: number | null) => void;
+ };
+ createPreActions: (dispatch: Dispatch, skipRefresh?: boolean) => {
+ onPreFilterChanged: (preFilter: {
+ [key: string]: string;
+ }) => void;
+ };
+ createProperties: (state: IApplicationStoreState) => IExternalTableState<TData>;
+ actionHandler: IActionHandler<IExternalTableState<TData>, Action>;
+}
+
+
/** Create an actionHandler and actions for external table states. */
-export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>) {
+export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>) : ExternalMethodes<TData> ;
+export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>, disableRow: (data: TData) => boolean) : ExternalMethodes<TData>;
+export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>, disableRow?: (data: TData) => boolean) : ExternalMethodes<TData> {
//#region Actions
abstract class TableAction extends Action { }
@@ -131,7 +156,9 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState
state = {
...state,
loading: false,
- rows: action.result.rows,
+ rows: disableRow
+ ? action.result.rows.map((row: TData) => ({...row, [RowDisabled]: disableRow(row) }))
+ : action.result.rows,
total: action.result.total,
page: action.result.page,
}
@@ -191,7 +218,7 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState
dispatch(new RefreshAction());
const ownState = selectState(getAppState());
const filter = { ...ownState.preFilter, ...(ownState.showFilter && ownState.filter || {}) };
- Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)).then(result => {
+ return Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)).then(result => {
if (ownState.page > 0 && ownState.rowsPerPage * ownState.page > result.total) { //if result is smaller than the currently shown page, new search and repaginate
@@ -207,30 +234,7 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState
}
- }).catch(error => new AddErrorInfoAction(error));
- };
-
- const reloadActionAsync = async (dispatch: Dispatch, getAppState: () => IApplicationStoreState) => {
- dispatch(new RefreshAction());
- const ownState = selectState(getAppState());
- const filter = { ...ownState.preFilter, ...(ownState.showFilter && ownState.filter || {}) };
-
- try {
- const result = await Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter));
-
-
- if (ownState.page > 0 && ownState.rowsPerPage * ownState.page > result.total) { //if result is smaller than the currently shown page, new search and repaginate
-
- let newPage = Math.floor(result.total / ownState.rowsPerPage);
-
- const repaginationResult = await Promise.resolve(callback(newPage, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter));
- dispatch(new SetResultAction(repaginationResult));
- } else {
- dispatch(new SetResultAction(result));
- }
- } catch (error) {
- new AddErrorInfoAction(error);
- }
+ }).catch(error => dispatch(new AddErrorInfoAction(error)));
};
const createPreActions = (dispatch: Dispatch, skipRefresh: boolean = false) => {
@@ -303,6 +307,6 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState
createProperties: createProperties,
createPreActions: createPreActions,
actionHandler: externalTableStateActionHandler,
- reloadActionAsync: reloadActionAsync,
}
-} \ No newline at end of file
+}
+