Skip to content

Commit dacb9ac

Browse files
author
JelteMX
committed
Chores: update dependencies, rewrite title methods, clean up code
1 parent 7c41382 commit dacb9ac

File tree

9 files changed

+2493
-2544
lines changed

9 files changed

+2493
-2544
lines changed

package-lock.json

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "treeview",
33
"widgetName": "TreeView",
4-
"version": "1.1.1",
4+
"version": "1.2.0",
55
"description": "TreeView for Mendix",
66
"copyright": "Jelte Lagendijk 2019",
77
"author": "Jelte Lagendijk <jelte.lagendijk@mendix.com>",
@@ -29,7 +29,7 @@
2929
},
3030
"license": "Apache-2.0",
3131
"devDependencies": {
32-
"@mendix/pluggable-widgets-tools": "^8.6.0",
32+
"@mendix/pluggable-widgets-tools": "8.6.0",
3333
"@types/big.js": "^4.0.5",
3434
"@types/classnames": "^2.2.4",
3535
"@types/debounce": "^1.2.0",

src/TreeView.tsx

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import {
1919
deleteObject
2020
} from "@jeltemx/mendix-react-widget-utils";
2121
import { splitRef } from "./utils/index";
22-
import { TitleMethod, EntryObjectExtraOptions, EntryObject } from "./store/objects/entry";
23-
import { getTitleFromObject, ClickCellType } from "./utils/titlehelper";
22+
import { EntryObjectExtraOptions, EntryObject } from "./store/objects/entry";
23+
import { getStaticTitleFromObject, getDynamicTitleFromObject, ClickCellType } from "./utils/titlehelper";
2424
import { validateProps } from "./utils/validation";
2525
import { commitObject } from "@jeltemx/mendix-react-widget-utils";
2626

@@ -32,11 +32,19 @@ class TreeView extends Component<TreeViewContainerProps> {
3232
private widgetId?: string;
3333
private searchEnabled: boolean;
3434

35+
fetchData = this._fetchData.bind(this);
36+
fetchChildren = this._fetchChildren.bind(this);
37+
executeAction = this._executeAction.bind(this);
38+
getEntryOptions = this._getEntryOptions.bind(this);
39+
getClassMethod = this._getClassMethod.bind(this);
40+
clickTypeHandler = this._clickTypeHandler.bind(this);
41+
createSearchHelper = this._createSearchHelper.bind(this);
42+
search = this._search.bind(this);
43+
debug = this._debug.bind(this);
44+
3545
constructor(props: TreeViewContainerProps) {
3646
super(props);
3747

38-
this.bindMethods();
39-
4048
const parentRef = props.relationType === "nodeParent" ? splitRef(props.relationNodeParent) : null;
4149
const childRef = props.relationType === "nodeChildren" ? splitRef(props.relationChildReference) : null;
4250
const hasChildAttr = props.relationNodeParentHasChildAttr !== "" ? props.relationNodeParentHasChildAttr : null;
@@ -117,18 +125,7 @@ class TreeView extends Component<TreeViewContainerProps> {
117125
);
118126
}
119127

120-
private bindMethods(): void {
121-
this.fetchData = this.fetchData.bind(this);
122-
this.fetchChildren = this.fetchChildren.bind(this);
123-
this.executeAction = this.executeAction.bind(this);
124-
this.getTitleMethod = this.getTitleMethod.bind(this);
125-
this.getClassMethod = this.getClassMethod.bind(this);
126-
this.clickTypeHandler = this.clickTypeHandler.bind(this);
127-
this.search = this.search.bind(this);
128-
this.debug = this.debug.bind(this);
129-
}
130-
131-
private async fetchData(object: mendix.lib.MxObject): Promise<void> {
128+
private async _fetchData(object: mendix.lib.MxObject): Promise<void> {
132129
this.debug("fetchData", object.getGuid());
133130
const {
134131
nodeEntity,
@@ -165,11 +162,9 @@ class TreeView extends Component<TreeViewContainerProps> {
165162
}
166163

167164
if (objects !== null) {
168-
const entryOpts: EntryObjectExtraOptions = { titleMethod: this.getTitleMethod() };
169-
170-
if (nodeLoadScenario === "top") {
171-
entryOpts.isRoot = true;
172-
}
165+
const entryOpts = this.getEntryOptions({
166+
isRoot: nodeLoadScenario === "top"
167+
});
173168

174169
this.store.setEntries(objects, entryOpts);
175170
} else {
@@ -179,7 +174,7 @@ class TreeView extends Component<TreeViewContainerProps> {
179174
this.store.setLoading(false);
180175
}
181176

182-
private async fetchChildren(parentObject: EntryObject): Promise<void> {
177+
private async _fetchChildren(parentObject: EntryObject): Promise<void> {
183178
if (this.props.nodeLoadScenario === "all") {
184179
return;
185180
}
@@ -228,10 +223,9 @@ class TreeView extends Component<TreeViewContainerProps> {
228223
}
229224

230225
if (objects !== null) {
231-
const entryOpts: EntryObjectExtraOptions = {
232-
titleMethod: this.getTitleMethod(),
226+
const entryOpts = this.getEntryOptions({
233227
parent: parentObject.mxObject.getGuid()
234-
};
228+
});
235229

236230
this.store.setEntries(objects, entryOpts, false);
237231
parentObject.setLoaded(true);
@@ -243,23 +237,33 @@ class TreeView extends Component<TreeViewContainerProps> {
243237
this.store.setLoading(false);
244238
}
245239

246-
private getTitleMethod(): TitleMethod {
240+
private _getEntryOptions(opts: Partial<EntryObjectExtraOptions>): EntryObjectExtraOptions {
247241
const renderAsHTML = this.props.uiNodeRenderAsHTML;
248242
const titleType = this.props.uiNodeTitleType;
249243
const attribute = this.props.uiNodeTitleAttr;
250244
const nanoflow = this.props.uiNodeTitleNanoflow;
251245

252-
return (obj: mendix.lib.MxObject): Promise<ReactNode> =>
253-
getTitleFromObject(obj, {
254-
attribute,
255-
executeAction: this.executeAction,
256-
nanoflow,
257-
titleType,
258-
renderAsHTML
259-
});
246+
if (titleType === "attribute" && attribute) {
247+
opts.staticTitleMethod = (obj: mendix.lib.MxObject) =>
248+
getStaticTitleFromObject(obj, {
249+
attribute,
250+
titleType,
251+
renderAsHTML
252+
});
253+
} else if (titleType === "nanoflow" && nanoflow.nanoflow) {
254+
opts.dynamicTitleMethod = (obj: mendix.lib.MxObject): Promise<ReactNode> =>
255+
getDynamicTitleFromObject(obj, {
256+
executeAction: this.executeAction,
257+
nanoflow,
258+
titleType,
259+
renderAsHTML
260+
});
261+
}
262+
263+
return opts;
260264
}
261265

262-
private getClassMethod(attr: string): (obj: mendix.lib.MxObject) => string {
266+
private _getClassMethod(attr: string): (obj: mendix.lib.MxObject) => string {
263267
return (obj: mendix.lib.MxObject): string => {
264268
if (!obj || !attr) {
265269
return "";
@@ -268,7 +272,7 @@ class TreeView extends Component<TreeViewContainerProps> {
268272
};
269273
}
270274

271-
private async clickTypeHandler(obj: mendix.lib.MxObject, clickType: ClickCellType = "single"): Promise<void> {
275+
private async _clickTypeHandler(obj: mendix.lib.MxObject, clickType: ClickCellType = "single"): Promise<void> {
272276
if (!obj || this.props.eventNodeClickFormat !== clickType) {
273277
return;
274278
}
@@ -295,7 +299,7 @@ class TreeView extends Component<TreeViewContainerProps> {
295299
}
296300
}
297301

298-
private async search(query: string): Promise<mendix.lib.MxObject[] | null> {
302+
private async _search(query: string): Promise<mendix.lib.MxObject[] | null> {
299303
const { searchNanoflow } = this.props;
300304

301305
if (!searchNanoflow) {
@@ -316,7 +320,7 @@ class TreeView extends Component<TreeViewContainerProps> {
316320
return objects;
317321
}
318322

319-
private async createSearchHelper(query: string): Promise<mendix.lib.MxObject | null> {
323+
private async _createSearchHelper(query: string): Promise<mendix.lib.MxObject | null> {
320324
const { searchHelperEntity, searchNodeReference, searchStringAttribute } = this.props;
321325
const searchNodeRef = searchNodeReference !== "" ? splitRef(searchNodeReference) : null;
322326

@@ -341,7 +345,7 @@ class TreeView extends Component<TreeViewContainerProps> {
341345
return helperObject;
342346
}
343347

344-
private executeAction(action: Action, showError = false, obj?: mendix.lib.MxObject): Promise<ActionReturn> {
348+
private _executeAction(action: Action, showError = false, obj?: mendix.lib.MxObject): Promise<ActionReturn> {
345349
this.debug("executeAction", action, obj && obj.getGuid());
346350
const { mxform } = this.props;
347351
const context = getObjectContextFromObjects(obj, this.props.mxObject);
@@ -359,7 +363,7 @@ class TreeView extends Component<TreeViewContainerProps> {
359363
);
360364
}
361365

362-
private debug(...args: unknown[]): void {
366+
private _debug(...args: unknown[]): void {
363367
const id = this.props.friendlyId || this.widgetId;
364368
if (window.logger) {
365369
window.logger.debug(`${id}:`, ...args);

src/components/TreeViewComponent.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, ReactNode, createElement } from "react";
1+
import { Component, ReactNode, createElement, ReactElement } from "react";
22
import { observer } from "mobx-react";
33
import { Tree as ArrayTree } from "array-to-tree";
44
import Tree, { AntTreeNode } from "antd/es/tree";
@@ -116,7 +116,7 @@ export class TreeViewComponent extends Component<TreeViewComponentProps> {
116116
);
117117
}
118118

119-
private renderTreeNodes(data: ArrayTree<TreeObject>[]): ReactNode {
119+
private renderTreeNodes(data: ArrayTree<TreeObject>[]): ReactElement<any>[] {
120120
const { iconIsGlyphicon } = this.props;
121121
return data.map(item => {
122122
let icon: ReactNode | boolean = false;
@@ -130,10 +130,11 @@ export class TreeViewComponent extends Component<TreeViewComponentProps> {
130130
icon = <span className={iconIsGlyphicon ? "glyphicon glyphicon-" + item.icon : item.icon} />;
131131
}
132132

133-
if (item.children) {
133+
if (item.children && item.children.length > 0) {
134+
const children = this.renderTreeNodes(item.children);
134135
return (
135136
<TreeNode key={item.guid} title={item.title} icon={icon} isLeaf={isLeaf} className={extraClass}>
136-
{this.renderTreeNodes(item.children)}
137+
{children}
137138
</TreeNode>
138139
);
139140
}

src/components/__tests__/HelloWorldSample.spec.tsx

Lines changed: 0 additions & 21 deletions
This file was deleted.

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="TreeView" version="1.1.1" xmlns="http://www.mendix.com/clientModule/1.0/">
3+
<clientModule name="TreeView" version="1.2.0" xmlns="http://www.mendix.com/clientModule/1.0/">
44
<widgetFiles>
55
<widgetFile path="TreeView.xml"/>
66
</widgetFiles>

src/store/objects/entry.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import { computed, flow, observable, action, toJS } from "mobx";
2-
import { ReactNode } from "react";
2+
import { ReactNode, ReactElement } from "react";
33
import { EntryObjectAttributes } from "..";
44
import { commitObject } from "@jeltemx/mendix-react-widget-utils";
55

6-
export type TitleMethod = ((obj: mendix.lib.MxObject) => Promise<ReactNode | string>) | null;
6+
export type DynamicTitleMethod = ((obj: mendix.lib.MxObject) => Promise<ReactNode | string>) | null;
7+
export type StaticTitleMethod = ((obj: mendix.lib.MxObject) => ReactElement | string) | null;
78
export type ClassMethod = ((obj: mendix.lib.MxObject) => string) | null;
89

910
export interface TreeObject {
1011
guid: string;
1112
parent: string;
1213
children: string[];
1314
hasChildren: boolean;
14-
title: string;
15+
title: string | ReactNode;
1516
root: boolean;
1617
selected: boolean;
1718
expanded: boolean;
@@ -21,7 +22,8 @@ export interface TreeObject {
2122
}
2223

2324
export interface EntryObjectExtraOptions {
24-
titleMethod?: TitleMethod;
25+
dynamicTitleMethod?: DynamicTitleMethod;
26+
staticTitleMethod?: StaticTitleMethod;
2527
classMethod?: ClassMethod;
2628
isRoot?: boolean;
2729
parent?: string;
@@ -40,7 +42,8 @@ export class EntryObject {
4042
public _changeHandler: (guid?: string, removedCb?: (removed: boolean) => void) => void;
4143

4244
public _attributes: EntryObjectAttributes;
43-
public _titleMethod: TitleMethod;
45+
public _dynamicTitleMethod: DynamicTitleMethod;
46+
public _staticTitleMethod: StaticTitleMethod;
4447
public _classMethod: ClassMethod;
4548

4649
@observable _title: string;
@@ -55,16 +58,16 @@ export class EntryObject {
5558
@observable _isRoot: boolean;
5659

5760
fixTitle = flow(function*(this: EntryObject) {
58-
if (this._titleMethod) {
59-
const title = yield this._titleMethod(this._obj);
61+
if (this._dynamicTitleMethod) {
62+
const title = yield this._dynamicTitleMethod(this._obj);
6063
// @ts-ignore
6164
this._title = title;
6265
}
6366
});
6467

6568
constructor(opts: EntryObjectOptions, attributes: EntryObjectAttributes) {
6669
const { mxObject, changeHandler, extraOpts } = opts;
67-
const { titleMethod, classMethod, isRoot, parent } = extraOpts;
70+
const { staticTitleMethod, dynamicTitleMethod, classMethod, isRoot, parent } = extraOpts;
6871
this._obj = mxObject;
6972

7073
this._title = "";
@@ -77,7 +80,8 @@ export class EntryObject {
7780
this._isLoaded = false;
7881
this._isExpanded = false;
7982
this._isRoot = typeof isRoot !== "undefined" ? isRoot : false;
80-
this._titleMethod = titleMethod || null;
83+
this._dynamicTitleMethod = dynamicTitleMethod || null;
84+
this._staticTitleMethod = staticTitleMethod || null;
8185
this._classMethod = classMethod || null;
8286
this._changeHandler = changeHandler || ((): void => {});
8387
this._subscriptions = [];
@@ -87,8 +91,10 @@ export class EntryObject {
8791
console.warn("No changehandler for ", opts);
8892
}
8993

90-
if (titleMethod) {
94+
if (dynamicTitleMethod) {
9195
this.fixTitle();
96+
} else if (staticTitleMethod) {
97+
this._title = staticTitleMethod(mxObject) as string;
9298
}
9399

94100
if (classMethod) {
@@ -160,7 +166,12 @@ export class EntryObject {
160166
}
161167
} else {
162168
this.setAttributes();
163-
this.fixTitle();
169+
170+
if (this._dynamicTitleMethod) {
171+
this.fixTitle();
172+
} else if (this._staticTitleMethod) {
173+
this._title = this._staticTitleMethod(this._obj) as string;
174+
}
164175
}
165176
});
166177
}

0 commit comments

Comments
 (0)