diff options
author | Michael Dürre <michael.duerre@highstreet-technologies.com> | 2022-09-08 09:45:06 +0200 |
---|---|---|
committer | Michael Dürre <michael.duerre@highstreet-technologies.com> | 2022-09-08 09:46:47 +0200 |
commit | a2b6dd34d73bf432846dc59c6f57dd59a03aff9b (patch) | |
tree | 35658e382769bc7575f87d0e9580d6ee98230eb2 /sdnr/wt/odlux/framework/src/components | |
parent | 6f9c3d2cea04a2af7a73d8df1de87d584b277552 (diff) |
update odlux sources
update basic odlux functionality for kohn
Issue-ID: CCSDK-3765
Signed-off-by: Michael Dürre <michael.duerre@highstreet-technologies.com>
Change-Id: I3723c9c2f35b9012ba537920b294a54bb556cbc6
Signed-off-by: Michael Dürre <michael.duerre@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wt/odlux/framework/src/components')
9 files changed, 330 insertions, 26 deletions
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts b/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts index ce5b2cd1e..3ed313497 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts +++ b/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts @@ -37,6 +37,7 @@ export type ColumnModel<TData> = { disablePadding?: boolean; width?: string | number ; className?: string; + hide?: boolean; style?: React.CSSProperties; align?: 'inherit' | 'left' | 'center' | 'right' | 'justify'; disableSorting?: boolean; 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 aac2a1252..8541cfe56 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/index.tsx +++ b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx @@ -36,7 +36,7 @@ import { EnhancedTableHead } from './tableHead'; import { EnhancedTableFilter } from './tableFilter'; import { ColumnModel, ColumnType } from './columnModel'; -import { Menu } from '@mui/material'; +import { Menu, Typography } from '@mui/material'; import { DistributiveOmit } from '@mui/types'; import makeStyles from '@mui/styles/makeStyles'; @@ -151,19 +151,23 @@ export type MaterialTableComponentState<TData = {}> = { rowsPerPage: number; loading: boolean; showFilter: boolean; + hiddenColumns: string[]; filter: { [property: string]: string }; }; export type TableApi = { forceRefresh?: () => Promise<void> }; -type MaterialTableComponentBaseProps<TData> = WithStyles<typeof styles> & { +type MaterialTableComponentBaseProps<TData> = WithStyles<typeof styles> & { className?: string; columns: ColumnModel<TData>[]; idProperty: keyof TData | ((data: TData) => React.Key); - tableId?: string; + + //Note: used to save settings as well. Must be unique across apps. Null tableIds will not get saved to the settings + tableId: string | null; isPopup?: boolean; title?: string; stickyHeader?: boolean; + allowHtmlHeader?: boolean; defaultSortOrder?: 'asc' | 'desc'; defaultSortColumn?: keyof TData; enableSelection?: boolean; @@ -182,6 +186,8 @@ type MaterialTableComponentPropsWithExternalState<TData = {}> = MaterialTableCom onHandleChangePage: (page: number) => void; onHandleChangeRowsPerPage: (rowsPerPage: number | null) => void; onHandleRequestSort: (property: string) => void; + onHideColumns : (columnNames: string[]) => void + onShowColumns: (columnNames: string[]) => void }; type MaterialTableComponentProps<TData = {}> = @@ -203,13 +209,18 @@ function isMaterialTableComponentPropsWithRowsAndRequestData(props: MaterialTabl propsWithExternalState.onHandleChangePage instanceof Function || propsWithExternalState.onHandleChangeRowsPerPage instanceof Function || propsWithExternalState.onToggleFilter instanceof Function || + propsWithExternalState.onHideColumns instanceof Function || propsWithExternalState.onHandleRequestSort instanceof Function } +// get settings in here! + + class MaterialTableComponent<TData extends {} = {}> extends React.Component<MaterialTableComponentProps, MaterialTableComponentState & { contextMenuInfo: { index: number; mouseX?: number; mouseY?: number }; }> { constructor(props: MaterialTableComponentProps) { super(props); + const page = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.page : 0; const rowsPerPage = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.rowsPerPage || 10 : 10; @@ -224,6 +235,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate selected: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.selected : null, rows: isMaterialTableComponentPropsWithRows(this.props) && this.props.rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) || [], total: isMaterialTableComponentPropsWithRows(this.props) && this.props.rows.length || 0, + hiddenColumns: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) && this.props.hiddenColumns || [], page, rowsPerPage, }; @@ -237,18 +249,27 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate } } render(): JSX.Element { - const { classes, columns } = this.props; + const { classes, columns, allowHtmlHeader } = this.props; const { rows, total: rowCount, order, orderBy, selected, rowsPerPage, page, showFilter, filter } = this.state; const emptyRows = rowsPerPage - Math.min(rowsPerPage, rowCount - page * rowsPerPage); const getId = typeof this.props.idProperty !== "function" ? (data: TData) => ((data as { [key: string]: any })[this.props.idProperty as any as string] as string | number) : this.props.idProperty; const toggleFilter = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.onToggleFilter : () => { !this.props.disableFilter && this.setState({ showFilter: !showFilter }, this.update) } + + const hideColumns = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.onHideColumns : (data: string[]) => { const newArray = [...new Set([...this.state.hiddenColumns, ...data])]; this.setState({hiddenColumns:newArray}); } + const showColumns = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.onShowColumns : (data: string[]) => { const newArray = this.state.hiddenColumns.filter(el=> !data.includes(el)); this.setState({hiddenColumns:newArray}); } + + const allColumnsHidden = this.props.columns.length === this.state.hiddenColumns.length; return ( <Paper className={this.props.className ? `${classes.root} ${this.props.className}` : classes.root}> <TableContainer className={classes.container}> <TableToolbar tableId={this.props.tableId} numSelected={selected && selected.length} title={this.props.title} customActionButtons={this.props.customActionButtons} onExportToCsv={this.exportToCsv} - onToggleFilter={toggleFilter} /> + onToggleFilter={toggleFilter} + columns={columns} + onHideColumns={hideColumns} + onShowColumns={showColumns} /> <Table padding="normal" aria-label={this.props.tableId ? this.props.tableId : 'tableTitle'} stickyHeader={this.props.stickyHeader || false} > <EnhancedTableHead + allowHtmlHeader={allowHtmlHeader || false} columns={columns} numSelected={selected && selected.length} order={order} @@ -257,10 +278,14 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate onRequestSort={this.onHandleRequestSort} rowCount={rows.length} enableSelection={this.props.enableSelection} + hiddenColumns={this.state.hiddenColumns} /> <TableBody> - {showFilter && <EnhancedTableFilter columns={columns} filter={filter} onFilterChanged={this.onFilterChanged} enableSelection={this.props.enableSelection} /> || null} - {rows // may need ordering here + {showFilter && <EnhancedTableFilter columns={columns} hiddenColumns={this.state.hiddenColumns} filter={filter} onFilterChanged={this.onFilterChanged} enableSelection={this.props.enableSelection} /> || null} + + {allColumnsHidden ? <Typography variant="body1" textAlign="center">All columns of this table are hidden.</Typography> : + + rows // may need ordering here .map((entry: TData & { [RowDisabled]?: boolean, [kex: string]: any }, index) => { const entryId = getId(entry); const contextMenu = (this.props.createContextMenu && this.state.contextMenuInfo.index === index && this.props.createContextMenu(entry)) || null; @@ -295,15 +320,17 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate > {this.props.enableSelection ? <TableCell padding="checkbox" style={{ width: "50px", color: entry[RowDisabled] || false ? "inherit" : undefined } }> - <Checkbox checked={isSelected} /> + <Checkbox color='secondary' checked={isSelected} /> </TableCell> : null } { + this.props.columns.map( col => { const style = col.width ? { width: col.width } : {}; - return ( + const tableCell = ( + <TableCell style={ entry[RowDisabled] || false ? { ...style, color: "inherit" } : style } aria-label={col.title? toAriaLabel(col.title) : toAriaLabel(col.property)} 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} /> @@ -313,6 +340,10 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate } </TableCell> ); + + //show column if... + const showColumn = !this.state.hiddenColumns.includes(col.property); + return showColumn && tableCell } ) } @@ -352,6 +383,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate } static getDerivedStateFromProps(props: MaterialTableComponentProps, state: MaterialTableComponentState & { _rawRows: {}[] }): MaterialTableComponentState & { _rawRows: {}[] } { + if (isMaterialTableComponentPropsWithRowsAndRequestData(props)) { return { ...state, @@ -363,6 +395,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate loading: props.loading, showFilter: props.showFilter, page: props.page, + hiddenColumns: props.hiddenColumns, rowsPerPage: props.rowsPerPage } } else if (isMaterialTableComponentPropsWithRows(props) && props.asynchronus && state._rawRows !== props.rows) { diff --git a/sdnr/wt/odlux/framework/src/components/material-table/showColumnDialog.tsx b/sdnr/wt/odlux/framework/src/components/material-table/showColumnDialog.tsx new file mode 100644 index 000000000..f8ae6ea97 --- /dev/null +++ b/sdnr/wt/odlux/framework/src/components/material-table/showColumnDialog.tsx @@ -0,0 +1,188 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2022 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { Button, Checkbox, FormControlLabel, MenuItem, Popover, Switch, Typography } from '@mui/material'; +import connect, { Connect, IDispatcher } from '../../flux/connect'; +import * as React from 'react'; + +import { ColumnModel } from './columnModel'; +import { IApplicationStoreState } from '../../store/applicationStore'; +import { TableSettingsColumn } from '../../models/settings'; +import { updateTableSettings } from '../../actions/settingsAction'; + +const mapStateToProps = (state: IApplicationStoreState) => ({ + settings: state.framework.applicationState.settings, + settingsDoneLoading: state.framework.applicationState.settings.isInitialLoadDone +}); + +const mapDispatchToProps = (dispatcher: IDispatcher) => ({ + saveToSettings: (tableName: string, columns: TableSettingsColumn[]) => dispatcher.dispatch(updateTableSettings(tableName, columns)) +}) + +type DialogProps = { + columns: ColumnModel<{}>[], + settingsName: string | null, + anchorEl: HTMLElement | null; + hideColumns: (columnNames: string[]) => void + showColumns: (columnNames: string[]) => void + onClose(): void + +} & Connect<typeof mapStateToProps, typeof mapDispatchToProps>; + + //TODO: figure out why everything gets triggered twice... + +const ShowColumnsDialog: React.FunctionComponent<DialogProps> = (props) => { + + const savedSettings = props.settingsName && props.settings.tables[props.settingsName]; + + const [checkedColumns, setCheckedColumns] = React.useState<{ property: string, display: boolean, title: string | undefined }[]>([]); + + const open = Boolean(props.anchorEl); + const allColumnNames = props.columns.map(e => e.property); + + React.useEffect(() => { + + createHideShowSelection(); + + }, []); + + React.useEffect(() => { + + createHideShowSelection(); + + }, [props.settings.isInitialLoadDone]); + + + const createHideShowSelection = () => { + let columns = props.columns.map(e => { return { property: e.property, display: !Boolean(e.hide), title: e.title } }); + + + if (savedSettings) { + + if (columns.length !== savedSettings.columns.length) { + console.error("saved column length does not match current column length. Maybe a settings entry got wrongly overridden?") + } + + //overwrite column data with settings + savedSettings?.columns.forEach(el => { + let foundIndex = columns.findIndex(e => e.property == el.property); + if (columns[foundIndex] !== undefined) + columns[foundIndex].display = el.displayed; + }); + + } else { + console.warn("No settingsName set, changes will not be saved.") + } + + setCheckedColumns(columns); + + const hideColumns = columns.filter(el => !el.display).map(e => e.property); + props.hideColumns(hideColumns); + } + + + const handleChange = (propertyName: string, checked: boolean) => { + if (!checked) { + props.hideColumns([propertyName]); + } else { + props.showColumns([propertyName]) + + } + + let updatedList = checkedColumns.map(item => { + if (item.property == propertyName) { + return { ...item, display: checked }; + } + return item; + }); + + setCheckedColumns(updatedList); + }; + + const onHideAll = () => { + + switchCheckedColumns(false); + props.hideColumns(allColumnNames); + } + + const onShowAll = () => { + + switchCheckedColumns(true); + props.showColumns(allColumnNames); + } + + const onClose = () => { + + const tableColumns: TableSettingsColumn[] = checkedColumns.map(el => { + return { + property: el.property, + displayed: el.display + } + }); + + if (props.settingsName) { + props.saveToSettings(props.settingsName, tableColumns); + } + props.onClose(); + + } + + const switchCheckedColumns = (changeToValue: boolean) => { + let updatedList = checkedColumns.map(item => { + return { ...item, display: changeToValue }; + }); + + setCheckedColumns(updatedList); + + } + + return (<Popover open={open} onClose={onClose} + anchorEl={props.anchorEl} + anchorOrigin={{ + vertical: 'top', + horizontal: 'left', + }} > + <div> + <Typography fontWeight={600} style={{ margin: 10 }} >Hide / Show Columns</Typography> + </div> + <div style={{ display: "flex", flexDirection: "column", margin: 10 }}> + { + checkedColumns?.map((el, i) => { + + return <> + + <FormControlLabel + value="end" + key={"hide-show-column-"+i} + aria-label={"hide-or-show-column-button"} + control={<Switch color="secondary" checked={el.display} onChange={e => handleChange(el.property, e.target.checked)} />} + label={el.title || el.property} + labelPlacement="end" + /> + </> + }) + } + <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}> + <Button color="secondary" aria-label="hide-all-columns-button" onClick={(e) => onHideAll()}>Hide all</Button> + <Button color="secondary" aria-label="show-all-columns-button" onClick={(e) => onShowAll()}>Show all</Button> + </div> + </div> + </Popover>) +} + +export default connect(mapStateToProps, mapDispatchToProps)(ShowColumnsDialog); diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx index a46dd18d8..1b9136844 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx +++ b/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx @@ -50,6 +50,7 @@ interface IEnhancedTableFilterComponentProps extends WithStyles<typeof styles> { onFilterChanged: (property: string, filterTerm: string) => void; filter: { [property: string]: string }; columns: ColumnModel<{}>[]; + hiddenColumns: string[]; enableSelection?: boolean; } @@ -73,7 +74,7 @@ class EnhancedTableFilterComponent extends React.Component<IEnhancedTableFilterC } {columns.map((col, ind) => { const style = col.width ? { width: col.width } : {}; - return ( + const tableCell = ( <TableCell className={col.type === ColumnType.numeric ? classes.numberInput : ''} key={col.property} @@ -99,6 +100,10 @@ class EnhancedTableFilterComponent extends React.Component<IEnhancedTableFilterC onChange={this.createInputFilterHandler(col.property)} />} </TableCell> ); + + const showColumn = !this.props.hiddenColumns.includes(col.property); + + return showColumn && tableCell; }, this)} </TableRow> ); diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx index c500f44ce..d6f7b7def 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx +++ b/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx @@ -50,7 +50,9 @@ interface IEnhancedTableHeadComponentProps extends styles_header { orderBy: string | null; rowCount: number; columns: ColumnModel<{}>[]; + hiddenColumns: string[]; enableSelection?: boolean; + allowHtmlHeader?: boolean; } class EnhancedTableHeadComponent extends React.Component<IEnhancedTableHeadComponentProps> { @@ -77,7 +79,7 @@ class EnhancedTableHeadComponent extends React.Component<IEnhancedTableHeadCompo } { columns.map(col => { const style = col.width ? { width: col.width } : {}; - return ( + const tableCell = ( <TableCell className= {classes.header} key={ col.property } align={ col.type === ColumnType.numeric ? 'right' : 'left' } @@ -102,11 +104,19 @@ class EnhancedTableHeadComponent extends React.Component<IEnhancedTableHeadCompo direction={ order || undefined } onClick={ this.createSortHandler(col.property) } > - { col.title || col.property } + { + this.props.allowHtmlHeader ? <div className="content" dangerouslySetInnerHTML={{__html: col.title || col.property}}></div> + : (col.title || col.property ) + } </TableSortLabel> </Tooltip> } </TableCell> ); + + //show column if... + const showColumn = !this.props.hiddenColumns.includes(col.property); + + return showColumn && tableCell; }, this) } </TableRow> </TableHead> 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 426436d44..143b802a4 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx +++ b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx @@ -33,6 +33,8 @@ import MenuItem from '@mui/material/MenuItem'; import Menu from '@mui/material/Menu'; import { SvgIconProps } from '@mui/material/SvgIcon'; import { Button } from '@mui/material'; +import { ColumnModel } from './columnModel'; +import ShowColumnsDialog from './showColumnDialog' const styles = (theme: Theme) => createStyles({ root: { @@ -69,18 +71,24 @@ const styles = (theme: Theme) => createStyles({ interface ITableToolbarComponentProps extends WithStyles<typeof styles> { numSelected: number | null; title?: string; - tableId?: string; + tableId: string | null; customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, ariaLabel: string, onClick: () => void, disabled?: boolean }[]; + columns: ColumnModel<{}>[]; + onHideColumns: (columnNames: string[]) => void + onShowColumns: (columnNames: string[]) => void onToggleFilter: () => void; onExportToCsv: () => void; } -class TableToolbarComponent extends React.Component<ITableToolbarComponentProps, { anchorEl: EventTarget & HTMLElement | null }> { +class TableToolbarComponent extends React.Component<ITableToolbarComponentProps, { anchorEl: EventTarget & HTMLElement | null, anchorElDialog: HTMLElement | null }> { + + constructor(props: ITableToolbarComponentProps) { super(props); this.state = { - anchorEl: null + anchorEl: null, + anchorElDialog: null }; } @@ -91,11 +99,22 @@ class TableToolbarComponent extends React.Component<ITableToolbarComponentProps, private handleClose = () => { this.setState({ anchorEl: null }); }; + + private showColumnsDialog = (event: React.MouseEvent<HTMLElement>) =>{ + this.setState({ anchorElDialog: this.state.anchorEl }); + } + + private onCloseDialog = () =>{ + this.setState({ anchorElDialog: null }); + + } + render() { const { numSelected, classes } = this.props; const open = !!this.state.anchorEl; - const buttonPrefix = this.props.tableId !== undefined ? this.props.tableId : 'table'; + const buttonPrefix = this.props.tableId !== null ? this.props.tableId : 'table'; return ( + <> <Toolbar className={`${classes.root} ${numSelected && numSelected > 0 ? classes.highlight : ''} `} > <div className={classes.title}> {numSelected && numSelected > 0 ? ( @@ -153,9 +172,18 @@ class TableToolbarComponent extends React.Component<ITableToolbarComponentProps, <Menu id="menu-appbar" anchorEl={this.state.anchorEl} anchorOrigin={{ vertical: 'top', horizontal: 'right' }} transformOrigin={{ vertical: 'top', horizontal: 'right' }} open={open} onClose={this.handleClose} > <MenuItem aria-label="export-table-as-csv" onClick={(e) =>{ this.props.onExportToCsv(); this.handleClose()}}>Export as CSV</MenuItem> + <MenuItem aria-label="hide-show-table-columns" onClick={(e) =>{ this.showColumnsDialog(e); this.handleClose()}}>Hide/show columns</MenuItem> </Menu> </div> </Toolbar> + <ShowColumnsDialog + anchorEl={this.state.anchorElDialog} + onClose={this.onCloseDialog} + settingsName={this.props.tableId} + columns={this.props.columns} + hideColumns={this.props.onHideColumns} + showColumns={this.props.onShowColumns} /> + </> ); } } 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 544e14e01..f9015493f 100644 --- a/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts +++ b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts @@ -28,6 +28,7 @@ export interface IExternalTableState<TData> { order: 'asc' | 'desc'; orderBy: string | null; selected: any[] | null; + hiddenColumns: string[] rows: (TData & { [RowDisabled]?: boolean })[]; total: number; page: number; @@ -48,7 +49,9 @@ export type ExternalMethodes<TData> = { onFilterChanged: (property: string, filterTerm: string) => void; onHandleChangePage: (page: number) => void; onHandleChangeRowsPerPage: (rowsPerPage: number | null) => void; - }; + onHideColumns: (columnName: string[]) => void; + onShowColumns: (columnName: string[]) => void; + }, createPreActions: (dispatch: Dispatch, skipRefresh?: boolean) => { onPreFilterChanged: (preFilter: { [key: string]: string; @@ -128,6 +131,18 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState } } + class HideColumnsAction extends TableAction{ + constructor(public property: string[]){ + super(); + } + } + + class ShowColumnsAction extends TableAction{ + constructor(public property: string[]){ + super(); + } + } + // #endregion //#region Action Handler @@ -135,6 +150,7 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState order: 'asc', orderBy: null, selected: null, + hiddenColumns:[], rows: [], total: 0, page: 0, @@ -208,6 +224,18 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState rowsPerPage: action.rowsPerPage } } + else if (action instanceof HideColumnsAction){ + + //merge arrays, remove duplicates + const newArray = [...new Set([...state.hiddenColumns, ...action.property])] + state = {...state, hiddenColumns: newArray}; + } + else if(action instanceof ShowColumnsAction){ + + const newArray = state.hiddenColumns.filter(el=> !action.property.includes(el)); + state = {...state, hiddenColumns: newArray}; + } + return state; } @@ -290,6 +318,16 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState dispatch(new SetRowsPerPageAction(rowsPerPage || 10)); (!skipRefresh) && dispatch(reloadAction); }); + }, + onHideColumns: (columnName: string[]) =>{ + dispatch((dispatch: Dispatch) => { + dispatch(new HideColumnsAction(columnName)); + }) + }, + onShowColumns: (columnName: string[]) =>{ + dispatch((dispatch: Dispatch) => { + dispatch(new ShowColumnsAction(columnName)); + }) } // selected: }; diff --git a/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx b/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx index 1134e230b..195706d28 100644 --- a/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx +++ b/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx @@ -64,9 +64,9 @@ const styles = (theme: Theme) => createStyles({ duration: theme.transitions.duration.leavingScreen, }), overflowX: 'hidden', - width: theme.spacing(7) + 1, + width: theme.spacing(7), [theme.breakpoints.up('sm')]: { - width: theme.spacing(9) + 1, + width: theme.spacing(9), }, }, drawer: { @@ -101,7 +101,7 @@ export const NavigationMenu = withStyles(styles)(connect()(({ classes, state, di //collapse menu on mount if necessary React.useEffect(()=>{ - if(isOpen && window.innerWidth < tabletWidthBreakpoint){ + if(isOpen && window.innerWidth <= tabletWidthBreakpoint){ setResponsive(true); dispatch(new MenuAction(false)); @@ -116,14 +116,12 @@ export const NavigationMenu = withStyles(styles)(connect()(({ classes, state, di if (window.innerWidth < tabletWidthBreakpoint && !responsive) { setResponsive(true); if (!closedByUser) { - console.log("responsive menu collapsed") dispatch(new MenuAction(false)); } } else if (window.innerWidth > tabletWidthBreakpoint && responsive) { setResponsive(false); if (!closedByUser) { - console.log("responsive menu restored") dispatch(new MenuAction(true)); } @@ -145,13 +143,14 @@ export const NavigationMenu = withStyles(styles)(connect()(({ classes, state, di let menuItems = state.framework.applicationRegistraion && Object.keys(state.framework.applicationRegistraion).map(key => { const reg = state.framework.applicationRegistraion[key]; + const icon = !reg.icon ? null :( typeof reg.icon === 'string' ? <img height={22} src={reg.icon} /> : <FontAwesomeIcon icon={reg.icon} /> ) return reg && ( <ListItemLink key={reg.name} to={reg.path || `/${reg.name}`} primary={reg.menuEntry || reg.name} secondary={reg.subMenuEntry} - icon={reg.icon && <FontAwesomeIcon icon={reg.icon} /> || null} /> + icon={icon} /> ) || null; }) || null; diff --git a/sdnr/wt/odlux/framework/src/components/titleBar.tsx b/sdnr/wt/odlux/framework/src/components/titleBar.tsx index 7872e51da..19d3bdf74 100644 --- a/sdnr/wt/odlux/framework/src/components/titleBar.tsx +++ b/sdnr/wt/odlux/framework/src/components/titleBar.tsx @@ -131,6 +131,10 @@ class TitleBarComponent extends React.Component<TitleBarProps, { anchorEl: HTMLE } } + const stateIcon = state.framework.applicationState.icon; + const icon = !stateIcon ? null :( typeof stateIcon === 'string' ? <img className={classes.icon} height={22} src={stateIcon} /> : <FontAwesomeIcon className={classes.icon} icon={stateIcon} /> ) + + return ( <AppBar enableColorOnDark position="absolute" className={classes.appBar}> <Toolbar> @@ -144,9 +148,7 @@ class TitleBarComponent extends React.Component<TitleBarProps, { anchorEl: HTMLE </IconButton> <Logo /> <Typography variant="h6" color="inherit" > - {state.framework.applicationState.icon - ? (<FontAwesomeIcon className={classes.icon} icon={state.framework.applicationState.icon} />) - : null} + {icon} {state.framework.applicationState.title} </Typography> <div className={classes.grow}></div> |