@limetech/lime-crm-building-blocks 1.96.0 → 1.98.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 +14 -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 +378 -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 +253 -27
  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 +437 -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 +375 -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-0957b2a6.entry.js +1 -0
  136. package/dist/lime-crm-building-blocks/p-123190c3.js +1 -0
  137. package/dist/lime-crm-building-blocks/p-244ee55b.entry.js +1 -0
  138. package/dist/lime-crm-building-blocks/p-35897ec3.js +1 -0
  139. package/dist/lime-crm-building-blocks/{p-85b7291c.entry.js → p-3932077b.entry.js} +1 -1
  140. package/dist/lime-crm-building-blocks/p-3b0a15ec.js +1 -0
  141. package/dist/lime-crm-building-blocks/p-5a6d2e7f.js +1 -0
  142. package/dist/lime-crm-building-blocks/p-60971d64.js +1 -0
  143. package/dist/lime-crm-building-blocks/p-6c1146ca.entry.js +1 -0
  144. package/dist/lime-crm-building-blocks/p-70a28b93.entry.js +1 -0
  145. package/dist/lime-crm-building-blocks/p-7e6fb4af.js +1 -0
  146. package/dist/lime-crm-building-blocks/{p-8664381a.entry.js → p-8c4eb49f.entry.js} +1 -1
  147. package/dist/lime-crm-building-blocks/p-96beaabc.entry.js +1 -0
  148. package/dist/lime-crm-building-blocks/p-a659d55a.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 +40 -7
  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 +1587 -114
  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
@@ -1,146 +1,68 @@
1
1
  import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
2
2
  import { T as Te } from './index.esm.js';
3
+ import { L as LIME_QUERY_OPERATORS, d as defineCustomElement$a } from './lime-query-filter-comparison.js';
4
+ import { g as getNormalizedProperties, a as getPropertyFromPath, d as defineCustomElement$4 } from './property-selector.js';
5
+ import { d as defineCustomElement$7, a as defineCustomElement$8, b as defineCustomElement$9, c as defineCustomElement$b } from './lime-query-filter-and.js';
6
+ import { d as defineCustomElement$6 } from './lime-query-value-input.js';
7
+ import { d as defineCustomElement$5 } from './limetype-field.js';
8
+ import { d as defineCustomElement$3 } from './response-format-editor.js';
9
+ import { d as defineCustomElement$2 } from './response-format-item.js';
3
10
 
4
11
  /**
5
- * Get normalized properties for a limetype
6
- * Adds system properties (_id, _timestamp, etc.) that map to the actual limeobject attributes
7
- * @param limetype The limetype to normalize
8
- * @returns Normalized properties with system properties prefixed with underscore
9
- */
10
- function getNormalizedProperties(limetype) {
11
- if (!(limetype === null || limetype === void 0 ? void 0 : limetype.properties)) {
12
- return {};
13
- }
14
- const properties = Object.assign({}, limetype.properties);
15
- // System properties that are exposed by the backend
16
- // Map from internal property name to API property name
17
- const systemProperties = {
18
- id: '_id',
19
- timestamp: '_timestamp',
20
- descriptive: '_descriptive',
21
- createduser: '_createduser',
22
- createdtime: '_createdtime',
23
- updateduser: '_updateduser',
24
- };
25
- // Find and normalize system properties by name
26
- for (const [propName, systemPropName] of Object.entries(systemProperties)) {
27
- const property = properties[propName];
28
- if (property) {
29
- properties[systemPropName] = property;
30
- delete properties[propName];
31
- }
32
- }
33
- return properties;
34
- }
35
- /**
36
- * Get property from limetype by path (e.g., "company.name")
37
- * Supports relation traversal with dot-notation
38
- * @param limetypes
39
- * @param limetype
40
- * @param path
12
+ * Convert UI filter representation to Lime Query filter format
13
+ * @param filter
41
14
  */
42
- function getPropertyFromPath(limetypes, limetype, path) {
43
- if (!path || !limetype || !limetypes) {
15
+ function guiFilterToLimeQuery(filter) {
16
+ if (filter.filter_type === '') {
44
17
  return undefined;
45
18
  }
46
- const parts = path.split('.');
47
- let currentType = limetypes[limetype];
48
- let property;
49
- for (const part of parts) {
50
- if (!currentType) {
19
+ if (filter.filter_type === 'comparison') {
20
+ return {
21
+ key: filter.property,
22
+ op: filter.operator,
23
+ exp: filter.value,
24
+ };
25
+ }
26
+ if (filter.filter_type === 'AND') {
27
+ const expressions = filter.expressions
28
+ .map(guiFilterToLimeQuery)
29
+ .filter((f) => f !== undefined);
30
+ if (expressions.length === 0) {
51
31
  return undefined;
52
32
  }
53
- const normalizedProperties = getNormalizedProperties(currentType);
54
- property = normalizedProperties[part];
55
- if (!property) {
33
+ if (expressions.length === 1) {
34
+ return expressions[0];
35
+ }
36
+ return {
37
+ op: 'AND',
38
+ exp: expressions,
39
+ };
40
+ }
41
+ if (filter.filter_type === 'OR') {
42
+ const expressions = filter.expressions
43
+ .map(guiFilterToLimeQuery)
44
+ .filter((f) => f !== undefined);
45
+ if (expressions.length === 0) {
56
46
  return undefined;
57
47
  }
58
- // If this is a relation, get the related limetype for next iteration
59
- if (property.relation) {
60
- currentType = property.relation.getLimetype();
48
+ if (expressions.length === 1) {
49
+ return expressions[0];
61
50
  }
62
- }
63
- return property;
64
- }
65
-
66
- /**
67
- * TypeScript type definitions for Lime Query DSL
68
- *
69
- * These types represent the structure of Lime Query as defined in:
70
- * - lime-core/lime_query/schema.py
71
- * - lime-core/lime_filter/schema.py
72
- */
73
- /**
74
- * Available operators with display metadata
75
- */
76
- const LIME_QUERY_OPERATORS = [
77
- { value: '=', label: 'Equals', icon: 'equals' },
78
- { value: '!=', label: 'Not Equals', icon: 'not-equal' },
79
- {
80
- value: '>',
81
- label: 'Greater Than',
82
- icon: 'greater-than',
83
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
84
- },
85
- {
86
- value: '>=',
87
- label: 'Greater or Equal',
88
- icon: 'greater-or-equal',
89
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
90
- },
91
- {
92
- value: '<',
93
- label: 'Less Than',
94
- icon: 'less-than',
95
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
96
- },
97
- {
98
- value: '<=',
99
- label: 'Less or Equal',
100
- icon: 'less-or-equal',
101
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
102
- },
103
- { value: 'IN', label: 'In List', icon: 'list' },
104
- {
105
- value: '?',
106
- label: 'Contains',
107
- icon: '-lime-filter-contain',
108
- applicableTypes: ['string', 'text'],
109
- },
110
- {
111
- value: '=?',
112
- label: 'Begins With',
113
- icon: '-lime-filter-begin',
114
- applicableTypes: ['string', 'text'],
115
- },
116
- {
117
- value: '=$',
118
- label: 'Ends With',
119
- icon: '-lime-filter-end',
120
- applicableTypes: ['string', 'text'],
121
- },
122
- ];
123
-
124
- /**
125
- * Convert Lime Query filter to UI filter representation
126
- * Throws errors for unsupported filter structures
127
- * @param filter
128
- */
129
- function limeQueryToGuiFilter(filter) {
130
- if (!filter) {
131
- // Return empty AND instead of missing expression
132
- // This ensures users see the "Add a condition" button
133
51
  return {
134
- filter_type: 'AND',
135
- expressions: [],
52
+ op: 'OR',
53
+ exp: expressions,
136
54
  };
137
55
  }
138
- // Check if it's a FilterExpression (has 'key' property)
139
- if ('key' in filter) {
140
- return validateAndConvertFilterExpression(filter);
56
+ if (filter.filter_type === 'NOT') {
57
+ const innerFilter = guiFilterToLimeQuery(filter.expression);
58
+ if (innerFilter) {
59
+ return {
60
+ op: '!',
61
+ exp: innerFilter,
62
+ };
63
+ }
141
64
  }
142
- // It's a FilterGroup
143
- return validateAndConvertFilterGroup(filter);
65
+ return undefined;
144
66
  }
145
67
  /**
146
68
  * Validate and convert a FilterExpression (comparison filter)
@@ -222,6 +144,124 @@ function validateAndConvertFilterGroup(filter) {
222
144
  // If we reach here, the operator is unsupported
223
145
  throw new Error(`Unsupported filter operator: ${filter.op}`);
224
146
  }
147
+ /**
148
+ * Convert Lime Query filter to UI filter representation
149
+ * Throws errors for unsupported filter structures
150
+ * @param filter
151
+ */
152
+ function limeQueryToGuiFilter(filter) {
153
+ if (!filter) {
154
+ // Return empty AND instead of missing expression
155
+ // This ensures users see the "Add a condition" button
156
+ return {
157
+ filter_type: 'AND',
158
+ expressions: [],
159
+ };
160
+ }
161
+ // Check if it's a FilterExpression (has 'key' property)
162
+ if ('key' in filter) {
163
+ return validateAndConvertFilterExpression(filter);
164
+ }
165
+ // It's a FilterGroup
166
+ return validateAndConvertFilterGroup(filter);
167
+ }
168
+ /**
169
+ * Normalize filter for GUI mode by ensuring proper AND/OR wrapper structure.
170
+ * GUI mode requires filters to be wrapped in AND([OR(...)]) so users have
171
+ * access to add/remove buttons on the AND and OR components.
172
+ *
173
+ * This function ensures that:
174
+ * - Single comparisons are wrapped in AND([OR([comparison])])
175
+ * - OR groups are wrapped in AND([OR group])
176
+ * - AND groups have their comparison children wrapped in OR
177
+ * - Empty/undefined filters become AND([])
178
+ *
179
+ * When converting back to Lime Query JSON, limeQueryFilterToLimeQuery()
180
+ * automatically unwraps single-item AND/OR groups.
181
+ *
182
+ * @param filter The filter expression from limeQueryToLimeQueryFilter
183
+ * @returns Normalized filter suitable for GUI editing
184
+ */
185
+ function normalizeLimeQueryFilterForGui(filter) {
186
+ // Empty AND is already correct for GUI
187
+ if (filter.filter_type === 'AND' && filter.expressions.length === 0) {
188
+ return filter;
189
+ }
190
+ // Single comparison needs wrapping
191
+ if (filter.filter_type === 'comparison') {
192
+ return {
193
+ filter_type: 'AND',
194
+ expressions: [
195
+ {
196
+ filter_type: 'OR',
197
+ expressions: [filter],
198
+ },
199
+ ],
200
+ };
201
+ }
202
+ // OR needs wrapping in AND
203
+ if (filter.filter_type === 'OR') {
204
+ return {
205
+ filter_type: 'AND',
206
+ expressions: [filter],
207
+ };
208
+ }
209
+ // NOT needs wrapping
210
+ if (filter.filter_type === 'NOT') {
211
+ return {
212
+ filter_type: 'AND',
213
+ expressions: [
214
+ {
215
+ filter_type: 'OR',
216
+ expressions: [filter],
217
+ },
218
+ ],
219
+ };
220
+ }
221
+ // AND group - check if children need OR wrappers
222
+ if (filter.filter_type === 'AND') {
223
+ const normalizedChildren = filter.expressions.map((child) => {
224
+ // If child is already OR, keep it
225
+ if (child.filter_type === 'OR') {
226
+ return child;
227
+ }
228
+ // If child is NOT, keep it (NOT can be a direct child of AND)
229
+ if (child.filter_type === 'NOT') {
230
+ return child;
231
+ }
232
+ // If child is comparison, wrap in OR
233
+ if (child.filter_type === 'comparison') {
234
+ return {
235
+ filter_type: 'OR',
236
+ expressions: [child],
237
+ };
238
+ }
239
+ // If child is nested AND, recursively normalize and wrap in OR
240
+ if (child.filter_type === 'AND') {
241
+ return {
242
+ filter_type: 'OR',
243
+ expressions: [normalizeLimeQueryFilterForGui(child)],
244
+ };
245
+ }
246
+ // Unknown filter type, keep as is
247
+ return child;
248
+ });
249
+ return {
250
+ filter_type: 'AND',
251
+ expressions: normalizedChildren,
252
+ };
253
+ }
254
+ // Fallback: wrap in AND/OR structure
255
+ return {
256
+ filter_type: 'AND',
257
+ expressions: [
258
+ {
259
+ filter_type: 'OR',
260
+ expressions: [filter],
261
+ },
262
+ ],
263
+ };
264
+ }
225
265
 
226
266
  /**
227
267
  * Dynamic filter values and placeholders that are valid in Lime Query
@@ -600,7 +640,7 @@ function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, guiModeEnabl
600
640
  };
601
641
  }
602
642
 
603
- 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}";
643
+ 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}}";
604
644
  const LimebbLimeQueryBuilderStyle0 = limeQueryBuilderCss;
605
645
 
606
646
  var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
@@ -621,10 +661,76 @@ const LimeQueryBuilder = /*@__PURE__*/ proxyCustomElement(class LimeQueryBuilder
621
661
  this.change = createEvent(this, "change", 7);
622
662
  this.mode = 'gui';
623
663
  this.codeValue = '';
664
+ this.limetype = '';
665
+ this.filter = {
666
+ filter_type: 'AND',
667
+ expressions: [],
668
+ };
669
+ this.handleLimetypeChange = (event) => {
670
+ event.stopPropagation();
671
+ this.limetype = event.detail;
672
+ // Reset filter when limetype changes
673
+ this.filter = {
674
+ filter_type: 'AND',
675
+ expressions: [],
676
+ };
677
+ // Reset response format when limetype changes
678
+ this.internalResponseFormat = {
679
+ object: {
680
+ _id: null,
681
+ },
682
+ };
683
+ this.emitChange();
684
+ };
685
+ this.handleFilterChange = (event) => {
686
+ event.stopPropagation();
687
+ // Convert missing expression back to empty AND to keep the UI consistent
688
+ if (event.detail.filter_type === '') {
689
+ this.filter = {
690
+ filter_type: 'AND',
691
+ expressions: [],
692
+ };
693
+ }
694
+ else {
695
+ this.filter = event.detail;
696
+ }
697
+ this.emitChange();
698
+ };
699
+ this.handleResponseFormatChange = (event) => {
700
+ event.stopPropagation();
701
+ this.internalResponseFormat = event.detail;
702
+ this.emitChange();
703
+ };
704
+ this.handleLimitChange = (event) => {
705
+ event.stopPropagation();
706
+ const value = event.detail;
707
+ this.limit = value ? Number.parseInt(value, 10) : undefined;
708
+ this.emitChange();
709
+ };
624
710
  this.switchToGui = () => {
625
- this.mode = 'gui';
711
+ // Validate JSON before switching
712
+ try {
713
+ const parsed = JSON.parse(this.codeValue);
714
+ // Check if it's supported in GUI
715
+ const support = this.checkGuiSupport();
716
+ if (!support.guiSupported) {
717
+ // Don't switch if GUI can't render this query
718
+ return;
719
+ }
720
+ // Update internal state from parsed query
721
+ this.limetype = parsed.limetype || '';
722
+ this.filter = normalizeLimeQueryFilterForGui(limeQueryToGuiFilter(parsed.filter));
723
+ this.internalResponseFormat = parsed.responseFormat;
724
+ this.limit = parsed.limit;
725
+ this.mode = 'gui';
726
+ this.change.emit(parsed);
727
+ }
728
+ catch (_a) {
729
+ // Don't switch if JSON is invalid (linter will show the error)
730
+ }
626
731
  };
627
732
  this.switchToCode = () => {
733
+ this.updateCodeValue();
628
734
  this.mode = 'code';
629
735
  };
630
736
  this.handleCodeChange = (event) => {
@@ -645,43 +751,130 @@ const LimeQueryBuilder = /*@__PURE__*/ proxyCustomElement(class LimeQueryBuilder
645
751
  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);
646
752
  }
647
753
  componentWillLoad() {
648
- // Initialize code value from input prop
649
- this.codeValue = JSON.stringify(this.value || {}, null, 2);
650
754
  // Force code mode if GUI is disabled
651
755
  if (!this.guiModeEnabled) {
652
756
  this.mode = 'code';
757
+ // Initialize code value from prop
758
+ this.updateCodeValue();
759
+ return;
760
+ }
761
+ if (this.value) {
762
+ this.limetype = this.value.limetype || '';
763
+ this.filter = normalizeLimeQueryFilterForGui(limeQueryToGuiFilter(this.value.filter));
764
+ this.internalResponseFormat = this.value.responseFormat;
765
+ this.limit = this.value.limit;
766
+ }
767
+ // Initialize code value from prop
768
+ this.updateCodeValue();
769
+ // Check if GUI mode is supported
770
+ const support = this.checkGuiSupport();
771
+ if (!support.guiSupported) {
772
+ this.mode = 'code';
653
773
  }
654
774
  }
655
775
  render() {
656
776
  const guiSupported = this.checkGuiSupport();
657
- return (h("div", { key: '77e93d0277a99b8ff1c777d7ee0b63259755f740', class: "lime-query-builder" }, this.label && (h("h3", { key: '4089d69ea3404c656f1c24ec73aef6df2cc8baec', class: "lime-query-builder-label" }, this.label)), this.guiModeEnabled && (h("div", { key: '5d18a749386651cc1361b712693bad105dba9b03', class: "mode-controls" }, this.renderModeSwitch(guiSupported))), !this.guiModeEnabled || this.mode === 'code' ? (h("div", { class: "code-mode" }, this.renderCodeEditor(guiSupported))) : (h("div", { class: "gui-mode" }, h("div", { class: "placeholder-message" }, h("h4", null, "GUI Mode Not Yet Supported"), h("p", null, "The visual query builder interface is not yet available. Please use Code mode to write queries in JSON format."))))));
777
+ const showCodeMode = !this.guiModeEnabled || this.mode === 'code';
778
+ return (h("div", { key: '96d1a933f699404c3806af3742e9ad30d53562aa', class: "lime-query-builder" }, this.renderLabel(), this.renderModeControls(guiSupported), showCodeMode
779
+ ? this.renderCodeMode(guiSupported)
780
+ : this.renderGuiMode()));
781
+ }
782
+ emitChange() {
783
+ // Only emit in GUI mode
784
+ if (this.mode === 'code') {
785
+ return;
786
+ }
787
+ if (!this.limetype) {
788
+ return;
789
+ }
790
+ // Use internal state, then default to returning just _id
791
+ const responseFormat = this.internalResponseFormat || {
792
+ object: {
793
+ _id: null,
794
+ },
795
+ };
796
+ const limeQuery = {
797
+ limetype: this.limetype,
798
+ responseFormat: responseFormat,
799
+ filter: guiFilterToLimeQuery(this.filter),
800
+ };
801
+ if (this.limit !== undefined && this.limit > 0) {
802
+ limeQuery.limit = this.limit;
803
+ }
804
+ this.change.emit(limeQuery);
805
+ }
806
+ updateCodeValue() {
807
+ if (!this.limetype) {
808
+ this.codeValue = JSON.stringify(this.value || {}, null, 2);
809
+ return;
810
+ }
811
+ // Use internal state, then default to returning just _id
812
+ const responseFormat = this.internalResponseFormat || {
813
+ object: {
814
+ _id: null,
815
+ },
816
+ };
817
+ const limeQuery = {
818
+ limetype: this.limetype,
819
+ responseFormat: responseFormat,
820
+ filter: guiFilterToLimeQuery(this.filter),
821
+ };
822
+ if (this.limit !== undefined && this.limit > 0) {
823
+ limeQuery.limit = this.limit;
824
+ }
825
+ this.codeValue = JSON.stringify(limeQuery, null, 2);
658
826
  }
659
827
  checkGuiSupport() {
660
- if (!this.limetypes || !this.codeValue) {
828
+ if (!this.limetypes) {
661
829
  // Can't validate yet, assume all is good
662
830
  return {
663
831
  valid: true,
664
- guiSupported: false,
832
+ guiSupported: true,
665
833
  validationErrors: [],
666
834
  guiLimitations: [],
667
835
  };
668
836
  }
669
- // Parse and validate the code value
670
- let limeQueryToCheck;
671
- try {
672
- limeQueryToCheck = JSON.parse(this.codeValue);
837
+ // When in code mode, validate the parsed code value instead of current state
838
+ let queryToCheck;
839
+ if (this.mode === 'code' && this.codeValue) {
840
+ try {
841
+ queryToCheck = JSON.parse(this.codeValue);
842
+ }
843
+ catch (_a) {
844
+ return {
845
+ valid: false,
846
+ guiSupported: false,
847
+ validationErrors: ['Invalid JSON'],
848
+ guiLimitations: [],
849
+ };
850
+ }
673
851
  }
674
- catch (_a) {
675
- return {
676
- valid: false,
677
- guiSupported: false,
678
- validationErrors: ['Invalid JSON'],
679
- guiLimitations: [],
852
+ else {
853
+ // Build query from current GUI state
854
+ if (!this.limetype) {
855
+ return {
856
+ valid: true,
857
+ guiSupported: true,
858
+ validationErrors: [],
859
+ guiLimitations: [],
860
+ };
861
+ }
862
+ const responseFormat = this
863
+ .internalResponseFormat || {
864
+ object: {
865
+ _id: null,
866
+ },
867
+ };
868
+ queryToCheck = {
869
+ limetype: this.limetype,
870
+ responseFormat: responseFormat,
871
+ filter: guiFilterToLimeQuery(this.filter),
680
872
  };
873
+ if (this.limit !== undefined && this.limit > 0) {
874
+ queryToCheck.limit = this.limit;
875
+ }
681
876
  }
682
- // In code-only mode, we don't track activeLimetype separately
683
- // Pass undefined since it's not needed for code mode validation
684
- return isLimeQuerySupported(limeQueryToCheck, this.limetypes, undefined, this.guiModeEnabled);
877
+ return isLimeQuerySupported(queryToCheck, this.limetypes, this.activeLimetype, this.guiModeEnabled);
685
878
  }
686
879
  renderModeSwitch(support) {
687
880
  const guiDisabled = !support.guiSupported;
@@ -694,15 +887,60 @@ const LimeQueryBuilder = /*@__PURE__*/ proxyCustomElement(class LimeQueryBuilder
694
887
  !guiSupported.guiSupported &&
695
888
  guiSupported.guiLimitations.length > 0 && (h("div", { class: "gui-limitations" }, h("strong", null, "Cannot switch to GUI mode:"), h("ul", null, guiSupported.guiLimitations.map((limitation) => (h("li", null, limitation))))))));
696
889
  }
890
+ renderLimetypeSection() {
891
+ return (h("div", { class: "limetype-section" }, 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 })));
892
+ }
893
+ renderResponseFormatSection() {
894
+ if (!this.limetype) {
895
+ return;
896
+ }
897
+ return (h("div", { class: "response-format-section" }, h("limebb-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalResponseFormat, onChange: this.handleResponseFormatChange })));
898
+ }
899
+ renderFilterSection() {
900
+ if (!this.limetype) {
901
+ return;
902
+ }
903
+ return (h("div", { class: "filter-section" }, h("h4", { class: "section-label" }, "Filter Conditions"), h("limebb-lime-query-filter-expression", { platform: this.platform, context: this.context, limetype: this.limetype, activeLimetype: this.activeLimetype, expression: this.filter, onExpressionChange: this.handleFilterChange })));
904
+ }
905
+ renderQueryOptionsSection() {
906
+ var _a;
907
+ if (!this.limetype) {
908
+ return;
909
+ }
910
+ return (h("div", { class: "query-options-section" }, h("h4", { class: "section-label" }, "Query Options"), h("div", { class: "query-options-controls" }, 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 }))));
911
+ }
912
+ renderGuiMode() {
913
+ return (h("div", { class: "gui-mode" }, this.renderLimetypeSection(), this.renderResponseFormatSection(), this.renderFilterSection(), this.renderQueryOptionsSection()));
914
+ }
915
+ renderLabel() {
916
+ if (!this.label) {
917
+ return;
918
+ }
919
+ return h("h3", { class: "lime-query-builder-label" }, this.label);
920
+ }
921
+ renderModeControls(support) {
922
+ if (!this.guiModeEnabled) {
923
+ return;
924
+ }
925
+ return (h("div", { class: "mode-controls" }, this.renderModeSwitch(support)));
926
+ }
927
+ renderCodeMode(support) {
928
+ return h("div", { class: "code-mode" }, this.renderCodeEditor(support));
929
+ }
697
930
  static get style() { return LimebbLimeQueryBuilderStyle0; }
698
931
  }, [1, "limebb-lime-query-builder", {
699
932
  "platform": [16],
700
933
  "context": [16],
701
934
  "value": [16],
702
935
  "label": [1],
936
+ "activeLimetype": [1, "active-limetype"],
703
937
  "limetypes": [32],
704
938
  "mode": [32],
705
- "codeValue": [32]
939
+ "codeValue": [32],
940
+ "limetype": [32],
941
+ "filter": [32],
942
+ "internalResponseFormat": [32],
943
+ "limit": [32]
706
944
  }]);
707
945
  __decorate([
708
946
  Te()
@@ -711,13 +949,63 @@ function defineCustomElement$1() {
711
949
  if (typeof customElements === "undefined") {
712
950
  return;
713
951
  }
714
- const components = ["limebb-lime-query-builder"];
952
+ const components = ["limebb-lime-query-builder", "limebb-lime-query-filter-and", "limebb-lime-query-filter-comparison", "limebb-lime-query-filter-expression", "limebb-lime-query-filter-not", "limebb-lime-query-filter-or", "limebb-lime-query-value-input", "limebb-limetype-field", "limebb-property-selector", "limebb-response-format-editor", "limebb-response-format-item"];
715
953
  components.forEach(tagName => { switch (tagName) {
716
954
  case "limebb-lime-query-builder":
717
955
  if (!customElements.get(tagName)) {
718
956
  customElements.define(tagName, LimeQueryBuilder);
719
957
  }
720
958
  break;
959
+ case "limebb-lime-query-filter-and":
960
+ if (!customElements.get(tagName)) {
961
+ defineCustomElement$b();
962
+ }
963
+ break;
964
+ case "limebb-lime-query-filter-comparison":
965
+ if (!customElements.get(tagName)) {
966
+ defineCustomElement$a();
967
+ }
968
+ break;
969
+ case "limebb-lime-query-filter-expression":
970
+ if (!customElements.get(tagName)) {
971
+ defineCustomElement$9();
972
+ }
973
+ break;
974
+ case "limebb-lime-query-filter-not":
975
+ if (!customElements.get(tagName)) {
976
+ defineCustomElement$8();
977
+ }
978
+ break;
979
+ case "limebb-lime-query-filter-or":
980
+ if (!customElements.get(tagName)) {
981
+ defineCustomElement$7();
982
+ }
983
+ break;
984
+ case "limebb-lime-query-value-input":
985
+ if (!customElements.get(tagName)) {
986
+ defineCustomElement$6();
987
+ }
988
+ break;
989
+ case "limebb-limetype-field":
990
+ if (!customElements.get(tagName)) {
991
+ defineCustomElement$5();
992
+ }
993
+ break;
994
+ case "limebb-property-selector":
995
+ if (!customElements.get(tagName)) {
996
+ defineCustomElement$4();
997
+ }
998
+ break;
999
+ case "limebb-response-format-editor":
1000
+ if (!customElements.get(tagName)) {
1001
+ defineCustomElement$3();
1002
+ }
1003
+ break;
1004
+ case "limebb-response-format-item":
1005
+ if (!customElements.get(tagName)) {
1006
+ defineCustomElement$2();
1007
+ }
1008
+ break;
721
1009
  } });
722
1010
  }
723
1011