@michalrakus/x-react-web-lib 0.21.0 → 0.25.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.
@@ -38,18 +38,21 @@ var XBrowseMetaForm = /** @class */ (function (_super) {
38
38
  }
39
39
  XBrowseMetaForm.prototype.render = function () {
40
40
  return (react_1.default.createElement("div", null,
41
- react_1.default.createElement(XInputDecimal_1.XInputDecimal, { form: this, field: "idXBrowseMeta", label: "ID", readOnly: true }),
42
- react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "entity", label: "Entity", size: 20 }),
43
- react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "browseId", label: "Browse ID", size: 20 }),
44
- react_1.default.createElement(XInputDecimal_1.XInputDecimal, { form: this, field: "rows", label: "Rows" }),
45
- react_1.default.createElement(XFormDataTable2_1.XFormDataTable2, { form: this, assocField: "columnMetaList", label: "Column list" },
46
- react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "idXColumnMeta", header: "ID", readOnly: true }),
47
- react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "field", header: "Field", width: "17rem" }),
48
- react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "header", header: "Header", width: "17rem" }),
49
- react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "align", header: "Align" }),
50
- react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "dropdownInFilter", header: "Dropdown in filter" }),
51
- react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "width", header: "Width" }),
52
- react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "columnOrder", header: "Column order" })),
41
+ react_1.default.createElement("div", { className: "x-form-row" },
42
+ react_1.default.createElement("div", { className: "x-form-col" },
43
+ react_1.default.createElement(XInputDecimal_1.XInputDecimal, { form: this, field: "idXBrowseMeta", label: "ID", readOnly: true }),
44
+ react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "entity", label: "Entity", size: 20 }),
45
+ react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "browseId", label: "Browse ID", size: 20 }),
46
+ react_1.default.createElement(XInputDecimal_1.XInputDecimal, { form: this, field: "rows", label: "Rows" }))),
47
+ react_1.default.createElement("div", { className: "x-viewport-width" },
48
+ react_1.default.createElement(XFormDataTable2_1.XFormDataTable2, { form: this, assocField: "columnMetaList", label: "Column list" },
49
+ react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "idXColumnMeta", header: "ID", readOnly: true }),
50
+ react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "field", header: "Field", width: "17rem" }),
51
+ react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "header", header: "Header", width: "17rem" }),
52
+ react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "align", header: "Align" }),
53
+ react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "dropdownInFilter", header: "Dropdown in filter" }),
54
+ react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "width", header: "Width" }),
55
+ react_1.default.createElement(XFormDataTable2_1.XFormColumn, { field: "columnOrder", header: "Column order" }))),
53
56
  react_1.default.createElement(XFormFooter_1.XFormFooter, { form: this })));
54
57
  };
55
58
  XBrowseMetaForm = __decorate([
@@ -155,15 +155,17 @@ var XUserForm = /** @class */ (function (_super) {
155
155
  var _this = this;
156
156
  // autoComplete="new-password" - bez tohto chrome predplna user/password, ak si user da ulozit user/password (pre danu url)
157
157
  return (react_1.default.createElement("div", null,
158
- react_1.default.createElement(XInputDecimal_1.XInputDecimal, { form: this, field: "idXUser", label: "ID", readOnly: true, labelStyle: { width: '14rem' } }),
159
- react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "username", label: "Username", size: 20, labelStyle: { width: '14rem' }, readOnly: this.state.usernameReadOnly }),
160
- react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "name", label: "Name", size: 30, labelStyle: { width: '14rem' } }),
161
- react_1.default.createElement("div", { className: "field grid" },
162
- react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem' } }, "New password"),
163
- react_1.default.createElement(password_1.Password, { value: this.state.passwordNew, onChange: function (e) { return _this.setState({ passwordNew: e.target.value }); }, feedback: false, maxLength: 64, size: 20, autoComplete: "new-password" })),
164
- react_1.default.createElement("div", { className: "field grid" },
165
- react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem', whiteSpace: 'nowrap' } }, "Confirm new password"),
166
- react_1.default.createElement(password_1.Password, { value: this.state.passwordNewConfirm, onChange: function (e) { return _this.setState({ passwordNewConfirm: e.target.value }); }, feedback: false, maxLength: 64, size: 20, autoComplete: "new-password" })),
158
+ react_1.default.createElement("div", { className: "x-form-row" },
159
+ react_1.default.createElement("div", { className: "x-form-col" },
160
+ react_1.default.createElement(XInputDecimal_1.XInputDecimal, { form: this, field: "idXUser", label: "ID", readOnly: true, labelStyle: { width: '14rem' } }),
161
+ react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "username", label: "Username", size: 20, labelStyle: { width: '14rem' }, readOnly: this.state.usernameReadOnly }),
162
+ react_1.default.createElement(XInputText_1.XInputText, { form: this, field: "name", label: "Name", size: 30, labelStyle: { width: '14rem' } }),
163
+ react_1.default.createElement("div", { className: "field grid" },
164
+ react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem' } }, "New password"),
165
+ react_1.default.createElement(password_1.Password, { value: this.state.passwordNew, onChange: function (e) { return _this.setState({ passwordNew: e.target.value }); }, feedback: false, maxLength: 64, size: 20, autoComplete: "new-password" })),
166
+ react_1.default.createElement("div", { className: "field grid" },
167
+ react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem', whiteSpace: 'nowrap' } }, "Confirm new password"),
168
+ react_1.default.createElement(password_1.Password, { value: this.state.passwordNewConfirm, onChange: function (e) { return _this.setState({ passwordNewConfirm: e.target.value }); }, feedback: false, maxLength: 64, size: 20, autoComplete: "new-password" })))),
167
169
  react_1.default.createElement(XFormFooter_1.XFormFooter, { form: this })));
168
170
  };
169
171
  XUserForm = __decorate([
@@ -134,20 +134,22 @@ var XChangePasswordForm = function (props) {
134
134
  return (
135
135
  // autoComplete="new-password" - bez tohto chrome predplna user/password, ak si user da ulozit user/password (pre danu url)
136
136
  react_1.default.createElement("div", null,
137
- react_1.default.createElement("div", { className: "flex justify-content-center" },
138
- react_1.default.createElement("h2", null, "Change password")),
139
- react_1.default.createElement("div", { className: "field grid" },
140
- react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem' } }, "User"),
141
- react_1.default.createElement(inputtext_1.InputText, { value: (_a = XUtils_1.XUtils.getXToken()) === null || _a === void 0 ? void 0 : _a.username, readOnly: true })),
142
- react_1.default.createElement("div", { className: "field grid" },
143
- react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem' } }, "Current password"),
144
- react_1.default.createElement(password_1.Password, { value: passwordCurrent, onChange: function (e) { return setPasswordCurrent(e.target.value); }, feedback: false, maxLength: 64, autoComplete: "new-password" })),
145
- react_1.default.createElement("div", { className: "field grid" },
146
- react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem' } }, "New password"),
147
- react_1.default.createElement(password_1.Password, { value: passwordNew, onChange: function (e) { return setPasswordNew(e.target.value); }, feedback: false, maxLength: 64, autoComplete: "new-password" })),
148
- react_1.default.createElement("div", { className: "field grid" },
149
- react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem', whiteSpace: 'nowrap' } }, "Confirm new password"),
150
- react_1.default.createElement(password_1.Password, { value: passwordNewConfirm, onChange: function (e) { return setPasswordNewConfirm(e.target.value); }, feedback: false, maxLength: 64, autoComplete: "new-password" })),
137
+ react_1.default.createElement("div", { className: "x-form-row" },
138
+ react_1.default.createElement("div", { className: "x-form-col" },
139
+ react_1.default.createElement("div", { className: "flex justify-content-center" },
140
+ react_1.default.createElement("h2", null, "Change password")),
141
+ react_1.default.createElement("div", { className: "field grid" },
142
+ react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem' } }, "User"),
143
+ react_1.default.createElement(inputtext_1.InputText, { value: (_a = XUtils_1.XUtils.getXToken()) === null || _a === void 0 ? void 0 : _a.username, readOnly: true })),
144
+ react_1.default.createElement("div", { className: "field grid" },
145
+ react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem' } }, "Current password"),
146
+ react_1.default.createElement(password_1.Password, { value: passwordCurrent, onChange: function (e) { return setPasswordCurrent(e.target.value); }, feedback: false, maxLength: 64, autoComplete: "new-password" })),
147
+ react_1.default.createElement("div", { className: "field grid" },
148
+ react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem' } }, "New password"),
149
+ react_1.default.createElement(password_1.Password, { value: passwordNew, onChange: function (e) { return setPasswordNew(e.target.value); }, feedback: false, maxLength: 64, autoComplete: "new-password" })),
150
+ react_1.default.createElement("div", { className: "field grid" },
151
+ react_1.default.createElement("label", { className: "col-fixed", style: { width: '14rem', whiteSpace: 'nowrap' } }, "Confirm new password"),
152
+ react_1.default.createElement(password_1.Password, { value: passwordNewConfirm, onChange: function (e) { return setPasswordNewConfirm(e.target.value); }, feedback: false, maxLength: 64, autoComplete: "new-password" })))),
151
153
  react_1.default.createElement("div", { className: "flex justify-content-center" },
152
154
  react_1.default.createElement(button_1.Button, { label: "Save", onClick: onClickSave }))));
153
155
  };
@@ -150,9 +150,10 @@ var XDropdown = /** @class */ (function (_super) {
150
150
  // TODO - readOnly implementovat
151
151
  // Dropdown setuje do atributu object.assocField asociovany objekt zo zoznamu objektov ktore ziskame podla asociacie
152
152
  var assocObject = this.getValueFromObject();
153
+ // appendTo={document.body} appenduje overlay panel na element body - eliminuje "skakanie" formularu na mobile pri kliknuti na dropdown
153
154
  return (react_1.default.createElement("div", { className: "field grid" },
154
155
  react_1.default.createElement("label", { htmlFor: props.assocField, className: "col-fixed", style: labelStyle }, label),
155
- react_1.default.createElement(dropdown_1.Dropdown, __assign({ id: props.assocField, optionLabel: props.displayField, value: assocObject, options: options, onChange: onValueChange }, this.getClassNameTooltip()))));
156
+ react_1.default.createElement(dropdown_1.Dropdown, __assign({ appendTo: document.body, id: props.assocField, optionLabel: props.displayField, value: assocObject, options: options, onChange: onValueChange }, this.getClassNameTooltip()))));
156
157
  };
157
158
  return XDropdown;
158
159
  }(XFormComponent_1.XFormComponent));
@@ -118,6 +118,7 @@ var XDropdownDT = function (props) {
118
118
  }
119
119
  }
120
120
  var options = props.dropdownOptionsMap[props.assocField] !== undefined ? props.dropdownOptionsMap[props.assocField] : []; // mozno mozme do options prasknut rovno undefined...
121
- return (react_1.default.createElement(dropdown_1.Dropdown, { id: props.assocField, optionLabel: props.displayField, value: assocObject, options: options, onChange: function (e) { return onValueChange(props.assocField, props.rowData, e.target.value); } }));
121
+ // appendTo={document.body} appenduje overlay panel na element body - eliminuje problem s overflow (pozri poznamku v XDropdownDTFilter)
122
+ return (react_1.default.createElement(dropdown_1.Dropdown, { appendTo: document.body, id: props.assocField, optionLabel: props.displayField, value: assocObject, options: options, onChange: function (e) { return onValueChange(props.assocField, props.rowData, e.target.value); } }));
122
123
  };
123
124
  exports.XDropdownDT = XDropdownDT;
@@ -109,6 +109,8 @@ var XDropdownDTFilter = function (props) {
109
109
  });
110
110
  }); };
111
111
  // dropdown pouziva ako optionValue displayField (nie cely objekt) - je to koli problemom s prazdnym riadkom (nepodarilo sa to spravit inac)
112
- return (react_1.default.createElement(dropdown_1.Dropdown, { style: { width: '100%' }, className: "ui-column-filter", optionLabel: displayField, optionValue: displayField, value: props.value, options: options, onChange: onValueChange }));
112
+ // appendTo={document.body} appenduje overlay panel na element body - panel je vdaka tomu viditelny aj ked ma jeho parent (TH/TD element tabulky)
113
+ // nastavny overflow: hidden, resp. koli scrollovaniu by overlay panel "nevysiel" von z tabulky, v pripade ze je tabulka mala (napr. ma 1 riadok)
114
+ return (react_1.default.createElement(dropdown_1.Dropdown, { appendTo: document.body, style: { width: '100%' }, className: "ui-column-filter", optionLabel: displayField, optionValue: displayField, value: props.value, options: options, onChange: onValueChange }));
113
115
  };
114
116
  exports.XDropdownDTFilter = XDropdownDTFilter;
@@ -84,6 +84,7 @@ var XExportRowsDialog = function (props) {
84
84
  react_1.default.createElement("label", { className: "col-fixed", style: { width: '9.3rem' } }, "Export type"),
85
85
  react_1.default.createElement(dropdown_1.Dropdown, { value: exportType, options: XUtils_1.XUtils.exportTypeOptions, onChange: function (e) { return setExportType(e.value); } })),
86
86
  elem,
87
- react_1.default.createElement(XButton_1.XButton, { label: "Export", onClick: onExport })));
87
+ react_1.default.createElement("div", { className: "flex justify-content-center" },
88
+ react_1.default.createElement(XButton_1.XButton, { label: "Export", onClick: onExport }))));
88
89
  };
89
90
  exports.XExportRowsDialog = XExportRowsDialog;
@@ -6,6 +6,7 @@ export interface XFormComponentProps {
6
6
  label?: string;
7
7
  readOnly?: boolean;
8
8
  labelStyle?: React.CSSProperties;
9
+ inline?: boolean;
9
10
  }
10
11
  export declare class XFormComponent<P extends XFormComponentProps> extends Component<P> {
11
12
  constructor(props: P);
@@ -11,8 +11,10 @@ export interface XFormDataTableProps {
11
11
  dataKey?: string;
12
12
  paginator?: boolean;
13
13
  rows?: number;
14
+ scrollable: boolean;
14
15
  scrollWidth?: string;
15
16
  scrollHeight?: string;
17
+ shrinkWidth: boolean;
16
18
  label?: string;
17
19
  readOnly?: boolean;
18
20
  onClickAddRow?: () => void;
@@ -21,6 +23,12 @@ export interface XFormDataTableProps {
21
23
  children: ReactChild[];
22
24
  }
23
25
  export declare class XFormDataTable2 extends Component<XFormDataTableProps> {
26
+ static defaultProps: {
27
+ scrollable: boolean;
28
+ scrollWidth: string;
29
+ scrollHeight: string;
30
+ shrinkWidth: boolean;
31
+ };
24
32
  props: XFormDataTableProps;
25
33
  entity?: string;
26
34
  dataKey?: string;
@@ -305,19 +305,22 @@ var XFormDataTable2 = /** @class */ (function (_super) {
305
305
  var object = this.props.form.state.object;
306
306
  var valueList = object !== null ? object[this.props.assocField] : [];
307
307
  var xEntity = XUtilsMetadata_1.XUtilsMetadata.getXEntity(this.getEntity());
308
- var scrollable;
309
- if (this.props.scrollWidth !== undefined || this.props.scrollHeight !== undefined) {
310
- scrollable = true;
308
+ var scrollWidth = undefined; // vypnute horizontalne scrollovanie
309
+ var scrollHeight = undefined; // vypnute vertikalne scrollovanie
310
+ if (this.props.scrollable) {
311
+ if (this.props.scrollWidth !== "none") {
312
+ scrollWidth = this.props.scrollWidth;
313
+ }
314
+ if (this.props.scrollHeight !== "none") {
315
+ scrollHeight = this.props.scrollHeight;
316
+ }
311
317
  }
312
- else {
313
- scrollable = false;
318
+ var style = {};
319
+ if (scrollWidth !== undefined) {
320
+ style.width = scrollWidth;
314
321
  }
315
- var style;
316
- if (this.props.scrollWidth !== undefined) {
317
- style = { width: this.props.scrollWidth };
318
- }
319
- else {
320
- style = { width: 'min-content' }; // ak nic nedame (nechame auto), tak natiahne tabulku na celu sirku stranky, co nechceme; min-content stlaci sirku stranky
322
+ if (this.props.shrinkWidth) {
323
+ style.maxWidth = 'min-content'; // ak nic nedame (nechame auto), tak (v pripade ak nebudeme mat horizontalny scrollbar) natiahne tabulku na celu sirku stranky, co nechceme
321
324
  }
322
325
  var tableStyle;
323
326
  if (this.props.width !== undefined) {
@@ -327,77 +330,80 @@ var XFormDataTable2 = /** @class */ (function (_super) {
327
330
  }
328
331
  tableStyle = { width: width };
329
332
  }
330
- // poznamka - resizableColumns su zrusene lebo nefunguje dropdown vo filtri
333
+ // pre lepsiu citatelnost vytvarame stlpce uz tu
334
+ var columnElemList = react_1.default.Children.map(this.props.children, function (child) {
335
+ // ak chceme zmenit child element, tak treba bud vytvorit novy alebo vyklonovat
336
+ // priklad je na https://soshace.com/building-react-components-using-children-props-and-context-api/
337
+ // (vzdy musime robit manipulacie so stlpcom, lebo potrebujeme pridat filter={true} sortable={true}
338
+ var childColumn = child; // nevedel som to krajsie...
339
+ var childColumnProps = childColumn.props;
340
+ // je dolezite, aby field obsahoval cely path az po zobrazovany atribut, lebo podla neho sa vykonava filtrovanie a sortovanie
341
+ // (aj ked, da sa to prebit na stlpcoch (na elemente Column), su na to atributy)
342
+ var field = XFormDataTable2.getPathForColumn(childColumnProps);
343
+ // TODO - toto by sa mohlo vytiahnut vyssie, aj v bodyTemplate sa vola metoda XUtilsMetadata.getXFieldByPath
344
+ var xField = XUtilsMetadata_1.XUtilsMetadata.getXFieldByPath(xEntity, field);
345
+ // *********** header ***********
346
+ var header = XFormDataTable2.getHeader(childColumnProps, xEntity, field, xField);
347
+ // *********** filterElement ***********
348
+ var filterElement;
349
+ if (xField.type === "boolean") {
350
+ var checkboxValue = thisLocal.getCheckboxFilterValue(field);
351
+ filterElement = react_1.default.createElement(tristatecheckbox_1.TriStateCheckbox, { value: checkboxValue, onChange: function (e) { return thisLocal.onCheckboxFilterChange(field, e.value); } });
352
+ }
353
+ else if (childColumnProps.dropdownInFilter) {
354
+ var dropdownValue = thisLocal.getDropdownFilterValue(field);
355
+ filterElement = react_1.default.createElement(XDropdownDTFilter_1.XDropdownDTFilter, { entity: thisLocal.getEntity(), path: field, value: dropdownValue, onValueChange: thisLocal.onDropdownFilterChange });
356
+ }
357
+ // *********** width/headerStyle ***********
358
+ var width = XUtils_1.XUtils.processPropWidth(childColumn.props.width);
359
+ if (width === undefined || width === "default") {
360
+ width = XUtilsMetadata_1.XUtilsMetadata.computeColumnWidth(xField, childColumnProps.type, header);
361
+ }
362
+ var headerStyle;
363
+ if (width !== undefined) {
364
+ headerStyle = { width: width };
365
+ }
366
+ // *********** align ***********
367
+ var align = "left"; // default
368
+ // do buducna
369
+ // if (childColumnProps.align !== undefined) {
370
+ // align = childColumnProps.align;
371
+ // }
372
+ // else {
373
+ // decimal defaultne zarovnavame doprava
374
+ // if (xField.type === "decimal") {
375
+ // align = "right";
376
+ // }
377
+ // else
378
+ if (xField.type === "boolean") {
379
+ align = "center";
380
+ }
381
+ // }
382
+ // *********** style ***********
383
+ var style;
384
+ // TODO - pouzit className a nie style
385
+ if (align === "center" || align === "right") {
386
+ style = { 'textAlign': align };
387
+ headerStyle = __assign(__assign({}, headerStyle), style); // headerStyle overrides style in TH cell
388
+ }
389
+ return react_1.default.createElement(column_1.Column, { field: field, header: header, filter: true, sortable: true, filterElement: filterElement, headerStyle: headerStyle, style: style, body: function (rowData) { return thisLocal.bodyTemplate(childColumnProps, rowData, xEntity); } });
390
+ });
331
391
  return (react_1.default.createElement("div", null,
332
392
  react_1.default.createElement("div", { className: "flex justify-content-center" },
333
393
  react_1.default.createElement("label", null, label)),
334
- 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, 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 columnResizeMode="expand"*/, tableStyle: tableStyle, scrollable: scrollable, scrollHeight: this.props.scrollHeight, style: style }, react_1.default.Children.map(this.props.children, function (child) {
335
- // ak chceme zmenit child element, tak treba bud vytvorit novy alebo vyklonovat
336
- // priklad je na https://soshace.com/building-react-components-using-children-props-and-context-api/
337
- // (vzdy musime robit manipulacie so stlpcom, lebo potrebujeme pridat filter={true} sortable={true}
338
- var childColumn = child; // nevedel som to krajsie...
339
- var childColumnProps = childColumn.props;
340
- // je dolezite, aby field obsahoval cely path az po zobrazovany atribut, lebo podla neho sa vykonava filtrovanie a sortovanie
341
- // (aj ked, da sa to prebit na stlpcoch (na elemente Column), su na to atributy)
342
- var field = XFormDataTable2.getPathForColumn(childColumnProps);
343
- // TODO - toto by sa mohlo vytiahnut vyssie, aj v bodyTemplate sa vola metoda XUtilsMetadata.getXFieldByPath
344
- var xField = XUtilsMetadata_1.XUtilsMetadata.getXFieldByPath(xEntity, field);
345
- // *********** header ***********
346
- var header = XFormDataTable2.getHeader(childColumnProps, xEntity, field, xField);
347
- // *********** filterElement ***********
348
- var filterElement;
349
- if (xField.type === "boolean") {
350
- var checkboxValue = thisLocal.getCheckboxFilterValue(field);
351
- filterElement = react_1.default.createElement(tristatecheckbox_1.TriStateCheckbox, { value: checkboxValue, onChange: function (e) { return thisLocal.onCheckboxFilterChange(field, e.value); } });
352
- }
353
- else if (childColumnProps.dropdownInFilter) {
354
- var dropdownValue = thisLocal.getDropdownFilterValue(field);
355
- filterElement = react_1.default.createElement(XDropdownDTFilter_1.XDropdownDTFilter, { entity: thisLocal.getEntity(), path: field, value: dropdownValue, onValueChange: thisLocal.onDropdownFilterChange });
356
- }
357
- // *********** width/headerStyle ***********
358
- var width;
359
- if (childColumnProps.width !== undefined) {
360
- width = childColumnProps.width;
361
- if (!isNaN(Number(width))) { // if width is number
362
- width = width + 'rem';
363
- }
364
- }
365
- else {
366
- width = XUtilsMetadata_1.XUtilsMetadata.computeColumnWidth(xField, childColumnProps.type, header);
367
- }
368
- var headerStyle;
369
- if (width !== undefined) {
370
- headerStyle = { width: width };
371
- }
372
- // *********** align ***********
373
- var align = "left"; // default
374
- // do buducna
375
- // if (childColumnProps.align !== undefined) {
376
- // align = childColumnProps.align;
377
- // }
378
- // else {
379
- // decimal defaultne zarovnavame doprava
380
- // if (xField.type === "decimal") {
381
- // align = "right";
382
- // }
383
- // else
384
- if (xField.type === "boolean") {
385
- align = "center";
386
- }
387
- // }
388
- // *********** style ***********
389
- var style;
390
- // TODO - pouzit className a nie style
391
- if (align === "center" || align === "right") {
392
- style = { 'textAlign': align };
393
- headerStyle = __assign(__assign({}, headerStyle), style); // headerStyle overrides style in TH cell
394
- }
395
- return react_1.default.createElement(column_1.Column, { field: field, header: header, filter: true, sortable: true, filterElement: filterElement, headerStyle: headerStyle, style: style, body: function (rowData) { return thisLocal.bodyTemplate(childColumnProps, rowData, xEntity); } });
396
- })),
394
+ react_1.default.createElement("div", { className: "flex justify-content-center" },
395
+ 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, 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)),
397
396
  react_1.default.createElement("div", { className: "flex justify-content-center" },
398
397
  react_1.default.createElement(XButton_1.XButton, { label: "Add row", onClick: onClickAddRow }),
399
398
  react_1.default.createElement(XButton_1.XButton, { label: "Remove row", onClick: onClickRemoveRow }))));
400
399
  };
400
+ XFormDataTable2.defaultProps = {
401
+ scrollable: true,
402
+ scrollWidth: '100%',
403
+ scrollHeight: '200vh',
404
+ // tym ze pouzivame 200vh (max-height pre body), tak realne scrollovanie sa zapne az pri velmi vela riadkoch
405
+ shrinkWidth: true
406
+ };
401
407
  return XFormDataTable2;
402
408
  }(react_1.Component));
403
409
  exports.XFormDataTable2 = XFormDataTable2;
@@ -86,7 +86,19 @@ var XFormNavigator3 = /** @class */ (function (_super) {
86
86
  console.log("neocakavana chyba - pole formElements je prazdne");
87
87
  }
88
88
  }
89
- this.setState({ formElements: formElementsCloned });
89
+ this.setState({ formElements: formElementsCloned }, function () {
90
+ // ked sa na mobile preklikavame medzi formularmi, tak browser drzi nascrollovanu poziciu ale my sa chceme vratit na zaciatok stranky
91
+ // (tento callback sa zavola po refreshnuti stranky)
92
+ // taketo nieco nezafungovalo, neviem preco...
93
+ // setTimeout(function() {
94
+ // window.scrollTo(0,0);
95
+ // }, 100);
96
+ // tak scrollujeme k menu, ktore je v hornej casti
97
+ var menuElem = document.getElementById("menuId");
98
+ if (menuElem !== null) {
99
+ menuElem.scrollIntoView();
100
+ }
101
+ });
90
102
  };
91
103
  XFormNavigator3.prototype.render = function () {
92
104
  var _this = this;
@@ -100,7 +112,8 @@ var XFormNavigator3 = /** @class */ (function (_super) {
100
112
  var display = (displayed ? "block" : "none");
101
113
  // TODO - neviem ci naisto treba key={index}
102
114
  // max-width: 100% - koli chybe ked sa na mobile nezobrazovala lava cast tabulky/formularu (nedalo sa k nej doscrollovat)
103
- return react_1.default.createElement("div", { key: index, style: { display: display, maxWidth: "100%" } }, formElementCloned);
115
+ // poznamka2: tento problem sa vyskytoval v suvislosti s flex-direction: column na .App-form - ten sme zrusili a preto maxWidth (zatial) odstranujeme
116
+ return react_1.default.createElement("div", { key: index, style: { display: display /*, maxWidth: "100%"*/ } }, formElementCloned);
104
117
  });
105
118
  return (react_1.default.createElement("div", { className: "App-form" }, forms));
106
119
  };
@@ -51,6 +51,6 @@ var XInputDate = function (props) {
51
51
  }
52
52
  return (react_1.default.createElement("div", { className: "field grid" },
53
53
  react_1.default.createElement("label", { htmlFor: props.field, className: "col-fixed", style: { width: XUtils_1.XUtils.FIELD_LABEL_WIDTH } }, label),
54
- react_1.default.createElement(calendar_1.Calendar, { id: props.field, value: fieldValue, onChange: onValueChange, disabled: readOnly, showIcon: true, touchUI: true, dateFormat: XUtilsConversions_1.dateFormatCalendar(), showTime: showTime, showSeconds: showTime, inputClassName: cssClassName, showOnFocus: false })));
54
+ react_1.default.createElement(calendar_1.Calendar, { id: props.field, value: fieldValue, onChange: onValueChange, disabled: readOnly, showIcon: true, dateFormat: XUtilsConversions_1.dateFormatCalendar(), showTime: showTime, showSeconds: showTime, inputClassName: cssClassName, showOnFocus: false })));
55
55
  };
56
56
  exports.XInputDate = XInputDate;
@@ -49,6 +49,7 @@ var XInputDateDT = function (props) {
49
49
  }
50
50
  // TODO - nefunguje dobre pridavanie noveho riadku - su tam stare neupdatnute hodnoty - este to asi neopravili https://github.com/primefaces/primereact/issues/1277
51
51
  // test mame na TestovaciForm
52
- return (react_1.default.createElement(calendar_1.Calendar, { id: props.field, value: fieldValue, onChange: function (e) { return onValueChange(props.field, props.rowData, e.value); }, disabled: readOnly, showIcon: true, dateFormat: XUtilsConversions_1.dateFormatCalendar(), showTime: showTime, showSeconds: showTime, inputClassName: cssClassName, showOnFocus: false }));
52
+ // appendTo={document.body} appenduje overlay panel na element body - eliminuje problem s overflow (pozri poznamku v XDropdownDTFilter)
53
+ return (react_1.default.createElement(calendar_1.Calendar, { appendTo: document.body, id: props.field, value: fieldValue, onChange: function (e) { return onValueChange(props.field, props.rowData, e.value); }, disabled: readOnly, showIcon: true, dateFormat: XUtilsConversions_1.dateFormatCalendar(), showTime: showTime, showSeconds: showTime, inputClassName: cssClassName, showOnFocus: false }));
53
54
  };
54
55
  exports.XInputDateDT = XInputDateDT;
@@ -1,11 +1,8 @@
1
- import { XFormBase } from "./XFormBase";
2
1
  import React from "react";
3
- export declare const XInputDecimal: (props: {
4
- form: XFormBase;
2
+ import { XFormComponentProps } from "./XFormComponent";
3
+ export interface XInputDecimalProps extends XFormComponentProps {
5
4
  field: string;
6
- label?: string | undefined;
7
- readOnly?: boolean | undefined;
8
- size?: number | undefined;
9
- labelStyle?: React.CSSProperties | undefined;
10
- inputStyle?: React.CSSProperties | undefined;
11
- }) => JSX.Element;
5
+ size?: number;
6
+ inputStyle?: React.CSSProperties;
7
+ }
8
+ export declare const XInputDecimal: (props: XInputDecimalProps) => JSX.Element;
@@ -10,17 +10,25 @@ var XUtilsMetadata_1 = require("./XUtilsMetadata");
10
10
  var XUtilsCommon_1 = require("../serverApi/XUtilsCommon");
11
11
  var XUtils_1 = require("./XUtils");
12
12
  var XInputDecimal = function (props) {
13
- var _a, _b;
13
+ var _a, _b, _c;
14
14
  props.form.addField(props.field);
15
15
  var xField = XUtilsMetadata_1.XUtilsMetadata.getXFieldByPathStr(props.form.getEntity(), props.field);
16
- var _c = XUtilsMetadata_1.XUtilsMetadata.getParamsForInputNumber(xField), useGrouping = _c.useGrouping, fractionDigits = _c.fractionDigits, min = _c.min, max = _c.max, size = _c.size;
16
+ var _d = XUtilsMetadata_1.XUtilsMetadata.getParamsForInputNumber(xField), useGrouping = _d.useGrouping, fractionDigits = _d.fractionDigits, min = _d.min, max = _d.max, size = _d.size;
17
17
  var label = (_a = props.label) !== null && _a !== void 0 ? _a : props.field;
18
18
  var readOnly = XUtils_1.XUtils.isReadOnly(props.field, props.readOnly);
19
19
  if (!xField.isNullable && !readOnly) {
20
20
  label = XUtils_1.XUtils.markNotNull(label);
21
21
  }
22
22
  var sizeInput = props.size !== undefined ? props.size : size;
23
- var labelStyle = (_b = props.labelStyle) !== null && _b !== void 0 ? _b : { width: XUtils_1.XUtils.FIELD_LABEL_WIDTH };
23
+ var inline = (_b = props.inline) !== null && _b !== void 0 ? _b : false;
24
+ var labelStyle = (_c = props.labelStyle) !== null && _c !== void 0 ? _c : {};
25
+ if (!inline) {
26
+ XUtils_1.XUtils.addCssPropIfNotExists(labelStyle, { width: XUtils_1.XUtils.FIELD_LABEL_WIDTH });
27
+ }
28
+ else {
29
+ XUtils_1.XUtils.addCssPropIfNotExists(labelStyle, { width: 'auto' }); // podla dlzky labelu
30
+ XUtils_1.XUtils.addCssPropIfNotExists(labelStyle, { marginLeft: '1rem' });
31
+ }
24
32
  var onValueChange = function (e) {
25
33
  // z InputNumber prichadza e.value - typ number alebo null
26
34
  props.form.onFieldChange(props.field, e.value);
@@ -10,23 +10,38 @@ export interface XEditModeHandlers {
10
10
  onMoveColumnLeft: (field: string) => void;
11
11
  onMoveColumnRight: (field: string) => void;
12
12
  }
13
- export declare const XLazyDataTable: (props: {
13
+ export interface XLazyDataTableProps {
14
14
  entity: string;
15
- dataKey?: string | undefined;
16
- rows?: number | undefined;
17
- scrollWidth?: string | undefined;
18
- scrollHeight?: string | undefined;
19
- onAddRow?: (() => void) | undefined;
20
- onEdit?: ((selectedRow: any) => void) | undefined;
21
- removeRow?: boolean | ((selectedRow: any) => Promise<boolean>) | undefined;
15
+ dataKey?: string;
16
+ paginator: boolean;
17
+ rows: number;
18
+ scrollable: boolean;
19
+ scrollWidth: string;
20
+ scrollHeight: string;
21
+ formFooterHeight?: string;
22
+ shrinkWidth: boolean;
23
+ onAddRow?: () => void;
24
+ onEdit?: (selectedRow: any) => void;
25
+ removeRow?: ((selectedRow: any) => Promise<boolean>) | boolean;
22
26
  appButtons?: any;
23
- searchTableParams?: SearchTableParams | undefined;
24
- width?: string | undefined;
25
- editMode?: boolean | undefined;
26
- editModeHandlers?: XEditModeHandlers | undefined;
27
- displayed?: boolean | undefined;
27
+ searchTableParams?: SearchTableParams;
28
+ width?: string;
29
+ editMode?: boolean;
30
+ editModeHandlers?: XEditModeHandlers;
31
+ displayed?: boolean;
28
32
  children: ReactChild[];
29
- }) => JSX.Element;
33
+ }
34
+ export declare const XLazyDataTable: {
35
+ (props: XLazyDataTableProps): JSX.Element;
36
+ defaultProps: {
37
+ paginator: boolean;
38
+ rows: number;
39
+ scrollable: boolean;
40
+ scrollWidth: string;
41
+ scrollHeight: string;
42
+ shrinkWidth: boolean;
43
+ };
44
+ };
30
45
  export interface XLazyColumnProps {
31
46
  field: string;
32
47
  header?: any;
@@ -107,13 +107,12 @@ var XButtonIconSmall_1 = require("./XButtonIconSmall");
107
107
  var tristatecheckbox_1 = require("primereact/tristatecheckbox");
108
108
  var XUtilsCommon_1 = require("../serverApi/XUtilsCommon");
109
109
  var XExportRowsDialog_1 = require("./XExportRowsDialog");
110
- // POZNAMKA: parameter width?: string; neviem ako funguje (najme pri pouziti scrollWidth/scrollHeight), ani sa zatial nikde nepouziva
111
110
  var XLazyDataTable = function (props) {
112
111
  var dataTableEl = react_1.useRef(null);
113
112
  var _a = __read(react_1.useState({ rowList: [], totalRecords: 0 }), 2), value = _a[0], setValue = _a[1];
114
113
  var _b = __read(react_1.useState(false), 2), loading = _b[0], setLoading = _b[1];
115
114
  var _c = __read(react_1.useState(0), 2), first = _c[0], setFirst = _c[1];
116
- var _d = __read(react_1.useState(props.rows !== undefined ? props.rows : 10), 2), rows = _d[0], setRows = _d[1];
115
+ var _d = __read(react_1.useState(props.paginator ? props.rows : undefined), 2), rows = _d[0], setRows = _d[1];
117
116
  var filtersInit = {};
118
117
  if (props.searchTableParams !== undefined && props.searchTableParams.filter !== undefined) {
119
118
  filtersInit[props.searchTableParams.displayField] = { value: props.searchTableParams.filter, matchMode: "startsWith" };
@@ -489,19 +488,62 @@ var XLazyDataTable = function (props) {
489
488
  return bodyValue;
490
489
  };
491
490
  var xEntity = XUtilsMetadata_1.XUtilsMetadata.getXEntity(props.entity);
492
- var scrollable;
493
- if (props.scrollWidth !== undefined || props.scrollHeight !== undefined) {
494
- scrollable = true;
495
- }
496
- else {
497
- scrollable = false;
491
+ // ak mame scrollWidth/scrollHeight = viewport (default), vyratame scrollWidth/scrollHeight tak aby tabulka "sadla" okna (viewport-u)
492
+ var scrollWidth = undefined; // vypnute horizontalne scrollovanie
493
+ var scrollHeight = undefined; // vypnute vertikalne scrollovanie
494
+ if (props.scrollable) {
495
+ if (props.scrollWidth !== "none") {
496
+ scrollWidth = props.scrollWidth;
497
+ if (scrollWidth === "viewport") {
498
+ scrollWidth = 'calc(100vw - 1.4rem)'; // 20px okraje
499
+ }
500
+ }
501
+ if (props.scrollHeight !== "none") {
502
+ scrollHeight = props.scrollHeight;
503
+ if (scrollHeight === "viewport") {
504
+ // vypocet je priblizny, robeny na mobil, desktop bude mat mozno iny
505
+ //const headerHeight = XUtils.toPX0('12.7rem');
506
+ //let footerHeight = XUtils.toPX0('3.7rem') + XUtils.toPX0('3rem'); // table footer (paging) + buttons Add row, Edit, ...
507
+ // na desktope mi nechce odpocitat vysku taskbar-u od window.screen.availHeight, tak to poriesime takymto hack-om:
508
+ // if (!XUtils.isMobile()) {
509
+ // footerHeight += XUtils.toPX0('6rem'); // priblizna vyska taskbaru (ak mam 2 rady buttonov)
510
+ // }
511
+ var viewHeight = void 0;
512
+ var headerFooterHeight = void 0;
513
+ if (props.searchTableParams === undefined) {
514
+ // sme v standardnom formulari
515
+ viewHeight = '100vh';
516
+ headerFooterHeight = XUtils_1.XUtils.toPX0('20.89rem') - XUtils_1.XUtils.toPX0('4.43rem'); // experimentalne zistena vyska header/footer (body - table body) bez formFooterHeight
517
+ }
518
+ else {
519
+ // sme v dialogu
520
+ if (XUtils_1.XUtils.isMobile()) {
521
+ viewHeight = '98vh'; // .p-dialog pre mobil ma max-height: 98%
522
+ headerFooterHeight = XUtils_1.XUtils.toPX0('17.60rem'); // rucne zratane
523
+ }
524
+ else {
525
+ viewHeight = '90vh'; // .p-dialog pre desktop ma max-height: 90%
526
+ headerFooterHeight = XUtils_1.XUtils.toPX0('18.60rem'); // rucne zratane (desktop ma vecsi margin dole na dialogu)
527
+ }
528
+ }
529
+ // pridame vysku paging-u, ak treba
530
+ if (props.paginator) {
531
+ headerFooterHeight += XUtils_1.XUtils.toPX0('3.71rem');
532
+ }
533
+ // este pridame vysku linkov na zdrojaky, ak treba
534
+ if (props.formFooterHeight !== undefined) {
535
+ headerFooterHeight += XUtils_1.XUtils.toPX0(XUtils_1.XUtils.processGridBreakpoints(props.formFooterHeight));
536
+ }
537
+ scrollHeight = "calc(" + viewHeight + " - " + headerFooterHeight + "px)";
538
+ }
539
+ }
498
540
  }
499
- var style;
500
- if (props.scrollWidth !== undefined) {
501
- style = { width: props.scrollWidth };
541
+ var style = {};
542
+ if (scrollWidth !== undefined) {
543
+ style.width = scrollWidth;
502
544
  }
503
- else {
504
- style = { width: 'min-content' }; // ak nic nedame (nechame auto), tak natiahne tabulku na celu sirku stranky, co nechceme; min-content stlaci sirku stranky
545
+ if (props.shrinkWidth) {
546
+ style.maxWidth = 'min-content'; // ak nic nedame (nechame auto), tak (v pripade ak nebudeme mat horizontalny scrollbar) natiahne tabulku na celu sirku stranky, co nechceme
505
547
  }
506
548
  var tableStyle;
507
549
  if (props.width !== undefined) {
@@ -528,97 +570,103 @@ var XLazyDataTable = function (props) {
528
570
  paginatorRight = react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-pencil", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onStart(); }, tooltip: "Edit form" });
529
571
  }
530
572
  // else -> editMode is undefined - browse is not editable
531
- // poznamka - resizableColumns su zrusene lebo nefunguje dropdown vo filtri
532
- return (react_1.default.createElement("div", { className: "x-lazy-datatable" },
533
- react_1.default.createElement("div", { className: "flex justify-content-center" },
534
- react_1.default.createElement(XButton_1.XButton, { label: "Filter", onClick: onClickFilter })),
535
- react_1.default.createElement(datatable_1.DataTable, { value: value.rowList, dataKey: dataKey, paginator: true, rows: rows, totalRecords: value.totalRecords, lazy: true, first: first, onPage: onPage, loading: loading, 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" /*resizableColumns columnResizeMode="expand"*/, tableStyle: tableStyle, paginatorLeft: paginatorLeft, paginatorRight: paginatorRight, scrollable: scrollable, scrollHeight: props.scrollHeight, style: style }, react_1.default.Children.map(props.children, function (child) {
536
- // ak chceme zmenit child element, tak treba bud vytvorit novy alebo vyklonovat
537
- // priklad je na https://soshace.com/building-react-components-using-children-props-and-context-api/
538
- // (vzdy musime robit manipulacie so stlpcom, lebo potrebujeme pridat filter={true} sortable={true}
539
- var childColumn = child; // nevedel som to krajsie...
540
- var xField = XUtilsMetadata_1.XUtilsMetadata.getXFieldByPath(xEntity, childColumn.props.field);
541
- // *********** header ***********
542
- var headerLabel = childColumn.props.header !== undefined ? childColumn.props.header : childColumn.props.field;
543
- var header;
544
- if (props.editMode === true) {
545
- header = react_1.default.createElement("div", null,
546
- react_1.default.createElement("div", null,
547
- react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-plus", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onAddColumn(childColumn.props.field); }, tooltip: "Add column" }),
548
- react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-pencil", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onEditColumn(childColumn.props.field); }, tooltip: "Edit column" }),
549
- react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-trash", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onRemoveColumn(childColumn.props.field); }, tooltip: "Remove column" })),
550
- react_1.default.createElement("div", null,
551
- react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-chevron-left", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onMoveColumnLeft(childColumn.props.field); }, tooltip: "Move column left" }),
552
- react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-chevron-right", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onMoveColumnRight(childColumn.props.field); }, tooltip: "Move column right" })),
553
- react_1.default.createElement("div", null, headerLabel));
554
- }
555
- else {
556
- header = headerLabel;
557
- }
558
- // *********** filterElement ***********
559
- var filterElement;
560
- if (xField.type === "boolean") {
561
- var checkboxValue = getCheckboxFilterValue(childColumn.props.field);
562
- filterElement = react_1.default.createElement(tristatecheckbox_1.TriStateCheckbox, { value: checkboxValue, onChange: function (e) { return onCheckboxFilterChange(childColumn.props.field, e.value); } });
563
- }
564
- else if (childColumn.props.dropdownInFilter) {
565
- var dropdownValue = getDropdownFilterValue(childColumn.props.field);
566
- filterElement = react_1.default.createElement(XDropdownDTFilter_1.XDropdownDTFilter, { entity: props.entity, path: childColumn.props.field, value: dropdownValue, onValueChange: onDropdownFilterChange });
567
- }
568
- // *********** body ***********
569
- // TODO - mozno by bolo dobre vytvarat body pre kazdy field, nech je to vsetko konzistentne
570
- var body;
571
- if (xField.type === "decimal" || xField.type === "date" || xField.type === "datetime" || xField.type === "boolean") {
572
- body = function (rowData) { return bodyTemplate(childColumn.props, rowData, xField); };
573
- }
574
- // *********** width/headerStyle ***********
575
- var width;
576
- if (childColumn.props.width !== undefined && childColumn.props.width !== null) {
577
- width = childColumn.props.width;
578
- if (!isNaN(Number(width))) { // if width is number
579
- width = width + 'rem';
580
- }
581
- }
582
- else {
583
- width = XUtilsMetadata_1.XUtilsMetadata.computeColumnWidth(xField, undefined, headerLabel);
584
- }
585
- var headerStyle;
586
- if (width !== undefined) {
587
- headerStyle = { width: width };
588
- }
589
- // *********** align ***********
590
- var align = "left"; // default
591
- if (childColumn.props.align !== undefined && childColumn.props.align !== null) {
592
- align = childColumn.props.align;
593
- }
594
- else {
595
- // decimal defaultne zarovnavame doprava
596
- if (xField.type === "decimal") {
597
- align = "right";
598
- }
599
- else if (xField.type === "boolean") {
600
- align = "center";
601
- }
573
+ // export pre search button-y zatial vypneme
574
+ var exportRows = (props.searchTableParams === undefined);
575
+ // pre lepsiu citatelnost vytvarame stlpce uz tu
576
+ var columnElemList = react_1.default.Children.map(props.children, function (child) {
577
+ // ak chceme zmenit child element, tak treba bud vytvorit novy alebo vyklonovat
578
+ // priklad je na https://soshace.com/building-react-components-using-children-props-and-context-api/
579
+ // (vzdy musime robit manipulacie so stlpcom, lebo potrebujeme pridat filter={true} sortable={true}
580
+ var childColumn = child; // nevedel som to krajsie...
581
+ var xField = XUtilsMetadata_1.XUtilsMetadata.getXFieldByPath(xEntity, childColumn.props.field);
582
+ // *********** header ***********
583
+ var headerLabel = childColumn.props.header !== undefined ? childColumn.props.header : childColumn.props.field;
584
+ var header;
585
+ if (props.editMode === true) {
586
+ header = react_1.default.createElement("div", null,
587
+ react_1.default.createElement("div", null,
588
+ react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-plus", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onAddColumn(childColumn.props.field); }, tooltip: "Add column" }),
589
+ react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-pencil", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onEditColumn(childColumn.props.field); }, tooltip: "Edit column" }),
590
+ react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-trash", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onRemoveColumn(childColumn.props.field); }, tooltip: "Remove column" })),
591
+ react_1.default.createElement("div", null,
592
+ react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-chevron-left", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onMoveColumnLeft(childColumn.props.field); }, tooltip: "Move column left" }),
593
+ react_1.default.createElement(XButtonIconSmall_1.XButtonIconSmall, { icon: "pi pi-chevron-right", onClick: function () { var _a; return (_a = props.editModeHandlers) === null || _a === void 0 ? void 0 : _a.onMoveColumnRight(childColumn.props.field); }, tooltip: "Move column right" })),
594
+ react_1.default.createElement("div", null, headerLabel));
595
+ }
596
+ else {
597
+ header = headerLabel;
598
+ }
599
+ // *********** filterElement ***********
600
+ var filterElement;
601
+ if (xField.type === "boolean") {
602
+ var checkboxValue = getCheckboxFilterValue(childColumn.props.field);
603
+ filterElement = react_1.default.createElement(tristatecheckbox_1.TriStateCheckbox, { value: checkboxValue, onChange: function (e) { return onCheckboxFilterChange(childColumn.props.field, e.value); } });
604
+ }
605
+ else if (childColumn.props.dropdownInFilter) {
606
+ var dropdownValue = getDropdownFilterValue(childColumn.props.field);
607
+ filterElement = react_1.default.createElement(XDropdownDTFilter_1.XDropdownDTFilter, { entity: props.entity, path: childColumn.props.field, value: dropdownValue, onValueChange: onDropdownFilterChange });
608
+ }
609
+ // *********** body ***********
610
+ // TODO - mozno by bolo dobre vytvarat body pre kazdy field, nech je to vsetko konzistentne
611
+ var body;
612
+ if (xField.type === "decimal" || xField.type === "date" || xField.type === "datetime" || xField.type === "boolean") {
613
+ body = function (rowData) { return bodyTemplate(childColumn.props, rowData, xField); };
614
+ }
615
+ // *********** width/headerStyle ***********
616
+ var width = XUtils_1.XUtils.processPropWidth(childColumn.props.width);
617
+ if (width === undefined || width === "default") {
618
+ width = XUtilsMetadata_1.XUtilsMetadata.computeColumnWidth(xField, undefined, headerLabel);
619
+ }
620
+ var headerStyle;
621
+ if (width !== undefined) {
622
+ headerStyle = { width: width };
623
+ }
624
+ // *********** align ***********
625
+ var align = "left"; // default
626
+ if (childColumn.props.align !== undefined && childColumn.props.align !== null) {
627
+ align = childColumn.props.align;
628
+ }
629
+ else {
630
+ // decimal defaultne zarovnavame doprava
631
+ if (xField.type === "decimal") {
632
+ align = "right";
602
633
  }
603
- // *********** style ***********
604
- var style;
605
- // TODO - pouzit className a nie style
606
- if (align === "center" || align === "right") {
607
- style = { 'textAlign': align };
608
- headerStyle = __assign(__assign({}, headerStyle), style); // headerStyle overrides style in TH cell
634
+ else if (xField.type === "boolean") {
635
+ align = "center";
609
636
  }
610
- return react_1.default.createElement(column_1.Column, { field: childColumn.props.field, header: header, filter: true, sortable: true, filterElement: filterElement, body: body, headerStyle: headerStyle, style: style });
611
- })),
637
+ }
638
+ // *********** style ***********
639
+ var style;
640
+ // TODO - pouzit className a nie style
641
+ if (align === "center" || align === "right") {
642
+ style = { 'textAlign': align };
643
+ headerStyle = __assign(__assign({}, headerStyle), style); // headerStyle overrides style in TH cell
644
+ }
645
+ return react_1.default.createElement(column_1.Column, { field: childColumn.props.field, header: header, filter: true, sortable: true, filterElement: filterElement, body: body, headerStyle: headerStyle, style: style });
646
+ });
647
+ return (react_1.default.createElement("div", null,
648
+ react_1.default.createElement("div", { className: "flex justify-content-center" },
649
+ react_1.default.createElement(XButton_1.XButton, { label: "Filter", onClick: onClickFilter })),
650
+ react_1.default.createElement("div", { className: "flex justify-content-center" },
651
+ 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, 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)),
612
652
  react_1.default.createElement("div", { className: "flex justify-content-center" },
613
653
  props.onAddRow !== undefined ? react_1.default.createElement(XButton_1.XButton, { label: "Add row", onClick: onClickAddRow }) : null,
614
654
  props.onEdit !== undefined ? react_1.default.createElement(XButton_1.XButton, { label: "Edit", onClick: onClickEdit }) : null,
615
655
  props.removeRow !== undefined && props.removeRow !== false ? react_1.default.createElement(XButton_1.XButton, { label: "Remove row", onClick: onClickRemoveRow }) : null,
616
- react_1.default.createElement(XButton_1.XButton, { label: "Export rows", onClick: onClickExport }),
656
+ exportRows ? react_1.default.createElement(XButton_1.XButton, { label: "Export rows", onClick: onClickExport }) : null,
617
657
  props.appButtons,
618
- react_1.default.createElement(XExportRowsDialog_1.XExportRowsDialog, { dialogOpened: exportRowsDialogOpened, rowCount: exportRowsDialogRowCount, onHideDialog: exportRowsDialogOnHide }),
619
- props.searchTableParams !== undefined ? react_1.default.createElement(XButton_1.XButton, { label: "Choose", onClick: onClickChoose }) : null)));
658
+ props.searchTableParams !== undefined ? react_1.default.createElement(XButton_1.XButton, { label: "Choose", onClick: onClickChoose }) : null,
659
+ exportRows ? react_1.default.createElement(XExportRowsDialog_1.XExportRowsDialog, { dialogOpened: exportRowsDialogOpened, rowCount: exportRowsDialogRowCount, onHideDialog: exportRowsDialogOnHide }) : null)));
620
660
  };
621
661
  exports.XLazyDataTable = XLazyDataTable;
662
+ exports.XLazyDataTable.defaultProps = {
663
+ paginator: true,
664
+ rows: 10,
665
+ scrollable: true,
666
+ scrollWidth: 'viewport',
667
+ scrollHeight: 'viewport',
668
+ shrinkWidth: true
669
+ };
622
670
  // TODO - XLazyColumn neni idealny nazov, lepsi je XColumn (ale zatial nechame XLazyColumn)
623
671
  var XLazyColumn = function (props) {
624
672
  // nevadi ze tu nic nevraciame, field a header vieme precitat a zvysok by sme aj tak zahodili lebo vytvarame novy element
@@ -111,7 +111,7 @@ var XLoginForm = function (props) {
111
111
  }
112
112
  });
113
113
  }); };
114
- return (react_1.default.createElement("div", null,
114
+ return (react_1.default.createElement("div", { className: "flex flex-column align-items-center" },
115
115
  react_1.default.createElement("h2", null, "Please log in"),
116
116
  react_1.default.createElement("div", { className: "field grid" },
117
117
  react_1.default.createElement("label", { htmlFor: "userName", className: "col-fixed", style: { width: '10.5rem' } }, "Username"),
@@ -1,5 +1,6 @@
1
1
  import { XToken } from "./XToken";
2
2
  import { CsvDecimalFormat, CsvSeparator, ExportType } from "../serverApi/ExportImportParam";
3
+ import React from "react";
3
4
  export declare enum OperationType {
4
5
  None = 0,
5
6
  Insert = 1,
@@ -15,10 +16,17 @@ export declare class XUtils {
15
16
  static exportTypeOptions: ExportType[];
16
17
  static csvSeparatorOptions: CsvSeparator[];
17
18
  static decimalFormatOptions: CsvDecimalFormat[];
19
+ static remSize: number | null;
18
20
  static FIELD_LABEL_WIDTH: string;
19
21
  static demo(): boolean;
20
22
  static isMobile(): boolean;
21
23
  static mobileCssSuffix(): string;
24
+ static toPX(size: string | undefined): number | undefined;
25
+ static toPX0(size: string | undefined): number;
26
+ static getRemSize(): number;
27
+ static processGridBreakpoints(breakpointExp: string): string | undefined;
28
+ static processPropWidth(widthProp: string | undefined): string | undefined;
29
+ static addCssPropIfNotExists(cssProps: React.CSSProperties, newCssProps: React.CSSProperties): void;
22
30
  static registerAppBrowse(elem: any, entity: string, formId?: string): void;
23
31
  static registerAppForm(elem: any, entity: string, formId?: string): void;
24
32
  static getAppForm(entity: string, formId?: string): any;
@@ -46,6 +46,33 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
46
46
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
47
  }
48
48
  };
49
+ var __values = (this && this.__values) || function(o) {
50
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
51
+ if (m) return m.call(o);
52
+ if (o && typeof o.length === "number") return {
53
+ next: function () {
54
+ if (o && i >= o.length) o = void 0;
55
+ return { value: o && o[i++], done: !o };
56
+ }
57
+ };
58
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
59
+ };
60
+ var __read = (this && this.__read) || function (o, n) {
61
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
62
+ if (!m) return o;
63
+ var i = m.call(o), r, ar = [], e;
64
+ try {
65
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
66
+ }
67
+ catch (error) { e = { error: error }; }
68
+ finally {
69
+ try {
70
+ if (r && !r.done && (m = i["return"])) m.call(i);
71
+ }
72
+ finally { if (e) throw e.error; }
73
+ }
74
+ return ar;
75
+ };
49
76
  Object.defineProperty(exports, "__esModule", { value: true });
50
77
  exports.XUtils = exports.OperationType = void 0;
51
78
  var XUtilsMetadata_1 = require("./XUtilsMetadata");
@@ -68,12 +95,146 @@ var XUtils = /** @class */ (function () {
68
95
  XUtils.isMobile = function () {
69
96
  // extra small displays (podla https://www.w3schools.com/howto/howto_css_media_query_breakpoints.asp)
70
97
  // mozno tu treba dat (window.screen.width * window.devicePixelRatio)
71
- // bolo 600 ($sm = 576 (primeflex)) - len ak bol mobil na vysku, 786 ma byt aj pre mobil na sirku
72
- return typeof window !== 'undefined' && window.screen.availWidth <= 786; // $sm = 576 (primeflex)
98
+ // bolo 600 ($sm = 576 (primeflex)) - len ak bol mobil na vysku, 768 ma byt aj pre mobil na sirku
99
+ return typeof window !== 'undefined' && window.screen.availWidth < 768; // $sm = 576 (primeflex)
73
100
  };
74
101
  XUtils.mobileCssSuffix = function () {
75
102
  return XUtils.isMobile() ? '-mobile' : '';
76
103
  };
104
+ XUtils.toPX = function (size) {
105
+ var sizeInPx;
106
+ if (size !== undefined) {
107
+ if (size.endsWith('px')) {
108
+ sizeInPx = parseFloat(size);
109
+ }
110
+ else if (size.endsWith('rem')) {
111
+ sizeInPx = parseFloat(size) * XUtils.getRemSize();
112
+ }
113
+ if (Number.isNaN(sizeInPx)) {
114
+ sizeInPx = undefined;
115
+ }
116
+ }
117
+ return sizeInPx;
118
+ };
119
+ XUtils.toPX0 = function (size) {
120
+ var _a;
121
+ return (_a = XUtils.toPX(size)) !== null && _a !== void 0 ? _a : 0;
122
+ };
123
+ XUtils.getRemSize = function () {
124
+ if (XUtils.remSize === null) {
125
+ // font-size of root element (HTML element), e.g. "14px"
126
+ XUtils.remSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);
127
+ }
128
+ return XUtils.remSize;
129
+ };
130
+ // param example: "3rem md:4rem xl:6rem"
131
+ // (in general: "<exp1> sm:<exp2> md:<exp3> lg:<exp4> xl:<exp5>")
132
+ // according to device width returns "exp(n)"
133
+ XUtils.processGridBreakpoints = function (breakpointExp) {
134
+ var e_1, _a, e_2, _b, e_3, _c;
135
+ var breakpointList = breakpointExp.split(' ');
136
+ try {
137
+ // pridame si prefix xs: ak neni ziaden prefix, aby sa s tym lahsie pracovalo
138
+ for (var _d = __values(breakpointList.entries()), _e = _d.next(); !_e.done; _e = _d.next()) {
139
+ var _f = __read(_e.value, 2), index = _f[0], breakpoint = _f[1];
140
+ if (breakpoint !== '' && breakpoint.indexOf(':') === -1) {
141
+ breakpointList[index] = 'xs:' + breakpoint;
142
+ }
143
+ }
144
+ }
145
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
146
+ finally {
147
+ try {
148
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
149
+ }
150
+ finally { if (e_1) throw e_1.error; }
151
+ }
152
+ // TODO - use variables $sm, $md, ...
153
+ var breakpointsToFind;
154
+ var availWidth;
155
+ if (typeof window !== 'undefined') {
156
+ availWidth = window.screen.availWidth; // pouzivame availWidth, nie width, availWidth odratava napr. taskbar
157
+ if (availWidth < 576) {
158
+ breakpointsToFind = ['xs:'];
159
+ }
160
+ else if (availWidth < 768) {
161
+ breakpointsToFind = ['sm:', 'xs:'];
162
+ }
163
+ else if (availWidth < 992) {
164
+ breakpointsToFind = ['md:', 'sm:', 'xs:'];
165
+ }
166
+ else if (availWidth < 1200) {
167
+ breakpointsToFind = ['lg:', 'md:', 'sm:', 'xs:'];
168
+ }
169
+ else {
170
+ breakpointsToFind = ['xl:', 'lg:', 'md:', 'sm:', 'xs:'];
171
+ }
172
+ }
173
+ else {
174
+ // desktop screen?
175
+ breakpointsToFind = ['xl:', 'lg:', 'md:', 'sm:', 'xs:'];
176
+ }
177
+ try {
178
+ for (var breakpointsToFind_1 = __values(breakpointsToFind), breakpointsToFind_1_1 = breakpointsToFind_1.next(); !breakpointsToFind_1_1.done; breakpointsToFind_1_1 = breakpointsToFind_1.next()) {
179
+ var breakpointToFind = breakpointsToFind_1_1.value;
180
+ try {
181
+ for (var breakpointList_1 = (e_3 = void 0, __values(breakpointList)), breakpointList_1_1 = breakpointList_1.next(); !breakpointList_1_1.done; breakpointList_1_1 = breakpointList_1.next()) {
182
+ var breakpoint = breakpointList_1_1.value;
183
+ if (breakpoint.startsWith(breakpointToFind)) {
184
+ return breakpoint.substring(breakpointToFind.length);
185
+ }
186
+ }
187
+ }
188
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
189
+ finally {
190
+ try {
191
+ if (breakpointList_1_1 && !breakpointList_1_1.done && (_c = breakpointList_1.return)) _c.call(breakpointList_1);
192
+ }
193
+ finally { if (e_3) throw e_3.error; }
194
+ }
195
+ }
196
+ }
197
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
198
+ finally {
199
+ try {
200
+ if (breakpointsToFind_1_1 && !breakpointsToFind_1_1.done && (_b = breakpointsToFind_1.return)) _b.call(breakpointsToFind_1);
201
+ }
202
+ finally { if (e_2) throw e_2.error; }
203
+ }
204
+ // should not happen
205
+ console.log("XUtils.processGridBreakpoints: unexpected error: no breakpoint value found, breakpointExp = " + breakpointExp + ", availWidth = " + availWidth);
206
+ return undefined;
207
+ };
208
+ XUtils.processPropWidth = function (widthProp) {
209
+ var width;
210
+ if (widthProp !== undefined && widthProp !== null) {
211
+ width = XUtils.processGridBreakpoints(widthProp);
212
+ if (width !== undefined) {
213
+ if (!isNaN(Number(width))) { // if width is number
214
+ width = width + 'rem';
215
+ }
216
+ }
217
+ }
218
+ return width;
219
+ };
220
+ XUtils.addCssPropIfNotExists = function (cssProps, newCssProps) {
221
+ var e_4, _a;
222
+ try {
223
+ for (var _b = __values(Object.entries(newCssProps)), _c = _b.next(); !_c.done; _c = _b.next()) {
224
+ var _d = __read(_c.value, 2), cssProp = _d[0], cssPropValue = _d[1];
225
+ if (!(cssProp in cssProps)) {
226
+ cssProps[cssProp] = cssPropValue;
227
+ }
228
+ }
229
+ }
230
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
231
+ finally {
232
+ try {
233
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
234
+ }
235
+ finally { if (e_4) throw e_4.error; }
236
+ }
237
+ };
77
238
  // zatial nepouzivane - v buducnosti sa takto mozu vytvorit registre browsov a formularov, ktore potom budeme vediet otvorit len na zaklade entity
78
239
  XUtils.registerAppBrowse = function (elem, entity, formId) {
79
240
  // console.log("***************** sme v register");
@@ -283,6 +444,7 @@ var XUtils = /** @class */ (function () {
283
444
  XUtils.exportTypeOptions = [ExportImportParam_1.ExportType.Csv, ExportImportParam_1.ExportType.Json];
284
445
  XUtils.csvSeparatorOptions = [ExportImportParam_1.CsvSeparator.Semicolon, ExportImportParam_1.CsvSeparator.Comma];
285
446
  XUtils.decimalFormatOptions = [ExportImportParam_1.CsvDecimalFormat.Comma, ExportImportParam_1.CsvDecimalFormat.Dot];
447
+ XUtils.remSize = null;
286
448
  // konstanty (zatial takto jednoducho)
287
449
  XUtils.FIELD_LABEL_WIDTH = '10.5rem';
288
450
  return XUtils;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michalrakus/x-react-web-lib",
3
- "version": "0.21.0",
3
+ "version": "0.25.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "clean": "rimraf lib",