@singularsystems/neo-react 1.6.2 → 1.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/ReactComponents/Card.d.ts +4 -2
- package/dist/ReactComponents/Card.js +18 -2
- package/dist/ReactComponents/DropDown/AutoCompleteDropDown.d.ts +9 -35
- package/dist/ReactComponents/DropDown/AutoCompleteDropDown.js +26 -110
- package/dist/ReactComponents/DropDown/DropDown.d.ts +19 -22
- package/dist/ReactComponents/DropDown/DropDown.js +50 -126
- package/dist/ReactComponents/DropDown/DropDownBase.d.ts +35 -1
- package/dist/ReactComponents/DropDown/DropDownBase.js +100 -1
- package/dist/ReactComponents/Grid/ButtonColumn.d.ts +8 -4
- package/dist/ReactComponents/Grid/ButtonColumn.js +37 -17
- package/dist/ReactComponents/Grid/Column.d.ts +1 -1
- package/dist/ReactComponents/Grid/Column.js +16 -7
- package/dist/ReactComponents/Grid/ColumnHelper.d.ts +7 -0
- package/dist/ReactComponents/Grid/Row.js +2 -1
- package/package.json +2 -2
- package/styles/Card.scss +19 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
This file details all new features and changes to functionality. If you only need to see changes that require updates to your project, see the [breaking changes](./Breaking.md) readme.
|
|
4
4
|
|
|
5
|
+
## Version 1.6.4 (20 July 2026)
|
|
6
|
+
|
|
7
|
+
- Neo.Card
|
|
8
|
+
- Added `description` prop to neo card.
|
|
9
|
+
- Additional root classes will be rendered when description, or headerElements is specified for more styling options.
|
|
10
|
+
- Drop down
|
|
11
|
+
- Added parent value to `onItemSelected`.
|
|
12
|
+
- Added `nullValue` to better control when a blank item renders.
|
|
13
|
+
- With this change, the basic `Neo.DropDown` component is more explicit with how it decides whether or not to show a blank item.
|
|
14
|
+
Previously if the items list contained an item with any falsy value, then a blank item would not be shown, and the item with the falsy value would be shown if the bound value was null.
|
|
15
|
+
This has changed so that only items with a value of `null` are considered blank items.
|
|
16
|
+
If you need a different value to be considered null, then set the `nullValue` prop.
|
|
17
|
+
- Grid
|
|
18
|
+
- Added `headerProps` and `cellProps` to allow customisation at header / cell level.
|
|
19
|
+
|
|
20
|
+
## Version 1.6.3 (14 July 2026)
|
|
21
|
+
|
|
22
|
+
- Allow `ICardProps` to be referenced.
|
|
23
|
+
|
|
5
24
|
## Version 1.6.2 (10 July 2026)
|
|
6
25
|
|
|
7
26
|
- Routing fix
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React, { JSX } from 'react';
|
|
2
2
|
import { Model } from '@singularsystems/neo-core';
|
|
3
|
-
interface ICardProps {
|
|
3
|
+
export interface ICardProps {
|
|
4
4
|
/** Icon to show next to title in header. */
|
|
5
5
|
icon?: string;
|
|
6
6
|
/** Title to show in header. */
|
|
7
7
|
title?: any;
|
|
8
|
+
/** Description to show below the title. */
|
|
9
|
+
description?: string;
|
|
8
10
|
/** Header elements to show on right hand side of header. */
|
|
9
11
|
headerElements?: JSX.Element;
|
|
10
12
|
/** Footer elements to show on bottom of the card. */
|
|
@@ -24,5 +26,5 @@ export default class Card extends React.Component<ICardProps & React.HTMLProps<H
|
|
|
24
26
|
private iconFactory;
|
|
25
27
|
private expandState;
|
|
26
28
|
render(): JSX.Element;
|
|
29
|
+
private renderTitle;
|
|
27
30
|
}
|
|
28
|
-
export {};
|
|
@@ -15,7 +15,7 @@ var Card = /** @class */ (function (_super) {
|
|
|
15
15
|
return _this;
|
|
16
16
|
}
|
|
17
17
|
Card.prototype.render = function () {
|
|
18
|
-
var _a = this.props, icon = _a.icon, title = _a.title, children = _a.children, headerElements = _a.headerElements, footerContent = _a.footerContent, useCustomScrollbar = _a.useCustomScrollbar, collapsible = _a.collapsible, initiallyCollapsed = _a.initiallyCollapsed, isExpanded = _a.isExpanded, expandIconPosition = _a.expandIconPosition, domProps = __rest(_a, ["icon", "title", "children", "headerElements", "footerContent", "useCustomScrollbar", "collapsible", "initiallyCollapsed", "isExpanded", "expandIconPosition"]);
|
|
18
|
+
var _a = this.props, icon = _a.icon, title = _a.title, description = _a.description, children = _a.children, headerElements = _a.headerElements, footerContent = _a.footerContent, useCustomScrollbar = _a.useCustomScrollbar, collapsible = _a.collapsible, initiallyCollapsed = _a.initiallyCollapsed, isExpanded = _a.isExpanded, expandIconPosition = _a.expandIconPosition, domProps = __rest(_a, ["icon", "title", "description", "children", "headerElements", "footerContent", "useCustomScrollbar", "collapsible", "initiallyCollapsed", "isExpanded", "expandIconPosition"]);
|
|
19
19
|
var className = Utils.joinWithSpaces("neo-card card", domProps.className);
|
|
20
20
|
expandIconPosition !== null && expandIconPosition !== void 0 ? expandIconPosition : (expandIconPosition = "right");
|
|
21
21
|
var isCollapsible = collapsible || isExpanded !== undefined || initiallyCollapsed !== undefined;
|
|
@@ -39,6 +39,12 @@ var Card = /** @class */ (function (_super) {
|
|
|
39
39
|
}
|
|
40
40
|
className += " card-collapsible";
|
|
41
41
|
}
|
|
42
|
+
if (headerElements) {
|
|
43
|
+
className += " card--with-header-elements";
|
|
44
|
+
}
|
|
45
|
+
if (description) {
|
|
46
|
+
className += " card--with-description";
|
|
47
|
+
}
|
|
42
48
|
if (icon && Misc.Settings.icons.shouldSuppress({ icon: icon, component: "card", props: this.props })) {
|
|
43
49
|
icon = undefined;
|
|
44
50
|
}
|
|
@@ -59,10 +65,20 @@ var Card = /** @class */ (function (_super) {
|
|
|
59
65
|
React.createElement("div", { className: "card-header-title" },
|
|
60
66
|
expandIconPosition === "left" && expandIndicator,
|
|
61
67
|
this.iconFactory.getIconComponent(icon),
|
|
62
|
-
|
|
68
|
+
this.renderTitle(title, description)),
|
|
63
69
|
headerElements && React.createElement("div", { className: "card-header-right-section", onClick: function (e) { return e.stopPropagation(); } }, headerElements)),
|
|
64
70
|
content));
|
|
65
71
|
};
|
|
72
|
+
Card.prototype.renderTitle = function (title, description) {
|
|
73
|
+
if (description) {
|
|
74
|
+
return (React.createElement("div", { className: "card-title-section" },
|
|
75
|
+
React.createElement("div", { className: "card-title-text" }, title),
|
|
76
|
+
React.createElement("div", { className: "card-title-description" }, description)));
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return typeof title === "string" ? React.createElement("span", null, title) : title;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
66
82
|
Card = __decorate([
|
|
67
83
|
observer
|
|
68
84
|
], Card);
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import React, { JSX } from 'react';
|
|
2
2
|
import { Model } from '@singularsystems/neo-core';
|
|
3
3
|
import { AxiosPromise } from 'axios';
|
|
4
|
-
import { DropDownBase, ItemSource } from './DropDownBase';
|
|
4
|
+
import { DropDownBase, ICommonDropDownProps, IOption, ItemSource } from './DropDownBase';
|
|
5
5
|
import type { Props, SelectInstance } from 'react-select';
|
|
6
6
|
import { ICommonEditorProps } from '../PropTypes';
|
|
7
7
|
import { FormContext } from '../FormContext';
|
|
8
|
-
interface
|
|
9
|
-
value: string | number;
|
|
10
|
-
label: string;
|
|
11
|
-
item?: T;
|
|
12
|
-
itemParent?: any;
|
|
13
|
-
options?: IOption[];
|
|
14
|
-
}
|
|
15
|
-
interface IAutoCompleteCommonProps<T, TChild = T> extends ICommonEditorProps<SelectInstance>, Props<IOption, true> {
|
|
8
|
+
interface IAutoCompleteCommonProps<T, TChild = T> extends ICommonEditorProps<SelectInstance>, Props<IOption, true>, ICommonDropDownProps<T, TChild> {
|
|
16
9
|
/**
|
|
17
10
|
* Callback for loading data.
|
|
18
11
|
*/
|
|
@@ -56,7 +49,7 @@ interface IAutoCompleteCommonProps<T, TChild = T> extends ICommonEditorProps<Sel
|
|
|
56
49
|
* The removedItem parameter will be provided when removing an item from a multi select drop down.
|
|
57
50
|
* The addedItem parameter will be provided when an item is selected in a multi select drop down. This is the item stored in the bindItems list.
|
|
58
51
|
*/
|
|
59
|
-
onItemSelected?: (item?: TChild, removedItem?: Model.ISelectedItem, addedItem?: Model.ISelectedItem) => void;
|
|
52
|
+
onItemSelected?: (item?: TChild, removedItem?: Model.ISelectedItem, addedItem?: Model.ISelectedItem, parent?: T) => void;
|
|
60
53
|
/**
|
|
61
54
|
* Millisecond delay from the last typed character, to when the itemSource function is called.
|
|
62
55
|
* Default is 500ms.
|
|
@@ -67,20 +60,12 @@ interface IAutoCompleteCommonProps<T, TChild = T> extends ICommonEditorProps<Sel
|
|
|
67
60
|
* Default is 1.
|
|
68
61
|
*/
|
|
69
62
|
minCharacters?: number;
|
|
70
|
-
/**
|
|
71
|
-
* The group member to use as the display for grouped items.
|
|
72
|
-
*/
|
|
73
|
-
groupDisplayMember?: NoInfer<keyof T>;
|
|
74
|
-
/**
|
|
75
|
-
* Name of the property on the parent which contains a child list.
|
|
76
|
-
*/
|
|
77
|
-
childListMember?: NoInfer<keyof T>;
|
|
78
63
|
}
|
|
79
|
-
export interface IAutoCompleteProps {
|
|
64
|
+
export interface IAutoCompleteProps<T, TChild> extends IAutoCompleteCommonProps<T, TChild> {
|
|
80
65
|
bind: Model.IPropertyInstance;
|
|
81
66
|
bindDisplay?: Model.IPropertyInstance;
|
|
82
67
|
}
|
|
83
|
-
export interface IAutoCompleteMultiSelectProps {
|
|
68
|
+
export interface IAutoCompleteMultiSelectProps<T, TChild = T> extends IAutoCompleteCommonProps<T, TChild> {
|
|
84
69
|
/**
|
|
85
70
|
* A list of ids and labels to use as the selected list.
|
|
86
71
|
*/
|
|
@@ -95,31 +80,20 @@ export interface IAutoCompleteMultiSelectProps {
|
|
|
95
80
|
*/
|
|
96
81
|
fieldInfoLimit?: number;
|
|
97
82
|
}
|
|
98
|
-
export default class AutoCompleteDropDown<T, TChild = T> extends DropDownBase<T,
|
|
83
|
+
export default class AutoCompleteDropDown<T, TChild = T> extends DropDownBase<T, TChild, IAutoCompleteProps<T, TChild> | IAutoCompleteMultiSelectProps<T, TChild>> {
|
|
99
84
|
static contextType: React.Context<import("../FormContext").FormContextParams>;
|
|
100
85
|
context: React.ContextType<typeof FormContext>;
|
|
101
86
|
private asyncSelectImplementation;
|
|
102
87
|
private selectImplementation;
|
|
103
|
-
constructor(props:
|
|
88
|
+
constructor(props: IAutoCompleteProps<T, TChild> | IAutoCompleteMultiSelectProps<T, TChild>);
|
|
104
89
|
private bindProperty;
|
|
105
90
|
private bindIdsList?;
|
|
106
91
|
private bindIdsProperty?;
|
|
107
|
-
static getBindProp<TChild>(props: IAutoCompleteProps | IAutoCompleteMultiSelectProps): Model.IPropertyInstance<any>;
|
|
92
|
+
static getBindProp<T, TChild>(props: IAutoCompleteProps<T, TChild> | IAutoCompleteMultiSelectProps<T, TChild>): Model.IPropertyInstance<any>;
|
|
93
|
+
protected get commonProps(): ICommonDropDownProps<T, TChild>;
|
|
108
94
|
private onKeyPress;
|
|
109
95
|
private setBindProperty;
|
|
110
|
-
private mapTArrayToOptions;
|
|
111
|
-
private mapChildItemsToOptions;
|
|
112
|
-
private getGroupedOptionsFromItems;
|
|
113
|
-
/**
|
|
114
|
-
* Finds an option in the items list by value.
|
|
115
|
-
* Handles both flat lists and grouped (nested) items.
|
|
116
|
-
* @param items The items array to search in
|
|
117
|
-
* @param value The value to search for
|
|
118
|
-
* @returns The matching IOption or undefined if not found
|
|
119
|
-
*/
|
|
120
|
-
private findOptionByValue;
|
|
121
96
|
private onItemSelected;
|
|
122
|
-
private get isGrouped();
|
|
123
97
|
render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | JSX.Element | null | undefined;
|
|
124
98
|
private getOption;
|
|
125
99
|
}
|
|
@@ -22,6 +22,13 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
22
22
|
var _a;
|
|
23
23
|
return (_a = props.bind) !== null && _a !== void 0 ? _a : props.bindItems;
|
|
24
24
|
};
|
|
25
|
+
Object.defineProperty(AutoCompleteDropDown.prototype, "commonProps", {
|
|
26
|
+
get: function () {
|
|
27
|
+
return this.props;
|
|
28
|
+
},
|
|
29
|
+
enumerable: false,
|
|
30
|
+
configurable: true
|
|
31
|
+
});
|
|
25
32
|
AutoCompleteDropDown.prototype.onKeyPress = function (searchValue, dataReceived) {
|
|
26
33
|
var _this = this;
|
|
27
34
|
var _a, _b;
|
|
@@ -35,7 +42,7 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
35
42
|
else {
|
|
36
43
|
items = list;
|
|
37
44
|
}
|
|
38
|
-
dataReceived(_this.
|
|
45
|
+
dataReceived(_this.mapItemsToOptions((items).slice()));
|
|
39
46
|
});
|
|
40
47
|
}, (_b = this.props.delayMs) !== null && _b !== void 0 ? _b : 500);
|
|
41
48
|
}
|
|
@@ -67,73 +74,9 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
};
|
|
70
|
-
AutoCompleteDropDown.prototype.mapTArrayToOptions = function (items) {
|
|
71
|
-
if (this.isGrouped) {
|
|
72
|
-
var firstChildItem = this.getFirstChildItem(items, this.props.childListMember);
|
|
73
|
-
if (firstChildItem) {
|
|
74
|
-
this.findMembers(firstChildItem);
|
|
75
|
-
}
|
|
76
|
-
return this.getGroupedOptionsFromItems(items);
|
|
77
|
-
}
|
|
78
|
-
if (items.length) {
|
|
79
|
-
this.findMembers(items[0]);
|
|
80
|
-
}
|
|
81
|
-
return this.mapChildItemsToOptions(items);
|
|
82
|
-
};
|
|
83
|
-
AutoCompleteDropDown.prototype.mapChildItemsToOptions = function (childItems, parentItem) {
|
|
84
|
-
var _this = this;
|
|
85
|
-
return childItems.map(function (childItem) { return ({
|
|
86
|
-
item: childItem,
|
|
87
|
-
itemParent: parentItem,
|
|
88
|
-
value: childItem[_this.valueMember],
|
|
89
|
-
label: childItem[_this.displayMember]
|
|
90
|
-
}); });
|
|
91
|
-
};
|
|
92
|
-
AutoCompleteDropDown.prototype.getGroupedOptionsFromItems = function (groupedItems) {
|
|
93
|
-
var _this = this;
|
|
94
|
-
var groupedOptions = groupedItems.map(function (groupItem) {
|
|
95
|
-
var childOptions = _this.mapChildItemsToOptions(groupItem[_this.props.childListMember], groupItem);
|
|
96
|
-
return {
|
|
97
|
-
item: groupItem,
|
|
98
|
-
itemParent: null,
|
|
99
|
-
label: groupItem[_this.props.groupDisplayMember],
|
|
100
|
-
options: childOptions
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
return groupedOptions;
|
|
104
|
-
};
|
|
105
|
-
/**
|
|
106
|
-
* Finds an option in the items list by value.
|
|
107
|
-
* Handles both flat lists and grouped (nested) items.
|
|
108
|
-
* @param items The items array to search in
|
|
109
|
-
* @param value The value to search for
|
|
110
|
-
* @returns The matching IOption or undefined if not found
|
|
111
|
-
*/
|
|
112
|
-
AutoCompleteDropDown.prototype.findOptionByValue = function (items, value) {
|
|
113
|
-
if (!items) {
|
|
114
|
-
return undefined;
|
|
115
|
-
}
|
|
116
|
-
if (this.isGrouped) {
|
|
117
|
-
// For grouped items, search within child options of each group
|
|
118
|
-
for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
|
|
119
|
-
var group = items_1[_i];
|
|
120
|
-
if (group.options) {
|
|
121
|
-
var childMatch = group.options.find(function (option) { return option.value === value; });
|
|
122
|
-
if (childMatch) {
|
|
123
|
-
return childMatch;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return undefined;
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
// For flat items, search directly
|
|
131
|
-
return items.find(function (item) { return item.value === value; });
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
77
|
AutoCompleteDropDown.prototype.onItemSelected = function (args, action) {
|
|
135
|
-
var _a;
|
|
136
|
-
var
|
|
78
|
+
var _a, _b;
|
|
79
|
+
var singleProps = this.props, multiProps = this.props;
|
|
137
80
|
if (multiProps.bindItems) {
|
|
138
81
|
var itemsProperty = multiProps.bindItems;
|
|
139
82
|
// Multi select
|
|
@@ -144,8 +87,8 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
144
87
|
if (this.bindIdsList) {
|
|
145
88
|
this.bindIdsList.push(action.option.value);
|
|
146
89
|
}
|
|
147
|
-
if (onItemSelected) {
|
|
148
|
-
onItemSelected((_a = action.option) === null || _a === void 0 ? void 0 : _a.item, undefined, newItem);
|
|
90
|
+
if (multiProps.onItemSelected) {
|
|
91
|
+
multiProps.onItemSelected((_a = action.option) === null || _a === void 0 ? void 0 : _a.item, undefined, newItem, (_b = action.option) === null || _b === void 0 ? void 0 : _b.itemParent);
|
|
149
92
|
}
|
|
150
93
|
}
|
|
151
94
|
else if (action.action === "remove-value") {
|
|
@@ -156,8 +99,8 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
156
99
|
this.bindIdsList.remove(removeItem.id);
|
|
157
100
|
}
|
|
158
101
|
}
|
|
159
|
-
if (onItemSelected) {
|
|
160
|
-
onItemSelected(undefined, removeItem);
|
|
102
|
+
if (multiProps.onItemSelected) {
|
|
103
|
+
multiProps.onItemSelected(undefined, removeItem);
|
|
161
104
|
}
|
|
162
105
|
}
|
|
163
106
|
else if (action.action === "clear") {
|
|
@@ -165,8 +108,8 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
165
108
|
if (this.bindIdsList) {
|
|
166
109
|
this.bindIdsList.length = 0;
|
|
167
110
|
}
|
|
168
|
-
if (onItemSelected) {
|
|
169
|
-
onItemSelected(undefined);
|
|
111
|
+
if (multiProps.onItemSelected) {
|
|
112
|
+
multiProps.onItemSelected(undefined);
|
|
170
113
|
}
|
|
171
114
|
}
|
|
172
115
|
itemsProperty.attachedTo.isSelfDirty = true;
|
|
@@ -177,18 +120,11 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
177
120
|
if (singleProps.bindDisplay) {
|
|
178
121
|
singleProps.bindDisplay.value = args ? args.label : "";
|
|
179
122
|
}
|
|
180
|
-
if (onItemSelected) {
|
|
181
|
-
onItemSelected(args === null || args === void 0 ? void 0 : args.item);
|
|
123
|
+
if (singleProps.onItemSelected) {
|
|
124
|
+
singleProps.onItemSelected(args === null || args === void 0 ? void 0 : args.item, undefined, undefined, args === null || args === void 0 ? void 0 : args.itemParent);
|
|
182
125
|
}
|
|
183
126
|
}
|
|
184
127
|
};
|
|
185
|
-
Object.defineProperty(AutoCompleteDropDown.prototype, "isGrouped", {
|
|
186
|
-
get: function () {
|
|
187
|
-
return this.props.groupDisplayMember !== undefined && this.props.childListMember !== undefined;
|
|
188
|
-
},
|
|
189
|
-
enumerable: false,
|
|
190
|
-
configurable: true
|
|
191
|
-
});
|
|
192
128
|
AutoCompleteDropDown.prototype.render = function () {
|
|
193
129
|
var _this = this;
|
|
194
130
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
@@ -210,40 +146,20 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
210
146
|
}
|
|
211
147
|
var defaultItems = undefined;
|
|
212
148
|
if (this.props.items) {
|
|
213
|
-
var
|
|
149
|
+
var items_1 = [];
|
|
214
150
|
if (this.isGrouped) {
|
|
215
|
-
|
|
216
|
-
defaultItems = this.
|
|
151
|
+
items_1 = this.getItems(this.props.items);
|
|
152
|
+
defaultItems = this.mapGroupedItemsToOptions(items_1);
|
|
217
153
|
}
|
|
218
154
|
else {
|
|
219
|
-
|
|
220
|
-
defaultItems = this.
|
|
155
|
+
items_1 = this.getItems(this.props.items);
|
|
156
|
+
defaultItems = this.mapItemsToOptions(items_1);
|
|
221
157
|
}
|
|
222
158
|
if (filterPredicate !== undefined) {
|
|
223
|
-
|
|
224
|
-
var groupsWithFilteredChildren = defaultItems.map(function (group) { return (__assign(__assign({}, group), { options: group.options.filter(function (option) {
|
|
225
|
-
if (bindValue) {
|
|
226
|
-
return bindValue.value === option.value || filterPredicate(option.item, option.itemParent);
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
return filterPredicate(option.item, option.itemParent);
|
|
230
|
-
}
|
|
231
|
-
}) })); });
|
|
232
|
-
// Remove groups that have no children after filtering
|
|
233
|
-
defaultItems = groupsWithFilteredChildren.filter(function (group) { return group.options.length > 0; });
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
if (bindValue) {
|
|
237
|
-
// Dont filter out the current selected item even if excluded by the filter.
|
|
238
|
-
defaultItems = defaultItems.filter(function (option) { return bindValue.value === option.value || filterPredicate(option.item, option.itemParent); });
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
defaultItems = defaultItems.filter(function (option) { return filterPredicate(option.item, option.itemParent); });
|
|
242
|
-
}
|
|
243
|
-
}
|
|
159
|
+
defaultItems = this.filterOptions(defaultItems, filterPredicate, bindValue);
|
|
244
160
|
}
|
|
245
|
-
if (descriptionMember === undefined &&
|
|
246
|
-
if (EnumHelper.isEnumItem(
|
|
161
|
+
if (descriptionMember === undefined && items_1.length > 0) {
|
|
162
|
+
if (EnumHelper.isEnumItem(items_1[0])) {
|
|
247
163
|
descriptionMember = "description";
|
|
248
164
|
}
|
|
249
165
|
}
|
|
@@ -1,56 +1,53 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { IBindableEditorProps } from '../PropTypes';
|
|
3
3
|
import { Data } from '@singularsystems/neo-core';
|
|
4
|
-
import { DropDownBase } from './DropDownBase';
|
|
4
|
+
import { DropDownBase, ICommonDropDownProps } from './DropDownBase';
|
|
5
5
|
import { FormContext } from '../FormContext';
|
|
6
|
-
export interface IDropDownSpecificProps<T, TChild = T> {
|
|
6
|
+
export interface IDropDownSpecificProps<T, TChild = T> extends ICommonDropDownProps<T, TChild> {
|
|
7
7
|
items?: T[] | Promise<T[]>;
|
|
8
8
|
itemSource?: Data.IAsyncDataSource<T[]> | Data.IArrayCacheEntry<T>;
|
|
9
9
|
valueMember?: NoInfer<keyof TChild>;
|
|
10
10
|
displayMember?: NoInfer<keyof TChild>;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Same as `allowDefault`.
|
|
13
|
+
* Set to true if the user should be able to de-select an item, and set the bound value to the `defaultValue`. This will show a default item in the list.
|
|
14
14
|
*/
|
|
15
15
|
allowNulls?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Set to true if the user should be able to de-select an item, and set the bound value to the `defaultValue`. This will show a default item in the list.
|
|
18
|
+
*/
|
|
19
|
+
allowDefault?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Value considered default. E.g. if allowDefault is true, then selecting the default item will set the bound value to this value. Defaults to `null`.
|
|
22
|
+
*/
|
|
23
|
+
defaultValue?: any;
|
|
16
24
|
/** Function used to filter items out of the datasource. */
|
|
17
25
|
filterPredicate?: (item: TChild, itemParent?: T) => boolean;
|
|
18
26
|
/** Callback which fires when an item is selected. */
|
|
19
|
-
onItemSelected?: (item?: TChild) => void;
|
|
27
|
+
onItemSelected?: (item?: TChild, parent?: T) => void;
|
|
20
28
|
/**
|
|
21
29
|
* True if the display member of the selected item should display as plain text.
|
|
22
30
|
* Use this if you need a readonly display, and don't want a form control rendered.
|
|
23
31
|
*/
|
|
24
32
|
renderAsText?: boolean;
|
|
25
|
-
/** Text to display when the bound value is
|
|
33
|
+
/** Text to display when the bound value is the default value, and there is no item with this value. */
|
|
26
34
|
nullText?: string;
|
|
27
|
-
/** Text to display as the first item in the drop down list when the user is allowed to select a
|
|
35
|
+
/** Text to display as the first item in the drop down list when the user is allowed to select a default item. */
|
|
28
36
|
deSelectText?: string;
|
|
29
37
|
/** Set to true if the property should be sorted by value instead of display text. */
|
|
30
38
|
sortByValue?: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* The group member to use as the display for grouped items.
|
|
33
|
-
*/
|
|
34
|
-
groupDisplayMember?: NoInfer<keyof T>;
|
|
35
|
-
/**
|
|
36
|
-
* The child list containing the grouped items.
|
|
37
|
-
*/
|
|
38
|
-
childListMember?: NoInfer<keyof T>;
|
|
39
39
|
}
|
|
40
40
|
export interface IDropDownProps<T, TChild = T> extends IBindableEditorProps<HTMLSelectElement> {
|
|
41
41
|
select: IDropDownSpecificProps<T, TChild>;
|
|
42
42
|
}
|
|
43
|
-
export default class DropDown<T, TChild = T> extends DropDownBase<T, IDropDownProps<T, TChild
|
|
43
|
+
export default class DropDown<T, TChild = T> extends DropDownBase<T, TChild, IDropDownProps<T, TChild>> {
|
|
44
44
|
static contextType: React.Context<import("../FormContext").FormContextParams>;
|
|
45
45
|
context: React.ContextType<typeof FormContext>;
|
|
46
|
-
private
|
|
46
|
+
private allOptions;
|
|
47
|
+
private selectedOption;
|
|
47
48
|
private sortByValue?;
|
|
48
|
-
private listIndexSymbol;
|
|
49
|
-
private get isGrouped();
|
|
50
49
|
constructor(props: IDropDownProps<T, TChild>);
|
|
51
|
-
|
|
52
|
-
private get groupedItems();
|
|
53
|
-
private createLookupIndex;
|
|
50
|
+
protected get commonProps(): ICommonDropDownProps<T, TChild>;
|
|
54
51
|
private getSelectedOption;
|
|
55
52
|
private onItemSelected;
|
|
56
53
|
render(): React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.JSX.Element;
|
|
@@ -10,130 +10,61 @@ var DropDown = /** @class */ (function (_super) {
|
|
|
10
10
|
__extends(DropDown, _super);
|
|
11
11
|
function DropDown(props) {
|
|
12
12
|
var _this = _super.call(this, props) || this;
|
|
13
|
-
_this.
|
|
13
|
+
_this.allOptions = [];
|
|
14
|
+
_this.selectedOption = null;
|
|
14
15
|
_this.onItemSelected = _this.onItemSelected.bind(_this);
|
|
15
16
|
_this.fieldInfoContainer = Model.ModelFieldInfo.asModelFieldInfoContainer(_this.props.bind.attachedTo);
|
|
16
17
|
return _this;
|
|
17
18
|
}
|
|
18
|
-
Object.defineProperty(DropDown.prototype, "
|
|
19
|
+
Object.defineProperty(DropDown.prototype, "commonProps", {
|
|
19
20
|
get: function () {
|
|
20
|
-
return this.props.select
|
|
21
|
-
&& this.props.select.childListMember !== undefined;
|
|
21
|
+
return this.props.select;
|
|
22
22
|
},
|
|
23
23
|
enumerable: false,
|
|
24
24
|
configurable: true
|
|
25
25
|
});
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
var _this = this;
|
|
29
|
-
var _a, _b;
|
|
30
|
-
var items = [];
|
|
31
|
-
if (this.isGrouped) {
|
|
32
|
-
var groups = this.getItems((_a = this.props.select.items) !== null && _a !== void 0 ? _a : this.props.select.itemSource);
|
|
33
|
-
var firstChildItem = this.getFirstChildItem(groups, this.props.select.childListMember);
|
|
34
|
-
if (firstChildItem) {
|
|
35
|
-
this.findMembers(firstChildItem);
|
|
36
|
-
}
|
|
37
|
-
items = groups.flatMap(function (group) { return group[_this.props.select.childListMember]; });
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
items = this.getItems((_b = this.props.select.items) !== null && _b !== void 0 ? _b : this.props.select.itemSource);
|
|
41
|
-
if (items && items.length > 0) {
|
|
42
|
-
var item = items[0];
|
|
43
|
-
this.findMembers(item);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
if (this.props.select.filterPredicate !== undefined) {
|
|
47
|
-
return items.filter(function (item) { return _this.props.bind.value === item[_this.valueMember] || _this.props.select.filterPredicate(item, undefined); });
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
return items;
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
enumerable: false,
|
|
54
|
-
configurable: true
|
|
55
|
-
});
|
|
56
|
-
Object.defineProperty(DropDown.prototype, "groupedItems", {
|
|
57
|
-
get: function () {
|
|
58
|
-
var _this = this;
|
|
59
|
-
var _a;
|
|
60
|
-
var groups = this.getItems((_a = this.props.select.items) !== null && _a !== void 0 ? _a : this.props.select.itemSource);
|
|
61
|
-
var firstChildItem = this.getFirstChildItem(groups, this.props.select.childListMember);
|
|
62
|
-
if (firstChildItem) {
|
|
63
|
-
this.findMembers(firstChildItem);
|
|
64
|
-
}
|
|
65
|
-
// Handle grouped filtering - filter children in each group
|
|
66
|
-
var groupsWithFilteredChildren = groups.map(function (group) {
|
|
67
|
-
var children = group[_this.props.select.childListMember];
|
|
68
|
-
if (_this.props.select.filterPredicate !== undefined) {
|
|
69
|
-
return __assign(__assign({}, group), { options: children.filter(function (item) { return _this.props.bind.value === (item)[_this.valueMember] || _this.props.select.filterPredicate(item, group); }) });
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
return __assign(__assign({}, group), { options: children });
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
// Remove groups that have no children after filtering
|
|
76
|
-
return groupsWithFilteredChildren.filter(function (group) { return group.options.length > 0; });
|
|
77
|
-
},
|
|
78
|
-
enumerable: false,
|
|
79
|
-
configurable: true
|
|
80
|
-
});
|
|
81
|
-
DropDown.prototype.createLookupIndex = function (list) {
|
|
82
|
-
var _this = this;
|
|
83
|
-
var index = {};
|
|
84
|
-
//@ts-ignore
|
|
85
|
-
list[this.listIndexSymbol] = index;
|
|
86
|
-
list.forEach(function (item) { return index[item[_this.valueMember]] = item; });
|
|
87
|
-
return index;
|
|
88
|
-
};
|
|
89
|
-
DropDown.prototype.getSelectedOption = function (value, items) {
|
|
26
|
+
DropDown.prototype.getSelectedOption = function (value) {
|
|
27
|
+
var _a, _b, _c;
|
|
90
28
|
if (!this.sortByValue) {
|
|
91
29
|
this.props.bind.propertyInfo.hasSortValue = true;
|
|
92
30
|
}
|
|
93
|
-
if (!this.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
var index = list[this.listIndexSymbol];
|
|
97
|
-
var indexJustCreated = false;
|
|
98
|
-
if (!index) {
|
|
99
|
-
index = this.createLookupIndex(list);
|
|
100
|
-
indexJustCreated = true;
|
|
101
|
-
}
|
|
102
|
-
this.selectedItem = index[value];
|
|
103
|
-
if (value && !this.selectedItem && !indexJustCreated) {
|
|
104
|
-
// Index may be out of date.
|
|
105
|
-
index = this.createLookupIndex(list);
|
|
106
|
-
this.selectedItem = index[value];
|
|
107
|
-
}
|
|
108
|
-
if (!this.selectedItem) {
|
|
109
|
-
// create default item.
|
|
110
|
-
this.selectedItem = {};
|
|
111
|
-
this.selectedItem[this.displayMember] = "";
|
|
112
|
-
this.selectedItem[this.valueMember] = null;
|
|
113
|
-
}
|
|
114
|
-
var displayValue = this.selectedItem[this.displayMember];
|
|
31
|
+
if (!this.selectedOption || this.selectedOption.value != value) {
|
|
32
|
+
this.selectedOption = (_a = this.findOptionByValue(this.allOptions, value)) !== null && _a !== void 0 ? _a : null;
|
|
33
|
+
var displayValue = (_c = (_b = this.selectedOption) === null || _b === void 0 ? void 0 : _b.label) !== null && _c !== void 0 ? _c : "";
|
|
115
34
|
this.setFieldInfo(this.props.bind, displayValue);
|
|
116
35
|
this.props.bind.sortValue = this.sortByValue ? value : displayValue;
|
|
117
36
|
}
|
|
118
|
-
return this.
|
|
37
|
+
return this.selectedOption;
|
|
119
38
|
};
|
|
120
39
|
DropDown.prototype.onItemSelected = function (e) {
|
|
121
|
-
this.
|
|
122
|
-
var
|
|
123
|
-
|
|
40
|
+
this.selectedOption = null;
|
|
41
|
+
var value = e.target.value;
|
|
42
|
+
var parsedValue = parseInt(e.target.value);
|
|
43
|
+
if (!isNaN(parsedValue)) {
|
|
44
|
+
value = parsedValue;
|
|
45
|
+
}
|
|
46
|
+
var selectedOption = this.getSelectedOption(value);
|
|
47
|
+
if (!selectedOption && (value === "false" || value === "true")) {
|
|
48
|
+
selectedOption = this.getSelectedOption(value === "true");
|
|
49
|
+
}
|
|
50
|
+
if (selectedOption) {
|
|
124
51
|
// Use the bound item to get the correct data type of the value member;
|
|
125
|
-
this.props.bind.value =
|
|
52
|
+
this.props.bind.value = selectedOption.value;
|
|
126
53
|
}
|
|
127
54
|
else {
|
|
128
|
-
this.props.bind.value =
|
|
55
|
+
this.props.bind.value = this.defaultItemValue;
|
|
129
56
|
}
|
|
130
57
|
if (this.props.select.onItemSelected !== undefined) {
|
|
131
|
-
|
|
58
|
+
if (selectedOption) {
|
|
59
|
+
this.props.select.onItemSelected(selectedOption.item, selectedOption.itemParent);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.props.select.onItemSelected(undefined, undefined);
|
|
63
|
+
}
|
|
132
64
|
}
|
|
133
65
|
};
|
|
134
66
|
DropDown.prototype.render = function () {
|
|
135
|
-
var
|
|
136
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
67
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
137
68
|
var splitProps = BindPropsHelper.normaliseEditorProps(this, this.props);
|
|
138
69
|
var domProps = BindPropsHelper.autoSetDomProperties(splitProps, this.context);
|
|
139
70
|
domProps.className = Utils.joinWithSpaces(domProps.className, splitProps.isBootstrap ? "form-control form-select" : "neo-forms-editor");
|
|
@@ -146,51 +77,44 @@ var DropDown = /** @class */ (function (_super) {
|
|
|
146
77
|
}
|
|
147
78
|
var displayInfo = this.props.bind.validator.getDisplayState(this.context.validationDisplayMode);
|
|
148
79
|
displayInfo.applyToDom(domProps, !splitProps.inGroup);
|
|
149
|
-
|
|
150
|
-
|
|
80
|
+
this.defaultItemValue = (_c = (_b = splitProps.select) === null || _b === void 0 ? void 0 : _b.defaultValue) !== null && _c !== void 0 ? _c : null;
|
|
81
|
+
this.allOptions = this.mapItemsToOptions(this.getItems((_d = this.props.select.items) !== null && _d !== void 0 ? _d : this.props.select.itemSource));
|
|
82
|
+
var options = this.allOptions;
|
|
83
|
+
var selectedOption = this.getSelectedOption(this.props.bind.value); // This sets the sort value to allow sorting of drop downs in grids.
|
|
151
84
|
var value = this.props.bind.value;
|
|
152
|
-
var valueIsEmpty = !value;
|
|
153
|
-
var notFound =
|
|
154
|
-
var
|
|
155
|
-
|
|
156
|
-
// If there is an item with a null value, don't add a blank drop down item.
|
|
157
|
-
addBlankItem = false;
|
|
158
|
-
}
|
|
85
|
+
var valueIsEmpty = ((_e = splitProps.select) === null || _e === void 0 ? void 0 : _e.defaultValue) !== undefined ? (value === splitProps.select.defaultValue) : !value;
|
|
86
|
+
var notFound = options.length > 0 && !valueIsEmpty && (selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.value) !== value;
|
|
87
|
+
var allowDefault = (_j = (_g = (_f = splitProps.select) === null || _f === void 0 ? void 0 : _f.allowDefault) !== null && _g !== void 0 ? _g : (_h = splitProps.select) === null || _h === void 0 ? void 0 : _h.allowNulls) !== null && _j !== void 0 ? _j : this.props.bind.propertyInfo.allowNulls;
|
|
88
|
+
var addDefaultItem = (!this.hasDefaultItem && (allowDefault || valueIsEmpty)) || notFound;
|
|
159
89
|
var control;
|
|
160
90
|
if (this.isLoading) {
|
|
161
91
|
control = React.createElement("div", { className: "form-control form-control-loading" },
|
|
162
92
|
React.createElement("div", { className: "spinner-border" }));
|
|
163
93
|
}
|
|
164
|
-
else if ((
|
|
165
|
-
control = React.createElement("span", null,
|
|
94
|
+
else if ((_k = splitProps.select) === null || _k === void 0 ? void 0 : _k.renderAsText) {
|
|
95
|
+
control = React.createElement("span", null, selectedOption ? selectedOption.label : "");
|
|
166
96
|
}
|
|
167
97
|
else if (splitProps.editor.isReadOnly) {
|
|
168
|
-
control = React.createElement("input", __assign({ type: "text", value:
|
|
98
|
+
control = React.createElement("input", __assign({ type: "text", value: selectedOption ? selectedOption.label : "", ref: splitProps.editor.inputElement }, domProps));
|
|
169
99
|
}
|
|
170
100
|
else {
|
|
171
101
|
if (domProps.readOnly) {
|
|
172
102
|
domProps.disabled = true;
|
|
173
103
|
}
|
|
174
|
-
var
|
|
175
|
-
var nullText = (
|
|
176
|
-
if (
|
|
104
|
+
var valueIsDefault = value === undefined || value === this.defaultItemValue;
|
|
105
|
+
var nullText = (valueIsDefault || ((_l = splitProps.select) === null || _l === void 0 ? void 0 : _l.deSelectText) === undefined) ? (_m = splitProps.select) === null || _m === void 0 ? void 0 : _m.nullText : (_o = splitProps.select) === null || _o === void 0 ? void 0 : _o.deSelectText;
|
|
106
|
+
if (valueIsDefault) {
|
|
177
107
|
domProps.className = Utils.joinWithSpaces(domProps.className, "select-no-value");
|
|
178
108
|
}
|
|
179
|
-
var
|
|
180
|
-
var groupDisplayMember_1;
|
|
181
|
-
if (this.isGrouped) {
|
|
182
|
-
childListMember = this.props.select.childListMember;
|
|
183
|
-
groupDisplayMember_1 = this.props.select.groupDisplayMember;
|
|
184
|
-
}
|
|
109
|
+
var filteredOptions = ((_p = splitProps.select) === null || _p === void 0 ? void 0 : _p.filterPredicate) === undefined ? options : this.filterOptions(options, splitProps.select.filterPredicate, this.props.bind);
|
|
185
110
|
control =
|
|
186
|
-
React.createElement("select", __assign({ value:
|
|
187
|
-
|
|
111
|
+
React.createElement("select", __assign({ value: value !== null && value !== void 0 ? value : "", onChange: this.onItemSelected, ref: splitProps.editor.inputElement }, domProps),
|
|
112
|
+
addDefaultItem && React.createElement("option", { className: "option-default" }, notFound ? "(Not found): ".concat(value) : nullText),
|
|
188
113
|
!this.isGrouped &&
|
|
189
|
-
|
|
114
|
+
filteredOptions.map(function (option) { return (React.createElement("option", { value: option.value, key: option.value }, option.label)); }),
|
|
190
115
|
this.isGrouped &&
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return React.createElement("optgroup", { label: group[groupDisplayMember_1], key: group[groupDisplayMember_1] }, (children.map(function (item) { return (React.createElement("option", { value: item[_this.valueMember], key: item[_this.valueMember] }, item[_this.displayMember])); })));
|
|
116
|
+
filteredOptions.map(function (group) {
|
|
117
|
+
return React.createElement("optgroup", { label: group.label, key: group.label }, (group.options.map(function (item) { return (React.createElement("option", { value: item.value, key: item.value }, item.label)); })));
|
|
194
118
|
}));
|
|
195
119
|
}
|
|
196
120
|
return (InputHelpers.surroundWithInputGroup(control, splitProps.editor, domProps));
|
|
@@ -1,15 +1,49 @@
|
|
|
1
1
|
import { Data, Model } from '@singularsystems/neo-core';
|
|
2
2
|
import ComponentBase from '../ComponentBase';
|
|
3
3
|
export type ItemSource<T> = T[] | Promise<T[]> | Data.IAsyncDataSource<T[]> | Data.IArrayCacheEntry<T>;
|
|
4
|
-
export
|
|
4
|
+
export interface IOption<T = any> {
|
|
5
|
+
value: string | number;
|
|
6
|
+
label: string;
|
|
7
|
+
item?: T;
|
|
8
|
+
itemParent?: any;
|
|
9
|
+
options?: IOption[];
|
|
10
|
+
}
|
|
11
|
+
export interface ICommonDropDownProps<T, TChild = T> {
|
|
12
|
+
/**
|
|
13
|
+
* The group member to use as the display for grouped items.
|
|
14
|
+
*/
|
|
15
|
+
groupDisplayMember?: NoInfer<keyof T>;
|
|
16
|
+
/**
|
|
17
|
+
* Name of the property on the parent which contains a child list.
|
|
18
|
+
*/
|
|
19
|
+
childListMember?: NoInfer<keyof T>;
|
|
20
|
+
}
|
|
21
|
+
export declare abstract class DropDownBase<T, TChild, TProps> extends ComponentBase<TProps> {
|
|
5
22
|
protected valueMember: keyof TChild;
|
|
6
23
|
protected displayMember: keyof TChild;
|
|
24
|
+
protected defaultItemValue: any;
|
|
25
|
+
protected hasDefaultItem: boolean;
|
|
7
26
|
protected findMembers(item: any): void;
|
|
8
27
|
protected isLoading: boolean;
|
|
9
28
|
protected dataSource: Data.IAsyncDataSource<T[]> | null;
|
|
10
29
|
protected cachedDataSource: Data.IDataCacheEntry | null;
|
|
11
30
|
protected fieldInfoContainer: Model.IModelFieldInfoContainer | null;
|
|
12
31
|
protected getItems(itemSource: ItemSource<T>): T[];
|
|
32
|
+
/** Returns either a flat list, or grouped options based on the provided props. */
|
|
33
|
+
protected mapItemsToOptions(items: T[]): IOption[];
|
|
34
|
+
protected mapGroupedItemsToOptions(groupedItems: T[]): IOption<any>[];
|
|
35
|
+
private mapChildItemsToOptions;
|
|
36
|
+
/**
|
|
37
|
+
* Finds an option in the items list by value.
|
|
38
|
+
* Handles both flat lists and grouped (nested) items.
|
|
39
|
+
* @param items The items array to search in
|
|
40
|
+
* @param value The value to search for
|
|
41
|
+
* @returns The matching IOption or undefined if not found
|
|
42
|
+
*/
|
|
43
|
+
protected findOptionByValue(items: IOption[] | undefined, value: string | number | boolean): IOption | undefined;
|
|
44
|
+
protected filterOptions(options: IOption[], filterPredicate: (item: TChild, itemParent?: T) => boolean, bindProperty: Model.IPropertyInstance | undefined): IOption<any>[];
|
|
45
|
+
protected abstract get commonProps(): ICommonDropDownProps<T, TChild>;
|
|
46
|
+
protected get isGrouped(): boolean;
|
|
13
47
|
afterRender(isInitial: boolean): Promise<void>;
|
|
14
48
|
private fieldDisplayInfo;
|
|
15
49
|
protected setFieldInfo(bindProperty: Model.IPropertyInstance, displayValue: string, readableName?: string): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __awaiter, __extends, __generator } from "tslib";
|
|
1
|
+
import { __assign, __awaiter, __extends, __generator } from "tslib";
|
|
2
2
|
import { Data } from '@singularsystems/neo-core';
|
|
3
3
|
import ComponentBase from '../ComponentBase';
|
|
4
4
|
import LookupHelper from './LookupHelper';
|
|
@@ -6,6 +6,8 @@ var DropDownBase = /** @class */ (function (_super) {
|
|
|
6
6
|
__extends(DropDownBase, _super);
|
|
7
7
|
function DropDownBase() {
|
|
8
8
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
9
|
+
_this.defaultItemValue = null;
|
|
10
|
+
_this.hasDefaultItem = false;
|
|
9
11
|
_this.isLoading = false;
|
|
10
12
|
_this.dataSource = null;
|
|
11
13
|
_this.cachedDataSource = null;
|
|
@@ -52,6 +54,103 @@ var DropDownBase = /** @class */ (function (_super) {
|
|
|
52
54
|
}
|
|
53
55
|
return items;
|
|
54
56
|
};
|
|
57
|
+
/** Returns either a flat list, or grouped options based on the provided props. */
|
|
58
|
+
DropDownBase.prototype.mapItemsToOptions = function (items) {
|
|
59
|
+
this.hasDefaultItem = false;
|
|
60
|
+
if (this.isGrouped) {
|
|
61
|
+
var firstChildItem = this.getFirstChildItem(items, this.commonProps.childListMember);
|
|
62
|
+
if (firstChildItem) {
|
|
63
|
+
this.findMembers(firstChildItem);
|
|
64
|
+
}
|
|
65
|
+
return this.mapGroupedItemsToOptions(items);
|
|
66
|
+
}
|
|
67
|
+
if (items.length) {
|
|
68
|
+
this.findMembers(items[0]);
|
|
69
|
+
}
|
|
70
|
+
return this.mapChildItemsToOptions(items);
|
|
71
|
+
};
|
|
72
|
+
DropDownBase.prototype.mapGroupedItemsToOptions = function (groupedItems) {
|
|
73
|
+
var _this = this;
|
|
74
|
+
var groupedOptions = groupedItems.map(function (groupItem) {
|
|
75
|
+
var childOptions = _this.mapChildItemsToOptions(groupItem[_this.commonProps.childListMember], groupItem);
|
|
76
|
+
return {
|
|
77
|
+
item: groupItem,
|
|
78
|
+
itemParent: null,
|
|
79
|
+
label: groupItem[_this.commonProps.groupDisplayMember],
|
|
80
|
+
options: childOptions
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
return groupedOptions;
|
|
84
|
+
};
|
|
85
|
+
DropDownBase.prototype.mapChildItemsToOptions = function (childItems, parentItem) {
|
|
86
|
+
var _this = this;
|
|
87
|
+
return childItems.map(function (childItem) {
|
|
88
|
+
var value = childItem[_this.valueMember];
|
|
89
|
+
if (value === _this.defaultItemValue) {
|
|
90
|
+
_this.hasDefaultItem = true;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
item: childItem,
|
|
94
|
+
itemParent: parentItem,
|
|
95
|
+
value: value,
|
|
96
|
+
label: childItem[_this.displayMember]
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Finds an option in the items list by value.
|
|
102
|
+
* Handles both flat lists and grouped (nested) items.
|
|
103
|
+
* @param items The items array to search in
|
|
104
|
+
* @param value The value to search for
|
|
105
|
+
* @returns The matching IOption or undefined if not found
|
|
106
|
+
*/
|
|
107
|
+
DropDownBase.prototype.findOptionByValue = function (items, value) {
|
|
108
|
+
if (!items) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
if (this.isGrouped) {
|
|
112
|
+
// For grouped items, search within child options of each group
|
|
113
|
+
for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
|
|
114
|
+
var group = items_1[_i];
|
|
115
|
+
if (group.options) {
|
|
116
|
+
var childMatch = group.options.find(function (option) { return option.value === value; });
|
|
117
|
+
if (childMatch) {
|
|
118
|
+
return childMatch;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// For flat items, search directly
|
|
126
|
+
return items.find(function (item) { return item.value === value; });
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
DropDownBase.prototype.filterOptions = function (options, filterPredicate, bindProperty) {
|
|
130
|
+
var filterPredicateIncludeSelected;
|
|
131
|
+
if (bindProperty) {
|
|
132
|
+
var bindValue_1 = bindProperty.value;
|
|
133
|
+
filterPredicateIncludeSelected = function (option) { return bindValue_1 === option.value || filterPredicate(option.item, option.itemParent); };
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
filterPredicateIncludeSelected = function (option) { return filterPredicate(option.item, option.itemParent); };
|
|
137
|
+
}
|
|
138
|
+
if (this.isGrouped) {
|
|
139
|
+
var groupsWithFilteredChildren = options.map(function (group) { return (__assign(__assign({}, group), { options: group.options.filter(filterPredicateIncludeSelected) })); });
|
|
140
|
+
// Remove groups that have no children after filtering
|
|
141
|
+
return groupsWithFilteredChildren.filter(function (group) { return group.options.length > 0; });
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
return options.filter(filterPredicateIncludeSelected);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
Object.defineProperty(DropDownBase.prototype, "isGrouped", {
|
|
148
|
+
get: function () {
|
|
149
|
+
return this.commonProps.groupDisplayMember !== undefined && this.commonProps.childListMember !== undefined;
|
|
150
|
+
},
|
|
151
|
+
enumerable: false,
|
|
152
|
+
configurable: true
|
|
153
|
+
});
|
|
55
154
|
DropDownBase.prototype.afterRender = function (isInitial) {
|
|
56
155
|
return __awaiter(this, void 0, void 0, function () {
|
|
57
156
|
var _a, bindProperty, displayValue, readableName, fieldInfo;
|
|
@@ -13,7 +13,7 @@ interface IDeleteButtonOptions extends IButtonOptions {
|
|
|
13
13
|
*/
|
|
14
14
|
onDeleteExisting?: (item: any) => Promise<boolean>;
|
|
15
15
|
}
|
|
16
|
-
export interface IButtonColumnProps extends INeoCommonColumnProps
|
|
16
|
+
export interface IButtonColumnProps extends INeoCommonColumnProps {
|
|
17
17
|
/** Item to pass to edit and delete callbacks. Defaults to the current rows item */
|
|
18
18
|
item?: any;
|
|
19
19
|
/** Text to show in the header. */
|
|
@@ -34,16 +34,20 @@ export interface IButtonColumnProps extends INeoCommonColumnProps, Omit<React.HT
|
|
|
34
34
|
childAlignment?: "left" | "right";
|
|
35
35
|
children?: React.ReactNode | (() => React.ReactNode);
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
type TableCellProps = Omit<React.HTMLProps<HTMLTableCellElement>, "children">;
|
|
38
|
+
export declare class ButtonColumn extends ComponentBase<IButtonColumnProps & TableCellProps> {
|
|
38
39
|
static isColumnComponent: boolean;
|
|
39
40
|
static contextType: React.Context<import("./Grid").GridContextParams<unknown>>;
|
|
40
41
|
context: React.ContextType<typeof GridContext>;
|
|
41
|
-
constructor(props: IButtonColumnProps);
|
|
42
|
+
constructor(props: IButtonColumnProps & TableCellProps);
|
|
42
43
|
private item;
|
|
43
44
|
private section;
|
|
44
45
|
protected onFirstRender(): void;
|
|
45
46
|
private get itemAsModel();
|
|
46
47
|
onDelete(): Promise<void>;
|
|
47
|
-
render(): React.JSX.Element;
|
|
48
|
+
render(): React.JSX.Element | null;
|
|
49
|
+
private renderHeader;
|
|
50
|
+
private renderBody;
|
|
51
|
+
private renderFooter;
|
|
48
52
|
}
|
|
49
53
|
export {};
|
|
@@ -60,28 +60,41 @@ var ButtonColumn = /** @class */ (function (_super) {
|
|
|
60
60
|
});
|
|
61
61
|
};
|
|
62
62
|
ButtonColumn.prototype.render = function () {
|
|
63
|
-
var _a, _b;
|
|
64
63
|
this.onRender();
|
|
65
|
-
var
|
|
64
|
+
var _a = this.props, item = _a.item, label = _a.label, showDefaultButtonText = _a.showDefaultButtonText, buttonSize = _a.buttonSize, showDelete = _a.showDelete, editButton = _a.editButton, deleteButton = _a.deleteButton, viewButton = _a.viewButton, childAlignment = _a.childAlignment, hideBelow = _a.hideBelow, hideAbove = _a.hideAbove, alignment = _a.alignment, headerProps = _a.headerProps, cellProps = _a.cellProps, suppressHeader = _a.suppressHeader, domProps = __rest(_a, ["item", "label", "showDefaultButtonText", "buttonSize", "showDelete", "editButton", "deleteButton", "viewButton", "childAlignment", "hideBelow", "hideAbove", "alignment", "headerProps", "cellProps", "suppressHeader"]);
|
|
66
65
|
domProps.className = Utils.joinWithSpaces("neo-grid-button-column", domProps.className);
|
|
67
66
|
domProps.className = ColumnHelper.addCommonClasses(domProps.className, this.props);
|
|
67
|
+
return (this.section !== "body" ?
|
|
68
|
+
(this.section === "header" ?
|
|
69
|
+
(suppressHeader ? null : this.renderHeader(label, domProps, headerProps)) :
|
|
70
|
+
(suppressHeader ? null : this.renderFooter(domProps, headerProps))) :
|
|
71
|
+
this.renderBody(this.props, domProps, cellProps));
|
|
72
|
+
};
|
|
73
|
+
ButtonColumn.prototype.renderHeader = function (label, domProps, headerProps) {
|
|
74
|
+
if (headerProps) {
|
|
75
|
+
Object.assign(domProps, headerProps);
|
|
76
|
+
}
|
|
77
|
+
return React.createElement("th", __assign({}, domProps), label);
|
|
78
|
+
};
|
|
79
|
+
ButtonColumn.prototype.renderBody = function (props, domProps, cellProps) {
|
|
80
|
+
var _a, _b;
|
|
68
81
|
var buttonColumnDefaults = Misc.Settings.grid.buttonColumnButtons;
|
|
69
82
|
var editButtonDefaults = __assign(__assign({}, buttonColumnDefaults), Misc.Settings.grid.editButton);
|
|
70
83
|
var deleteButtonDefaults = __assign(__assign({}, buttonColumnDefaults), Misc.Settings.grid.deleteButton);
|
|
71
84
|
var viewButtonDefaults = __assign(__assign({}, buttonColumnDefaults), Misc.Settings.grid.viewButton);
|
|
72
|
-
if (!showDefaultButtonText) {
|
|
85
|
+
if (!props.showDefaultButtonText) {
|
|
73
86
|
editButtonDefaults.text = "";
|
|
74
87
|
deleteButtonDefaults.text = "";
|
|
75
88
|
viewButtonDefaults.text = "";
|
|
76
89
|
}
|
|
77
|
-
if (buttonSize) {
|
|
78
|
-
editButtonDefaults.size = buttonSize;
|
|
79
|
-
deleteButtonDefaults.size = buttonSize;
|
|
80
|
-
viewButtonDefaults.size = buttonSize;
|
|
90
|
+
if (props.buttonSize) {
|
|
91
|
+
editButtonDefaults.size = props.buttonSize;
|
|
92
|
+
deleteButtonDefaults.size = props.buttonSize;
|
|
93
|
+
viewButtonDefaults.size = props.buttonSize;
|
|
81
94
|
}
|
|
82
|
-
var editButtonOptions = editButton ? Utils.populatePartialWithDefaults(editButton, editButtonDefaults) : null;
|
|
83
|
-
var deleteButtonOptions = (deleteButton || showDelete) ? Utils.populatePartialWithDefaults(deleteButton, deleteButtonDefaults) : null;
|
|
84
|
-
var viewButtonOptions = viewButton ? Utils.populatePartialWithDefaults(viewButton, viewButtonDefaults) : null;
|
|
95
|
+
var editButtonOptions = props.editButton ? Utils.populatePartialWithDefaults(props.editButton, editButtonDefaults) : null;
|
|
96
|
+
var deleteButtonOptions = (props.deleteButton || props.showDelete) ? Utils.populatePartialWithDefaults(props.deleteButton, deleteButtonDefaults) : null;
|
|
97
|
+
var viewButtonOptions = props.viewButton ? Utils.populatePartialWithDefaults(props.viewButton, viewButtonDefaults) : null;
|
|
85
98
|
if (deleteButtonOptions) {
|
|
86
99
|
if (!deleteButtonOptions.onClick) {
|
|
87
100
|
deleteButtonOptions.onClick = this.onDelete;
|
|
@@ -95,13 +108,20 @@ var ButtonColumn = /** @class */ (function (_super) {
|
|
|
95
108
|
viewButtonOptions && React.createElement(NeoButton, __assign({}, viewButtonOptions)),
|
|
96
109
|
editButtonOptions && React.createElement(NeoButton, __assign({}, editButtonOptions)),
|
|
97
110
|
deleteButtonOptions && React.createElement(NeoButton, __assign({}, deleteButtonOptions)));
|
|
98
|
-
var children =
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
111
|
+
var children = props.children instanceof Function ? props.children() : props.children;
|
|
112
|
+
if (cellProps) {
|
|
113
|
+
Object.assign(domProps, cellProps);
|
|
114
|
+
}
|
|
115
|
+
return (React.createElement("td", __assign({}, domProps),
|
|
116
|
+
props.childAlignment === "right" ? buttons : undefined,
|
|
117
|
+
React.Children.map(children, function (c) { return setButtonProps(c); }),
|
|
118
|
+
props.childAlignment !== "right" ? buttons : undefined));
|
|
119
|
+
};
|
|
120
|
+
ButtonColumn.prototype.renderFooter = function (domProps, headerProps) {
|
|
121
|
+
if (headerProps) {
|
|
122
|
+
Object.assign(domProps, headerProps);
|
|
123
|
+
}
|
|
124
|
+
return React.createElement("th", __assign({}, domProps));
|
|
105
125
|
};
|
|
106
126
|
ButtonColumn.isColumnComponent = true;
|
|
107
127
|
ButtonColumn.contextType = GridContext;
|
|
@@ -43,7 +43,7 @@ export default class Column<TData> extends ComponentBase<INeoColumnProps<TData>>
|
|
|
43
43
|
private headerClick;
|
|
44
44
|
refreshStateObserver(props: IBindableEditorProps): void;
|
|
45
45
|
componentWillUnmount(): void;
|
|
46
|
-
render(): React.JSX.Element;
|
|
46
|
+
render(): React.JSX.Element | null;
|
|
47
47
|
private renderHeader;
|
|
48
48
|
private renderBody;
|
|
49
49
|
private renderFooter;
|
|
@@ -91,7 +91,7 @@ var Column = /** @class */ (function (_super) {
|
|
|
91
91
|
Column.prototype.render = function () {
|
|
92
92
|
this.onRender();
|
|
93
93
|
var allProps = BindPropsHelper.normaliseContainerProps(this, this.props, false);
|
|
94
|
-
var _a = allProps.containerDom, width = _a.width, hideBelow = _a.hideBelow, hideAbove = _a.hideAbove, headerTooltip = _a.headerTooltip, cellTooltip = _a.cellTooltip, alignment = _a.alignment, sort = _a.sort, sum = _a.sum, footerContent = _a.footerContent, headerClassName = _a.headerClassName, cellClassName = _a.cellClassName, onHeaderClick = _a.onHeaderClick, domProps = __rest(_a, ["width", "hideBelow", "hideAbove", "headerTooltip", "cellTooltip", "alignment", "sort", "sum", "footerContent", "headerClassName", "cellClassName", "onHeaderClick"]);
|
|
94
|
+
var _a = allProps.containerDom, width = _a.width, hideBelow = _a.hideBelow, hideAbove = _a.hideAbove, headerTooltip = _a.headerTooltip, cellTooltip = _a.cellTooltip, alignment = _a.alignment, sort = _a.sort, invertSortIcon = _a.invertSortIcon, sum = _a.sum, footerContent = _a.footerContent, headerClassName = _a.headerClassName, cellClassName = _a.cellClassName, headerProps = _a.headerProps, cellProps = _a.cellProps, suppressHeader = _a.suppressHeader, onHeaderClick = _a.onHeaderClick, domProps = __rest(_a, ["width", "hideBelow", "hideAbove", "headerTooltip", "cellTooltip", "alignment", "sort", "invertSortIcon", "sum", "footerContent", "headerClassName", "cellClassName", "headerProps", "cellProps", "suppressHeader", "onHeaderClick"]);
|
|
95
95
|
if (allProps.bind !== undefined) {
|
|
96
96
|
if (!this.controlType || this.isHeader) {
|
|
97
97
|
this.controlType = BindPropsHelper.getControlType(allProps);
|
|
@@ -131,14 +131,17 @@ var Column = /** @class */ (function (_super) {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
this.refreshStateObserver(allProps.editor);
|
|
134
|
-
return this.isHeader ? this.renderHeader(allProps, domProps, headerTooltip, headerClassName) :
|
|
135
|
-
this.isFooter ? this.renderFooter(allProps, domProps) :
|
|
136
|
-
this.renderBody(allProps, domProps, cellTooltip, cellClassName);
|
|
134
|
+
return this.isHeader ? (suppressHeader ? null : this.renderHeader(allProps, domProps, headerTooltip, headerClassName, headerProps)) :
|
|
135
|
+
this.isFooter ? (suppressHeader ? null : this.renderFooter(allProps, domProps, headerProps)) :
|
|
136
|
+
this.renderBody(allProps, domProps, cellTooltip, cellClassName, cellProps);
|
|
137
137
|
};
|
|
138
|
-
Column.prototype.renderHeader = function (props, domProps, tooltip, headerClassName) {
|
|
138
|
+
Column.prototype.renderHeader = function (props, domProps, tooltip, headerClassName, headerProps) {
|
|
139
139
|
var _this = this;
|
|
140
140
|
var sortIcon = null;
|
|
141
141
|
var sortProperty = this.getSortProperty();
|
|
142
|
+
if (headerProps) {
|
|
143
|
+
Object.assign(domProps, headerProps);
|
|
144
|
+
}
|
|
142
145
|
domProps.className = Utils.joinWithSpaces(domProps.className, headerClassName);
|
|
143
146
|
if (sortProperty && !this.suppressSort) {
|
|
144
147
|
var sortInfo = this.context.dataView.sortInfo.find(function (c) { return c.column === sortProperty.propertyInfo; });
|
|
@@ -154,7 +157,7 @@ var Column = /** @class */ (function (_super) {
|
|
|
154
157
|
sortIcon &&
|
|
155
158
|
React.createElement("i", { className: "column-sort-icon fa fa-" + sortIcon })));
|
|
156
159
|
};
|
|
157
|
-
Column.prototype.renderBody = function (props, domProps, cellTooltip, cellClassName) {
|
|
160
|
+
Column.prototype.renderBody = function (props, domProps, cellTooltip, cellClassName, cellProps) {
|
|
158
161
|
var _this = this;
|
|
159
162
|
var editorProps = props.editor;
|
|
160
163
|
var containerProps = props.container;
|
|
@@ -188,6 +191,9 @@ var Column = /** @class */ (function (_super) {
|
|
|
188
191
|
editor = BindPropsHelper.getFormControl(props);
|
|
189
192
|
}
|
|
190
193
|
}
|
|
194
|
+
if (cellProps) {
|
|
195
|
+
Object.assign(domProps, cellProps);
|
|
196
|
+
}
|
|
191
197
|
domProps.className = Utils.joinWithSpaces(domProps.className, cellClassName);
|
|
192
198
|
return (React.createElement("td", __assign({ "data-tip": cellTooltip }, domProps),
|
|
193
199
|
!containerProps.suppressDefaultContent && (editor !== undefined ?
|
|
@@ -197,10 +203,13 @@ var Column = /** @class */ (function (_super) {
|
|
|
197
203
|
containerProps.bindContext &&
|
|
198
204
|
React.createElement(FormContext.Consumer, null, function (value) { return (React.createElement(FormContext.Provider, { value: __assign(__assign({}, value), { parentType: EditorParentType.Column, bindProperty: containerProps.bindContext }) }, _this.props.children instanceof Function ? _this.props.children() : _this.props.children)); })));
|
|
199
205
|
};
|
|
200
|
-
Column.prototype.renderFooter = function (props, domProps) {
|
|
206
|
+
Column.prototype.renderFooter = function (props, domProps, headerProps) {
|
|
201
207
|
var _this = this;
|
|
202
208
|
var colProps = props.containerDom;
|
|
203
209
|
var hasSummary = (colProps.sum && !!props.bind) || colProps.footerContent;
|
|
210
|
+
if (headerProps) {
|
|
211
|
+
Object.assign(domProps, headerProps);
|
|
212
|
+
}
|
|
204
213
|
return (React.createElement("th", __assign({}, domProps), hasSummary &&
|
|
205
214
|
React.createElement(Observer, null, function () { return colProps.footerContent ? colProps.footerContent(_this.context.dataView.filteredItems) :
|
|
206
215
|
_this.numFormatState(props.bind.propertyInfo, props.bind.propertyInfo.propertyType, props.numProps).getFormattedValue(_this.context.dataView.filteredItems.sum(props.bind.propertyInfo)); })));
|
|
@@ -6,7 +6,14 @@ export interface INeoCommonColumnProps {
|
|
|
6
6
|
hideAbove?: Components.breakpoint;
|
|
7
7
|
/** Set the alignment of the column. */
|
|
8
8
|
alignment?: "left" | "center" | "right";
|
|
9
|
+
/** Props to apply to the header cell. */
|
|
10
|
+
headerProps?: TableCellSectionProps;
|
|
11
|
+
/** Props to apply to body cells. */
|
|
12
|
+
cellProps?: TableCellSectionProps;
|
|
13
|
+
/** If set, the header cell for this column will be hidden. */
|
|
14
|
+
suppressHeader?: boolean;
|
|
9
15
|
}
|
|
16
|
+
export type TableCellSectionProps = Omit<React.HTMLProps<HTMLTableCellElement>, "className" | "onClick">;
|
|
10
17
|
export declare class ColumnHelper {
|
|
11
18
|
static addCommonClasses(className: string | undefined, props: INeoCommonColumnProps): string | undefined;
|
|
12
19
|
}
|
|
@@ -21,9 +21,10 @@ var Row = /** @class */ (function (_super) {
|
|
|
21
21
|
if (!this.context.doneStaticSetup) {
|
|
22
22
|
this.context.doneStaticSetup = true;
|
|
23
23
|
React.Children.forEach(this.props.children, function (child) {
|
|
24
|
+
var _a, _b, _c;
|
|
24
25
|
if (child) {
|
|
25
26
|
var childProps = child.props;
|
|
26
|
-
_this.context.columnCount += (childProps ? childProps.
|
|
27
|
+
_this.context.columnCount += (childProps ? ((_c = (_b = (_a = childProps.cellProps) === null || _a === void 0 ? void 0 : _a.colSpan) !== null && _b !== void 0 ? _b : childProps.colSpan) !== null && _c !== void 0 ? _c : 1) : 1);
|
|
27
28
|
if (childProps && (childProps.sum || childProps.footerContent)) {
|
|
28
29
|
_this.context.hasSummaries = true;
|
|
29
30
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@singularsystems/neo-react",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.4",
|
|
4
4
|
"description": "React application logic and components for the Neo client library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"typescript": "5.9.3"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@singularsystems/neo-core": "1.6.
|
|
30
|
+
"@singularsystems/neo-core": "1.6.3",
|
|
31
31
|
"@types/react-color": "3.0.13",
|
|
32
32
|
"axios": "1.13.5",
|
|
33
33
|
"inversify": "6.0.2",
|
package/styles/Card.scss
CHANGED
|
@@ -37,4 +37,23 @@
|
|
|
37
37
|
border-bottom: 0;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
&.card--with-description {
|
|
42
|
+
.card-header {
|
|
43
|
+
.card-header-title {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
|
|
47
|
+
.neo-icon {
|
|
48
|
+
margin-right: 1rem;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.card-title-description {
|
|
54
|
+
font-size: 14px;
|
|
55
|
+
line-height: 1.2;
|
|
56
|
+
color: $text-muted;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
40
59
|
}
|