@limetech/lime-crm-building-blocks 1.100.1 → 1.102.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 (131) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/lime-crm-building-blocks.cjs.js +1 -1
  3. package/dist/cjs/lime-query-validation-6be10fa7.js +558 -0
  4. package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +22 -426
  5. package/dist/cjs/limebb-lime-query-filter-builder_3.cjs.entry.js +86 -243
  6. package/dist/cjs/limebb-lime-query-filter-comparison_2.cjs.entry.js +1 -1
  7. package/dist/cjs/limebb-lime-query-filter-group_3.cjs.entry.js +2 -2
  8. package/dist/cjs/limebb-lime-query-order-by-item.cjs.entry.js +51 -0
  9. package/dist/cjs/limebb-lime-query-response-format-builder.cjs.entry.js +242 -0
  10. package/dist/cjs/limebb-lime-query-response-format-editor_2.cjs.entry.js +322 -0
  11. package/dist/cjs/limebb-live-docs-info.cjs.entry.js +2 -2
  12. package/dist/cjs/limebb-locale-picker.cjs.entry.js +1 -1
  13. package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +2 -2
  14. package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +3 -3
  15. package/dist/cjs/limebb-notification-item.cjs.entry.js +1 -1
  16. package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
  17. package/dist/cjs/limebb-text-editor.cjs.entry.js +1 -1
  18. package/dist/cjs/limebb-trend-indicator.cjs.entry.js +1 -1
  19. package/dist/cjs/loader.cjs.js +1 -1
  20. package/dist/collection/collection-manifest.json +5 -2
  21. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison.js +1 -1
  22. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-group.js +1 -1
  23. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-not.js +1 -1
  24. package/dist/collection/components/lime-query-builder/lime-query-builder.css +2 -5
  25. package/dist/collection/components/lime-query-builder/lime-query-builder.js +20 -20
  26. package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.css +91 -0
  27. package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.js +355 -0
  28. package/dist/collection/components/lime-query-builder/lime-query-validation.js +154 -7
  29. package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +1 -1
  30. package/dist/collection/components/lime-query-builder/order-by/order-by-editor.css +72 -0
  31. package/dist/collection/components/lime-query-builder/order-by/order-by-editor.js +252 -0
  32. package/dist/collection/components/lime-query-builder/order-by/order-by-item.css +45 -0
  33. package/dist/collection/components/lime-query-builder/order-by/order-by-item.js +173 -0
  34. package/dist/collection/components/lime-query-builder/{response-format-editor.css → response-format/response-format-editor.css} +1 -1
  35. package/dist/collection/components/lime-query-builder/{response-format-editor.js → response-format/response-format-editor.js} +5 -5
  36. package/dist/collection/components/lime-query-builder/response-format/response-format-helpers.js +92 -0
  37. package/dist/collection/components/lime-query-builder/{response-format-item.css → response-format/response-format-item.css} +1 -1
  38. package/dist/collection/components/lime-query-builder/{response-format-item.js → response-format/response-format-item.js} +6 -6
  39. package/dist/collection/components/limeobject/file-viewer/live-docs-info.js +2 -2
  40. package/dist/collection/components/locale-picker/locale-picker.js +1 -1
  41. package/dist/collection/components/notification-list/notification-item/notification-item.js +1 -1
  42. package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
  43. package/dist/collection/components/summary-popover/summary-popover.js +3 -3
  44. package/dist/collection/components/text-editor/mention-group-counter.js +2 -2
  45. package/dist/collection/components/text-editor/text-editor.js +1 -1
  46. package/dist/collection/components/trend-indicator/trend-indicator.js +1 -1
  47. package/dist/components/lime-query-filter-comparison.js +1 -1
  48. package/dist/components/lime-query-filter-expression.js +2 -2
  49. package/dist/components/lime-query-validation.js +555 -0
  50. package/dist/components/lime-query-value-input.js +1 -1
  51. package/dist/components/limebb-lime-query-builder.js +53 -444
  52. package/dist/components/limebb-lime-query-order-by-editor.d.ts +11 -0
  53. package/dist/components/limebb-lime-query-order-by-editor.js +6 -0
  54. package/dist/components/limebb-lime-query-order-by-item.d.ts +11 -0
  55. package/dist/components/limebb-lime-query-order-by-item.js +6 -0
  56. package/dist/components/limebb-lime-query-response-format-builder.d.ts +11 -0
  57. package/dist/components/limebb-lime-query-response-format-builder.js +283 -0
  58. package/dist/components/limebb-lime-query-response-format-editor.d.ts +11 -0
  59. package/dist/components/{limebb-response-format-editor.js → limebb-lime-query-response-format-editor.js} +2 -2
  60. package/dist/components/limebb-lime-query-response-format-item.d.ts +11 -0
  61. package/dist/components/{limebb-response-format-item.js → limebb-lime-query-response-format-item.js} +2 -2
  62. package/dist/components/limebb-locale-picker.js +1 -1
  63. package/dist/components/limebb-mention-group-counter.js +2 -2
  64. package/dist/components/limebb-percentage-visualizer.js +2 -2
  65. package/dist/components/limebb-text-editor.js +1 -1
  66. package/dist/components/limebb-trend-indicator.js +1 -1
  67. package/dist/components/limetype-field.js +1 -1
  68. package/dist/components/live-docs-info.js +2 -2
  69. package/dist/components/notification-item.js +1 -1
  70. package/dist/components/order-by-editor.js +123 -0
  71. package/dist/components/order-by-item.js +73 -0
  72. package/dist/components/property-selector.js +1 -1
  73. package/dist/components/response-format-editor.js +11 -11
  74. package/dist/components/response-format-item.js +9 -9
  75. package/dist/components/summary-popover.js +3 -3
  76. package/dist/esm/lime-crm-building-blocks.js +1 -1
  77. package/dist/esm/lime-query-validation-573223a5.js +555 -0
  78. package/dist/esm/limebb-lime-query-builder.entry.js +22 -426
  79. package/dist/esm/limebb-lime-query-filter-builder_3.entry.js +86 -243
  80. package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +1 -1
  81. package/dist/esm/limebb-lime-query-filter-group_3.entry.js +3 -3
  82. package/dist/esm/limebb-lime-query-order-by-item.entry.js +47 -0
  83. package/dist/esm/limebb-lime-query-response-format-builder.entry.js +238 -0
  84. package/dist/esm/limebb-lime-query-response-format-editor_2.entry.js +317 -0
  85. package/dist/esm/limebb-live-docs-info.entry.js +2 -2
  86. package/dist/esm/limebb-locale-picker.entry.js +1 -1
  87. package/dist/esm/limebb-mention-group-counter.entry.js +2 -2
  88. package/dist/esm/limebb-navigation-button_2.entry.js +3 -3
  89. package/dist/esm/limebb-notification-item.entry.js +1 -1
  90. package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
  91. package/dist/esm/limebb-property-selector.entry.js +1 -1
  92. package/dist/esm/limebb-text-editor.entry.js +1 -1
  93. package/dist/esm/limebb-trend-indicator.entry.js +1 -1
  94. package/dist/esm/loader.js +1 -1
  95. package/dist/esm/{property-resolution-fde2375e.js → property-resolution-c21a1369.js} +1 -1
  96. package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
  97. package/dist/lime-crm-building-blocks/{p-79b8b09b.entry.js → p-0de79b7f.entry.js} +1 -1
  98. package/dist/lime-crm-building-blocks/{p-1034b4a5.entry.js → p-0f7135ff.entry.js} +1 -1
  99. package/dist/lime-crm-building-blocks/{p-6aa216ec.entry.js → p-186e9f1a.entry.js} +1 -1
  100. package/dist/lime-crm-building-blocks/p-289ce8b9.entry.js +1 -0
  101. package/dist/lime-crm-building-blocks/p-3351395b.entry.js +1 -0
  102. package/dist/lime-crm-building-blocks/p-33e6d0ec.entry.js +1 -0
  103. package/dist/lime-crm-building-blocks/{p-8581245a.entry.js → p-3d1be1c9.entry.js} +1 -1
  104. package/dist/lime-crm-building-blocks/{p-b57dafef.entry.js → p-577d8909.entry.js} +1 -1
  105. package/dist/lime-crm-building-blocks/{p-89a6c396.entry.js → p-6579412e.entry.js} +1 -1
  106. package/dist/lime-crm-building-blocks/{p-8fb2e192.entry.js → p-6f6fed59.entry.js} +1 -1
  107. package/dist/lime-crm-building-blocks/{p-58782467.entry.js → p-7e5528f6.entry.js} +1 -1
  108. package/dist/lime-crm-building-blocks/{p-2048ac67.entry.js → p-a9ac501f.entry.js} +1 -1
  109. package/dist/lime-crm-building-blocks/{p-f79e354b.entry.js → p-abfc7815.entry.js} +1 -1
  110. package/dist/lime-crm-building-blocks/{p-e0ab1554.js → p-b748c770.js} +1 -1
  111. package/dist/lime-crm-building-blocks/p-be845252.entry.js +1 -0
  112. package/dist/lime-crm-building-blocks/p-cb338753.entry.js +1 -0
  113. package/dist/lime-crm-building-blocks/{p-76d81eee.entry.js → p-d0721b22.entry.js} +1 -1
  114. package/dist/lime-crm-building-blocks/p-fa2da6bc.js +1 -0
  115. package/dist/types/components/lime-query-builder/lime-query-builder.d.ts +9 -6
  116. package/dist/types/components/lime-query-builder/lime-query-response-format-builder.d.ts +102 -0
  117. package/dist/types/components/lime-query-builder/lime-query-validation.d.ts +13 -0
  118. package/dist/types/components/lime-query-builder/order-by/order-by-editor.d.ts +58 -0
  119. package/dist/types/components/lime-query-builder/order-by/order-by-item.d.ts +37 -0
  120. package/dist/types/components/lime-query-builder/{response-format-editor.d.ts → response-format/response-format-editor.d.ts} +2 -2
  121. package/dist/types/components/lime-query-builder/response-format/response-format-helpers.d.ts +42 -0
  122. package/dist/types/components/lime-query-builder/{response-format-item.d.ts → response-format/response-format-item.d.ts} +2 -2
  123. package/dist/types/components.d.ts +667 -279
  124. package/package.json +1 -1
  125. package/dist/cjs/limebb-response-format-item.cjs.entry.js +0 -80
  126. package/dist/components/limebb-response-format-editor.d.ts +0 -11
  127. package/dist/components/limebb-response-format-item.d.ts +0 -11
  128. package/dist/esm/limebb-response-format-item.entry.js +0 -76
  129. package/dist/lime-crm-building-blocks/p-244ee55b.entry.js +0 -1
  130. package/dist/lime-crm-building-blocks/p-323c49bc.entry.js +0 -1
  131. package/dist/lime-crm-building-blocks/p-f22b66f6.entry.js +0 -1
@@ -0,0 +1,355 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
4
+ r = Reflect.decorate(decorators, target, key, desc);
5
+ else
6
+ for (var i = decorators.length - 1; i >= 0; i--)
7
+ if (d = decorators[i])
8
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ import { h } from "@stencil/core";
12
+ import { SelectLimeTypes as Limetypes, } from "@limetech/lime-web-components";
13
+ import { parseResponseFormat, stringifyResponseFormat, getDefaultResponseFormat, } from "./response-format/response-format-helpers";
14
+ import { validateResponseFormatOnly, } from "./lime-query-validation";
15
+ /**
16
+ * Response Format Builder
17
+ *
18
+ * A focused component for editing Lime Query ResponseFormat in isolation.
19
+ * Supports both GUI and code modes for maximum flexibility.
20
+ *
21
+ * Use this component when you need to configure which properties to return
22
+ * from a query, but don't need filter, limit, or other query parameters.
23
+ *
24
+ * **Features**:
25
+ * - **GUI Mode**: Visual property selector with relation navigation
26
+ * - **Code Mode**: JSON editor for ResponseFormat structure
27
+ * - **Validation**: Ensures JSON is valid ResponseFormat (rejects other fields)
28
+ * - **Mode Toggle**: Switch between GUI and code modes seamlessly
29
+ * - **Feature Flag**: Respects `useLimeQueryBuilderGuiMode` setting
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * <limebb-lime-query-response-format-builder
34
+ * platform={this.platform}
35
+ * context={this.context}
36
+ * limetype="deal"
37
+ * value={this.responseFormat}
38
+ * label="Select Properties to Return"
39
+ * onChange={this.handleChange}
40
+ * />
41
+ * ```
42
+ *
43
+ * @exampleComponent limebb-example-response-format-builder-basic
44
+ * @private
45
+ */
46
+ export class LimeQueryResponseFormatBuilder {
47
+ constructor() {
48
+ /**
49
+ * Optional label for the builder
50
+ */
51
+ this.label = 'Response Format';
52
+ this.mode = 'gui';
53
+ this.codeValue = '';
54
+ /**
55
+ * Switch from code mode to GUI mode
56
+ */
57
+ this.switchToGui = () => {
58
+ // Validate JSON before switching
59
+ try {
60
+ const parsed = parseResponseFormat(this.codeValue);
61
+ // Check if it's supported in GUI
62
+ const support = validateResponseFormatOnly(parsed, this.limetypes, this.limetype, this.guiModeEnabled);
63
+ if (!support.guiSupported) {
64
+ // Don't switch if GUI can't render this response format
65
+ return;
66
+ }
67
+ // Update internal state from parsed value
68
+ this.internalValue = parsed;
69
+ this.mode = 'gui';
70
+ this.change.emit(parsed);
71
+ }
72
+ catch (_a) {
73
+ // Don't switch if JSON is invalid (linter will show the error)
74
+ }
75
+ };
76
+ /**
77
+ * Switch from GUI mode to code mode
78
+ */
79
+ this.switchToCode = () => {
80
+ this.updateCodeValue();
81
+ this.mode = 'code';
82
+ };
83
+ /**
84
+ * Handle code editor changes
85
+ * @param event
86
+ */
87
+ this.handleCodeChange = (event) => {
88
+ event.stopPropagation();
89
+ this.codeValue = event.detail;
90
+ // Try to parse and emit if valid
91
+ try {
92
+ const parsed = parseResponseFormat(this.codeValue);
93
+ this.internalValue = parsed;
94
+ this.change.emit(parsed);
95
+ }
96
+ catch (_a) {
97
+ // Invalid JSON - don't emit change
98
+ // Validation errors will be shown by checkGuiSupport()
99
+ }
100
+ };
101
+ /**
102
+ * Handle GUI mode changes
103
+ * @param event
104
+ */
105
+ this.handleGuiChange = (event) => {
106
+ event.stopPropagation();
107
+ this.internalValue = event.detail;
108
+ this.updateCodeValue();
109
+ this.change.emit(event.detail);
110
+ };
111
+ }
112
+ /**
113
+ * Check if GUI mode is enabled via feature flag
114
+ */
115
+ get guiModeEnabled() {
116
+ var _a, _b, _c;
117
+ 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);
118
+ }
119
+ componentWillLoad() {
120
+ // Initialize internal value
121
+ this.internalValue = this.value || getDefaultResponseFormat();
122
+ // Update code value from internal value
123
+ this.updateCodeValue();
124
+ // Force code mode if GUI is disabled
125
+ if (!this.guiModeEnabled) {
126
+ this.mode = 'code';
127
+ return;
128
+ }
129
+ // Check if GUI mode is supported for current value
130
+ const support = this.checkGuiSupport();
131
+ if (!support.guiSupported) {
132
+ this.mode = 'code';
133
+ }
134
+ }
135
+ componentWillUpdate() {
136
+ // Sync internal value when prop changes externally
137
+ if (this.value && this.mode === 'gui') {
138
+ this.internalValue = this.value;
139
+ }
140
+ }
141
+ render() {
142
+ const guiSupported = this.checkGuiSupport();
143
+ return (h("div", { key: '2b5e4ee360d6997a176d24e5a7aa36158461ad4a', class: "response-format-builder" }, this.label && h("h3", { key: 'b81f58824e4cf3114efd4d2978c833f7f06f2004', class: "builder-label" }, this.label), this.guiModeEnabled && (h("div", { key: '1b2ec0cd39909568732be94707a9dcadaa4a1223', class: "mode-controls" }, this.renderModeSwitch(guiSupported))), !this.guiModeEnabled || this.mode === 'code' ? (h("div", { class: "code-mode" }, this.renderCodeEditor(guiSupported))) : (h("div", { class: "gui-mode" }, this.renderGuiMode()))));
144
+ }
145
+ renderModeSwitch(support) {
146
+ const guiDisabled = !support.guiSupported;
147
+ return (h("div", { class: "mode-switch" }, h("limel-button", { label: "GUI", primary: this.mode === 'gui', disabled: guiDisabled, onClick: this.switchToGui }), h("limel-button", { label: "Code", primary: this.mode === 'code', onClick: this.switchToCode })));
148
+ }
149
+ renderCodeEditor(support) {
150
+ return (h("div", { class: "code-editor-container" }, h("limel-code-editor", { value: this.codeValue, language: "json", lineNumbers: true, fold: true, lint: true, onChange: this.handleCodeChange }), !support.valid && support.validationErrors.length > 0 && (h("div", { class: "validation-errors" }, h("strong", null, "Invalid Response Format:"), h("ul", null, support.validationErrors.map((error) => (h("li", null, error)))))), this.guiModeEnabled &&
151
+ support.valid &&
152
+ !support.guiSupported &&
153
+ support.guiLimitations.length > 0 && (h("div", { class: "gui-limitations" }, h("strong", null, "Cannot switch to GUI mode:"), h("ul", null, support.guiLimitations.map((limitation) => (h("li", null, limitation))))))));
154
+ }
155
+ renderGuiMode() {
156
+ return (h("limebb-lime-query-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalValue, onChange: this.handleGuiChange }));
157
+ }
158
+ /**
159
+ * Check if current value can be rendered in GUI mode
160
+ */
161
+ checkGuiSupport() {
162
+ if (!this.limetypes) {
163
+ return {
164
+ valid: false,
165
+ guiSupported: false,
166
+ validationErrors: ['Limetypes not loaded'],
167
+ guiLimitations: [],
168
+ };
169
+ }
170
+ // Try to parse code value if in code mode
171
+ let valueToCheck;
172
+ if (this.mode === 'code') {
173
+ try {
174
+ valueToCheck = parseResponseFormat(this.codeValue);
175
+ }
176
+ catch (error) {
177
+ return {
178
+ valid: false,
179
+ guiSupported: false,
180
+ validationErrors: [error.message],
181
+ guiLimitations: [],
182
+ };
183
+ }
184
+ }
185
+ else {
186
+ valueToCheck = this.internalValue;
187
+ }
188
+ return validateResponseFormatOnly(valueToCheck, this.limetypes, this.limetype, this.guiModeEnabled);
189
+ }
190
+ /**
191
+ * Update code value from internal state
192
+ */
193
+ updateCodeValue() {
194
+ this.codeValue = stringifyResponseFormat(this.internalValue);
195
+ }
196
+ static get is() { return "limebb-lime-query-response-format-builder"; }
197
+ static get encapsulation() { return "shadow"; }
198
+ static get originalStyleUrls() {
199
+ return {
200
+ "$": ["lime-query-response-format-builder.scss"]
201
+ };
202
+ }
203
+ static get styleUrls() {
204
+ return {
205
+ "$": ["lime-query-response-format-builder.css"]
206
+ };
207
+ }
208
+ static get properties() {
209
+ return {
210
+ "platform": {
211
+ "type": "unknown",
212
+ "mutable": false,
213
+ "complexType": {
214
+ "original": "LimeWebComponentPlatform",
215
+ "resolved": "LimeWebComponentPlatform",
216
+ "references": {
217
+ "LimeWebComponentPlatform": {
218
+ "location": "import",
219
+ "path": "@limetech/lime-web-components",
220
+ "id": "node_modules::LimeWebComponentPlatform"
221
+ }
222
+ }
223
+ },
224
+ "required": false,
225
+ "optional": false,
226
+ "docs": {
227
+ "tags": [],
228
+ "text": "Platform service provider"
229
+ },
230
+ "getter": false,
231
+ "setter": false
232
+ },
233
+ "context": {
234
+ "type": "unknown",
235
+ "mutable": false,
236
+ "complexType": {
237
+ "original": "LimeWebComponentContext",
238
+ "resolved": "LimeWebComponentContext",
239
+ "references": {
240
+ "LimeWebComponentContext": {
241
+ "location": "import",
242
+ "path": "@limetech/lime-web-components",
243
+ "id": "node_modules::LimeWebComponentContext"
244
+ }
245
+ }
246
+ },
247
+ "required": false,
248
+ "optional": false,
249
+ "docs": {
250
+ "tags": [],
251
+ "text": "Component context"
252
+ },
253
+ "getter": false,
254
+ "setter": false
255
+ },
256
+ "limetype": {
257
+ "type": "string",
258
+ "mutable": false,
259
+ "complexType": {
260
+ "original": "string",
261
+ "resolved": "string",
262
+ "references": {}
263
+ },
264
+ "required": false,
265
+ "optional": false,
266
+ "docs": {
267
+ "tags": [],
268
+ "text": "The limetype to configure response format for\nThis is fixed and not editable by the user"
269
+ },
270
+ "getter": false,
271
+ "setter": false,
272
+ "attribute": "limetype",
273
+ "reflect": false
274
+ },
275
+ "value": {
276
+ "type": "unknown",
277
+ "mutable": false,
278
+ "complexType": {
279
+ "original": "ResponseFormat",
280
+ "resolved": "ResponseFormat | undefined",
281
+ "references": {
282
+ "ResponseFormat": {
283
+ "location": "import",
284
+ "path": "./lime-query.types",
285
+ "id": "src/components/lime-query-builder/lime-query.types.ts::ResponseFormat"
286
+ }
287
+ }
288
+ },
289
+ "required": false,
290
+ "optional": true,
291
+ "docs": {
292
+ "tags": [],
293
+ "text": "Current response format value"
294
+ },
295
+ "getter": false,
296
+ "setter": false
297
+ },
298
+ "label": {
299
+ "type": "string",
300
+ "mutable": false,
301
+ "complexType": {
302
+ "original": "string",
303
+ "resolved": "string",
304
+ "references": {}
305
+ },
306
+ "required": false,
307
+ "optional": false,
308
+ "docs": {
309
+ "tags": [],
310
+ "text": "Optional label for the builder"
311
+ },
312
+ "getter": false,
313
+ "setter": false,
314
+ "attribute": "label",
315
+ "reflect": false,
316
+ "defaultValue": "'Response Format'"
317
+ }
318
+ };
319
+ }
320
+ static get states() {
321
+ return {
322
+ "limetypes": {},
323
+ "mode": {},
324
+ "codeValue": {},
325
+ "internalValue": {}
326
+ };
327
+ }
328
+ static get events() {
329
+ return [{
330
+ "method": "change",
331
+ "name": "change",
332
+ "bubbles": true,
333
+ "cancelable": true,
334
+ "composed": true,
335
+ "docs": {
336
+ "tags": [],
337
+ "text": "Emitted when the response format changes"
338
+ },
339
+ "complexType": {
340
+ "original": "ResponseFormat",
341
+ "resolved": "ResponseFormat",
342
+ "references": {
343
+ "ResponseFormat": {
344
+ "location": "import",
345
+ "path": "./lime-query.types",
346
+ "id": "src/components/lime-query-builder/lime-query.types.ts::ResponseFormat"
347
+ }
348
+ }
349
+ }
350
+ }];
351
+ }
352
+ }
353
+ __decorate([
354
+ Limetypes()
355
+ ], LimeQueryResponseFormatBuilder.prototype, "limetypes", void 0);
@@ -328,6 +328,113 @@ function validateLimeQueryFilterInternal(filter, activeLimetype, limetypes, guiM
328
328
  }
329
329
  return errors;
330
330
  }
331
+ /**
332
+ * Validate orderBy specification
333
+ * @param orderBy Array of orderBy items to validate
334
+ * @param limetypes Record of all available limetypes
335
+ * @param limetype The limetype for this Lime Query
336
+ * @returns Array of validation error messages
337
+ */
338
+ function validateOrderBy(orderBy, limetypes, limetype) {
339
+ const errors = [];
340
+ if (!Array.isArray(orderBy)) {
341
+ errors.push('orderBy must be an array');
342
+ return errors;
343
+ }
344
+ if (!limetype || !limetypes[limetype]) {
345
+ // Can't validate property paths without limetype
346
+ return errors;
347
+ }
348
+ for (const [index, item] of orderBy.entries()) {
349
+ const itemErrors = validateOrderByItem(item, index, limetypes, limetype);
350
+ errors.push(...itemErrors);
351
+ }
352
+ return errors;
353
+ }
354
+ /**
355
+ * Validate a single orderBy item
356
+ * @param item The orderBy item to validate
357
+ * @param index The index of the item in the array (for error messages)
358
+ * @param limetypes Record of all available limetypes
359
+ * @param limetype The limetype for this Lime Query
360
+ * @returns Array of validation error messages for this item
361
+ */
362
+ function validateOrderByItem(item, index, limetypes, limetype) {
363
+ const errors = [];
364
+ const objectError = validateOrderByItemIsObject(item, index);
365
+ if (objectError) {
366
+ return [objectError];
367
+ }
368
+ const keys = Object.keys(item);
369
+ const keyError = validateOrderByItemHasSingleKey(keys, index);
370
+ if (keyError) {
371
+ return [keyError];
372
+ }
373
+ const propertyPath = keys[0];
374
+ const direction = item[propertyPath];
375
+ const directionError = validateOrderByDirection(direction, index);
376
+ if (directionError) {
377
+ errors.push(directionError);
378
+ }
379
+ const pathError = validateOrderByPropertyPath(propertyPath, limetypes, limetype, index);
380
+ if (pathError) {
381
+ errors.push(pathError);
382
+ }
383
+ return errors;
384
+ }
385
+ /**
386
+ * Validate that the orderBy item is an object
387
+ * @param item
388
+ * @param index
389
+ */
390
+ function validateOrderByItemIsObject(item, index) {
391
+ if (typeof item !== 'object' || item === null) {
392
+ return `orderBy[${index}] must be an object`;
393
+ }
394
+ return null;
395
+ }
396
+ /**
397
+ * Validate that the orderBy item has exactly one property key
398
+ * @param keys
399
+ * @param index
400
+ */
401
+ function validateOrderByItemHasSingleKey(keys, index) {
402
+ if (keys.length === 0) {
403
+ return `orderBy[${index}] must have a property path`;
404
+ }
405
+ if (keys.length > 1) {
406
+ return `orderBy[${index}] must have exactly one property, got ${keys.length}`;
407
+ }
408
+ return null;
409
+ }
410
+ /**
411
+ * Validate that the sort direction is either ASC or DESC
412
+ * @param direction
413
+ * @param index
414
+ */
415
+ function validateOrderByDirection(direction, index) {
416
+ if (direction !== 'ASC' && direction !== 'DESC') {
417
+ return `orderBy[${index}]: direction must be 'ASC' or 'DESC', got '${direction}'`;
418
+ }
419
+ return null;
420
+ }
421
+ /**
422
+ * Validate that the property path exists on the limetype
423
+ * @param propertyPath
424
+ * @param limetypes
425
+ * @param limetype
426
+ * @param index
427
+ */
428
+ function validateOrderByPropertyPath(propertyPath, limetypes, limetype, index) {
429
+ if (!propertyPath || propertyPath === '') {
430
+ return null;
431
+ }
432
+ const property = getPropertyFromPath(limetypes, limetype, propertyPath);
433
+ if (!property) {
434
+ return `orderBy[${index}]: property path '${propertyPath}' does not exist on limetype '${limetype}'`;
435
+ }
436
+ return null;
437
+ }
331
438
  /**
332
439
  * Validate Lime Query response format and collect errors/limitations
333
440
  * @param responseFormat The response format to validate
@@ -377,14 +484,14 @@ export function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, guiMo
377
484
  if (limeQuery.offset !== undefined && !limeQuery.orderBy) {
378
485
  validationErrors.push('offset requires orderBy to be specified');
379
486
  }
487
+ // Validate orderBy
488
+ if (limeQuery.orderBy) {
489
+ const orderByErrors = validateOrderBy(limeQuery.orderBy, limetypes, limeQuery.limetype);
490
+ validationErrors.push(...orderByErrors);
491
+ }
380
492
  // Check for GUI-unsupported top-level properties
381
- if (guiModeEnabled) {
382
- if (limeQuery.orderBy) {
383
- guiLimitations.push('orderBy is not yet supported in GUI mode');
384
- }
385
- if (limeQuery.offset !== undefined) {
386
- guiLimitations.push('offset is not yet supported in GUI mode');
387
- }
493
+ if (guiModeEnabled && limeQuery.offset !== undefined) {
494
+ guiLimitations.push('offset is not yet supported in GUI mode');
388
495
  }
389
496
  // Validate filter
390
497
  if (limeQuery.filter) {
@@ -404,3 +511,43 @@ export function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, guiMo
404
511
  guiLimitations,
405
512
  };
406
513
  }
514
+ // ============================================================================
515
+ // Specialized Validators for Modular Builders
516
+ // ============================================================================
517
+ /**
518
+ * Validate a ResponseFormat in isolation (for response-format-builder)
519
+ *
520
+ * This validator is designed for the response-format-builder component,
521
+ * which only handles ResponseFormat editing without the full LimeQuery context.
522
+ *
523
+ * @param responseFormat - The response format to validate
524
+ * @param limetypes - Record of all available limetypes
525
+ * @param limetype - The limetype context for validation
526
+ * @param guiModeEnabled - Whether GUI mode is enabled (affects validation)
527
+ * @returns Validation result with errors and GUI limitations
528
+ */
529
+ export function validateResponseFormatOnly(responseFormat, limetypes, limetype, guiModeEnabled = true) {
530
+ const validationErrors = [];
531
+ const guiLimitations = [];
532
+ // Validate limetype exists
533
+ if (!limetypes[limetype]) {
534
+ validationErrors.push(`Unknown limetype: ${limetype}`);
535
+ // Can't proceed with property validation if limetype is unknown
536
+ return {
537
+ valid: false,
538
+ guiSupported: false,
539
+ validationErrors,
540
+ guiLimitations,
541
+ };
542
+ }
543
+ // Use internal validation logic
544
+ const { errors, limitations } = validateLimeQueryResponseFormatInternal(responseFormat, limetypes, limetype, guiModeEnabled);
545
+ validationErrors.push(...errors);
546
+ guiLimitations.push(...limitations);
547
+ return {
548
+ valid: validationErrors.length === 0,
549
+ guiSupported: guiLimitations.length === 0,
550
+ validationErrors,
551
+ guiLimitations,
552
+ };
553
+ }
@@ -78,7 +78,7 @@ export class LimetypeField {
78
78
  value: '',
79
79
  };
80
80
  options.unshift(emptyOption);
81
- return (h("limel-select", { key: 'fd9522c5df730f65a5ac57140bca6c05c5acd63d', label: this.label, options: options, value: selectedOption, required: this.required, helperText: this.helperText, invalid: invalid, disabled: this.disabled || this.readonly, onChange: this.handleChange }));
81
+ return (h("limel-select", { key: 'ee9fdc46424c9e6dc5897260cb16bcbedd43413a', label: this.label, options: options, value: selectedOption, required: this.required, helperText: this.helperText, invalid: invalid, disabled: this.disabled || this.readonly, onChange: this.handleChange }));
82
82
  }
83
83
  componentWillRender() {
84
84
  this.updatePropertyFields(this.value || '');
@@ -0,0 +1,72 @@
1
+ :host(limebb-lime-query-order-by-editor) {
2
+ display: block;
3
+ width: 100%;
4
+ }
5
+
6
+ .order-by-editor {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: 1rem;
10
+ padding: 1rem;
11
+ }
12
+
13
+ .header {
14
+ display: flex;
15
+ justify-content: space-between;
16
+ align-items: center;
17
+ gap: 1rem;
18
+ }
19
+ .header h4 {
20
+ margin: 0;
21
+ font-size: 1rem;
22
+ font-weight: 600;
23
+ color: rgb(var(--contrast-1000));
24
+ }
25
+
26
+ .order-by-list {
27
+ display: flex;
28
+ flex-direction: column;
29
+ gap: 1rem;
30
+ padding: 0.5rem;
31
+ border: 1px solid rgb(var(--contrast-300));
32
+ border-radius: 0.25rem;
33
+ background-color: rgb(var(--contrast-50));
34
+ min-height: 4rem;
35
+ }
36
+
37
+ .order-by-item {
38
+ padding: 0.5rem;
39
+ border-radius: 0.25rem;
40
+ transition: background-color 0.2s;
41
+ }
42
+ .order-by-item:hover {
43
+ background-color: rgb(var(--contrast-100));
44
+ }
45
+
46
+ .actions {
47
+ display: flex;
48
+ justify-content: flex-start;
49
+ }
50
+
51
+ .summary {
52
+ display: flex;
53
+ justify-content: space-between;
54
+ align-items: center;
55
+ padding-top: 0.5rem;
56
+ border-top: 1px solid rgb(var(--contrast-300));
57
+ }
58
+ .summary .count {
59
+ font-size: 0.875rem;
60
+ font-weight: 500;
61
+ color: rgb(var(--contrast-900));
62
+ }
63
+
64
+ .empty-state {
65
+ padding: 2rem;
66
+ text-align: center;
67
+ color: rgb(var(--contrast-700));
68
+ font-style: italic;
69
+ }
70
+ .empty-state p {
71
+ margin: 0;
72
+ }