aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx
diff options
context:
space:
mode:
authorAijana Schumann <aijana.schumann@highstreet-technologies.com>2020-03-13 10:39:11 +0100
committerAijana Schumann <aijana.schumann@highstreet-technologies.com>2020-03-13 10:39:11 +0100
commit05da65b2d01a75404059d7526b4cbb868f631dd7 (patch)
tree5a4a77ffd32c2a81567279c58c361344f52bb476 /sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx
parent25cb54c517caacafc76534b8972fa8df86a80dbf (diff)
Fix odlux bugs
Fix help and about app not scrollable Fix filter hiding and showing without user interaction and default sort in all tables Issue-ID: SDNC-1117 Signed-off-by: Aijana Schumann <aijana.schumann@highstreet-technologies.com> Change-Id: I5c6ff86c73a3b222a8d9022125454788496f6399
Diffstat (limited to 'sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx')
-rw-r--r--sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx120
1 files changed, 95 insertions, 25 deletions
diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx b/sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx
index 98ee291d1..1bb49367c 100644
--- a/sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx
@@ -37,6 +37,11 @@ const styles = (theme: Theme) => createStyles({
}
});
+export enum SearchMode {
+ OnKeyDown = 1,
+ OnEnter =2
+}
+
export type TreeItem<TData = { }> = {
disabled?: boolean;
icon?: React.ComponentType<SvgIconProps>;
@@ -47,13 +52,19 @@ export type TreeItem<TData = { }> = {
value?: TData;
}
+export type ExternalTreeItem<TData = {}> = TreeItem<TData> & {
+ isMatch?: boolean;
+}
+
+
type TreeViewComponentState<TData = { }> = {
/** All indices of all expanded Items */
- expandedItems: TreeItem<TData>[];
+ expandedItems: ExternalTreeItem<TData>[];
/** The index of the active iten or undefined if no item is active. */
- activeItem: undefined | TreeItem<TData>;
+ activeItem?: ExternalTreeItem<TData>;
/** The search term or undefined if search is corrently not active. */
- searchTerm: undefined | string;
+ searchTerm?: string;
+ searchTermValue?: string;
}
type TreeViewComponentBaseProps<TData = {}> = WithTheme & WithStyles<typeof styles> & {
@@ -65,6 +76,7 @@ type TreeViewComponentBaseProps<TData = {}> = WithTheme & WithStyles<typeof styl
style?: React.CSSProperties;
itemHeight?: number;
depthOffset?: number;
+ searchMode?: SearchMode;
}
type TreeViewComponentWithInternalStateProps<TData = { }> = TreeViewComponentBaseProps<TData> & {
@@ -72,7 +84,17 @@ type TreeViewComponentWithInternalStateProps<TData = { }> = TreeViewComponentBas
onFolderClick?: (item: TreeItem<TData>) => void;
}
-type TreeViewComponentWithExternalStateProps<TData = { }> = TreeViewComponentBaseProps<TData> & TreeViewComponentState<TData> & {
+type TreeViewComponentWithExternalSearchProps<TData = {}> = TreeViewComponentBaseProps<TData> & {
+ items: ExternalTreeItem<TData>[];
+ searchTerm: string;
+ onSearch: (searchTerm: string) => void;
+ onItemClick?: (item: TreeItem<TData>) => void;
+ onFolderClick?: (item: TreeItem<TData>) => void;
+}
+
+type TreeViewComponentWithExternalStateProps<TData = {}> = TreeViewComponentBaseProps<TData> & TreeViewComponentState<TData> & {
+ items: ExternalTreeItem<TData>[];
+ searchTerm: string;
onSearch: (searchTerm: string) => void;
onItemClick: (item: TreeItem<TData>) => void;
onFolderClick: (item: TreeItem<TData>) => void;
@@ -80,14 +102,25 @@ type TreeViewComponentWithExternalStateProps<TData = { }> = TreeViewComponentBas
type TreeViewComponentProps<TData = { }> =
| TreeViewComponentWithInternalStateProps<TData>
+ | TreeViewComponentWithExternalSearchProps<TData>
| TreeViewComponentWithExternalStateProps<TData>;
+function isTreeViewComponentWithExternalSearchProps(props: TreeViewComponentProps): props is TreeViewComponentWithExternalSearchProps {
+ const propsWithExternalState = (props as TreeViewComponentWithExternalStateProps)
+ return (
+ propsWithExternalState.onSearch instanceof Function &&
+ propsWithExternalState.onFolderClick === undefined &&
+ propsWithExternalState.expandedItems === undefined &&
+ propsWithExternalState.searchTerm !== undefined
+ );
+}
+
function isTreeViewComponentWithExternalStateProps(props: TreeViewComponentProps): props is TreeViewComponentWithExternalStateProps {
const propsWithExternalState = (props as TreeViewComponentWithExternalStateProps)
return (
- propsWithExternalState.onSearch instanceof Function ||
- propsWithExternalState.expandedItems !== undefined ||
- propsWithExternalState.activeItem !== undefined ||
+ propsWithExternalState.onSearch instanceof Function &&
+ propsWithExternalState.onFolderClick instanceof Function &&
+ propsWithExternalState.expandedItems !== undefined &&
propsWithExternalState.searchTerm !== undefined
);
}
@@ -103,19 +136,20 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
this.state = {
expandedItems: [],
activeItem: undefined,
- searchTerm: undefined
+ searchTerm: undefined,
+ searchTermValue: undefined
};
}
render(): JSX.Element {
this.itemIndex = 0;
- const { searchTerm } = this.state;
+ const { searchTerm , searchTermValue} = this.state;
const { children, items, enableSearchBar } = this.props;
return (
<div className={this.props.className ? `${this.props.classes.root} ${this.props.className}` : this.props.classes.root} style={this.props.style}>
{children}
- {enableSearchBar && <TextField label={"Search"} fullWidth={true} className={ this.props.classes.search } value={searchTerm} onChange={this.onChangeSearchText} /> || null}
+ {enableSearchBar && <TextField label={"Search"} fullWidth={true} className={this.props.classes.search} value={searchTermValue} onKeyDown={this.onSearchKeyDown} onChange={this.onChangeSearchText} /> || null}
<List>
{this.renderItems(items, searchTerm && searchTerm.toLowerCase())}
</List>
@@ -124,20 +158,21 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
}
private itemIndex: number = 0;
- private renderItems = (items: TreeItem<TData>[], searchTerm: string | undefined, depth: number = 1) => {
+ private renderItems = (items: TreeItem<TData>[], searchTerm: string | undefined, depth: number = 1, forceRender: boolean = true) => {
+
return items.reduce((acc, item) => {
const children = item.children; // this.props.childrenProperty && ((item as any)[this.props.childrenProperty] as TData[]);
- const childrenJsx = children && this.renderItems(children, searchTerm, depth + 1);
+ const childrenJsx = children && this.renderItems(children, searchTerm, depth + 1, this.state.expandedItems.indexOf(item) > -1);
- const expanded = searchTerm
+ const expanded = !isTreeViewComponentWithExternalStateProps(this.props) && searchTerm
? childrenJsx && childrenJsx.length > 0
: !children
? false
: this.state.expandedItems.indexOf(item) > -1;
const isFolder = children !== undefined;
- const itemJsx = this.renderItem(item, searchTerm, depth, isFolder, expanded || false);
+ const itemJsx = this.renderItem(item, searchTerm, depth, isFolder, expanded || false, forceRender);
itemJsx && acc.push(itemJsx);
if (isFolder && expanded && childrenJsx) {
@@ -147,7 +182,7 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
}, [] as JSX.Element[]);
}
- private renderItem = (item: TreeItem<TData>, searchTerm: string | undefined, depth: number, isFolder: boolean, expanded: boolean): JSX.Element | null => {
+ private renderItem = (item: ExternalTreeItem<TData>, searchTerm: string | undefined, depth: number, isFolder: boolean, expanded: boolean, forceRender: boolean): JSX.Element | null => {
const styles = {
item: {
paddingLeft: (((this.props.depthOffset || 0) + depth) * this.props.theme.spacing(3)),
@@ -175,7 +210,7 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
}
};
- return ((searchTerm && (matchIndex > -1 || expanded) || !searchTerm)
+ return ((searchTerm && (matchIndex > -1 || expanded || (!isTreeViewComponentWithExternalStateProps(this.props) && item.isMatch || depth === 1)) || !searchTerm || forceRender)
? (
<ListItem key={`tree-list-${this.itemIndex++}`} style={styles.item} onClick={handleClickCreator(false)} button >
@@ -186,7 +221,7 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
{ // highlight search result
matchIndex > -1
- ? (<span>
+ ? <ListItemText className={item.contentClass} primary={(<span>
{text.substring(0, matchIndex)}
<span
style={{
@@ -198,8 +233,15 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
{text.substring(matchIndex, matchIndex + searchTermLength)}
</span>
{text.substring(matchIndex + searchTermLength)}
- </span>)
- : (<ListItemText className={ item.contentClass } primary={text} />)
+ </span>)} />
+ : <ListItemText className={item.contentClass} primary={(
+ <span style={item.isMatch ? {
+ display: 'inline-block',
+ backgroundColor: 'rgba(255,235,59,0.5)',
+ padding: '3px',
+ } : undefined}>
+ {text} </span>
+ )} />
}
{ // display the right icon, depending on the state
@@ -235,16 +277,39 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
});
};
+ private onSearchKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
+ const enterMode = this.props.searchMode === SearchMode.OnEnter;
+
+ if (enterMode && event.keyCode === 13) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ enterMode && this.setState({
+ searchTerm: this.state.searchTermValue
+ });
+
+ if (isTreeViewComponentWithExternalSearchProps(this.props) || isTreeViewComponentWithExternalStateProps(this.props)) {
+ this.props.onSearch(this.state.searchTermValue || "");
+ }
+ }
+ }
+
private onChangeSearchText = (event: React.ChangeEvent<HTMLInputElement>) => {
event.preventDefault();
event.stopPropagation();
- if (isTreeViewComponentWithExternalStateProps(this.props)) {
- this.props.onSearch(event.target.value)
- } else {
- this.setState({
- searchTerm: event.target.value
- });
+ const keyDownMode = (!this.props.searchMode || this.props.searchMode === SearchMode.OnKeyDown);
+
+ this.setState(keyDownMode
+ ? {
+ searchTerm: event.target.value,
+ searchTermValue: event.target.value,
+ } as any : {
+ searchTermValue: event.target.value,
+ }) as any;
+
+ if ((isTreeViewComponentWithExternalSearchProps(this.props) || isTreeViewComponentWithExternalStateProps(this.props)) && keyDownMode) {
+ this.props.onSearch(event.target.value);
}
};
@@ -256,6 +321,11 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
activeItem: props.activeItem,
searchTerm: props.searchTerm
};
+ } else if (isTreeViewComponentWithExternalSearchProps(props)) {
+ return {
+ ...state,
+ searchTerm: props.searchTerm,
+ };
}
return state;
}