@limetech/lime-crm-building-blocks 1.96.0 → 1.97.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/{_MapCache-2e84a981.js → _MapCache-8b125fbb.js} +0 -26
  3. package/dist/cjs/{_Uint8Array-1e99726d.js → _Uint8Array-95263550.js} +1 -12
  4. package/dist/cjs/_baseIsEqual-cb7951b0.js +496 -0
  5. package/dist/cjs/_defineProperty-40a6ad5d.js +15 -0
  6. package/dist/cjs/{get-1acf79ce.js → get-932b213e.js} +5 -4
  7. package/dist/cjs/isEqual-e77cce75.js +37 -0
  8. package/dist/cjs/isSymbol-5b36aeee.js +30 -0
  9. package/dist/cjs/lime-crm-building-blocks.cjs.js +1 -1
  10. package/dist/cjs/lime-query.types-bcb63a22.js +61 -0
  11. package/dist/cjs/limebb-component-config.cjs.entry.js +3 -2
  12. package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +382 -150
  13. package/dist/cjs/limebb-lime-query-filter-and_5.cjs.entry.js +278 -0
  14. package/dist/cjs/limebb-lime-query-value-input.cjs.entry.js +239 -0
  15. package/dist/cjs/limebb-limetype-field_2.cjs.entry.js +406 -0
  16. package/dist/cjs/limebb-live-docs-info.cjs.entry.js +2 -2
  17. package/dist/cjs/limebb-locale-picker.cjs.entry.js +13 -498
  18. package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +2 -2
  19. package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +3 -3
  20. package/dist/cjs/limebb-notification-item.cjs.entry.js +1 -1
  21. package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
  22. package/dist/cjs/limebb-property-selector.cjs.entry.js +234 -0
  23. package/dist/cjs/limebb-response-format-item.cjs.entry.js +80 -0
  24. package/dist/cjs/limebb-text-editor.cjs.entry.js +20 -61
  25. package/dist/cjs/limebb-trend-indicator.cjs.entry.js +1 -1
  26. package/dist/cjs/limetype-1fe0207f.js +90 -0
  27. package/dist/cjs/loader.cjs.js +1 -1
  28. package/dist/cjs/property-resolution-fb42a46b.js +66 -0
  29. package/dist/collection/collection-manifest.json +10 -0
  30. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-and.css +121 -0
  31. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-and.js +257 -0
  32. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison.css +39 -0
  33. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison.js +246 -0
  34. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-expression.css +104 -0
  35. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-expression.js +220 -0
  36. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-not.css +107 -0
  37. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-not.js +212 -0
  38. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-or.css +123 -0
  39. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-or.js +237 -0
  40. package/dist/collection/components/lime-query-builder/expressions/lime-query-value-input.css +48 -0
  41. package/dist/collection/components/lime-query-builder/expressions/lime-query-value-input.js +457 -0
  42. package/dist/collection/components/lime-query-builder/filter-conversion.js +118 -21
  43. package/dist/collection/components/lime-query-builder/lime-query-builder.css +30 -17
  44. package/dist/collection/components/lime-query-builder/lime-query-builder.js +233 -28
  45. package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +435 -0
  46. package/dist/collection/components/lime-query-builder/property-selection-format.js +158 -0
  47. package/dist/collection/components/lime-query-builder/property-selector/property-selector.css +8 -0
  48. package/dist/collection/components/lime-query-builder/property-selector/property-selector.js +422 -0
  49. package/dist/collection/components/lime-query-builder/response-format-editor.css +72 -0
  50. package/dist/collection/components/lime-query-builder/response-format-editor.js +249 -0
  51. package/dist/collection/components/lime-query-builder/response-format-item.css +61 -0
  52. package/dist/collection/components/lime-query-builder/response-format-item.js +208 -0
  53. package/dist/collection/components/limeobject/file-viewer/live-docs-info.js +2 -2
  54. package/dist/collection/components/locale-picker/locale-picker.js +1 -1
  55. package/dist/collection/components/notification-list/notification-item/notification-item.js +1 -1
  56. package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
  57. package/dist/collection/components/summary-popover/summary-popover.js +3 -3
  58. package/dist/collection/components/text-editor/mention-group-counter.js +2 -2
  59. package/dist/collection/components/text-editor/text-editor.js +1 -1
  60. package/dist/collection/components/trend-indicator/trend-indicator.js +1 -1
  61. package/dist/components/_MapCache.js +2 -27
  62. package/dist/components/_Uint8Array.js +2 -12
  63. package/dist/components/_baseIsEqual.js +494 -0
  64. package/dist/components/_defineProperty.js +13 -0
  65. package/dist/components/get.js +2 -1
  66. package/dist/components/isEqual.js +35 -0
  67. package/dist/components/isSymbol.js +28 -0
  68. package/dist/components/lime-query-filter-and.js +408 -0
  69. package/dist/components/lime-query-filter-comparison.js +152 -0
  70. package/dist/components/lime-query-value-input.js +266 -0
  71. package/dist/components/limebb-lime-query-builder.js +441 -149
  72. package/dist/components/limebb-lime-query-filter-and.d.ts +11 -0
  73. package/dist/components/limebb-lime-query-filter-and.js +6 -0
  74. package/dist/components/limebb-lime-query-filter-comparison.d.ts +11 -0
  75. package/dist/components/limebb-lime-query-filter-comparison.js +6 -0
  76. package/dist/components/limebb-lime-query-filter-expression.d.ts +11 -0
  77. package/dist/components/limebb-lime-query-filter-expression.js +6 -0
  78. package/dist/components/limebb-lime-query-filter-not.d.ts +11 -0
  79. package/dist/components/limebb-lime-query-filter-not.js +6 -0
  80. package/dist/components/limebb-lime-query-filter-or.d.ts +11 -0
  81. package/dist/components/limebb-lime-query-filter-or.js +6 -0
  82. package/dist/components/limebb-lime-query-value-input.d.ts +11 -0
  83. package/dist/components/limebb-lime-query-value-input.js +6 -0
  84. package/dist/components/limebb-limetype-field.d.ts +11 -0
  85. package/dist/components/limebb-limetype-field.js +6 -0
  86. package/dist/components/limebb-locale-picker.js +8 -493
  87. package/dist/components/limebb-mention-group-counter.js +2 -2
  88. package/dist/components/limebb-percentage-visualizer.js +2 -2
  89. package/dist/components/limebb-property-selector.d.ts +11 -0
  90. package/dist/components/limebb-property-selector.js +6 -0
  91. package/dist/components/limebb-response-format-editor.d.ts +11 -0
  92. package/dist/components/limebb-response-format-editor.js +6 -0
  93. package/dist/components/limebb-response-format-item.d.ts +11 -0
  94. package/dist/components/limebb-response-format-item.js +6 -0
  95. package/dist/components/limebb-text-editor.js +7 -48
  96. package/dist/components/limebb-trend-indicator.js +1 -1
  97. package/dist/components/limetype-field.js +184 -0
  98. package/dist/components/limetype.js +85 -0
  99. package/dist/components/live-docs-info.js +2 -2
  100. package/dist/components/notification-item.js +1 -1
  101. package/dist/components/property-selector.js +317 -0
  102. package/dist/components/response-format-editor.js +278 -0
  103. package/dist/components/response-format-item.js +104 -0
  104. package/dist/components/summary-popover.js +3 -3
  105. package/dist/esm/{_MapCache-6484495d.js → _MapCache-af496e9d.js} +2 -27
  106. package/dist/esm/{_Uint8Array-e5cac922.js → _Uint8Array-d6ebd526.js} +3 -13
  107. package/dist/esm/_baseIsEqual-28053b81.js +494 -0
  108. package/dist/esm/_defineProperty-e6a185c3.js +13 -0
  109. package/dist/esm/{get-f9e0b2e1.js → get-3e42932b.js} +2 -1
  110. package/dist/esm/isEqual-57d0c223.js +35 -0
  111. package/dist/esm/isSymbol-1c5f65cc.js +28 -0
  112. package/dist/esm/lime-crm-building-blocks.js +1 -1
  113. package/dist/esm/lime-query.types-f72355e1.js +59 -0
  114. package/dist/esm/limebb-component-config.entry.js +3 -2
  115. package/dist/esm/limebb-lime-query-builder.entry.js +379 -147
  116. package/dist/esm/limebb-lime-query-filter-and_5.entry.js +270 -0
  117. package/dist/esm/limebb-lime-query-value-input.entry.js +235 -0
  118. package/dist/esm/limebb-limetype-field_2.entry.js +401 -0
  119. package/dist/esm/limebb-live-docs-info.entry.js +2 -2
  120. package/dist/esm/limebb-locale-picker.entry.js +9 -494
  121. package/dist/esm/limebb-mention-group-counter.entry.js +2 -2
  122. package/dist/esm/limebb-navigation-button_2.entry.js +3 -3
  123. package/dist/esm/limebb-notification-item.entry.js +1 -1
  124. package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
  125. package/dist/esm/limebb-property-selector.entry.js +230 -0
  126. package/dist/esm/limebb-response-format-item.entry.js +76 -0
  127. package/dist/esm/limebb-text-editor.entry.js +7 -48
  128. package/dist/esm/limebb-trend-indicator.entry.js +1 -1
  129. package/dist/esm/limetype-6e7552a7.js +85 -0
  130. package/dist/esm/loader.js +1 -1
  131. package/dist/esm/property-resolution-fde2375e.js +63 -0
  132. package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
  133. package/dist/lime-crm-building-blocks/{p-88c64360.entry.js → p-00da9b24.entry.js} +1 -1
  134. package/dist/lime-crm-building-blocks/p-02c0cc04.entry.js +1 -0
  135. package/dist/lime-crm-building-blocks/p-123190c3.js +1 -0
  136. package/dist/lime-crm-building-blocks/p-244ee55b.entry.js +1 -0
  137. package/dist/lime-crm-building-blocks/p-35897ec3.js +1 -0
  138. package/dist/lime-crm-building-blocks/{p-85b7291c.entry.js → p-3932077b.entry.js} +1 -1
  139. package/dist/lime-crm-building-blocks/p-3b0a15ec.js +1 -0
  140. package/dist/lime-crm-building-blocks/p-5a6d2e7f.js +1 -0
  141. package/dist/lime-crm-building-blocks/p-60971d64.js +1 -0
  142. package/dist/lime-crm-building-blocks/p-6c1146ca.entry.js +1 -0
  143. package/dist/lime-crm-building-blocks/p-70a28b93.entry.js +1 -0
  144. package/dist/lime-crm-building-blocks/p-7e6fb4af.js +1 -0
  145. package/dist/lime-crm-building-blocks/{p-8664381a.entry.js → p-8c4eb49f.entry.js} +1 -1
  146. package/dist/lime-crm-building-blocks/p-96beaabc.entry.js +1 -0
  147. package/dist/lime-crm-building-blocks/p-a659d55a.js +1 -0
  148. package/dist/lime-crm-building-blocks/p-b7c72179.entry.js +1 -0
  149. package/dist/lime-crm-building-blocks/p-baf4e428.entry.js +1 -0
  150. package/dist/lime-crm-building-blocks/p-d298b34e.js +1 -0
  151. package/dist/lime-crm-building-blocks/{p-7c4bdc1b.entry.js → p-d89c44ad.entry.js} +1 -1
  152. package/dist/lime-crm-building-blocks/p-e0ab1554.js +1 -0
  153. package/dist/lime-crm-building-blocks/{p-8064cbfb.entry.js → p-e9d23ef7.entry.js} +1 -1
  154. package/dist/lime-crm-building-blocks/p-ef8a5266.entry.js +1 -0
  155. package/dist/lime-crm-building-blocks/{p-c9126885.entry.js → p-f52125a0.entry.js} +1 -1
  156. package/dist/lime-crm-building-blocks/p-f99c611d.entry.js +1 -0
  157. package/dist/lime-crm-building-blocks/p-fe2b91d9.js +1 -0
  158. package/dist/types/components/lime-query-builder/expressions/lime-query-filter-and.d.ts +56 -0
  159. package/dist/types/components/lime-query-builder/expressions/lime-query-filter-comparison.d.ts +64 -0
  160. package/dist/types/components/lime-query-builder/expressions/lime-query-filter-expression.d.ts +53 -0
  161. package/dist/types/components/lime-query-builder/expressions/lime-query-filter-not.d.ts +54 -0
  162. package/dist/types/components/lime-query-builder/expressions/lime-query-filter-or.d.ts +55 -0
  163. package/dist/types/components/lime-query-builder/expressions/lime-query-value-input.d.ts +92 -0
  164. package/dist/types/components/lime-query-builder/filter-conversion.d.ts +18 -0
  165. package/dist/types/components/lime-query-builder/lime-query-builder.d.ts +30 -8
  166. package/dist/types/components/lime-query-builder/limetype-field/limetype-field.d.ts +96 -0
  167. package/dist/types/components/lime-query-builder/property-selection-format.d.ts +23 -0
  168. package/dist/types/components/lime-query-builder/property-selector/property-selector.d.ts +71 -0
  169. package/dist/types/components/lime-query-builder/response-format-editor.d.ts +57 -0
  170. package/dist/types/components/lime-query-builder/response-format-item.d.ts +46 -0
  171. package/dist/types/components.d.ts +1558 -117
  172. package/package.json +1 -1
  173. package/dist/lime-crm-building-blocks/p-00e7e0d4.entry.js +0 -1
  174. package/dist/lime-crm-building-blocks/p-11ac105b.entry.js +0 -1
  175. package/dist/lime-crm-building-blocks/p-5abe3fff.entry.js +0 -1
  176. package/dist/lime-crm-building-blocks/p-8044ffbd.js +0 -1
  177. package/dist/lime-crm-building-blocks/p-92ec9205.entry.js +0 -1
  178. package/dist/lime-crm-building-blocks/p-bcc23575.js +0 -1
  179. package/dist/lime-crm-building-blocks/p-c40a3f4b.js +0 -1
@@ -4,147 +4,64 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-ff255a0d.js');
6
6
  const index_esm = require('./index.esm-a894ac76.js');
7
+ const limeQuery_types = require('./lime-query.types-bcb63a22.js');
8
+ const propertyResolution = require('./property-resolution-fb42a46b.js');
7
9
 
8
10
  /**
9
- * Get normalized properties for a limetype
10
- * Adds system properties (_id, _timestamp, etc.) that map to the actual limeobject attributes
11
- * @param limetype The limetype to normalize
12
- * @returns Normalized properties with system properties prefixed with underscore
13
- */
14
- function getNormalizedProperties(limetype) {
15
- if (!(limetype === null || limetype === void 0 ? void 0 : limetype.properties)) {
16
- return {};
17
- }
18
- const properties = Object.assign({}, limetype.properties);
19
- // System properties that are exposed by the backend
20
- // Map from internal property name to API property name
21
- const systemProperties = {
22
- id: '_id',
23
- timestamp: '_timestamp',
24
- descriptive: '_descriptive',
25
- createduser: '_createduser',
26
- createdtime: '_createdtime',
27
- updateduser: '_updateduser',
28
- };
29
- // Find and normalize system properties by name
30
- for (const [propName, systemPropName] of Object.entries(systemProperties)) {
31
- const property = properties[propName];
32
- if (property) {
33
- properties[systemPropName] = property;
34
- delete properties[propName];
35
- }
36
- }
37
- return properties;
38
- }
39
- /**
40
- * Get property from limetype by path (e.g., "company.name")
41
- * Supports relation traversal with dot-notation
42
- * @param limetypes
43
- * @param limetype
44
- * @param path
11
+ * Convert UI filter representation to Lime Query filter format
12
+ * @param filter
45
13
  */
46
- function getPropertyFromPath(limetypes, limetype, path) {
47
- if (!path || !limetype || !limetypes) {
14
+ function guiFilterToLimeQuery(filter) {
15
+ if (filter.filter_type === '') {
48
16
  return undefined;
49
17
  }
50
- const parts = path.split('.');
51
- let currentType = limetypes[limetype];
52
- let property;
53
- for (const part of parts) {
54
- if (!currentType) {
18
+ if (filter.filter_type === 'comparison') {
19
+ return {
20
+ key: filter.property,
21
+ op: filter.operator,
22
+ exp: filter.value,
23
+ };
24
+ }
25
+ if (filter.filter_type === 'AND') {
26
+ const expressions = filter.expressions
27
+ .map(guiFilterToLimeQuery)
28
+ .filter((f) => f !== undefined);
29
+ if (expressions.length === 0) {
55
30
  return undefined;
56
31
  }
57
- const normalizedProperties = getNormalizedProperties(currentType);
58
- property = normalizedProperties[part];
59
- if (!property) {
32
+ if (expressions.length === 1) {
33
+ return expressions[0];
34
+ }
35
+ return {
36
+ op: 'AND',
37
+ exp: expressions,
38
+ };
39
+ }
40
+ if (filter.filter_type === 'OR') {
41
+ const expressions = filter.expressions
42
+ .map(guiFilterToLimeQuery)
43
+ .filter((f) => f !== undefined);
44
+ if (expressions.length === 0) {
60
45
  return undefined;
61
46
  }
62
- // If this is a relation, get the related limetype for next iteration
63
- if (property.relation) {
64
- currentType = property.relation.getLimetype();
47
+ if (expressions.length === 1) {
48
+ return expressions[0];
65
49
  }
66
- }
67
- return property;
68
- }
69
-
70
- /**
71
- * TypeScript type definitions for Lime Query DSL
72
- *
73
- * These types represent the structure of Lime Query as defined in:
74
- * - lime-core/lime_query/schema.py
75
- * - lime-core/lime_filter/schema.py
76
- */
77
- /**
78
- * Available operators with display metadata
79
- */
80
- const LIME_QUERY_OPERATORS = [
81
- { value: '=', label: 'Equals', icon: 'equals' },
82
- { value: '!=', label: 'Not Equals', icon: 'not-equal' },
83
- {
84
- value: '>',
85
- label: 'Greater Than',
86
- icon: 'greater-than',
87
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
88
- },
89
- {
90
- value: '>=',
91
- label: 'Greater or Equal',
92
- icon: 'greater-or-equal',
93
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
94
- },
95
- {
96
- value: '<',
97
- label: 'Less Than',
98
- icon: 'less-than',
99
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
100
- },
101
- {
102
- value: '<=',
103
- label: 'Less or Equal',
104
- icon: 'less-or-equal',
105
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
106
- },
107
- { value: 'IN', label: 'In List', icon: 'list' },
108
- {
109
- value: '?',
110
- label: 'Contains',
111
- icon: '-lime-filter-contain',
112
- applicableTypes: ['string', 'text'],
113
- },
114
- {
115
- value: '=?',
116
- label: 'Begins With',
117
- icon: '-lime-filter-begin',
118
- applicableTypes: ['string', 'text'],
119
- },
120
- {
121
- value: '=$',
122
- label: 'Ends With',
123
- icon: '-lime-filter-end',
124
- applicableTypes: ['string', 'text'],
125
- },
126
- ];
127
-
128
- /**
129
- * Convert Lime Query filter to UI filter representation
130
- * Throws errors for unsupported filter structures
131
- * @param filter
132
- */
133
- function limeQueryToGuiFilter(filter) {
134
- if (!filter) {
135
- // Return empty AND instead of missing expression
136
- // This ensures users see the "Add a condition" button
137
50
  return {
138
- filter_type: 'AND',
139
- expressions: [],
51
+ op: 'OR',
52
+ exp: expressions,
140
53
  };
141
54
  }
142
- // Check if it's a FilterExpression (has 'key' property)
143
- if ('key' in filter) {
144
- return validateAndConvertFilterExpression(filter);
55
+ if (filter.filter_type === 'NOT') {
56
+ const innerFilter = guiFilterToLimeQuery(filter.expression);
57
+ if (innerFilter) {
58
+ return {
59
+ op: '!',
60
+ exp: innerFilter,
61
+ };
62
+ }
145
63
  }
146
- // It's a FilterGroup
147
- return validateAndConvertFilterGroup(filter);
64
+ return undefined;
148
65
  }
149
66
  /**
150
67
  * Validate and convert a FilterExpression (comparison filter)
@@ -156,7 +73,7 @@ function validateAndConvertFilterExpression(filter) {
156
73
  throw new Error('Invalid filter: comparison must have key, op, and exp properties');
157
74
  }
158
75
  // Validate operator is supported
159
- const supportedOps = LIME_QUERY_OPERATORS.map((o) => o.value);
76
+ const supportedOps = limeQuery_types.LIME_QUERY_OPERATORS.map((o) => o.value);
160
77
  if (!supportedOps.includes(filter.op)) {
161
78
  throw new Error(`Unsupported filter operator: ${filter.op}`);
162
79
  }
@@ -226,6 +143,124 @@ function validateAndConvertFilterGroup(filter) {
226
143
  // If we reach here, the operator is unsupported
227
144
  throw new Error(`Unsupported filter operator: ${filter.op}`);
228
145
  }
146
+ /**
147
+ * Convert Lime Query filter to UI filter representation
148
+ * Throws errors for unsupported filter structures
149
+ * @param filter
150
+ */
151
+ function limeQueryToGuiFilter(filter) {
152
+ if (!filter) {
153
+ // Return empty AND instead of missing expression
154
+ // This ensures users see the "Add a condition" button
155
+ return {
156
+ filter_type: 'AND',
157
+ expressions: [],
158
+ };
159
+ }
160
+ // Check if it's a FilterExpression (has 'key' property)
161
+ if ('key' in filter) {
162
+ return validateAndConvertFilterExpression(filter);
163
+ }
164
+ // It's a FilterGroup
165
+ return validateAndConvertFilterGroup(filter);
166
+ }
167
+ /**
168
+ * Normalize filter for GUI mode by ensuring proper AND/OR wrapper structure.
169
+ * GUI mode requires filters to be wrapped in AND([OR(...)]) so users have
170
+ * access to add/remove buttons on the AND and OR components.
171
+ *
172
+ * This function ensures that:
173
+ * - Single comparisons are wrapped in AND([OR([comparison])])
174
+ * - OR groups are wrapped in AND([OR group])
175
+ * - AND groups have their comparison children wrapped in OR
176
+ * - Empty/undefined filters become AND([])
177
+ *
178
+ * When converting back to Lime Query JSON, limeQueryFilterToLimeQuery()
179
+ * automatically unwraps single-item AND/OR groups.
180
+ *
181
+ * @param filter The filter expression from limeQueryToLimeQueryFilter
182
+ * @returns Normalized filter suitable for GUI editing
183
+ */
184
+ function normalizeLimeQueryFilterForGui(filter) {
185
+ // Empty AND is already correct for GUI
186
+ if (filter.filter_type === 'AND' && filter.expressions.length === 0) {
187
+ return filter;
188
+ }
189
+ // Single comparison needs wrapping
190
+ if (filter.filter_type === 'comparison') {
191
+ return {
192
+ filter_type: 'AND',
193
+ expressions: [
194
+ {
195
+ filter_type: 'OR',
196
+ expressions: [filter],
197
+ },
198
+ ],
199
+ };
200
+ }
201
+ // OR needs wrapping in AND
202
+ if (filter.filter_type === 'OR') {
203
+ return {
204
+ filter_type: 'AND',
205
+ expressions: [filter],
206
+ };
207
+ }
208
+ // NOT needs wrapping
209
+ if (filter.filter_type === 'NOT') {
210
+ return {
211
+ filter_type: 'AND',
212
+ expressions: [
213
+ {
214
+ filter_type: 'OR',
215
+ expressions: [filter],
216
+ },
217
+ ],
218
+ };
219
+ }
220
+ // AND group - check if children need OR wrappers
221
+ if (filter.filter_type === 'AND') {
222
+ const normalizedChildren = filter.expressions.map((child) => {
223
+ // If child is already OR, keep it
224
+ if (child.filter_type === 'OR') {
225
+ return child;
226
+ }
227
+ // If child is NOT, keep it (NOT can be a direct child of AND)
228
+ if (child.filter_type === 'NOT') {
229
+ return child;
230
+ }
231
+ // If child is comparison, wrap in OR
232
+ if (child.filter_type === 'comparison') {
233
+ return {
234
+ filter_type: 'OR',
235
+ expressions: [child],
236
+ };
237
+ }
238
+ // If child is nested AND, recursively normalize and wrap in OR
239
+ if (child.filter_type === 'AND') {
240
+ return {
241
+ filter_type: 'OR',
242
+ expressions: [normalizeLimeQueryFilterForGui(child)],
243
+ };
244
+ }
245
+ // Unknown filter type, keep as is
246
+ return child;
247
+ });
248
+ return {
249
+ filter_type: 'AND',
250
+ expressions: normalizedChildren,
251
+ };
252
+ }
253
+ // Fallback: wrap in AND/OR structure
254
+ return {
255
+ filter_type: 'AND',
256
+ expressions: [
257
+ {
258
+ filter_type: 'OR',
259
+ expressions: [filter],
260
+ },
261
+ ],
262
+ };
263
+ }
229
264
 
230
265
  /**
231
266
  * Dynamic filter values and placeholders that are valid in Lime Query
@@ -291,7 +326,7 @@ function validatePlaceholder(value, activeLimetype, limetypes) {
291
326
  }
292
327
  // Validate the property path exists on the active limetype
293
328
  try {
294
- const property = getPropertyFromPath(limetypes, activeLimetype, propertyPath);
329
+ const property = propertyResolution.getPropertyFromPath(limetypes, activeLimetype, propertyPath);
295
330
  if (!property) {
296
331
  return {
297
332
  valid: false,
@@ -461,7 +496,7 @@ function validatePropertySelection(selection, limetypes, limetype, guiModeEnable
461
496
  if (!limetypeObj) {
462
497
  throw new Error(`Unknown limetype: ${limetype}`);
463
498
  }
464
- const normalizedProperties = getNormalizedProperties(limetypeObj);
499
+ const normalizedProperties = propertyResolution.getNormalizedProperties(limetypeObj);
465
500
  const allGuiLimitations = [];
466
501
  for (const [propName, propValue] of Object.entries(selection)) {
467
502
  // Skip # properties (comments/metadata that backend accepts via unknown=INCLUDE)
@@ -604,7 +639,7 @@ function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, guiModeEnabl
604
639
  };
605
640
  }
606
641
 
607
- const limeQueryBuilderCss = ":host(limebb-lime-query-builder){display:block;width:100%}.lime-query-builder{display:flex;flex-direction:column;gap:2rem}.mode-controls{display:flex;align-items:center;gap:0.5rem;padding:0.5rem;background-color:rgb(var(--contrast-100));border-radius:var(--border-radius)}.mode-switch{display:flex;align-items:center;gap:0.5rem}.mode-switch limel-button{min-width:5rem}.mode-switch limel-helper-text{margin-left:1rem;color:rgb(var(--color-red-default))}.gui-mode,.code-mode{display:block}.code-editor-container{--code-editor-max-height:70vh;display:flex;flex-direction:column;gap:1rem}.code-editor-container .validation-errors{padding:0.75rem 1rem;color:rgb(var(--color-red-default));background-color:rgb(var(--color-red-lighter));border-left:0.25rem solid rgb(var(--color-red-default));border-radius:0.25rem;font-size:0.875rem}.code-editor-container .validation-errors strong{display:block;margin-bottom:0.5rem;font-weight:600}.code-editor-container .validation-errors ul{margin:0;padding-left:1.5rem}.code-editor-container .validation-errors li{margin:0.25rem 0}.code-editor-container .gui-limitations{padding:0.75rem 1rem;color:rgb(var(--color-blue-dark));background-color:rgb(var(--color-blue-lighter));border-left:0.25rem solid rgb(var(--color-blue-default));border-radius:0.25rem;font-size:0.875rem}.code-editor-container .gui-limitations strong{display:block;margin-bottom:0.5rem;font-weight:600}.code-editor-container .gui-limitations ul{margin:0;padding-left:1.5rem}.code-editor-container .gui-limitations li{margin:0.25rem 0}.lime-query-builder-label{margin:0;font-size:1.5rem;font-weight:600;color:rgb(var(--contrast-1100))}.placeholder-message{padding:2rem;text-align:center;background-color:rgb(var(--contrast-100));border-radius:var(--border-radius);border:1px solid rgb(var(--contrast-300))}.placeholder-message h4{margin:0 0 1rem 0;font-size:1.125rem;font-weight:600;color:rgb(var(--contrast-1100))}.placeholder-message p{margin:0;color:rgb(var(--contrast-900));line-height:1.5}";
642
+ const limeQueryBuilderCss = ":host(limebb-lime-lime-query-builder){display:block;width:100%}.lime-query-builder{display:flex;flex-direction:column;gap:2rem}.mode-controls{display:flex;align-items:center;gap:0.5rem;padding:0.5rem}.mode-switch{display:flex;align-items:center;gap:0.5rem}.mode-switch limel-button{min-width:5rem}.mode-switch limel-helper-text{margin-left:1rem;color:rgb(var(--color-red-default))}.gui-mode,.code-mode{display:block}.code-editor-container{--code-editor-max-height:70vh;display:flex;flex-direction:column;gap:1rem}.code-editor-container .validation-errors{padding:0.75rem 1rem;color:rgb(var(--color-red-default));background-color:rgb(var(--color-red-lighter));border-left:0.25rem solid rgb(var(--color-red-default));border-radius:0.25rem;font-size:0.875rem}.code-editor-container .validation-errors strong{display:block;margin-bottom:0.5rem;font-weight:600}.code-editor-container .validation-errors ul{margin:0;padding-left:1.5rem}.code-editor-container .validation-errors li{margin:0.25rem 0}.code-editor-container .gui-limitations{padding:0.75rem 1rem;color:rgb(var(--color-blue-dark));background-color:rgb(var(--color-blue-lighter));border-left:0.25rem solid rgb(var(--color-blue-default));border-radius:0.25rem;font-size:0.875rem}.code-editor-container .gui-limitations strong{display:block;margin-bottom:0.5rem;font-weight:600}.code-editor-container .gui-limitations ul{margin:0;padding-left:1.5rem}.code-editor-container .gui-limitations li{margin:0.25rem 0}.lime-query-builder-label{margin:0;font-size:1.5rem;font-weight:600;color:rgb(var(--contrast-1100))}.limetype-section{display:flex;flex-direction:column}.filter-section,.query-options-section{display:flex;flex-direction:column;gap:1rem}.section-label{margin:0;font-size:1.125rem;font-weight:600;color:rgb(var(--contrast-1000))}.query-options-controls{display:grid;grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));gap:1rem}@media (max-width: 768px){.lime-query-builder{gap:1.5rem}.query-options-controls{grid-template-columns:1fr}}";
608
643
  const LimebbLimeQueryBuilderStyle0 = limeQueryBuilderCss;
609
644
 
610
645
  var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
@@ -623,10 +658,80 @@ const LimeQueryBuilder = class {
623
658
  this.change = index.createEvent(this, "change", 7);
624
659
  this.mode = 'gui';
625
660
  this.codeValue = '';
661
+ this.limetype = '';
662
+ this.filter = {
663
+ filter_type: 'AND',
664
+ expressions: [],
665
+ };
666
+ this.handleLimetypeChange = (event) => {
667
+ event.stopPropagation();
668
+ this.limetype = event.detail;
669
+ // Reset filter when limetype changes
670
+ this.filter = {
671
+ filter_type: 'AND',
672
+ expressions: [],
673
+ };
674
+ // Reset response format when limetype changes
675
+ this.internalResponseFormat = {
676
+ object: {
677
+ _id: null,
678
+ },
679
+ };
680
+ this.emitChange();
681
+ };
682
+ this.handleFilterChange = (event) => {
683
+ event.stopPropagation();
684
+ // Convert missing expression back to empty AND to keep the UI consistent
685
+ if (event.detail.filter_type === '') {
686
+ this.filter = {
687
+ filter_type: 'AND',
688
+ expressions: [],
689
+ };
690
+ }
691
+ else {
692
+ this.filter = event.detail;
693
+ }
694
+ this.emitChange();
695
+ };
696
+ this.handleResponseFormatChange = (event) => {
697
+ event.stopPropagation();
698
+ this.internalResponseFormat = event.detail;
699
+ this.emitChange();
700
+ };
701
+ this.handleLimitChange = (event) => {
702
+ event.stopPropagation();
703
+ const value = event.detail;
704
+ this.limit = value ? Number.parseInt(value, 10) : undefined;
705
+ this.emitChange();
706
+ };
707
+ this.handleActiveLimetypeChange = (event) => {
708
+ event.stopPropagation();
709
+ this.activeLimetype = event.detail || undefined;
710
+ };
626
711
  this.switchToGui = () => {
627
- this.mode = 'gui';
712
+ // Validate JSON before switching
713
+ try {
714
+ const parsed = JSON.parse(this.codeValue);
715
+ // Check if it's supported in GUI
716
+ const support = this.checkGuiSupport();
717
+ if (!support.guiSupported) {
718
+ // Don't switch if GUI can't render this query
719
+ return;
720
+ }
721
+ // Update internal state from parsed query
722
+ this.limetype = parsed.limetype || '';
723
+ this.filter = normalizeLimeQueryFilterForGui(limeQueryToGuiFilter(parsed.filter));
724
+ this.internalResponseFormat = parsed.responseFormat;
725
+ this.limit = parsed.limit;
726
+ this.mode = 'gui';
727
+ this.change.emit(parsed);
728
+ }
729
+ catch (_a) {
730
+ // Don't switch if JSON is invalid (linter will show the error)
731
+ }
628
732
  };
629
733
  this.switchToCode = () => {
734
+ this.updateCodeValue();
630
735
  this.mode = 'code';
631
736
  };
632
737
  this.handleCodeChange = (event) => {
@@ -647,43 +752,130 @@ const LimeQueryBuilder = class {
647
752
  return ((_c = (_b = (_a = this.platform) === null || _a === void 0 ? void 0 : _a.isFeatureEnabled) === null || _b === void 0 ? void 0 : _b.call(_a, 'useLimeQueryBuilderGuiMode')) !== null && _c !== void 0 ? _c : false);
648
753
  }
649
754
  componentWillLoad() {
650
- // Initialize code value from input prop
651
- this.codeValue = JSON.stringify(this.value || {}, null, 2);
652
755
  // Force code mode if GUI is disabled
653
756
  if (!this.guiModeEnabled) {
654
757
  this.mode = 'code';
758
+ // Initialize code value from prop
759
+ this.updateCodeValue();
760
+ return;
761
+ }
762
+ if (this.value) {
763
+ this.limetype = this.value.limetype || '';
764
+ this.filter = normalizeLimeQueryFilterForGui(limeQueryToGuiFilter(this.value.filter));
765
+ this.internalResponseFormat = this.value.responseFormat;
766
+ this.limit = this.value.limit;
767
+ }
768
+ // Initialize code value from prop
769
+ this.updateCodeValue();
770
+ // Check if GUI mode is supported
771
+ const support = this.checkGuiSupport();
772
+ if (!support.guiSupported) {
773
+ this.mode = 'code';
655
774
  }
656
775
  }
657
776
  render() {
658
777
  const guiSupported = this.checkGuiSupport();
659
- return (index.h("div", { key: '77e93d0277a99b8ff1c777d7ee0b63259755f740', class: "lime-query-builder" }, this.label && (index.h("h3", { key: '4089d69ea3404c656f1c24ec73aef6df2cc8baec', class: "lime-query-builder-label" }, this.label)), this.guiModeEnabled && (index.h("div", { key: '5d18a749386651cc1361b712693bad105dba9b03', class: "mode-controls" }, this.renderModeSwitch(guiSupported))), !this.guiModeEnabled || this.mode === 'code' ? (index.h("div", { class: "code-mode" }, this.renderCodeEditor(guiSupported))) : (index.h("div", { class: "gui-mode" }, index.h("div", { class: "placeholder-message" }, index.h("h4", null, "GUI Mode Not Yet Supported"), index.h("p", null, "The visual query builder interface is not yet available. Please use Code mode to write queries in JSON format."))))));
778
+ const showCodeMode = !this.guiModeEnabled || this.mode === 'code';
779
+ return (index.h("div", { key: 'd179549c02b40689f61a47f327c9b4ab3e578258', class: "lime-query-builder" }, this.renderLabel(), this.renderModeControls(guiSupported), showCodeMode
780
+ ? this.renderCodeMode(guiSupported)
781
+ : this.renderGuiMode()));
782
+ }
783
+ emitChange() {
784
+ // Only emit in GUI mode
785
+ if (this.mode === 'code') {
786
+ return;
787
+ }
788
+ if (!this.limetype) {
789
+ return;
790
+ }
791
+ // Use internal state, then default to returning just _id
792
+ const responseFormat = this.internalResponseFormat || {
793
+ object: {
794
+ _id: null,
795
+ },
796
+ };
797
+ const limeQuery = {
798
+ limetype: this.limetype,
799
+ responseFormat: responseFormat,
800
+ filter: guiFilterToLimeQuery(this.filter),
801
+ };
802
+ if (this.limit !== undefined && this.limit > 0) {
803
+ limeQuery.limit = this.limit;
804
+ }
805
+ this.change.emit(limeQuery);
806
+ }
807
+ updateCodeValue() {
808
+ if (!this.limetype) {
809
+ this.codeValue = JSON.stringify(this.value || {}, null, 2);
810
+ return;
811
+ }
812
+ // Use internal state, then default to returning just _id
813
+ const responseFormat = this.internalResponseFormat || {
814
+ object: {
815
+ _id: null,
816
+ },
817
+ };
818
+ const limeQuery = {
819
+ limetype: this.limetype,
820
+ responseFormat: responseFormat,
821
+ filter: guiFilterToLimeQuery(this.filter),
822
+ };
823
+ if (this.limit !== undefined && this.limit > 0) {
824
+ limeQuery.limit = this.limit;
825
+ }
826
+ this.codeValue = JSON.stringify(limeQuery, null, 2);
660
827
  }
661
828
  checkGuiSupport() {
662
- if (!this.limetypes || !this.codeValue) {
829
+ if (!this.limetypes) {
663
830
  // Can't validate yet, assume all is good
664
831
  return {
665
832
  valid: true,
666
- guiSupported: false,
833
+ guiSupported: true,
667
834
  validationErrors: [],
668
835
  guiLimitations: [],
669
836
  };
670
837
  }
671
- // Parse and validate the code value
672
- let limeQueryToCheck;
673
- try {
674
- limeQueryToCheck = JSON.parse(this.codeValue);
838
+ // When in code mode, validate the parsed code value instead of current state
839
+ let queryToCheck;
840
+ if (this.mode === 'code' && this.codeValue) {
841
+ try {
842
+ queryToCheck = JSON.parse(this.codeValue);
843
+ }
844
+ catch (_a) {
845
+ return {
846
+ valid: false,
847
+ guiSupported: false,
848
+ validationErrors: ['Invalid JSON'],
849
+ guiLimitations: [],
850
+ };
851
+ }
675
852
  }
676
- catch (_a) {
677
- return {
678
- valid: false,
679
- guiSupported: false,
680
- validationErrors: ['Invalid JSON'],
681
- guiLimitations: [],
853
+ else {
854
+ // Build query from current GUI state
855
+ if (!this.limetype) {
856
+ return {
857
+ valid: true,
858
+ guiSupported: true,
859
+ validationErrors: [],
860
+ guiLimitations: [],
861
+ };
862
+ }
863
+ const responseFormat = this
864
+ .internalResponseFormat || {
865
+ object: {
866
+ _id: null,
867
+ },
682
868
  };
869
+ queryToCheck = {
870
+ limetype: this.limetype,
871
+ responseFormat: responseFormat,
872
+ filter: guiFilterToLimeQuery(this.filter),
873
+ };
874
+ if (this.limit !== undefined && this.limit > 0) {
875
+ queryToCheck.limit = this.limit;
876
+ }
683
877
  }
684
- // In code-only mode, we don't track activeLimetype separately
685
- // Pass undefined since it's not needed for code mode validation
686
- return isLimeQuerySupported(limeQueryToCheck, this.limetypes, undefined, this.guiModeEnabled);
878
+ return isLimeQuerySupported(queryToCheck, this.limetypes, this.activeLimetype, this.guiModeEnabled);
687
879
  }
688
880
  renderModeSwitch(support) {
689
881
  const guiDisabled = !support.guiSupported;
@@ -696,6 +888,46 @@ const LimeQueryBuilder = class {
696
888
  !guiSupported.guiSupported &&
697
889
  guiSupported.guiLimitations.length > 0 && (index.h("div", { class: "gui-limitations" }, index.h("strong", null, "Cannot switch to GUI mode:"), index.h("ul", null, guiSupported.guiLimitations.map((limitation) => (index.h("li", null, limitation))))))));
698
890
  }
891
+ renderLimetypeSection() {
892
+ return (index.h("div", { class: "limetype-section" }, index.h("limebb-limetype-field", { platform: this.platform, context: this.context, label: "Object Type", value: this.limetype, required: true, fieldName: "limetype", helperText: "Select the type of object you want to query", onChange: this.handleLimetypeChange })));
893
+ }
894
+ renderResponseFormatSection() {
895
+ if (!this.limetype) {
896
+ return;
897
+ }
898
+ return (index.h("div", { class: "response-format-section" }, index.h("limebb-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalResponseFormat, onChange: this.handleResponseFormatChange })));
899
+ }
900
+ renderFilterSection() {
901
+ if (!this.limetype) {
902
+ return;
903
+ }
904
+ return (index.h("div", { class: "filter-section" }, index.h("h4", { class: "section-label" }, "Filter Conditions"), index.h("limebb-lime-query-filter-expression", { platform: this.platform, context: this.context, limetype: this.limetype, activeLimetype: this.activeLimetype, expression: this.filter, onExpressionChange: this.handleFilterChange })));
905
+ }
906
+ renderQueryOptionsSection() {
907
+ var _a;
908
+ if (!this.limetype) {
909
+ return;
910
+ }
911
+ return (index.h("div", { class: "query-options-section" }, index.h("h4", { class: "section-label" }, "Query Options"), index.h("div", { class: "query-options-controls" }, index.h("limebb-limetype-field", { platform: this.platform, context: this.context, label: "Active Object Type", value: this.activeLimetype, required: false, fieldName: "activeLimetype", helperText: "Limetype of the active object (for %activeObject% placeholders)", onChange: this.handleActiveLimetypeChange }), index.h("limel-input-field", { label: "Limit", type: "number", value: ((_a = this.limit) === null || _a === void 0 ? void 0 : _a.toString()) || '', placeholder: "No limit", helperText: "Maximum number of results", onChange: this.handleLimitChange }))));
912
+ }
913
+ renderGuiMode() {
914
+ return (index.h("div", { class: "gui-mode" }, this.renderLimetypeSection(), this.renderResponseFormatSection(), this.renderFilterSection(), this.renderQueryOptionsSection()));
915
+ }
916
+ renderLabel() {
917
+ if (!this.label) {
918
+ return;
919
+ }
920
+ return index.h("h3", { class: "lime-query-builder-label" }, this.label);
921
+ }
922
+ renderModeControls(support) {
923
+ if (!this.guiModeEnabled) {
924
+ return;
925
+ }
926
+ return (index.h("div", { class: "mode-controls" }, this.renderModeSwitch(support)));
927
+ }
928
+ renderCodeMode(support) {
929
+ return index.h("div", { class: "code-mode" }, this.renderCodeEditor(support));
930
+ }
699
931
  };
700
932
  __decorate([
701
933
  index_esm.Te()