@singularsystems/neo-react 0.10.40 → 0.10.43
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/dist/Modules/NeoReactModule.js +2 -0
- package/dist/Modules/Types.d.ts +4 -0
- package/dist/React/AutoRunner.d.ts +1 -1
- package/dist/React/AutoRunner.js +2 -1
- package/dist/ReactComponents/Button.js +2 -2
- package/dist/ReactComponents/DropDown/AutoCompleteDropDown.d.ts +7 -0
- package/dist/ReactComponents/DropDown/AutoCompleteDropDown.js +19 -6
- package/dist/ReactComponents/DropDown/DropDown.js +4 -3
- package/dist/ReactComponents/DropDown/DropDownBase.js +5 -1
- package/dist/ReactComponents/FileManager/FileBasicInput.js +25 -4
- package/dist/ReactComponents/Grid/ButtonColumn.d.ts +12 -2
- package/dist/ReactComponents/Grid/ButtonColumn.js +23 -2
- package/dist/ReactComponents/Grid/Grid.d.ts +6 -0
- package/dist/ReactComponents/Grid/Grid.js +9 -5
- package/dist/ReactComponents/Modal/Modal.js +4 -1
- package/dist/ReactComponents/NumberInput.js +8 -4
- package/dist/ReactComponents/_Exports.d.ts +2 -1
- package/dist/ReactComponents/_Exports.js +2 -1
- package/dist/Views/ViewModelBase.d.ts +8 -0
- package/dist/Views/ViewModelBase.js +21 -0
- package/package.json +2 -2
- package/styles/Forms.scss +19 -1
|
@@ -10,9 +10,11 @@ import { AutoRunnerFactory } from '../React/AutoRunner';
|
|
|
10
10
|
import { RoutingState } from '../Routing/RoutingState';
|
|
11
11
|
import { ContextMenuState } from '../ReactComponents/ContextMenu/ContextMenuState';
|
|
12
12
|
import { DisposeHelper } from '../Services/DisposeHelper';
|
|
13
|
+
import Decimal from 'decimal.js-light';
|
|
13
14
|
var neoReactModule = new AppServices.Module("neo-react", function (container) {
|
|
14
15
|
container.bind(AppServices.NeoTypes.Core.AutoRunnerFactory).to(AutoRunnerFactory).inSingletonScope();
|
|
15
16
|
container.bind(AppServices.NeoTypes.Core.ModelCreator).to(ReactModelCreator).inTransientScope();
|
|
17
|
+
container.bind(AppServices.NeoTypes.Misc.DecimalType).toConstantValue(Decimal);
|
|
16
18
|
container.bind(AppServices.NeoTypes.UI.ErrorHandler).to(ErrorHandler).inSingletonScope();
|
|
17
19
|
container.bind(AppServices.NeoTypes.UI.GlobalContextMenuState).toConstantValue(new ContextMenuState());
|
|
18
20
|
container.bind(AppServices.NeoTypes.Routing.PageLeaveHandler).to(PageLeaveHandler).inSingletonScope();
|
package/dist/Modules/Types.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import Slider, { Range } from 'rc-slider';
|
|
|
5
5
|
import { SketchPicker } from 'react-color';
|
|
6
6
|
import AsyncSelect from 'react-select/async';
|
|
7
7
|
import { AxiosStatic } from 'axios';
|
|
8
|
+
import Decimal from 'decimal.js-light';
|
|
8
9
|
import Select from 'react-select';
|
|
9
10
|
import { IDisposeHelper } from '../Services/IDisposeHelper';
|
|
10
11
|
declare const NeoReactTypes: {
|
|
@@ -38,6 +39,9 @@ declare const NeoReactTypes: {
|
|
|
38
39
|
Localisation: {
|
|
39
40
|
LocalisationService: AppServices.ServiceIdentifier<import("@singularsystems/neo-core/dist/Localisation").ILocalisationService>;
|
|
40
41
|
};
|
|
42
|
+
Misc: {
|
|
43
|
+
DecimalType: AppServices.ServiceIdentifier<typeof Decimal>;
|
|
44
|
+
};
|
|
41
45
|
Security: {
|
|
42
46
|
AuthenticationService: AppServices.ServiceIdentifier<import("@singularsystems/neo-core/dist/Security").IAuthenticationService>;
|
|
43
47
|
AuthorisationService: AppServices.ServiceIdentifier<import("@singularsystems/neo-core/dist/Security").IAuthorisationService>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Misc, Model } from '@singularsystems/neo-core';
|
|
2
2
|
import { IAutoRunnerFactory } from '@singularsystems/neo-core/dist/Model/IAutoRunner';
|
|
3
3
|
export declare class AutoRunnerFactory implements IAutoRunnerFactory {
|
|
4
|
-
create<T extends Model.IModelBase>(model: T, callback: (model: T) => void, options?: Misc.IAutoRunnerOptions): Misc.IAutoRunner;
|
|
4
|
+
create<T extends Model.IModelBase>(model: T, callback: (model: T) => void, options?: Misc.IAutoRunnerOptions<T>): Misc.IAutoRunner;
|
|
5
5
|
}
|
package/dist/React/AutoRunner.js
CHANGED
|
@@ -55,9 +55,10 @@ var AutoRunner = /** @class */ (function () {
|
|
|
55
55
|
if (instance && !trackedInstances.has(instance)) {
|
|
56
56
|
trackedInstances.set(instance, true);
|
|
57
57
|
var info = instance.constructor.neo;
|
|
58
|
+
var filterProperties = path === "" ? this.options.rootProperties : undefined;
|
|
58
59
|
for (var _i = 0, _b = info.properties; _i < _b.length; _i++) {
|
|
59
60
|
var propertyInfo = _b[_i];
|
|
60
|
-
if (!propertyInfo.noTrack && instance.meta[propertyInfo.propertyName]) {
|
|
61
|
+
if (!propertyInfo.noTrack && instance.meta[propertyInfo.propertyName] && (!filterProperties || filterProperties.indexOf(propertyInfo.propertyName) >= 0)) {
|
|
61
62
|
if (propertyInfo.relationType === Misc.RelationType.None) {
|
|
62
63
|
var key = path + propertyInfo.propertyName;
|
|
63
64
|
var useDelay = this.propertyMap[key];
|
|
@@ -49,7 +49,7 @@ var Button = /** @class */ (function (_super) {
|
|
|
49
49
|
Button.prototype.render = function () {
|
|
50
50
|
var _this = this;
|
|
51
51
|
var _a;
|
|
52
|
-
var _b = this.props, isSubmit = _b.isSubmit, variant = _b.variant, size = _b.size, isOutline = _b.isOutline, icon = _b.icon, iconAlignment = _b.iconAlignment, text = _b.text, menuItems = _b.menuItems, splitMenu = _b.splitMenu, menuAlignment = _b.menuAlignment, buttonGroupClassName = _b.buttonGroupClassName, tooltip = _b.tooltip, task = _b.task, pulse = _b.pulse, native = __rest(_b, ["isSubmit", "variant", "size", "isOutline", "icon", "iconAlignment", "text", "menuItems", "splitMenu", "menuAlignment", "buttonGroupClassName", "tooltip", "task", "pulse"]);
|
|
52
|
+
var _b = this.props, isSubmit = _b.isSubmit, variant = _b.variant, size = _b.size, isOutline = _b.isOutline, icon = _b.icon, iconAlignment = _b.iconAlignment, text = _b.text, menuItems = _b.menuItems, splitMenu = _b.splitMenu, menuAlignment = _b.menuAlignment, buttonGroupClassName = _b.buttonGroupClassName, tooltip = _b.tooltip, task = _b.task, isBusy = _b.isBusy, pulse = _b.pulse, native = __rest(_b, ["isSubmit", "variant", "size", "isOutline", "icon", "iconAlignment", "text", "menuItems", "splitMenu", "menuAlignment", "buttonGroupClassName", "tooltip", "task", "isBusy", "pulse"]);
|
|
53
53
|
native.type = isSubmit ? "submit" : "button";
|
|
54
54
|
variant = (variant !== null && variant !== void 0 ? variant : "primary");
|
|
55
55
|
var isDropDown = menuItems && menuItems.length;
|
|
@@ -60,7 +60,7 @@ var Button = /** @class */ (function (_super) {
|
|
|
60
60
|
buttonClasses += " dropdown-toggle";
|
|
61
61
|
native.onClick = this.showMenu;
|
|
62
62
|
}
|
|
63
|
-
if ((_a = task) === null || _a === void 0 ? void 0 : _a.isBusy) {
|
|
63
|
+
if (isBusy || ((_a = task) === null || _a === void 0 ? void 0 : _a.isBusy)) {
|
|
64
64
|
icon = "fa-circle-notch fa-spin";
|
|
65
65
|
native.disabled = true;
|
|
66
66
|
}
|
|
@@ -20,6 +20,12 @@ interface IAutoCompleteCommonProps<T> extends ICommonEditorProps, Props<IOption,
|
|
|
20
20
|
items?: ItemSource<T>;
|
|
21
21
|
valueMember?: keyof T;
|
|
22
22
|
displayMember?: keyof T;
|
|
23
|
+
/**
|
|
24
|
+
* Property of an item to use as the description.
|
|
25
|
+
*
|
|
26
|
+
* Description will be shown in muted text below the item name.
|
|
27
|
+
*/
|
|
28
|
+
descriptionMember?: keyof T | false;
|
|
23
29
|
/**
|
|
24
30
|
* Callback used to provide a custom option component instead of displaying the display member value.
|
|
25
31
|
*/
|
|
@@ -72,5 +78,6 @@ export default class AutoCompleteDropDown<T> extends DropDownBase<T, IAutoComple
|
|
|
72
78
|
private mapTArrayToOptions;
|
|
73
79
|
private onItemSelected;
|
|
74
80
|
render(): JSX.Element;
|
|
81
|
+
private getOption;
|
|
75
82
|
}
|
|
76
83
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __assign, __decorate, __extends, __metadata, __rest } from "tslib";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Misc, Utils } from '@singularsystems/neo-core';
|
|
3
|
+
import { EnumHelper, Misc, Utils } from '@singularsystems/neo-core';
|
|
4
4
|
import { observer } from 'mobx-react';
|
|
5
5
|
import { DropDownBase } from './DropDownBase';
|
|
6
6
|
import { BindPropsHelper } from '../PropTypes';
|
|
@@ -98,7 +98,7 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
98
98
|
AutoCompleteDropDown.prototype.render = function () {
|
|
99
99
|
var _this = this;
|
|
100
100
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
101
|
-
var _m = this.props, bind = _m.bind, bindDisplay = _m.bindDisplay, bindItems = _m.bindItems, bindIds = _m.bindIds, itemSource = _m.itemSource, items = _m.items, displayMember = _m.displayMember, valueMember = _m.valueMember, option = _m.option, noRecordsPrompt = _m.noRecordsPrompt, typeToSearchPrompt = _m.typeToSearchPrompt, delayMs = _m.delayMs, minCharacters = _m.minCharacters, onItemSelected = _m.onItemSelected, otherProps = __rest(_m, ["bind", "bindDisplay", "bindItems", "bindIds", "itemSource", "items", "displayMember", "valueMember", "option", "noRecordsPrompt", "typeToSearchPrompt", "delayMs", "minCharacters", "onItemSelected"]);
|
|
101
|
+
var _m = this.props, bind = _m.bind, bindDisplay = _m.bindDisplay, bindItems = _m.bindItems, bindIds = _m.bindIds, itemSource = _m.itemSource, items = _m.items, displayMember = _m.displayMember, valueMember = _m.valueMember, descriptionMember = _m.descriptionMember, option = _m.option, noRecordsPrompt = _m.noRecordsPrompt, typeToSearchPrompt = _m.typeToSearchPrompt, delayMs = _m.delayMs, minCharacters = _m.minCharacters, onItemSelected = _m.onItemSelected, otherProps = __rest(_m, ["bind", "bindDisplay", "bindItems", "bindIds", "itemSource", "items", "displayMember", "valueMember", "descriptionMember", "option", "noRecordsPrompt", "typeToSearchPrompt", "delayMs", "minCharacters", "onItemSelected"]);
|
|
102
102
|
var splitProps = BindPropsHelper.splitCommonEditorProps(otherProps);
|
|
103
103
|
var nativeProps = splitProps.rest;
|
|
104
104
|
var bindItemsProperty = bindItems;
|
|
@@ -112,7 +112,13 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
112
112
|
this.valueMember = (_c = this.props.valueMember, (_c !== null && _c !== void 0 ? _c : ""));
|
|
113
113
|
var defaultItems = undefined;
|
|
114
114
|
if (this.props.items) {
|
|
115
|
-
|
|
115
|
+
var items_1 = this.getItems(this.props.items);
|
|
116
|
+
defaultItems = this.mapTArrayToOptions(items_1);
|
|
117
|
+
if (descriptionMember === undefined && items_1.length > 0) {
|
|
118
|
+
if (EnumHelper.isEnumItem(items_1[0])) {
|
|
119
|
+
descriptionMember = "description";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
116
122
|
}
|
|
117
123
|
var value = null;
|
|
118
124
|
if (bindItems) {
|
|
@@ -135,11 +141,15 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
135
141
|
}
|
|
136
142
|
var components = (_j = nativeProps.components, (_j !== null && _j !== void 0 ? _j : {}));
|
|
137
143
|
if (this.props.option) {
|
|
138
|
-
components.Option =
|
|
144
|
+
components.Option = this.getOption(this.props.option);
|
|
139
145
|
}
|
|
140
146
|
else if (components.Option) {
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
components.Option = this.getOption(components.Option);
|
|
148
|
+
}
|
|
149
|
+
else if (descriptionMember) {
|
|
150
|
+
components.Option = this.getOption(function (item) { return React.createElement(React.Fragment, null,
|
|
151
|
+
React.createElement("div", { className: "react-select-name" }, item[_this.displayMember]),
|
|
152
|
+
React.createElement("div", { className: "react-select-description" }, item[descriptionMember])); }, "with-description");
|
|
143
153
|
}
|
|
144
154
|
if (nativeProps.isClearable === undefined) {
|
|
145
155
|
nativeProps.isClearable = true;
|
|
@@ -165,6 +175,9 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
165
175
|
return Tooltip.fromDataAttributes(InputHelpers.surroundWithInputGroup(React.createElement(this.selectImplementation, __assign({}, nativeProps, { placeholder: (_l = this.props.placeholder, (_l !== null && _l !== void 0 ? _l : "")), classNamePrefix: "react-select-bs", options: defaultItems, isLoading: this.isLoading, isMulti: bindItems !== undefined, noOptionsMessage: function (c) { var _a; return _a = _this.props.noRecordsPrompt, (_a !== null && _a !== void 0 ? _a : "No records found"); }, value: value, onChange: this.onItemSelected, components: components })), splitProps.editor), nativeProps);
|
|
166
176
|
}
|
|
167
177
|
};
|
|
178
|
+
AutoCompleteDropDown.prototype.getOption = function (content, additionalClass) {
|
|
179
|
+
return function (item) { return (React.createElement("div", __assign({ ref: item.innerRef }, item.innerProps, { className: Utils.joinWithSpaces("react-select-row", additionalClass, item.isFocused ? "focused" : undefined, item.isSelected ? "selected" : undefined) }), content(item.data))); };
|
|
180
|
+
};
|
|
168
181
|
AutoCompleteDropDown.contextType = FormContext;
|
|
169
182
|
AutoCompleteDropDown = __decorate([
|
|
170
183
|
observer,
|
|
@@ -80,7 +80,7 @@ var DropDown = /** @class */ (function (_super) {
|
|
|
80
80
|
};
|
|
81
81
|
DropDown.prototype.render = function () {
|
|
82
82
|
var _this = this;
|
|
83
|
-
var _a, _b, _c, _d, _e;
|
|
83
|
+
var _a, _b, _c, _d, _e, _f;
|
|
84
84
|
var splitProps = BindPropsHelper.normaliseEditorProps(this, this.props);
|
|
85
85
|
var domProps = BindPropsHelper.autoSetDomProperties(splitProps, this.context);
|
|
86
86
|
domProps.className = Utils.joinWithSpaces(domProps.className, splitProps.isBootstrap ? "form-control" : "neo-forms-editor");
|
|
@@ -96,7 +96,7 @@ var DropDown = /** @class */ (function (_super) {
|
|
|
96
96
|
var selectedItem = this.getSelectedOption(this.props.bind.value); // This sets the sort value to allow sorting of drop downs in grids.
|
|
97
97
|
var value = this.props.bind.value;
|
|
98
98
|
var addBlankItem = (_b = (_a = splitProps.select) === null || _a === void 0 ? void 0 : _a.allowNulls, (_b !== null && _b !== void 0 ? _b : this.props.bind.propertyInfo.allowNulls)) || !value;
|
|
99
|
-
if (addBlankItem && items.find(function (item) { return item[_this.valueMember] === null; })) {
|
|
99
|
+
if (addBlankItem && items.find(function (item) { return item[_this.valueMember] === null || item[_this.valueMember] === ""; })) {
|
|
100
100
|
// If there is an item with a null value, don't add a blank drop down item.
|
|
101
101
|
addBlankItem = false;
|
|
102
102
|
}
|
|
@@ -116,9 +116,10 @@ var DropDown = /** @class */ (function (_super) {
|
|
|
116
116
|
domProps.disabled = true;
|
|
117
117
|
}
|
|
118
118
|
var valueIsBlank = value === undefined || value === null;
|
|
119
|
+
var nullText = (valueIsBlank || ((_d = splitProps.select) === null || _d === void 0 ? void 0 : _d.deSelectText) === undefined) ? (_e = splitProps.select) === null || _e === void 0 ? void 0 : _e.nullText : (_f = splitProps.select) === null || _f === void 0 ? void 0 : _f.deSelectText;
|
|
119
120
|
control =
|
|
120
121
|
React.createElement("select", __assign({ value: valueIsBlank ? "" : value, onChange: this.onItemSelected, ref: splitProps.editor.inputElement }, domProps),
|
|
121
|
-
addBlankItem && React.createElement("option", null,
|
|
122
|
+
addBlankItem && React.createElement("option", null, nullText),
|
|
122
123
|
items.map(function (item) { return (React.createElement("option", { value: item[_this.valueMember], key: item[_this.valueMember] }, item[_this.displayMember])); }));
|
|
123
124
|
}
|
|
124
125
|
return (InputHelpers.surroundWithInputGroup(control, splitProps.editor));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __awaiter, __extends, __generator } from "tslib";
|
|
2
|
-
import { Data, Model } from '@singularsystems/neo-core';
|
|
2
|
+
import { Data, EnumHelper, Model } from '@singularsystems/neo-core';
|
|
3
3
|
import ComponentBase from '../ComponentBase';
|
|
4
4
|
var DropDownBase = /** @class */ (function (_super) {
|
|
5
5
|
__extends(DropDownBase, _super);
|
|
@@ -13,6 +13,10 @@ var DropDownBase = /** @class */ (function (_super) {
|
|
|
13
13
|
}
|
|
14
14
|
DropDownBase.prototype.findMembers = function (item) {
|
|
15
15
|
if (!this.valueMember || !this.displayMember) {
|
|
16
|
+
if (EnumHelper.isEnumItem(item)) {
|
|
17
|
+
this.valueMember = "id";
|
|
18
|
+
this.displayMember = "name";
|
|
19
|
+
}
|
|
16
20
|
if (!this.displayMember) {
|
|
17
21
|
var neoTypeInfo = item.constructor.neo;
|
|
18
22
|
if (neoTypeInfo && neoTypeInfo.displayMember) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __assign, __decorate, __extends, __metadata, __rest } from "tslib";
|
|
1
|
+
import { __assign, __awaiter, __decorate, __extends, __generator, __metadata, __rest } from "tslib";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { observer } from 'mobx-react';
|
|
4
4
|
import { FileContext } from './FileContext';
|
|
@@ -14,9 +14,30 @@ var FileBasicInput = /** @class */ (function (_super) {
|
|
|
14
14
|
return _this;
|
|
15
15
|
}
|
|
16
16
|
FileBasicInput.prototype.onFileSelected = function (e) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
var _a, _b;
|
|
18
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
19
|
+
var input;
|
|
20
|
+
return __generator(this, function (_c) {
|
|
21
|
+
switch (_c.label) {
|
|
22
|
+
case 0:
|
|
23
|
+
if (!e.target.files) return [3 /*break*/, 4];
|
|
24
|
+
_c.label = 1;
|
|
25
|
+
case 1:
|
|
26
|
+
_c.trys.push([1, , 3, 4]);
|
|
27
|
+
return [4 /*yield*/, this.fileManager.processFiles(e.target.files, { handleErrors: !this.fileManager.options.taskRunner })];
|
|
28
|
+
case 2:
|
|
29
|
+
_c.sent();
|
|
30
|
+
return [3 /*break*/, 4];
|
|
31
|
+
case 3:
|
|
32
|
+
input = (_a = e.target, (_a !== null && _a !== void 0 ? _a : (_b = this.props.inputRef) === null || _b === void 0 ? void 0 : _b.current));
|
|
33
|
+
if (input) {
|
|
34
|
+
input.value = "";
|
|
35
|
+
}
|
|
36
|
+
return [7 /*endfinally*/];
|
|
37
|
+
case 4: return [2 /*return*/];
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
20
41
|
};
|
|
21
42
|
FileBasicInput.prototype.render = function () {
|
|
22
43
|
var _a = this.props, fileManager = _a.fileManager, isHidden = _a.isHidden, inputRef = _a.inputRef, native = __rest(_a, ["fileManager", "isHidden", "inputRef"]);
|
|
@@ -3,6 +3,16 @@ import { GridContext } from './Grid';
|
|
|
3
3
|
import { IButtonOptions } from '@singularsystems/neo-core/dist/Components/ButtonOptions';
|
|
4
4
|
import ComponentBase from '../ComponentBase';
|
|
5
5
|
import { INeoCommonColumnProps } from './ColumnHelper';
|
|
6
|
+
interface IDeleteButtonOptions extends IButtonOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Callback to run when a non new item is deleted.
|
|
9
|
+
* * Use this to call an api to delete the item in the database.
|
|
10
|
+
* * Return true if the item was deleted, and must be removed from the list.
|
|
11
|
+
* * The list will not be marked dirty.
|
|
12
|
+
* * If the item is new, it will be removed without invoking this callback.
|
|
13
|
+
*/
|
|
14
|
+
onDeleteExisting?: (item: any) => Promise<boolean>;
|
|
15
|
+
}
|
|
6
16
|
interface IButtonColumnProps extends INeoCommonColumnProps, React.HTMLProps<HTMLTableCellElement> {
|
|
7
17
|
/** Item to pass to edit and delete callbacks. Defaults to the current rows item */
|
|
8
18
|
item?: any;
|
|
@@ -15,7 +25,7 @@ interface IButtonColumnProps extends INeoCommonColumnProps, React.HTMLProps<HTML
|
|
|
15
25
|
/** Show delete button? Not required if deleteButton options are set. */
|
|
16
26
|
showDelete?: boolean;
|
|
17
27
|
/** Delete button options. Will cause delete button to be shown. */
|
|
18
|
-
deleteButton?:
|
|
28
|
+
deleteButton?: IDeleteButtonOptions;
|
|
19
29
|
/** Edit button options. Will cause edit button to be shown. */
|
|
20
30
|
editButton?: IButtonOptions;
|
|
21
31
|
/** View button options. Will cause view button to be shown. */
|
|
@@ -31,7 +41,7 @@ export declare class ButtonColumn extends ComponentBase<IButtonColumnProps> {
|
|
|
31
41
|
private item;
|
|
32
42
|
private section;
|
|
33
43
|
protected onFirstRender(): void;
|
|
34
|
-
onDelete(): void
|
|
44
|
+
onDelete(): Promise<void>;
|
|
35
45
|
render(): JSX.Element;
|
|
36
46
|
}
|
|
37
47
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __assign, __extends, __rest } from "tslib";
|
|
1
|
+
import { __assign, __awaiter, __extends, __generator, __rest } from "tslib";
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { GridContext } from './Grid';
|
|
4
4
|
import NeoButton from '../Button';
|
|
@@ -17,7 +17,28 @@ var ButtonColumn = /** @class */ (function (_super) {
|
|
|
17
17
|
this.item = this.context.currentItem;
|
|
18
18
|
};
|
|
19
19
|
ButtonColumn.prototype.onDelete = function () {
|
|
20
|
-
|
|
20
|
+
var _a, _b;
|
|
21
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
22
|
+
var item, mustRemove;
|
|
23
|
+
return __generator(this, function (_c) {
|
|
24
|
+
switch (_c.label) {
|
|
25
|
+
case 0:
|
|
26
|
+
item = (_a = this.props.item, (_a !== null && _a !== void 0 ? _a : this.item));
|
|
27
|
+
if (!(item.isNew === false && ((_b = this.props.deleteButton) === null || _b === void 0 ? void 0 : _b.onDeleteExisting) !== undefined)) return [3 /*break*/, 2];
|
|
28
|
+
return [4 /*yield*/, this.props.deleteButton.onDeleteExisting(item)];
|
|
29
|
+
case 1:
|
|
30
|
+
mustRemove = _c.sent();
|
|
31
|
+
if (mustRemove) {
|
|
32
|
+
this.context.dataView.rawItems.removeWithoutTracking(item);
|
|
33
|
+
}
|
|
34
|
+
return [3 /*break*/, 3];
|
|
35
|
+
case 2:
|
|
36
|
+
this.context.dataView.rawItems.remove(item);
|
|
37
|
+
_c.label = 3;
|
|
38
|
+
case 3: return [2 /*return*/];
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
21
42
|
};
|
|
22
43
|
ButtonColumn.prototype.render = function () {
|
|
23
44
|
this.onRender();
|
|
@@ -67,6 +67,12 @@ export interface IGridProps<T> extends React.HTMLProps<HTMLTableElement> {
|
|
|
67
67
|
isSmallTable?: boolean;
|
|
68
68
|
/** Additional footer row(s) to display below the main footer row. */
|
|
69
69
|
footerContent?: (data: T[]) => React.ReactNode;
|
|
70
|
+
/**
|
|
71
|
+
* Additional content to show next to the add new button.
|
|
72
|
+
*
|
|
73
|
+
* Set `showAddButton = false` if you don't want the default button.
|
|
74
|
+
*/
|
|
75
|
+
footerButtons?: () => React.ReactNode;
|
|
70
76
|
}
|
|
71
77
|
export default class Grid<T> extends React.Component<IGridProps<T>> {
|
|
72
78
|
static contextType: React.Context<import("../../React/DataView").DataViewContextParams<unknown>>;
|
|
@@ -32,7 +32,7 @@ var Grid = /** @class */ (function (_super) {
|
|
|
32
32
|
}
|
|
33
33
|
Grid.prototype.render = function () {
|
|
34
34
|
var _this = this;
|
|
35
|
-
var _a = this.props, items = _a.items, showAddButton = _a.showAddButton, addButton = _a.addButton, filterPredicate = _a.filterPredicate, keyProperty = _a.keyProperty, allowSort = _a.allowSort, expandAll = _a.expandAll, collapseAll = _a.collapseAll, initialSort = _a.initialSort, initialSortAscending = _a.initialSortAscending, isBordered = _a.isBordered, isStriped = _a.isStriped, isBorderless = _a.isBorderless, showHover = _a.showHover, isSmallTable = _a.isSmallTable, footerContent = _a.footerContent, domProps = __rest(_a, ["items", "showAddButton", "addButton", "filterPredicate", "keyProperty", "allowSort", "expandAll", "collapseAll", "initialSort", "initialSortAscending", "isBordered", "isStriped", "isBorderless", "showHover", "isSmallTable", "footerContent"]);
|
|
35
|
+
var _a = this.props, items = _a.items, showAddButton = _a.showAddButton, addButton = _a.addButton, filterPredicate = _a.filterPredicate, keyProperty = _a.keyProperty, allowSort = _a.allowSort, expandAll = _a.expandAll, collapseAll = _a.collapseAll, initialSort = _a.initialSort, initialSortAscending = _a.initialSortAscending, isBordered = _a.isBordered, isStriped = _a.isStriped, isBorderless = _a.isBorderless, showHover = _a.showHover, isSmallTable = _a.isSmallTable, footerContent = _a.footerContent, footerButtons = _a.footerButtons, domProps = __rest(_a, ["items", "showAddButton", "addButton", "filterPredicate", "keyProperty", "allowSort", "expandAll", "collapseAll", "initialSort", "initialSortAscending", "isBordered", "isStriped", "isBorderless", "showHover", "isSmallTable", "footerContent", "footerButtons"]);
|
|
36
36
|
if (expandAll === true) {
|
|
37
37
|
this.gridContext.expandAll = true;
|
|
38
38
|
}
|
|
@@ -90,11 +90,12 @@ var Grid = /** @class */ (function (_super) {
|
|
|
90
90
|
React.createElement(GridContext.Provider, { value: this.gridContext },
|
|
91
91
|
React.createElement(TableSection, { type: "header" }, this.headerItem && this.props.children(this.headerItem, this.headerItem.meta)),
|
|
92
92
|
React.createElement(TableSection, { type: "body" }, this.gridContext.dataView.getItems().map(function (item) { return (React.createElement(ItemGroup, { item: item, key: keyProperty ? item[keyProperty] : item.entityIdentifier, template: _this.props.children })); })),
|
|
93
|
-
React.createElement(Observer, null, function () { return (showAddButton || addButton || _this.gridContext.hasSummaries || footerContent !== undefined) &&
|
|
93
|
+
React.createElement(Observer, null, function () { return (showAddButton || addButton || footerButtons || _this.gridContext.hasSummaries || footerContent !== undefined) &&
|
|
94
94
|
React.createElement(TableSection, { type: "footer" },
|
|
95
95
|
_this.gridContext.hasSummaries && _this.headerItem && _this.props.children(_this.headerItem, _this.headerItem.meta),
|
|
96
96
|
footerContent !== undefined && footerContent(_this.gridContext.dataView.getItems()),
|
|
97
|
-
(showAddButton || addButton
|
|
97
|
+
(showAddButton || addButton || footerButtons) &&
|
|
98
|
+
React.createElement(AddButtonRow, { addButton: addButton, showAddButton: showAddButton, additionalContent: footerButtons })); }))));
|
|
98
99
|
};
|
|
99
100
|
Grid.prototype.setInitialSort = function (initialSort, initialSortAscending) {
|
|
100
101
|
var _a;
|
|
@@ -171,12 +172,15 @@ var AddButtonRow = /** @class */ (function (_super) {
|
|
|
171
172
|
}
|
|
172
173
|
};
|
|
173
174
|
AddButtonRow.prototype.render = function () {
|
|
174
|
-
var
|
|
175
|
+
var _a = this.props, addButton = _a.addButton, showAddButton = _a.showAddButton, additionalContent = _a.additionalContent;
|
|
176
|
+
var addButtonOptions = Utils.populatePartialWithDefaults(addButton, __assign({}, Misc.Settings.grid.addButton));
|
|
175
177
|
if (!addButtonOptions.onClick)
|
|
176
178
|
addButtonOptions.onClick = this.onAddNew;
|
|
177
179
|
return (React.createElement("tr", { ref: this.domRef },
|
|
178
180
|
React.createElement("td", { colSpan: this.context.columnCount + (this.context.expandProperty ? 1 : 0) },
|
|
179
|
-
React.createElement(
|
|
181
|
+
React.createElement("div", { className: "neo-grid-button-row" },
|
|
182
|
+
showAddButton !== false && React.createElement(NeoButton, __assign({}, addButtonOptions)),
|
|
183
|
+
additionalContent !== undefined && additionalContent()))));
|
|
180
184
|
};
|
|
181
185
|
AddButtonRow.contextType = GridContext;
|
|
182
186
|
return AddButtonRow;
|
|
@@ -41,13 +41,16 @@ var Modal = /** @class */ (function (_super) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
show = !!propertyInstance.value;
|
|
44
|
-
onClose = function () {
|
|
44
|
+
onClose = function (event) {
|
|
45
45
|
if (propertyInstance.value === true) {
|
|
46
46
|
propertyInstance.value = false;
|
|
47
47
|
}
|
|
48
48
|
else {
|
|
49
49
|
propertyInstance.value = null;
|
|
50
50
|
}
|
|
51
|
+
if (_this.props.onClose) {
|
|
52
|
+
_this.props.onClose(event);
|
|
53
|
+
}
|
|
51
54
|
};
|
|
52
55
|
}
|
|
53
56
|
else {
|
|
@@ -45,7 +45,7 @@ var FormatState = /** @class */ (function () {
|
|
|
45
45
|
return this.zeroText;
|
|
46
46
|
}
|
|
47
47
|
if (value !== undefined && value !== null) {
|
|
48
|
-
if (value instanceof
|
|
48
|
+
if (value instanceof Misc.Globals.decimalType) {
|
|
49
49
|
value = value.toNumber();
|
|
50
50
|
}
|
|
51
51
|
if (typeof value === "number") {
|
|
@@ -65,6 +65,8 @@ var FormatState = /** @class */ (function () {
|
|
|
65
65
|
return FormatState;
|
|
66
66
|
}());
|
|
67
67
|
export { FormatState };
|
|
68
|
+
// Taken from https://github.com/MikeMcl/decimal.js-light/blob/master/decimal.js since it is not exported.
|
|
69
|
+
var validDecimalRegex = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i;
|
|
68
70
|
var NumberInput = /** @class */ (function (_super) {
|
|
69
71
|
__extends(NumberInput, _super);
|
|
70
72
|
function NumberInput(props) {
|
|
@@ -82,8 +84,10 @@ var NumberInput = /** @class */ (function (_super) {
|
|
|
82
84
|
}
|
|
83
85
|
NumberInput.prototype.onChanged = function (e) {
|
|
84
86
|
var newValue;
|
|
85
|
-
if (e.target.value !== ""
|
|
86
|
-
|
|
87
|
+
if (e.target.value !== "") {
|
|
88
|
+
if (isNaN(parseFloat(e.target.value)) || !validDecimalRegex.test(e.target.value)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
87
91
|
}
|
|
88
92
|
if (e.target.value == "") {
|
|
89
93
|
newValue = this.props.bind.propertyInfo.allowNulls ? null : new Decimal(0);
|
|
@@ -122,7 +126,7 @@ var NumberInput = /** @class */ (function (_super) {
|
|
|
122
126
|
};
|
|
123
127
|
NumberInput.prototype.getBindValueAsNumber = function () {
|
|
124
128
|
var propertyValue = this.props.bind.value;
|
|
125
|
-
if (propertyValue instanceof
|
|
129
|
+
if (propertyValue instanceof Misc.Globals.decimalType) {
|
|
126
130
|
return propertyValue.toNumber();
|
|
127
131
|
}
|
|
128
132
|
else {
|
|
@@ -36,6 +36,7 @@ import Tab from './Tabs/Tab';
|
|
|
36
36
|
import Toast from './Notifications/Toast';
|
|
37
37
|
import ToastContainer from './Notifications/ToastContainer';
|
|
38
38
|
import Tooltip from './Tooltip';
|
|
39
|
+
import { TooltipHelper } from './TooltipHelper';
|
|
39
40
|
import TooltipProvider from './TooltipProvider';
|
|
40
41
|
import ValidationSummary from './ValidationSummary';
|
|
41
|
-
export { Alert, AutoCompleteDropDown, Button, Card, Checkbox, Collapsable, ColorPicker, ContextMenuContainer, DatePicker, DropDown, FileBasicInput, FileContext, FileDropArea, FileInput, FileUploadButton, FileUploadProgress, Form, FormContext, FormGroup, FormGroupFloating, FormGroupInline, GridLayout, Input, Link, Loader, Modal, ModalContainer, NumberInput, Pager, PagerControlsBasic, PageSizeControl, Passwordbox, ProgressBar, RadioList, Slider, TabContainer, Tab, Textbox, Toast, ToastContainer, Tooltip, TooltipProvider, ValidationSummary };
|
|
42
|
+
export { Alert, AutoCompleteDropDown, Button, Card, Checkbox, Collapsable, ColorPicker, ContextMenuContainer, DatePicker, DropDown, FileBasicInput, FileContext, FileDropArea, FileInput, FileUploadButton, FileUploadProgress, Form, FormContext, FormGroup, FormGroupFloating, FormGroupInline, GridLayout, Input, Link, Loader, Modal, ModalContainer, NumberInput, Pager, PagerControlsBasic, PageSizeControl, Passwordbox, ProgressBar, RadioList, Slider, TabContainer, Tab, Textbox, Toast, ToastContainer, Tooltip, TooltipHelper, TooltipProvider, ValidationSummary };
|
|
@@ -36,6 +36,7 @@ import Tab from './Tabs/Tab';
|
|
|
36
36
|
import Toast from './Notifications/Toast';
|
|
37
37
|
import ToastContainer from './Notifications/ToastContainer';
|
|
38
38
|
import Tooltip from './Tooltip';
|
|
39
|
+
import { TooltipHelper } from './TooltipHelper';
|
|
39
40
|
import TooltipProvider from './TooltipProvider';
|
|
40
41
|
import ValidationSummary from './ValidationSummary';
|
|
41
|
-
export { Alert, AutoCompleteDropDown, Button, Card, Checkbox, Collapsable, ColorPicker, ContextMenuContainer, DatePicker, DropDown, FileBasicInput, FileContext, FileDropArea, FileInput, FileUploadButton, FileUploadProgress, Form, FormContext, FormGroup, FormGroupFloating, FormGroupInline, GridLayout, Input, Link, Loader, Modal, ModalContainer, NumberInput, Pager, PagerControlsBasic, PageSizeControl, Passwordbox, ProgressBar, RadioList, Slider, TabContainer, Tab, Textbox, Toast, ToastContainer, Tooltip, TooltipProvider, ValidationSummary };
|
|
42
|
+
export { Alert, AutoCompleteDropDown, Button, Card, Checkbox, Collapsable, ColorPicker, ContextMenuContainer, DatePicker, DropDown, FileBasicInput, FileContext, FileDropArea, FileInput, FileUploadButton, FileUploadProgress, Form, FormContext, FormGroup, FormGroupFloating, FormGroupInline, GridLayout, Input, Link, Loader, Modal, ModalContainer, NumberInput, Pager, PagerControlsBasic, PageSizeControl, Passwordbox, ProgressBar, RadioList, Slider, TabContainer, Tab, Textbox, Toast, ToastContainer, Tooltip, TooltipHelper, TooltipProvider, ValidationSummary };
|
|
@@ -19,6 +19,7 @@ export default abstract class ViewModelBase extends ModelBase implements IViewMo
|
|
|
19
19
|
registerReaction<T>(expression: () => T, effect: (value: T) => void): IReactionDisposer;
|
|
20
20
|
/**
|
|
21
21
|
* Instantiates, and registers a child view model that will be disposed when this view model is disposed.
|
|
22
|
+
* The task runner will be passed to the new vm from this one.
|
|
22
23
|
* @param viewModel View model type.
|
|
23
24
|
*/
|
|
24
25
|
registerViewModel<TViewModel extends IViewModel>(viewModel: new () => TViewModel, options?: {
|
|
@@ -37,7 +38,14 @@ export default abstract class ViewModelBase extends ModelBase implements IViewMo
|
|
|
37
38
|
* Uses the task runner to call an api endpoint. The returned data is deserialised into an instance of the provided model type.
|
|
38
39
|
*/
|
|
39
40
|
waitForModel<T extends BindableBase>(modelType: typeof BindableBase, task: AxiosPromise<Model.PlainTrackedObject<T>>, options?: Partial<WaitForTaskRunnerOptions<Model.PlainTrackedObject<T>>>): Promise<T>;
|
|
41
|
+
/**
|
|
42
|
+
* Registers the object for disposal when this viewmodel is disposed.
|
|
43
|
+
*/
|
|
40
44
|
autoDispose<T extends Misc.IDisposable>(disposable: T): T;
|
|
45
|
+
/**
|
|
46
|
+
* Binds a list of functions to the viewmodel instance.
|
|
47
|
+
*/
|
|
48
|
+
protected bindMethods(...fns: Function[]): void;
|
|
41
49
|
dispose(): void;
|
|
42
50
|
/**
|
|
43
51
|
* Creates a view model instance.
|
|
@@ -59,9 +59,30 @@ var ViewModelBase = /** @class */ (function (_super) {
|
|
|
59
59
|
});
|
|
60
60
|
});
|
|
61
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* Registers the object for disposal when this viewmodel is disposed.
|
|
64
|
+
*/
|
|
62
65
|
ViewModelBase.prototype.autoDispose = function (disposable) {
|
|
63
66
|
return this.disposeHelper.autoDispose(disposable);
|
|
64
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* Binds a list of functions to the viewmodel instance.
|
|
70
|
+
*/
|
|
71
|
+
ViewModelBase.prototype.bindMethods = function () {
|
|
72
|
+
var fns = [];
|
|
73
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
74
|
+
fns[_i] = arguments[_i];
|
|
75
|
+
}
|
|
76
|
+
for (var _a = 0, fns_1 = fns; _a < fns_1.length; _a++) {
|
|
77
|
+
var fn = fns_1[_a];
|
|
78
|
+
if (fn.name) {
|
|
79
|
+
this[fn.name] = fn.bind(this);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
throw "Cannot bind a function without a name.";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
65
86
|
ViewModelBase.prototype.dispose = function () {
|
|
66
87
|
this.disposeHelper.dispose();
|
|
67
88
|
for (var _i = 0, _a = this.trackedViewModels; _i < _a.length; _i++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@singularsystems/neo-react",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.43",
|
|
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",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@types/rc-slider": "^8.6.5",
|
|
34
34
|
"@types/react-color": "^3.0.1",
|
|
35
35
|
"@types/react-select": "3.1.0",
|
|
36
|
-
"@singularsystems/neo-core": "^0.10.
|
|
36
|
+
"@singularsystems/neo-core": "^0.10.50",
|
|
37
37
|
"axios": "^0.21.1",
|
|
38
38
|
"decimal.js-light": "2.5.1",
|
|
39
39
|
"history": "4.10.1",
|
package/styles/Forms.scss
CHANGED
|
@@ -139,8 +139,26 @@ div.neo-form-group-floating {
|
|
|
139
139
|
justify-content: space-between;
|
|
140
140
|
border-bottom: 1px solid #eee;
|
|
141
141
|
cursor: pointer;
|
|
142
|
-
|
|
142
|
+
|
|
143
|
+
&.with-description {
|
|
144
|
+
div.react-select-name {
|
|
145
|
+
width: 100%;
|
|
146
|
+
}
|
|
147
|
+
div.react-select-description {
|
|
148
|
+
font-size: 0.9rem;
|
|
149
|
+
color: #999;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
143
153
|
&.focused, &:hover {
|
|
144
154
|
background: $input-btn-focus-color;
|
|
145
155
|
}
|
|
156
|
+
&.selected {
|
|
157
|
+
background: #1E90FF;
|
|
158
|
+
color: #fff;
|
|
159
|
+
|
|
160
|
+
div.react-select-description {
|
|
161
|
+
color: #C7E4FF;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
146
164
|
}
|