@limetech/lime-crm-building-blocks 1.100.0 → 1.101.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 (123) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/lime-crm-building-blocks.cjs.js +1 -1
  3. package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +177 -204
  4. package/dist/cjs/{limebb-lime-query-filter-builder_3.cjs.entry.js → limebb-lime-query-filter-builder_4.cjs.entry.js} +86 -1
  5. package/dist/cjs/limebb-lime-query-filter-comparison_2.cjs.entry.js +147 -0
  6. package/dist/cjs/{limebb-lime-query-filter-comparison_5.cjs.entry.js → limebb-lime-query-filter-group_3.cjs.entry.js} +5 -333
  7. package/dist/cjs/limebb-lime-query-order-by-item.cjs.entry.js +51 -0
  8. package/dist/cjs/limebb-live-docs-info.cjs.entry.js +2 -2
  9. package/dist/cjs/limebb-locale-picker.cjs.entry.js +1 -1
  10. package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +2 -2
  11. package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +3 -3
  12. package/dist/cjs/limebb-notification-item.cjs.entry.js +1 -1
  13. package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
  14. package/dist/cjs/limebb-property-selector.cjs.entry.js +234 -0
  15. package/dist/cjs/limebb-text-editor.cjs.entry.js +1 -1
  16. package/dist/cjs/limebb-trend-indicator.cjs.entry.js +1 -1
  17. package/dist/cjs/loader.cjs.js +1 -1
  18. package/dist/collection/collection-manifest.json +2 -2
  19. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison.js +1 -1
  20. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-group.js +1 -1
  21. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-not.js +1 -1
  22. package/dist/collection/components/lime-query-builder/expressions/lime-query-value-input.js +7 -7
  23. package/dist/collection/components/lime-query-builder/lime-query-builder.css +2 -5
  24. package/dist/collection/components/lime-query-builder/lime-query-builder.js +19 -19
  25. package/dist/collection/components/lime-query-builder/lime-query-validation.js +160 -26
  26. package/dist/collection/components/lime-query-builder/lime-query.types.js +1 -57
  27. package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +1 -1
  28. package/dist/collection/components/lime-query-builder/order-by/order-by-editor.css +72 -0
  29. package/dist/collection/components/lime-query-builder/order-by/order-by-editor.js +252 -0
  30. package/dist/collection/components/lime-query-builder/order-by/order-by-item.css +45 -0
  31. package/dist/collection/components/lime-query-builder/order-by/order-by-item.js +173 -0
  32. package/dist/collection/components/limeobject/file-viewer/live-docs-info.js +2 -2
  33. package/dist/collection/components/locale-picker/locale-picker.js +1 -1
  34. package/dist/collection/components/notification-list/notification-item/notification-item.js +1 -1
  35. package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
  36. package/dist/collection/components/summary-popover/summary-popover.js +3 -3
  37. package/dist/collection/components/text-editor/mention-group-counter.js +2 -2
  38. package/dist/collection/components/text-editor/text-editor.js +1 -1
  39. package/dist/collection/components/trend-indicator/trend-indicator.js +1 -1
  40. package/dist/components/lime-query-filter-comparison.js +1 -1
  41. package/dist/components/lime-query-filter-expression.js +2 -2
  42. package/dist/components/lime-query-value-input.js +3 -3
  43. package/dist/components/limebb-lime-query-builder.js +201 -215
  44. package/dist/components/limebb-lime-query-order-by-editor.d.ts +11 -0
  45. package/dist/components/limebb-lime-query-order-by-editor.js +6 -0
  46. package/dist/components/limebb-lime-query-order-by-item.d.ts +11 -0
  47. package/dist/components/limebb-lime-query-order-by-item.js +6 -0
  48. package/dist/components/limebb-locale-picker.js +1 -1
  49. package/dist/components/limebb-mention-group-counter.js +2 -2
  50. package/dist/components/limebb-percentage-visualizer.js +2 -2
  51. package/dist/components/limebb-text-editor.js +1 -1
  52. package/dist/components/limebb-trend-indicator.js +1 -1
  53. package/dist/components/limetype-field.js +1 -1
  54. package/dist/components/live-docs-info.js +2 -2
  55. package/dist/components/notification-item.js +1 -1
  56. package/dist/components/order-by-editor.js +123 -0
  57. package/dist/components/order-by-item.js +73 -0
  58. package/dist/components/property-selector.js +1 -1
  59. package/dist/components/summary-popover.js +3 -3
  60. package/dist/esm/lime-crm-building-blocks.js +1 -1
  61. package/dist/esm/limebb-lime-query-builder.entry.js +179 -206
  62. package/dist/esm/{limebb-lime-query-filter-builder_3.entry.js → limebb-lime-query-filter-builder_4.entry.js} +86 -2
  63. package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +142 -0
  64. package/dist/esm/{limebb-lime-query-filter-comparison_5.entry.js → limebb-lime-query-filter-group_3.entry.js} +7 -333
  65. package/dist/esm/limebb-lime-query-order-by-item.entry.js +47 -0
  66. package/dist/esm/limebb-live-docs-info.entry.js +2 -2
  67. package/dist/esm/limebb-locale-picker.entry.js +1 -1
  68. package/dist/esm/limebb-mention-group-counter.entry.js +2 -2
  69. package/dist/esm/limebb-navigation-button_2.entry.js +3 -3
  70. package/dist/esm/limebb-notification-item.entry.js +1 -1
  71. package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
  72. package/dist/esm/limebb-property-selector.entry.js +230 -0
  73. package/dist/esm/limebb-text-editor.entry.js +1 -1
  74. package/dist/esm/limebb-trend-indicator.entry.js +1 -1
  75. package/dist/esm/loader.js +1 -1
  76. package/dist/esm/{property-resolution-fde2375e.js → property-resolution-c21a1369.js} +1 -1
  77. package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
  78. package/dist/lime-crm-building-blocks/{p-631ca5a5.entry.js → p-0cd036ed.entry.js} +1 -1
  79. package/dist/lime-crm-building-blocks/p-2725671e.entry.js +1 -0
  80. package/dist/lime-crm-building-blocks/{p-9cac4de2.entry.js → p-425eaba2.entry.js} +1 -1
  81. package/dist/lime-crm-building-blocks/{p-e8946134.entry.js → p-5cf4898d.entry.js} +1 -1
  82. package/dist/lime-crm-building-blocks/p-67c174d0.entry.js +1 -0
  83. package/dist/lime-crm-building-blocks/p-6aa216ec.entry.js +1 -0
  84. package/dist/lime-crm-building-blocks/{p-93cadc1e.entry.js → p-8601eab5.entry.js} +1 -1
  85. package/dist/lime-crm-building-blocks/{p-b9b954d9.entry.js → p-8c2fb1c9.entry.js} +1 -1
  86. package/dist/lime-crm-building-blocks/{p-3122ea05.entry.js → p-92dfc5f8.entry.js} +1 -1
  87. package/dist/lime-crm-building-blocks/{p-569c86b5.entry.js → p-a1ee8990.entry.js} +1 -1
  88. package/dist/lime-crm-building-blocks/p-abfc7815.entry.js +1 -0
  89. package/dist/lime-crm-building-blocks/{p-e0ab1554.js → p-b748c770.js} +1 -1
  90. package/dist/lime-crm-building-blocks/p-ccf34631.entry.js +1 -0
  91. package/dist/lime-crm-building-blocks/{p-36ea13c0.entry.js → p-d84874dc.entry.js} +1 -1
  92. package/dist/lime-crm-building-blocks/p-f9efca1d.entry.js +1 -0
  93. package/dist/types/components/lime-query-builder/expressions/lime-query-value-input.d.ts +2 -3
  94. package/dist/types/components/lime-query-builder/lime-query-builder.d.ts +9 -6
  95. package/dist/types/components/lime-query-builder/lime-query.types.d.ts +0 -72
  96. package/dist/types/components/lime-query-builder/order-by/order-by-editor.d.ts +58 -0
  97. package/dist/types/components/lime-query-builder/order-by/order-by-item.d.ts +37 -0
  98. package/dist/types/components.d.ts +165 -205
  99. package/package.json +1 -1
  100. package/dist/cjs/limebb-lime-query-filter-and.cjs.entry.js +0 -80
  101. package/dist/cjs/limebb-lime-query-filter-expression.cjs.entry.js +0 -45
  102. package/dist/cjs/limebb-lime-query-filter-or.cjs.entry.js +0 -68
  103. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-and.css +0 -121
  104. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-and.js +0 -249
  105. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-or.css +0 -123
  106. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-or.js +0 -237
  107. package/dist/collection/components/lime-query-builder/filter-conversion.js +0 -255
  108. package/dist/components/limebb-lime-query-filter-and.d.ts +0 -11
  109. package/dist/components/limebb-lime-query-filter-and.js +0 -135
  110. package/dist/components/limebb-lime-query-filter-or.d.ts +0 -11
  111. package/dist/components/limebb-lime-query-filter-or.js +0 -123
  112. package/dist/esm/limebb-lime-query-filter-and.entry.js +0 -76
  113. package/dist/esm/limebb-lime-query-filter-expression.entry.js +0 -41
  114. package/dist/esm/limebb-lime-query-filter-or.entry.js +0 -64
  115. package/dist/lime-crm-building-blocks/p-24aeb928.entry.js +0 -1
  116. package/dist/lime-crm-building-blocks/p-422f6d51.entry.js +0 -1
  117. package/dist/lime-crm-building-blocks/p-67dbaa4c.entry.js +0 -1
  118. package/dist/lime-crm-building-blocks/p-6d119dab.entry.js +0 -1
  119. package/dist/lime-crm-building-blocks/p-91732502.entry.js +0 -1
  120. package/dist/lime-crm-building-blocks/p-b198194a.entry.js +0 -1
  121. package/dist/types/components/lime-query-builder/expressions/lime-query-filter-and.d.ts +0 -57
  122. package/dist/types/components/lime-query-builder/expressions/lime-query-filter-or.d.ts +0 -56
  123. package/dist/types/components/lime-query-builder/filter-conversion.d.ts +0 -31
@@ -75,6 +75,11 @@ export class LimeQueryBuilder {
75
75
  this.limit = value ? Number.parseInt(value, 10) : undefined;
76
76
  this.emitChange();
77
77
  };
78
+ this.handleOrderByChange = (event) => {
79
+ event.stopPropagation();
80
+ this.orderBy = event.detail;
81
+ this.emitChange();
82
+ };
78
83
  this.switchToGui = () => {
79
84
  // Validate JSON before switching
80
85
  try {
@@ -90,6 +95,7 @@ export class LimeQueryBuilder {
90
95
  this.filter = parsed.filter;
91
96
  this.internalResponseFormat = parsed.responseFormat;
92
97
  this.limit = parsed.limit;
98
+ this.orderBy = parsed.orderBy;
93
99
  this.mode = 'gui';
94
100
  this.change.emit(parsed);
95
101
  }
@@ -131,6 +137,7 @@ export class LimeQueryBuilder {
131
137
  this.filter = this.value.filter;
132
138
  this.internalResponseFormat = this.value.responseFormat;
133
139
  this.limit = this.value.limit;
140
+ this.orderBy = this.value.orderBy;
134
141
  }
135
142
  // Initialize code value from prop
136
143
  this.updateCodeValue();
@@ -143,7 +150,7 @@ export class LimeQueryBuilder {
143
150
  render() {
144
151
  const guiSupported = this.checkGuiSupport();
145
152
  const showCodeMode = !this.guiModeEnabled || this.mode === 'code';
146
- return (h("div", { key: '0b4d2bb5b4d503a775d8d3215e1e4c74fdb1eceb', class: "lime-query-builder" }, this.renderLabel(), this.renderModeControls(guiSupported), showCodeMode
153
+ return (h("div", { key: 'f51ae0459c1c7f482f3a790abb4cc3bd60b83e70', class: "lime-query-builder" }, this.renderLabel(), this.renderModeControls(guiSupported), showCodeMode
147
154
  ? this.renderCodeMode(guiSupported)
148
155
  : this.renderGuiMode()));
149
156
  }
@@ -155,27 +162,16 @@ export class LimeQueryBuilder {
155
162
  if (!this.limetype) {
156
163
  return;
157
164
  }
158
- // Use internal state, then default to returning just _id
159
- const responseFormat = this.internalResponseFormat || {
160
- object: {
161
- _id: null,
162
- },
163
- };
164
- const limeQuery = {
165
- limetype: this.limetype,
166
- responseFormat: responseFormat,
167
- filter: this.filter,
168
- };
169
- if (this.limit !== undefined && this.limit > 0) {
170
- limeQuery.limit = this.limit;
171
- }
172
- this.change.emit(limeQuery);
165
+ this.change.emit(this.buildLimeQuery());
173
166
  }
174
167
  updateCodeValue() {
175
168
  if (!this.limetype) {
176
169
  this.codeValue = JSON.stringify(this.value || {}, null, 2);
177
170
  return;
178
171
  }
172
+ this.codeValue = JSON.stringify(this.buildLimeQuery(), null, 2);
173
+ }
174
+ buildLimeQuery() {
179
175
  // Use internal state, then default to returning just _id
180
176
  const responseFormat = this.internalResponseFormat || {
181
177
  object: {
@@ -190,7 +186,10 @@ export class LimeQueryBuilder {
190
186
  if (this.limit !== undefined && this.limit > 0) {
191
187
  limeQuery.limit = this.limit;
192
188
  }
193
- this.codeValue = JSON.stringify(limeQuery, null, 2);
189
+ if (this.orderBy && this.orderBy.length > 0) {
190
+ limeQuery.orderBy = this.orderBy;
191
+ }
192
+ return limeQuery;
194
193
  }
195
194
  checkGuiSupport() {
196
195
  if (!this.limetypes) {
@@ -275,7 +274,7 @@ export class LimeQueryBuilder {
275
274
  if (!this.limetype) {
276
275
  return;
277
276
  }
278
- 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 }))));
277
+ 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 }), h("limebb-lime-query-order-by-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.orderBy, onChange: this.handleOrderByChange }))));
279
278
  }
280
279
  renderGuiMode() {
281
280
  return (h("div", { class: "gui-mode" }, this.renderLimetypeSection(), this.renderResponseFormatSection(), this.renderFilterSection(), this.renderQueryOptionsSection()));
@@ -426,7 +425,8 @@ export class LimeQueryBuilder {
426
425
  "limetype": {},
427
426
  "filter": {},
428
427
  "internalResponseFormat": {},
429
- "limit": {}
428
+ "limit": {},
429
+ "orderBy": {}
430
430
  };
431
431
  }
432
432
  static get events() {
@@ -1,5 +1,5 @@
1
+ import { Operator } from "@limetech/lime-web-components";
1
2
  import { getNormalizedProperties } from "./property-resolution";
2
- import { limeQueryToGuiFilter } from "./filter-conversion";
3
3
  import { getPropertyFromPath } from "./property-resolution";
4
4
  /**
5
5
  * Dynamic filter values and placeholders that are valid in Lime Query
@@ -248,6 +248,49 @@ export function validatePropertySelection(selection, limetypes, limetype, guiMod
248
248
  }
249
249
  return allGuiLimitations;
250
250
  }
251
+ /**
252
+ * Validate a comparison expression (has 'key' property)
253
+ * @param filter
254
+ * @param activeLimetype
255
+ * @param limetypes
256
+ */
257
+ function validateComparisonExpression(filter, activeLimetype, limetypes) {
258
+ // Validate operator
259
+ const allValidOperators = Object.values(Operator);
260
+ if (!allValidOperators.includes(filter.op)) {
261
+ throw new Error(`Unsupported filter operator: ${filter.op}`);
262
+ }
263
+ // Validate placeholder
264
+ const result = validatePlaceholder(filter.exp, activeLimetype, limetypes);
265
+ if (!result.valid) {
266
+ throw new Error(`Invalid placeholder in filter '${filter.key}': ${result.error}`);
267
+ }
268
+ }
269
+ /**
270
+ * Validate a group expression (AND/OR/NOT)
271
+ * @param filter
272
+ * @param activeLimetype
273
+ * @param limetypes
274
+ * @param guiModeEnabled
275
+ */
276
+ function validateGroupExpression(filter, activeLimetype, limetypes, guiModeEnabled) {
277
+ // Validate operator
278
+ if (filter.op !== Operator.AND &&
279
+ filter.op !== Operator.OR &&
280
+ filter.op !== Operator.NOT) {
281
+ throw new Error(`Unsupported group operator: ${filter.op}`);
282
+ }
283
+ // Recursively validate children
284
+ if (filter.op === Operator.NOT) {
285
+ validateFilterPlaceholders(filter.exp, activeLimetype, limetypes, guiModeEnabled);
286
+ }
287
+ else if (filter.op === Operator.AND || filter.op === Operator.OR) {
288
+ const expressions = filter.exp;
289
+ for (const expr of expressions) {
290
+ validateFilterPlaceholders(expr, activeLimetype, limetypes, guiModeEnabled);
291
+ }
292
+ }
293
+ }
251
294
  /**
252
295
  * Validate placeholders in a filter expression
253
296
  * @param filter Filter expression to validate
@@ -259,27 +302,12 @@ function validateFilterPlaceholders(filter, activeLimetype, limetypes, guiModeEn
259
302
  if (!filter) {
260
303
  return;
261
304
  }
262
- // Check if it's a FilterExpression (has 'key' property)
263
305
  if ('key' in filter) {
264
- const result = validatePlaceholder(filter.exp, activeLimetype, limetypes);
265
- if (!result.valid) {
266
- throw new Error(`Invalid placeholder in filter '${filter.key}': ${result.error}`);
267
- }
306
+ validateComparisonExpression(filter, activeLimetype, limetypes);
268
307
  return;
269
308
  }
270
- // It's a FilterGroup - recursively validate children
271
309
  if ('exp' in filter) {
272
- if (filter.op === '!') {
273
- // NOT has a single expression
274
- validateFilterPlaceholders(filter.exp, activeLimetype, limetypes, guiModeEnabled);
275
- }
276
- else if (filter.op === 'AND' || filter.op === 'OR') {
277
- // AND/OR have array of expressions
278
- const expressions = filter.exp;
279
- for (const expr of expressions) {
280
- validateFilterPlaceholders(expr, activeLimetype, limetypes, guiModeEnabled);
281
- }
282
- }
310
+ validateGroupExpression(filter, activeLimetype, limetypes, guiModeEnabled);
283
311
  }
284
312
  }
285
313
  /**
@@ -293,7 +321,6 @@ function validateFilterPlaceholders(filter, activeLimetype, limetypes, guiModeEn
293
321
  function validateLimeQueryFilterInternal(filter, activeLimetype, limetypes, guiModeEnabled) {
294
322
  const errors = [];
295
323
  try {
296
- limeQueryToGuiFilter(filter);
297
324
  validateFilterPlaceholders(filter, activeLimetype, limetypes, guiModeEnabled);
298
325
  }
299
326
  catch (error) {
@@ -301,6 +328,113 @@ function validateLimeQueryFilterInternal(filter, activeLimetype, limetypes, guiM
301
328
  }
302
329
  return errors;
303
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
+ }
304
438
  /**
305
439
  * Validate Lime Query response format and collect errors/limitations
306
440
  * @param responseFormat The response format to validate
@@ -350,14 +484,14 @@ export function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, guiMo
350
484
  if (limeQuery.offset !== undefined && !limeQuery.orderBy) {
351
485
  validationErrors.push('offset requires orderBy to be specified');
352
486
  }
487
+ // Validate orderBy
488
+ if (limeQuery.orderBy) {
489
+ const orderByErrors = validateOrderBy(limeQuery.orderBy, limetypes, limeQuery.limetype);
490
+ validationErrors.push(...orderByErrors);
491
+ }
353
492
  // Check for GUI-unsupported top-level properties
354
- if (guiModeEnabled) {
355
- if (limeQuery.orderBy) {
356
- guiLimitations.push('orderBy is not yet supported in GUI mode');
357
- }
358
- if (limeQuery.offset !== undefined) {
359
- guiLimitations.push('offset is not yet supported in GUI mode');
360
- }
493
+ if (guiModeEnabled && limeQuery.offset !== undefined) {
494
+ guiLimitations.push('offset is not yet supported in GUI mode');
361
495
  }
362
496
  // Validate filter
363
497
  if (limeQuery.filter) {
@@ -1,57 +1 @@
1
- /**
2
- * TypeScript type definitions for Lime Query DSL
3
- *
4
- * These types represent the structure of Lime Query as defined in:
5
- * - lime-core/lime_query/schema.py
6
- * - lime-core/lime_filter/schema.py
7
- */
8
- /**
9
- * Available operators with display metadata
10
- */
11
- export const LIME_QUERY_OPERATORS = [
12
- { value: '=', label: 'Equals', icon: 'equals' },
13
- { value: '!=', label: 'Not Equals', icon: 'not-equal' },
14
- {
15
- value: '>',
16
- label: 'Greater Than',
17
- icon: 'greater-than',
18
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
19
- },
20
- {
21
- value: '>=',
22
- label: 'Greater or Equal',
23
- icon: 'greater-or-equal',
24
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
25
- },
26
- {
27
- value: '<',
28
- label: 'Less Than',
29
- icon: 'less-than',
30
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
31
- },
32
- {
33
- value: '<=',
34
- label: 'Less or Equal',
35
- icon: 'less-or-equal',
36
- applicableTypes: ['integer', 'decimal', 'date', 'time'],
37
- },
38
- { value: 'IN', label: 'In List', icon: 'list' },
39
- {
40
- value: '?',
41
- label: 'Contains',
42
- icon: '-lime-filter-contain',
43
- applicableTypes: ['string', 'text'],
44
- },
45
- {
46
- value: '=?',
47
- label: 'Begins With',
48
- icon: '-lime-filter-begin',
49
- applicableTypes: ['string', 'text'],
50
- },
51
- {
52
- value: '=$',
53
- label: 'Ends With',
54
- icon: '-lime-filter-end',
55
- applicableTypes: ['string', 'text'],
56
- },
57
- ];
1
+ export {};
@@ -78,7 +78,7 @@ export class LimetypeField {
78
78
  value: '',
79
79
  };
80
80
  options.unshift(emptyOption);
81
- return (h("limel-select", { key: 'cf27b83c4751838e85436af443a275b3d7c9dfee', 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: 'fd9522c5df730f65a5ac57140bca6c05c5acd63d', 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
+ }