Skip to content

Commit 6b218e2

Browse files
author
JelteMX
committed
Update code && add expand/collapse all button
1 parent 5a9beb2 commit 6b218e2

File tree

11 files changed

+2162
-2417
lines changed

11 files changed

+2162
-2417
lines changed

package-lock.json

Lines changed: 2081 additions & 2378 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "mxtreetable",
33
"widgetName": "MxTreeTable",
4-
"version": "2.0.7",
4+
"version": "2.0.8",
55
"description": "TreeTable widget",
66
"copyright": "Mendix 2019",
77
"author": "Jelte Lagendijk <jelte.lagendijk@mendix.com>",
@@ -32,7 +32,7 @@
3232
},
3333
"license": "Apache-2.0",
3434
"devDependencies": {
35-
"@mendix/pluggable-widgets-tools": "^8.6.0",
35+
"@mendix/pluggable-widgets-tools": "8.6.0",
3636
"@types/big.js": "^4.0.5",
3737
"@types/camelcase": "^5.2.0",
3838
"@types/classnames": "^2.2.10",
@@ -53,7 +53,7 @@
5353
"webpack-bundle-analyzer": "^3.6.0"
5454
},
5555
"dependencies": {
56-
"@jeltemx/mendix-react-widget-utils": "^0.6.2",
56+
"@jeltemx/mendix-react-widget-utils": "^0.7.0",
5757
"@thi.ng/strings": "^1.8.3",
5858
"antd": "^3.26.7",
5959
"array-to-tree": "^3.3.2",
@@ -63,6 +63,7 @@
6363
"mobx": "^4.15.2",
6464
"mobx-react": "^6.2.2",
6565
"promise-queue": "^2.2.5",
66+
"react-icons": "^3.10.0",
6667
"store2": "^2.11.1"
6768
}
6869
}

src/MxTreeTable.tsx

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ import {
1212
IAction,
1313
getObjectContextFromObjects,
1414
executeMicroflow,
15-
executeNanoFlow,
16-
openPage,
15+
executeNanoflow,
1716
fetchByXpath,
1817
getObjects,
1918
ValidationMessage,
2019
getObject,
2120
commitObject,
2221
createObject,
2322
OpenPageAs,
24-
entityIsPersistable
23+
entityIsPersistable,
24+
executeAction
2525
} from "@jeltemx/mendix-react-widget-utils";
2626

2727
import { NodeStore, NodeStoreConstructorOptions } from "./store";
@@ -45,7 +45,7 @@ import { TableState } from "./store/index";
4545
import { ColumnProps } from "antd/es/table/interface";
4646

4747
export interface Action extends IAction {}
48-
export type ActionReturn = string | number | boolean | mendix.lib.MxObject | mendix.lib.MxObject[] | void;
48+
export type ActionReturn = null | string | number | boolean | mendix.lib.MxObject | mendix.lib.MxObject[] | void;
4949
export interface TransformNanoflows {
5050
[key: string]: Nanoflow;
5151
}
@@ -253,7 +253,8 @@ class MxTreeTable extends Component<MxTreeTableContainerProps> {
253253
getInlineActionButtons: this._getInlineButtonColumns.bind(this),
254254
buttonBar,
255255
clickToSelect: selectClickSelect,
256-
hideSelectBoxes: selectHideCheckboxes
256+
hideSelectBoxes: selectHideCheckboxes,
257+
renderExpandButton: this.props.loadScenario === "all" && this.props.uiRenderExpandButton
257258
});
258259
}
259260

@@ -627,7 +628,7 @@ class MxTreeTable extends Component<MxTreeTableContainerProps> {
627628
if (mf !== null) {
628629
executeMicroflow(mf, context, this.props.mxform, true);
629630
} else if (nf !== null) {
630-
executeNanoFlow(nf, context, this.props.mxform, true);
631+
executeNanoflow(nf, context, this.props.mxform, true);
631632
}
632633
}
633634

@@ -696,7 +697,7 @@ Your context object is of type "${contextEntity}". Please check the configuratio
696697
this.debug("Action executed");
697698
});
698699
} else if (nf !== null) {
699-
return executeNanoFlow(nf, context, mxform).then(() => {
700+
return executeNanoflow(nf, context, mxform).then(() => {
700701
this.debug("Action executed");
701702
});
702703
}
@@ -888,19 +889,12 @@ Your context object is of type "${contextEntity}". Please check the configuratio
888889

889890
private _executeAction(action: Action, showError = false, obj?: mendix.lib.MxObject): Promise<ActionReturn> {
890891
this.debug("executeAction", action, obj && obj.getGuid());
891-
const { mxform } = this.props;
892-
const context = getObjectContextFromObjects(obj, this.props.mxObject);
893-
894-
if (action.microflow) {
895-
return executeMicroflow(action.microflow, context, mxform, showError);
896-
} else if (action.nanoflow) {
897-
return executeNanoFlow(action.nanoflow, context, mxform, showError);
898-
} else if (action.page) {
899-
return openPage(action.page, context, showError);
900-
}
901892

902-
return Promise.reject(
903-
new Error(`No microflow/nanoflow/page defined for this action: ${JSON.stringify(action)}`)
893+
return executeAction(
894+
action,
895+
showError,
896+
getObjectContextFromObjects(obj, this.props.mxObject),
897+
this.props.mxform
904898
);
905899
}
906900

src/MxTreeTable.webmodeler.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export class preview extends Component<MxTreeTableContainerProps> {
6464

6565
const store: MockStore = {
6666
validationMessages,
67+
rowObjects: [],
6768
rowTree: [],
6869
expandedKeys: [],
6970
isLoading: false,

src/MxTreeTable.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ It should be a non-persistent entity (persistent is not permitted) with a refere
423423
<caption>Expand first level</caption>
424424
<description>Only works while loading the whole tree: Automatically expand the first level of the tree. Currently it is only possible to automatically expand the first level. This will be ignored if the user has already used state management before.</description>
425425
</property>
426+
<property key="uiRenderExpandButton" type="boolean" defaultValue="false">
427+
<caption>Render expand button</caption>
428+
<description>Render a button to expand/collapse all</description>
429+
</property>
426430
</propertyGroup>
427431
</propertyGroup>
428432

src/components/TreeTable.tsx

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Component, ReactNode, createElement } from "react";
22
import { observer } from "mobx-react";
33
import classNames from "classnames";
4+
import { FaExpandAlt, FaCompressAlt } from "react-icons/fa";
45
import Table, { TableRowSelection, ColumnProps } from "antd/es/table";
56

67
// Importing seperate so we don't pollute the CSS too much
@@ -38,6 +39,7 @@ export interface TreeTableProps {
3839
onSelect?: (ids: string[]) => void;
3940
buttonBar?: ReactNode;
4041
hideSelectBoxes?: boolean;
42+
renderExpandButton?: boolean;
4143
}
4244

4345
const DEBOUNCE = 250;
@@ -54,8 +56,8 @@ export class TreeTable extends Component<TreeTableProps> {
5456
this.onRowDblClick = this.onRowDblClick.bind(this);
5557
this.onExpand = this.onExpand.bind(this);
5658
this.setSelected = this.setSelected.bind(this);
57-
// this.expandAll = this.expandAll.bind(this);
58-
// this.collapseAll = this.collapseAll.bind(this);
59+
this.expandAll = this.expandAll.bind(this);
60+
this.collapseAll = this.collapseAll.bind(this);
5961
this.onSelectionChange = this.onSelectionChange.bind(this);
6062
this.rowClassName = this.rowClassName.bind(this);
6163
}
@@ -158,11 +160,20 @@ export class TreeTable extends Component<TreeTableProps> {
158160
}
159161

160162
columns = columns.map((col, index) => {
161-
if (!col.key) {
162-
return col;
163+
const newCol = { ...col };
164+
if (!newCol.key) {
165+
return newCol;
166+
}
167+
if (index === 0 && this.props.renderExpandButton) {
168+
newCol.title = (
169+
<div>
170+
{this.renderExpandButton()}
171+
{col.title}
172+
</div>
173+
);
163174
}
164175
return {
165-
...col,
176+
...newCol,
166177
render: (text, record) => {
167178
if (index === 0 && record._icon) {
168179
return (
@@ -205,6 +216,23 @@ export class TreeTable extends Component<TreeTableProps> {
205216
);
206217
}
207218

219+
private renderExpandButton(): ReactNode {
220+
const expanded = this.props.store.expandedKeys.length > 0;
221+
const className = classNames("treetable-expand-button");
222+
if (expanded) {
223+
return (
224+
<div role="button" className={className} onClick={this.collapseAll}>
225+
<FaCompressAlt />
226+
</div>
227+
);
228+
}
229+
return (
230+
<div role="button" className={className} onClick={this.expandAll}>
231+
<FaExpandAlt />
232+
</div>
233+
);
234+
}
235+
208236
private setSelected(keys: string[]): void {
209237
this.onSelectionChange(keys);
210238
}
@@ -215,18 +243,18 @@ export class TreeTable extends Component<TreeTableProps> {
215243
return `treetable-treelevel-${index}${className}`;
216244
}
217245

218-
// private expandAll(): void {
219-
// const parentIds = this.props.rows
220-
// .filter(row => typeof row._parent !== "undefined" && row._parent)
221-
// .map(row => row._parent) as string[];
222-
// this.setState({
223-
// expandedRowKeys: uniq(parentIds)
224-
// });
225-
// }
246+
private expandAll(): void {
247+
const parentIds = this.props.store.rowObjects
248+
.filter(row => typeof row._parent !== "undefined" && row._parent)
249+
.map(row => row._parent) as string[];
250+
const filtered = parentIds.filter((item, i, ar) => ar.indexOf(item) === i);
226251

227-
// private collapseAll(): void {
228-
// this.props.store.setExpanded([]);
229-
// }
252+
this.props.store.setExpanded(filtered);
253+
}
254+
255+
private collapseAll(): void {
256+
this.props.store.setExpanded([]);
257+
}
230258

231259
private onRowClick(record: TableRecord): void {
232260
if (this.props.onClick) {

src/components/__tests__/TreeTable.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const rows = (): any[] => {
4949
const getTableProps = (rows?: TreeRowObject[], columns?: TreeColumnProps[]): TreeTableProps => {
5050
const store: MockStore = {
5151
validationMessages: [],
52+
rowObjects: [],
5253
rowTree: rows || [],
5354
expandedKeys: [],
5455
isLoading: false,

src/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<package xmlns="http://www.mendix.com/package/1.0/">
3-
<clientModule name="MxTreeTable" version="2.0.7" xmlns="http://www.mendix.com/clientModule/1.0/">
3+
<clientModule name="MxTreeTable" version="2.0.8" xmlns="http://www.mendix.com/clientModule/1.0/">
44
<widgetFiles>
55
<widgetFile path="MxTreeTable.xml"/>
66
</widgetFiles>

src/store/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export interface TableState {
2323

2424
export interface MockStore {
2525
rowTree: Tree<TreeRowObject[]>;
26+
rowObjects: RowObject[];
2627
setSelected: (keys?: string[]) => void;
2728
setExpanded: (keys?: string[]) => void;
2829
selectedRows: string[];

src/ui/MxTreeTable.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@
77
@import "~antd/es/pagination/style/index.css";
88

99
.widget-treetable-wrapper {
10+
11+
.treetable-expand-button {
12+
display: inline-block;
13+
height: 25px;
14+
width: 14px;
15+
margin-right: 10px;
16+
line-height: 14px;
17+
margin-top: 0px;
18+
padding: 6px 0 0 0;
19+
}
20+
1021
.ant-table-thead {
1122
.ant-table-selection-column {
1223
.ant-checkbox-input {

0 commit comments

Comments
 (0)