@limetech/lime-crm-building-blocks 1.104.0 → 1.104.1
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 +7 -0
- package/dist/cjs/{lime-query-validation-6be10fa7.js → lime-query-validation-82aa2855.js} +84 -84
- package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +44 -43
- package/dist/cjs/limebb-lime-query-filter-builder_3.cjs.entry.js +1 -1
- package/dist/cjs/limebb-lime-query-response-format-builder.cjs.entry.js +42 -42
- package/dist/collection/components/lime-query-builder/lime-query-builder.css +9 -9
- package/dist/collection/components/lime-query-builder/lime-query-builder.js +42 -41
- package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.css +5 -5
- package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.js +42 -42
- package/dist/collection/components/lime-query-builder/lime-query-validation.js +84 -84
- package/dist/collection/components/lime-query-builder/order-by/order-by-editor.css +2 -2
- package/dist/collection/components/lime-query-builder/response-format/response-format-helpers.js +2 -2
- package/dist/components/lime-query-validation.js +84 -84
- package/dist/components/limebb-lime-query-builder.js +43 -42
- package/dist/components/limebb-lime-query-response-format-builder.js +41 -41
- package/dist/components/order-by-editor.js +1 -1
- package/dist/esm/{lime-query-validation-573223a5.js → lime-query-validation-9e386da8.js} +84 -84
- package/dist/esm/limebb-lime-query-builder.entry.js +44 -43
- package/dist/esm/limebb-lime-query-filter-builder_3.entry.js +1 -1
- package/dist/esm/limebb-lime-query-response-format-builder.entry.js +42 -42
- package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
- package/dist/lime-crm-building-blocks/{p-6c7af6bb.entry.js → p-7d2188aa.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-7fbb6eba.entry.js +1 -0
- package/dist/lime-crm-building-blocks/p-ac9e81c9.entry.js +1 -0
- package/dist/lime-crm-building-blocks/p-efa5bcd4.js +1 -0
- package/dist/types/components/lime-query-builder/lime-query-builder.d.ts +3 -3
- package/dist/types/components/lime-query-builder/lime-query-response-format-builder.d.ts +13 -13
- package/dist/types/components/lime-query-builder/lime-query-validation.d.ts +17 -17
- package/dist/types/components.d.ts +12 -12
- package/package.json +1 -1
- package/dist/lime-crm-building-blocks/p-96fee7ee.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-fa2da6bc.js +0 -1
- package/dist/lime-crm-building-blocks/p-fe6a94a1.entry.js +0 -1
|
@@ -16,16 +16,16 @@ import { validateResponseFormatOnly, } from "./lime-query-validation";
|
|
|
16
16
|
* Response Format Builder
|
|
17
17
|
*
|
|
18
18
|
* A focused component for editing Lime Query ResponseFormat in isolation.
|
|
19
|
-
* Supports both
|
|
19
|
+
* Supports both visual and code modes for maximum flexibility.
|
|
20
20
|
*
|
|
21
21
|
* Use this component when you need to configure which properties to return
|
|
22
22
|
* from a query, but don't need filter, limit, or other query parameters.
|
|
23
23
|
*
|
|
24
24
|
* **Features**:
|
|
25
|
-
* - **
|
|
25
|
+
* - **Visual Mode**: Visual property selector with relation navigation
|
|
26
26
|
* - **Code Mode**: JSON editor for ResponseFormat structure
|
|
27
27
|
* - **Validation**: Ensures JSON is valid ResponseFormat (rejects other fields)
|
|
28
|
-
* - **Mode Toggle**: Switch between
|
|
28
|
+
* - **Mode Toggle**: Switch between visual and code modes seamlessly
|
|
29
29
|
* - **Feature Flag**: Respects `useLimeQueryBuilderGuiMode` setting
|
|
30
30
|
*
|
|
31
31
|
* @example
|
|
@@ -53,34 +53,34 @@ export class LimeQueryResponseFormatBuilder {
|
|
|
53
53
|
* Optional helper text for the builder
|
|
54
54
|
*/
|
|
55
55
|
this.helperText = '';
|
|
56
|
-
this.mode = '
|
|
56
|
+
this.mode = 'visual';
|
|
57
57
|
this.codeValue = '';
|
|
58
58
|
this.handleModeChange = (event) => {
|
|
59
59
|
event.stopPropagation();
|
|
60
60
|
const mode = event.detail.id;
|
|
61
|
-
if (mode === '
|
|
62
|
-
this.
|
|
61
|
+
if (mode === 'visual') {
|
|
62
|
+
this.switchToVisualMode();
|
|
63
63
|
}
|
|
64
64
|
else if (mode === 'code') {
|
|
65
65
|
this.switchToCode();
|
|
66
66
|
}
|
|
67
67
|
};
|
|
68
68
|
/**
|
|
69
|
-
* Switch from code mode to
|
|
69
|
+
* Switch from code mode to visual mode
|
|
70
70
|
*/
|
|
71
|
-
this.
|
|
71
|
+
this.switchToVisualMode = () => {
|
|
72
72
|
// Validate JSON before switching
|
|
73
73
|
try {
|
|
74
74
|
const parsed = parseResponseFormat(this.codeValue);
|
|
75
|
-
// Check if it's supported in
|
|
76
|
-
const support = validateResponseFormatOnly(parsed, this.limetypes, this.limetype, this.
|
|
77
|
-
if (!support.
|
|
78
|
-
// Don't switch if
|
|
75
|
+
// Check if it's supported in visual mode
|
|
76
|
+
const support = validateResponseFormatOnly(parsed, this.limetypes, this.limetype, this.visualModeEnabled);
|
|
77
|
+
if (!support.visualModeSupported) {
|
|
78
|
+
// Don't switch if visual mode can't render this response format
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
// Update internal state from parsed value
|
|
82
82
|
this.internalValue = parsed;
|
|
83
|
-
this.mode = '
|
|
83
|
+
this.mode = 'visual';
|
|
84
84
|
this.change.emit(parsed);
|
|
85
85
|
}
|
|
86
86
|
catch (_a) {
|
|
@@ -88,7 +88,7 @@ export class LimeQueryResponseFormatBuilder {
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
/**
|
|
91
|
-
* Switch from
|
|
91
|
+
* Switch from visual mode to code mode
|
|
92
92
|
*/
|
|
93
93
|
this.switchToCode = () => {
|
|
94
94
|
this.updateCodeValue();
|
|
@@ -109,14 +109,14 @@ export class LimeQueryResponseFormatBuilder {
|
|
|
109
109
|
}
|
|
110
110
|
catch (_a) {
|
|
111
111
|
// Invalid JSON - don't emit change
|
|
112
|
-
// Validation errors will be shown by
|
|
112
|
+
// Validation errors will be shown by checkVisualModeSupport()
|
|
113
113
|
}
|
|
114
114
|
};
|
|
115
115
|
/**
|
|
116
|
-
* Handle
|
|
116
|
+
* Handle visual mode changes
|
|
117
117
|
* @param event
|
|
118
118
|
*/
|
|
119
|
-
this.
|
|
119
|
+
this.handleVisualModeChange = (event) => {
|
|
120
120
|
event.stopPropagation();
|
|
121
121
|
this.internalValue = event.detail;
|
|
122
122
|
this.updateCodeValue();
|
|
@@ -124,9 +124,9 @@ export class LimeQueryResponseFormatBuilder {
|
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
126
|
/**
|
|
127
|
-
* Check if
|
|
127
|
+
* Check if visual mode is enabled via feature flag
|
|
128
128
|
*/
|
|
129
|
-
get
|
|
129
|
+
get visualModeEnabled() {
|
|
130
130
|
var _a, _b, _c;
|
|
131
131
|
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);
|
|
132
132
|
}
|
|
@@ -135,32 +135,32 @@ export class LimeQueryResponseFormatBuilder {
|
|
|
135
135
|
this.internalValue = this.value || getDefaultResponseFormat();
|
|
136
136
|
// Update code value from internal value
|
|
137
137
|
this.updateCodeValue();
|
|
138
|
-
// Force code mode if
|
|
139
|
-
if (!this.
|
|
138
|
+
// Force code mode if visual mode is disabled
|
|
139
|
+
if (!this.visualModeEnabled) {
|
|
140
140
|
this.mode = 'code';
|
|
141
141
|
return;
|
|
142
142
|
}
|
|
143
|
-
// Check if
|
|
144
|
-
const support = this.
|
|
145
|
-
if (!support.
|
|
143
|
+
// Check if visual mode is supported for current value
|
|
144
|
+
const support = this.checkVisualModeSupport();
|
|
145
|
+
if (!support.visualModeSupported) {
|
|
146
146
|
this.mode = 'code';
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
componentWillUpdate() {
|
|
150
150
|
// Sync internal value when prop changes externally
|
|
151
|
-
if (this.value && this.mode === '
|
|
151
|
+
if (this.value && this.mode === 'visual') {
|
|
152
152
|
this.internalValue = this.value;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
render() {
|
|
156
|
-
const
|
|
157
|
-
return (h("div", { key: '
|
|
156
|
+
const visualModeSupported = this.checkVisualModeSupport();
|
|
157
|
+
return (h("div", { key: '7ae23c1366da49b591c0914f49f25c179e4d6712', class: "response-format-builder" }, this.label && h("h1", { key: '0cd528a69dd1b05769c678151f0827de15d167a8', class: "builder-label" }, this.label), this.helperText && (h("p", { key: 'b636ca0d32b244d051e74ed538cbd11438f29cd1', class: "builder-helper-text" }, this.helperText)), this.visualModeEnabled && (h("div", { key: 'dc7248cb27d99aa654b0f1659938c3f2933d89e0', class: "mode-controls" }, this.renderModeSwitch(visualModeSupported))), !this.visualModeEnabled || this.mode === 'code' ? (h("div", { class: "code-mode" }, this.renderCodeEditor(visualModeSupported))) : (h("div", { class: "visual-mode" }, this.renderVisualMode()))));
|
|
158
158
|
}
|
|
159
159
|
renderModeSwitch(support) {
|
|
160
|
-
const
|
|
160
|
+
const visualDisabled = !support.visualModeSupported;
|
|
161
161
|
const buttons = [
|
|
162
162
|
{
|
|
163
|
-
id: '
|
|
163
|
+
id: 'visual',
|
|
164
164
|
title: 'Visual',
|
|
165
165
|
},
|
|
166
166
|
{
|
|
@@ -168,27 +168,27 @@ export class LimeQueryResponseFormatBuilder {
|
|
|
168
168
|
title: 'Code',
|
|
169
169
|
},
|
|
170
170
|
].map((button) => (Object.assign(Object.assign({}, button), { selected: button.id === this.mode })));
|
|
171
|
-
return (h("limel-button-group", { value: buttons, disabled:
|
|
171
|
+
return (h("limel-button-group", { value: buttons, disabled: visualDisabled, onChange: this.handleModeChange }));
|
|
172
172
|
}
|
|
173
173
|
renderCodeEditor(support) {
|
|
174
|
-
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.
|
|
174
|
+
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.visualModeEnabled &&
|
|
175
175
|
support.valid &&
|
|
176
|
-
!support.
|
|
177
|
-
support.
|
|
176
|
+
!support.visualModeSupported &&
|
|
177
|
+
support.visualModeLimitations.length > 0 && (h("div", { class: "visual-mode-limitations" }, h("strong", null, "Cannot switch to visual mode:"), h("ul", null, support.visualModeLimitations.map((limitation) => (h("li", null, limitation))))))));
|
|
178
178
|
}
|
|
179
|
-
|
|
180
|
-
return (h("limebb-lime-query-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalValue, onChange: this.
|
|
179
|
+
renderVisualMode() {
|
|
180
|
+
return (h("limebb-lime-query-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalValue, onChange: this.handleVisualModeChange }));
|
|
181
181
|
}
|
|
182
182
|
/**
|
|
183
|
-
* Check if current value can be rendered in
|
|
183
|
+
* Check if current value can be rendered in visual mode
|
|
184
184
|
*/
|
|
185
|
-
|
|
185
|
+
checkVisualModeSupport() {
|
|
186
186
|
if (!this.limetypes) {
|
|
187
187
|
return {
|
|
188
188
|
valid: false,
|
|
189
|
-
|
|
189
|
+
visualModeSupported: false,
|
|
190
190
|
validationErrors: ['Limetypes not loaded'],
|
|
191
|
-
|
|
191
|
+
visualModeLimitations: [],
|
|
192
192
|
};
|
|
193
193
|
}
|
|
194
194
|
// Try to parse code value if in code mode
|
|
@@ -200,16 +200,16 @@ export class LimeQueryResponseFormatBuilder {
|
|
|
200
200
|
catch (error) {
|
|
201
201
|
return {
|
|
202
202
|
valid: false,
|
|
203
|
-
|
|
203
|
+
visualModeSupported: false,
|
|
204
204
|
validationErrors: [error.message],
|
|
205
|
-
|
|
205
|
+
visualModeLimitations: [],
|
|
206
206
|
};
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
else {
|
|
210
210
|
valueToCheck = this.internalValue;
|
|
211
211
|
}
|
|
212
|
-
return validateResponseFormatOnly(valueToCheck, this.limetypes, this.limetype, this.
|
|
212
|
+
return validateResponseFormatOnly(valueToCheck, this.limetypes, this.limetype, this.visualModeEnabled);
|
|
213
213
|
}
|
|
214
214
|
/**
|
|
215
215
|
* Update code value from internal state
|
|
@@ -88,47 +88,47 @@ export function validatePlaceholder(value, activeLimetype, limetypes) {
|
|
|
88
88
|
/**
|
|
89
89
|
* Validate a response format against limetype schemas
|
|
90
90
|
* Throws errors for invalid property references
|
|
91
|
-
* Returns
|
|
91
|
+
* Returns visual mode limitations for features not yet supported in visual mode
|
|
92
92
|
* @param responseFormat
|
|
93
93
|
* @param limetypes Record of all available limetypes
|
|
94
94
|
* @param limetype The root limetype for this query
|
|
95
|
-
* @param
|
|
96
|
-
* @returns
|
|
95
|
+
* @param visualModeEnabled Whether visual mode is enabled
|
|
96
|
+
* @returns Visual mode limitations found (if any)
|
|
97
97
|
*/
|
|
98
|
-
export function validateResponseFormat(responseFormat, limetypes, limetype,
|
|
99
|
-
const
|
|
100
|
-
// Check for
|
|
101
|
-
if (
|
|
102
|
-
|
|
98
|
+
export function validateResponseFormat(responseFormat, limetypes, limetype, visualModeEnabled = true) {
|
|
99
|
+
const visualModeLimitations = [];
|
|
100
|
+
// Check for visual-mode-unsupported features
|
|
101
|
+
if (visualModeEnabled && responseFormat.aggregates) {
|
|
102
|
+
visualModeLimitations.push('responseFormat.aggregates is not yet supported in visual mode');
|
|
103
103
|
}
|
|
104
104
|
// Validate object properties (throws on invalid properties)
|
|
105
105
|
if (responseFormat.object) {
|
|
106
|
-
const objectLimitations = validatePropertySelection(responseFormat.object, limetypes, limetype,
|
|
107
|
-
|
|
106
|
+
const objectLimitations = validatePropertySelection(responseFormat.object, limetypes, limetype, visualModeEnabled);
|
|
107
|
+
visualModeLimitations.push(...objectLimitations);
|
|
108
108
|
}
|
|
109
|
-
return
|
|
109
|
+
return visualModeLimitations;
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
112
|
* Extract non-metadata keys from a property value object
|
|
113
113
|
* Filters out _alias and all # properties (which are treated as comments)
|
|
114
114
|
* @param propValue Property value object
|
|
115
115
|
* @param propName Property name (for error messages)
|
|
116
|
-
* @param
|
|
117
|
-
* @returns Object with non-metadata keys and any
|
|
116
|
+
* @param visualModeEnabled Whether visual mode is enabled (affects validation)
|
|
117
|
+
* @returns Object with non-metadata keys and any visual mode limitations found
|
|
118
118
|
*/
|
|
119
|
-
function extractNonMetadataKeys(propValue, propName,
|
|
119
|
+
function extractNonMetadataKeys(propValue, propName, visualModeEnabled = true) {
|
|
120
120
|
const keys = Object.keys(propValue);
|
|
121
|
-
const
|
|
122
|
-
// Check for # properties other than #description (
|
|
123
|
-
if (
|
|
121
|
+
const visualModeLimitations = [];
|
|
122
|
+
// Check for # properties other than #description (visual mode limitation)
|
|
123
|
+
if (visualModeEnabled) {
|
|
124
124
|
const unsupportedHashProps = keys.filter((k) => k.startsWith('#') && k !== '#description');
|
|
125
125
|
if (unsupportedHashProps.length > 0) {
|
|
126
|
-
|
|
126
|
+
visualModeLimitations.push(`Property '${propName}' contains # properties not supported in visual mode: ${unsupportedHashProps.join(', ')}`);
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
// Filter out _alias and all # properties (they are metadata/comments)
|
|
130
130
|
const nonMetadataKeys = keys.filter((k) => k !== '_alias' && !k.startsWith('#'));
|
|
131
|
-
return { keys: nonMetadataKeys,
|
|
131
|
+
return { keys: nonMetadataKeys, visualModeLimitations };
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
134
|
* Validate a relation property value
|
|
@@ -136,10 +136,10 @@ function extractNonMetadataKeys(propValue, propName, guiModeEnabled = true) {
|
|
|
136
136
|
* @param propValue Property value
|
|
137
137
|
* @param limetypes Record of all available limetypes
|
|
138
138
|
* @param property
|
|
139
|
-
* @param
|
|
140
|
-
* @returns
|
|
139
|
+
* @param visualModeEnabled Whether visual mode is enabled (affects validation)
|
|
140
|
+
* @returns Visual mode limitations found (if any)
|
|
141
141
|
*/
|
|
142
|
-
function validateRelationProperty(propName, propValue, limetypes, property,
|
|
142
|
+
function validateRelationProperty(propName, propValue, limetypes, property, visualModeEnabled = true) {
|
|
143
143
|
// null is valid - just return the relation ID
|
|
144
144
|
if (propValue === null) {
|
|
145
145
|
return [];
|
|
@@ -148,10 +148,10 @@ function validateRelationProperty(propName, propValue, limetypes, property, guiM
|
|
|
148
148
|
throw new TypeError(`Relation property '${propName}' must be null or an object`);
|
|
149
149
|
}
|
|
150
150
|
const propValueObj = propValue;
|
|
151
|
-
const { keys: otherKeys,
|
|
151
|
+
const { keys: otherKeys, visualModeLimitations } = extractNonMetadataKeys(propValueObj, propName, visualModeEnabled);
|
|
152
152
|
// If it's just {} or { _alias: "...", "#...": "..." }, that's valid
|
|
153
153
|
if (otherKeys.length === 0) {
|
|
154
|
-
return
|
|
154
|
+
return visualModeLimitations;
|
|
155
155
|
}
|
|
156
156
|
// Otherwise, validate nested properties
|
|
157
157
|
const relatedLimetype = property.relation.getLimetype();
|
|
@@ -163,27 +163,27 @@ function validateRelationProperty(propName, propValue, limetypes, property, guiM
|
|
|
163
163
|
for (const key of otherKeys) {
|
|
164
164
|
cleanSelection[key] = propValueObj[key];
|
|
165
165
|
}
|
|
166
|
-
const nestedLimitations = validatePropertySelection(cleanSelection, limetypes, relatedLimetype.name,
|
|
167
|
-
return [...
|
|
166
|
+
const nestedLimitations = validatePropertySelection(cleanSelection, limetypes, relatedLimetype.name, visualModeEnabled);
|
|
167
|
+
return [...visualModeLimitations, ...nestedLimitations];
|
|
168
168
|
}
|
|
169
169
|
/**
|
|
170
170
|
* Validate a non-relation property value
|
|
171
171
|
* @param propName Property name
|
|
172
172
|
* @param propValue Property value
|
|
173
|
-
* @param
|
|
174
|
-
* @returns
|
|
173
|
+
* @param visualModeEnabled Whether visual mode is enabled (affects validation)
|
|
174
|
+
* @returns Visual mode limitations found (if any)
|
|
175
175
|
*/
|
|
176
|
-
function validateNonRelationProperty(propName, propValue,
|
|
176
|
+
function validateNonRelationProperty(propName, propValue, visualModeEnabled = true) {
|
|
177
177
|
// null is valid
|
|
178
178
|
if (propValue === null) {
|
|
179
179
|
return [];
|
|
180
180
|
}
|
|
181
181
|
// Allow empty object {} or object with only metadata (_alias, #...)
|
|
182
182
|
if (typeof propValue === 'object') {
|
|
183
|
-
const { keys: nonMetadataKeys,
|
|
183
|
+
const { keys: nonMetadataKeys, visualModeLimitations } = extractNonMetadataKeys(propValue, propName, visualModeEnabled);
|
|
184
184
|
if (nonMetadataKeys.length === 0) {
|
|
185
185
|
// {} or { _alias: "...", "#...": "..." } is valid
|
|
186
|
-
return
|
|
186
|
+
return visualModeLimitations;
|
|
187
187
|
}
|
|
188
188
|
throw new Error(`Non-relation property '${propName}' cannot have nested properties other than _alias or # properties (got: ${nonMetadataKeys.join(', ')})`);
|
|
189
189
|
}
|
|
@@ -196,14 +196,14 @@ function validateNonRelationProperty(propName, propValue, guiModeEnabled = true)
|
|
|
196
196
|
* @param normalizedProperties Normalized properties of the limetype
|
|
197
197
|
* @param limetypes Record of all available limetypes
|
|
198
198
|
* @param limetype Current limetype name
|
|
199
|
-
* @param
|
|
200
|
-
* @returns
|
|
199
|
+
* @param visualModeEnabled Whether visual mode is enabled (affects validation)
|
|
200
|
+
* @returns Visual mode limitations found (if any)
|
|
201
201
|
*/
|
|
202
|
-
function validateSinglePropertyEntry(propName, propValue, normalizedProperties, limetypes, limetype,
|
|
203
|
-
// Allow empty string (editing state in
|
|
202
|
+
function validateSinglePropertyEntry(propName, propValue, normalizedProperties, limetypes, limetype, visualModeEnabled = true) {
|
|
203
|
+
// Allow empty string (editing state in visual mode)
|
|
204
204
|
if (propName === '') {
|
|
205
|
-
// Only validate empty property name in
|
|
206
|
-
if (
|
|
205
|
+
// Only validate empty property name in visual mode
|
|
206
|
+
if (visualModeEnabled && propValue !== null) {
|
|
207
207
|
throw new Error('Empty property name must have null value');
|
|
208
208
|
}
|
|
209
209
|
return [];
|
|
@@ -215,10 +215,10 @@ function validateSinglePropertyEntry(propName, propValue, normalizedProperties,
|
|
|
215
215
|
}
|
|
216
216
|
// Validate value based on property type
|
|
217
217
|
if (property.relation) {
|
|
218
|
-
return validateRelationProperty(propName, propValue, limetypes, property,
|
|
218
|
+
return validateRelationProperty(propName, propValue, limetypes, property, visualModeEnabled);
|
|
219
219
|
}
|
|
220
220
|
else {
|
|
221
|
-
return validateNonRelationProperty(propName, propValue,
|
|
221
|
+
return validateNonRelationProperty(propName, propValue, visualModeEnabled);
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
@@ -227,26 +227,26 @@ function validateSinglePropertyEntry(propName, propValue, normalizedProperties,
|
|
|
227
227
|
* @param selection
|
|
228
228
|
* @param limetypes Record of all available limetypes
|
|
229
229
|
* @param limetype The limetype for this level of the selection
|
|
230
|
-
* @param
|
|
231
|
-
* @returns
|
|
230
|
+
* @param visualModeEnabled Whether visual mode is enabled (affects validation)
|
|
231
|
+
* @returns Visual mode limitations found (if any)
|
|
232
232
|
*/
|
|
233
|
-
export function validatePropertySelection(selection, limetypes, limetype,
|
|
233
|
+
export function validatePropertySelection(selection, limetypes, limetype, visualModeEnabled = true) {
|
|
234
234
|
const limetypeObj = limetypes[limetype];
|
|
235
235
|
if (!limetypeObj) {
|
|
236
236
|
throw new Error(`Unknown limetype: ${limetype}`);
|
|
237
237
|
}
|
|
238
238
|
const normalizedProperties = getNormalizedProperties(limetypeObj);
|
|
239
|
-
const
|
|
239
|
+
const allVisualModeLimitations = [];
|
|
240
240
|
for (const [propName, propValue] of Object.entries(selection)) {
|
|
241
241
|
// Skip # properties (comments/metadata that backend accepts via unknown=INCLUDE)
|
|
242
242
|
// Note: _alias only appears inside property value objects, not at this level
|
|
243
243
|
if (propName.startsWith('#')) {
|
|
244
244
|
continue;
|
|
245
245
|
}
|
|
246
|
-
const limitations = validateSinglePropertyEntry(propName, propValue, normalizedProperties, limetypes, limetype,
|
|
247
|
-
|
|
246
|
+
const limitations = validateSinglePropertyEntry(propName, propValue, normalizedProperties, limetypes, limetype, visualModeEnabled);
|
|
247
|
+
allVisualModeLimitations.push(...limitations);
|
|
248
248
|
}
|
|
249
|
-
return
|
|
249
|
+
return allVisualModeLimitations;
|
|
250
250
|
}
|
|
251
251
|
/**
|
|
252
252
|
* Validate a comparison expression (has 'key' property)
|
|
@@ -271,9 +271,9 @@ function validateComparisonExpression(filter, activeLimetype, limetypes) {
|
|
|
271
271
|
* @param filter
|
|
272
272
|
* @param activeLimetype
|
|
273
273
|
* @param limetypes
|
|
274
|
-
* @param
|
|
274
|
+
* @param visualModeEnabled
|
|
275
275
|
*/
|
|
276
|
-
function validateGroupExpression(filter, activeLimetype, limetypes,
|
|
276
|
+
function validateGroupExpression(filter, activeLimetype, limetypes, visualModeEnabled) {
|
|
277
277
|
// Validate operator
|
|
278
278
|
if (filter.op !== Operator.AND &&
|
|
279
279
|
filter.op !== Operator.OR &&
|
|
@@ -282,12 +282,12 @@ function validateGroupExpression(filter, activeLimetype, limetypes, guiModeEnabl
|
|
|
282
282
|
}
|
|
283
283
|
// Recursively validate children
|
|
284
284
|
if (filter.op === Operator.NOT) {
|
|
285
|
-
validateFilterPlaceholders(filter.exp, activeLimetype, limetypes,
|
|
285
|
+
validateFilterPlaceholders(filter.exp, activeLimetype, limetypes, visualModeEnabled);
|
|
286
286
|
}
|
|
287
287
|
else if (filter.op === Operator.AND || filter.op === Operator.OR) {
|
|
288
288
|
const expressions = filter.exp;
|
|
289
289
|
for (const expr of expressions) {
|
|
290
|
-
validateFilterPlaceholders(expr, activeLimetype, limetypes,
|
|
290
|
+
validateFilterPlaceholders(expr, activeLimetype, limetypes, visualModeEnabled);
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
}
|
|
@@ -296,9 +296,9 @@ function validateGroupExpression(filter, activeLimetype, limetypes, guiModeEnabl
|
|
|
296
296
|
* @param filter Filter expression to validate
|
|
297
297
|
* @param activeLimetype The limetype of the active object
|
|
298
298
|
* @param limetypes Record of all available limetypes
|
|
299
|
-
* @param
|
|
299
|
+
* @param visualModeEnabled Whether visual mode is enabled (affects validation)
|
|
300
300
|
*/
|
|
301
|
-
function validateFilterPlaceholders(filter, activeLimetype, limetypes,
|
|
301
|
+
function validateFilterPlaceholders(filter, activeLimetype, limetypes, visualModeEnabled = true) {
|
|
302
302
|
if (!filter) {
|
|
303
303
|
return;
|
|
304
304
|
}
|
|
@@ -307,7 +307,7 @@ function validateFilterPlaceholders(filter, activeLimetype, limetypes, guiModeEn
|
|
|
307
307
|
return;
|
|
308
308
|
}
|
|
309
309
|
if ('exp' in filter) {
|
|
310
|
-
validateGroupExpression(filter, activeLimetype, limetypes,
|
|
310
|
+
validateGroupExpression(filter, activeLimetype, limetypes, visualModeEnabled);
|
|
311
311
|
}
|
|
312
312
|
}
|
|
313
313
|
/**
|
|
@@ -315,13 +315,13 @@ function validateFilterPlaceholders(filter, activeLimetype, limetypes, guiModeEn
|
|
|
315
315
|
* @param filter The filter expression or group to validate
|
|
316
316
|
* @param activeLimetype Optional active object limetype for placeholder validation
|
|
317
317
|
* @param limetypes Record of all available limetypes
|
|
318
|
-
* @param
|
|
318
|
+
* @param visualModeEnabled Whether visual mode is enabled
|
|
319
319
|
* @returns Array of validation error messages
|
|
320
320
|
*/
|
|
321
|
-
function validateLimeQueryFilterInternal(filter, activeLimetype, limetypes,
|
|
321
|
+
function validateLimeQueryFilterInternal(filter, activeLimetype, limetypes, visualModeEnabled) {
|
|
322
322
|
const errors = [];
|
|
323
323
|
try {
|
|
324
|
-
validateFilterPlaceholders(filter, activeLimetype, limetypes,
|
|
324
|
+
validateFilterPlaceholders(filter, activeLimetype, limetypes, visualModeEnabled);
|
|
325
325
|
}
|
|
326
326
|
catch (error) {
|
|
327
327
|
errors.push(`Invalid filter: ${error.message}`);
|
|
@@ -440,14 +440,14 @@ function validateOrderByPropertyPath(propertyPath, limetypes, limetype, index) {
|
|
|
440
440
|
* @param responseFormat The response format to validate
|
|
441
441
|
* @param limetypes Record of all available limetypes
|
|
442
442
|
* @param limetype The limetype for this Lime Query
|
|
443
|
-
* @param
|
|
444
|
-
* @returns Object with validation errors and
|
|
443
|
+
* @param visualModeEnabled Whether visual mode is enabled
|
|
444
|
+
* @returns Object with validation errors and visual mode limitations
|
|
445
445
|
*/
|
|
446
|
-
function validateLimeQueryResponseFormatInternal(responseFormat, limetypes, limetype,
|
|
446
|
+
function validateLimeQueryResponseFormatInternal(responseFormat, limetypes, limetype, visualModeEnabled) {
|
|
447
447
|
const errors = [];
|
|
448
448
|
const limitations = [];
|
|
449
449
|
try {
|
|
450
|
-
const formatLimitations = validateResponseFormat(responseFormat, limetypes, limetype,
|
|
450
|
+
const formatLimitations = validateResponseFormat(responseFormat, limetypes, limetype, visualModeEnabled);
|
|
451
451
|
limitations.push(...formatLimitations);
|
|
452
452
|
}
|
|
453
453
|
catch (error) {
|
|
@@ -457,25 +457,25 @@ function validateLimeQueryResponseFormatInternal(responseFormat, limetypes, lime
|
|
|
457
457
|
}
|
|
458
458
|
/**
|
|
459
459
|
* Validate a Lime Query
|
|
460
|
-
* Returns validation result with separate arrays for validity errors and
|
|
460
|
+
* Returns validation result with separate arrays for validity errors and visual mode limitations
|
|
461
461
|
* @param limeQuery The Lime Query to validate
|
|
462
462
|
* @param limetypes Record of all available limetypes
|
|
463
463
|
* @param activeLimetype Optional active object limetype for placeholder validation
|
|
464
|
-
* @param
|
|
464
|
+
* @param visualModeEnabled Whether visual mode is enabled (affects validation)
|
|
465
465
|
* @returns LimeQueryValidationResult with validity status and any errors/limitations
|
|
466
466
|
*/
|
|
467
|
-
export function isLimeQuerySupported(limeQuery, limetypes, activeLimetype,
|
|
467
|
+
export function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, visualModeEnabled = true) {
|
|
468
468
|
// Handle empty/undefined Lime Query
|
|
469
469
|
if (!limeQuery) {
|
|
470
470
|
return {
|
|
471
471
|
valid: true,
|
|
472
|
-
|
|
472
|
+
visualModeSupported: true,
|
|
473
473
|
validationErrors: [],
|
|
474
|
-
|
|
474
|
+
visualModeLimitations: [],
|
|
475
475
|
};
|
|
476
476
|
}
|
|
477
477
|
const validationErrors = [];
|
|
478
|
-
const
|
|
478
|
+
const visualModeLimitations = [];
|
|
479
479
|
// Validate limetype exists
|
|
480
480
|
if (limeQuery.limetype && !limetypes[limeQuery.limetype]) {
|
|
481
481
|
validationErrors.push(`Unknown limetype: ${limeQuery.limetype}`);
|
|
@@ -489,26 +489,26 @@ export function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, guiMo
|
|
|
489
489
|
const orderByErrors = validateOrderBy(limeQuery.orderBy, limetypes, limeQuery.limetype);
|
|
490
490
|
validationErrors.push(...orderByErrors);
|
|
491
491
|
}
|
|
492
|
-
// Check for
|
|
493
|
-
if (
|
|
494
|
-
|
|
492
|
+
// Check for visual-mode-unsupported top-level properties
|
|
493
|
+
if (visualModeEnabled && limeQuery.offset !== undefined) {
|
|
494
|
+
visualModeLimitations.push('offset is not yet supported in visual mode');
|
|
495
495
|
}
|
|
496
496
|
// Validate filter
|
|
497
497
|
if (limeQuery.filter) {
|
|
498
|
-
const filterErrors = validateLimeQueryFilterInternal(limeQuery.filter, activeLimetype, limetypes,
|
|
498
|
+
const filterErrors = validateLimeQueryFilterInternal(limeQuery.filter, activeLimetype, limetypes, visualModeEnabled);
|
|
499
499
|
validationErrors.push(...filterErrors);
|
|
500
500
|
}
|
|
501
501
|
// Validate responseFormat
|
|
502
502
|
if (limeQuery.responseFormat) {
|
|
503
|
-
const { errors, limitations } = validateLimeQueryResponseFormatInternal(limeQuery.responseFormat, limetypes, limeQuery.limetype,
|
|
503
|
+
const { errors, limitations } = validateLimeQueryResponseFormatInternal(limeQuery.responseFormat, limetypes, limeQuery.limetype, visualModeEnabled);
|
|
504
504
|
validationErrors.push(...errors);
|
|
505
|
-
|
|
505
|
+
visualModeLimitations.push(...limitations);
|
|
506
506
|
}
|
|
507
507
|
return {
|
|
508
508
|
valid: validationErrors.length === 0,
|
|
509
|
-
|
|
509
|
+
visualModeSupported: visualModeLimitations.length === 0,
|
|
510
510
|
validationErrors,
|
|
511
|
-
|
|
511
|
+
visualModeLimitations,
|
|
512
512
|
};
|
|
513
513
|
}
|
|
514
514
|
// ============================================================================
|
|
@@ -523,31 +523,31 @@ export function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, guiMo
|
|
|
523
523
|
* @param responseFormat - The response format to validate
|
|
524
524
|
* @param limetypes - Record of all available limetypes
|
|
525
525
|
* @param limetype - The limetype context for validation
|
|
526
|
-
* @param
|
|
527
|
-
* @returns Validation result with errors and
|
|
526
|
+
* @param visualModeEnabled - Whether visual mode is enabled (affects validation)
|
|
527
|
+
* @returns Validation result with errors and visual mode limitations
|
|
528
528
|
*/
|
|
529
|
-
export function validateResponseFormatOnly(responseFormat, limetypes, limetype,
|
|
529
|
+
export function validateResponseFormatOnly(responseFormat, limetypes, limetype, visualModeEnabled = true) {
|
|
530
530
|
const validationErrors = [];
|
|
531
|
-
const
|
|
531
|
+
const visualModeLimitations = [];
|
|
532
532
|
// Validate limetype exists
|
|
533
533
|
if (!limetypes[limetype]) {
|
|
534
534
|
validationErrors.push(`Unknown limetype: ${limetype}`);
|
|
535
535
|
// Can't proceed with property validation if limetype is unknown
|
|
536
536
|
return {
|
|
537
537
|
valid: false,
|
|
538
|
-
|
|
538
|
+
visualModeSupported: false,
|
|
539
539
|
validationErrors,
|
|
540
|
-
|
|
540
|
+
visualModeLimitations,
|
|
541
541
|
};
|
|
542
542
|
}
|
|
543
543
|
// Use internal validation logic
|
|
544
|
-
const { errors, limitations } = validateLimeQueryResponseFormatInternal(responseFormat, limetypes, limetype,
|
|
544
|
+
const { errors, limitations } = validateLimeQueryResponseFormatInternal(responseFormat, limetypes, limetype, visualModeEnabled);
|
|
545
545
|
validationErrors.push(...errors);
|
|
546
|
-
|
|
546
|
+
visualModeLimitations.push(...limitations);
|
|
547
547
|
return {
|
|
548
548
|
valid: validationErrors.length === 0,
|
|
549
|
-
|
|
549
|
+
visualModeSupported: visualModeLimitations.length === 0,
|
|
550
550
|
validationErrors,
|
|
551
|
-
|
|
551
|
+
visualModeLimitations,
|
|
552
552
|
};
|
|
553
553
|
}
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
|
|
58
58
|
limel-header.is-narrow {
|
|
59
59
|
--header-top-right-left-border-radius: 0;
|
|
60
|
-
width: calc(100% + var(--limebb-lime-query-builder-
|
|
61
|
-
margin-left: calc(var(--limebb-lime-query-builder-
|
|
60
|
+
width: calc(100% + var(--limebb-lime-query-builder-visual-mode-padding) * 2);
|
|
61
|
+
margin-left: calc(var(--limebb-lime-query-builder-visual-mode-padding) * -1);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
.empty-state {
|
package/dist/collection/components/lime-query-builder/response-format/response-format-helpers.js
CHANGED
|
@@ -32,7 +32,7 @@ export function parseResponseFormat(json) {
|
|
|
32
32
|
`Only 'object' and 'aggregates' are allowed.`);
|
|
33
33
|
}
|
|
34
34
|
// Must have at least one of object or aggregates
|
|
35
|
-
// Note: Empty objects {} are valid (starting point for
|
|
35
|
+
// Note: Empty objects {} are valid (starting point for visual mode)
|
|
36
36
|
const hasProperties = keys.length > 0;
|
|
37
37
|
if (hasProperties && !parsed.object && !parsed.aggregates) {
|
|
38
38
|
throw new Error('Response format must contain at least one of: object, aggregates');
|
|
@@ -84,7 +84,7 @@ export function isValidResponseFormatStructure(json) {
|
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
// Must have at least one of object or aggregates
|
|
87
|
-
// Note: Empty objects {} are valid (starting point for
|
|
87
|
+
// Note: Empty objects {} are valid (starting point for visual mode)
|
|
88
88
|
const hasProperties = keys.length > 0;
|
|
89
89
|
if (hasProperties && !json.object && !json.aggregates) {
|
|
90
90
|
return {
|