@michalrakus/x-react-web-lib 1.34.0 → 1.35.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.
Files changed (36) hide show
  1. package/XDocTemplateButton.d.ts +3 -0
  2. package/XDocTemplateButton.js +5 -0
  3. package/gulpfile.js +3 -0
  4. package/lib/administration/x-enum-enum.d.ts +12 -0
  5. package/lib/administration/x-enum-enum.js +2 -0
  6. package/lib/administration/x-enum.d.ts +10 -0
  7. package/lib/administration/x-enum.js +2 -0
  8. package/lib/components/XAutoComplete.d.ts +1 -0
  9. package/lib/components/XAutoComplete.js +1 -1
  10. package/lib/components/XAutoCompleteBase.d.ts +2 -0
  11. package/lib/components/XAutoCompleteBase.js +6 -2
  12. package/lib/components/XAutoCompleteDT.d.ts +1 -0
  13. package/lib/components/XAutoCompleteDT.js +1 -1
  14. package/lib/components/XFormFooter.d.ts +4 -0
  15. package/lib/components/XFormFooter.js +20 -1
  16. package/lib/components/XInputFileList.js +6 -27
  17. package/lib/components/XLazyDataTable/XExportRowsDialog.js +37 -59
  18. package/lib/components/XLazyDataTable/XLazyDataTable.d.ts +13 -4
  19. package/lib/components/XLazyDataTable/XLazyDataTable.js +104 -79
  20. package/lib/components/XUtils.d.ts +1 -0
  21. package/lib/components/XUtils.js +15 -6
  22. package/lib/modules/docTemplates/XDocTemplateButton.d.ts +7 -0
  23. package/lib/modules/docTemplates/XDocTemplateButton.js +150 -0
  24. package/lib/modules/docTemplates/xt-doc-template-field-to-join.d.ts +6 -0
  25. package/lib/modules/docTemplates/xt-doc-template-field-to-join.js +2 -0
  26. package/lib/modules/docTemplates/xt-doc-template.d.ts +18 -0
  27. package/lib/modules/docTemplates/xt-doc-template.js +2 -0
  28. package/lib/modules/files/x-file.d.ts +8 -0
  29. package/lib/modules/files/x-file.js +2 -0
  30. package/lib/serverApi/FindParam.d.ts +2 -1
  31. package/lib/serverApi/FindParam.js +1 -0
  32. package/lib/serverApi/x-lib-api.d.ts +6 -0
  33. package/lib/serverApi/x-lib-api.js +0 -1
  34. package/package.json +1 -1
  35. package/xt-doc-template.d.ts +3 -0
  36. package/xt-doc-template.js +5 -0
@@ -0,0 +1,3 @@
1
+ // generated by gulp
2
+
3
+ export * from './lib/modules/docTemplates/XDocTemplateButton';
@@ -0,0 +1,5 @@
1
+ // generated by gulp
2
+
3
+ 'use strict';
4
+
5
+ module.exports = require('./lib/modules/docTemplates/XDocTemplateButton.js');
package/gulpfile.js CHANGED
@@ -78,6 +78,9 @@ function generateApi(cb) {
78
78
  "./lib/components/XUtils",
79
79
  "./lib/components/XUtilsMetadata",
80
80
 
81
+ "./lib/modules/docTemplates/XDocTemplateButton",
82
+ "./lib/modules/docTemplates/xt-doc-template",
83
+
81
84
  "./lib/serverApi/ExportImportParam",
82
85
  "./lib/serverApi/FindParam",
83
86
  "./lib/serverApi/XUtilsCommon",
@@ -0,0 +1,12 @@
1
+ import { XUser } from "../serverApi/XUser";
2
+ import { XEnum } from "./x-enum";
3
+ export interface XEnumEnum {
4
+ id: number;
5
+ code: string;
6
+ name: string;
7
+ readOnly: boolean;
8
+ xEnumList: XEnum[];
9
+ modifDate: Date;
10
+ modifXUser: XUser;
11
+ version: number;
12
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,10 @@
1
+ import { XEnumEnum } from "./x-enum-enum";
2
+ export interface XEnum {
3
+ id: number;
4
+ code: string;
5
+ name: string;
6
+ enabled: boolean;
7
+ readOnly: boolean;
8
+ enumOrder: number;
9
+ xEnumEnum: XEnumEnum;
10
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -12,6 +12,7 @@ export interface XAutoCompleteProps extends XFormComponentProps<XObject> {
12
12
  itemTemplate?: (suggestion: any, index: number, createStringValue: boolean, defaultValue: (suggestion: any) => string) => React.ReactNode;
13
13
  searchBrowse?: JSX.Element;
14
14
  assocForm?: JSX.Element;
15
+ dropdownButtonEnabled?: boolean;
15
16
  suggestions?: any[];
16
17
  suggestionsLoad?: XSuggestionsLoadProp;
17
18
  lazyLoadMaxRows?: number;
@@ -70,7 +70,7 @@ var XAutoComplete = /** @class */ (function (_super) {
70
70
  // div className="col" nam zabezpeci aby XAutoCompleteBase nezaberal celu dlzku grid-u (ma nastaveny width=100% vdaka "formgroup-inline")
71
71
  return (react_1.default.createElement("div", { className: "field grid" },
72
72
  react_1.default.createElement("label", { htmlFor: this.props.assocField, className: "col-fixed", style: this.getLabelStyle() }, this.getLabel()),
73
- react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: this.getValue(), onChange: this.onChangeAutoCompleteBase, field: this.props.displayField, itemTemplate: this.props.itemTemplate, searchBrowse: this.props.searchBrowse, valueForm: this.props.assocForm, idField: xEntityAssoc.idField, readOnly: this.isReadOnly(), error: this.getError(), onErrorChange: this.onErrorChangeAutoCompleteBase, width: this.props.width, scrollHeight: this.props.scrollHeight, suggestions: this.props.suggestions, suggestionsLoad: this.props.suggestionsLoad, lazyLoadMaxRows: this.props.lazyLoadMaxRows, splitQueryValue: this.props.splitQueryValue, minLength: this.props.minLength, suggestionsQuery: { entity: this.xAssoc.entityName, filter: function () { return _this.getFilterBase(_this.props.filter); }, sortField: this.props.sortField, fields: this.props.fields }, inputClassName: this.props.inputClassName, setFocusOnCreate: this.props.setFocusOnCreate })));
73
+ react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: this.getValue(), onChange: this.onChangeAutoCompleteBase, field: this.props.displayField, itemTemplate: this.props.itemTemplate, searchBrowse: this.props.searchBrowse, valueForm: this.props.assocForm, dropdownButtonEnabled: this.props.dropdownButtonEnabled, idField: xEntityAssoc.idField, readOnly: this.isReadOnly(), error: this.getError(), onErrorChange: this.onErrorChangeAutoCompleteBase, width: this.props.width, scrollHeight: this.props.scrollHeight, suggestions: this.props.suggestions, suggestionsLoad: this.props.suggestionsLoad, lazyLoadMaxRows: this.props.lazyLoadMaxRows, splitQueryValue: this.props.splitQueryValue, minLength: this.props.minLength, suggestionsQuery: { entity: this.xAssoc.entityName, filter: function () { return _this.getFilterBase(_this.props.filter); }, sortField: this.props.sortField, fields: this.props.fields }, inputClassName: this.props.inputClassName, setFocusOnCreate: this.props.setFocusOnCreate })));
74
74
  };
75
75
  return XAutoComplete;
76
76
  }(XFormComponent_1.XFormComponent));
@@ -28,6 +28,7 @@ export interface XAutoCompleteBaseProps {
28
28
  idField?: string;
29
29
  addRowEnabled: boolean;
30
30
  onAddRow?: (inputValue: string) => void;
31
+ dropdownButtonEnabled: boolean;
31
32
  insertButtonTooltip?: string;
32
33
  updateButtonTooltip?: string;
33
34
  searchButtonTooltip?: string;
@@ -48,6 +49,7 @@ export declare class XAutoCompleteBase extends Component<XAutoCompleteBaseProps>
48
49
  lazyLoadMaxRows: number;
49
50
  splitQueryValue: boolean;
50
51
  addRowEnabled: boolean;
52
+ dropdownButtonEnabled: boolean;
51
53
  minLength: number;
52
54
  buttonsLayout: string;
53
55
  scrollHeight: string;
@@ -688,6 +688,7 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
688
688
  var buttons;
689
689
  if (!readOnly) {
690
690
  var createInsertItem = (this.props.addRowEnabled && (this.props.valueForm !== undefined || this.props.onAddRow !== undefined));
691
+ // TODO - upratat koli split layuot-u (ak dropdownButtonEnabled = false tak moze vzniknut split button s jednym buttonom)
691
692
  if (createInsertItem || this.props.valueForm || this.props.searchBrowse) {
692
693
  // mame searchBrowse alebo CRUD operacie, potrebujeme viac buttonov alebo SplitButton
693
694
  var buttonItems = [];
@@ -700,7 +701,9 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
700
701
  if (this.props.searchBrowse) {
701
702
  this.createSearchItem(buttonItems);
702
703
  }
703
- this.createDropdownItem(buttonItems);
704
+ if (this.props.dropdownButtonEnabled) {
705
+ this.createDropdownItem(buttonItems);
706
+ }
704
707
  if (this.props.buttonsLayout === "buttons") {
705
708
  buttons = buttonItems.map(function (value, index) { return react_1.default.createElement(button_1.Button, { key: "button".concat(index), icon: value.icon, tooltip: value.tooltip, tooltipOptions: { position: 'top' }, onClick: function (e) { return value.command(e); }, className: 'x-dropdownbutton' + XUtils_1.XUtils.mobileCssSuffix() }); });
706
709
  }
@@ -713,7 +716,7 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
713
716
  }
714
717
  else {
715
718
  // mame len 1 operaciu - dame jednoduchy button
716
- buttons = [react_1.default.createElement(button_1.Button, { icon: "pi pi-chevron-down", onClick: function (e) { return _this.onOpenDropdown(e); }, className: 'x-dropdownbutton' + XUtils_1.XUtils.mobileCssSuffix() })];
719
+ buttons = [react_1.default.createElement(button_1.Button, { icon: "pi pi-chevron-down", onClick: function (e) { return _this.onOpenDropdown(e); }, className: 'x-dropdownbutton' + XUtils_1.XUtils.mobileCssSuffix(), disabled: !this.props.dropdownButtonEnabled })];
717
720
  }
718
721
  }
719
722
  else {
@@ -753,6 +756,7 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
753
756
  lazyLoadMaxRows: 10,
754
757
  splitQueryValue: true,
755
758
  addRowEnabled: true,
759
+ dropdownButtonEnabled: true,
756
760
  minLength: 1,
757
761
  buttonsLayout: "buttons",
758
762
  scrollHeight: '15rem' // primereact has 200px
@@ -12,6 +12,7 @@ export interface XAutoCompleteDTProps extends XFormComponentDTProps {
12
12
  itemTemplate?: (suggestion: any, index: number, createStringValue: boolean, defaultValue: (suggestion: any) => string) => React.ReactNode;
13
13
  searchBrowse?: JSX.Element;
14
14
  assocForm?: JSX.Element;
15
+ dropdownButtonEnabled?: boolean;
15
16
  suggestions?: any[];
16
17
  suggestionsLoad?: XSuggestionsLoadProp;
17
18
  lazyLoadMaxRows?: number;
@@ -68,7 +68,7 @@ var XAutoCompleteDT = /** @class */ (function (_super) {
68
68
  // TODO - size
69
69
  //const size = this.props.size ?? xDisplayField.length;
70
70
  // div className="col" nam zabezpeci aby XAutoCompleteBase nezaberal celu dlzku grid-u (ma nastaveny width=100% vdaka "formgroup-inline")
71
- return (react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: this.getValue(), onChange: this.onChangeAutoCompleteBase, field: this.props.displayField, itemTemplate: this.props.itemTemplate, searchBrowse: this.props.searchBrowse, valueForm: this.props.assocForm, idField: xEntityAssoc.idField, readOnly: this.isReadOnly(), error: this.getError(), onErrorChange: this.onErrorChangeAutoCompleteBase, suggestions: this.props.suggestions, suggestionsLoad: this.props.suggestionsLoad, lazyLoadMaxRows: this.props.lazyLoadMaxRows, splitQueryValue: this.props.splitQueryValue, addRowEnabled: this.props.addRowEnabled, minLength: this.props.minLength, scrollHeight: this.props.scrollHeight, suggestionsQuery: { entity: this.xAssoc.entityName, filter: function () { return _this.getFilterBase(_this.props.filter); }, sortField: this.props.sortField, fields: this.props.fields }, inputClassName: this.props.inputClassName }));
71
+ return (react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: this.getValue(), onChange: this.onChangeAutoCompleteBase, field: this.props.displayField, itemTemplate: this.props.itemTemplate, searchBrowse: this.props.searchBrowse, valueForm: this.props.assocForm, dropdownButtonEnabled: this.props.dropdownButtonEnabled, idField: xEntityAssoc.idField, readOnly: this.isReadOnly(), error: this.getError(), onErrorChange: this.onErrorChangeAutoCompleteBase, suggestions: this.props.suggestions, suggestionsLoad: this.props.suggestionsLoad, lazyLoadMaxRows: this.props.lazyLoadMaxRows, splitQueryValue: this.props.splitQueryValue, addRowEnabled: this.props.addRowEnabled, minLength: this.props.minLength, scrollHeight: this.props.scrollHeight, suggestionsQuery: { entity: this.xAssoc.entityName, filter: function () { return _this.getFilterBase(_this.props.filter); }, sortField: this.props.sortField, fields: this.props.fields }, inputClassName: this.props.inputClassName }));
72
72
  };
73
73
  return XAutoCompleteDT;
74
74
  }(XFormComponentDT_1.XFormComponentDT));
@@ -1,6 +1,10 @@
1
1
  import React from "react";
2
2
  import { XFormBase } from "./XFormBase";
3
+ import { XtDocTemplate } from "../modules/docTemplates/xt-doc-template";
3
4
  export declare const xSaveButtonId: string;
4
5
  export declare const XFormFooter: (props: {
5
6
  form: XFormBase;
7
+ docTemplates?: true | ((entity: string) => Promise<XtDocTemplate[]>) | undefined;
8
+ bodyRight?: React.ReactNode;
9
+ indentWidth?: string | undefined;
6
10
  }) => React.JSX.Element;
@@ -7,13 +7,32 @@ exports.XFormFooter = exports.xSaveButtonId = void 0;
7
7
  var react_1 = __importDefault(require("react"));
8
8
  var XButton_1 = require("./XButton");
9
9
  var XLocale_1 = require("./XLocale");
10
+ var XDocTemplateButton_1 = require("../modules/docTemplates/XDocTemplateButton");
11
+ var XUtils_1 = require("./XUtils");
10
12
  // constant to be used in method formReadOnly to identify save button
11
13
  exports.xSaveButtonId = "x-save-button-id";
12
14
  // helper wrapper
13
15
  var XFormFooter = function (props) {
14
16
  var readOnly = props.form.formReadOnlyBase(exports.xSaveButtonId);
17
+ var leftCompensationElem = null;
18
+ var rightNodeList = [];
19
+ // template button is rendered only for update (id !== undefined; row must exist in DB), not for insert
20
+ if (props.docTemplates && !XUtils_1.XUtils.isMobile() && props.form.props.id !== undefined) {
21
+ rightNodeList.push(react_1.default.createElement(XDocTemplateButton_1.XDocTemplateButton, { key: "docTemplates", entity: props.form.getEntity(), rowId: props.form.props.id, docTemplates: typeof props.docTemplates === 'function' ? props.docTemplates : undefined }));
22
+ }
23
+ if (props.bodyRight) {
24
+ rightNodeList.push(props.bodyRight);
25
+ }
26
+ if (props.indentWidth && rightNodeList.length > 0) {
27
+ // used only to create some distance between buttons Cancel and XDocTemplateButton (all content is centered), because Cancel is frequently used
28
+ leftCompensationElem = react_1.default.createElement("div", { style: { width: props.indentWidth } });
29
+ rightNodeList =
30
+ [react_1.default.createElement("div", { className: "flex justify-content-end", style: { width: props.indentWidth } }, rightNodeList)];
31
+ }
15
32
  return (react_1.default.createElement("div", { className: "flex justify-content-center" },
33
+ leftCompensationElem,
16
34
  react_1.default.createElement(XButton_1.XButton, { icon: "pi pi-save", label: (0, XLocale_1.xLocaleOption)('save'), onClick: props.form.onClickSave, disabled: readOnly }),
17
- react_1.default.createElement(XButton_1.XButton, { icon: "pi pi-times", label: (0, XLocale_1.xLocaleOption)('cancel'), onClick: props.form.onClickCancel })));
35
+ react_1.default.createElement(XButton_1.XButton, { icon: "pi pi-times", label: (0, XLocale_1.xLocaleOption)('cancel'), onClick: props.form.onClickCancel }),
36
+ rightNodeList));
18
37
  };
19
38
  exports.XFormFooter = XFormFooter;
@@ -75,6 +75,7 @@ var XButtonIconNarrow_1 = require("./XButtonIconNarrow");
75
75
  var XUtilsConversions_1 = require("../serverApi/XUtilsConversions");
76
76
  var XLocale_1 = require("./XLocale");
77
77
  var XUtilsMetadataCommon_1 = require("../serverApi/XUtilsMetadataCommon");
78
+ // notice: in skch there is new version XInputFileList2 and that version don´t use fetch api because fetch api does not support progress bar
78
79
  var XInputFileList = /** @class */ (function (_super) {
79
80
  __extends(XInputFileList, _super);
80
81
  function XInputFileList(props) {
@@ -168,31 +169,9 @@ var XInputFileList = /** @class */ (function (_super) {
168
169
  };
169
170
  XInputFileList.prototype.onDownloadFile = function (xFile) {
170
171
  return __awaiter(this, void 0, void 0, function () {
171
- var response, e_3, fileName, respBlob, url, a;
172
172
  return __generator(this, function (_a) {
173
- switch (_a.label) {
174
- case 0:
175
- _a.trys.push([0, 2, , 3]);
176
- return [4 /*yield*/, XUtils_1.XUtils.fetchBasicJson('x-download-file', { xFileId: xFile.id })];
177
- case 1:
178
- response = _a.sent();
179
- return [3 /*break*/, 3];
180
- case 2:
181
- e_3 = _a.sent();
182
- XUtils_1.XUtils.showErrorMessage((0, XLocale_1.xLocaleOption)('fileDownloadFailed'), e_3);
183
- return [2 /*return*/];
184
- case 3:
185
- fileName = xFile.name;
186
- return [4 /*yield*/, response.blob()];
187
- case 4:
188
- respBlob = _a.sent();
189
- url = window.URL.createObjectURL(respBlob);
190
- a = document.createElement('a');
191
- a.href = url;
192
- a.download = fileName;
193
- a.click();
194
- return [2 /*return*/];
195
- }
173
+ XUtils_1.XUtils.downloadFile('x-download-file', { xFileId: xFile.id }, xFile.name);
174
+ return [2 /*return*/];
196
175
  });
197
176
  });
198
177
  };
@@ -207,7 +186,7 @@ var XInputFileList = /** @class */ (function (_super) {
207
186
  });
208
187
  };
209
188
  XInputFileList.prototype.render = function () {
210
- var e_4, _a;
189
+ var e_3, _a;
211
190
  var _this = this;
212
191
  var _b, _c, _d;
213
192
  var label = (_b = this.props.label) !== null && _b !== void 0 ? _b : this.props.assocField;
@@ -230,12 +209,12 @@ var XInputFileList = /** @class */ (function (_super) {
230
209
  _loop_1(fileItem);
231
210
  }
232
211
  }
233
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
212
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
234
213
  finally {
235
214
  try {
236
215
  if (fileItemList_1_1 && !fileItemList_1_1.done && (_a = fileItemList_1.return)) _a.call(fileItemList_1);
237
216
  }
238
- finally { if (e_4) throw e_4.error; }
217
+ finally { if (e_3) throw e_3.error; }
239
218
  }
240
219
  // vrchny div uklada child elementy pod seba (standardny display:block), zarovnane su dolava
241
220
  return (react_1.default.createElement("div", null,
@@ -104,68 +104,46 @@ var XExportRowsDialog = function (props) {
104
104
  setCsvEncoding(ExportImportParam_1.CsvEncoding.Win1250);
105
105
  };
106
106
  var onExport = function () { return __awaiter(void 0, void 0, void 0, function () {
107
- var exportParams, apiPath, requestPayload, exportExcelParam, exportCsvParam, exportJsonParam, response, e_1, fileExt, fileName, respBlob, url, a;
107
+ var exportParams, apiPath, requestPayload, exportExcelParam, exportCsvParam, exportJsonParam, fileExt, fileName;
108
108
  return __generator(this, function (_a) {
109
- switch (_a.label) {
110
- case 0:
111
- // export vykoname az po zatvoreni dialogu - moze dlho trvat a pobezi asynchronne (user zatial moze pracovat s aplikaciou)
112
- // zavrieme dialog
113
- props.hideDialog();
114
- exportParams = props.dialogState.exportParams;
115
- if (exportType === ExportImportParam_1.ExportType.Excel) {
116
- apiPath = "x-lazy-data-table-export-excel";
117
- exportExcelParam = {
118
- queryParam: exportParams.queryParam,
119
- excelCsvParam: createExcelCsvParam(exportParams),
120
- widths: exportParams.widths
121
- };
122
- requestPayload = exportExcelParam;
123
- }
124
- else if (exportType === ExportImportParam_1.ExportType.Csv) {
125
- apiPath = "x-lazy-data-table-export-csv";
126
- exportCsvParam = {
127
- queryParam: exportParams.queryParam,
128
- excelCsvParam: createExcelCsvParam(exportParams),
129
- csvParam: {
130
- csvSeparator: csvSeparator, csvDecimalFormat: decimalFormat, csvEncoding: csvEncoding
131
- }
132
- };
133
- requestPayload = exportCsvParam;
134
- }
135
- else if (exportType === ExportImportParam_1.ExportType.Json) {
136
- apiPath = "x-lazy-data-table-export-json";
137
- exportJsonParam = {
138
- queryParam: exportParams.queryParam
139
- };
140
- requestPayload = exportJsonParam;
141
- }
142
- else {
143
- throw "Unimplemented exportType = ".concat(exportType);
109
+ // export vykoname az po zatvoreni dialogu - moze dlho trvat a pobezi asynchronne (user zatial moze pracovat s aplikaciou)
110
+ // zavrieme dialog
111
+ props.hideDialog();
112
+ exportParams = props.dialogState.exportParams;
113
+ if (exportType === ExportImportParam_1.ExportType.Excel) {
114
+ apiPath = "x-lazy-data-table-export-excel";
115
+ exportExcelParam = {
116
+ queryParam: exportParams.queryParam,
117
+ excelCsvParam: createExcelCsvParam(exportParams),
118
+ widths: exportParams.widths
119
+ };
120
+ requestPayload = exportExcelParam;
121
+ }
122
+ else if (exportType === ExportImportParam_1.ExportType.Csv) {
123
+ apiPath = "x-lazy-data-table-export-csv";
124
+ exportCsvParam = {
125
+ queryParam: exportParams.queryParam,
126
+ excelCsvParam: createExcelCsvParam(exportParams),
127
+ csvParam: {
128
+ csvSeparator: csvSeparator, csvDecimalFormat: decimalFormat, csvEncoding: csvEncoding
144
129
  }
145
- _a.label = 1;
146
- case 1:
147
- _a.trys.push([1, 3, , 4]);
148
- return [4 /*yield*/, XUtils_1.XUtils.fetchBasicJson(apiPath, requestPayload)];
149
- case 2:
150
- response = _a.sent();
151
- return [3 /*break*/, 4];
152
- case 3:
153
- e_1 = _a.sent();
154
- XUtils_1.XUtils.showErrorMessage("Export failed.", e_1);
155
- return [2 /*return*/];
156
- case 4:
157
- fileExt = exportType === ExportImportParam_1.ExportType.Excel ? "xlsx" : exportType;
158
- fileName = "".concat(exportParams.fileName, ".").concat(fileExt);
159
- return [4 /*yield*/, response.blob()];
160
- case 5:
161
- respBlob = _a.sent();
162
- url = window.URL.createObjectURL(respBlob);
163
- a = document.createElement('a');
164
- a.href = url;
165
- a.download = fileName;
166
- a.click();
167
- return [2 /*return*/];
130
+ };
131
+ requestPayload = exportCsvParam;
132
+ }
133
+ else if (exportType === ExportImportParam_1.ExportType.Json) {
134
+ apiPath = "x-lazy-data-table-export-json";
135
+ exportJsonParam = {
136
+ queryParam: exportParams.queryParam
137
+ };
138
+ requestPayload = exportJsonParam;
139
+ }
140
+ else {
141
+ throw "Unimplemented exportType = ".concat(exportType);
168
142
  }
143
+ fileExt = exportType === ExportImportParam_1.ExportType.Excel ? "xlsx" : exportType;
144
+ fileName = "".concat(exportParams.fileName, ".").concat(fileExt);
145
+ XUtils_1.XUtils.downloadFile(apiPath, requestPayload, fileName);
146
+ return [2 /*return*/];
169
147
  });
170
148
  }); };
171
149
  var createExcelCsvParam = function (exportParams) {
@@ -7,6 +7,7 @@ import { XAggregateFunction, XCustomFilter } from "../../serverApi/FindParam";
7
7
  import { XOnSaveOrCancelProp } from "../XFormBase";
8
8
  import { IconType } from "primereact/utils";
9
9
  import { ButtonProps } from "primereact/button";
10
+ import { XtDocTemplate } from "../../modules/docTemplates/xt-doc-template";
10
11
  export type XBetweenFilterProp = "row" | "column" | undefined;
11
12
  export type XMultilineRenderType = "singleLine" | "fewLines" | "allLines";
12
13
  export interface XAppButtonForRow {
@@ -67,10 +68,11 @@ export interface XLazyDataTableProps {
67
68
  formFooterHeight?: string;
68
69
  shrinkWidth: boolean;
69
70
  onResetTable?: () => void;
70
- onAddRow?: () => void;
71
+ onAddRow?: (filters: DataTableFilterMeta) => void;
71
72
  onEdit?: (selectedRow: any) => void;
72
73
  removeRow?: ((selectedRow: any) => Promise<boolean>) | boolean;
73
74
  onRemoveRow?: XOnSaveOrCancelProp;
75
+ docTemplates?: true | ((entity: string) => Promise<XtDocTemplate[]>);
74
76
  appButtonsForRow?: XAppButtonForRow[];
75
77
  appButtons?: any;
76
78
  filters?: DataTableFilterMeta;
@@ -83,7 +85,7 @@ export interface XLazyDataTableProps {
83
85
  multilineSwitchInitValue: XMultilineRenderType;
84
86
  multilineSwitchFewLinesCount: number;
85
87
  multilineSwitchValue?: [XMultilineRenderType, React.Dispatch<React.SetStateAction<XMultilineRenderType>>];
86
- headerElementRight?: React.ReactNode;
88
+ headerBodyRight?: React.ReactNode;
87
89
  searchBrowseParams?: XSearchBrowseParams;
88
90
  width?: string;
89
91
  rowClassName?: (data: any) => object | string | undefined;
@@ -113,19 +115,26 @@ export declare const XLazyDataTable: {
113
115
  };
114
116
  };
115
117
  export type XGetFilterItem = (field: string) => DataTableFilterMetaData | DataTableOperatorFilterMetaData;
116
- export type XSetFilterItem = (field: string, filterItem: DataTableFilterMetaData | DataTableOperatorFilterMetaData) => void;
118
+ export type XSetFilterItem = (field: string, filterItem: DataTableFilterMetaData | DataTableOperatorFilterMetaData, autoFilter: boolean) => void;
117
119
  export type XFilterElementParams = {
118
120
  getFilterItem: XGetFilterItem;
119
121
  setFilterItem: XSetFilterItem;
120
122
  options: ColumnFilterElementTemplateOptions;
123
+ autoFilter: boolean;
124
+ };
125
+ export type XFilterElementProp = {
126
+ element: (params: XFilterElementParams) => React.ReactNode;
127
+ matchModeLabel?: string;
121
128
  };
122
- export type XFilterElementProp = (params: XFilterElementParams) => React.ReactNode;
123
129
  export type XAutoCompleteInFilterProps = {
124
130
  assocField?: string;
125
131
  filter?: XCustomFilter;
126
132
  sortField?: string | DataTableSortMeta[];
133
+ fields?: string[];
127
134
  lazyLoadMaxRows?: number;
128
135
  field?: string | string[];
136
+ itemTemplate?: (suggestion: any, index: number, createStringValue: boolean, defaultValue: (suggestion: any) => string) => React.ReactNode;
137
+ inputClassName?: string;
129
138
  searchBrowse?: JSX.Element;
130
139
  valueForm?: JSX.Element;
131
140
  minLength?: number;
@@ -137,6 +137,7 @@ var XInputTextBase_1 = require("../XInputTextBase");
137
137
  var useXStateSession_1 = require("../useXStateSession");
138
138
  var useXStateSessionBase_1 = require("../useXStateSessionBase");
139
139
  var _ = __importStar(require("lodash"));
140
+ var XDocTemplateButton_1 = require("../../modules/docTemplates/XDocTemplateButton");
140
141
  var XStateKeySuffix;
141
142
  (function (XStateKeySuffix) {
142
143
  XStateKeySuffix["filters"] = "filters";
@@ -214,7 +215,10 @@ var XLazyDataTable = function (props) {
214
215
  };
215
216
  var getInitFilterMatchMode = function (xLazyColumnProps, xField) {
216
217
  var filterMatchMode;
217
- if (isAutoCompleteInFilterEnabled(xLazyColumnProps)) {
218
+ if (xLazyColumnProps.filterElement !== undefined) {
219
+ filterMatchMode = FindParam_1.XFilterMatchMode.X_FILTER_ELEMENT; // little hack
220
+ }
221
+ else if (isAutoCompleteInFilterEnabled(xLazyColumnProps)) {
218
222
  filterMatchMode = FindParam_1.XFilterMatchMode.X_AUTO_COMPLETE; // little hack
219
223
  }
220
224
  else if (xField.type === "string" || xField.type === "jsonb") {
@@ -730,7 +734,7 @@ var XLazyDataTable = function (props) {
730
734
  var onClickAddRow = function () {
731
735
  //console.log("zavolany onClickAddRow");
732
736
  if (props.onAddRow !== undefined) {
733
- props.onAddRow();
737
+ props.onAddRow(filters);
734
738
  }
735
739
  };
736
740
  var onClickEdit = function () {
@@ -882,13 +886,14 @@ var XLazyDataTable = function (props) {
882
886
  // ****** vseobecne metodky pre set/get do/z filtra ********
883
887
  // zatial funguje len pre simple filtrovanie (filterDisplay="row")
884
888
  // vseobecna specialna metodka pouzvana pri custom filtri (XLazyColumn.filterElement)
885
- var setFilterItem = function (field, filterItem) {
889
+ // nepodarilo sa posunut autoFilter takym sposobom aby app programmer nemusel autoFilter nastavovat
890
+ var setFilterItem = function (field, filterItem, autoFilter) {
886
891
  filters[field] = filterItem;
887
892
  // neskusal som, ci treba aj toto klonovat ale pravdepodobne hej
888
893
  var filtersCloned = __assign({}, filters);
889
894
  setFilters(filtersCloned);
890
895
  removePagingFromStorage();
891
- loadDataBaseIfAutoFilter(filtersCloned, false);
896
+ loadDataBaseIfAutoFilter(filtersCloned, autoFilter);
892
897
  };
893
898
  // vseobecna specialna metodka pouzvana pri custom filtri (XLazyColumn.filterElement)
894
899
  var getFilterItem = function (field) {
@@ -1153,6 +1158,7 @@ var XLazyDataTable = function (props) {
1153
1158
  }
1154
1159
  // pre lepsiu citatelnost vytvarame stlpce uz tu
1155
1160
  var columnElemList = react_1.default.Children.map(props.children.filter(function (child) { return XUtils_1.XUtils.xViewStatus(child.props.columnViewStatus) !== XUtils_1.XViewStatus.Hidden; }), function (child) {
1161
+ var _a, _b;
1156
1162
  // ak chceme zmenit child element, tak treba bud vytvorit novy alebo vyklonovat
1157
1163
  // priklad je na https://soshace.com/building-react-components-using-children-props-and-context-api/
1158
1164
  // (vzdy musime robit manipulacie so stlpcom, lebo potrebujeme pridat filter={true} sortable={true}
@@ -1177,92 +1183,107 @@ var XLazyDataTable = function (props) {
1177
1183
  }
1178
1184
  // *********** filterElement ***********
1179
1185
  var betweenFilter = undefined;
1180
- var filterElement;
1186
+ var filterElement = null;
1181
1187
  if (childColumn.props.filterElement !== undefined) {
1182
- filterElement = function (options) {
1183
- // compilator sa stazoval ze childColumn.props.filterElement moze byt undefined, preto som pridal "!"
1184
- return childColumn.props.filterElement({ getFilterItem: getFilterItem, setFilterItem: setFilterItem, options: options });
1185
- };
1188
+ // if we use matchModeLabel and this special match mode is chosen then we use custom filter element
1189
+ // if we don't use matchModeLabel (undefined) then we use custom filter element always
1190
+ if ((childColumn.props.filterElement.matchModeLabel && getFilterMatchMode(childColumn.props.field) === FindParam_1.XFilterMatchMode.X_FILTER_ELEMENT)
1191
+ || childColumn.props.filterElement.matchModeLabel === undefined) {
1192
+ filterElement = function (options) {
1193
+ // compilator sa stazoval ze childColumn.props.filterElement moze byt undefined, preto som pridal "!"
1194
+ return childColumn.props.filterElement.element({ getFilterItem: getFilterItem, setFilterItem: setFilterItem, options: options, autoFilter: childColumn.props.autoFilter });
1195
+ };
1196
+ }
1186
1197
  }
1187
- else if (getFilterMatchMode(childColumn.props.field) === FindParam_1.XFilterMatchMode.X_AUTO_COMPLETE) {
1188
- var assocField_1 = undefined; // path to manyToOne assoc
1189
- var displayField = undefined; // field/fields displayed in autocomplete (can be path)
1190
- // if childColumn.props.autoComplete = true, then autoComplete = undefined and default autocomlete is created
1191
- var autoComplete = (typeof childColumn.props.autoComplete === 'object' ? childColumn.props.autoComplete : undefined);
1192
- if (autoComplete) {
1193
- if (autoComplete.field) {
1194
- displayField = autoComplete.field;
1198
+ if (filterElement === null) {
1199
+ if (getFilterMatchMode(childColumn.props.field) === FindParam_1.XFilterMatchMode.X_AUTO_COMPLETE) {
1200
+ var assocField_1 = undefined; // path to manyToOne assoc
1201
+ var displayField = undefined; // field/fields displayed in autocomplete (can be path)
1202
+ // if childColumn.props.autoComplete = true, then autoComplete = undefined and default autocomplete is created
1203
+ var autoComplete = (typeof childColumn.props.autoComplete === 'object' ? childColumn.props.autoComplete : undefined);
1204
+ if (autoComplete) {
1205
+ if (autoComplete.field) {
1206
+ displayField = autoComplete.field;
1207
+ }
1208
+ if (autoComplete.assocField) {
1209
+ // check - autoComplete.assocField must be prefix (part) of childColumn.props.field
1210
+ if (!childColumn.props.field.startsWith(autoComplete.assocField + ".")) {
1211
+ throw "XLazyColumn with field \"".concat(childColumn.props.field, "\": autoComplete.assocField \"").concat(autoComplete.assocField, "\" is not prefix of the field");
1212
+ }
1213
+ assocField_1 = autoComplete.assocField;
1214
+ if (displayField === undefined) {
1215
+ // take displayField from childColumn.props.field (rest of the path)
1216
+ displayField = childColumn.props.field.substring(autoComplete.assocField.length + 1);
1217
+ }
1218
+ }
1195
1219
  }
1196
- if (autoComplete.assocField) {
1197
- // check - autoComplete.assocField must be prefix (part) of childColumn.props.field
1198
- if (!childColumn.props.field.startsWith(autoComplete.assocField + ".")) {
1199
- throw "XLazyColumn with field \"".concat(childColumn.props.field, "\": autoComplete.assocField \"").concat(autoComplete.assocField, "\" is not prefix of the field");
1220
+ if (assocField_1 === undefined) {
1221
+ // default - take assocField/displayField from childColumn.props.field
1222
+ var _c = __read(XUtilsCommon_1.XUtilsCommon.getPathToAssocAndField(childColumn.props.field), 2), assocFieldTemp = _c[0], displayFieldTemp = _c[1];
1223
+ if (assocFieldTemp === null) {
1224
+ throw "XLazyColumn with field \"".concat(childColumn.props.field, "\": unexpected error - path of length >= 2 expected");
1200
1225
  }
1201
- assocField_1 = autoComplete.assocField;
1226
+ assocField_1 = assocFieldTemp;
1202
1227
  if (displayField === undefined) {
1203
- // take displayField from childColumn.props.field (rest of the path)
1204
- displayField = childColumn.props.field.substring(autoComplete.assocField.length + 1);
1228
+ displayField = displayFieldTemp;
1205
1229
  }
1206
1230
  }
1231
+ var xAssoc = XUtilsMetadataCommon_1.XUtilsMetadataCommon.getXAssocToOneByPath(xEntity, assocField_1);
1232
+ var object = getFilterValue(childColumn.props.field);
1233
+ filterElement = react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: object, onChange: function (object, objectChange) { return setFilterValue(childColumn.props.field, object, undefined, object !== null ? [{
1234
+ where: "[".concat(assocField_1, "] = ").concat(object['id']),
1235
+ params: {}
1236
+ }] : undefined, childColumn.props.autoFilter); }, error: undefined, onErrorChange: function (error) { }, idField: "id", field: displayField, itemTemplate: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.itemTemplate, inputClassName: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.inputClassName, suggestionsQuery: {
1237
+ entity: xAssoc.entityName,
1238
+ filter: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.filter,
1239
+ sortField: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.sortField,
1240
+ fields: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.fields
1241
+ }, searchBrowse: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.searchBrowse, valueForm: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.valueForm, addRowEnabled: false, width: "100%", scrollHeight: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.scrollHeight, suggestionsLoad: "lazy", lazyLoadMaxRows: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.lazyLoadMaxRows, minLength: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.minLength });
1207
1242
  }
1208
- if (assocField_1 === undefined) {
1209
- // default - take assocField/displayField from childColumn.props.field
1210
- var _a = __read(XUtilsCommon_1.XUtilsCommon.getPathToAssocAndField(childColumn.props.field), 2), assocFieldTemp = _a[0], displayFieldTemp = _a[1];
1211
- if (assocFieldTemp === null) {
1212
- throw "XLazyColumn with field \"".concat(childColumn.props.field, "\": unexpected error - path of length >= 2 expected");
1213
- }
1214
- assocField_1 = assocFieldTemp;
1215
- if (displayField === undefined) {
1216
- displayField = displayFieldTemp;
1243
+ else {
1244
+ if (xField.type === "boolean") {
1245
+ var checkboxValue = getFilterValue(childColumn.props.field);
1246
+ filterElement = react_1.default.createElement(tristatecheckbox_1.TriStateCheckbox, { value: checkboxValue, onChange: function (e) { return setFilterValue(childColumn.props.field, e.value, api_1.FilterMatchMode.EQUALS, undefined, childColumn.props.autoFilter); } });
1217
1247
  }
1218
- }
1219
- var xAssoc = XUtilsMetadataCommon_1.XUtilsMetadataCommon.getXAssocToOneByPath(xEntity, assocField_1);
1220
- var object = getFilterValue(childColumn.props.field);
1221
- filterElement = react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: object, onChange: function (object, objectChange) { return setFilterValue(childColumn.props.field, object, undefined, object !== null ? [{ where: "[".concat(assocField_1, "] = ").concat(object['id']), params: {} }] : undefined, childColumn.props.autoFilter); }, error: undefined, onErrorChange: function (error) { }, idField: "id", field: displayField, suggestionsQuery: { entity: xAssoc.entityName, filter: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.filter, sortField: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.sortField }, searchBrowse: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.searchBrowse, valueForm: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.valueForm, addRowEnabled: false, width: "100%", scrollHeight: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.scrollHeight, suggestionsLoad: "lazy", lazyLoadMaxRows: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.lazyLoadMaxRows, minLength: autoComplete === null || autoComplete === void 0 ? void 0 : autoComplete.minLength });
1222
- }
1223
- else {
1224
- if (xField.type === "boolean") {
1225
- var checkboxValue = getFilterValue(childColumn.props.field);
1226
- filterElement = react_1.default.createElement(tristatecheckbox_1.TriStateCheckbox, { value: checkboxValue, onChange: function (e) { return setFilterValue(childColumn.props.field, e.value, api_1.FilterMatchMode.EQUALS, undefined, childColumn.props.autoFilter); } });
1227
- }
1228
- else if (childColumn.props.dropdownInFilter) {
1229
- var dropdownValue = getDropdownFilterValue(childColumn.props.field);
1230
- filterElement = react_1.default.createElement(XDropdownDTFilter_1.XDropdownDTFilter, { entity: props.entity, path: childColumn.props.field, value: dropdownValue, onValueChange: function (field, displayValue) { return onDropdownFilterChange(field, displayValue, childColumn.props.autoFilter); }, filter: childColumn.props.dropdownFilter, sortField: childColumn.props.dropdownSortField });
1231
- }
1232
- else if (xField.type === "string") {
1233
- var stringValue = getFilterValue(childColumn.props.field);
1234
- filterElement = react_1.default.createElement(XInputTextBase_1.XInputTextBase, { value: stringValue, onChange: function (value) { return setFilterValue(childColumn.props.field, value, undefined, undefined, childColumn.props.autoFilter); } });
1235
- }
1236
- else if (xField.type === "date" || xField.type === "datetime") {
1237
- betweenFilter = getBetweenFilter(childColumn.props.betweenFilter, props.betweenFilter);
1238
- if (betweenFilter !== undefined) {
1239
- // display: 'flex' umiestni XCalendar elementy vedla seba
1240
- filterElement =
1241
- react_1.default.createElement("div", { style: betweenFilter === "row" ? { display: 'flex' } : undefined },
1242
- react_1.default.createElement(XCalendar_1.XCalendar, { value: getFilterValue1(childColumn.props.field), onChange: function (value) { return setFilterValue1(childColumn.props.field, value, childColumn.props.autoFilter); }, scale: xField.scale, datetime: xField.type === "datetime" }),
1243
- react_1.default.createElement(XCalendar_1.XCalendar, { value: getFilterValue2(childColumn.props.field), onChange: function (value) { return setFilterValue2(childColumn.props.field, value, childColumn.props.autoFilter); }, scale: xField.scale, datetime: xField.type === "datetime" }));
1248
+ else if (childColumn.props.dropdownInFilter) {
1249
+ var dropdownValue = getDropdownFilterValue(childColumn.props.field);
1250
+ filterElement = react_1.default.createElement(XDropdownDTFilter_1.XDropdownDTFilter, { entity: props.entity, path: childColumn.props.field, value: dropdownValue, onValueChange: function (field, displayValue) { return onDropdownFilterChange(field, displayValue, childColumn.props.autoFilter); }, filter: childColumn.props.dropdownFilter, sortField: childColumn.props.dropdownSortField });
1244
1251
  }
1245
- else {
1246
- var dateValue = getFilterValue(childColumn.props.field);
1247
- filterElement = react_1.default.createElement(XCalendar_1.XCalendar, { value: dateValue, onChange: function (value) { return setFilterValue(childColumn.props.field, value, undefined, undefined, childColumn.props.autoFilter); }, scale: xField.scale, datetime: xField.type === "datetime" });
1252
+ else if (xField.type === "string") {
1253
+ var stringValue = getFilterValue(childColumn.props.field);
1254
+ filterElement = react_1.default.createElement(XInputTextBase_1.XInputTextBase, { value: stringValue, onChange: function (value) { return setFilterValue(childColumn.props.field, value, undefined, undefined, childColumn.props.autoFilter); } });
1248
1255
  }
1249
- }
1250
- else if (xField.type === "decimal" || xField.type === "number") {
1251
- var params = XUtilsMetadata_1.XUtilsMetadata.getParamsForInputNumber(xField);
1252
- betweenFilter = getBetweenFilter(childColumn.props.betweenFilter, props.betweenFilter);
1253
- if (betweenFilter !== undefined) {
1254
- // display: 'flex' umiestni input elementy pod seba (betweenFilter = "column") resp. vedla seba (betweenFilter = "row")
1255
- filterElement =
1256
- react_1.default.createElement("div", { style: { display: 'flex', flexDirection: betweenFilter } },
1257
- react_1.default.createElement(XInputDecimalBase_1.XInputDecimalBase, __assign({ value: getFilterValue1(childColumn.props.field), onChange: function (value) { return setFilterValue1(childColumn.props.field, value, childColumn.props.autoFilter); } }, params)),
1258
- react_1.default.createElement(XInputDecimalBase_1.XInputDecimalBase, __assign({ value: getFilterValue2(childColumn.props.field), onChange: function (value) { return setFilterValue2(childColumn.props.field, value, childColumn.props.autoFilter); } }, params)));
1256
+ else if (xField.type === "date" || xField.type === "datetime") {
1257
+ betweenFilter = getBetweenFilter(childColumn.props.betweenFilter, props.betweenFilter);
1258
+ if (betweenFilter !== undefined) {
1259
+ // display: 'flex' umiestni XCalendar elementy vedla seba
1260
+ filterElement =
1261
+ react_1.default.createElement("div", { style: betweenFilter === "row" ? { display: 'flex' } : undefined },
1262
+ react_1.default.createElement(XCalendar_1.XCalendar, { value: getFilterValue1(childColumn.props.field), onChange: function (value) { return setFilterValue1(childColumn.props.field, value, childColumn.props.autoFilter); }, scale: xField.scale, datetime: xField.type === "datetime" }),
1263
+ react_1.default.createElement(XCalendar_1.XCalendar, { value: getFilterValue2(childColumn.props.field), onChange: function (value) { return setFilterValue2(childColumn.props.field, value, childColumn.props.autoFilter); }, scale: xField.scale, datetime: xField.type === "datetime" }));
1264
+ }
1265
+ else {
1266
+ var dateValue = getFilterValue(childColumn.props.field);
1267
+ filterElement = react_1.default.createElement(XCalendar_1.XCalendar, { value: dateValue, onChange: function (value) { return setFilterValue(childColumn.props.field, value, undefined, undefined, childColumn.props.autoFilter); }, scale: xField.scale, datetime: xField.type === "datetime" });
1268
+ }
1259
1269
  }
1260
- else {
1261
- var numberValue = getFilterValue(childColumn.props.field);
1262
- filterElement = react_1.default.createElement(XInputDecimalBase_1.XInputDecimalBase, __assign({ value: numberValue, onChange: function (value) { return setFilterValue(childColumn.props.field, value, undefined, undefined, childColumn.props.autoFilter); } }, params));
1270
+ else if (xField.type === "decimal" || xField.type === "number") {
1271
+ var params = XUtilsMetadata_1.XUtilsMetadata.getParamsForInputNumber(xField);
1272
+ betweenFilter = getBetweenFilter(childColumn.props.betweenFilter, props.betweenFilter);
1273
+ if (betweenFilter !== undefined) {
1274
+ // display: 'flex' umiestni input elementy pod seba (betweenFilter = "column") resp. vedla seba (betweenFilter = "row")
1275
+ filterElement =
1276
+ react_1.default.createElement("div", { style: { display: 'flex', flexDirection: betweenFilter } },
1277
+ react_1.default.createElement(XInputDecimalBase_1.XInputDecimalBase, __assign({ value: getFilterValue1(childColumn.props.field), onChange: function (value) { return setFilterValue1(childColumn.props.field, value, childColumn.props.autoFilter); } }, params)),
1278
+ react_1.default.createElement(XInputDecimalBase_1.XInputDecimalBase, __assign({ value: getFilterValue2(childColumn.props.field), onChange: function (value) { return setFilterValue2(childColumn.props.field, value, childColumn.props.autoFilter); } }, params)));
1279
+ }
1280
+ else {
1281
+ var numberValue = getFilterValue(childColumn.props.field);
1282
+ filterElement = react_1.default.createElement(XInputDecimalBase_1.XInputDecimalBase, __assign({ value: numberValue, onChange: function (value) { return setFilterValue(childColumn.props.field, value, undefined, undefined, childColumn.props.autoFilter); } }, params));
1283
+ }
1263
1284
  }
1264
1285
  }
1265
- }
1286
+ } // if (filterElement === null)
1266
1287
  // ************** dataType **************
1267
1288
  // depending on the dataType of the column, suitable match modes are displayed in filter
1268
1289
  var dataType = "text";
@@ -1296,6 +1317,9 @@ var XLazyDataTable = function (props) {
1296
1317
  if (isAutoCompleteInFilterEnabled(childColumn.props)) {
1297
1318
  filterMatchModeOptions.push({ label: (0, XLocale_1.xLocaleOption)('xAutoComplete'), value: FindParam_1.XFilterMatchMode.X_AUTO_COMPLETE });
1298
1319
  }
1320
+ if ((_a = childColumn.props.filterElement) === null || _a === void 0 ? void 0 : _a.matchModeLabel) {
1321
+ filterMatchModeOptions.push({ label: (_b = childColumn.props.filterElement) === null || _b === void 0 ? void 0 : _b.matchModeLabel, value: FindParam_1.XFilterMatchMode.X_FILTER_ELEMENT });
1322
+ }
1299
1323
  }
1300
1324
  // *********** showClearButton ***********
1301
1325
  // pre filterDisplay = "row" nechceme clear button, chceme setrit miesto
@@ -1364,7 +1388,7 @@ var XLazyDataTable = function (props) {
1364
1388
  setMultilineSwitchValue(switchValue);
1365
1389
  setupExpandedRows(value, switchValue);
1366
1390
  }, className: "m-1" }) : null,
1367
- props.headerElementRight,
1391
+ props.headerBodyRight,
1368
1392
  props.label && !isMobile ? react_1.default.createElement("div", { className: "x-lazy-datatable-label-right-compensation" }) : null),
1369
1393
  react_1.default.createElement("div", { className: "flex justify-content-center" },
1370
1394
  react_1.default.createElement(datatable_1.DataTable, { value: value.rowList, dataKey: dataKey, expandedRows: expandedRows, rowExpansionTemplate: props.rowExpansionTemplate ? rowExpansionTemplate : undefined, paginator: props.paginator, pageLinkSize: pageLinkSize, 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, rowClassName: props.rowClassName, 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)),
@@ -1373,8 +1397,9 @@ var XLazyDataTable = function (props) {
1373
1397
  props.onEdit !== undefined && props.searchBrowseParams === undefined ? react_1.default.createElement(XButton_1.XButton, { key: "editRow", icon: "pi pi-pencil", label: (0, XLocale_1.xLocaleOption)('editRow'), onClick: onClickEdit }) : null,
1374
1398
  props.removeRow !== undefined && props.removeRow !== false && props.searchBrowseParams === undefined ? react_1.default.createElement(XButton_1.XButton, { key: "removeRow", icon: "pi pi-times", label: (0, XLocale_1.xLocaleOption)('removeRow'), onClick: onClickRemoveRow }) : null,
1375
1399
  exportRows ? react_1.default.createElement(XButton_1.XButton, { key: "exportRows", icon: "pi pi-file-export", label: (0, XLocale_1.xLocaleOption)('exportRows'), onClick: onClickExport }) : null,
1376
- props.appButtonsForRow ? props.appButtonsForRow.map(function (xAppButton) { return react_1.default.createElement(XButton_1.XButton, { key: xAppButton.key, icon: xAppButton.icon, label: xAppButton.label, onClick: function () { return onClickAppButtonForRow(xAppButton.onClick); }, style: xAppButton.style }); }) : null,
1377
- props.appButtons,
1400
+ props.docTemplates && !isMobile && props.searchBrowseParams === undefined ? react_1.default.createElement(XDocTemplateButton_1.XDocTemplateButton, { key: "docTemplates", entity: props.entity, rowId: selectedRow ? selectedRow[xEntity.idField] : undefined, docTemplates: typeof props.docTemplates === 'function' ? props.docTemplates : undefined }) : null,
1401
+ props.appButtonsForRow && props.searchBrowseParams === undefined ? props.appButtonsForRow.map(function (xAppButton) { return react_1.default.createElement(XButton_1.XButton, { key: xAppButton.key, icon: xAppButton.icon, label: xAppButton.label, onClick: function () { return onClickAppButtonForRow(xAppButton.onClick); }, style: xAppButton.style }); }) : null,
1402
+ props.appButtons && props.searchBrowseParams === undefined,
1378
1403
  props.searchBrowseParams !== undefined ? react_1.default.createElement(XButton_1.XButton, { key: "choose", label: (0, XLocale_1.xLocaleOption)('chooseRow'), onClick: onClickChoose }) : null,
1379
1404
  exportRows ? react_1.default.createElement(XExportRowsDialog_1.XExportRowsDialog, { key: "exportRowsDialog", dialogState: exportRowsDialogState, hideDialog: function () { return setExportRowsDialogState({ dialogOpened: false }); } }) : null),
1380
1405
  hasContentTypeHtml() ? react_1.default.createElement(editor_1.Editor, { style: { display: 'none' }, showHeader: false }) : null /* we want to import css if needed (<style type="text/css" data-primereact-style-id="editor">) */));
@@ -73,6 +73,7 @@ export declare class XUtils {
73
73
  static fetch(path: string, value: any, usePublicToken?: boolean | XToken): Promise<any>;
74
74
  static post(path: string, value: any): Promise<Response>;
75
75
  static openExcelReport(apiPath: string, requestPayload: any, fileName?: string): Promise<boolean>;
76
+ static downloadFile(apiPath: string, requestPayload: any, fileName: string): Promise<boolean>;
76
77
  static fetchBasicJson(path: string, value: any, usePublicToken?: boolean | XToken): Promise<Response>;
77
78
  static fetchFile(path: string, jsonFieldValue: any, fileToPost: any): Promise<any>;
78
79
  static fetchBasicAuthBasic(path: string, headers: any, body: any, usePublicToken?: boolean | XToken): Promise<Response>;
@@ -81,6 +81,7 @@ var ExportImportParam_1 = require("../serverApi/ExportImportParam");
81
81
  var XResponseError_1 = require("./XResponseError");
82
82
  var FindParam_1 = require("../serverApi/FindParam");
83
83
  var XUtilsMetadataCommon_1 = require("../serverApi/XUtilsMetadataCommon");
84
+ var XLocale_1 = require("./XLocale");
84
85
  var OperationType;
85
86
  (function (OperationType) {
86
87
  OperationType[OperationType["None"] = 0] = "None";
@@ -335,7 +336,17 @@ var XUtils = /** @class */ (function () {
335
336
  };
336
337
  XUtils.openExcelReport = function (apiPath, requestPayload, fileName) {
337
338
  return __awaiter(this, void 0, void 0, function () {
338
- var response, e_5, fileNameExt, respBlob, url, a;
339
+ return __generator(this, function (_a) {
340
+ return [2 /*return*/, XUtils.downloadFile(apiPath, requestPayload, "".concat(fileName !== null && fileName !== void 0 ? fileName : apiPath, ".xlsx"))];
341
+ });
342
+ });
343
+ };
344
+ // general method for file download
345
+ // returns true if the download finished successfully (often we don´t need this info)
346
+ // it would be nice if the fileName could be taken also from backend, from the service call
347
+ XUtils.downloadFile = function (apiPath, requestPayload, fileName) {
348
+ return __awaiter(this, void 0, void 0, function () {
349
+ var response, e_5, respBlob, url, a;
339
350
  return __generator(this, function (_a) {
340
351
  switch (_a.label) {
341
352
  case 0:
@@ -346,17 +357,15 @@ var XUtils = /** @class */ (function () {
346
357
  return [3 /*break*/, 3];
347
358
  case 2:
348
359
  e_5 = _a.sent();
349
- XUtils.showErrorMessage("Nepodarilo sa vytvori\u0165/stiahnu\u0165 xlsx s\u00FAbor.", e_5); // dalsie info (apiPath, payload) by mali byt v "e"
360
+ XUtils.showErrorMessage((0, XLocale_1.xLocaleOption)('fileDownloadFailed'), e_5); // next info (apiPath, payload) should be in "e"
350
361
  return [2 /*return*/, false];
351
- case 3:
352
- fileNameExt = "".concat(fileName !== null && fileName !== void 0 ? fileName : apiPath, ".xlsx");
353
- return [4 /*yield*/, response.blob()];
362
+ case 3: return [4 /*yield*/, response.blob()];
354
363
  case 4:
355
364
  respBlob = _a.sent();
356
365
  url = window.URL.createObjectURL(respBlob);
357
366
  a = document.createElement('a');
358
367
  a.href = url;
359
- a.download = fileNameExt;
368
+ a.download = fileName;
360
369
  a.click();
361
370
  return [2 /*return*/, true];
362
371
  }
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import { XtDocTemplate } from "./xt-doc-template";
3
+ export declare const XDocTemplateButton: (props: {
4
+ entity: string;
5
+ rowId: number | undefined;
6
+ docTemplates?: ((entity: string) => Promise<XtDocTemplate[]>) | undefined;
7
+ }) => React.JSX.Element | null;
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __generator = (this && this.__generator) || function (thisArg, body) {
35
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
36
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
37
+ function verb(n) { return function (v) { return step([n, v]); }; }
38
+ function step(op) {
39
+ if (f) throw new TypeError("Generator is already executing.");
40
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
41
+ 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;
42
+ if (y = 0, t) op = [op[0] & 2, t.value];
43
+ switch (op[0]) {
44
+ case 0: case 1: t = op; break;
45
+ case 4: _.label++; return { value: op[1], done: false };
46
+ case 5: _.label++; y = op[1]; op = [0]; continue;
47
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
48
+ default:
49
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
50
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
51
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
52
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
53
+ if (t[2]) _.ops.pop();
54
+ _.trys.pop(); continue;
55
+ }
56
+ op = body.call(thisArg, _);
57
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
58
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
59
+ }
60
+ };
61
+ var __read = (this && this.__read) || function (o, n) {
62
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
63
+ if (!m) return o;
64
+ var i = m.call(o), r, ar = [], e;
65
+ try {
66
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
67
+ }
68
+ catch (error) { e = { error: error }; }
69
+ finally {
70
+ try {
71
+ if (r && !r.done && (m = i["return"])) m.call(i);
72
+ }
73
+ finally { if (e) throw e.error; }
74
+ }
75
+ return ar;
76
+ };
77
+ Object.defineProperty(exports, "__esModule", { value: true });
78
+ exports.XDocTemplateButton = void 0;
79
+ var react_1 = __importStar(require("react"));
80
+ var button_1 = require("primereact/button");
81
+ var splitbutton_1 = require("primereact/splitbutton");
82
+ var XUtils_1 = require("../../components/XUtils");
83
+ var XUtilsCommon_1 = require("../../serverApi/XUtilsCommon");
84
+ var XLocale_1 = require("../../components/XLocale");
85
+ var XDocTemplateButton = function (props) {
86
+ var _a = __read((0, react_1.useState)([]), 2), docTemplateList = _a[0], setDocTemplateList = _a[1];
87
+ // parameter [] - works like componentDidMount
88
+ (0, react_1.useEffect)(function () {
89
+ loadDocTemplates();
90
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
91
+ var loadDocTemplates = function () { return __awaiter(void 0, void 0, void 0, function () {
92
+ var docTemplateListLocal;
93
+ return __generator(this, function (_a) {
94
+ switch (_a.label) {
95
+ case 0:
96
+ if (!props.docTemplates) return [3 /*break*/, 2];
97
+ return [4 /*yield*/, props.docTemplates(props.entity)];
98
+ case 1:
99
+ docTemplateListLocal = _a.sent();
100
+ return [3 /*break*/, 4];
101
+ case 2: return [4 /*yield*/, XUtils_1.XUtils.fetchRows('XtDocTemplate', XUtilsCommon_1.XUtilsCommon.createCustomFilter("[entity] = '".concat(props.entity, "' AND [availableInForms] = TRUE")), "label", ["templateXFile.name"])];
102
+ case 3:
103
+ // default
104
+ docTemplateListLocal = _a.sent();
105
+ _a.label = 4;
106
+ case 4:
107
+ setDocTemplateList(docTemplateListLocal);
108
+ return [2 /*return*/];
109
+ }
110
+ });
111
+ }); };
112
+ var onClickButton = function (xtDocTemplate) { return __awaiter(void 0, void 0, void 0, function () {
113
+ var xtRunDocTemplateRequest;
114
+ var _a;
115
+ return __generator(this, function (_b) {
116
+ // in XLazyDataTable if no row is selected
117
+ if (!props.rowId) {
118
+ alert((0, XLocale_1.xLocaleOption)('pleaseSelectRow'));
119
+ return [2 /*return*/];
120
+ }
121
+ xtRunDocTemplateRequest = { xtDocTemplateId: xtDocTemplate.id, rowId: props.rowId, xUser: (_a = XUtils_1.XUtils.getXToken()) === null || _a === void 0 ? void 0 : _a.xUser };
122
+ // TODO - pridat id-cko do nazvu? alebo na XtDocTemplate vytvorit nejaky atribut pre nazov suboru vo forme Klient-{klient.meno}-{klient.priezvisko}.xlsx
123
+ // ale to by chcelo vytvorit ten nazov v service (po tom co bude nacitany row) a nejako ho dostat sem
124
+ XUtils_1.XUtils.downloadFile('xt-run-doc-template', xtRunDocTemplateRequest, xtDocTemplate.templateXFile.name);
125
+ return [2 /*return*/];
126
+ });
127
+ }); };
128
+ if (docTemplateList.length === 0) {
129
+ return null;
130
+ }
131
+ else if (docTemplateList.length === 1) {
132
+ // simple button
133
+ var docTemplate_1 = docTemplateList[0];
134
+ return (react_1.default.createElement(button_1.Button, { icon: "pi pi-file-export", label: docTemplate_1.label, onClick: function () { return onClickButton(docTemplate_1); }, className: "m-1" }));
135
+ }
136
+ else {
137
+ // split button
138
+ var docTemplate0_1 = docTemplateList[0];
139
+ var items = [];
140
+ var _loop_1 = function (index) {
141
+ var docTemplate = docTemplateList[index];
142
+ items.push({ icon: "pi pi-file-export", label: docTemplate.label, command: function () { return onClickButton(docTemplate); } });
143
+ };
144
+ for (var index = 1; index < docTemplateList.length; index++) {
145
+ _loop_1(index);
146
+ }
147
+ return (react_1.default.createElement(splitbutton_1.SplitButton, { icon: "pi pi-file-export", label: docTemplate0_1.label, onClick: function () { return onClickButton(docTemplate0_1); }, model: items, className: "m-1" }));
148
+ }
149
+ };
150
+ exports.XDocTemplateButton = XDocTemplateButton;
@@ -0,0 +1,6 @@
1
+ import { XtDocTemplate } from "./xt-doc-template";
2
+ export interface XtDocTemplateFieldToJoin {
3
+ id: number;
4
+ xtDocTemplate: XtDocTemplate;
5
+ field: string;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,18 @@
1
+ import { XtDocTemplateFieldToJoin } from "./xt-doc-template-field-to-join";
2
+ import { XUser } from "../../serverApi/XUser";
3
+ import { XFile } from "../files/x-file";
4
+ import { XEnum } from "../../administration/x-enum";
5
+ export interface XtDocTemplate {
6
+ id: number;
7
+ label: string;
8
+ comment: string | null;
9
+ entity: string;
10
+ xtDocTemplateFieldToJoinList: XtDocTemplateFieldToJoin[];
11
+ templateId: string | null;
12
+ templateType: XEnum;
13
+ templateXFile: XFile;
14
+ availableInForms: boolean;
15
+ modifDate: Date | null;
16
+ modifXUser: XUser | null;
17
+ version: number;
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ export interface XFile {
2
+ id: number;
3
+ name: string;
4
+ size: number;
5
+ pathName: string;
6
+ modifDate: Date;
7
+ modifXUser: number;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -14,7 +14,8 @@ export interface XCustomFilterItem {
14
14
  }
15
15
  export type XCustomFilter = XCustomFilterItem | XCustomFilterItem[];
16
16
  export declare enum XFilterMatchMode {
17
- X_AUTO_COMPLETE = "xAutoComplete"
17
+ X_AUTO_COMPLETE = "xAutoComplete",
18
+ X_FILTER_ELEMENT = "xFilterElement"
18
19
  }
19
20
  export interface XDataTableFilterMetaData extends DataTableFilterMetaData {
20
21
  customFilterItems?: XCustomFilterItem[];
@@ -12,6 +12,7 @@ var ResultType;
12
12
  var XFilterMatchMode;
13
13
  (function (XFilterMatchMode) {
14
14
  XFilterMatchMode["X_AUTO_COMPLETE"] = "xAutoComplete";
15
+ XFilterMatchMode["X_FILTER_ELEMENT"] = "xFilterElement"; // custom filter element (defined in filterElement property)
15
16
  })(XFilterMatchMode = exports.XFilterMatchMode || (exports.XFilterMatchMode = {}));
16
17
  var XAggregateFunction;
17
18
  (function (XAggregateFunction) {
@@ -1,6 +1,12 @@
1
+ import { XUser } from "./XUser";
1
2
  export interface XGetSequenceValueRequest {
2
3
  name: string;
3
4
  }
4
5
  export interface XGetSequenceValueResponse {
5
6
  value: number;
6
7
  }
8
+ export interface XtRunDocTemplateRequest {
9
+ xtDocTemplateId: number;
10
+ rowId: number;
11
+ xUser?: XUser;
12
+ }
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // misc api used in lib
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michalrakus/x-react-web-lib",
3
- "version": "1.34.0",
3
+ "version": "1.35.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "clean": "rimraf lib",
@@ -0,0 +1,3 @@
1
+ // generated by gulp
2
+
3
+ export * from './lib/modules/docTemplates/xt-doc-template';
@@ -0,0 +1,5 @@
1
+ // generated by gulp
2
+
3
+ 'use strict';
4
+
5
+ module.exports = require('./lib/modules/docTemplates/xt-doc-template.js');