@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.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/lime-crm-building-blocks.cjs.js +1 -1
- package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +177 -204
- package/dist/cjs/{limebb-lime-query-filter-builder_3.cjs.entry.js → limebb-lime-query-filter-builder_4.cjs.entry.js} +86 -1
- package/dist/cjs/limebb-lime-query-filter-comparison_2.cjs.entry.js +147 -0
- package/dist/cjs/{limebb-lime-query-filter-comparison_5.cjs.entry.js → limebb-lime-query-filter-group_3.cjs.entry.js} +5 -333
- package/dist/cjs/limebb-lime-query-order-by-item.cjs.entry.js +51 -0
- package/dist/cjs/limebb-live-docs-info.cjs.entry.js +2 -2
- package/dist/cjs/limebb-locale-picker.cjs.entry.js +1 -1
- package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +2 -2
- package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +3 -3
- package/dist/cjs/limebb-notification-item.cjs.entry.js +1 -1
- package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
- package/dist/cjs/limebb-property-selector.cjs.entry.js +234 -0
- package/dist/cjs/limebb-text-editor.cjs.entry.js +1 -1
- package/dist/cjs/limebb-trend-indicator.cjs.entry.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +2 -2
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison.js +1 -1
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-group.js +1 -1
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-not.js +1 -1
- package/dist/collection/components/lime-query-builder/expressions/lime-query-value-input.js +7 -7
- package/dist/collection/components/lime-query-builder/lime-query-builder.css +2 -5
- package/dist/collection/components/lime-query-builder/lime-query-builder.js +19 -19
- package/dist/collection/components/lime-query-builder/lime-query-validation.js +160 -26
- package/dist/collection/components/lime-query-builder/lime-query.types.js +1 -57
- package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +1 -1
- package/dist/collection/components/lime-query-builder/order-by/order-by-editor.css +72 -0
- package/dist/collection/components/lime-query-builder/order-by/order-by-editor.js +252 -0
- package/dist/collection/components/lime-query-builder/order-by/order-by-item.css +45 -0
- package/dist/collection/components/lime-query-builder/order-by/order-by-item.js +173 -0
- package/dist/collection/components/limeobject/file-viewer/live-docs-info.js +2 -2
- package/dist/collection/components/locale-picker/locale-picker.js +1 -1
- package/dist/collection/components/notification-list/notification-item/notification-item.js +1 -1
- package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
- package/dist/collection/components/summary-popover/summary-popover.js +3 -3
- package/dist/collection/components/text-editor/mention-group-counter.js +2 -2
- package/dist/collection/components/text-editor/text-editor.js +1 -1
- package/dist/collection/components/trend-indicator/trend-indicator.js +1 -1
- package/dist/components/lime-query-filter-comparison.js +1 -1
- package/dist/components/lime-query-filter-expression.js +2 -2
- package/dist/components/lime-query-value-input.js +3 -3
- package/dist/components/limebb-lime-query-builder.js +201 -215
- package/dist/components/limebb-lime-query-order-by-editor.d.ts +11 -0
- package/dist/components/limebb-lime-query-order-by-editor.js +6 -0
- package/dist/components/limebb-lime-query-order-by-item.d.ts +11 -0
- package/dist/components/limebb-lime-query-order-by-item.js +6 -0
- package/dist/components/limebb-locale-picker.js +1 -1
- package/dist/components/limebb-mention-group-counter.js +2 -2
- package/dist/components/limebb-percentage-visualizer.js +2 -2
- package/dist/components/limebb-text-editor.js +1 -1
- package/dist/components/limebb-trend-indicator.js +1 -1
- package/dist/components/limetype-field.js +1 -1
- package/dist/components/live-docs-info.js +2 -2
- package/dist/components/notification-item.js +1 -1
- package/dist/components/order-by-editor.js +123 -0
- package/dist/components/order-by-item.js +73 -0
- package/dist/components/property-selector.js +1 -1
- package/dist/components/summary-popover.js +3 -3
- package/dist/esm/lime-crm-building-blocks.js +1 -1
- package/dist/esm/limebb-lime-query-builder.entry.js +179 -206
- package/dist/esm/{limebb-lime-query-filter-builder_3.entry.js → limebb-lime-query-filter-builder_4.entry.js} +86 -2
- package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +142 -0
- package/dist/esm/{limebb-lime-query-filter-comparison_5.entry.js → limebb-lime-query-filter-group_3.entry.js} +7 -333
- package/dist/esm/limebb-lime-query-order-by-item.entry.js +47 -0
- package/dist/esm/limebb-live-docs-info.entry.js +2 -2
- package/dist/esm/limebb-locale-picker.entry.js +1 -1
- package/dist/esm/limebb-mention-group-counter.entry.js +2 -2
- package/dist/esm/limebb-navigation-button_2.entry.js +3 -3
- package/dist/esm/limebb-notification-item.entry.js +1 -1
- package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
- package/dist/esm/limebb-property-selector.entry.js +230 -0
- package/dist/esm/limebb-text-editor.entry.js +1 -1
- package/dist/esm/limebb-trend-indicator.entry.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{property-resolution-fde2375e.js → property-resolution-c21a1369.js} +1 -1
- package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
- package/dist/lime-crm-building-blocks/{p-631ca5a5.entry.js → p-0cd036ed.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-2725671e.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-9cac4de2.entry.js → p-425eaba2.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-e8946134.entry.js → p-5cf4898d.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-67c174d0.entry.js +1 -0
- package/dist/lime-crm-building-blocks/p-6aa216ec.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-93cadc1e.entry.js → p-8601eab5.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-b9b954d9.entry.js → p-8c2fb1c9.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-3122ea05.entry.js → p-92dfc5f8.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-569c86b5.entry.js → p-a1ee8990.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-abfc7815.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-e0ab1554.js → p-b748c770.js} +1 -1
- package/dist/lime-crm-building-blocks/p-ccf34631.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-36ea13c0.entry.js → p-d84874dc.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-f9efca1d.entry.js +1 -0
- package/dist/types/components/lime-query-builder/expressions/lime-query-value-input.d.ts +2 -3
- package/dist/types/components/lime-query-builder/lime-query-builder.d.ts +9 -6
- package/dist/types/components/lime-query-builder/lime-query.types.d.ts +0 -72
- package/dist/types/components/lime-query-builder/order-by/order-by-editor.d.ts +58 -0
- package/dist/types/components/lime-query-builder/order-by/order-by-item.d.ts +37 -0
- package/dist/types/components.d.ts +165 -205
- package/package.json +1 -1
- package/dist/cjs/limebb-lime-query-filter-and.cjs.entry.js +0 -80
- package/dist/cjs/limebb-lime-query-filter-expression.cjs.entry.js +0 -45
- package/dist/cjs/limebb-lime-query-filter-or.cjs.entry.js +0 -68
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-and.css +0 -121
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-and.js +0 -249
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-or.css +0 -123
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-or.js +0 -237
- package/dist/collection/components/lime-query-builder/filter-conversion.js +0 -255
- package/dist/components/limebb-lime-query-filter-and.d.ts +0 -11
- package/dist/components/limebb-lime-query-filter-and.js +0 -135
- package/dist/components/limebb-lime-query-filter-or.d.ts +0 -11
- package/dist/components/limebb-lime-query-filter-or.js +0 -123
- package/dist/esm/limebb-lime-query-filter-and.entry.js +0 -76
- package/dist/esm/limebb-lime-query-filter-expression.entry.js +0 -41
- package/dist/esm/limebb-lime-query-filter-or.entry.js +0 -64
- package/dist/lime-crm-building-blocks/p-24aeb928.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-422f6d51.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-67dbaa4c.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-6d119dab.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-91732502.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-b198194a.entry.js +0 -1
- package/dist/types/components/lime-query-builder/expressions/lime-query-filter-and.d.ts +0 -57
- package/dist/types/components/lime-query-builder/expressions/lime-query-filter-or.d.ts +0 -56
- 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: '
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: '
|
|
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
|
+
}
|