@michalrakus/x-react-web-lib 1.5.0 → 1.6.0

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.
@@ -0,0 +1,3 @@
1
+ // generated by gulp
2
+
3
+ export * from './lib/components/XButtonIconMedium';
@@ -0,0 +1,5 @@
1
+ // generated by gulp
2
+
3
+ 'use strict';
4
+
5
+ module.exports = require('./lib/components/XButtonIconMedium.js');
@@ -0,0 +1,3 @@
1
+ // generated by gulp
2
+
3
+ export * from './lib/components/XFormBaseModif';
@@ -0,0 +1,5 @@
1
+ // generated by gulp
2
+
3
+ 'use strict';
4
+
5
+ module.exports = require('./lib/components/XFormBaseModif.js');
@@ -0,0 +1,3 @@
1
+ // generated by gulp
2
+
3
+ export * from './lib/components/XInputFileList';
@@ -0,0 +1,5 @@
1
+ // generated by gulp
2
+
3
+ 'use strict';
4
+
5
+ module.exports = require('./lib/components/XInputFileList.js');
package/gulpfile.js CHANGED
@@ -18,6 +18,7 @@ function generateApi(cb) {
18
18
  "./lib/components/XAutoCompleteBase",
19
19
  "./lib/components/XBrowse",
20
20
  "./lib/components/XButton",
21
+ "./lib/components/XButtonIconMedium",
21
22
  "./lib/components/XButtonIconNarrow",
22
23
  "./lib/components/XButtonIconSmall",
23
24
  "./lib/components/XCalendar",
@@ -29,6 +30,7 @@ function generateApi(cb) {
29
30
  "./lib/components/XErrors",
30
31
  "./lib/components/XFieldChangeEvent",
31
32
  "./lib/components/XFormBase",
33
+ "./lib/components/XFormBaseModif",
32
34
  "./lib/components/XFormBaseT",
33
35
  "./lib/components/XFormDataTable2",
34
36
  "./lib/components/XFormFooter",
@@ -37,6 +39,7 @@ function generateApi(cb) {
37
39
  "./lib/components/XInputDate",
38
40
  "./lib/components/XInputDecimal",
39
41
  "./lib/components/XInputDecimalBase",
42
+ "./lib/components/XInputFileList",
40
43
  "./lib/components/XInputText",
41
44
  "./lib/components/XInputTextarea",
42
45
  "./lib/components/XLazyDataTable",
@@ -47,7 +47,7 @@ var XUtils_1 = require("../components/XUtils");
47
47
  var XUserBrowse = function (props) {
48
48
  var onAddRow = function () {
49
49
  // openForm pridavame automaticky v XFormNavigator3 pri renderovani komponentu
50
- props.openForm(react_1.default.createElement(XUserForm_1.XUserForm, { object: { enabled: true } }));
50
+ props.openForm(react_1.default.createElement(XUserForm_1.XUserForm, { object: { enabled: true, version: 0 } }));
51
51
  };
52
52
  var onEdit = function (selectedRow) {
53
53
  // openForm pridavame automaticky v XFormNavigator3 pri renderovani komponentu
@@ -1,6 +1,7 @@
1
1
  /// <reference types="react" />
2
- import { FormProps, XFormBase } from "../components/XFormBase";
3
- export declare class XUserForm extends XFormBase {
2
+ import { FormProps } from "../components/XFormBase";
3
+ import { XFormBaseModif } from "../components/XFormBaseModif";
4
+ export declare class XUserForm extends XFormBaseModif {
4
5
  constructor(props: FormProps);
5
6
  componentDidMount(): Promise<void>;
6
7
  onClickSave(): Promise<void>;
@@ -73,6 +73,8 @@ var XUtils_1 = require("../components/XUtils");
73
73
  var XFormFooter_1 = require("../components/XFormFooter");
74
74
  var XCheckbox_1 = require("../components/XCheckbox");
75
75
  var XEnvVars_1 = require("../components/XEnvVars");
76
+ var XFormBaseModif_1 = require("../components/XFormBaseModif");
77
+ var XInputDate_1 = require("../components/XInputDate");
76
78
  var XUserForm = /** @class */ (function (_super) {
77
79
  __extends(XUserForm, _super);
78
80
  function XUserForm(props) {
@@ -138,6 +140,7 @@ var XUserForm = /** @class */ (function (_super) {
138
140
  this.state.object.password = undefined;
139
141
  }
140
142
  }
143
+ this.preSave(this.state.object);
141
144
  _a.label = 1;
142
145
  case 1:
143
146
  _a.trys.push([1, 3, , 4]);
@@ -177,7 +180,9 @@ var XUserForm = /** @class */ (function (_super) {
177
180
  react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "username", label: "Username", size: 30, labelStyle: { width: '14rem' }, readOnly: this.state.usernameEnabledReadOnly }),
178
181
  react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "name", label: "Name", size: 30, labelStyle: { width: '14rem' } }),
179
182
  react_1.default.createElement(XCheckbox_1.XCheckbox, { form: this, field: "enabled", label: "Enabled", labelStyle: { width: '14rem' }, readOnly: this.state.usernameEnabledReadOnly }),
180
- passwordElems)),
183
+ passwordElems,
184
+ react_1.default.createElement(XInputDate_1.XInputDate, { form: this, field: "modifDate", label: "Modified at", readOnly: true, labelStyle: { width: '14rem' } }),
185
+ react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "modifXUser.name", label: "Modified by", size: 20, labelStyle: { width: '14rem' } }))),
181
186
  react_1.default.createElement(XFormFooter_1.XFormFooter, { form: this })));
182
187
  };
183
188
  XUserForm = __decorate([
@@ -185,5 +190,5 @@ var XUserForm = /** @class */ (function (_super) {
185
190
  __metadata("design:paramtypes", [Object])
186
191
  ], XUserForm);
187
192
  return XUserForm;
188
- }(XFormBase_1.XFormBase));
193
+ }(XFormBaseModif_1.XFormBaseModif));
189
194
  exports.XUserForm = XUserForm;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { ButtonProps } from "primereact/button";
3
+ import { IconType } from "primereact/utils";
4
+ export declare const XButtonIconMedium: (props: {
5
+ icon: IconType<ButtonProps>;
6
+ onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
7
+ disabled?: boolean | undefined;
8
+ tooltip?: any;
9
+ }) => JSX.Element;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.XButtonIconMedium = void 0;
7
+ var react_1 = __importDefault(require("react"));
8
+ var button_1 = require("primereact/button");
9
+ // button trochu mensi (priblizne 30px x 30px) od klasickeho Button, pri pouziti v datatable nastavuje v TD malicky padding (cez css) -> nezvecsuje vysku riadku
10
+ var XButtonIconMedium = function (props) {
11
+ return (react_1.default.createElement(button_1.Button, { icon: props.icon, onClick: props.onClick, disabled: props.disabled, className: 'x-button-icon-medium p-button-sm', tooltip: props.tooltip }));
12
+ };
13
+ exports.XButtonIconMedium = XButtonIconMedium;
@@ -5,6 +5,7 @@ import { XObject } from "./XObject";
5
5
  export interface XDropdownProps extends XFormComponentProps<XObject> {
6
6
  assocField: string;
7
7
  displayField: string;
8
+ sortField?: string;
8
9
  filter?: XFilterProp;
9
10
  }
10
11
  export declare class XDropdown extends XFormComponent<XObject, XDropdownProps> {
@@ -50,7 +50,7 @@ var XDropdown = /** @class */ (function (_super) {
50
50
  // planuje sa to riesit bud zavedenim cache pre options alebo vytiahnutim options na uroven XFormBase
51
51
  return (react_1.default.createElement("div", { className: "field grid" },
52
52
  react_1.default.createElement("label", { htmlFor: this.props.assocField, className: "col-fixed", style: this.getLabelStyle() }, this.getLabel()),
53
- react_1.default.createElement(XDropdownForEntity_1.XDropdownForEntity, { id: this.props.assocField, entity: this.xAssoc.entityName, displayField: this.props.displayField, value: this.getValue(), onChange: function (value) { return _this.onValueChangeBase(value, _this.props.onChange); }, readOnly: this.isReadOnly(), isNotNull: this.isNotNull(), error: this.getError(), filter: this.getFilterBase(this.props.filter) })));
53
+ react_1.default.createElement(XDropdownForEntity_1.XDropdownForEntity, { id: this.props.assocField, entity: this.xAssoc.entityName, displayField: this.props.displayField, sortField: this.props.sortField, value: this.getValue(), onChange: function (value) { return _this.onValueChangeBase(value, _this.props.onChange); }, readOnly: this.isReadOnly(), isNotNull: this.isNotNull(), error: this.getError(), filter: this.getFilterBase(this.props.filter) })));
54
54
  };
55
55
  return XDropdown;
56
56
  }(XFormComponent_1.XFormComponent));
@@ -5,6 +5,7 @@ export interface XDropdownForEntityProps {
5
5
  id?: string;
6
6
  entity: string;
7
7
  displayField: string;
8
+ sortField?: string;
8
9
  value: any | null;
9
10
  onChange: (value: any | null) => void;
10
11
  readOnly?: boolean;
@@ -110,13 +110,14 @@ var XDropdownForEntity = /** @class */ (function (_super) {
110
110
  this.loadOptions();
111
111
  };
112
112
  XDropdownForEntity.prototype.loadOptions = function () {
113
+ var _a;
113
114
  return __awaiter(this, void 0, void 0, function () {
114
115
  var options;
115
- return __generator(this, function (_a) {
116
- switch (_a.label) {
117
- case 0: return [4 /*yield*/, XUtils_1.XUtils.fetchRows(this.props.entity, this.props.filter, this.props.displayField)];
116
+ return __generator(this, function (_b) {
117
+ switch (_b.label) {
118
+ case 0: return [4 /*yield*/, XUtils_1.XUtils.fetchRows(this.props.entity, this.props.filter, (_a = this.props.sortField) !== null && _a !== void 0 ? _a : this.props.displayField)];
118
119
  case 1:
119
- options = _a.sent();
120
+ options = _b.sent();
120
121
  if (this.props.isNotNull === undefined || !this.props.isNotNull) {
121
122
  // pridame prazdnu polozku
122
123
  options.splice(0, 0, {}); // null polozka
@@ -0,0 +1,5 @@
1
+ import { XFormBase } from "./XFormBase";
2
+ import { XObject } from "./XObject";
3
+ export declare class XFormBaseModif extends XFormBase {
4
+ preSave(object: XObject): void;
5
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.XFormBaseModif = void 0;
19
+ var XFormBase_1 = require("./XFormBase");
20
+ var XUtils_1 = require("./XUtils");
21
+ var XFormBaseModif = /** @class */ (function (_super) {
22
+ __extends(XFormBaseModif, _super);
23
+ function XFormBaseModif() {
24
+ return _super !== null && _super.apply(this, arguments) || this;
25
+ }
26
+ XFormBaseModif.prototype.preSave = function (object) {
27
+ var _a;
28
+ object.modifDate = new Date();
29
+ object.modifXUser = (_a = XUtils_1.XUtils.getXToken()) === null || _a === void 0 ? void 0 : _a.xUser;
30
+ };
31
+ return XFormBaseModif;
32
+ }(XFormBase_1.XFormBase));
33
+ exports.XFormBaseModif = XFormBaseModif;
@@ -24,12 +24,14 @@ export interface XFormDataTableProps {
24
24
  rows?: number;
25
25
  filterDisplay: "menu" | "row" | "none";
26
26
  sortable: boolean;
27
+ sortField?: string;
27
28
  scrollable: boolean;
28
29
  scrollWidth?: string;
29
30
  scrollHeight?: string;
30
31
  shrinkWidth: boolean;
31
32
  label?: string;
32
33
  readOnly?: boolean;
34
+ showAddRemoveButtons?: boolean;
33
35
  onClickAddRow?: () => void;
34
36
  onClickRemoveRow?: (row: any) => void;
35
37
  removeButtonInRow: boolean;
@@ -48,6 +50,7 @@ export declare class XFormDataTable2 extends Component<XFormDataTableProps> {
48
50
  scrollWidth: string;
49
51
  scrollHeight: string;
50
52
  shrinkWidth: boolean;
53
+ showAddRemoveButtons: boolean;
51
54
  removeButtonInRow: boolean;
52
55
  addRowLabel: string;
53
56
  removeRowLabel: string;
@@ -612,7 +612,7 @@ var XFormDataTable2 = /** @class */ (function (_super) {
612
612
  // }
613
613
  return react_1.default.createElement(column_1.Column, { field: field, header: header, filter: thisLocal.props.filterDisplay !== "none", sortable: thisLocal.props.sortable, filterElement: filterElement, showFilterMenu: showFilterMenu, showClearButton: showClearButton, headerStyle: headerStyle, align: align, body: function (rowData) { return thisLocal.bodyTemplate(childColumnProps, readOnly, rowData, xEntity); } });
614
614
  });
615
- if (this.props.removeButtonInRow) {
615
+ if (this.props.showAddRemoveButtons && this.props.removeButtonInRow) {
616
616
  // je dolezite nastavit sirku header-a, lebo inac ma stlpec sirku 0 a nevidno ho
617
617
  columnElemList.push(react_1.default.createElement(column_1.Column, { key: "removeButton", headerStyle: { width: '2rem' }, body: function (rowData) { return react_1.default.createElement(XButtonIconNarrow_1.XButtonIconNarrow, { icon: "pi pi-times", onClick: function () { return _this.removeRow(rowData); }, disabled: readOnly, addMargin: false }); } }));
618
618
  }
@@ -620,10 +620,12 @@ var XFormDataTable2 = /** @class */ (function (_super) {
620
620
  react_1.default.createElement("div", { className: "flex justify-content-center" },
621
621
  react_1.default.createElement("label", null, label)),
622
622
  react_1.default.createElement("div", { className: "flex justify-content-center" },
623
- react_1.default.createElement(datatable_1.DataTable, { ref: function (el) { return _this.dt = el; }, value: valueList, dataKey: this.dataKey, paginator: paginator, rows: rows, totalRecords: valueList.length, filterDisplay: filterDisplay, filters: this.state.filters, onFilter: this.onFilter, sortMode: "multiple", removableSort: true, selectionMode: "single", selection: this.state.selectedRow, onSelectionChange: this.onSelectionChange, className: "p-datatable-sm x-form-datatable", resizableColumns: true, columnResizeMode: "expand", tableStyle: tableStyle, scrollable: this.props.scrollable, scrollHeight: scrollHeight, style: style }, columnElemList)),
624
- react_1.default.createElement("div", { className: "flex justify-content-center" },
625
- react_1.default.createElement(XButton_1.XButton, { icon: this.props.addRowIcon, label: this.props.addRowLabel, onClick: this.onClickAddRow, disabled: readOnly }),
626
- this.props.removeButtonInRow ? undefined : react_1.default.createElement(XButton_1.XButton, { icon: this.props.removeRowIcon, label: this.props.removeRowLabel, onClick: this.onClickRemoveRowBySelection, disabled: readOnly }))));
623
+ react_1.default.createElement(datatable_1.DataTable, { ref: function (el) { return _this.dt = el; }, value: valueList, dataKey: this.dataKey, paginator: paginator, rows: rows, totalRecords: valueList.length, filterDisplay: filterDisplay, filters: this.state.filters, onFilter: this.onFilter, sortMode: "multiple", removableSort: true, multiSortMeta: this.props.sortField !== undefined ? [{ field: this.props.sortField, order: 1 }] : undefined, selectionMode: "single", selection: this.state.selectedRow, onSelectionChange: this.onSelectionChange, className: "p-datatable-sm x-form-datatable", resizableColumns: true, columnResizeMode: "expand", tableStyle: tableStyle, scrollable: this.props.scrollable, scrollHeight: scrollHeight, style: style }, columnElemList)),
624
+ this.props.showAddRemoveButtons ?
625
+ react_1.default.createElement("div", { className: "flex justify-content-center" },
626
+ react_1.default.createElement(XButton_1.XButton, { icon: this.props.addRowIcon, label: this.props.addRowLabel, onClick: this.onClickAddRow, disabled: readOnly }),
627
+ this.props.removeButtonInRow ? undefined : react_1.default.createElement(XButton_1.XButton, { icon: this.props.removeRowIcon, label: this.props.removeRowLabel, onClick: this.onClickRemoveRowBySelection, disabled: readOnly }))
628
+ : undefined));
627
629
  };
628
630
  XFormDataTable2.defaultProps = {
629
631
  filterDisplay: "row",
@@ -633,6 +635,7 @@ var XFormDataTable2 = /** @class */ (function (_super) {
633
635
  scrollHeight: '200vh',
634
636
  // tym ze pouzivame 200vh (max-height pre body), tak realne scrollovanie sa zapne az pri velmi vela riadkoch
635
637
  shrinkWidth: true,
638
+ showAddRemoveButtons: true,
636
639
  removeButtonInRow: false,
637
640
  addRowLabel: 'Add row',
638
641
  removeRowLabel: 'Remove row'
@@ -0,0 +1,35 @@
1
+ import { Component } from "react";
2
+ import { FileUploadHandlerEvent } from "primereact/fileupload";
3
+ import { XFormBase } from "./XFormBase";
4
+ interface XFile {
5
+ id: number;
6
+ name: string;
7
+ size: number;
8
+ pathName?: string;
9
+ }
10
+ export interface XInputFileListProps {
11
+ form: XFormBase;
12
+ assocField: string;
13
+ label?: string;
14
+ chooseLabel?: string;
15
+ readOnly?: boolean;
16
+ saveDest: "fileSystem" | "database";
17
+ subdir?: string;
18
+ }
19
+ export declare class XInputFileList extends Component<XInputFileListProps> {
20
+ static defaultProps: {
21
+ chooseLabel: string;
22
+ saveDest: string;
23
+ };
24
+ fileUploadRef: any;
25
+ props: XInputFileListProps;
26
+ entity: string;
27
+ idField: string;
28
+ xFileField: string;
29
+ constructor(props: XInputFileListProps);
30
+ uploadHandler(event: FileUploadHandlerEvent): Promise<void>;
31
+ onDownloadFile(xFile: XFile): Promise<void>;
32
+ onRemoveFile(fileItem: any): Promise<void>;
33
+ render(): JSX.Element;
34
+ }
35
+ export {};
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
+ return new (P || (P = Promise))(function (resolve, reject) {
20
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
24
+ });
25
+ };
26
+ var __generator = (this && this.__generator) || function (thisArg, body) {
27
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
28
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
29
+ function verb(n) { return function (v) { return step([n, v]); }; }
30
+ function step(op) {
31
+ if (f) throw new TypeError("Generator is already executing.");
32
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
33
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
34
+ if (y = 0, t) op = [op[0] & 2, t.value];
35
+ switch (op[0]) {
36
+ case 0: case 1: t = op; break;
37
+ case 4: _.label++; return { value: op[1], done: false };
38
+ case 5: _.label++; y = op[1]; op = [0]; continue;
39
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
40
+ default:
41
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
42
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
43
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
44
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
45
+ if (t[2]) _.ops.pop();
46
+ _.trys.pop(); continue;
47
+ }
48
+ op = body.call(thisArg, _);
49
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
50
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
+ }
52
+ };
53
+ var __values = (this && this.__values) || function(o) {
54
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
55
+ if (m) return m.call(o);
56
+ if (o && typeof o.length === "number") return {
57
+ next: function () {
58
+ if (o && i >= o.length) o = void 0;
59
+ return { value: o && o[i++], done: !o };
60
+ }
61
+ };
62
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
63
+ };
64
+ var __importDefault = (this && this.__importDefault) || function (mod) {
65
+ return (mod && mod.__esModule) ? mod : { "default": mod };
66
+ };
67
+ Object.defineProperty(exports, "__esModule", { value: true });
68
+ exports.XInputFileList = void 0;
69
+ var react_1 = __importDefault(require("react"));
70
+ var react_2 = require("react");
71
+ var fileupload_1 = require("primereact/fileupload");
72
+ var XUtilsMetadata_1 = require("./XUtilsMetadata");
73
+ var XUtils_1 = require("./XUtils");
74
+ var XButton_1 = require("./XButton");
75
+ var XButtonIconNarrow_1 = require("./XButtonIconNarrow");
76
+ var XInputFileList = /** @class */ (function (_super) {
77
+ __extends(XInputFileList, _super);
78
+ function XInputFileList(props) {
79
+ var _this = _super.call(this, props) || this;
80
+ _this.fileUploadRef = react_1.default.createRef();
81
+ _this.props = props;
82
+ var xEntityForm = XUtilsMetadata_1.XUtilsMetadata.getXEntity(props.form.getEntity());
83
+ var xAssocToMany = XUtilsMetadata_1.XUtilsMetadata.getXAssocToMany(xEntityForm, props.assocField);
84
+ _this.entity = xAssocToMany.entityName;
85
+ var xEntity = XUtilsMetadata_1.XUtilsMetadata.getXEntity(_this.entity);
86
+ _this.idField = xEntity.idField;
87
+ _this.xFileField = XUtilsMetadata_1.XUtilsMetadata.getXAssocToOneByAssocEntity(xEntity, 'XFile').name;
88
+ _this.onDownloadFile = _this.onDownloadFile.bind(_this);
89
+ _this.onRemoveFile = _this.onRemoveFile.bind(_this);
90
+ _this.uploadHandler = _this.uploadHandler.bind(_this);
91
+ var fieldFilename = "".concat(props.assocField, ".").concat(_this.xFileField, ".filename");
92
+ props.form.addField(fieldFilename);
93
+ return _this;
94
+ }
95
+ XInputFileList.prototype.uploadHandler = function (event) {
96
+ return __awaiter(this, void 0, void 0, function () {
97
+ var endpoint, _a, _b, file, xFile, e_1, newFileItem, e_2_1;
98
+ var e_2, _c;
99
+ return __generator(this, function (_d) {
100
+ switch (_d.label) {
101
+ case 0:
102
+ endpoint = this.props.saveDest === 'fileSystem' ? 'x-upload-file-into-file-system' : 'x-upload-file-into-db';
103
+ _d.label = 1;
104
+ case 1:
105
+ _d.trys.push([1, 9, 10, 11]);
106
+ _a = __values(event.files), _b = _a.next();
107
+ _d.label = 2;
108
+ case 2:
109
+ if (!!_b.done) return [3 /*break*/, 8];
110
+ file = _b.value;
111
+ xFile = void 0;
112
+ _d.label = 3;
113
+ case 3:
114
+ _d.trys.push([3, 5, , 6]);
115
+ return [4 /*yield*/, XUtils_1.XUtils.fetchFile(endpoint, { filename: file.name, subdir: this.props.subdir }, file)];
116
+ case 4:
117
+ xFile = _d.sent();
118
+ return [3 /*break*/, 6];
119
+ case 5:
120
+ e_1 = _d.sent();
121
+ XUtils_1.XUtils.showErrorMessage("Upload of file \"".concat(file.name, "\" failed."), e_1);
122
+ this.fileUploadRef.current.clear(); // vyprazdnime hidden input, nech moze user znova zadat subory
123
+ return [2 /*return*/]; // prerusime upload tohto a dalsich suborov
124
+ case 6:
125
+ newFileItem = {};
126
+ newFileItem[this.xFileField] = xFile;
127
+ this.props.form.onTableAddRow(this.props.assocField, newFileItem, this.idField);
128
+ _d.label = 7;
129
+ case 7:
130
+ _b = _a.next();
131
+ return [3 /*break*/, 2];
132
+ case 8: return [3 /*break*/, 11];
133
+ case 9:
134
+ e_2_1 = _d.sent();
135
+ e_2 = { error: e_2_1 };
136
+ return [3 /*break*/, 11];
137
+ case 10:
138
+ try {
139
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
140
+ }
141
+ finally { if (e_2) throw e_2.error; }
142
+ return [7 /*endfinally*/];
143
+ case 11:
144
+ // vymaze zaznamy v event.files (hidden input type="file"), sposobi ze tlacitko "+Pridat" otvori dialog na vyber suborov
145
+ this.fileUploadRef.current.clear();
146
+ return [2 /*return*/];
147
+ }
148
+ });
149
+ });
150
+ };
151
+ XInputFileList.prototype.onDownloadFile = function (xFile) {
152
+ return __awaiter(this, void 0, void 0, function () {
153
+ var response, e_3, fileName, respBlob, url, a;
154
+ return __generator(this, function (_a) {
155
+ switch (_a.label) {
156
+ case 0:
157
+ _a.trys.push([0, 2, , 3]);
158
+ return [4 /*yield*/, XUtils_1.XUtils.fetchBasicJson('x-download-file', { xFileId: xFile.id })];
159
+ case 1:
160
+ response = _a.sent();
161
+ return [3 /*break*/, 3];
162
+ case 2:
163
+ e_3 = _a.sent();
164
+ XUtils_1.XUtils.showErrorMessage("Download failed.", e_3);
165
+ return [2 /*return*/];
166
+ case 3:
167
+ fileName = xFile.name;
168
+ return [4 /*yield*/, response.blob()];
169
+ case 4:
170
+ respBlob = _a.sent();
171
+ url = window.URL.createObjectURL(respBlob);
172
+ a = document.createElement('a');
173
+ a.href = url;
174
+ a.download = fileName;
175
+ a.click();
176
+ return [2 /*return*/];
177
+ }
178
+ });
179
+ });
180
+ };
181
+ XInputFileList.prototype.onRemoveFile = function (fileItem) {
182
+ return __awaiter(this, void 0, void 0, function () {
183
+ return __generator(this, function (_a) {
184
+ // poznamka: nemozme zmazat zaznam na backend-e, lebo ak user ukonci editaciu formulara tlacitkom Cancel (alebo odide uplne prec),
185
+ // tak musime mat v databaze zachovany povodny stav dat/suborov
186
+ this.props.form.onTableRemoveRow(this.props.assocField, fileItem);
187
+ return [2 /*return*/];
188
+ });
189
+ });
190
+ };
191
+ XInputFileList.prototype.render = function () {
192
+ var e_4, _a;
193
+ var _this = this;
194
+ var _b, _c;
195
+ var label = (_b = this.props.label) !== null && _b !== void 0 ? _b : this.props.assocField;
196
+ var readOnly = this.props.form.formReadOnlyBase(this.props.assocField) || ((_c = this.props.readOnly) !== null && _c !== void 0 ? _c : false);
197
+ var object = this.props.form.state.object;
198
+ var fileItemList = object !== null ? object[this.props.assocField] : [];
199
+ var elemList = [];
200
+ var _loop_1 = function (fileItem) {
201
+ var xFile = fileItem[this_1.xFileField];
202
+ // p-inputgroup uklada child elementy do riadku (display:flex)
203
+ // TODO - pouzit XButtonIconSmall pre button na mazanie - problem je ze tam nevieme (narychlo) dat class m-1
204
+ elemList.push(react_1.default.createElement("div", { key: fileItem[this_1.idField].toString(), className: "p-inputgroup p-mb-1" },
205
+ react_1.default.createElement(XButton_1.XButton, { label: xFile.name, onClick: function () { return _this.onDownloadFile(xFile); } }),
206
+ react_1.default.createElement(XButtonIconNarrow_1.XButtonIconNarrow, { icon: "pi pi-times", onClick: function () { return _this.onRemoveFile(fileItem); }, disabled: readOnly })));
207
+ };
208
+ var this_1 = this;
209
+ try {
210
+ for (var fileItemList_1 = __values(fileItemList), fileItemList_1_1 = fileItemList_1.next(); !fileItemList_1_1.done; fileItemList_1_1 = fileItemList_1.next()) {
211
+ var fileItem = fileItemList_1_1.value;
212
+ _loop_1(fileItem);
213
+ }
214
+ }
215
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
216
+ finally {
217
+ try {
218
+ if (fileItemList_1_1 && !fileItemList_1_1.done && (_a = fileItemList_1.return)) _a.call(fileItemList_1);
219
+ }
220
+ finally { if (e_4) throw e_4.error; }
221
+ }
222
+ // vrchny div uklada child elementy pod seba (standardny display:block), zarovnane su dolava
223
+ return (react_1.default.createElement("div", null,
224
+ react_1.default.createElement("label", null, label),
225
+ elemList,
226
+ react_1.default.createElement(fileupload_1.FileUpload, { ref: this.fileUploadRef, mode: "basic", multiple: true, auto: true, customUpload: true, uploadHandler: this.uploadHandler, chooseLabel: this.props.chooseLabel, className: "m-1", disabled: readOnly })));
227
+ };
228
+ XInputFileList.defaultProps = {
229
+ chooseLabel: "Add",
230
+ saveDest: "fileSystem"
231
+ };
232
+ return XInputFileList;
233
+ }(react_2.Component));
234
+ exports.XInputFileList = XInputFileList;
@@ -1,5 +1,5 @@
1
1
  import React, { ReactChild } from 'react';
2
- import { DataTableFilterMetaData, DataTableOperatorFilterMetaData } from 'primereact/datatable';
2
+ import { DataTableFilterMeta, DataTableFilterMetaData, DataTableOperatorFilterMetaData } from 'primereact/datatable';
3
3
  import { ColumnBodyOptions, ColumnFilterElementTemplateOptions } from 'primereact/column';
4
4
  import { SearchTableParams } from "./SearchTableParams";
5
5
  import { XAggregateType, XCustomFilter } from "../serverApi/FindParam";
@@ -32,8 +32,9 @@ export interface XLazyDataTableProps {
32
32
  removeRow?: ((selectedRow: any) => Promise<boolean>) | boolean;
33
33
  onRemoveRow?: XOnSaveOrCancelProp;
34
34
  appButtons?: any;
35
+ filters?: DataTableFilterMeta;
35
36
  customFilter?: XCustomFilter;
36
- initSortField?: string;
37
+ sortField?: string;
37
38
  searchTableParams?: SearchTableParams;
38
39
  width?: string;
39
40
  dataLoadedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];
@@ -54,8 +55,14 @@ export declare const XLazyDataTable: {
54
55
  shrinkWidth: boolean;
55
56
  };
56
57
  };
58
+ export type XGetFilterItem = (field: string) => DataTableFilterMetaData | DataTableOperatorFilterMetaData;
57
59
  export type XSetFilterItem = (field: string, filterItem: DataTableFilterMetaData | DataTableOperatorFilterMetaData) => void;
58
- export type XFilterElementProp = (setFilterItem: XSetFilterItem, options: ColumnFilterElementTemplateOptions) => React.ReactNode;
60
+ export type XFilterElementParams = {
61
+ getFilterItem: XGetFilterItem;
62
+ setFilterItem: XSetFilterItem;
63
+ options: ColumnFilterElementTemplateOptions;
64
+ };
65
+ export type XFilterElementProp = (params: XFilterElementParams) => React.ReactNode;
59
66
  export interface XLazyColumnProps {
60
67
  field: string;
61
68
  header?: any;
@@ -204,6 +204,9 @@ var XLazyDataTable = function (props) {
204
204
  var _d = __read((0, react_1.useState)(0), 2), first = _d[0], setFirst = _d[1];
205
205
  var _e = __read((0, react_1.useState)(props.paginator ? props.rows : undefined), 2), rows = _e[0], setRows = _e[1];
206
206
  var filtersInit = createInitFilters();
207
+ if (props.filters) {
208
+ filtersInit = __assign(__assign({}, filtersInit), props.filters); // items from props.filters will replace existing items in filtersInit
209
+ }
207
210
  if (props.searchTableParams !== undefined) {
208
211
  var displayFieldFilter = props.searchTableParams.displayFieldFilter;
209
212
  if (displayFieldFilter !== undefined) {
@@ -213,7 +216,7 @@ var XLazyDataTable = function (props) {
213
216
  customFilter = XUtils_1.XUtils.filterAnd(customFilter, props.searchTableParams.customFilter);
214
217
  }
215
218
  var _f = __read((0, react_1.useState)(filtersInit), 2), filters = _f[0], setFilters = _f[1]; // filtrovanie na "controlled manner" (moze sa sem nainicializovat nejaka hodnota)
216
- var _g = __read((0, react_1.useState)(props.initSortField ? [{ field: props.initSortField, order: 1 }] : []), 2), multiSortMeta = _g[0], setMultiSortMeta = _g[1];
219
+ var _g = __read((0, react_1.useState)(props.sortField ? [{ field: props.sortField, order: 1 }] : []), 2), multiSortMeta = _g[0], setMultiSortMeta = _g[1];
217
220
  var _h = __read((0, react_1.useState)(null), 2), selectedRow = _h[0], setSelectedRow = _h[1];
218
221
  var _j = __read((_a = props.dataLoadedState) !== null && _a !== void 0 ? _a : (0, react_1.useState)(false), 2), dataLoaded = _j[0], setDataLoaded = _j[1]; // priznak kde si zapiseme, ci uz sme nacitali data
219
222
  var _k = __read((0, react_1.useState)(false), 2), exportRowsDialogOpened = _k[0], setExportRowsDialogOpened = _k[1];
@@ -271,6 +274,11 @@ var XLazyDataTable = function (props) {
271
274
  //console.log("zavolany onClickFilter");
272
275
  loadData();
273
276
  };
277
+ var onClickClearFilter = function () {
278
+ // najjednoduchsi sposob - pomeni aj pripadne nastavene matchMode hodnoty
279
+ var filtersInit = createInitFilters();
280
+ setFilters(filtersInit);
281
+ };
274
282
  var loadData = function () {
275
283
  loadDataBase({ resultType: FindParam_1.ResultType.RowCountAndPagedRows, first: first, rows: rows, filters: filters, customFilter: customFilter, multiSortMeta: multiSortMeta, entity: props.entity, fields: getFields(), aggregateItems: aggregateItems });
276
284
  };
@@ -522,6 +530,10 @@ var XLazyDataTable = function (props) {
522
530
  var filtersCloned = __assign({}, filters);
523
531
  setFilters(filtersCloned);
524
532
  };
533
+ // vseobecna specialna metodka pouzvana pri custom filtri (XLazyColumn.filterElement)
534
+ var getFilterItem = function (field) {
535
+ return filters[field];
536
+ };
525
537
  // vseobecna metodka - nastavi hodnotu do filtra
526
538
  // ak je matchMode === undefined, tak zachova povodnu hodnotu matchMode
527
539
  var setFilterValue = function (field, value, matchMode) {
@@ -750,8 +762,8 @@ var XLazyDataTable = function (props) {
750
762
  var filterElement;
751
763
  if (childColumn.props.filterElement !== undefined) {
752
764
  filterElement = function (options) {
753
- // compilator sa stazoval ze childColumn.props.filterElement muze byt undefined, preto som pridal "!"
754
- return childColumn.props.filterElement(setFilterItem, options);
765
+ // compilator sa stazoval ze childColumn.props.filterElement moze byt undefined, preto som pridal "!"
766
+ return childColumn.props.filterElement({ getFilterItem: getFilterItem, setFilterItem: setFilterItem, options: options });
755
767
  };
756
768
  }
757
769
  else {
@@ -872,7 +884,8 @@ var XLazyDataTable = function (props) {
872
884
  });
873
885
  return (react_1.default.createElement("div", null,
874
886
  react_1.default.createElement("div", { className: "flex justify-content-center" },
875
- react_1.default.createElement(XButton_1.XButton, { label: "Filter", onClick: onClickFilter })),
887
+ react_1.default.createElement(XButton_1.XButton, { label: "Filter", onClick: onClickFilter }),
888
+ react_1.default.createElement(XButton_1.XButton, { label: "Clear filter", onClick: onClickClearFilter })),
876
889
  react_1.default.createElement("div", { className: "flex justify-content-center" },
877
890
  react_1.default.createElement(datatable_1.DataTable, { value: value.rowList, dataKey: dataKey, paginator: props.paginator, rows: rows, totalRecords: value.totalRecords, lazy: true, first: first, onPage: onPage, loading: loading, filterDisplay: props.filterDisplay, filters: filters, onFilter: onFilter, sortMode: "multiple", removableSort: true, multiSortMeta: multiSortMeta, onSort: onSort, selectionMode: "single", selection: selectedRow, onSelectionChange: onSelectionChange, onRowDoubleClick: onRowDoubleClick, ref: dataTableEl, className: "p-datatable-sm x-lazy-datatable", resizableColumns: true, columnResizeMode: "expand", tableStyle: tableStyle, paginatorLeft: paginatorLeft, paginatorRight: paginatorRight, scrollable: props.scrollable, scrollHeight: scrollHeight, style: style }, columnElemList)),
878
891
  react_1.default.createElement("div", { className: "flex justify-content-center" },
@@ -501,8 +501,14 @@ var XUtils = /** @class */ (function () {
501
501
  XUtils.showErrorMessage = function (message, e) {
502
502
  var msg = message + XUtilsCommon_1.XUtilsCommon.newLine;
503
503
  if (e instanceof XResponseError_1.XResponseError) {
504
- msg += e.message + XUtilsCommon_1.XUtilsCommon.newLine;
505
- msg += JSON.stringify(e.xResponseErrorBody, null, 4);
504
+ // better error message for optimistic locking
505
+ if (e.xResponseErrorBody.exceptionName === 'OptimisticLockVersionMismatchError') {
506
+ msg += "The optimistic lock failed, someone else has changed the row during the editation. Sorry, you have to cancel the editation and start the editation again.";
507
+ }
508
+ else {
509
+ msg += e.message + XUtilsCommon_1.XUtilsCommon.newLine;
510
+ msg += JSON.stringify(e.xResponseErrorBody, null, 4);
511
+ }
506
512
  }
507
513
  else if (e instanceof Error) {
508
514
  msg += e.message;
@@ -28,5 +28,8 @@ export interface XAssoc {
28
28
  name: string;
29
29
  entityName: string;
30
30
  inverseAssocName?: string;
31
+ isCascadeInsert: boolean;
32
+ isCascadeUpdate: boolean;
33
+ isCascadeRemove: boolean;
31
34
  isNullable: boolean;
32
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michalrakus/x-react-web-lib",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "clean": "rimraf lib",