@michalrakus/x-react-web-lib 1.18.0 → 1.19.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.
@@ -2,37 +2,37 @@ import React from "react";
2
2
  import { XFilterProp, XFormComponent, XFormComponentProps } from "./XFormComponent";
3
3
  import { XAssoc } from "../serverApi/XEntityMetadata";
4
4
  import { OperationType } from "./XUtils";
5
+ import { XSuggestionsLoadProp } from "./XAutoCompleteBase";
5
6
  import { XError } from "./XErrors";
6
7
  import { XObject } from "./XObject";
7
8
  import { DataTableSortMeta } from "primereact/datatable";
8
9
  export interface XAutoCompleteProps extends XFormComponentProps<XObject> {
9
10
  assocField: string;
10
- displayField: string;
11
+ displayField: string | string[];
11
12
  searchBrowse?: JSX.Element;
12
13
  assocForm?: JSX.Element;
14
+ suggestions?: any[];
15
+ suggestionsLoad?: XSuggestionsLoadProp;
16
+ lazyLoadMaxRows?: number;
17
+ splitQueryValue?: boolean;
18
+ minLength?: number;
13
19
  filter?: XFilterProp;
14
20
  sortField?: string | DataTableSortMeta[];
15
21
  fields?: string[];
16
- suggestions?: any[];
17
- lazy?: boolean;
18
22
  width?: string;
23
+ scrollHeight?: string;
19
24
  inputStyle?: React.CSSProperties;
20
25
  }
21
26
  export declare class XAutoComplete extends XFormComponent<XObject, XAutoCompleteProps> {
22
27
  protected xAssoc: XAssoc;
23
28
  protected errorInBase: string | undefined;
24
- state: {
25
- suggestions: any[];
26
- };
27
29
  constructor(props: XAutoCompleteProps);
28
- componentDidMount(): void;
29
- readAndSetSuggestions(setStateCallback?: () => void): Promise<void>;
30
30
  getField(): string;
31
31
  isNotNull(): boolean;
32
+ getFirstDisplayField(): string;
32
33
  getValue(): any | null;
33
34
  onChangeAutoCompleteBase(object: any, objectChange: OperationType): void;
34
35
  onErrorChangeAutoCompleteBase(error: string | undefined): void;
35
- onSearchStart(finishSearchStart?: () => void): void;
36
36
  validate(): {
37
37
  field: string;
38
38
  xError: XError;
@@ -14,42 +14,6 @@ var __extends = (this && this.__extends) || (function () {
14
14
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
15
  };
16
16
  })();
17
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
- return new (P || (P = Promise))(function (resolve, reject) {
20
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
- step((generator = generator.apply(thisArg, _arguments || [])).next());
24
- });
25
- };
26
- var __generator = (this && this.__generator) || function (thisArg, body) {
27
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
28
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
29
- function verb(n) { return function (v) { return step([n, v]); }; }
30
- function step(op) {
31
- if (f) throw new TypeError("Generator is already executing.");
32
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
33
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
34
- if (y = 0, t) op = [op[0] & 2, t.value];
35
- switch (op[0]) {
36
- case 0: case 1: t = op; break;
37
- case 4: _.label++; return { value: op[1], done: false };
38
- case 5: _.label++; y = op[1]; op = [0]; continue;
39
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
40
- default:
41
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
42
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
43
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
44
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
45
- if (t[2]) _.ops.pop();
46
- _.trys.pop(); continue;
47
- }
48
- op = body.call(thisArg, _);
49
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
50
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
- }
52
- };
53
17
  var __importDefault = (this && this.__importDefault) || function (mod) {
54
18
  return (mod && mod.__esModule) ? mod : { "default": mod };
55
19
  };
@@ -57,7 +21,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
57
21
  exports.XAutoComplete = void 0;
58
22
  var react_1 = __importDefault(require("react"));
59
23
  var XFormComponent_1 = require("./XFormComponent");
60
- var XUtils_1 = require("./XUtils");
61
24
  var XAutoCompleteBase_1 = require("./XAutoCompleteBase");
62
25
  var XUtilsMetadataCommon_1 = require("../serverApi/XUtilsMetadataCommon");
63
26
  var XAutoComplete = /** @class */ (function (_super) {
@@ -66,65 +29,32 @@ var XAutoComplete = /** @class */ (function (_super) {
66
29
  var _this = _super.call(this, props) || this;
67
30
  _this.xAssoc = XUtilsMetadataCommon_1.XUtilsMetadataCommon.getXAssocToOne(XUtilsMetadataCommon_1.XUtilsMetadataCommon.getXEntity(props.form.getEntity()), props.assocField);
68
31
  _this.errorInBase = undefined;
69
- _this.state = {
70
- suggestions: []
71
- };
72
32
  _this.onChangeAutoCompleteBase = _this.onChangeAutoCompleteBase.bind(_this);
73
33
  _this.onErrorChangeAutoCompleteBase = _this.onErrorChangeAutoCompleteBase.bind(_this);
74
- _this.onSearchStart = _this.onSearchStart.bind(_this);
75
- props.form.addField(props.assocField + '.' + props.displayField);
34
+ props.form.addField(props.assocField + '.' + _this.getFirstDisplayField());
76
35
  return _this;
77
36
  }
78
- XAutoComplete.prototype.componentDidMount = function () {
79
- //console.log("volany XAutoComplete.componentDidMount()");
80
- if (!this.props.lazy) {
81
- this.readAndSetSuggestions();
82
- }
83
- };
84
- XAutoComplete.prototype.readAndSetSuggestions = function (setStateCallback) {
85
- var _a;
86
- return __awaiter(this, void 0, void 0, function () {
87
- var suggestions;
88
- return __generator(this, function (_b) {
89
- switch (_b.label) {
90
- case 0:
91
- if (!(this.props.suggestions === undefined)) return [3 /*break*/, 2];
92
- return [4 /*yield*/, XUtils_1.XUtils.fetchRows(this.xAssoc.entityName, this.getFilterBase(this.props.filter), (_a = this.props.sortField) !== null && _a !== void 0 ? _a : this.props.displayField, this.props.fields)];
93
- case 1:
94
- suggestions = _b.sent();
95
- this.setState({ suggestions: suggestions }, setStateCallback);
96
- _b.label = 2;
97
- case 2: return [2 /*return*/];
98
- }
99
- });
100
- });
101
- };
37
+ // componentDidMount() {
38
+ // }
102
39
  XAutoComplete.prototype.getField = function () {
103
40
  return this.props.assocField;
104
41
  };
105
42
  XAutoComplete.prototype.isNotNull = function () {
106
43
  return !this.xAssoc.isNullable;
107
44
  };
45
+ XAutoComplete.prototype.getFirstDisplayField = function () {
46
+ return Array.isArray(this.props.displayField) ? this.props.displayField[0] : this.props.displayField;
47
+ };
108
48
  XAutoComplete.prototype.getValue = function () {
109
49
  var assocObject = this.getValueFromObject();
110
50
  return assocObject;
111
51
  };
112
52
  XAutoComplete.prototype.onChangeAutoCompleteBase = function (object, objectChange) {
113
53
  this.onValueChangeBase(object, this.props.onChange, objectChange);
114
- if (objectChange !== XUtils_1.OperationType.None) {
115
- // zmenil sa zaznam dobrovolnika v DB
116
- // zatial len refreshneme z DB
117
- // ak by bol reqest pomaly, mozme pri inserte (nove id) / update (existujuce id) upravit zoznam a usetrime tym request do DB
118
- // ak bol delete (dobrovolnik === null), treba urobit refresh do DB (alebo si poslat id-cko zmazaneho zaznamu)
119
- this.readAndSetSuggestions();
120
- }
121
54
  };
122
55
  XAutoComplete.prototype.onErrorChangeAutoCompleteBase = function (error) {
123
56
  this.errorInBase = error; // odlozime si error
124
57
  };
125
- XAutoComplete.prototype.onSearchStart = function (finishSearchStart) {
126
- this.readAndSetSuggestions(finishSearchStart);
127
- };
128
58
  // overrides method in XFormComponent
129
59
  XAutoComplete.prototype.validate = function () {
130
60
  if (this.errorInBase) {
@@ -136,12 +66,11 @@ var XAutoComplete = /** @class */ (function (_super) {
136
66
  };
137
67
  XAutoComplete.prototype.render = function () {
138
68
  var _this = this;
139
- var _a;
140
69
  var xEntityAssoc = XUtilsMetadataCommon_1.XUtilsMetadataCommon.getXEntity(this.xAssoc.entityName);
141
70
  // div className="col" nam zabezpeci aby XAutoCompleteBase nezaberal celu dlzku grid-u (ma nastaveny width=100% vdaka "formgroup-inline")
142
71
  return (react_1.default.createElement("div", { className: "field grid" },
143
72
  react_1.default.createElement("label", { htmlFor: this.props.assocField, className: "col-fixed", style: this.getLabelStyle() }, this.getLabel()),
144
- react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: this.getValue(), suggestions: (_a = this.props.suggestions) !== null && _a !== void 0 ? _a : this.state.suggestions, onChange: this.onChangeAutoCompleteBase, field: this.props.displayField, searchBrowse: this.props.searchBrowse, valueForm: this.props.assocForm, idField: xEntityAssoc.idField, readOnly: this.isReadOnly(), error: this.getError(), onErrorChange: this.onErrorChangeAutoCompleteBase, width: this.props.width, customFilterFunction: function () { return _this.getFilterBase(_this.props.filter); }, onSearchStart: this.props.lazy ? this.onSearchStart : undefined })));
73
+ react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: this.getValue(), onChange: this.onChangeAutoCompleteBase, field: this.props.displayField, 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 } })));
145
74
  };
146
75
  return XAutoComplete;
147
76
  }(XFormComponent_1.XFormComponent));
@@ -4,41 +4,69 @@ import { OperationType } from "./XUtils";
4
4
  import { MenuItem } from "primereact/menuitem";
5
5
  import { XSearchBrowseParams } from "./XSearchBrowseParams";
6
6
  import { XCustomFilter } from "../serverApi/FindParam";
7
+ import { DataTableSortMeta } from "primereact/datatable";
8
+ export type XSuggestionsLoadProp = "eager" | "onSearchStart" | "lazy";
9
+ export type XSuggestionsLoadType = "suggestions" | XSuggestionsLoadProp;
10
+ export type XFilterOrFunction = XCustomFilter | (() => XCustomFilter | undefined);
11
+ export interface XQuery {
12
+ entity: string;
13
+ filter?: XFilterOrFunction;
14
+ sortField?: string | DataTableSortMeta[];
15
+ fields?: string[];
16
+ }
7
17
  export interface XAutoCompleteBaseProps {
8
18
  value: any;
9
- suggestions: any[];
10
19
  onChange: (object: any, objectChange: OperationType) => void;
11
- field: string;
20
+ suggestions?: any[];
21
+ suggestionsLoad?: XSuggestionsLoadProp;
22
+ suggestionsQuery?: XQuery;
23
+ lazyLoadMaxRows: number;
24
+ field: string | string[];
25
+ splitQueryValue: boolean;
12
26
  searchBrowse?: JSX.Element;
13
27
  valueForm?: JSX.Element;
14
28
  idField?: string;
15
- maxLength?: number;
29
+ minLength?: number;
16
30
  width?: string;
31
+ scrollHeight?: string;
17
32
  readOnly?: boolean;
18
33
  error?: string;
19
34
  onErrorChange: (error: string | undefined) => void;
20
35
  setFocusOnCreate?: boolean;
21
- customFilterFunction?: () => XCustomFilter | undefined;
22
- onSearchStart?: (finishSearchStart?: () => void) => void;
23
36
  }
24
37
  export declare class XAutoCompleteBase extends Component<XAutoCompleteBaseProps> {
38
+ private static valueMoreSuggestions;
39
+ static defaultProps: {
40
+ lazyLoadMaxRows: number;
41
+ splitQueryValue: boolean;
42
+ minLength: number;
43
+ scrollHeight: string;
44
+ };
25
45
  autoCompleteRef: any;
26
46
  state: {
27
47
  inputChanged: boolean;
28
48
  inputValueState: string | undefined;
29
49
  notValid: boolean;
50
+ suggestions: any[] | undefined;
30
51
  filteredSuggestions: any[] | undefined;
31
52
  formDialogOpened: boolean;
32
53
  searchDialogOpened: boolean;
33
54
  };
34
- wasSearchStartCalled: boolean;
55
+ suggestionsLoadedForOSS: boolean;
56
+ wasOnChangeCalled: boolean;
35
57
  formDialogObjectId: number | undefined;
36
58
  formDialogInitValuesForInsert: any | undefined;
37
59
  constructor(props: XAutoCompleteBaseProps);
60
+ getXSuggestionsLoadType(): XSuggestionsLoadType;
61
+ getFields(): string[];
62
+ getFirstField(): string;
38
63
  componentDidMount(): void;
64
+ loadSuggestions(): Promise<void>;
65
+ fetchSuggestions(): Promise<any[]>;
66
+ getSortField(): string | DataTableSortMeta[] | undefined;
39
67
  completeMethod(event: {
40
68
  query: string;
41
- }): void;
69
+ }): Promise<void>;
42
70
  onChange(e: AutoCompleteChangeEvent): void;
43
71
  onSelect(e: any): void;
44
72
  onBlur(e: React.FocusEvent<HTMLInputElement>): void;
@@ -56,6 +84,9 @@ export declare class XAutoCompleteBase extends Component<XAutoCompleteBaseProps>
56
84
  openDropdown(e: any): void;
57
85
  onEditAssocValue(): void;
58
86
  computeInputValue(): any;
87
+ itemTemplate(suggestion: any, index: number): React.ReactNode;
88
+ computeDisplayValue(suggestion: any): string;
89
+ static isMoreSuggestions(suggestion: any): boolean;
59
90
  createSearchBrowseParams(): XSearchBrowseParams;
60
91
  render(): JSX.Element;
61
92
  }
@@ -48,6 +48,42 @@ var __importStar = (this && this.__importStar) || function (mod) {
48
48
  __setModuleDefault(result, mod);
49
49
  return result;
50
50
  };
51
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
52
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
53
+ return new (P || (P = Promise))(function (resolve, reject) {
54
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
55
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
56
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
57
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
58
+ });
59
+ };
60
+ var __generator = (this && this.__generator) || function (thisArg, body) {
61
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
62
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
63
+ function verb(n) { return function (v) { return step([n, v]); }; }
64
+ function step(op) {
65
+ if (f) throw new TypeError("Generator is already executing.");
66
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
67
+ 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;
68
+ if (y = 0, t) op = [op[0] & 2, t.value];
69
+ switch (op[0]) {
70
+ case 0: case 1: t = op; break;
71
+ case 4: _.label++; return { value: op[1], done: false };
72
+ case 5: _.label++; y = op[1]; op = [0]; continue;
73
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
74
+ default:
75
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
76
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
77
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
78
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
79
+ if (t[2]) _.ops.pop();
80
+ _.trys.pop(); continue;
81
+ }
82
+ op = body.call(thisArg, _);
83
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
84
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
85
+ }
86
+ };
51
87
  var __read = (this && this.__read) || function (o, n) {
52
88
  var m = typeof Symbol === "function" && o[Symbol.iterator];
53
89
  if (!m) return o;
@@ -73,6 +109,17 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
73
109
  }
74
110
  return to.concat(ar || Array.prototype.slice.call(from));
75
111
  };
112
+ var __values = (this && this.__values) || function(o) {
113
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
114
+ if (m) return m.call(o);
115
+ if (o && typeof o.length === "number") return {
116
+ next: function () {
117
+ if (o && i >= o.length) o = void 0;
118
+ return { value: o && o[i++], done: !o };
119
+ }
120
+ };
121
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
122
+ };
76
123
  Object.defineProperty(exports, "__esModule", { value: true });
77
124
  exports.XAutoCompleteBase = void 0;
78
125
  var react_1 = __importStar(require("react"));
@@ -81,6 +128,7 @@ var splitbutton_1 = require("primereact/splitbutton");
81
128
  var dialog_1 = require("primereact/dialog");
82
129
  var XUtils_1 = require("./XUtils");
83
130
  var button_1 = require("primereact/button");
131
+ var XUtilsCommon_1 = require("../serverApi/XUtilsCommon");
84
132
  var XAutoCompleteBase = /** @class */ (function (_super) {
85
133
  __extends(XAutoCompleteBase, _super);
86
134
  function XAutoCompleteBase(props) {
@@ -90,63 +138,226 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
90
138
  inputChanged: false,
91
139
  inputValueState: undefined,
92
140
  notValid: false,
141
+ suggestions: undefined,
93
142
  filteredSuggestions: undefined,
94
143
  formDialogOpened: false,
95
144
  searchDialogOpened: false
96
145
  };
97
- _this.wasSearchStartCalled = false;
146
+ _this.suggestionsLoadedForOSS = false;
147
+ _this.wasOnChangeCalled = false;
98
148
  _this.completeMethod = _this.completeMethod.bind(_this);
99
149
  _this.onChange = _this.onChange.bind(_this);
100
150
  _this.onSelect = _this.onSelect.bind(_this);
101
151
  _this.onBlur = _this.onBlur.bind(_this);
152
+ _this.itemTemplate = _this.itemTemplate.bind(_this);
153
+ _this.computeDisplayValue = _this.computeDisplayValue.bind(_this);
102
154
  _this.formDialogOnSaveOrCancel = _this.formDialogOnSaveOrCancel.bind(_this);
103
155
  _this.formDialogOnHide = _this.formDialogOnHide.bind(_this);
104
156
  _this.searchDialogOnChoose = _this.searchDialogOnChoose.bind(_this);
105
157
  _this.searchDialogOnHide = _this.searchDialogOnHide.bind(_this);
106
158
  return _this;
107
159
  }
160
+ XAutoCompleteBase.prototype.getXSuggestionsLoadType = function () {
161
+ var suggestionsLoadType;
162
+ if (this.props.suggestions) {
163
+ suggestionsLoadType = "suggestions";
164
+ }
165
+ else if (!this.props.suggestionsLoad) {
166
+ suggestionsLoadType = "onSearchStart"; // default
167
+ }
168
+ else {
169
+ suggestionsLoadType = this.props.suggestionsLoad;
170
+ }
171
+ return suggestionsLoadType;
172
+ };
173
+ // helper
174
+ XAutoCompleteBase.prototype.getFields = function () {
175
+ return Array.isArray(this.props.field) ? this.props.field : [this.props.field];
176
+ };
177
+ XAutoCompleteBase.prototype.getFirstField = function () {
178
+ return this.getFields()[0];
179
+ };
108
180
  XAutoCompleteBase.prototype.componentDidMount = function () {
181
+ if (this.getXSuggestionsLoadType() === "eager") {
182
+ this.loadSuggestions();
183
+ }
109
184
  if (this.props.setFocusOnCreate) {
110
185
  this.setFocusToInput();
111
186
  }
112
187
  };
113
- XAutoCompleteBase.prototype.completeMethod = function (event) {
114
- var _this = this;
115
- var filteredSuggestions;
116
- if (!event.query.trim().length) {
117
- filteredSuggestions = __spreadArray([], __read(this.props.suggestions), false);
118
- }
119
- else {
120
- var queryNormalized_1 = XUtils_1.XUtils.normalizeString(event.query);
121
- filteredSuggestions = this.props.suggestions.filter(function (suggestion) {
122
- var fieldValue = suggestion[_this.props.field];
123
- // specialna null polozka (prazdny objekt) - test dame az za test fieldValue na undefined - koli performance
124
- if (fieldValue === undefined && Object.keys(suggestion).length === 0) {
125
- return false;
188
+ XAutoCompleteBase.prototype.loadSuggestions = function () {
189
+ return __awaiter(this, void 0, void 0, function () {
190
+ var suggestions;
191
+ return __generator(this, function (_a) {
192
+ switch (_a.label) {
193
+ case 0: return [4 /*yield*/, this.fetchSuggestions()];
194
+ case 1:
195
+ suggestions = _a.sent();
196
+ this.setState({ suggestions: suggestions });
197
+ return [2 /*return*/];
126
198
  }
127
- // bolo:
128
- //return XUtils.normalizeString(fieldValue).startsWith(queryNormalized);
129
- return XUtils_1.XUtils.normalizeString(fieldValue).indexOf(queryNormalized_1) !== -1;
130
199
  });
131
- }
132
- this.setState({ filteredSuggestions: filteredSuggestions });
200
+ });
133
201
  };
134
- XAutoCompleteBase.prototype.onChange = function (e) {
135
- if (typeof e.value === 'string') {
136
- // ak user zacne typovat znaky, nacitame suggestions, ak sme lazy (onSearchStart !== undefined)
137
- if (this.props.onSearchStart) {
138
- if (e.value !== '') { // ak user vymaze cely input, este nechceme nacitat suggestions, az ked zapise nejaky znak
139
- if (!this.wasSearchStartCalled) {
140
- this.props.onSearchStart();
141
- this.wasSearchStartCalled = true; // ak user dalej typuje, nechceme znova nacitavat suggestions
142
- }
202
+ XAutoCompleteBase.prototype.fetchSuggestions = function () {
203
+ return __awaiter(this, void 0, void 0, function () {
204
+ return __generator(this, function (_a) {
205
+ if (!this.props.suggestionsQuery) {
206
+ throw "XAutoCompleteBase.loadSuggestions: unexpected error - prop suggestionsQuery is undefined";
143
207
  }
208
+ return [2 /*return*/, XUtils_1.XUtils.fetchRows(this.props.suggestionsQuery.entity, XUtils_1.XUtils.evalFilter(this.props.suggestionsQuery.filter), this.getSortField(), this.props.suggestionsQuery.fields)];
209
+ });
210
+ });
211
+ };
212
+ XAutoCompleteBase.prototype.getSortField = function () {
213
+ var sortField = this.props.suggestionsQuery.sortField;
214
+ if (!sortField) {
215
+ // len pri ne-lazy pouzivame ako default sort prvy displayField
216
+ // pri lazy to spomaluje selecty v pripade ze klauzula LIMIT vyrazne obmedzi vysledny zoznam suggestions
217
+ // pri lazy zosortujeme na frontende v XAutoCompleteBase
218
+ if (this.getXSuggestionsLoadType() !== "lazy") {
219
+ sortField = this.getFirstField();
144
220
  }
221
+ }
222
+ return sortField;
223
+ };
224
+ XAutoCompleteBase.prototype.completeMethod = function (event) {
225
+ return __awaiter(this, void 0, void 0, function () {
226
+ var filteredSuggestions, xSuggestionsLoadType, suggestions, queryNormalized, queryNormalizedList_1, filter, suggestionsRequest, findResult;
227
+ var _this = this;
228
+ return __generator(this, function (_a) {
229
+ switch (_a.label) {
230
+ case 0:
231
+ xSuggestionsLoadType = this.getXSuggestionsLoadType();
232
+ if (!(xSuggestionsLoadType !== "lazy")) return [3 /*break*/, 8];
233
+ suggestions = void 0;
234
+ if (!(xSuggestionsLoadType === "suggestions")) return [3 /*break*/, 1];
235
+ suggestions = this.props.suggestions;
236
+ return [3 /*break*/, 7];
237
+ case 1:
238
+ if (!(xSuggestionsLoadType === "eager")) return [3 /*break*/, 2];
239
+ suggestions = this.state.suggestions;
240
+ return [3 /*break*/, 7];
241
+ case 2:
242
+ if (!(xSuggestionsLoadType === "onSearchStart")) return [3 /*break*/, 6];
243
+ if (!!this.suggestionsLoadedForOSS) return [3 /*break*/, 4];
244
+ return [4 /*yield*/, this.fetchSuggestions()];
245
+ case 3:
246
+ suggestions = _a.sent();
247
+ // ulozime si
248
+ this.setState({ suggestions: suggestions });
249
+ this.suggestionsLoadedForOSS = true; // ak user dalej typuje, nechceme znova nacitavat suggestions
250
+ return [3 /*break*/, 5];
251
+ case 4:
252
+ // uz mame nacitane
253
+ suggestions = this.state.suggestions;
254
+ _a.label = 5;
255
+ case 5: return [3 /*break*/, 7];
256
+ case 6: throw 'Unexpected error - unknown xSuggestionsLoadType';
257
+ case 7:
258
+ if (!event.query.trim().length) {
259
+ // input je prazdny - volanie sem nastane ak user otvori dropdown cez dropdown button
260
+ filteredSuggestions = __spreadArray([], __read(suggestions), false);
261
+ }
262
+ else {
263
+ queryNormalized = XUtils_1.XUtils.normalizeString(event.query);
264
+ if (this.props.splitQueryValue) {
265
+ queryNormalizedList_1 = queryNormalized.split(' ').filter(function (value) { return value !== ''; }); // nechceme pripadne prazdne retazce ''
266
+ }
267
+ else {
268
+ queryNormalizedList_1 = [queryNormalized]; // nesplitujeme
269
+ }
270
+ filteredSuggestions = suggestions.filter(function (suggestion) {
271
+ var e_1, _a;
272
+ var fieldValue = _this.computeDisplayValue(suggestion);
273
+ // specialna null polozka (prazdny objekt) - test dame az za test fieldValue na undefined - koli performance
274
+ if (fieldValue === undefined && Object.keys(suggestion).length === 0) {
275
+ return false;
276
+ }
277
+ var fieldValueNormalized = XUtils_1.XUtils.normalizeString(fieldValue);
278
+ // all partial query values must match
279
+ var match = true;
280
+ try {
281
+ for (var queryNormalizedList_2 = __values(queryNormalizedList_1), queryNormalizedList_2_1 = queryNormalizedList_2.next(); !queryNormalizedList_2_1.done; queryNormalizedList_2_1 = queryNormalizedList_2.next()) {
282
+ var queryItemNormalized = queryNormalizedList_2_1.value;
283
+ // look for substring
284
+ if (fieldValueNormalized.indexOf(queryItemNormalized) === -1) {
285
+ match = false;
286
+ break;
287
+ }
288
+ }
289
+ }
290
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
291
+ finally {
292
+ try {
293
+ if (queryNormalizedList_2_1 && !queryNormalizedList_2_1.done && (_a = queryNormalizedList_2.return)) _a.call(queryNormalizedList_2);
294
+ }
295
+ finally { if (e_1) throw e_1.error; }
296
+ }
297
+ return match;
298
+ });
299
+ }
300
+ return [3 /*break*/, 10];
301
+ case 8:
302
+ // ************* lazy ***************
303
+ // na backendev SELECT-e pouzijeme klauzulu LIMIT <maxRows + 1>
304
+ // ak najdeme menej ako <maxRows + 1> zaznamov tak vieme ze sme nasli vsetky
305
+ // ak najdeme presne <maxRows + 1> zaznamov, tak na konci zobrazime uzivatelovi specialnu polozku "..."
306
+ // ktora ho upozorni ze existuju aj dalsie zaznamy splnujuce podmienku
307
+ // pikoska - ak je query je velmi siroke (select by bez LIMIT <maxRows + 1> vratil mnoho zaznamov),
308
+ // tak je takyto select velmi lacny (niekolko ms) - staci totiz najst prvych napr. 20 zaznamov splnujucich podmienku, t.j. netreba robit full-table scan
309
+ // to ale plati len v pripade ze nepouzijeme ORDER BY - pri pouziti ORDER BY urobi full-table scan (vyfiltruje) a nasledne zosortuje
310
+ // toto sa da obist specialnym selectom:
311
+ // select t.* from (select t0.* from table t0 order by t0.<attr1>) t where <full-text-condition> limit 20
312
+ // (najprv zosortuje a az potom filtruje prvych 20 zaznamov - predpoklad je ze nad t0.<attr1> mame index aby rychlo sortoval)
313
+ // tento specialny select mozme v buducnosti dorobit (na backende) ak chceme podporovat (rychle) sortovanie v DB pre autocomplete
314
+ if (!this.props.suggestionsQuery) {
315
+ throw "XAutoCompleteBase.loadSuggestions: unexpected error - prop suggestionsQuery is undefined";
316
+ }
317
+ filter = XUtils_1.XUtils.evalFilter(this.props.suggestionsQuery.filter);
318
+ suggestionsRequest = {
319
+ maxRows: this.props.lazyLoadMaxRows + 1,
320
+ fullTextSearch: { fields: this.getFields(), value: event.query.trim(), splitValue: this.props.splitQueryValue, matchMode: "contains" },
321
+ entity: this.props.suggestionsQuery.entity,
322
+ filterItems: XUtils_1.XUtils.createCustomFilterItems(filter),
323
+ multiSortMeta: XUtils_1.XUtils.createMultiSortMeta(this.getSortField()),
324
+ fields: this.props.suggestionsQuery.fields
325
+ };
326
+ return [4 /*yield*/, XUtils_1.XUtils.fetchOne('x-lazy-auto-complete-suggestions', suggestionsRequest)];
327
+ case 9:
328
+ findResult = _a.sent();
329
+ filteredSuggestions = findResult.rowList;
330
+ // ak sme nesortovali v DB (co je draha operacia) tak zosortujeme teraz
331
+ // (computeDisplayValue sa vola duplicitne ale pre tych cca 20 zaznamov je to ok)
332
+ if (this.props.suggestionsQuery.sortField === undefined) {
333
+ filteredSuggestions = XUtils_1.XUtils.arraySort(filteredSuggestions, this.computeDisplayValue);
334
+ }
335
+ // ak mame o 1 zaznam viac ako je lazyLoadMaxRows, zmenime posledny zaznam na ...
336
+ if (filteredSuggestions.length > this.props.lazyLoadMaxRows) {
337
+ filteredSuggestions[filteredSuggestions.length - 1] = XAutoCompleteBase.valueMoreSuggestions; // zatial priamo string
338
+ }
339
+ _a.label = 10;
340
+ case 10:
341
+ this.setState({ filteredSuggestions: filteredSuggestions });
342
+ return [2 /*return*/];
343
+ }
344
+ });
345
+ });
346
+ };
347
+ XAutoCompleteBase.prototype.onChange = function (e) {
348
+ if (typeof e.value === 'string' && !XAutoCompleteBase.isMoreSuggestions(e.value)) {
145
349
  this.setState({ inputChanged: true, inputValueState: e.value });
350
+ this.wasOnChangeCalled = false; // reset na default hodnotu
146
351
  }
147
352
  };
148
353
  XAutoCompleteBase.prototype.onSelect = function (e) {
149
- this.setObjectValue(e.value, XUtils_1.OperationType.None);
354
+ // nevolame this.setObjectValue ak uz bol zavolany z onBlur
355
+ if (!this.wasOnChangeCalled) {
356
+ // nedovolime vybrat specialny zaznam ...
357
+ if (!XAutoCompleteBase.isMoreSuggestions(e.value)) {
358
+ this.setObjectValue(e.value, XUtils_1.OperationType.None);
359
+ }
360
+ }
150
361
  };
151
362
  XAutoCompleteBase.prototype.onBlur = function (e) {
152
363
  // optimalizacia - testujeme len ak inputChanged === true
@@ -159,6 +370,11 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
159
370
  var filteredSuggestions = this.state.filteredSuggestions;
160
371
  if (filteredSuggestions && filteredSuggestions.length === 1) {
161
372
  this.setObjectValue(filteredSuggestions[0], XUtils_1.OperationType.None);
373
+ // ak bol tento this.setObjectValue vyvolany klikom do suggestions dropdown-u,
374
+ // tak bude este nasledne zavolany onSelect a tam chceme zamedzit volaniu this.setObjectValue,
375
+ // preto nastavujeme tento priznak
376
+ // priznak vratime naspet na false ak uzivatel zacne cokolvek robit s autocomplete (zacne don typovat alebo klikne na dropdown)
377
+ this.wasOnChangeCalled = true;
162
378
  }
163
379
  else {
164
380
  // tu by sme mohli skusit vyratat vysledok pre filteredSuggestions este raz, mozno este vypocet filteredSuggestions nedobehol
@@ -190,8 +406,9 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
190
406
  }
191
407
  }
192
408
  }
193
- // odchadzame z inputu, zresetujeme priznak - ak zacne user pracovat s autocomplete-om, nacitaju sa suggestions z DB (ak mame lazy)
194
- this.wasSearchStartCalled = false;
409
+ // odchadzame z inputu, zresetujeme priznak - ak zacne user pracovat s autocomplete-om, nacitaju sa suggestions z DB (ak mame suggestionsLoad = onSearchStart)
410
+ // suggestions chceme nacitat, lebo user moze zmenit iny atribut ktory ovplyvnuje filter autocomplete-u -> chceme novy zoznam suggestions
411
+ this.suggestionsLoadedForOSS = false;
195
412
  };
196
413
  XAutoCompleteBase.prototype.createErrorMessage = function () {
197
414
  return "Value \"".concat(this.state.inputValueState, "\" was not found among valid values.");
@@ -231,6 +448,14 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
231
448
  if (object !== null) {
232
449
  // ak bol save, treba tento novy object pouzit
233
450
  this.setObjectValue(object, objectChange);
451
+ // ak pouzivame zoznam this.state.suggestions, tak ho rereadneme
452
+ // poznamka: ak pouzivame this.props.suggestions z parenta, tak si musi zoznam rereadnut parent!
453
+ if (objectChange !== XUtils_1.OperationType.None) {
454
+ // zmenil sa zaznam dobrovolnika v DB
455
+ // zatial len refreshneme z DB
456
+ // ak by bol reqest pomaly, mozme pri inserte (nove id) / update (existujuce id) upravit zoznam a usetrime tym request do DB
457
+ this.loadSuggestions();
458
+ }
234
459
  // treba upravit this.state.filteredSuggestions? setli sme novy objekt, panel so suggestions by mal byt zavrety - TODO - overit
235
460
  }
236
461
  else {
@@ -270,7 +495,7 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
270
495
  _this.formDialogInitValuesForInsert = {};
271
496
  // ak mame nevalidnu hodnotu, tak ju predplnime (snaha o user friendly)
272
497
  if (_this.state.inputChanged) {
273
- _this.formDialogInitValuesForInsert[_this.props.field] = _this.state.inputValueState;
498
+ _this.formDialogInitValuesForInsert[_this.getFirstField()] = _this.state.inputValueState;
274
499
  }
275
500
  _this.setState({ formDialogOpened: true });
276
501
  }
@@ -329,15 +554,9 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
329
554
  });
330
555
  };
331
556
  XAutoCompleteBase.prototype.onOpenDropdown = function (e) {
332
- var _this = this;
333
- if (this.props.onSearchStart) {
334
- this.props.onSearchStart(function () { return _this.openDropdown(e); });
335
- }
336
- else {
337
- // otvori dropdown (search je metoda popisana v API, volanie sme skopcili zo zdrojakov primereact)
338
- //this.autoCompleteRef.current.search(e, '', 'dropdown');
339
- this.openDropdown(e);
340
- }
557
+ this.openDropdown(e);
558
+ this.suggestionsLoadedForOSS = false; // user mohol vyplnit nieco co meni filter a ide znova pracovat s autocomplete, nacitame suggestions znova (suggestionsLoad = onSearchStart)
559
+ this.wasOnChangeCalled = false; // reset na default hodnotu
341
560
  };
342
561
  XAutoCompleteBase.prototype.openDropdown = function (e) {
343
562
  // otvori dropdown (search je metoda popisana v API, volanie sme skopcili zo zdrojakov primereact)
@@ -358,19 +577,64 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
358
577
  if (!this.state.inputChanged) {
359
578
  // poznamka: ak object === null tak treba do inputu zapisovat prazdny retazec, ak by sme pouzili null, neprejavila by sa zmena v modeli na null
360
579
  var object = this.props.value;
361
- inputValue = (object !== null) ? object : ""; // TODO - je "" ok?
580
+ inputValue = (object !== null) ? this.computeDisplayValue(object) : ""; // TODO - je "" ok?
362
581
  }
363
582
  else {
364
583
  inputValue = this.state.inputValueState;
365
584
  }
366
585
  return inputValue;
367
586
  };
587
+ XAutoCompleteBase.prototype.itemTemplate = function (suggestion, index) {
588
+ return this.computeDisplayValue(suggestion);
589
+ };
590
+ XAutoCompleteBase.prototype.computeDisplayValue = function (suggestion) {
591
+ var e_2, _a;
592
+ var displayValue = "";
593
+ if (XAutoCompleteBase.isMoreSuggestions(suggestion)) {
594
+ displayValue = suggestion;
595
+ }
596
+ else {
597
+ try {
598
+ for (var _b = __values(this.getFields()), _c = _b.next(); !_c.done; _c = _b.next()) {
599
+ var field = _c.value;
600
+ // TODO - konverzie na spravny typ/string
601
+ var _d = __read(XUtilsCommon_1.XUtilsCommon.getPrefixAndField(field), 2), prefix = _d[0], fieldOnly = _d[1];
602
+ var value = XUtilsCommon_1.XUtilsCommon.getValueByPath(suggestion, fieldOnly);
603
+ if (value !== null && value !== undefined) {
604
+ var valueStr = value.toString(); // TODO - spravnu konverziu
605
+ if (valueStr !== "") {
606
+ if (displayValue !== "") {
607
+ displayValue += " ";
608
+ }
609
+ if (prefix) {
610
+ displayValue += prefix;
611
+ }
612
+ displayValue += valueStr;
613
+ }
614
+ }
615
+ }
616
+ }
617
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
618
+ finally {
619
+ try {
620
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
621
+ }
622
+ finally { if (e_2) throw e_2.error; }
623
+ }
624
+ }
625
+ return displayValue;
626
+ };
627
+ // vrati true ak sa jedna o specialny typ XAutoCompleteBase.valueMoreSuggestions
628
+ XAutoCompleteBase.isMoreSuggestions = function (suggestion) {
629
+ return typeof suggestion === "string" && suggestion === XAutoCompleteBase.valueMoreSuggestions;
630
+ };
368
631
  // takto cez metodku, mozno sa metodka vola len ked sa otvori dialog a usetrime nieco...
369
632
  XAutoCompleteBase.prototype.createSearchBrowseParams = function () {
633
+ var _a;
370
634
  return {
371
635
  onChoose: this.searchDialogOnChoose,
372
- displayFieldFilter: (this.state.inputChanged ? { field: this.props.field, constraint: { value: this.state.inputValueState, matchMode: "startsWith" } } : undefined),
373
- customFilterFunction: this.props.customFilterFunction
636
+ displayFieldFilter: (this.state.inputChanged ? { field: this.getFirstField(), constraint: { value: this.state.inputValueState, matchMode: "contains" } } : undefined),
637
+ customFilter: (_a = this.props.suggestionsQuery) === null || _a === void 0 ? void 0 : _a.filter
374
638
  };
375
639
  };
376
640
  XAutoCompleteBase.prototype.render = function () {
@@ -421,7 +685,7 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
421
685
  // <DobrovolnikForm id={this.formDialogObjectId} object={this.formDialogInitValuesForInsert} onSaveOrCancel={this.formDialogOnSaveOrCancel}/>
422
686
  // formgroup-inline lepi SplitButton na autocomplete a zarovna jeho vysku
423
687
  return (react_1.default.createElement("div", { className: "x-auto-complete-base", style: { width: this.props.width } },
424
- react_1.default.createElement(autocomplete_1.AutoComplete, __assign({ value: inputValue, suggestions: this.state.filteredSuggestions, completeMethod: this.completeMethod, field: this.props.field, onChange: this.onChange, onSelect: this.onSelect, onBlur: this.onBlur, maxLength: this.props.maxLength, ref: this.autoCompleteRef, readOnly: readOnly, disabled: readOnly }, XUtils_1.XUtils.createErrorProps(error))),
688
+ react_1.default.createElement(autocomplete_1.AutoComplete, __assign({ value: inputValue, suggestions: this.state.filteredSuggestions, completeMethod: this.completeMethod, itemTemplate: this.itemTemplate, onChange: this.onChange, onSelect: this.onSelect, onBlur: this.onBlur, minLength: this.props.minLength, scrollHeight: this.props.scrollHeight, ref: this.autoCompleteRef, readOnly: readOnly, disabled: readOnly }, XUtils_1.XUtils.createErrorProps(error))),
425
689
  dropdownButton,
426
690
  this.props.valueForm != undefined ?
427
691
  react_1.default.createElement(dialog_1.Dialog, { visible: this.state.formDialogOpened, onHide: this.formDialogOnHide, header: this.formDialogObjectId ? 'Modification' : 'New row' }, react_1.default.cloneElement(this.props.valueForm, {
@@ -432,6 +696,13 @@ var XAutoCompleteBase = /** @class */ (function (_super) {
432
696
  react_1.default.createElement(dialog_1.Dialog, { visible: this.state.searchDialogOpened, onHide: this.searchDialogOnHide }, react_1.default.cloneElement(this.props.searchBrowse, { searchBrowseParams: this.createSearchBrowseParams() } /*, props.searchBrowse.children*/))
433
697
  : undefined));
434
698
  };
699
+ XAutoCompleteBase.valueMoreSuggestions = "...";
700
+ XAutoCompleteBase.defaultProps = {
701
+ lazyLoadMaxRows: 10,
702
+ splitQueryValue: true,
703
+ minLength: 1,
704
+ scrollHeight: '15rem' // primereact has 200px
705
+ };
435
706
  return XAutoCompleteBase;
436
707
  }(react_1.Component));
437
708
  exports.XAutoCompleteBase = XAutoCompleteBase;
@@ -3,24 +3,28 @@ import { XFormComponentDT, XFormComponentDTProps } from "./XFormComponentDT";
3
3
  import { XAssoc } from "../serverApi/XEntityMetadata";
4
4
  import { OperationType } from "./XUtils";
5
5
  import { XError } from "./XErrors";
6
+ import { XSuggestionsLoadProp } from "./XAutoCompleteBase";
6
7
  import { XTableFieldFilterProp } from "./XFormDataTable2";
8
+ import { DataTableSortMeta } from "primereact/datatable";
7
9
  export interface XAutoCompleteDTProps extends XFormComponentDTProps {
8
10
  assocField: string;
9
11
  displayField: string;
10
12
  searchBrowse?: JSX.Element;
11
13
  assocForm?: JSX.Element;
12
- filter?: XTableFieldFilterProp;
13
14
  suggestions?: any[];
15
+ suggestionsLoad?: XSuggestionsLoadProp;
16
+ lazyLoadMaxRows?: number;
17
+ splitQueryValue?: boolean;
18
+ minLength?: number;
19
+ filter?: XTableFieldFilterProp;
20
+ sortField?: string | DataTableSortMeta[];
21
+ fields?: string[];
22
+ scrollHeight?: string;
14
23
  }
15
24
  export declare class XAutoCompleteDT extends XFormComponentDT<XAutoCompleteDTProps> {
16
25
  protected xAssoc: XAssoc;
17
26
  protected errorInBase: string | undefined;
18
- state: {
19
- suggestions: any[];
20
- };
21
27
  constructor(props: XAutoCompleteDTProps);
22
- componentDidMount(): void;
23
- readAndSetSuggestions(): Promise<void>;
24
28
  getField(): string;
25
29
  isNotNull(): boolean;
26
30
  getValue(): any | null;
@@ -14,42 +14,6 @@ var __extends = (this && this.__extends) || (function () {
14
14
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
15
  };
16
16
  })();
17
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
- return new (P || (P = Promise))(function (resolve, reject) {
20
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
- step((generator = generator.apply(thisArg, _arguments || [])).next());
24
- });
25
- };
26
- var __generator = (this && this.__generator) || function (thisArg, body) {
27
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
28
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
29
- function verb(n) { return function (v) { return step([n, v]); }; }
30
- function step(op) {
31
- if (f) throw new TypeError("Generator is already executing.");
32
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
33
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
34
- if (y = 0, t) op = [op[0] & 2, t.value];
35
- switch (op[0]) {
36
- case 0: case 1: t = op; break;
37
- case 4: _.label++; return { value: op[1], done: false };
38
- case 5: _.label++; y = op[1]; op = [0]; continue;
39
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
40
- default:
41
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
42
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
43
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
44
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
45
- if (t[2]) _.ops.pop();
46
- _.trys.pop(); continue;
47
- }
48
- op = body.call(thisArg, _);
49
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
50
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
- }
52
- };
53
17
  var __importDefault = (this && this.__importDefault) || function (mod) {
54
18
  return (mod && mod.__esModule) ? mod : { "default": mod };
55
19
  };
@@ -57,7 +21,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
57
21
  exports.XAutoCompleteDT = void 0;
58
22
  var react_1 = __importDefault(require("react"));
59
23
  var XFormComponentDT_1 = require("./XFormComponentDT");
60
- var XUtils_1 = require("./XUtils");
61
24
  var XAutoCompleteBase_1 = require("./XAutoCompleteBase");
62
25
  var XUtilsMetadataCommon_1 = require("../serverApi/XUtilsMetadataCommon");
63
26
  var XAutoCompleteDT = /** @class */ (function (_super) {
@@ -66,33 +29,12 @@ var XAutoCompleteDT = /** @class */ (function (_super) {
66
29
  var _this = _super.call(this, props) || this;
67
30
  _this.xAssoc = XUtilsMetadataCommon_1.XUtilsMetadataCommon.getXAssocToOne(XUtilsMetadataCommon_1.XUtilsMetadataCommon.getXEntity(props.entity), props.assocField);
68
31
  _this.errorInBase = undefined;
69
- _this.state = {
70
- suggestions: []
71
- };
72
32
  _this.onChangeAutoCompleteBase = _this.onChangeAutoCompleteBase.bind(_this);
73
33
  _this.onErrorChangeAutoCompleteBase = _this.onErrorChangeAutoCompleteBase.bind(_this);
74
34
  return _this;
75
35
  }
76
- XAutoCompleteDT.prototype.componentDidMount = function () {
77
- this.readAndSetSuggestions();
78
- };
79
- XAutoCompleteDT.prototype.readAndSetSuggestions = function () {
80
- return __awaiter(this, void 0, void 0, function () {
81
- var suggestions;
82
- return __generator(this, function (_a) {
83
- switch (_a.label) {
84
- case 0:
85
- if (!(this.props.suggestions === undefined)) return [3 /*break*/, 2];
86
- return [4 /*yield*/, XUtils_1.XUtils.fetchRows(this.xAssoc.entityName, this.getFilterBase(this.props.filter), this.props.displayField)];
87
- case 1:
88
- suggestions = _a.sent();
89
- this.setState({ suggestions: suggestions });
90
- _a.label = 2;
91
- case 2: return [2 /*return*/];
92
- }
93
- });
94
- });
95
- };
36
+ // componentDidMount() {
37
+ // }
96
38
  XAutoCompleteDT.prototype.getField = function () {
97
39
  return this.props.assocField;
98
40
  };
@@ -105,13 +47,6 @@ var XAutoCompleteDT = /** @class */ (function (_super) {
105
47
  };
106
48
  XAutoCompleteDT.prototype.onChangeAutoCompleteBase = function (object, objectChange) {
107
49
  this.onValueChangeBase(object, this.props.onChange, objectChange);
108
- if (objectChange !== XUtils_1.OperationType.None) {
109
- // zmenil sa zaznam dobrovolnika v DB
110
- // zatial len refreshneme z DB
111
- // ak by bol reqest pomaly, mozme pri inserte (nove id) / update (existujuce id) upravit zoznam a usetrime tym request do DB
112
- // ak bol delete (dobrovolnik === null), treba urobit refresh do DB (alebo si poslat id-cko zmazaneho zaznamu)
113
- this.readAndSetSuggestions();
114
- }
115
50
  };
116
51
  XAutoCompleteDT.prototype.onErrorChangeAutoCompleteBase = function (error) {
117
52
  this.errorInBase = error; // odlozime si error
@@ -128,13 +63,12 @@ var XAutoCompleteDT = /** @class */ (function (_super) {
128
63
  };
129
64
  XAutoCompleteDT.prototype.render = function () {
130
65
  var _this = this;
131
- var _a;
132
66
  var xEntityAssoc = XUtilsMetadataCommon_1.XUtilsMetadataCommon.getXEntity(this.xAssoc.entityName);
133
67
  //const xDisplayField = XUtilsMetadataCommon.getXFieldByPath(xEntityAssoc, this.props.displayField);
134
68
  // TODO - size
135
69
  //const size = this.props.size ?? xDisplayField.length;
136
70
  // div className="col" nam zabezpeci aby XAutoCompleteBase nezaberal celu dlzku grid-u (ma nastaveny width=100% vdaka "formgroup-inline")
137
- return (react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: this.getValue(), suggestions: (_a = this.props.suggestions) !== null && _a !== void 0 ? _a : this.state.suggestions, onChange: this.onChangeAutoCompleteBase, field: this.props.displayField, searchBrowse: this.props.searchBrowse, valueForm: this.props.assocForm, idField: xEntityAssoc.idField, readOnly: this.isReadOnly(), error: this.getError(), onErrorChange: this.onErrorChangeAutoCompleteBase, customFilterFunction: function () { return _this.getFilterBase(_this.props.filter); } }));
71
+ return (react_1.default.createElement(XAutoCompleteBase_1.XAutoCompleteBase, { value: this.getValue(), onChange: this.onChangeAutoCompleteBase, field: this.props.displayField, 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, 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 } }));
138
72
  };
139
73
  return XAutoCompleteDT;
140
74
  }(XFormComponentDT_1.XFormComponentDT));
@@ -541,7 +541,7 @@ var XFormDataTable2 = /** @class */ (function (_super) {
541
541
  }
542
542
  var filterDisplay = this.props.filterDisplay !== "none" ? this.props.filterDisplay : undefined;
543
543
  // default sortovanie - ak mame insert tak nesortujeme (drzime poradie v akom user zaznam vytvoril), ak mame update tak podla id zosortujeme (nech je to zobrazene vzdy rovnako)
544
- var sortField = ((_a = this.props.sortField) !== null && _a !== void 0 ? _a : this.props.form.isAddRow()) ? undefined : xEntity.idField;
544
+ var sortField = (_a = this.props.sortField) !== null && _a !== void 0 ? _a : (this.props.form.isAddRow() ? undefined : xEntity.idField);
545
545
  var label = this.props.label !== undefined ? this.props.label : this.props.assocField;
546
546
  var readOnly = this.isReadOnly();
547
547
  // v bloku function (child) nejde pouzit priamo this, thisLocal uz ide pouzit
@@ -1,5 +1,5 @@
1
1
  import React, { ReactChild } from 'react';
2
- import { DataTableFilterMeta, DataTableFilterMetaData, DataTableOperatorFilterMetaData } from 'primereact/datatable';
2
+ import { DataTableFilterMeta, DataTableFilterMetaData, DataTableOperatorFilterMetaData, DataTableSortMeta } from 'primereact/datatable';
3
3
  import { ColumnBodyOptions, ColumnFilterElementTemplateOptions } from 'primereact/column';
4
4
  import { XViewStatusOrBoolean } from "./XUtils";
5
5
  import { XSearchBrowseParams } from "./XSearchBrowseParams";
@@ -51,11 +51,13 @@ export interface XLazyDataTableProps {
51
51
  appButtons?: any;
52
52
  filters?: DataTableFilterMeta;
53
53
  customFilter?: XCustomFilter;
54
- sortField?: string;
54
+ sortField?: string | DataTableSortMeta[];
55
55
  fullTextSearch: boolean | string[];
56
+ fields?: string[];
56
57
  multiLineSwitch: boolean;
57
58
  searchBrowseParams?: XSearchBrowseParams;
58
59
  width?: string;
60
+ rowClassName?: (data: any) => object | string | undefined;
59
61
  dataLoadedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];
60
62
  editMode?: boolean;
61
63
  editModeHandlers?: XEditModeHandlers;
@@ -96,6 +96,15 @@ var __read = (this && this.__read) || function (o, n) {
96
96
  }
97
97
  return ar;
98
98
  };
99
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
100
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
101
+ if (ar || !(i in from)) {
102
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
103
+ ar[i] = from[i];
104
+ }
105
+ }
106
+ return to.concat(ar || Array.prototype.slice.call(from));
107
+ };
99
108
  Object.defineProperty(exports, "__esModule", { value: true });
100
109
  exports.XLazyColumn = exports.XLazyDataTable = void 0;
101
110
  var react_1 = __importStar(require("react"));
@@ -220,15 +229,15 @@ var XLazyDataTable = function (props) {
220
229
  filtersInit[displayFieldFilter.field] = createFilterItem(props.filterDisplay, displayFieldFilter.constraint);
221
230
  }
222
231
  // ak mame props.searchBrowseParams.customFilterFunction, pridame filter
223
- if (props.searchBrowseParams.customFilterFunction) {
224
- customFilterItems = XUtils_1.XUtils.filterAnd(customFilterItems, props.searchBrowseParams.customFilterFunction());
232
+ if (props.searchBrowseParams.customFilter) {
233
+ customFilterItems = XUtils_1.XUtils.filterAnd(customFilterItems, XUtils_1.XUtils.evalFilter(props.searchBrowseParams.customFilter));
225
234
  }
226
235
  }
227
236
  var _f = __read((0, react_1.useState)(filtersInit), 2), filters = _f[0], setFilters = _f[1]; // filtrovanie na "controlled manner" (moze sa sem nainicializovat nejaka hodnota)
228
237
  var initFtsInputValue = props.fullTextSearch ? createInitFtsInputValue() : undefined;
229
238
  var _g = __read((0, react_1.useState)(initFtsInputValue), 2), ftsInputValue = _g[0], setFtsInputValue = _g[1];
230
239
  var _h = __read((0, react_1.useState)(true), 2), multiLineSwitchValue = _h[0], setMultiLineSwitchValue = _h[1];
231
- var _j = __read((0, react_1.useState)(props.sortField ? [{ field: props.sortField, order: 1 }] : []), 2), multiSortMeta = _j[0], setMultiSortMeta = _j[1];
240
+ var _j = __read((0, react_1.useState)(XUtils_1.XUtils.createMultiSortMeta(props.sortField)), 2), multiSortMeta = _j[0], setMultiSortMeta = _j[1];
232
241
  var _k = __read((0, react_1.useState)(null), 2), selectedRow = _k[0], setSelectedRow = _k[1];
233
242
  var _l = __read((_a = props.dataLoadedState) !== null && _a !== void 0 ? _a : (0, react_1.useState)(false), 2), dataLoaded = _l[0], setDataLoaded = _l[1]; // priznak kde si zapiseme, ci uz sme nacitali data
234
243
  var _m = __read((0, react_1.useState)(false), 2), exportRowsDialogOpened = _m[0], setExportRowsDialogOpened = _m[1];
@@ -335,6 +344,7 @@ var XLazyDataTable = function (props) {
335
344
  xFullTextSearch = {
336
345
  fields: Array.isArray(props.fullTextSearch) ? props.fullTextSearch : undefined,
337
346
  value: ftsInputValue.value,
347
+ splitValue: true,
338
348
  matchMode: ftsInputValue.matchMode
339
349
  };
340
350
  }
@@ -359,6 +369,9 @@ var XLazyDataTable = function (props) {
359
369
  }
360
370
  finally { if (e_3) throw e_3.error; }
361
371
  }
372
+ if (props.fields) {
373
+ fields.push.apply(fields, __spreadArray([], __read(props.fields), false));
374
+ }
362
375
  return fields;
363
376
  };
364
377
  var getHeaders = function () {
@@ -887,7 +900,7 @@ var XLazyDataTable = function (props) {
887
900
  react_1.default.createElement(XButton_1.XButton, { key: "clearFilter", label: (0, XLocale_1.xLocaleOption)('clearFilter'), onClick: onClickClearFilter }),
888
901
  props.multiLineSwitch ? react_1.default.createElement(inputswitch_1.InputSwitch, { checked: multiLineSwitchValue, onChange: function (e) { return setMultiLineSwitchValue(e.value); }, className: "m-1" }) : null),
889
902
  react_1.default.createElement("div", { className: "flex justify-content-center" },
890
- react_1.default.createElement(datatable_1.DataTable, { value: value.rowList, dataKey: dataKey, paginator: props.paginator, rows: rows, totalRecords: value.totalRecords, lazy: true, first: first, onPage: onPage, loading: loading, filterDisplay: props.filterDisplay, filters: filters, onFilter: onFilter, sortMode: "multiple", removableSort: true, multiSortMeta: multiSortMeta, onSort: onSort, selectionMode: "single", selection: selectedRow, onSelectionChange: onSelectionChange, onRowDoubleClick: onRowDoubleClick, ref: dataTableEl, className: "p-datatable-sm x-lazy-datatable", resizableColumns: true, columnResizeMode: "expand", tableStyle: tableStyle, paginatorLeft: paginatorLeft, paginatorRight: paginatorRight, scrollable: props.scrollable, scrollHeight: scrollHeight, style: style }, columnElemList)),
903
+ react_1.default.createElement(datatable_1.DataTable, { value: value.rowList, dataKey: dataKey, paginator: props.paginator, rows: rows, totalRecords: value.totalRecords, lazy: true, first: first, onPage: onPage, loading: loading, filterDisplay: props.filterDisplay, filters: filters, onFilter: onFilter, sortMode: "multiple", removableSort: true, multiSortMeta: multiSortMeta, onSort: onSort, selectionMode: "single", selection: selectedRow, onSelectionChange: onSelectionChange, onRowDoubleClick: onRowDoubleClick, 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)),
891
904
  react_1.default.createElement("div", { className: "flex justify-content-center" },
892
905
  props.onAddRow !== undefined && props.searchBrowseParams === undefined ? react_1.default.createElement(XButton_1.XButton, { key: "addRow", icon: "pi pi-plus", label: (0, XLocale_1.xLocaleOption)('addRow'), onClick: onClickAddRow }) : null,
893
906
  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,
@@ -1,5 +1,5 @@
1
1
  import { DataTableFilterMetaData } from "primereact/datatable";
2
- import { XCustomFilter } from "../serverApi/FindParam";
2
+ import { XFilterOrFunction } from "./XAutoCompleteBase";
3
3
  export interface XFieldFilter {
4
4
  field: string;
5
5
  constraint: DataTableFilterMetaData;
@@ -7,5 +7,5 @@ export interface XFieldFilter {
7
7
  export interface XSearchBrowseParams {
8
8
  onChoose: (chosenRow: any) => void;
9
9
  displayFieldFilter?: XFieldFilter;
10
- customFilterFunction?: () => XCustomFilter | undefined;
10
+ customFilter?: XFilterOrFunction;
11
11
  }
@@ -203,8 +203,8 @@ var XSearchButton = /** @class */ (function (_super) {
203
203
  var createSearchBrowseParams = function () {
204
204
  return {
205
205
  onChoose: onChoose,
206
- displayFieldFilter: (inputChanged ? { field: props.displayField, constraint: { value: inputValueState, matchMode: "startsWith" } } : undefined),
207
- customFilterFunction: function () { return _this.getFilterBase(_this.props.filter); }
206
+ displayFieldFilter: (inputChanged ? { field: props.displayField, constraint: { value: inputValueState, matchMode: "contains" } } : undefined),
207
+ customFilter: function () { return _this.getFilterBase(_this.props.filter); }
208
208
  };
209
209
  };
210
210
  // vypocitame inputValue
@@ -184,8 +184,8 @@ var XSearchButtonDT = function (props) {
184
184
  react_1.default.createElement(dialog_1.Dialog, { visible: dialogOpened, onHide: onHide }, react_1.default.cloneElement(props.searchBrowse, {
185
185
  searchBrowseParams: {
186
186
  onChoose: onChoose,
187
- displayFieldFilter: (inputChanged ? { field: props.displayField, constraint: { value: inputValueState, matchMode: "startsWith" } } : undefined),
188
- customFilterFunction: function () { return undefined; } // TODO - dorobit
187
+ displayFieldFilter: (inputChanged ? { field: props.displayField, constraint: { value: inputValueState, matchMode: "contains" } } : undefined),
188
+ customFilter: undefined // TODO - dorobit
189
189
  }
190
190
  } /*, props.searchBrowse.children*/))));
191
191
  };
@@ -7,6 +7,7 @@ import { XCustomFilter, XCustomFilterItem } from "../serverApi/FindParam";
7
7
  import { DataTableSortMeta } from "primereact/datatable";
8
8
  import { XObject } from "./XObject";
9
9
  import { XTableFieldReadOnlyProp } from "./XFormDataTable2";
10
+ import { XFilterOrFunction } from "./XAutoCompleteBase";
10
11
  export declare enum OperationType {
11
12
  None = 0,
12
13
  Insert = 1,
@@ -54,6 +55,7 @@ export declare class XUtils {
54
55
  static getAppForm(entity: string, formId?: string): any;
55
56
  static fetchMany(path: string, value: any, usePublicToken?: boolean | XToken): Promise<any[]>;
56
57
  static fetchRows(entity: string, customFilter?: XCustomFilter | undefined, sortField?: string | DataTableSortMeta[] | undefined, fields?: string[]): Promise<any[]>;
58
+ static fetchRowCount(entity: string, customFilter?: XCustomFilter | undefined): Promise<number>;
57
59
  static fetchOne(path: string, value: any, usePublicToken?: boolean | XToken): Promise<any>;
58
60
  static fetchString(path: string, value: any): Promise<string>;
59
61
  static fetch(path: string, value: any, usePublicToken?: boolean | XToken): Promise<any>;
@@ -108,8 +110,10 @@ export declare class XUtils {
108
110
  static getErrorMessage(xError: XError): string | undefined;
109
111
  static normalizeString(value: string): string;
110
112
  static createCustomFilterItems(customFilter: XCustomFilter | undefined): XCustomFilterItem[] | undefined;
113
+ static createMultiSortMeta(sortField: string | DataTableSortMeta[] | undefined): DataTableSortMeta[] | undefined;
111
114
  static filterAnd(...filters: (XCustomFilter | undefined)[]): XCustomFilterItem[] | undefined;
112
115
  static filterIdIn(idField: string, idList: number[]): XCustomFilter;
116
+ static evalFilter(filter: XFilterOrFunction | undefined): XCustomFilter | undefined;
113
117
  static isTableRowInserted(tableRow: any): boolean;
114
118
  static xViewStatus(xViewStatusOrBoolean: XViewStatusOrBoolean): XViewStatus;
115
119
  }
@@ -272,20 +272,11 @@ var XUtils = /** @class */ (function () {
272
272
  // pomocna metodka pouzivajuca lazyDataTable service
273
273
  XUtils.fetchRows = function (entity, customFilter, sortField, fields) {
274
274
  return __awaiter(this, void 0, void 0, function () {
275
- var multiSortMeta, findParam, rowList;
275
+ var findParam, rowList;
276
276
  return __generator(this, function (_a) {
277
277
  switch (_a.label) {
278
278
  case 0:
279
- multiSortMeta = undefined;
280
- if (sortField) {
281
- if (Array.isArray(sortField)) {
282
- multiSortMeta = sortField;
283
- }
284
- else {
285
- multiSortMeta = [{ field: sortField, order: 1 }];
286
- }
287
- }
288
- findParam = { resultType: FindParam_1.ResultType.AllRows, entity: entity, customFilterItems: XUtils.createCustomFilterItems(customFilter), multiSortMeta: multiSortMeta, fields: fields };
279
+ findParam = { resultType: FindParam_1.ResultType.AllRows, entity: entity, customFilterItems: XUtils.createCustomFilterItems(customFilter), multiSortMeta: XUtils.createMultiSortMeta(sortField), fields: fields };
289
280
  return [4 /*yield*/, XUtils.fetchOne('lazyDataTableFindRows', findParam)];
290
281
  case 1:
291
282
  rowList = (_a.sent()).rowList;
@@ -294,6 +285,22 @@ var XUtils = /** @class */ (function () {
294
285
  });
295
286
  });
296
287
  };
288
+ // pomocna metodka pouzivajuca lazyDataTable service
289
+ XUtils.fetchRowCount = function (entity, customFilter) {
290
+ return __awaiter(this, void 0, void 0, function () {
291
+ var findParam, totalRecords;
292
+ return __generator(this, function (_a) {
293
+ switch (_a.label) {
294
+ case 0:
295
+ findParam = { resultType: FindParam_1.ResultType.OnlyRowCount, entity: entity, customFilterItems: XUtils.createCustomFilterItems(customFilter) };
296
+ return [4 /*yield*/, XUtils.fetchOne('lazyDataTableFindRows', findParam)];
297
+ case 1:
298
+ totalRecords = (_a.sent()).totalRecords;
299
+ return [2 /*return*/, totalRecords];
300
+ }
301
+ });
302
+ });
303
+ };
297
304
  XUtils.fetchOne = function (path, value, usePublicToken) {
298
305
  return XUtils.fetch(path, value, usePublicToken);
299
306
  };
@@ -701,6 +708,28 @@ var XUtils = /** @class */ (function () {
701
708
  }
702
709
  return customFilterItems;
703
710
  };
711
+ // pomocna metodka - konvertuje sortField -> DataTableSortMeta[]
712
+ XUtils.createMultiSortMeta = function (sortField) {
713
+ var multiSortMeta = undefined;
714
+ if (sortField) {
715
+ if (Array.isArray(sortField)) {
716
+ multiSortMeta = sortField;
717
+ }
718
+ else {
719
+ // default order is asc, supported is also value in form "<column name> desc"
720
+ var order = 1;
721
+ var fieldAndOrder = sortField.split(' ');
722
+ if (fieldAndOrder.length === 2) {
723
+ sortField = fieldAndOrder[0];
724
+ if (fieldAndOrder[1].toLowerCase() === "desc") {
725
+ order = -1;
726
+ }
727
+ }
728
+ multiSortMeta = [{ field: sortField, order: order }];
729
+ }
730
+ }
731
+ return multiSortMeta;
732
+ };
704
733
  // pomocna metodka
705
734
  XUtils.filterAnd = function () {
706
735
  var e_7, _a;
@@ -736,6 +765,17 @@ var XUtils = /** @class */ (function () {
736
765
  return { where: "[".concat(idField, "] IN (:...idList)"), params: { "idList": idList.length > 0 ? idList : [0] } };
737
766
  };
738
767
  // pomocna metodka
768
+ XUtils.evalFilter = function (filter) {
769
+ var customFilter = undefined;
770
+ if (typeof filter === 'object') {
771
+ customFilter = filter;
772
+ }
773
+ if (typeof filter === 'function') {
774
+ customFilter = filter();
775
+ }
776
+ return customFilter;
777
+ };
778
+ // pomocna metodka
739
779
  XUtils.isTableRowInserted = function (tableRow) {
740
780
  var _a;
741
781
  return (_a = tableRow.__x_generatedRowId) !== null && _a !== void 0 ? _a : false; // specialny priznak, ze sme vygenerovali id-cko
@@ -1,8 +1,9 @@
1
1
  import { DataTableFilterMeta, DataTableSortMeta } from "primereact/datatable";
2
2
  export declare enum ResultType {
3
3
  OnlyRowCount = 0,
4
- RowCountAndPagedRows = 1,
5
- AllRows = 2
4
+ OnlyPagedRows = 1,
5
+ RowCountAndPagedRows = 2,
6
+ AllRows = 3
6
7
  }
7
8
  export interface XParams {
8
9
  [key: string]: any;
@@ -15,6 +16,7 @@ export type XCustomFilter = XCustomFilterItem | XCustomFilterItem[];
15
16
  export interface XFullTextSearch {
16
17
  fields?: string[];
17
18
  value: string;
19
+ splitValue: boolean;
18
20
  matchMode: 'startsWith' | 'contains' | 'endsWith' | 'equals';
19
21
  }
20
22
  export declare enum XAggregateType {
@@ -39,3 +41,11 @@ export interface FindParam {
39
41
  fields?: string[];
40
42
  aggregateItems?: XAggregateItem[];
41
43
  }
44
+ export interface XLazyAutoCompleteSuggestionsRequest {
45
+ maxRows: number;
46
+ fullTextSearch?: XFullTextSearch;
47
+ entity: string;
48
+ filterItems?: XCustomFilterItem[];
49
+ multiSortMeta?: DataTableSortMeta[];
50
+ fields?: string[];
51
+ }
@@ -18,8 +18,9 @@ exports.XAggregateType = exports.ResultType = void 0;
18
18
  var ResultType;
19
19
  (function (ResultType) {
20
20
  ResultType[ResultType["OnlyRowCount"] = 0] = "OnlyRowCount";
21
- ResultType[ResultType["RowCountAndPagedRows"] = 1] = "RowCountAndPagedRows";
22
- ResultType[ResultType["AllRows"] = 2] = "AllRows";
21
+ ResultType[ResultType["OnlyPagedRows"] = 1] = "OnlyPagedRows";
22
+ ResultType[ResultType["RowCountAndPagedRows"] = 2] = "RowCountAndPagedRows";
23
+ ResultType[ResultType["AllRows"] = 3] = "AllRows";
23
24
  })(ResultType = exports.ResultType || (exports.ResultType = {}));
24
25
  var XAggregateType;
25
26
  (function (XAggregateType) {
@@ -8,6 +8,7 @@ export declare class XUtilsCommon {
8
8
  static getPathToAssoc(path: string): string;
9
9
  static getPathToAssocAndField(path: string): [string | null, string];
10
10
  static isSingleField(path: string): boolean;
11
+ static getPrefixAndField(path: string): [string | null, string];
11
12
  static objectAsJSON(value: any): string;
12
13
  static getDayName(date: Date | null | undefined): string | undefined;
13
14
  static dateAddDays(date: Date | null, days: number): Date | null;
@@ -157,6 +157,17 @@ var XUtilsCommon = /** @class */ (function () {
157
157
  XUtilsCommon.isSingleField = function (path) {
158
158
  return path.indexOf(".") === -1;
159
159
  };
160
+ XUtilsCommon.getPrefixAndField = function (path) {
161
+ var posDot = path.indexOf(":");
162
+ if (posDot === -1) {
163
+ return [null, path];
164
+ }
165
+ else {
166
+ var prefix = path.substring(0, posDot);
167
+ var pathOnly = path.substring(posDot + 1);
168
+ return [prefix, pathOnly];
169
+ }
170
+ };
160
171
  XUtilsCommon.objectAsJSON = function (value) {
161
172
  // sem treba dat nejaku pre nas vhodnu serializaciu
162
173
  // zatial provizorne robene cez antipatern - modifikaciu prototype funcii primitivnych typov
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michalrakus/x-react-web-lib",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "clean": "rimraf lib",