@syncfusion/ej2-querybuilder 24.2.9 → 25.1.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/ej2-querybuilder.min.js +2 -2
  3. package/dist/ej2-querybuilder.umd.min.js +2 -2
  4. package/dist/ej2-querybuilder.umd.min.js.map +1 -1
  5. package/dist/es6/ej2-querybuilder.es2015.js +1616 -162
  6. package/dist/es6/ej2-querybuilder.es2015.js.map +1 -1
  7. package/dist/es6/ej2-querybuilder.es5.js +1618 -162
  8. package/dist/es6/ej2-querybuilder.es5.js.map +1 -1
  9. package/dist/global/ej2-querybuilder.min.js +2 -2
  10. package/dist/global/ej2-querybuilder.min.js.map +1 -1
  11. package/dist/global/index.d.ts +1 -1
  12. package/package.json +12 -12
  13. package/src/global.js +2 -0
  14. package/src/query-builder/index.d.ts +1 -0
  15. package/src/query-builder/index.js +1 -0
  16. package/src/query-builder/query-builder-model.d.ts +69 -1
  17. package/src/query-builder/query-builder.d.ts +189 -4
  18. package/src/query-builder/query-builder.js +906 -137
  19. package/src/query-builder/query-library.d.ts +24 -0
  20. package/src/query-builder/query-library.js +689 -0
  21. package/styles/bootstrap-dark.css +29 -12
  22. package/styles/bootstrap.css +29 -12
  23. package/styles/bootstrap4.css +25 -12
  24. package/styles/bootstrap5-dark.css +38 -12
  25. package/styles/bootstrap5.css +38 -12
  26. package/styles/fabric-dark.css +25 -12
  27. package/styles/fabric.css +25 -12
  28. package/styles/fluent-dark.css +42 -12
  29. package/styles/fluent.css +42 -12
  30. package/styles/highcontrast-light.css +25 -12
  31. package/styles/highcontrast.css +25 -12
  32. package/styles/material-dark.css +34 -12
  33. package/styles/material.css +34 -12
  34. package/styles/material3-dark.css +25 -12
  35. package/styles/material3.css +25 -12
  36. package/styles/query-builder/_bds-definition.scss +107 -0
  37. package/styles/query-builder/_layout.scss +37 -7
  38. package/styles/query-builder/_theme.scss +19 -2
  39. package/styles/query-builder/bootstrap-dark.css +29 -12
  40. package/styles/query-builder/bootstrap.css +29 -12
  41. package/styles/query-builder/bootstrap4.css +25 -12
  42. package/styles/query-builder/bootstrap5-dark.css +38 -12
  43. package/styles/query-builder/bootstrap5.css +38 -12
  44. package/styles/query-builder/fabric-dark.css +25 -12
  45. package/styles/query-builder/fabric.css +25 -12
  46. package/styles/query-builder/fluent-dark.css +42 -12
  47. package/styles/query-builder/fluent.css +42 -12
  48. package/styles/query-builder/highcontrast-light.css +25 -12
  49. package/styles/query-builder/highcontrast.css +25 -12
  50. package/styles/query-builder/icons/_bds.scss +7 -0
  51. package/styles/query-builder/material-dark.css +34 -12
  52. package/styles/query-builder/material.css +34 -12
  53. package/styles/query-builder/material3-dark.css +25 -12
  54. package/styles/query-builder/material3.css +25 -12
  55. package/styles/query-builder/tailwind-dark.css +30 -11
  56. package/styles/query-builder/tailwind.css +30 -11
  57. package/styles/tailwind-dark.css +30 -11
  58. package/styles/tailwind.css +30 -11
@@ -89,6 +89,9 @@ __decorate([
89
89
  __decorate([
90
90
  Property(false)
91
91
  ], Rule.prototype, "not", void 0);
92
+ __decorate([
93
+ Property(false)
94
+ ], Rule.prototype, "isLocked", void 0);
92
95
  /**
93
96
  * Defines the property for value.
94
97
  */
@@ -114,6 +117,18 @@ __decorate([
114
117
  */
115
118
  class ShowButtons extends ChildProperty {
116
119
  }
120
+ __decorate([
121
+ Property(false)
122
+ ], ShowButtons.prototype, "cloneRule", void 0);
123
+ __decorate([
124
+ Property(false)
125
+ ], ShowButtons.prototype, "cloneGroup", void 0);
126
+ __decorate([
127
+ Property(false)
128
+ ], ShowButtons.prototype, "lockRule", void 0);
129
+ __decorate([
130
+ Property(false)
131
+ ], ShowButtons.prototype, "lockGroup", void 0);
117
132
  __decorate([
118
133
  Property(true)
119
134
  ], ShowButtons.prototype, "ruleDelete", void 0);
@@ -128,7 +143,7 @@ let QueryBuilder = class QueryBuilder extends Component {
128
143
  super(options, element);
129
144
  this.isReadonly = true;
130
145
  this.fields = { text: 'label', value: 'field' };
131
- this.updatedRule = { not: false, condition: 'and' };
146
+ this.updatedRule = { not: false, condition: 'and', isLocked: false };
132
147
  this.isLocale = false;
133
148
  this.isRefreshed = false;
134
149
  this.isNotified = false;
@@ -139,6 +154,14 @@ let QueryBuilder = class QueryBuilder extends Component {
139
154
  this.isDestroy = false;
140
155
  this.isGetNestedData = false;
141
156
  this.isCustomOprCols = [];
157
+ this.groupCounter = 0;
158
+ this.lockItems = [];
159
+ this.groupIndex = -1;
160
+ this.ruleIndex = -1;
161
+ this.isLastGroup = false;
162
+ this.cloneGrpBtnClick = false;
163
+ this.isMiddleGroup = false;
164
+ this.cloneRuleBtnClick = false;
142
165
  MultiSelect.Inject(CheckBoxSelection);
143
166
  }
144
167
  getPersistData() {
@@ -190,6 +213,14 @@ let QueryBuilder = class QueryBuilder extends Component {
190
213
  getModuleName() {
191
214
  return 'query-builder';
192
215
  }
216
+ requiredModules() {
217
+ const modules = [];
218
+ modules.push({
219
+ member: 'query-library',
220
+ args: [this]
221
+ });
222
+ return modules;
223
+ }
193
224
  GetRootColumnName(field) {
194
225
  return this.separator ? field.split(this.separator)[0] : field;
195
226
  }
@@ -378,31 +409,51 @@ let QueryBuilder = class QueryBuilder extends Component {
378
409
  txtareaElem.style.height = txtareaElem.scrollHeight + 'px';
379
410
  }
380
411
  if (target.tagName === 'BUTTON' && target.className.indexOf('e-qb-toggle') < 0) {
381
- if (target.className.indexOf('e-removerule') > -1) {
382
- this.actionButton = target;
383
- this.deleteRule(target);
384
- }
385
- else if (target.className.indexOf('e-deletegroup') > -1) {
386
- this.actionButton = target;
387
- this.deleteGroup(closest(target, '.e-group-container'));
388
- }
389
- else if (target.className.indexOf('e-edit-rule') > -1) {
390
- const animation = new Animation({ duration: 1000, delay: 0 });
391
- animation.animate('.e-query-builder', { name: 'SlideLeftIn' });
392
- document.getElementById(this.element.id + '_summary_content').style.display = 'none';
393
- if (this.element.querySelectorAll('.e-group-container').length < 1) {
394
- this.addGroupElement(false, this.element, this.rule.condition, false, this.rule.not);
395
- const mRules = extend({}, this.rule, {}, true);
396
- this.setGroupRules(mRules);
397
- this.renderSummaryCollapse();
398
- }
399
- else {
400
- const groupElem = this.element.querySelector('.e-group-container');
401
- if (groupElem.querySelectorAll('.e-collapse-rule').length < 1) {
412
+ switch (true) {
413
+ case target.className.indexOf('e-removerule') > -1:
414
+ this.actionButton = target;
415
+ this.deleteRule(target);
416
+ break;
417
+ case target.className.indexOf('e-clone-rule-btn') > -1:
418
+ this.actionButton = target;
419
+ this.cloneRuleBtnClick = true;
420
+ this.ruleClone(target);
421
+ break;
422
+ case target.className.indexOf('e-lock-rule-btn') > -1:
423
+ this.actionButton = target;
424
+ this.ruleLock(target);
425
+ break;
426
+ case target.className.indexOf('e-lock-grp-btn') > -1:
427
+ this.actionButton = target;
428
+ this.groupLock(target);
429
+ break;
430
+ case target.className.indexOf('e-clone-grp-btn') > -1:
431
+ this.actionButton = target;
432
+ this.cloneGrpBtnClick = true;
433
+ this.groupClone(closest(target, '.e-group-container'));
434
+ break;
435
+ case target.className.indexOf('e-deletegroup') > -1:
436
+ this.actionButton = target;
437
+ this.deleteGroup(closest(target, '.e-group-container'));
438
+ break;
439
+ case target.className.indexOf('e-edit-rule') > -1:
440
+ const animation = new Animation({ duration: 1000, delay: 0 });
441
+ animation.animate('.e-query-builder', { name: 'SlideLeftIn' });
442
+ document.getElementById(this.element.id + '_summary_content').style.display = 'none';
443
+ if (this.element.querySelectorAll('.e-group-container').length < 1) {
444
+ this.addGroupElement(false, this.element, this.rule.condition, false, this.rule.not);
445
+ const mRules = extend({}, this.rule, {}, true);
446
+ this.setGroupRules(mRules);
402
447
  this.renderSummaryCollapse();
403
448
  }
404
- groupElem.style.display = 'block';
405
- }
449
+ else {
450
+ const groupElem = this.element.querySelector('.e-group-container');
451
+ if (groupElem.querySelectorAll('.e-collapse-rule').length < 1) {
452
+ this.renderSummaryCollapse();
453
+ }
454
+ groupElem.style.display = 'block';
455
+ }
456
+ break;
406
457
  }
407
458
  }
408
459
  else if ((target.tagName === 'LABEL' && target.parentElement.className.indexOf('e-btn-group') > -1) ||
@@ -502,7 +553,18 @@ let QueryBuilder = class QueryBuilder extends Component {
502
553
  else {
503
554
  ruleElem = this.createElement('div', { attrs: { class: 'e-rule-container' } });
504
555
  ruleElem.setAttribute('id', target.id + '_rule' + this.ruleIdCounter);
505
- ruleListElem.appendChild(ruleElem);
556
+ if (this.showButtons.cloneRule && this.cloneRuleBtnClick) {
557
+ if (this.ruleIndex < 0) {
558
+ ruleListElem.appendChild(ruleElem);
559
+ }
560
+ else {
561
+ ruleListElem.insertBefore(ruleElem, ruleListElem.children[this.ruleIndex + 1]); // added clone rule to next position
562
+ }
563
+ this.cloneRuleBtnClick = false;
564
+ }
565
+ else {
566
+ ruleListElem.appendChild(ruleElem);
567
+ }
506
568
  this.ruleIdCounter++;
507
569
  }
508
570
  if (column && column.ruleTemplate && rule) {
@@ -552,6 +614,21 @@ let QueryBuilder = class QueryBuilder extends Component {
552
614
  elem = this.ruleElem.querySelector('.e-rule-field').cloneNode(true);
553
615
  ruleElem.appendChild(elem);
554
616
  }
617
+ if (this.showButtons.lockGroup) {
618
+ removeClass(ruleElem.querySelectorAll('.e-lock-grp-btn'), 'e-button-hide');
619
+ }
620
+ if (this.showButtons.lockRule) {
621
+ removeClass(ruleElem.querySelectorAll('.e-lock-rule-btn'), 'e-button-hide');
622
+ }
623
+ if (this.showButtons.cloneGroup) {
624
+ removeClass(ruleElem.querySelectorAll('.e-clone-grp-btn'), 'e-button-hide');
625
+ }
626
+ if (this.showButtons.cloneRule) {
627
+ removeClass(ruleElem.querySelectorAll('.e-clone-rule-btn'), 'e-button-hide');
628
+ }
629
+ if (this.showButtons.ruleDelete) {
630
+ removeClass(ruleElem.querySelectorAll('.e-lock-grp-btn'), 'e-button-hide');
631
+ }
555
632
  if (column && column.ruleTemplate && rule) {
556
633
  this.renderReactTemplates();
557
634
  }
@@ -594,7 +671,7 @@ let QueryBuilder = class QueryBuilder extends Component {
594
671
  else {
595
672
  ruleElem = this.appendRuleElem(trgt, column, act, pId, 'field');
596
673
  ruleElem.querySelector('.e-filter-input').setAttribute('id', ruleElem.id + '_filterkey');
597
- let element = ruleElem.querySelector('button');
674
+ const element = ruleElem.querySelector('.e-rule-delete');
598
675
  if (this.element.className.indexOf('e-device') > -1 || this.displayMode === 'Vertical') {
599
676
  element.textContent = this.l10n.getConstant('Remove');
600
677
  addClass([element], 'e-flat');
@@ -604,8 +681,11 @@ let QueryBuilder = class QueryBuilder extends Component {
604
681
  addClass([element], 'e-round');
605
682
  addClass([element], 'e-icon-btn');
606
683
  element.setAttribute('title', this.l10n.getConstant('DeleteRule'));
607
- element = this.createElement('span', { attrs: { class: 'e-btn-icon e-icons e-delete-icon' } });
608
- ruleElem.querySelector('button').appendChild(element);
684
+ const spanElement = this.createElement('span', { attrs: { class: 'e-btn-icon e-icons e-delete-icon' } });
685
+ ruleElem.querySelector('.e-rule-delete').appendChild(spanElement);
686
+ }
687
+ if (!this.showButtons.ruleDelete) {
688
+ element.classList.add('e-button-hide');
609
689
  }
610
690
  }
611
691
  if (this.displayMode === 'Vertical' || this.element.className.indexOf('e-device') > -1) {
@@ -636,6 +716,9 @@ let QueryBuilder = class QueryBuilder extends Component {
636
716
  if (this.separator && rule.field) {
637
717
  ddlValue = this.GetRootColumnName(rule.field);
638
718
  }
719
+ else if (this.autoSelectField) {
720
+ ddlValue = this.GetRootColumnName(rule.field);
721
+ }
639
722
  else {
640
723
  ddlValue = this.isImportRules ? this.GetRootColumnName(rule.field) : rule.field;
641
724
  }
@@ -643,8 +726,7 @@ let QueryBuilder = class QueryBuilder extends Component {
643
726
  dataSource: this.columns,
644
727
  fields: this.fields, placeholder: this.l10n.getConstant('SelectField'),
645
728
  popupHeight: ((this.columns.length > 5) ? height : 'auto'), close: this.fieldClose.bind(this, ruleElem.id + '_filterkey'),
646
- change: this.changeField.bind(this), value: rule ? ddlValue : null, open: this.popupOpen.bind(this, true),
647
- cssClass: 'qb-dropdownlist'
729
+ change: this.changeField.bind(this), value: rule ? ddlValue : null, open: this.popupOpen.bind(this, true), cssClass: 'qb-dropdownlist'
648
730
  };
649
731
  if (this.fieldModel) {
650
732
  ddlField = Object.assign({}, ddlField, this.fieldModel);
@@ -734,12 +816,23 @@ let QueryBuilder = class QueryBuilder extends Component {
734
816
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
735
817
  const custom = rule.custom;
736
818
  if (Object.keys(rule).length) {
737
- rules.rules.push({
738
- 'field': rule.field, 'type': rule.type, 'label': rule.label, 'operator': rule.operator, value: rule.value
739
- });
740
- if (custom) {
741
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
742
- rules.rules[rules.rules.length - 1].custom = custom;
819
+ if (this.ruleIndex < 0) {
820
+ rules.rules.push({
821
+ 'field': rule.field, 'type': rule.type, 'label': rule.label, 'operator': rule.operator, value: rule.value
822
+ });
823
+ if (custom) {
824
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
825
+ rules.rules[rules.rules.length - 1].custom = custom;
826
+ }
827
+ }
828
+ else {
829
+ rules.rules.splice(this.ruleIndex + 1, 0, {
830
+ 'field': rule.field, 'type': rule.type, 'label': rule.label, 'operator': rule.operator, value: rule.value
831
+ });
832
+ if (custom) {
833
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
834
+ rules.rules[this.ruleIndex + 1].custom = custom;
835
+ }
743
836
  }
744
837
  }
745
838
  else {
@@ -747,6 +840,9 @@ let QueryBuilder = class QueryBuilder extends Component {
747
840
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
748
841
  newRule.custom = custom;
749
842
  }
843
+ if (this.autoSelectField) {
844
+ rule.field = newRule.field = this.rule.rules[0].field;
845
+ }
750
846
  rules.rules.push(newRule);
751
847
  }
752
848
  }
@@ -946,6 +1042,8 @@ let QueryBuilder = class QueryBuilder extends Component {
946
1042
  ruleTemplate() {
947
1043
  let tempElem;
948
1044
  let clsName;
1045
+ let cloneClsName;
1046
+ let lockClsName;
949
1047
  const ruleElem = this.createElement('div');
950
1048
  const fieldElem = this.createElement('div', { attrs: { class: 'e-rule-field' } });
951
1049
  tempElem = this.createElement('div', { attrs: { class: 'e-rule-filter' } });
@@ -957,6 +1055,24 @@ let QueryBuilder = class QueryBuilder extends Component {
957
1055
  tempElem = this.createElement('div', { attrs: { class: 'e-rule-value' } });
958
1056
  fieldElem.appendChild(tempElem);
959
1057
  tempElem = this.createElement('div', { attrs: { class: 'e-rule-value-delete' } });
1058
+ if (this.showButtons.cloneRule) {
1059
+ cloneClsName = 'e-clone-rule-btn e-clone-rule e-css e-btn e-small e-round e-icon-btn';
1060
+ }
1061
+ else {
1062
+ cloneClsName = 'e-clone-rule-btn e-clone-rule e-css e-btn e-small e-round e-icon-btn e-button-hide';
1063
+ }
1064
+ if (this.showButtons.lockRule) {
1065
+ lockClsName = 'e-lock-rule-btn e-lock-rule e-css e-btn e-small e-round e-icons e-icon-btn';
1066
+ }
1067
+ else {
1068
+ lockClsName = 'e-lock-rule-btn e-lock-rule e-css e-btn e-small e-round e-icons e-icon-btn e-button-hide';
1069
+ }
1070
+ const cloneRuleBtnElem = this.createElement('button', { attrs: { title: this.l10n.getConstant('CloneRule'), type: 'button', class: cloneClsName } });
1071
+ let spanElement = this.createElement('span', { attrs: { class: 'e-btn-icon e-icons e-copy' } });
1072
+ cloneRuleBtnElem.appendChild(spanElement);
1073
+ const cloneLockBtnElem = this.createElement('button', { attrs: { title: this.l10n.getConstant('LockRule'), type: 'button', class: lockClsName } });
1074
+ spanElement = this.createElement('span', { attrs: { class: 'e-btn-icon e-icons e-unlock' } });
1075
+ cloneLockBtnElem.appendChild(spanElement);
960
1076
  if (this.showButtons.ruleDelete || isNullOrUndefined(this.showButtons.ruleDelete)) {
961
1077
  clsName = 'e-removerule e-rule-delete e-css e-btn e-small';
962
1078
  }
@@ -964,6 +1080,8 @@ let QueryBuilder = class QueryBuilder extends Component {
964
1080
  clsName = 'e-removerule e-rule-delete e-css e-btn e-small e-button-hide';
965
1081
  }
966
1082
  const delBtnElem = this.createElement('button', { attrs: { type: 'button', class: clsName } });
1083
+ tempElem.appendChild(cloneRuleBtnElem);
1084
+ tempElem.appendChild(cloneLockBtnElem);
967
1085
  tempElem.appendChild(delBtnElem);
968
1086
  fieldElem.appendChild(tempElem);
969
1087
  ruleElem.appendChild(fieldElem);
@@ -1032,9 +1150,6 @@ let QueryBuilder = class QueryBuilder extends Component {
1032
1150
  button.appendTo(dltGroupBtn);
1033
1151
  dltGroupBtn.setAttribute('title', this.l10n.getConstant('DeleteGroup'));
1034
1152
  rippleEffect(dltGroupBtn, { selector: '.deletegroup' });
1035
- if (!this.headerTemplate) {
1036
- groupElem.querySelector('.e-group-action').appendChild(dltGroupBtn);
1037
- }
1038
1153
  const ruleList = target.querySelector('.e-rule-list');
1039
1154
  const childElems = ruleList.children;
1040
1155
  let grpLen = 0;
@@ -1043,20 +1158,72 @@ let QueryBuilder = class QueryBuilder extends Component {
1043
1158
  grpLen += 1;
1044
1159
  }
1045
1160
  }
1046
- ruleList.appendChild(groupElem);
1161
+ if (this.showButtons.cloneGroup && this.cloneGrpBtnClick) {
1162
+ if (this.groupIndex === (childElems.length - 1)) {
1163
+ ruleList.appendChild(groupElem);
1164
+ this.isLastGroup = true;
1165
+ }
1166
+ else {
1167
+ childElems[this.groupIndex + 1].parentNode.insertBefore(groupElem, childElems[this.groupIndex + 1]); // clone the element to nxt element
1168
+ this.isMiddleGroup = true;
1169
+ }
1170
+ }
1171
+ else {
1172
+ ruleList.appendChild(groupElem);
1173
+ }
1047
1174
  const level = this.levelColl[target.id].slice(0);
1048
1175
  level.push(grpLen);
1049
1176
  this.levelColl[groupElem.id] = level;
1177
+ if (this.groupIndex > -1) {
1178
+ this.refreshLevelColl();
1179
+ }
1050
1180
  if (!this.isImportRules) {
1051
1181
  this.isAddSuccess = true;
1052
1182
  this.addGroups([], target.id.replace(this.element.id + '_', ''));
1053
1183
  this.isAddSuccess = false;
1054
- if (isBtnClick) {
1184
+ if (isBtnClick && this.addRuleToNewGroups) {
1055
1185
  this.addRuleElement(groupElem, {});
1056
1186
  }
1057
1187
  }
1188
+ if (!this.headerTemplate) {
1189
+ let lockClsName = '';
1190
+ if (this.showButtons.cloneGroup) {
1191
+ lockClsName = 'e-clone-grp-btn e-css e-btn e-small e-round e-icons e-icon-btn';
1192
+ }
1193
+ else {
1194
+ lockClsName = 'e-clone-grp-btn e-css e-btn e-small e-round e-icons e-icon-btn e-button-hide';
1195
+ }
1196
+ const cloneBtnElem = this.createElement('button', { attrs: { title: this.l10n.getConstant('CloneGroup'), type: 'button', class: lockClsName } });
1197
+ const spanElement = this.createElement('span', { attrs: { class: 'e-btn-icon e-icons e-copy' } });
1198
+ cloneBtnElem.appendChild(spanElement);
1199
+ groupElem.querySelector('.e-group-action').appendChild(cloneBtnElem);
1200
+ if (this.showButtons.lockGroup) {
1201
+ lockClsName = 'e-lock-grp-btn e-css e-btn e-small e-round e-icons e-icon-btn';
1202
+ }
1203
+ else {
1204
+ lockClsName = 'e-lock-grp-btn e-css e-btn e-small e-round e-icons e-icon-btn e-button-hide';
1205
+ }
1206
+ const lockBtnElem = this.createElement('button', { attrs: { title: this.l10n.getConstant('LockGroup'), type: 'button', class: lockClsName } });
1207
+ const lockSpanElement = this.createElement('span', { attrs: { class: 'e-btn-icon e-icons e-unlock' } });
1208
+ lockBtnElem.appendChild(lockSpanElement);
1209
+ groupElem.querySelector('.e-group-action').appendChild(lockBtnElem);
1210
+ groupElem.querySelector('.e-group-action').appendChild(dltGroupBtn);
1211
+ }
1058
1212
  }
1059
1213
  else {
1214
+ if (!this.headerTemplate) {
1215
+ let lockClsName = '';
1216
+ if (this.showButtons.lockGroup) {
1217
+ lockClsName = 'e-lock-grp-btn e-css e-btn e-small e-round e-icons e-icon-btn';
1218
+ }
1219
+ else {
1220
+ lockClsName = 'e-lock-grp-btn e-css e-btn e-small e-round e-icons e-icon-btn e-button-hide';
1221
+ }
1222
+ const lockBtnElem = this.createElement('button', { attrs: { title: this.l10n.getConstant('LockGroup'), type: 'button', class: lockClsName } });
1223
+ const spanElement = this.createElement('span', { attrs: { class: 'e-btn-icon e-icons e-unlock' } });
1224
+ lockBtnElem.appendChild(spanElement);
1225
+ groupElem.querySelector('.e-group-action').appendChild(lockBtnElem);
1226
+ }
1060
1227
  target.appendChild(groupElem);
1061
1228
  this.levelColl[groupElem.id] = [0];
1062
1229
  }
@@ -1390,7 +1557,7 @@ let QueryBuilder = class QueryBuilder extends Component {
1390
1557
  this.prevItemData = args.itemData;
1391
1558
  const fieldElem = closest(args.element, '.e-rule-filter') || closest(args.element, '.e-rule-sub-filter');
1392
1559
  const column = this.fieldMode === 'DropdownTree' ? this.getColumn(args.value[0]) : this.getColumn(args.value);
1393
- if (this.fieldMode === 'DropdownTree' && fieldElem != null) {
1560
+ if (this.fieldMode === 'DropdownTree' && fieldElem !== null) {
1394
1561
  const ddtElem = fieldElem.querySelector('.e-dropdowntree.e-control');
1395
1562
  const ddt = getComponent(ddtElem, 'dropdowntree');
1396
1563
  if (column) {
@@ -1462,7 +1629,7 @@ let QueryBuilder = class QueryBuilder extends Component {
1462
1629
  let filterElem = closest(ddlArgs.element, '.e-rule-filter');
1463
1630
  filterElem = filterElem ? filterElem : closest(ddlArgs.element, '.e-rule-sub-filter');
1464
1631
  let ddlObj = getComponent(ddlArgs.element, 'dropdownlist');
1465
- if (this.fieldMode === 'DropdownTree' && filterElem != null) {
1632
+ if (this.fieldMode === 'DropdownTree' && filterElem !== null) {
1466
1633
  ddlObj = getComponent(ddlArgs.element, 'dropdowntree');
1467
1634
  }
1468
1635
  const element = closest(ddlArgs.element, '.e-group-container');
@@ -1589,7 +1756,7 @@ let QueryBuilder = class QueryBuilder extends Component {
1589
1756
  this.GetRootColumnName(rule.field) === this.GetRootColumnName(this.previousColumn.field))) {
1590
1757
  const subField = this.selectedColumn.columns;
1591
1758
  for (let i = 0; i < subField.length; i++) {
1592
- if (rule.field === subField[i].field || rule.field.indexOf(subField[i].field) > -1) {
1759
+ if (rule.field === subField[i].field) {
1593
1760
  dropDownList.value = subField[i].field;
1594
1761
  this.selectedColumn = subField[i];
1595
1762
  subFieldValue = true;
@@ -1628,7 +1795,7 @@ let QueryBuilder = class QueryBuilder extends Component {
1628
1795
  rule.value = [];
1629
1796
  }
1630
1797
  }
1631
- else if (typeof rule.value === 'object' && rule.value != null) {
1798
+ else if (typeof rule.value === 'object' && rule.value !== null) {
1632
1799
  rule.value = rule.value.length > 0 ? rule.value[0] : rule.type === 'number' ? 0 : '';
1633
1800
  }
1634
1801
  if (ddlArgs.previousItemData) {
@@ -1655,6 +1822,9 @@ let QueryBuilder = class QueryBuilder extends Component {
1655
1822
  if (valElem && this.getColumn(rule.field).template) {
1656
1823
  filterElem = operatorElem.previousElementSibling;
1657
1824
  }
1825
+ if (valElem.children.length == 0) {
1826
+ filterElem = operatorElem.previousElementSibling;
1827
+ }
1658
1828
  this.changeRuleValues(filterElem, rule, tempRule, ddlArgs);
1659
1829
  }
1660
1830
  }
@@ -1685,7 +1855,9 @@ let QueryBuilder = class QueryBuilder extends Component {
1685
1855
  tempRule.type = this.fieldMode === 'DropdownTree' ? this.getColumn(fieldObj.value[0]).type :
1686
1856
  this.getColumn(fieldObj.value).type;
1687
1857
  const itemData = ddlArgs.itemData;
1688
- this.renderValues(operatorElem, itemData, ddlArgs.previousItemData, true, rule, tempRule, ddlArgs.element);
1858
+ if (ddlObj.value !== '') {
1859
+ this.renderValues(operatorElem, itemData, ddlArgs.previousItemData, true, rule, tempRule, ddlArgs.element);
1860
+ }
1689
1861
  }
1690
1862
  else {
1691
1863
  const ruleId = closest(operatorElem, '.e-rule-container').id;
@@ -1699,7 +1871,14 @@ let QueryBuilder = class QueryBuilder extends Component {
1699
1871
  }
1700
1872
  const height = (this.element.className.indexOf('e-device') > -1) ? '250px' : '200px';
1701
1873
  let value = operatorList[0].value;
1702
- value = rule ? (rule.operator !== '' ? rule.operator : value) : value;
1874
+ let ddlIdx = 0;
1875
+ if (!this.autoSelectOperator) {
1876
+ value = '';
1877
+ ddlIdx = -1;
1878
+ }
1879
+ if (this.isImportRules || (this.ruleIndex > -1 || this.groupIndex > -1)) {
1880
+ value = rule ? (rule.operator ? rule.operator : value) : value;
1881
+ }
1703
1882
  let ddlOperator;
1704
1883
  ddlOperator = {
1705
1884
  dataSource: operatorList,
@@ -1707,7 +1886,7 @@ let QueryBuilder = class QueryBuilder extends Component {
1707
1886
  placeholder: this.l10n.getConstant('SelectOperator'),
1708
1887
  popupHeight: ((operatorList.length > 5) ? height : 'auto'),
1709
1888
  change: this.changeField.bind(this),
1710
- index: 0,
1889
+ index: ddlIdx,
1711
1890
  value: value,
1712
1891
  open: this.popupOpen.bind(this, false)
1713
1892
  };
@@ -1721,7 +1900,12 @@ let QueryBuilder = class QueryBuilder extends Component {
1721
1900
  tempRule.type = this.selectedColumn.type;
1722
1901
  tempRule.operator = rule.operator;
1723
1902
  }
1724
- this.renderValues(operatorElem, this.selectedColumn, ddlArgs.previousItemData, false, rule, tempRule, ddlArgs.element);
1903
+ if (!isNullOrUndefined(value) && value !== '') {
1904
+ this.renderValues(operatorElem, this.selectedColumn, ddlArgs.previousItemData, false, rule, tempRule, ddlArgs.element);
1905
+ }
1906
+ else if (this.autoSelectField && this.autoSelectOperator) {
1907
+ this.renderValues(operatorElem, this.selectedColumn, ddlArgs.previousItemData, false, rule, tempRule, ddlArgs.element);
1908
+ }
1725
1909
  }
1726
1910
  }
1727
1911
  if (!this.isImportRules) {
@@ -1938,17 +2122,11 @@ let QueryBuilder = class QueryBuilder extends Component {
1938
2122
  if (!this.dataColl.length && values.length) {
1939
2123
  isValues = true;
1940
2124
  }
1941
- let fieldValue = this.selectedRule.field;
1942
- const isNested = this.selectedRule.field.indexOf(this.separator);
1943
- if (isNested !== 0 && this.fieldMode !== 'DropdownTree') {
1944
- const nest = this.selectedRule.field.split(this.separator);
1945
- fieldValue = nest[nest.length - 1];
1946
- }
1947
2125
  let multiSelectValue;
1948
2126
  multiSelectValue = {
1949
2127
  dataSource: isValues ? values : (isFetched ? ds : this.dataManager),
1950
2128
  query: new Query([rule.field]),
1951
- fields: { text: fieldValue, value: fieldValue },
2129
+ fields: { text: this.selectedRule.field, value: this.selectedRule.field },
1952
2130
  placeholder: this.l10n.getConstant('SelectValue'),
1953
2131
  value: selectedValue,
1954
2132
  mode: 'CheckBox',
@@ -2078,14 +2256,14 @@ let QueryBuilder = class QueryBuilder extends Component {
2078
2256
  const columnData = this.getItemData(parentId);
2079
2257
  let selectedValue;
2080
2258
  const isTemplate = (typeof columnData.template === 'string');
2081
- if (this.isImportRules || this.isPublic || isTemplate) {
2259
+ if (this.isImportRules || this.ruleIndex > -1 || this.groupIndex > -1 || this.isPublic || isTemplate) {
2082
2260
  selectedValue = rule.value;
2083
2261
  }
2084
2262
  else {
2085
2263
  selectedValue = this.setDefaultValue(parentId, false, false);
2086
2264
  }
2087
2265
  if ((operator === 'in' || operator === 'notin') && (this.dataColl.length || columnData.values)) {
2088
- selectedVal = this.isImportRules ? rule.value : this.setDefaultValue(parentId, true, false);
2266
+ selectedVal = (this.isImportRules || this.ruleIndex > -1 || this.groupIndex > -1) ? rule.value : this.setDefaultValue(parentId, true, false);
2089
2267
  this.renderMultiSelect(columnData, parentId, idx, selectedVal, columnData.values);
2090
2268
  if (this.displayMode === 'Vertical' || this.element.className.indexOf('e-device') > -1) {
2091
2269
  ruleValElem.style.width = '100%';
@@ -2097,7 +2275,7 @@ let QueryBuilder = class QueryBuilder extends Component {
2097
2275
  }
2098
2276
  else {
2099
2277
  if (operator === 'in' || operator === 'notin') {
2100
- selectedVal = this.isImportRules ? rule.value : this.setDefaultValue(parentId, true, false);
2278
+ selectedVal = (this.isImportRules || this.ruleIndex > -1 || this.groupIndex > -1) ? rule.value : this.setDefaultValue(parentId, true, false);
2101
2279
  selectedValue = selectedVal.join(',');
2102
2280
  }
2103
2281
  let txtBox;
@@ -2117,9 +2295,9 @@ let QueryBuilder = class QueryBuilder extends Component {
2117
2295
  renderNumberValue(parentId, rule, operator, idx, ruleValElem, itemData, length) {
2118
2296
  const columnData = this.getItemData(parentId);
2119
2297
  const isTemplate = (typeof columnData.template === 'string');
2120
- let selectedVal = (this.isImportRules || this.isPublic || isTemplate) ? rule.value : this.setDefaultValue(parentId, false, true);
2298
+ let selectedVal = (this.isImportRules || this.ruleIndex > -1 || this.groupIndex > -1 || this.isPublic || isTemplate) ? rule.value : this.setDefaultValue(parentId, false, true);
2121
2299
  if ((operator === 'in' || operator === 'notin') && (this.dataColl.length || columnData.values)) {
2122
- selectedVal = this.isImportRules ? rule.value : this.setDefaultValue(parentId, true, false);
2300
+ selectedVal = (this.isImportRules || this.ruleIndex > -1 || this.groupIndex > -1) ? rule.value : this.setDefaultValue(parentId, true, false);
2123
2301
  this.renderMultiSelect(columnData, parentId, idx, selectedVal, columnData.values);
2124
2302
  if (this.element.className.indexOf('e-device') > -1 || this.displayMode === 'Vertical') {
2125
2303
  ruleValElem.style.width = '100%';
@@ -2130,7 +2308,7 @@ let QueryBuilder = class QueryBuilder extends Component {
2130
2308
  }
2131
2309
  }
2132
2310
  else if (operator === 'in' || operator === 'notin') {
2133
- selectedVal = this.isImportRules ? rule.value : this.setDefaultValue(parentId, true, false);
2311
+ selectedVal = (this.isImportRules || this.ruleIndex > -1 || this.groupIndex > -1) ? rule.value : this.setDefaultValue(parentId, true, false);
2134
2312
  const selVal = selectedVal.join(',');
2135
2313
  let txtInp;
2136
2314
  txtInp = {
@@ -2403,8 +2581,8 @@ let QueryBuilder = class QueryBuilder extends Component {
2403
2581
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2404
2582
  : this.getColumn(filtObj.value);
2405
2583
  this.selectedRule = column;
2584
+ const ddlObj = getComponent(target.querySelector('input'), 'dropdownlist');
2406
2585
  if (isRender) {
2407
- const ddlObj = getComponent(target.querySelector('input'), 'dropdownlist');
2408
2586
  itemData = element.id.indexOf('operator') > -1 ? itemData : this.selectedRule;
2409
2587
  if (itemData.operators) {
2410
2588
  ddlObj.value = null;
@@ -2412,7 +2590,13 @@ let QueryBuilder = class QueryBuilder extends Component {
2412
2590
  ddlObj.dataSource = itemData.operators;
2413
2591
  ddlObj.index = this.getOperatorIndex(ddlObj, rule);
2414
2592
  ddlObj.value = tempRule.operator = ddlObj.dataSource[ddlObj.index].value;
2415
- ddlObj.dataBind();
2593
+ if (!this.autoSelectOperator) {
2594
+ ddlObj.index = -1;
2595
+ tempRule.operator = ddlObj.value = '';
2596
+ }
2597
+ else {
2598
+ ddlObj.dataBind();
2599
+ }
2416
2600
  }
2417
2601
  }
2418
2602
  const operator = tempRule.operator.toString();
@@ -2445,39 +2629,41 @@ let QueryBuilder = class QueryBuilder extends Component {
2445
2629
  this.validateValue(rule, closest(target, '.e-rule-container'));
2446
2630
  this.destroyControls(target);
2447
2631
  }
2448
- if (column) {
2449
- itemData.template = column.template;
2450
- }
2451
- if (itemData.template) {
2452
- addClass([target.nextElementSibling], 'e-template-value');
2453
- itemData.template = column.template;
2454
- isTempRendered = this.setColumnTemplate(itemData, parentId, column.field, itemData.value ||
2455
- operator, target, rule);
2456
- }
2457
- if (isTempRendered) {
2458
- const parentElem = target.parentElement.querySelector('.e-rule-value');
2459
- if (this.element.className.indexOf('e-device') > -1 || this.displayMode === 'Vertical') {
2460
- parentElem.style.width = '100%';
2461
- }
2462
- else {
2463
- parentElem.style.width = '200px';
2464
- }
2465
- }
2466
- else {
2467
- removeClass([target.nextElementSibling], 'e-template-value');
2468
- let inputLen = 1;
2469
- if (tempRule.type === 'boolean') {
2470
- inputLen = this.selectedColumn.values ? this.selectedColumn.values.length : 2;
2632
+ if (this.isImportRules || (ddlObj && ddlObj.value !== '')) {
2633
+ if (column) {
2634
+ itemData.template = column.template;
2635
+ }
2636
+ if (itemData.template) {
2637
+ addClass([target.nextElementSibling], 'e-template-value');
2638
+ itemData.template = column.template;
2639
+ isTempRendered = this.setColumnTemplate(itemData, parentId, column.field, itemData.value ||
2640
+ operator, target, rule);
2641
+ }
2642
+ if (isTempRendered) {
2643
+ const parentElem = target.parentElement.querySelector('.e-rule-value');
2644
+ if (this.element.className.indexOf('e-device') > -1 || this.displayMode === 'Vertical') {
2645
+ parentElem.style.width = '100%';
2646
+ }
2647
+ else {
2648
+ parentElem.style.width = '200px';
2649
+ }
2471
2650
  }
2472
2651
  else {
2473
- inputLen = (operator && operator.toLowerCase().indexOf('between') > -1) ? 2 : 1;
2474
- }
2475
- for (let i = 0; i < inputLen; i++) {
2476
- const valElem = this.createElement('input', { attrs: { type: 'text', id: parentId + '_valuekey' + i } });
2477
- target.nextElementSibling.appendChild(valElem);
2652
+ removeClass([target.nextElementSibling], 'e-template-value');
2653
+ let inputLen = 1;
2654
+ if (tempRule.type === 'boolean') {
2655
+ inputLen = this.selectedColumn.values ? this.selectedColumn.values.length : 2;
2656
+ }
2657
+ else {
2658
+ inputLen = (operator && operator.toLowerCase().indexOf('between') > -1) ? 2 : 1;
2659
+ }
2660
+ for (let i = 0; i < inputLen; i++) {
2661
+ const valElem = this.createElement('input', { attrs: { type: 'text', id: parentId + '_valuekey' + i } });
2662
+ target.nextElementSibling.appendChild(valElem);
2663
+ }
2478
2664
  }
2665
+ this.renderControls(target, itemData, rule, tempRule, isTempRendered);
2479
2666
  }
2480
- this.renderControls(target, itemData, rule, tempRule, isTempRendered);
2481
2667
  }
2482
2668
  else {
2483
2669
  const parentElem = target.parentElement.querySelector('.e-rule-value');
@@ -2910,8 +3096,8 @@ let QueryBuilder = class QueryBuilder extends Component {
2910
3096
  let i;
2911
3097
  let len;
2912
3098
  let tooltip;
2913
- let popupElement;
2914
3099
  super.destroy();
3100
+ let popupElement;
2915
3101
  element = this.element.querySelectorAll('.e-addrulegroup');
2916
3102
  len = element.length;
2917
3103
  for (i = 0; i < len; i++) {
@@ -2997,7 +3183,8 @@ let QueryBuilder = class QueryBuilder extends Component {
2997
3183
  if (grouplen) {
2998
3184
  this.isPublic = true;
2999
3185
  for (let i = 0, len = groups.length; i < len; i++) {
3000
- this.updatedRule = { condition: groups[i].condition, not: groups[i].not };
3186
+ this.updatedRule = { isLocked: groups[i].isLocked, condition: groups[i].condition,
3187
+ not: groups[i].not };
3001
3188
  this.importRules(groups[i], groupElem, false, groups[i].not);
3002
3189
  }
3003
3190
  this.isPublic = false;
@@ -3005,15 +3192,27 @@ let QueryBuilder = class QueryBuilder extends Component {
3005
3192
  else {
3006
3193
  let condition = 'and';
3007
3194
  let not = false;
3195
+ let isLocked = false;
3008
3196
  if (this.updatedRule) {
3009
3197
  condition = this.updatedRule.condition;
3010
3198
  not = this.updatedRule.not;
3199
+ isLocked = this.updatedRule.isLocked;
3011
3200
  }
3012
- if (this.enableNotCondition) {
3013
- rule.rules.push({ 'condition': condition, 'not': not, rules: [] });
3201
+ if (this.groupIndex < 0) {
3202
+ if (this.enableNotCondition) {
3203
+ rule.rules.push({ 'condition': condition, 'not': not, rules: [] });
3204
+ }
3205
+ else {
3206
+ rule.rules.push({ 'condition': condition, rules: [] });
3207
+ }
3014
3208
  }
3015
3209
  else {
3016
- rule.rules.push({ 'condition': condition, rules: [] });
3210
+ if (this.enableNotCondition) {
3211
+ rule.rules.splice(this.groupIndex + 1, 0, { condition: condition, not: not, rules: [], isLocked: isLocked });
3212
+ }
3213
+ else {
3214
+ rule.rules.splice(this.groupIndex + 1, 0, { condition: condition, rules: [], isLocked: isLocked });
3215
+ }
3017
3216
  }
3018
3217
  }
3019
3218
  if (!this.headerTemplate) {
@@ -3195,17 +3394,53 @@ let QueryBuilder = class QueryBuilder extends Component {
3195
3394
  this.refresh();
3196
3395
  break;
3197
3396
  case 'showButtons':
3198
- if (newProp.showButtons.ruleDelete) {
3199
- removeClass(this.element.querySelectorAll('.e-rule-delete'), 'e-button-hide');
3397
+ if (!isNullOrUndefined(newProp.showButtons.lockGroup)) {
3398
+ if (newProp.showButtons.lockGroup) {
3399
+ removeClass(this.element.querySelectorAll('.e-lock-grp-btn'), 'e-button-hide');
3400
+ }
3401
+ else {
3402
+ addClass(this.element.querySelectorAll('.e-lock-grp-btn'), 'e-button-hide');
3403
+ }
3200
3404
  }
3201
- else {
3202
- addClass(this.element.querySelectorAll('.e-rule-delete'), 'e-button-hide');
3405
+ if (!isNullOrUndefined(newProp.showButtons.lockRule)) {
3406
+ if (newProp.showButtons.lockRule) {
3407
+ removeClass(this.element.querySelectorAll('.e-lock-rule-btn'), 'e-button-hide');
3408
+ }
3409
+ else {
3410
+ addClass(this.element.querySelectorAll('.e-lock-rule-btn'), 'e-button-hide');
3411
+ }
3203
3412
  }
3204
- if (newProp.showButtons.groupDelete) {
3205
- removeClass(this.element.querySelectorAll('.e-deletegroup'), 'e-button-hide');
3413
+ if (!isNullOrUndefined(newProp.showButtons.cloneGroup)) {
3414
+ if (newProp.showButtons.cloneGroup) {
3415
+ removeClass(this.element.querySelectorAll('.e-clone-grp-btn'), 'e-button-hide');
3416
+ }
3417
+ else {
3418
+ addClass(this.element.querySelectorAll('.e-clone-grp-btn'), 'e-button-hide');
3419
+ }
3206
3420
  }
3207
- else {
3208
- addClass(this.element.querySelectorAll('.e-deletegroup'), 'e-button-hide');
3421
+ if (!isNullOrUndefined(newProp.showButtons.cloneRule)) {
3422
+ if (newProp.showButtons.cloneRule) {
3423
+ removeClass(this.element.querySelectorAll('.e-clone-rule-btn'), 'e-button-hide');
3424
+ }
3425
+ else {
3426
+ addClass(this.element.querySelectorAll('.e-clone-rule-btn'), 'e-button-hide');
3427
+ }
3428
+ }
3429
+ if (!isNullOrUndefined(newProp.showButtons.ruleDelete)) {
3430
+ if (newProp.showButtons.ruleDelete) {
3431
+ removeClass(this.element.querySelectorAll('.e-rule-delete'), 'e-button-hide');
3432
+ }
3433
+ else {
3434
+ addClass(this.element.querySelectorAll('.e-rule-delete'), 'e-button-hide');
3435
+ }
3436
+ }
3437
+ if (!isNullOrUndefined(newProp.showButtons.groupDelete)) {
3438
+ if (newProp.showButtons.groupDelete) {
3439
+ removeClass(this.element.querySelectorAll('.e-deletegroup'), 'e-button-hide');
3440
+ }
3441
+ else {
3442
+ addClass(this.element.querySelectorAll('.e-deletegroup'), 'e-button-hide');
3443
+ }
3209
3444
  }
3210
3445
  break;
3211
3446
  case 'cssClass':
@@ -3282,8 +3517,11 @@ let QueryBuilder = class QueryBuilder extends Component {
3282
3517
  this.element.id = this.element.id || getUniqueID('ej2-querybuilder');
3283
3518
  this.defaultLocale = {
3284
3519
  StartsWith: 'Starts With',
3520
+ DoesNotStartWith: 'Does Not Start With',
3285
3521
  EndsWith: 'Ends With',
3522
+ DoesNotEndWith: 'Does Not End With',
3286
3523
  Contains: 'Contains',
3524
+ DoesNotContain: 'Does Not Contain',
3287
3525
  NotLike: 'Not Like',
3288
3526
  Like: 'Like',
3289
3527
  Equal: 'Equal',
@@ -3317,7 +3555,13 @@ let QueryBuilder = class QueryBuilder extends Component {
3317
3555
  IsNotNull: 'Is Not Null',
3318
3556
  True: 'true',
3319
3557
  False: 'false',
3320
- AddButton: 'Add Group/Condition'
3558
+ AddButton: 'Add Group/Condition',
3559
+ CloneGroup: 'Clone Group',
3560
+ LockGroup: 'Lock Group',
3561
+ CloneRule: 'Clone Rule',
3562
+ LockRule: 'Lock Rule',
3563
+ UnlockRule: 'Unlock Rule',
3564
+ UnlockGroup: 'Unlock Group'
3321
3565
  };
3322
3566
  this.l10n = new L10n('querybuilder', this.defaultLocale, this.locale);
3323
3567
  this.intl = new Internationalization(this.locale);
@@ -3330,8 +3574,11 @@ let QueryBuilder = class QueryBuilder extends Component {
3330
3574
  this.customOperators = {
3331
3575
  stringOperator: [
3332
3576
  { value: 'startswith', key: this.l10n.getConstant('StartsWith') },
3577
+ { value: 'notstartswith', key: this.l10n.getConstant('DoesNotStartWith') },
3333
3578
  { value: 'endswith', key: this.l10n.getConstant('EndsWith') },
3579
+ { value: 'notendswith', key: this.l10n.getConstant('DoesNotEndWith') },
3334
3580
  { value: 'contains', key: this.l10n.getConstant('Contains') },
3581
+ { value: 'notcontains', key: this.l10n.getConstant('DoesNotContain') },
3335
3582
  { value: 'equal', key: this.l10n.getConstant('Equal') },
3336
3583
  { value: 'notequal', key: this.l10n.getConstant('NotEqual') },
3337
3584
  { value: 'in', key: this.l10n.getConstant('In') },
@@ -3345,7 +3592,9 @@ let QueryBuilder = class QueryBuilder extends Component {
3345
3592
  { value: 'greaterthanorequal', key: this.l10n.getConstant('GreaterThanOrEqual') },
3346
3593
  { value: 'lessthan', key: this.l10n.getConstant('LessThan') },
3347
3594
  { value: 'lessthanorequal', key: this.l10n.getConstant('LessThanOrEqual') },
3348
- { value: 'notequal', key: this.l10n.getConstant('NotEqual') }
3595
+ { value: 'notequal', key: this.l10n.getConstant('NotEqual') },
3596
+ { value: 'between', key: this.l10n.getConstant('Between') },
3597
+ { value: 'notbetween', key: this.l10n.getConstant('NotBetween') }
3349
3598
  ],
3350
3599
  booleanOperator: [
3351
3600
  { value: 'equal', key: this.l10n.getConstant('Equal') },
@@ -3667,6 +3916,10 @@ let QueryBuilder = class QueryBuilder extends Component {
3667
3916
  this.setProperties({ rule: rule }, true);
3668
3917
  rule = this.getRuleCollection(this.rule, false);
3669
3918
  this.importRules(this.rule, this.element.querySelector('.e-group-container'), true, this.rule.not, isRoot);
3919
+ if (rule.isLocked) {
3920
+ const lockGrpTarget = this.element.querySelector('.e-group-container').querySelector('.e-lock-grp-btn');
3921
+ this.groupLock(lockGrpTarget);
3922
+ }
3670
3923
  this.isImportRules = false;
3671
3924
  }
3672
3925
  keyBoardHandler(e) {
@@ -3762,7 +4015,8 @@ let QueryBuilder = class QueryBuilder extends Component {
3762
4015
  rule.value !== undefined)) || (customObj && customObj.isQuestion)) {
3763
4016
  const condition = rule.condition;
3764
4017
  rule = {
3765
- 'label': rule.label, 'field': rule.field, 'operator': rule.operator, 'type': rule.type, 'value': rule.value
4018
+ 'label': rule.label, 'field': rule.field, 'operator': rule.operator, 'type': rule.type, 'value': rule.value,
4019
+ 'isLocked': rule.isLocked
3766
4020
  };
3767
4021
  if (condition) {
3768
4022
  rule.condition = condition;
@@ -3771,6 +4025,7 @@ let QueryBuilder = class QueryBuilder extends Component {
3771
4025
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3772
4026
  rule.custom = customObj;
3773
4027
  }
4028
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3774
4029
  if ((rule.operator === 'in' || rule.operator === 'notin') && rule.value && rule.value.length === 0) {
3775
4030
  rule = {};
3776
4031
  }
@@ -3796,10 +4051,10 @@ let QueryBuilder = class QueryBuilder extends Component {
3796
4051
  }
3797
4052
  else {
3798
4053
  if (this.enableNotCondition) {
3799
- rule = { 'condition': rule.condition, 'rules': rule.rules, 'not': rule.not };
4054
+ rule = { 'condition': rule.condition, 'rules': rule.rules, 'not': rule.not, 'isLocked': rule.isLocked };
3800
4055
  }
3801
4056
  else {
3802
- rule = { 'condition': rule.condition, 'rules': rule.rules };
4057
+ rule = { 'condition': rule.condition, 'rules': rule.rules, 'isLocked': rule.isLocked };
3803
4058
  }
3804
4059
  if (customObj) {
3805
4060
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -3964,11 +4219,20 @@ let QueryBuilder = class QueryBuilder extends Component {
3964
4219
  let ruleValue;
3965
4220
  let ignoreCase = false;
3966
4221
  let column;
3967
- const ignoreOper = ['notcontains', 'notstartswith', 'notendswith'];
3968
4222
  if (!ruleColl) {
3969
4223
  return pred;
3970
4224
  }
3971
4225
  for (let i = 0, len = ruleColl.length; i < len; i++) {
4226
+ let operator = ruleColl[i].operator;
4227
+ if (operator === 'notstartswith') {
4228
+ operator = 'doesnotstartwith';
4229
+ }
4230
+ else if (operator === 'notendswith') {
4231
+ operator = 'doesnotendwith';
4232
+ }
4233
+ else if (operator === 'notcontains') {
4234
+ operator = 'doesnotcontain';
4235
+ }
3972
4236
  const keys = Object.keys(ruleColl[i]);
3973
4237
  ignoreCase = false;
3974
4238
  if (keys.indexOf('rules') > -1 && ruleColl[i].rules) {
@@ -3987,7 +4251,7 @@ let QueryBuilder = class QueryBuilder extends Component {
3987
4251
  }
3988
4252
  }
3989
4253
  }
3990
- else if (!isNullOrUndefined(ruleColl[i].operator) && !isNullOrUndefined(ruleColl[i].operator.length)) {
4254
+ else if (!isNullOrUndefined(operator) && !isNullOrUndefined(operator.length)) {
3991
4255
  const oper = ruleColl[i].operator.toLowerCase();
3992
4256
  let isDateFilter = false;
3993
4257
  const dateOperColl = ['equal', 'notequal', 'greaterthan', 'greaterthanorequal', 'lessthan', 'lessthanorequal'];
@@ -4018,23 +4282,20 @@ let QueryBuilder = class QueryBuilder extends Component {
4018
4282
  }
4019
4283
  if (i === 0) {
4020
4284
  if (isDateFilter || (oper.indexOf('in') > -1 || oper.indexOf('between') > -1 || oper.indexOf('null') > -1 ||
4021
- oper.indexOf('empty') > -1) && oper.indexOf('contains') < 0) {
4285
+ oper.indexOf('empty') > -1) && (oper.indexOf('contain') < 0)) {
4022
4286
  pred = isDateFilter ? this.datePredicate(ruleColl[i], ruleValue) :
4023
4287
  this.arrayPredicate(ruleColl[i]);
4024
4288
  }
4025
4289
  else {
4026
4290
  const value = ruleValue;
4027
- if (value !== '' && ignoreOper.indexOf(oper) < 0) {
4028
- pred = new Predicate(ruleColl[i].field, ruleColl[i].operator, ruleValue, ignoreCase);
4291
+ if (value !== '') {
4292
+ pred = new Predicate(ruleColl[i].field, operator, ruleValue, ignoreCase);
4029
4293
  }
4030
4294
  }
4031
4295
  }
4032
4296
  else {
4033
- if (ignoreOper.indexOf(oper) > -1) {
4034
- continue;
4035
- }
4036
4297
  if (isDateFilter || (oper.indexOf('in') > -1 || oper.indexOf('between') > -1 ||
4037
- oper.indexOf('null') > -1 || oper.indexOf('empty') > -1) && oper.indexOf('contains') < 0) {
4298
+ oper.indexOf('null') > -1 || oper.indexOf('empty') > -1) && oper.indexOf('contain') < 0) {
4038
4299
  pred = isDateFilter ? this.datePredicate(ruleColl[i], ruleValue, pred, rule.condition) :
4039
4300
  this.arrayPredicate(ruleColl[i], pred, rule.condition);
4040
4301
  }
@@ -4043,19 +4304,19 @@ let QueryBuilder = class QueryBuilder extends Component {
4043
4304
  const value = ruleValue;
4044
4305
  if (pred && value !== '') {
4045
4306
  pred
4046
- = pred.and(ruleColl[i].field, ruleColl[i].operator, ruleValue, ignoreCase);
4307
+ = pred.and(ruleColl[i].field, operator, ruleValue, ignoreCase);
4047
4308
  }
4048
4309
  else if (value !== '') {
4049
- pred = new Predicate(ruleColl[i].field, ruleColl[i].operator, ruleValue, ignoreCase);
4310
+ pred = new Predicate(ruleColl[i].field, operator, ruleValue, ignoreCase);
4050
4311
  }
4051
4312
  }
4052
4313
  else {
4053
4314
  const value = ruleValue;
4054
4315
  if (pred && value !== '') {
4055
- pred = pred.or(ruleColl[i].field, ruleColl[i].operator, ruleValue, ignoreCase);
4316
+ pred = pred.or(ruleColl[i].field, operator, ruleValue, ignoreCase);
4056
4317
  }
4057
4318
  else if (value !== '') {
4058
- pred = new Predicate(ruleColl[i].field, ruleColl[i].operator, ruleValue, ignoreCase);
4319
+ pred = new Predicate(ruleColl[i].field, operator, ruleValue, ignoreCase);
4059
4320
  }
4060
4321
  }
4061
4322
  }
@@ -4335,15 +4596,28 @@ let QueryBuilder = class QueryBuilder extends Component {
4335
4596
  for (let i = 0, len = ruleColl.length; i < len; i++) {
4336
4597
  const keys = Object.keys(ruleColl[i]);
4337
4598
  if (!isNullOrUndefined(ruleColl[i].rules) && keys.indexOf('rules') > -1 && (ruleColl[i].rules.length !== 0)) {
4599
+ if (this.element.querySelectorAll('.e-group-container').length > this.maxGroupCount) {
4600
+ return null;
4601
+ }
4338
4602
  parentElem = this.renderGroup(ruleColl[i], ruleColl[i].condition, parentElem, ruleColl[i].not);
4339
4603
  parentElem = this.importRules(ruleColl[i], parentElem, true);
4340
4604
  }
4341
4605
  else {
4342
4606
  this.renderRule(ruleColl[i], parentElem);
4343
4607
  }
4608
+ if (!isNullOrUndefined(ruleColl[i].rules) && ruleColl[i].isLocked) {
4609
+ const lockGrpTarget = parentElem.querySelector('.e-rule-list').children[i].querySelector('.e-lock-grp-btn');
4610
+ this.groupLock(lockGrpTarget);
4611
+ }
4612
+ if (isNullOrUndefined(ruleColl[i].rules) && ruleColl[i].isLocked) {
4613
+ const lockRuleTarget = parentElem.querySelector('.e-rule-list').children[i].querySelector('.e-lock-rule-btn');
4614
+ this.ruleLock(lockRuleTarget);
4615
+ }
4344
4616
  }
4345
4617
  }
4346
- parentElem = closest(parentElem, '.e-rule-list');
4618
+ if (parentElem) {
4619
+ parentElem = closest(parentElem, '.e-rule-list');
4620
+ }
4347
4621
  if (parentElem) {
4348
4622
  parentElem = closest(parentElem, '.e-group-container');
4349
4623
  }
@@ -4352,7 +4626,20 @@ let QueryBuilder = class QueryBuilder extends Component {
4352
4626
  renderGroup(rule, condition, parentElem, not, isRoot) {
4353
4627
  this.addGroupElement(true, parentElem, condition, false, not, isRoot, rule); //Child group
4354
4628
  const element = parentElem.querySelectorAll('.e-group-container');
4355
- return element[element.length - 1];
4629
+ const cloneElem = parentElem.querySelector('.e-rule-list').children;
4630
+ if (this.showButtons.cloneGroup && this.cloneGrpBtnClick && this.isMiddleGroup) {
4631
+ this.isMiddleGroup = false;
4632
+ this.cloneGrpBtnClick = false;
4633
+ return cloneElem[this.groupIndex + 1]; // group added in the middle
4634
+ }
4635
+ else if (this.showButtons.cloneGroup && this.cloneGrpBtnClick && this.isLastGroup) {
4636
+ this.isLastGroup = false;
4637
+ this.cloneGrpBtnClick = false;
4638
+ return cloneElem[cloneElem.length - 1]; // group added in the end
4639
+ }
4640
+ else {
4641
+ return element[element.length - 1];
4642
+ }
4356
4643
  }
4357
4644
  renderRule(rule, parentElem) {
4358
4645
  if (parentElem.className.indexOf('e-group-container') > -1) {
@@ -4550,15 +4837,19 @@ let QueryBuilder = class QueryBuilder extends Component {
4550
4837
  valueStr += rule.value ? '("%' + rule.value + '%")' : '(' + rule.value + ')';
4551
4838
  }
4552
4839
  else {
4553
- if (rule.type === 'number' || typeof rule.value === 'boolean' || rule.value === null) {
4840
+ if (rule.type === 'number' || typeof rule.value === 'boolean' ||
4841
+ (rule.value === null && (rule.operator.toString().indexOf('empty') < -1))) {
4554
4842
  valueStr += rule.value;
4555
4843
  }
4844
+ else if (rule.operator.toString().indexOf('empty') > -1) {
4845
+ valueStr += '""';
4846
+ }
4556
4847
  else {
4557
4848
  valueStr += '"' + rule.value + '"';
4558
4849
  }
4559
4850
  }
4560
4851
  }
4561
- if (rule.operator.toString().indexOf('null') > -1 || (rule.operator.toString().indexOf('empty') > -1)) {
4852
+ if (rule.operator.toString().indexOf('null') > -1) {
4562
4853
  if (enableEscape) {
4563
4854
  rule.field = '`' + rule.field + '`';
4564
4855
  }
@@ -4570,6 +4861,13 @@ let QueryBuilder = class QueryBuilder extends Component {
4570
4861
  queryStr += rule.field + ' ' + ruleOpertor;
4571
4862
  }
4572
4863
  else {
4864
+ let custOper = ruleOpertor;
4865
+ if (rule.operator === 'isempty') {
4866
+ custOper = '=';
4867
+ }
4868
+ else if (rule.operator === 'isnotempty') {
4869
+ custOper = '!=';
4870
+ }
4573
4871
  if (enableEscape) {
4574
4872
  rule.field = '`' + rule.field + '`';
4575
4873
  }
@@ -4578,7 +4876,7 @@ let QueryBuilder = class QueryBuilder extends Component {
4578
4876
  rule.field = '"' + rule.field + '"';
4579
4877
  }
4580
4878
  }
4581
- queryStr += rule.field + ' ' + ruleOpertor + ' ' + valueStr;
4879
+ queryStr += rule.field + ' ' + custOper + ' ' + valueStr;
4582
4880
  }
4583
4881
  if (rule.condition && rule.condition !== '') {
4584
4882
  condition = rule.condition;
@@ -4608,7 +4906,7 @@ let QueryBuilder = class QueryBuilder extends Component {
4608
4906
  * Sets the rules from the sql query.
4609
4907
  *
4610
4908
  * @param {string} sqlString - 'sql String' to be passed to set the rule.
4611
- * @param {boolean} sqlLocale - Set `true` if Localization for Sql query.
4909
+ * @param {boolean} sqlLocale - Optional. Set `true` if Localization for Sql query.
4612
4910
  * @returns {void}
4613
4911
  */
4614
4912
  setRulesFromSql(sqlString, sqlLocale) {
@@ -4640,15 +4938,173 @@ let QueryBuilder = class QueryBuilder extends Component {
4640
4938
  *
4641
4939
  * @param {RuleModel} rule - 'rule' to be passed to get the sql.
4642
4940
  * @param {boolean} allowEscape - Set `true` if it exclude the escape character.
4643
- * @param {boolean} sqlLocale - Set `true` if Localization for Sql query.
4644
- * @returns {object} - Sql query from rules.
4941
+ * @param {boolean} sqlLocale - Set `true` if Localization for Sql query.
4942
+ * @returns {string} - Sql query from rules.
4645
4943
  */
4646
4944
  getSqlFromRules(rule, allowEscape, sqlLocale) {
4647
4945
  if (!rule) {
4648
4946
  rule = this.getValidRules();
4649
4947
  }
4650
4948
  rule = this.getRuleCollection(rule, false);
4651
- return this.getSqlString(this.getValidRules(rule), allowEscape, null, sqlLocale).replace(/"/g, '\'');
4949
+ const sqlString = this.getSqlString(this.getValidRules(rule), allowEscape, null, sqlLocale).replace(/"/g, '\'');
4950
+ return sqlString;
4951
+ }
4952
+ /**
4953
+ * Gets the parameter SQL query from rules.
4954
+ *
4955
+ * @param {RuleModel} rule – Specify the rule to be passed to get the parameter sql string.
4956
+ * @returns {ParameterizedSql} – Parameterized SQL query from rules.
4957
+ */
4958
+ getParameterizedSql(rule) {
4959
+ if (!rule) {
4960
+ rule = this.getValidRules();
4961
+ }
4962
+ const obj = { sql: null };
4963
+ this.notify('query-library', { prop: 'getParameterSql', onPropertyChange: false, value: { rule: rule, obj: obj } });
4964
+ return obj['sql'];
4965
+ }
4966
+ /**
4967
+ * Sets the rules from the parameter sql query.
4968
+ *
4969
+ * @param { ParameterizedSql} sqlQuery – Specifies the parameter SQL to be passed to set the rule and load it to the query builder.
4970
+ * @returns {void}
4971
+ */
4972
+ setParameterizedSql(sqlQuery) {
4973
+ const obj = { sql: null };
4974
+ this.notify('query-library', { prop: 'convertParamSqlToSql', onPropertyChange: false, value: { sql: sqlQuery, obj: obj } });
4975
+ let sql = obj['sql'];
4976
+ if (sql) {
4977
+ sql = sql.replace(/`/g, '');
4978
+ const ruleModel = this.getRulesFromSql(sql);
4979
+ this.setRules({ condition: ruleModel.condition, not: ruleModel.not, rules: ruleModel.rules });
4980
+ }
4981
+ }
4982
+ /**
4983
+ * Gets the named parameter SQL query from rules.
4984
+ *
4985
+ * @param {RuleModel} rule – Specify the rule to be passed to get the named parameter SQL string.
4986
+ * @returns {ParameterizedNamedSql} – Parameterized Named SQL query from rules.
4987
+ */
4988
+ getParameterizedNamedSql(rule) {
4989
+ if (!rule) {
4990
+ rule = this.getValidRules();
4991
+ }
4992
+ const obj = { sql: null };
4993
+ this.notify('query-library', { prop: 'getNamedParameterSql', onPropertyChange: false, value: { rule: rule, obj: obj } });
4994
+ return obj['sql'];
4995
+ }
4996
+ /**
4997
+ * Sets the rules from the named parameter SQL query.
4998
+ *
4999
+ * @param { ParameterizedNamedSql } sqlQuery – Specifies the named parameter SQL to be passed to set the rule and load it to the query builder.
5000
+ * @returns {void}
5001
+ */
5002
+ setParameterizedNamedSql(sqlQuery) {
5003
+ const obj = { sql: null };
5004
+ this.notify('query-library', { prop: 'convertNamedParamSqlToSql', onPropertyChange: false, value: { sql: sqlQuery, obj: obj } });
5005
+ let sql = obj['sql'];
5006
+ if (sql) {
5007
+ sql = sql.replace(/`/g, '');
5008
+ const ruleModel = this.getRulesFromSql(sql);
5009
+ this.setRules({ condition: ruleModel.condition, not: ruleModel.not, rules: ruleModel.rules });
5010
+ }
5011
+ }
5012
+ /**
5013
+ * Set the rules from Mongo query.
5014
+ *
5015
+ * @param {string} mongoQuery - 'sql String' to be passed to get the rule.
5016
+ * @param {boolean} mongoLocale - Set `true` if Localization for Mongo query.
5017
+ * @returns {void}
5018
+ */
5019
+ setMongoQuery(mongoQuery, mongoLocale) {
5020
+ this.rule = { condition: 'and', not: false, rules: [] };
5021
+ this.notify('query-library', { prop: 'mongoParser', onPropertyChange: false, value: { mongoQuery: JSON.parse(mongoQuery), rule: this.rule, mongoLocale: mongoLocale } });
5022
+ }
5023
+ /**
5024
+ * Gets the Mongo query from rules.
5025
+ *
5026
+ * @param {RuleModel} rule - 'rule' to be passed to get the sql.
5027
+ * @returns {object} - Sql query from rules.
5028
+ */
5029
+ getMongoQuery(rule) {
5030
+ if (!rule) {
5031
+ rule = this.getValidRules();
5032
+ }
5033
+ const obj = { mongoQuery: null };
5034
+ this.notify('query-library', { prop: 'getMongoFromRules', onPropertyChange: false, value: { rule: rule, mongoQuery: '', obj: obj } });
5035
+ return obj['mongoQuery'];
5036
+ }
5037
+ /**
5038
+ * Clones the rule based on the rule ID to the specific group.
5039
+ *
5040
+ * @param {string} ruleID - Specifies the ruleID that needs to be cloned.
5041
+ * @param {string} groupID - Specifies the groupID in which the rule to be cloned.
5042
+ * @param {number} index - Specifies the index to insert the cloned rule inside the group.
5043
+ * @returns {void}
5044
+ */
5045
+ cloneRule(ruleID, groupID, index) {
5046
+ const getRule = this.getRule(ruleID.replace(this.element.id + '_', ''));
5047
+ let isCloneRule = this.showButtons.cloneRule;
5048
+ groupID = groupID.replace(this.element.id + '_', '');
5049
+ this.ruleIndex = index;
5050
+ this.cloneRuleBtnClick = true;
5051
+ this.showButtons.cloneRule = true;
5052
+ this.addRules([{
5053
+ 'label': getRule.label, 'field': getRule.field, 'type': getRule.type, 'operator': getRule.operator,
5054
+ 'value': getRule.value
5055
+ }], groupID);
5056
+ this.ruleIndex = -1;
5057
+ this.cloneRuleBtnClick = false;
5058
+ this.showButtons.cloneRule = isCloneRule;
5059
+ isCloneRule = false;
5060
+ }
5061
+ /**
5062
+ * Clones the group based on the group ID to the specific group.
5063
+ *
5064
+ * @param {string} groupID - Specifies the groupID that needs to be cloned.
5065
+ * @param {string} parentGroupID - Specifies the parentGroupID in which the group to be cloned.
5066
+ * @param {number} index - Specifies the index to insert the cloned group inside the parent group.
5067
+ * @returns {void}
5068
+ */
5069
+ cloneGroup(groupID, parentGroupID, index) {
5070
+ parentGroupID = parentGroupID.replace(this.element.id + '_', '');
5071
+ const group = this.getGroup(parentGroupID);
5072
+ let isCloneGroup = this.showButtons.cloneGroup;
5073
+ groupID = groupID.replace(this.element.id + '_', '');
5074
+ this.groupIndex = index;
5075
+ this.cloneGrpBtnClick = true;
5076
+ this.showButtons.cloneGroup = true;
5077
+ this.addGroups([{ 'condition': group.condition, 'not': group.not, 'rules': group.rules }], groupID);
5078
+ this.groupIndex = -1;
5079
+ this.cloneGrpBtnClick = false;
5080
+ this.showButtons.cloneGroup = isCloneGroup;
5081
+ isCloneGroup = false;
5082
+ }
5083
+ /**
5084
+ * Locks the rule based on the rule ID.
5085
+ *
5086
+ * @param {string} ruleID - Specifies the ruleID that needs to be locked.
5087
+ * @returns {void}
5088
+ */
5089
+ lockRule(ruleID) {
5090
+ if (ruleID.indexOf(this.element.id) < 0) {
5091
+ ruleID = this.element.id + '_' + ruleID;
5092
+ }
5093
+ const target = document.getElementById(ruleID).querySelectorAll('.e-lock-rule-btn')[0];
5094
+ this.ruleLock(target);
5095
+ }
5096
+ /**
5097
+ * Locks the group based on the group ID
5098
+ *
5099
+ * @param {string} groupID - Specifies the groupID that needs to be locked.
5100
+ * @returns {void}
5101
+ */
5102
+ lockGroup(groupID) {
5103
+ if (groupID.indexOf(this.element.id) < 0) {
5104
+ groupID = this.element.id + '_' + groupID;
5105
+ }
5106
+ const target = document.getElementById(groupID).querySelectorAll('.e-lock-grp-btn')[0];
5107
+ this.groupLock(target);
4652
5108
  }
4653
5109
  sqlParser(sqlString, sqlLocale) {
4654
5110
  let st = 0;
@@ -4850,13 +5306,13 @@ let QueryBuilder = class QueryBuilder extends Component {
4850
5306
  for (let i = 0; i < localeOperator.length; i++) {
4851
5307
  if (this.sqlOperators[localeOperator[i]] === operator.toUpperCase()) {
4852
5308
  if (value && value.indexOf('%') === 0 && value[value.length - 1] === '%') {
4853
- return (localeOperator[i] === 'notcontains') ? 'notcontains' : 'contains';
5309
+ return (operator.toUpperCase() === 'NOT LIKE') ? 'notcontains' : 'contains';
4854
5310
  }
4855
5311
  else if (value && value.indexOf('%') !== 0 && value.indexOf('%') === value.length - 1) {
4856
- return (localeOperator[i] === 'notstartswith') ? 'notstartswith' : 'startswith';
5312
+ return (operator.toUpperCase() === 'NOT LIKE') ? 'notstartswith' : 'startswith';
4857
5313
  }
4858
5314
  else if (value && value.indexOf('%') === 0 && value.indexOf('%') !== value.length - 1) {
4859
- return (localeOperator[i] === 'notendswith') ? 'notendswith' : 'endswith';
5315
+ return (operator.toUpperCase() === 'NOT LIKE') ? 'notendswith' : 'endswith';
4860
5316
  }
4861
5317
  return localeOperator[i];
4862
5318
  }
@@ -5041,6 +5497,14 @@ let QueryBuilder = class QueryBuilder extends Component {
5041
5497
  }
5042
5498
  else if (parser[i + 1][0] === 'Operators') {
5043
5499
  rule.operator = this.getOperator(parser[i + 2][1], parser[i + 1][1], sqlLocale);
5500
+ if (rule.operator == "equal" && parser[i + 2][0] === "String" && parser[i + 2][1] === "''") {
5501
+ rule.operator = "isempty";
5502
+
5503
+ }
5504
+ else if (rule.operator == "notequal" && parser[i + 2][0] === "String" && parser[i + 2][1] === "''") {
5505
+ rule.operator = "isnotempty";
5506
+
5507
+ }
5044
5508
  if (parser[i + 2][0] === 'Number') {
5045
5509
  rule.type = 'number';
5046
5510
  rule.value = Number(parser[i + 2][1]);
@@ -5097,31 +5561,326 @@ let QueryBuilder = class QueryBuilder extends Component {
5097
5561
  }
5098
5562
  return rules;
5099
5563
  }
5100
- };
5101
- __decorate([
5102
- Event()
5103
- ], QueryBuilder.prototype, "created", void 0);
5104
- __decorate([
5105
- Event()
5106
- ], QueryBuilder.prototype, "actionBegin", void 0);
5107
- __decorate([
5108
- Event()
5109
- ], QueryBuilder.prototype, "beforeChange", void 0);
5110
- __decorate([
5111
- Event()
5112
- ], QueryBuilder.prototype, "change", void 0);
5113
- __decorate([
5114
- Event()
5115
- ], QueryBuilder.prototype, "dataBound", void 0);
5116
- __decorate([
5117
- Event()
5118
- ], QueryBuilder.prototype, "ruleChange", void 0);
5119
- __decorate([
5120
- Property({ ruleDelete: true, groupInsert: true, groupDelete: true })
5121
- ], QueryBuilder.prototype, "showButtons", void 0);
5122
- __decorate([
5123
- Property(false)
5124
- ], QueryBuilder.prototype, "summaryView", void 0);
5564
+ /**
5565
+ * Clone the Group
5566
+ *
5567
+ * @param {Element | string} target - 'target' to be passed to clone the group.
5568
+ * @returns {void}
5569
+ */
5570
+ groupClone(target) {
5571
+ const groupElem = target.closest('.e-rule-list').closest('.e-group-container');
5572
+ let targetGrpId;
5573
+ let groupId;
5574
+ if (typeof target === 'string') {
5575
+ groupId = this.element.id + '_' + target;
5576
+ target = document.getElementById(groupId);
5577
+ }
5578
+ else {
5579
+ targetGrpId = target.id.replace(this.element.id + '_', '');
5580
+ groupId = groupElem.id.replace(this.element.id + '_', '');
5581
+ }
5582
+ const group = this.getGroup(targetGrpId);
5583
+ this.groupIndex = Array.prototype.indexOf.call(target.closest('.e-rule-list').children, target.closest('.e-group-container'));
5584
+ this.addGroups([{ 'condition': group.condition, 'not': group.not, 'rules': group.rules }], groupId);
5585
+ this.groupIndex = -1;
5586
+ }
5587
+ ruleClone(target) {
5588
+ const ruleElem = closest(target, '.e-rule-container');
5589
+ const groupElem = target.closest('.e-rule-list').closest('.e-group-container');
5590
+ const getRule = this.getRule(target);
5591
+ const groupId = groupElem.id.replace(this.element.id + '_', '');
5592
+ const ruleElemColl = groupElem.querySelectorAll('.e-rule-container');
5593
+ for (let i = 0, iLen = ruleElemColl.length; i < iLen; i++) {
5594
+ if (ruleElem.id === ruleElemColl[i].id) {
5595
+ this.ruleIndex = i;
5596
+ }
5597
+ }
5598
+ this.addRules([{ 'label': getRule.label, 'field': getRule.field, 'type': getRule.type, 'operator': getRule.operator,
5599
+ 'value': getRule.value }], groupId);
5600
+ this.ruleIndex = -1;
5601
+ }
5602
+ ruleLock(target) {
5603
+ const ruleElem = closest(target, '.e-rule-container');
5604
+ const rule = this.getRule(ruleElem.id.replace(this.element.id + '_', ''));
5605
+ if (ruleElem.classList.contains('e-disable')) {
5606
+ rule.isLocked = false;
5607
+ this.lockItems = this.lockItems.filter(lockItem => lockItem !== ruleElem.id);
5608
+ ruleElem.classList.remove('e-disable');
5609
+ this.disableRuleControls(target, ruleElem, false);
5610
+ target.children[0].classList.add('e-unlock');
5611
+ target.children[0].classList.remove('e-lock');
5612
+ target.setAttribute('title', this.l10n.getConstant('LockRule'));
5613
+ }
5614
+ else {
5615
+ rule.isLocked = true;
5616
+ if (this.lockItems.indexOf(ruleElem.id) < 0) {
5617
+ this.lockItems.splice(this.lockItems.length - 1, 0, ruleElem.id);
5618
+ }
5619
+ ruleElem.classList.add('e-disable');
5620
+ this.disableRuleControls(target, ruleElem, true);
5621
+ target.children[0].classList.add('e-lock');
5622
+ target.children[0].classList.remove('e-unlock');
5623
+ target.setAttribute('title', this.l10n.getConstant('UnlockRule'));
5624
+ }
5625
+ }
5626
+ groupLock(target) {
5627
+ const groupElem = closest(target, '.e-group-container');
5628
+ let group = this.getGroup(groupElem.id.replace(this.element.id + '_', ''));
5629
+ const isRoot = groupElem.id.indexOf('group0') > -1;
5630
+ if (groupElem.classList.contains('e-disable')) {
5631
+ if (isRoot) {
5632
+ const newGroup = {};
5633
+ newGroup.condition = group.condition;
5634
+ newGroup.not = group.not;
5635
+ newGroup.isLocked = false;
5636
+ this.setProperties({ rule: newGroup }, true);
5637
+ }
5638
+ else {
5639
+ group.isLocked = false;
5640
+ }
5641
+ this.lockItems = this.lockItems.filter(lockItem => lockItem !== groupElem.id);
5642
+ groupElem.classList.remove('e-disable');
5643
+ this.disableHeaderControls(target, groupElem, false);
5644
+ target.children[0].classList.add('e-unlock');
5645
+ target.children[0].classList.remove('e-lock');
5646
+ target.setAttribute('title', this.l10n.getConstant('LockGroup'));
5647
+ this.updateLockItems();
5648
+ }
5649
+ else {
5650
+ if (isRoot) {
5651
+ const newGroup = {};
5652
+ newGroup.condition = group.condition;
5653
+ newGroup.not = group.not;
5654
+ newGroup.isLocked = true;
5655
+ this.setProperties({ rule: newGroup }, true);
5656
+ }
5657
+ else {
5658
+ group.isLocked = true;
5659
+ }
5660
+ if (this.lockItems.indexOf(groupElem.id) < 0) {
5661
+ this.lockItems.splice(this.lockItems.length - 1, 0, groupElem.id);
5662
+ }
5663
+ groupElem.classList.add('e-disable');
5664
+ this.disableHeaderControls(target, groupElem, true);
5665
+ target.children[0].classList.add('e-lock');
5666
+ target.children[0].classList.remove('e-unlock');
5667
+ target.setAttribute('title', this.l10n.getConstant('UnlockGroup'));
5668
+ }
5669
+ }
5670
+ updateLockItems() {
5671
+ for (let i = 0; i < this.lockItems.length; i++) {
5672
+ const idColl = this.lockItems[i].split('_');
5673
+ if (idColl.length > 2) {
5674
+ let ruleElem = this.element.querySelector('#' + this.lockItems[i]);
5675
+ const target = ruleElem.querySelector('.e-lock-rule-btn');
5676
+ ruleElem = closest(target, '.e-rule-container');
5677
+ if (!ruleElem.classList.contains('e-disable')) {
5678
+ this.ruleLock(target);
5679
+ }
5680
+ }
5681
+ else {
5682
+ let groupElem = this.element.querySelector('#' + this.lockItems[i]);
5683
+ const target = groupElem.querySelector('.e-lock-grp-btn');
5684
+ groupElem = closest(target, '.e-group-container');
5685
+ if (!groupElem.classList.contains('e-disable')) {
5686
+ this.groupLock(target);
5687
+ }
5688
+ }
5689
+ }
5690
+ }
5691
+ disableHeaderControls(target, groupElem, isDisabled) {
5692
+ const andElem = groupElem.querySelectorAll('.e-btngroup-and');
5693
+ const orElem = groupElem.querySelectorAll('.e-btngroup-or');
5694
+ const notElem = groupElem.querySelectorAll('.e-qb-toggle');
5695
+ const addElem = groupElem.querySelectorAll('.e-add-btn');
5696
+ const deleteGrpElem = groupElem.querySelectorAll('.e-deletegroup');
5697
+ const lockElem = groupElem.querySelectorAll('.e-lock-grp-btn');
5698
+ const cloneElem = groupElem.querySelectorAll('.e-clone-grp-btn');
5699
+ const groupContElem = groupElem.querySelectorAll('.e-group-container');
5700
+ for (let i = 0; i < andElem.length; i++) {
5701
+ if (isDisabled) {
5702
+ if (groupContElem[i] && groupContElem[i].classList.contains('e-disable')) {
5703
+ groupContElem[i].classList.add('e-disable');
5704
+ }
5705
+ andElem[i].disabled = true;
5706
+ orElem[i].disabled = true;
5707
+ addElem[i].disabled = true;
5708
+ if (notElem[i]) {
5709
+ notElem[i].disabled = true;
5710
+ }
5711
+ if (deleteGrpElem[i]) {
5712
+ deleteGrpElem[i].disabled = true;
5713
+ }
5714
+ if (cloneElem[i]) {
5715
+ cloneElem[i].disabled = true;
5716
+ }
5717
+ andElem[i].parentElement.classList.add('e-disabled');
5718
+ if (lockElem[i] !== target) {
5719
+ lockElem[i].disabled = true;
5720
+ lockElem[i].children[0].classList.remove('e-unlock');
5721
+ lockElem[i].children[0].classList.add('e-lock');
5722
+ }
5723
+ }
5724
+ else {
5725
+ if (groupContElem[i]) {
5726
+ groupContElem[i].classList.remove('e-disable');
5727
+ }
5728
+ andElem[i].disabled = false;
5729
+ orElem[i].disabled = false;
5730
+ addElem[i].disabled = false;
5731
+ lockElem[i].disabled = false;
5732
+ if (notElem[i]) {
5733
+ notElem[i].disabled = false;
5734
+ }
5735
+ if (deleteGrpElem[i]) {
5736
+ deleteGrpElem[i].disabled = false;
5737
+ }
5738
+ if (cloneElem[i]) {
5739
+ cloneElem[i].disabled = false;
5740
+ }
5741
+ andElem[i].parentElement.classList.remove('e-disabled');
5742
+ lockElem[i].children[0].classList.remove('e-lock');
5743
+ lockElem[i].children[0].classList.add('e-unlock');
5744
+ }
5745
+ }
5746
+ this.disableRuleControls(target, groupElem, isDisabled);
5747
+ }
5748
+ disableRuleControls(target, groupElem, isDisabled) {
5749
+ const ddlElement = groupElem.querySelectorAll('.e-control.e-dropdownlist');
5750
+ const numericElement = groupElem.querySelectorAll('.e-control.e-numerictextbox');
5751
+ const textElement = groupElem.querySelectorAll('.e-control.e-textbox');
5752
+ const dateElement = groupElem.querySelectorAll('.e-control.e-datepicker');
5753
+ const checkboxElement = groupElem.querySelectorAll('.e-control.e-checkbox');
5754
+ const radioBtnElement = groupElem.querySelectorAll('.e-control.e-radio');
5755
+ const multiSelectElement = groupElem.querySelectorAll('.e-control.e-multiselect');
5756
+ const deleteElem = groupElem.querySelectorAll('.e-rule-delete');
5757
+ const lockElem = groupElem.querySelectorAll('.e-lock-rule');
5758
+ const cloneElem = groupElem.querySelectorAll('.e-clone-rule');
5759
+ const ruleElem = groupElem.querySelectorAll('.e-rule-container');
5760
+ for (let i = 0; i < deleteElem.length; i++) {
5761
+ if (isDisabled) {
5762
+ if (ruleElem[i] && ruleElem[i].classList.contains('e-disable')) {
5763
+ ruleElem[i].classList.add('e-disable');
5764
+ }
5765
+ deleteElem[i].disabled = true;
5766
+ if (cloneElem[i]) {
5767
+ cloneElem[i].disabled = true;
5768
+ }
5769
+ if (lockElem[i] !== target) {
5770
+ lockElem[i].disabled = true;
5771
+ lockElem[i].children[0].classList.remove('e-unlock');
5772
+ lockElem[i].children[0].classList.add('e-lock');
5773
+ }
5774
+ }
5775
+ else {
5776
+ if (ruleElem[i]) {
5777
+ ruleElem[i].classList.remove('e-disable');
5778
+ }
5779
+ if (cloneElem[i]) {
5780
+ cloneElem[i].disabled = false;
5781
+ }
5782
+ deleteElem[i].disabled = false;
5783
+ lockElem[i].disabled = false;
5784
+ lockElem[i].children[0].classList.remove('e-lock');
5785
+ lockElem[i].children[0].classList.add('e-unlock');
5786
+ }
5787
+ }
5788
+ let dropDownObj;
5789
+ let numericObj;
5790
+ let textObj;
5791
+ let dateObj;
5792
+ let checkBoxObj;
5793
+ let radioBtnObj;
5794
+ let multiSelectObj;
5795
+ for (let i = 0; i < ddlElement.length; i++) {
5796
+ dropDownObj = getComponent(ddlElement[i], 'dropdownlist');
5797
+ if (isDisabled) {
5798
+ dropDownObj.enabled = false;
5799
+ }
5800
+ else {
5801
+ dropDownObj.enabled = true;
5802
+ }
5803
+ }
5804
+ for (let i = 0; i < numericElement.length; i++) {
5805
+ numericObj = getComponent(numericElement[i], 'numerictextbox');
5806
+ if (isDisabled) {
5807
+ numericObj.enabled = false;
5808
+ }
5809
+ else {
5810
+ numericObj.enabled = true;
5811
+ }
5812
+ }
5813
+ for (let i = 0; i < textElement.length; i++) {
5814
+ textObj = getComponent(textElement[i], 'textbox');
5815
+ if (isDisabled) {
5816
+ textObj.enabled = false;
5817
+ }
5818
+ else {
5819
+ textObj.enabled = true;
5820
+ }
5821
+ }
5822
+ for (let i = 0; i < dateElement.length; i++) {
5823
+ dateObj = getComponent(dateElement[i], 'datepicker');
5824
+ if (isDisabled) {
5825
+ dateObj.enabled = false;
5826
+ }
5827
+ else {
5828
+ dateObj.enabled = true;
5829
+ }
5830
+ }
5831
+ for (let i = 0; i < checkboxElement.length; i++) {
5832
+ checkBoxObj = getComponent(checkboxElement[i], 'checkbox');
5833
+ if (isDisabled) {
5834
+ checkBoxObj.disabled = true;
5835
+ }
5836
+ else {
5837
+ checkBoxObj.disabled = false;
5838
+ }
5839
+ }
5840
+ for (let i = 0; i < radioBtnElement.length; i++) {
5841
+ radioBtnObj = getComponent(radioBtnElement[i], 'radio');
5842
+ if (isDisabled) {
5843
+ radioBtnObj.disabled = true;
5844
+ }
5845
+ else {
5846
+ radioBtnObj.disabled = false;
5847
+ }
5848
+ }
5849
+ for (let i = 0; i < multiSelectElement.length; i++) {
5850
+ multiSelectObj = getComponent(multiSelectElement[i], 'multiselect');
5851
+ if (isDisabled) {
5852
+ multiSelectObj.enabled = false;
5853
+ }
5854
+ else {
5855
+ multiSelectObj.enabled = true;
5856
+ }
5857
+ }
5858
+ }
5859
+ };
5860
+ __decorate([
5861
+ Event()
5862
+ ], QueryBuilder.prototype, "created", void 0);
5863
+ __decorate([
5864
+ Event()
5865
+ ], QueryBuilder.prototype, "actionBegin", void 0);
5866
+ __decorate([
5867
+ Event()
5868
+ ], QueryBuilder.prototype, "beforeChange", void 0);
5869
+ __decorate([
5870
+ Event()
5871
+ ], QueryBuilder.prototype, "change", void 0);
5872
+ __decorate([
5873
+ Event()
5874
+ ], QueryBuilder.prototype, "dataBound", void 0);
5875
+ __decorate([
5876
+ Event()
5877
+ ], QueryBuilder.prototype, "ruleChange", void 0);
5878
+ __decorate([
5879
+ Complex({}, ShowButtons)
5880
+ ], QueryBuilder.prototype, "showButtons", void 0);
5881
+ __decorate([
5882
+ Property(false)
5883
+ ], QueryBuilder.prototype, "summaryView", void 0);
5125
5884
  __decorate([
5126
5885
  Property(false)
5127
5886
  ], QueryBuilder.prototype, "allowValidation", void 0);
@@ -5179,6 +5938,15 @@ __decorate([
5179
5938
  __decorate([
5180
5939
  Property(false)
5181
5940
  ], QueryBuilder.prototype, "readonly", void 0);
5941
+ __decorate([
5942
+ Property(true)
5943
+ ], QueryBuilder.prototype, "addRuleToNewGroups", void 0);
5944
+ __decorate([
5945
+ Property(false)
5946
+ ], QueryBuilder.prototype, "autoSelectField", void 0);
5947
+ __decorate([
5948
+ Property(true)
5949
+ ], QueryBuilder.prototype, "autoSelectOperator", void 0);
5182
5950
  __decorate([
5183
5951
  Property('')
5184
5952
  ], QueryBuilder.prototype, "separator", void 0);
@@ -5189,6 +5957,692 @@ QueryBuilder = __decorate([
5189
5957
  NotifyPropertyChanges
5190
5958
  ], QueryBuilder);
5191
5959
 
5960
+ class QueryLibrary {
5961
+ constructor(parent) {
5962
+ this.parent = parent;
5963
+ this.addEventListener();
5964
+ }
5965
+ destroy() {
5966
+ if (this.parent.isDestroyed) {
5967
+ return;
5968
+ }
5969
+ this.removeEventListener();
5970
+ }
5971
+ addEventListener() {
5972
+ if (this.parent.isDestroyed) {
5973
+ return;
5974
+ }
5975
+ this.parent.on('query-library', this.queryLibrary, this);
5976
+ this.parent.on('destroyed', this.destroy, this);
5977
+ }
5978
+ removeEventListener() {
5979
+ this.parent.off('query-library', this.queryLibrary);
5980
+ this.parent.off('destroyed', this.destroy);
5981
+ }
5982
+ queryLibrary(args) {
5983
+ switch (args.prop) {
5984
+ case 'getMongoFromRules':
5985
+ args.value['obj']['mongoQuery'] = this.getMongoFromRules(args.value['rule'], args.value['mongoQuery']);
5986
+ break;
5987
+ case 'mongoParser':
5988
+ this.mongoParser(args.value['mongoQuery'], args.value['rule'], args.value['mongoLocale']);
5989
+ break;
5990
+ case 'getParameterSql':
5991
+ args.value['obj']['sql'] = this.getParameterSql(args.value['rule']);
5992
+ break;
5993
+ case 'getNamedParameterSql':
5994
+ args.value['obj']['sql'] = this.getNamedParameterSql(args.value['rule']);
5995
+ break;
5996
+ case 'convertParamSqlToSql':
5997
+ args.value['obj']['sql'] = this.convertParamSqlToSql(args.value['sql']);
5998
+ break;
5999
+ case 'convertNamedParamSqlToSql':
6000
+ args.value['obj']['sql'] = this.convertNamedParamSqlToSql(args.value['sql']);
6001
+ break;
6002
+ }
6003
+ }
6004
+ getMongoFromRules(rule, mongoQuery) {
6005
+ mongoQuery = '{';
6006
+ if (rule.condition === 'or') {
6007
+ mongoQuery += '"$or":[';
6008
+ mongoQuery = this.convertMongoQuery(rule.rules, mongoQuery) + ']';
6009
+ }
6010
+ else {
6011
+ mongoQuery += '"$and":[';
6012
+ mongoQuery = this.convertMongoQuery(rule.rules, mongoQuery) + ']';
6013
+ }
6014
+ mongoQuery += '}';
6015
+ return mongoQuery;
6016
+ }
6017
+ getOperatorFromMongoOperator(operator) {
6018
+ let operatorValue;
6019
+ switch (operator) {
6020
+ case '$ne':
6021
+ operatorValue = 'notequal';
6022
+ break;
6023
+ case '$gt':
6024
+ operatorValue = 'greaterthan';
6025
+ break;
6026
+ case '$gte':
6027
+ operatorValue = 'greaterthanorequal';
6028
+ break;
6029
+ case '$lt':
6030
+ operatorValue = 'lessthan';
6031
+ break;
6032
+ case '$lte':
6033
+ operatorValue = 'lessthanorequal';
6034
+ break;
6035
+ case '$nin':
6036
+ operatorValue = 'notin';
6037
+ break;
6038
+ }
6039
+ return operatorValue;
6040
+ }
6041
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6042
+ convertMongoQuery(rules, mongoQuery) {
6043
+ let i = 0;
6044
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6045
+ rules.forEach((item) => {
6046
+ i++;
6047
+ mongoQuery += '{';
6048
+ if (item.rules !== undefined) {
6049
+ if (item.condition === 'or') {
6050
+ mongoQuery += ' "$or":[';
6051
+ mongoQuery = this.convertMongoQuery(item.rules, mongoQuery) + ']';
6052
+ }
6053
+ else {
6054
+ mongoQuery += ' "$and":[';
6055
+ mongoQuery = this.convertMongoQuery(item.rules, mongoQuery) + ']';
6056
+ }
6057
+ }
6058
+ let itVal = item.type === 'string' && item.operator !== 'in' && item.operator !== 'notin' && item.value && item.value.trim() !== '' ? item.value.replace(/'/g, '\\') : '';
6059
+ if (item.type === 'string' && (item.operator === 'in' || item.operator === 'notin') && item.value && item.value.length === 1) {
6060
+ itVal = item.value[0].replace(/'/g, '\\');
6061
+ }
6062
+ const field = item.field ? item.field.substring(0) : '';
6063
+ switch (item.operator) {
6064
+ case 'contains':
6065
+ mongoQuery += '"' + field + '":{"$regex":"' + itVal + '"}';
6066
+ break;
6067
+ case 'notcontains':
6068
+ mongoQuery += '"' + field + '":{"$not":{"$regex":"' + item.value + '"}}';
6069
+ break;
6070
+ case 'startswith':
6071
+ mongoQuery += '"' + field + '":{"$regex":"^' + itVal + '"}';
6072
+ break;
6073
+ case 'notstartswith':
6074
+ mongoQuery += '"' + field + '":{"$not":{"$regex":"^' + item.value + '"}}';
6075
+ break;
6076
+ case 'endswith':
6077
+ mongoQuery += '"' + field + '":{"$regex":"' + itVal + '$"}';
6078
+ break;
6079
+ case 'notendswith':
6080
+ mongoQuery += '"' + field + '":{"$not":{"$regex":"' + item.value + '$"}}';
6081
+ break;
6082
+ case 'isnull':
6083
+ mongoQuery += '"' + field + '": null';
6084
+ break;
6085
+ case 'isnotnull':
6086
+ mongoQuery += '"' + field + '":{"$ne": null}';
6087
+ break;
6088
+ case 'isempty':
6089
+ mongoQuery += '"' + field + '": ""';
6090
+ break;
6091
+ case 'isnotempty':
6092
+ mongoQuery += '"' + field + '":{"$ne": ""}';
6093
+ break;
6094
+ case 'equal':
6095
+ if (item.type === 'string') {
6096
+ mongoQuery += '"' + field + '":"' + itVal + '"';
6097
+ }
6098
+ else if (item.type === 'date') {
6099
+ mongoQuery += '"' + field + '":"' + item.value + '"';
6100
+ }
6101
+ else if (item.type === 'boolean') {
6102
+ mongoQuery += '"' + field + '":' + item.value + '';
6103
+ }
6104
+ else {
6105
+ mongoQuery += '"' + field + '":' + item.value + '';
6106
+ }
6107
+ break;
6108
+ case 'notequal':
6109
+ if (item.type === 'string') {
6110
+ mongoQuery += '"' + field + '":{"$ne":"' + itVal + '"}';
6111
+ }
6112
+ else if (item.type === 'date') {
6113
+ mongoQuery += '"' + field + '":{"$ne":"' + item.value + '"}';
6114
+ }
6115
+ else {
6116
+ mongoQuery += '"' + field + '":{"$ne":' + item.value + '}';
6117
+ }
6118
+ break;
6119
+ case 'in':
6120
+ if (item.type === 'string') {
6121
+ if (item.value.length > 1) {
6122
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6123
+ let s = item.value.map((x, j) => (j < item.value.length ? `"${x}"` : '')).toString();
6124
+ s = s.endsWith(',') ? s.substring(0, s.length - 1) : s;
6125
+ mongoQuery += '"' + field + '": { "$in": [' + s + ']}';
6126
+ }
6127
+ else {
6128
+ mongoQuery += '"' + field + '": { "$in": ["' + itVal + '"]}';
6129
+ }
6130
+ }
6131
+ else if (item.type === 'number') {
6132
+ if (item.value.length > 1) {
6133
+ mongoQuery += '"' + field + '": { "$in": [' + item.value.toString() + ']}';
6134
+ }
6135
+ else {
6136
+ mongoQuery += '"' + field + '": { "$in": [' + item.value + ']}';
6137
+ }
6138
+ }
6139
+ break;
6140
+ case 'notin':
6141
+ if (item.type === 'string') {
6142
+ if (item.value.length > 1) {
6143
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6144
+ let s = item.value.map((x, j) => (j < item.value.length ? `"${x}"` : '')).toString();
6145
+ s = s.endsWith(',') ? s.substring(0, s.length - 1) : s;
6146
+ mongoQuery += '"' + field + '": { "$nin": [' + s + ']}';
6147
+ }
6148
+ else {
6149
+ mongoQuery += '"' + field + '": { "$nin": ["' + itVal + '"]}';
6150
+ }
6151
+ }
6152
+ else if (item.type === 'number') {
6153
+ if (item.value.length > 1) {
6154
+ mongoQuery += '"' + field + '": { "$nin": [' + item.value.toString() + ']}';
6155
+ }
6156
+ else {
6157
+ mongoQuery += '"' + field + '": { "$nin": [' + item.value + ']}';
6158
+ }
6159
+ }
6160
+ break;
6161
+ case 'greaterthan':
6162
+ if (item.type === 'number') {
6163
+ mongoQuery += '"' + field + '": { "$gt": ' + item.value + '}';
6164
+ }
6165
+ else {
6166
+ mongoQuery += '"' + field + '": { "$gt": "' + item.value + '"}';
6167
+ }
6168
+ break;
6169
+ case 'greaterthanorequal':
6170
+ if (item.type === 'number') {
6171
+ mongoQuery += '"' + field + '": { "$gte": ' + item.value + '}';
6172
+ }
6173
+ else {
6174
+ mongoQuery += '"' + field + '": { "$gte": "' + item.value + '"}';
6175
+ }
6176
+ break;
6177
+ case 'between':
6178
+ if (item.type === 'number') {
6179
+ mongoQuery += '"' + field + '": {"$gte":' + item.value[0] + ', "$lte":' + item.value[1] + '}';
6180
+ }
6181
+ else {
6182
+ mongoQuery += '"' + field + '": {"$gte": "' + item.value[0] + '", "$lte": "' + item.value[1] + '"}';
6183
+ }
6184
+ break;
6185
+ case 'notbetween':
6186
+ if (item.type === 'number') {
6187
+ mongoQuery += '"$or":[{"' + field + '": {"$lt":' + item.value[0] + '}}, {"' + field + '": {"$gt":' + item.value[1] + '}}]';
6188
+ }
6189
+ else {
6190
+ mongoQuery += '"$or":[{"' + field + '": {"$lt": "' + item.value[0] + '"}}, {"' + field + '": {"$gt": "' + item.value[1] + '"}}]';
6191
+ }
6192
+ break;
6193
+ case 'lessthan':
6194
+ if (item.type === 'number') {
6195
+ mongoQuery += '"' + field + '": { "$lt": ' + item.value + '}';
6196
+ }
6197
+ else {
6198
+ mongoQuery += '"' + field + '": { "$lt": "' + item.value + '"}';
6199
+ }
6200
+ break;
6201
+ case 'lessthanorequal':
6202
+ if (item.type === 'number') {
6203
+ mongoQuery += '"' + field + '": { "$lte": ' + item.value + '}';
6204
+ }
6205
+ else {
6206
+ mongoQuery += '"' + field + '": { "$lte": "' + item.value + '"}';
6207
+ }
6208
+ break;
6209
+ }
6210
+ mongoQuery += '}';
6211
+ if (rules.length !== i) {
6212
+ mongoQuery += ',';
6213
+ }
6214
+ });
6215
+ return mongoQuery;
6216
+ }
6217
+ mongoParser(mongoQuery, rule, mongoLocale) {
6218
+ let mongoList;
6219
+ if (Object.keys(mongoQuery).indexOf('$and') > -1) {
6220
+ mongoList = mongoQuery['$and'];
6221
+ rule.condition = 'and';
6222
+ }
6223
+ else if (Object.keys(mongoQuery).indexOf('$or') > -1) {
6224
+ mongoList = mongoQuery['$or'];
6225
+ rule.condition = 'or';
6226
+ }
6227
+ rule.rules = [];
6228
+ this.mongoRecursion(mongoList, rule.rules, mongoLocale);
6229
+ }
6230
+ mongoRecursion(mongoList, rules, mongoLocale) {
6231
+ let operatorValue;
6232
+ let type;
6233
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6234
+ let stringValue;
6235
+ let key;
6236
+ let betweenValue;
6237
+ let condition;
6238
+ let value;
6239
+ let subRules;
6240
+ let rule;
6241
+ let keyObj;
6242
+ let ruleValue;
6243
+ for (let i = 0, len = mongoList.length; i < len; i++) {
6244
+ const betweenOperatorArray = [];
6245
+ let inOperatorArray = [];
6246
+ condition = Object.keys(mongoList[i])[0];
6247
+ value = mongoList[i][condition];
6248
+ if (condition === '$and') {
6249
+ if (this.parent.enableNotCondition) {
6250
+ subRules = { condition: condition.replace('$', ''), rules: [], not: false };
6251
+ }
6252
+ else {
6253
+ subRules = { condition: condition.replace('$', ''), rules: [] };
6254
+ }
6255
+ rules.push(subRules);
6256
+ this.mongoRecursion(mongoList[i][condition], rules[rules.length - 1].rules, mongoLocale);
6257
+ }
6258
+ else if (condition === '$or') {
6259
+ let notBetween;
6260
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, max-len
6261
+ let innerObject = [];
6262
+ let keys = [];
6263
+ let firstKey = [];
6264
+ let secondKey = [];
6265
+ let innerKeys = [];
6266
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, max-len
6267
+ let firstValue = [];
6268
+ let secondValue = [];
6269
+ let innerFirstValue = [];
6270
+ let innerSecondValue = [];
6271
+ if (Array.isArray(value) && value.length === 2) {
6272
+ keys = Object.keys(value);
6273
+ innerFirstValue = value[keys[0]];
6274
+ innerSecondValue = value[keys[1]];
6275
+ if (typeof innerFirstValue === 'object') {
6276
+ innerObject = Object.keys(innerFirstValue)[0];
6277
+ innerKeys = Object.keys(innerFirstValue[Object.keys(innerFirstValue)[0]]);
6278
+ firstKey = innerKeys[0];
6279
+ secondKey = Object.keys(innerSecondValue[Object.keys(innerSecondValue)[0]])[0];
6280
+ if (firstKey === '$lt' && secondKey === '$gt') {
6281
+ operatorValue = 'notbetween';
6282
+ // eslint-disable-next-line security/detect-object-injection
6283
+ firstValue = innerFirstValue[innerObject][firstKey];
6284
+ // eslint-disable-next-line security/detect-object-injection
6285
+ secondValue = innerSecondValue[innerObject][secondKey];
6286
+ type = typeof firstValue === 'number' ? 'number' : 'date';
6287
+ ruleValue = [firstValue, secondValue];
6288
+ rule = { field: innerObject, label: innerObject, value: ruleValue, operator: operatorValue, type: type };
6289
+ rules.push(rule);
6290
+ notBetween = true;
6291
+ }
6292
+ }
6293
+ }
6294
+ if (!notBetween) {
6295
+ if (this.parent.enableNotCondition) {
6296
+ subRules = { condition: condition.replace('$', ''), rules: [], not: false };
6297
+ }
6298
+ else {
6299
+ subRules = { condition: condition.replace('$', ''), rules: [] };
6300
+ }
6301
+ rules.push(subRules);
6302
+ this.mongoRecursion(mongoList[i][condition], rules[rules.length - 1].rules, mongoLocale);
6303
+ }
6304
+ }
6305
+ else {
6306
+ value = mongoList[i][condition];
6307
+ if (value === null) { // isnull operator
6308
+ operatorValue = 'isnull';
6309
+ }
6310
+ if (typeof value === 'boolean') { // boolean type values
6311
+ operatorValue = 'equal';
6312
+ type = 'boolean';
6313
+ ruleValue = value;
6314
+ }
6315
+ if (typeof (value) === 'number') {
6316
+ ruleValue = value;
6317
+ type = 'number';
6318
+ operatorValue = 'equal';
6319
+ }
6320
+ else if (typeof (value) === 'object' && value !== null) {
6321
+ keyObj = Object.keys(value);
6322
+ for (let i = 0; i < keyObj.length; i++) {
6323
+ key = keyObj[i];
6324
+ stringValue = (value)[keyObj[i]];
6325
+ if (key === '$ne' && isNullOrUndefined(stringValue)) { // not null operator
6326
+ operatorValue = 'isnotnull';
6327
+ ruleValue = null;
6328
+ }
6329
+ if (key === '$ne' && typeof stringValue === 'boolean') { // not equal operator for boolean
6330
+ operatorValue = 'notequal';
6331
+ ruleValue = stringValue;
6332
+ type = 'boolean';
6333
+ }
6334
+ if (keyObj.length >= 2 && keyObj[i]) {
6335
+ if (typeof (stringValue) == 'object') { // between and notbetween operators
6336
+ operatorValue = 'notbetween';
6337
+ condition = Object.keys(stringValue)[0];
6338
+ betweenValue = [Object.keys(stringValue[condition])[0]];
6339
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6340
+ betweenOperatorArray.push(stringValue[condition][betweenValue]);
6341
+ type = 'number';
6342
+ }
6343
+ else {
6344
+ operatorValue = 'between';
6345
+ betweenOperatorArray.push(stringValue);
6346
+ }
6347
+ if (typeof (stringValue) === 'number') {
6348
+ type = 'number';
6349
+ }
6350
+ }
6351
+ else if (typeof (stringValue) === 'object' && stringValue !== null) { // "in" and "notin" operator
6352
+ if (key === '$not' && Object.keys(stringValue)[0] === '$regex') {
6353
+ if (stringValue['$regex'].indexOf('^') > -1) {
6354
+ operatorValue = 'notstartswith';
6355
+ ruleValue = stringValue['$regex'].replace('^', '');
6356
+ }
6357
+ else if (stringValue['$regex'].indexOf('$') > -1) {
6358
+ operatorValue = 'notendswith';
6359
+ ruleValue = stringValue['$regex'].replace('$', '');
6360
+ }
6361
+ else {
6362
+ operatorValue = 'notcontains';
6363
+ ruleValue = stringValue['$regex'];
6364
+ }
6365
+ }
6366
+ else {
6367
+ operatorValue = key === '$in' ? 'in' : 'notin';
6368
+ inOperatorArray = stringValue;
6369
+ type = typeof (stringValue[0]) === 'number' ? 'number' : 'string';
6370
+ }
6371
+ }
6372
+ else if (typeof (stringValue) === 'number') { // number type values
6373
+ operatorValue = this.getOperatorFromMongoOperator(key);
6374
+ type = 'number';
6375
+ ruleValue = stringValue;
6376
+ }
6377
+ if (typeof (stringValue) === 'string') { // string type values
6378
+ if (key === '$regex') {
6379
+ operatorValue = 'contains';
6380
+ ruleValue = stringValue;
6381
+ type = 'string';
6382
+ }
6383
+ if (key === '$ne') { // not equal
6384
+ if (stringValue !== null && stringValue.length > 0 && isNaN(Date.parse(stringValue))) {
6385
+ operatorValue = 'notequal';
6386
+ ruleValue = stringValue;
6387
+ }
6388
+ else if (isNullOrUndefined(stringValue)) { // is not null operator
6389
+ operatorValue = 'isnotnull';
6390
+ ruleValue = stringValue;
6391
+ }
6392
+ else if (stringValue === '') { // is not empty operator
6393
+ operatorValue = 'isnotempty';
6394
+ ruleValue = stringValue;
6395
+ }
6396
+ type = 'string';
6397
+ }
6398
+ if (stringValue.indexOf('^') > -1) {
6399
+ operatorValue = 'startswith';
6400
+ ruleValue = stringValue.replace('^', '');
6401
+ type = 'string';
6402
+ }
6403
+ if (stringValue.indexOf('$') > -1 && key !== '$not') {
6404
+ operatorValue = 'endswith';
6405
+ ruleValue = stringValue.replace('$', '');
6406
+ type = 'string';
6407
+ }
6408
+ if (!isNaN(Date.parse(stringValue))) { // Date type operators
6409
+ operatorValue = operatorValue || this.getOperatorFromMongoOperator(key);
6410
+ type = 'date';
6411
+ ruleValue = stringValue;
6412
+ }
6413
+ }
6414
+ }
6415
+ }
6416
+ else if (value && typeof (value) === 'string' && !isNaN(Date.parse(value))) {
6417
+ operatorValue = 'equal';
6418
+ ruleValue = value;
6419
+ type = 'date';
6420
+ }
6421
+ else if (typeof (value) === 'string' && value !== '' && value !== 'true' && value !== 'false') {
6422
+ operatorValue = 'equal';
6423
+ ruleValue = value;
6424
+ type = 'string';
6425
+ }
6426
+ else if (typeof (value) === 'string' && value === '') {
6427
+ operatorValue = 'isempty';
6428
+ ruleValue = value;
6429
+ type = 'string';
6430
+ }
6431
+ if (betweenOperatorArray && betweenOperatorArray.length > 1) { // between opertor value
6432
+ rule = { field: condition, label: condition, value: betweenOperatorArray, operator: operatorValue, type: type };
6433
+ }
6434
+ else if (inOperatorArray && inOperatorArray.length > 1) { // in operator value
6435
+ rule = { field: condition, label: condition, value: inOperatorArray, operator: operatorValue, type: type };
6436
+ }
6437
+ else {
6438
+ rule = { field: condition, label: condition, value: ruleValue, operator: operatorValue, type: type };
6439
+ }
6440
+ rules.push(rule);
6441
+ operatorValue = '';
6442
+ }
6443
+ }
6444
+ }
6445
+ convertParamSqlToSql(sql) {
6446
+ const paramSql = sql.sql;
6447
+ const paramValues = sql.params;
6448
+ const parts = paramSql.split('?');
6449
+ let normalSql = parts[0];
6450
+ for (let i = 0; i < paramValues.length; i++) {
6451
+ normalSql += (typeof (paramValues[i]) === 'string' ? `'${paramValues[i]}'` + parts[i + 1] : paramValues[i] + parts[i + 1]);
6452
+ }
6453
+ if (normalSql.length >= 2 && normalSql[0] === '(' && normalSql[normalSql.length - 1] === ')') {
6454
+ normalSql = normalSql.slice(1, -1);
6455
+ }
6456
+ normalSql = normalSql.replace(/!= ''(?! =)/g, 'IS NOT EMPTY').replace(/= ''/g, 'IS EMPTY');
6457
+ return normalSql;
6458
+ }
6459
+ convertNamedParamSqlToSql(sql) {
6460
+ const namedParamSql = sql.sql;
6461
+ const params = sql.params;
6462
+ let normalSql = namedParamSql;
6463
+ Object.keys(params).forEach((paramName) => {
6464
+ const paramValue = params[paramName];
6465
+ paramName = ':' + paramName;
6466
+ normalSql = normalSql.replace(paramName, typeof (paramValue) === 'string' ? `'${paramValue}'` : String(paramValue));
6467
+ });
6468
+ if (normalSql.length >= 2 && normalSql[0] === '(' && normalSql[normalSql.length - 1] === ')') {
6469
+ normalSql = normalSql.slice(1, -1);
6470
+ }
6471
+ normalSql = normalSql.replace(/!= ''(?! =)/g, 'IS NOT EMPTY').replace(/= ''/g, 'IS EMPTY');
6472
+ return normalSql;
6473
+ }
6474
+ getParameterSql(qbrule) {
6475
+ const qbRule = extend({}, qbrule, null, true);
6476
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6477
+ const value = this.updateRuleValue(qbRule, false);
6478
+ return this.getParameterSQLVal(this.parent.getSqlFromRules(qbRule), value['ruleVal']);
6479
+ }
6480
+ getNamedParameterSql(qbrule) {
6481
+ const qbRule = extend({}, qbrule, null, true);
6482
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6483
+ const value = this.updateRuleValue(qbRule, true);
6484
+ return this.getNamedParameterSQLVal(this.parent.getSqlFromRules(qbRule), value['namedRuleVal']);
6485
+ }
6486
+ getParameterSQLVal(content, ruleValue) {
6487
+ const replacedString = content.replace(/[%']/g, '');
6488
+ return { sql: '(' + replacedString + ')', params: ruleValue };
6489
+ }
6490
+ getNamedParameterSQLVal(content, ruleValue) {
6491
+ const replacedString = content.replace(/[%']/g, '');
6492
+ return { sql: '(' + replacedString + ')', params: ruleValue };
6493
+ }
6494
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6495
+ updateRuleValue(rule, isNamedParameter) {
6496
+ const ruleVal = [];
6497
+ const namedRuleVal = {};
6498
+ const namedParameters = [];
6499
+ return this.updateValue(rule.rules, isNamedParameter, ruleVal, namedRuleVal, namedParameters);
6500
+ }
6501
+ updateValue(rules, isNamedParameter, ruleVal,
6502
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6503
+ namedRuleVal, namedParameters) {
6504
+ if (isNullOrUndefined(rules)) {
6505
+ return { ruleVal, namedRuleVal };
6506
+ }
6507
+ for (let i = 0; i < rules.length; i++) {
6508
+ if (rules[i].rules) {
6509
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6510
+ const value = this.updateValue(rules[i].rules, isNamedParameter, ruleVal, namedRuleVal, namedParameters);
6511
+ ruleVal = value['ruleVal'];
6512
+ namedRuleVal = value['namedRuleVal'];
6513
+ }
6514
+ else {
6515
+ let namedField;
6516
+ if (rules[i].value instanceof Array) {
6517
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6518
+ for (let j = 0; j < (rules[i].value).length; j++) {
6519
+ if (isNamedParameter) {
6520
+ namedField = this.getNamedParameter(rules[i].field, namedParameters);
6521
+ }
6522
+ if (!isNullOrUndefined(rules[i].value[j])) {
6523
+ if (rules[i].type === 'string' || rules[i].type === 'date') {
6524
+ if (isNamedParameter) {
6525
+ namedRuleVal[namedField] = rules[i].value[j];
6526
+ }
6527
+ else {
6528
+ ruleVal.push(rules[i].value[j]);
6529
+ }
6530
+ }
6531
+ else {
6532
+ if (isNamedParameter) {
6533
+ namedRuleVal[namedField] = rules[i].value[j];
6534
+ }
6535
+ else {
6536
+ ruleVal.push(rules[i].value[j]);
6537
+ }
6538
+ }
6539
+ }
6540
+ if (isNamedParameter) {
6541
+ rules[i].value[j] = ':' + namedField;
6542
+ }
6543
+ else {
6544
+ rules[i].value[j] = '?';
6545
+ }
6546
+ }
6547
+ }
6548
+ else {
6549
+ if (isNamedParameter) {
6550
+ namedField = this.getNamedParameter(rules[i].field, namedParameters);
6551
+ }
6552
+ if (rules[i].operator.indexOf('null') < 1) {
6553
+ if (rules[i].type !== 'string' || (rules[i].type === 'string' && (rules[i].value !== '' || rules[i].value === 0))) {
6554
+ if (rules[i].type === 'string' || rules[i].type === 'date') {
6555
+ if (rules[i].operator.indexOf('empty') < 1) {
6556
+ let value = rules[i].value.toString();
6557
+ switch (rules[i].operator) {
6558
+ case 'startswith':
6559
+ case 'notstartswith':
6560
+ value = value + '%';
6561
+ break;
6562
+ case 'endswith':
6563
+ case 'notendswith':
6564
+ value = '%' + value;
6565
+ break;
6566
+ case 'contains':
6567
+ case 'notcontains':
6568
+ value = '%' + value + '%';
6569
+ break;
6570
+ }
6571
+ if (isNamedParameter) {
6572
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6573
+ namedRuleVal[namedField] = value;
6574
+ }
6575
+ else {
6576
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6577
+ ruleVal.push(value);
6578
+ }
6579
+ }
6580
+ else {
6581
+ if (isNamedParameter) {
6582
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6583
+ namedRuleVal[namedField] = '';
6584
+ }
6585
+ else {
6586
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6587
+ ruleVal.push('');
6588
+ }
6589
+ if (rules[i].operator === 'isempty') {
6590
+ rules[i].operator = 'equal';
6591
+ }
6592
+ else {
6593
+ rules[i].operator = 'notequal';
6594
+ }
6595
+ }
6596
+ }
6597
+ else {
6598
+ if (!isNullOrUndefined(rules[i].value)) {
6599
+ if (isNamedParameter) {
6600
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6601
+ namedRuleVal[namedField] = rules[i].value;
6602
+ }
6603
+ else {
6604
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6605
+ ruleVal.push(rules[i].value);
6606
+ }
6607
+ }
6608
+ }
6609
+ if (isNamedParameter) {
6610
+ rules[i].value = ':' + namedField;
6611
+ }
6612
+ else {
6613
+ rules[i].value = '?';
6614
+ }
6615
+ }
6616
+ }
6617
+ }
6618
+ }
6619
+ }
6620
+ return { ruleVal, namedRuleVal };
6621
+ }
6622
+ getNamedParameter(field, namedParameters) {
6623
+ let newField = null;
6624
+ if (namedParameters.length > 0) {
6625
+ for (let i = namedParameters.length - 1; i >= 0; i--) {
6626
+ const currField = namedParameters[i];
6627
+ if (currField.indexOf(field) > -1) {
6628
+ const idx = parseInt(currField.split('_')[1], 10) + 1;
6629
+ newField = field + '_' + idx;
6630
+ namedParameters.push(newField);
6631
+ break;
6632
+ }
6633
+ }
6634
+ }
6635
+ if (!newField) {
6636
+ newField = field + '_1';
6637
+ namedParameters.push(newField);
6638
+ }
6639
+ return newField;
6640
+ }
6641
+ getModuleName() {
6642
+ return 'query-library';
6643
+ }
6644
+ }
6645
+
5192
6646
  /**
5193
6647
  * QueryBuilder modules
5194
6648
  */
@@ -5197,5 +6651,5 @@ QueryBuilder = __decorate([
5197
6651
  * QueryBuilder all modules
5198
6652
  */
5199
6653
 
5200
- export { Columns, Rule, Value, ShowButtons, QueryBuilder };
6654
+ export { Columns, Rule, Value, ShowButtons, QueryBuilder, QueryLibrary };
5201
6655
  //# sourceMappingURL=ej2-querybuilder.es2015.js.map