@limetech/lime-crm-building-blocks 1.105.0 → 1.105.2
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/{lime-query-validation-82aa2855.js → lime-query-validation-6d419d03.js} +78 -16
- package/dist/cjs/limebb-document-item.cjs.entry.js +29 -8
- package/dist/cjs/limebb-document-picker.cjs.entry.js +3 -3
- package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +2 -2
- package/dist/cjs/limebb-lime-query-filter-group_3.cjs.entry.js +1 -1
- package/dist/cjs/limebb-lime-query-response-format-builder.cjs.entry.js +2 -2
- package/dist/cjs/limebb-property-selector.cjs.entry.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{property-resolution-fb42a46b.js → property-resolution-5f798b03.js} +47 -0
- package/dist/collection/components/chat-list/chat-item/chat-item.js +2 -2
- package/dist/collection/components/chat-list/chat-list.js +2 -2
- package/dist/collection/components/component-command-picker/component-config/component-config.js +2 -2
- package/dist/collection/components/component-command-picker/component-picker/component-picker.js +2 -2
- package/dist/collection/components/date-picker/date-picker.js +2 -2
- package/dist/collection/components/date-range/date-range.js +2 -2
- package/dist/collection/components/document-picker/document-item/document-item.js +55 -10
- package/dist/collection/components/document-picker/document-picker.js +5 -5
- package/dist/collection/components/feed/feed-item/feed-timeline-item.js +2 -2
- package/dist/collection/components/feed/feed.js +2 -2
- package/dist/collection/components/info-tile/info-tile.js +2 -2
- package/dist/collection/components/kanban/kanban-group/kanban-group.js +2 -2
- package/dist/collection/components/kanban/kanban-item/kanban-item.js +2 -2
- package/dist/collection/components/kanban/kanban.js +2 -2
- package/dist/collection/components/lime-query-builder/lime-query-validation.js +78 -17
- package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +2 -2
- package/dist/collection/components/lime-query-builder/property-resolution.js +46 -0
- package/dist/collection/components/limeobject/file-viewer/file-viewer.js +2 -2
- package/dist/collection/components/loader/loader.js +2 -2
- package/dist/collection/components/locale-picker/locale-picker.js +2 -2
- package/dist/collection/components/notification-list/notification-item/notification-item.js +2 -2
- package/dist/collection/components/notification-list/notification-list.js +2 -2
- package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
- package/dist/collection/components/trend-indicator/trend-indicator.js +2 -2
- package/dist/components/document-item.js +31 -9
- package/dist/components/lime-query-validation.js +78 -16
- package/dist/components/limebb-document-picker.js +3 -3
- package/dist/components/property-selector.js +47 -1
- package/dist/esm/lime-crm-building-blocks.js +1 -1
- package/dist/esm/{lime-query-validation-9e386da8.js → lime-query-validation-237ee440.js} +78 -16
- package/dist/esm/limebb-document-item.entry.js +29 -8
- package/dist/esm/limebb-document-picker.entry.js +3 -3
- package/dist/esm/limebb-lime-query-builder.entry.js +2 -2
- package/dist/esm/limebb-lime-query-filter-group_3.entry.js +1 -1
- package/dist/esm/limebb-lime-query-response-format-builder.entry.js +2 -2
- package/dist/esm/limebb-property-selector.entry.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{property-resolution-c21a1369.js → property-resolution-e4e8dcf7.js} +47 -1
- package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
- package/dist/lime-crm-building-blocks/{p-ac9e81c9.entry.js → p-09ce8be4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-11aa4103.js +1 -0
- package/dist/lime-crm-building-blocks/p-2673c79e.entry.js +1 -0
- package/dist/lime-crm-building-blocks/p-80b9d946.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-d8696b23.entry.js → p-9c2062bc.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-b02c99d5.js +1 -0
- package/dist/lime-crm-building-blocks/{p-908dd7d5.entry.js → p-ee0e42dd.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-1421e1f8.entry.js → p-f7ea292d.entry.js} +1 -1
- package/dist/types/components/document-picker/document-item/document-item.d.ts +8 -1
- package/dist/types/components/document-picker/document-item/document-item.types.d.ts +3 -15
- package/dist/types/components/lime-query-builder/lime-query-validation.d.ts +14 -0
- package/dist/types/components/lime-query-builder/property-resolution.d.ts +12 -0
- package/dist/types/components.d.ts +96 -88
- package/package.json +4 -4
- package/dist/lime-crm-building-blocks/p-876701c6.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-9d25ed5a.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-b748c770.js +0 -1
- package/dist/lime-crm-building-blocks/p-efa5bcd4.js +0 -1
package/dist/collection/components/component-command-picker/component-config/component-config.js
CHANGED
|
@@ -154,7 +154,7 @@ export class ComponentConfig {
|
|
|
154
154
|
"optional": false,
|
|
155
155
|
"docs": {
|
|
156
156
|
"tags": [],
|
|
157
|
-
"text": "Reference to the platform"
|
|
157
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
158
158
|
},
|
|
159
159
|
"getter": false,
|
|
160
160
|
"setter": false
|
|
@@ -177,7 +177,7 @@ export class ComponentConfig {
|
|
|
177
177
|
"optional": false,
|
|
178
178
|
"docs": {
|
|
179
179
|
"tags": [],
|
|
180
|
-
"text": "The context this component
|
|
180
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
181
181
|
},
|
|
182
182
|
"getter": false,
|
|
183
183
|
"setter": false
|
package/dist/collection/components/component-command-picker/component-picker/component-picker.js
CHANGED
|
@@ -174,7 +174,7 @@ export class ComponentPicker {
|
|
|
174
174
|
"optional": false,
|
|
175
175
|
"docs": {
|
|
176
176
|
"tags": [],
|
|
177
|
-
"text": "Reference to the platform"
|
|
177
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
178
178
|
},
|
|
179
179
|
"getter": false,
|
|
180
180
|
"setter": false
|
|
@@ -197,7 +197,7 @@ export class ComponentPicker {
|
|
|
197
197
|
"optional": false,
|
|
198
198
|
"docs": {
|
|
199
199
|
"tags": [],
|
|
200
|
-
"text": "The context this component
|
|
200
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
201
201
|
},
|
|
202
202
|
"getter": false,
|
|
203
203
|
"setter": false
|
|
@@ -118,7 +118,7 @@ export class DatePicker {
|
|
|
118
118
|
"name": "inheritdoc",
|
|
119
119
|
"text": undefined
|
|
120
120
|
}],
|
|
121
|
-
"text": "Reference to the platform"
|
|
121
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
122
122
|
},
|
|
123
123
|
"getter": false,
|
|
124
124
|
"setter": false
|
|
@@ -144,7 +144,7 @@ export class DatePicker {
|
|
|
144
144
|
"name": "inheritdoc",
|
|
145
145
|
"text": undefined
|
|
146
146
|
}],
|
|
147
|
-
"text": "The context this component
|
|
147
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
148
148
|
},
|
|
149
149
|
"getter": false,
|
|
150
150
|
"setter": false
|
|
@@ -89,7 +89,7 @@ export class DateRange {
|
|
|
89
89
|
"name": "inheritdoc",
|
|
90
90
|
"text": undefined
|
|
91
91
|
}],
|
|
92
|
-
"text": "Reference to the platform"
|
|
92
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
93
93
|
},
|
|
94
94
|
"getter": false,
|
|
95
95
|
"setter": false
|
|
@@ -115,7 +115,7 @@ export class DateRange {
|
|
|
115
115
|
"name": "inheritdoc",
|
|
116
116
|
"text": undefined
|
|
117
117
|
}],
|
|
118
|
-
"text": "The context this component
|
|
118
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
119
119
|
},
|
|
120
120
|
"getter": false,
|
|
121
121
|
"setter": false
|
|
@@ -13,6 +13,11 @@ export class DocumentItemComponent {
|
|
|
13
13
|
* - 'checkbox': renders a checkbox for multiple selection.
|
|
14
14
|
*/
|
|
15
15
|
this.type = 'checkbox';
|
|
16
|
+
/**
|
|
17
|
+
* The preferred file URL types to use when displaying
|
|
18
|
+
* the document's image preview.
|
|
19
|
+
*/
|
|
20
|
+
this.fileTypes = ['view', 'contents', 'download'];
|
|
16
21
|
this.handleDocumentItemClick = (event) => {
|
|
17
22
|
if (this.isUnavailable()) {
|
|
18
23
|
return;
|
|
@@ -72,21 +77,22 @@ export class DocumentItemComponent {
|
|
|
72
77
|
}
|
|
73
78
|
render() {
|
|
74
79
|
const isUnavailable = this.isUnavailable();
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
const image = this.getImage();
|
|
81
|
+
return (h(Host, { key: '7fc37bbc0185cdb38c837f2487c88f4d275d1c2f', id: String(this.item.file.id), class: {
|
|
82
|
+
'has-image': !!image,
|
|
77
83
|
'has-error': !!this.item.hasError,
|
|
78
|
-
}, role: this.type === 'radio' ? 'radio' : 'checkbox', "aria-checked": this.item.selected ? 'true' : 'false', "aria-disabled": isUnavailable ? 'true' : 'false', tabIndex: isUnavailable ? -1 : 0 }, h("limel-card", { key: '
|
|
84
|
+
}, role: this.type === 'radio' ? 'radio' : 'checkbox', "aria-checked": this.item.selected ? 'true' : 'false', "aria-disabled": isUnavailable ? 'true' : 'false', tabIndex: isUnavailable ? -1 : 0 }, h("limel-card", { key: 'da1329af4f1eac4617da054b5b02715b512631ff', image: image, clickable: isUnavailable ? false : true, onClick: this.handleDocumentItemClick, onKeyDown: this.handleKeyDown }, h("div", { key: 'a30361cfb76512065fe3cf1b513f31257cf115ee', slot: "component" }, this.renderFileSize(), this.renderBooleanInput())), this.renderHelp()));
|
|
79
85
|
}
|
|
80
86
|
renderBooleanInput() {
|
|
81
87
|
const id = this.getControlId();
|
|
82
88
|
if (this.type === 'radio') {
|
|
83
|
-
return (h("limel-radio-button", { id: id, label: this.item.
|
|
89
|
+
return (h("limel-radio-button", { id: id, label: this.item.file.filename, disabled: this.isUnavailable(), checked: this.item.selected, onClick: this.handleSelectionControlClick, onChange: this.handleSelectionControlChange }));
|
|
84
90
|
}
|
|
85
|
-
return (h("limel-checkbox", { id: id, label: this.item.
|
|
91
|
+
return (h("limel-checkbox", { id: id, label: this.item.file.filename, disabled: this.isUnavailable(), checked: this.item.selected, onClick: this.handleSelectionControlClick, onChange: this.handleSelectionControlChange }));
|
|
86
92
|
}
|
|
87
93
|
renderFileSize() {
|
|
88
|
-
var _a;
|
|
89
|
-
const formattedFileSize = formatBytes((_a = this.item) === null || _a === void 0 ? void 0 : _a.
|
|
94
|
+
var _a, _b;
|
|
95
|
+
const formattedFileSize = formatBytes((_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.file) === null || _b === void 0 ? void 0 : _b.size);
|
|
90
96
|
if (!formattedFileSize) {
|
|
91
97
|
return;
|
|
92
98
|
}
|
|
@@ -112,7 +118,7 @@ export class DocumentItemComponent {
|
|
|
112
118
|
this.interact.emit(Object.assign(Object.assign({}, this.item), { selected }));
|
|
113
119
|
}
|
|
114
120
|
getControlId() {
|
|
115
|
-
return `boolean-input-${String(this.item.id)}`;
|
|
121
|
+
return `boolean-input-${String(this.item.file.id)}`;
|
|
116
122
|
}
|
|
117
123
|
isUnavailable() {
|
|
118
124
|
var _a, _b;
|
|
@@ -126,6 +132,21 @@ export class DocumentItemComponent {
|
|
|
126
132
|
input.checked = false;
|
|
127
133
|
}
|
|
128
134
|
}
|
|
135
|
+
getImage() {
|
|
136
|
+
const href = this.hrefForFile();
|
|
137
|
+
if (!href) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
src: href,
|
|
142
|
+
alt: this.item.file.filename,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
hrefForFile() {
|
|
146
|
+
return ['preview', ...this.fileTypes]
|
|
147
|
+
.map((type) => this.item.file.getUrl(type))
|
|
148
|
+
.find(Boolean);
|
|
149
|
+
}
|
|
129
150
|
static get is() { return "limebb-document-item"; }
|
|
130
151
|
static get encapsulation() { return "shadow"; }
|
|
131
152
|
static get delegatesFocus() { return true; }
|
|
@@ -162,7 +183,7 @@ export class DocumentItemComponent {
|
|
|
162
183
|
"name": "inheritdoc",
|
|
163
184
|
"text": undefined
|
|
164
185
|
}],
|
|
165
|
-
"text": "Reference to the platform"
|
|
186
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
166
187
|
},
|
|
167
188
|
"getter": false,
|
|
168
189
|
"setter": false
|
|
@@ -188,7 +209,7 @@ export class DocumentItemComponent {
|
|
|
188
209
|
"name": "inheritdoc",
|
|
189
210
|
"text": undefined
|
|
190
211
|
}],
|
|
191
|
-
"text": "The context this component
|
|
212
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
192
213
|
},
|
|
193
214
|
"getter": false,
|
|
194
215
|
"setter": false
|
|
@@ -235,6 +256,30 @@ export class DocumentItemComponent {
|
|
|
235
256
|
"attribute": "type",
|
|
236
257
|
"reflect": true,
|
|
237
258
|
"defaultValue": "'checkbox'"
|
|
259
|
+
},
|
|
260
|
+
"fileTypes": {
|
|
261
|
+
"type": "unknown",
|
|
262
|
+
"mutable": false,
|
|
263
|
+
"complexType": {
|
|
264
|
+
"original": "LimeFileUrlType[]",
|
|
265
|
+
"resolved": "LimeFileUrlType[]",
|
|
266
|
+
"references": {
|
|
267
|
+
"LimeFileUrlType": {
|
|
268
|
+
"location": "import",
|
|
269
|
+
"path": "@limetech/lime-web-components",
|
|
270
|
+
"id": "node_modules::LimeFileUrlType"
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
"required": false,
|
|
275
|
+
"optional": false,
|
|
276
|
+
"docs": {
|
|
277
|
+
"tags": [],
|
|
278
|
+
"text": "The preferred file URL types to use when displaying\nthe document's image preview."
|
|
279
|
+
},
|
|
280
|
+
"getter": false,
|
|
281
|
+
"setter": false,
|
|
282
|
+
"defaultValue": "['view', 'contents', 'download']"
|
|
238
283
|
}
|
|
239
284
|
};
|
|
240
285
|
}
|
|
@@ -47,7 +47,7 @@ export class DocumentPicker {
|
|
|
47
47
|
// or allow deselecting if clicking the already selected item
|
|
48
48
|
updatedItems = this.items
|
|
49
49
|
.map((item) => {
|
|
50
|
-
if (item.id === interactedItem.id) {
|
|
50
|
+
if (item.file.id === interactedItem.file.id) {
|
|
51
51
|
return Object.assign(Object.assign({}, item), { selected: interactedItem.selected });
|
|
52
52
|
}
|
|
53
53
|
return Object.assign(Object.assign({}, item), { selected: false });
|
|
@@ -57,7 +57,7 @@ export class DocumentPicker {
|
|
|
57
57
|
else {
|
|
58
58
|
updatedItems = this.items
|
|
59
59
|
.map((item) => {
|
|
60
|
-
if (item.id === interactedItem.id) {
|
|
60
|
+
if (item.file.id === interactedItem.file.id) {
|
|
61
61
|
return Object.assign(Object.assign({}, item), { selected: interactedItem.selected });
|
|
62
62
|
}
|
|
63
63
|
return item;
|
|
@@ -79,7 +79,7 @@ export class DocumentPicker {
|
|
|
79
79
|
return (h(Host, { key: '5e4a9004ed3b81b6c35be868c664e61cb88d490c' }, h("limel-notched-outline", { key: 'ada8928b3ed815896e1ef5fb61f539f0ab77c7af', labelId: this.labelId, label: this.label, required: this.required, invalid: this.invalid, hasFloatingLabel: true }, h("div", { key: '343aeef460a4ea4e0a4a247daf6988f749dc2b49', slot: "content", role: this.type === 'radio' ? 'radiogroup' : 'group', "aria-labelledby": this.label ? this.labelId : undefined, "aria-describedby": this.helperText ? this.helperTextId : undefined }, this.renderItems())), this.renderHelperLine()));
|
|
80
80
|
}
|
|
81
81
|
renderItems() {
|
|
82
|
-
return this.items.map((item) => (h("limebb-document-item", { platform: this.platform, context: this.context, item: item, key: item.id, type: this.type, onInteract: this.handleItemInteract })));
|
|
82
|
+
return this.items.map((item) => (h("limebb-document-item", { platform: this.platform, context: this.context, item: item, key: item.file.id, type: this.type, onInteract: this.handleItemInteract })));
|
|
83
83
|
}
|
|
84
84
|
static get is() { return "limebb-document-picker"; }
|
|
85
85
|
static get encapsulation() { return "shadow"; }
|
|
@@ -116,7 +116,7 @@ export class DocumentPicker {
|
|
|
116
116
|
"name": "inheritdoc",
|
|
117
117
|
"text": undefined
|
|
118
118
|
}],
|
|
119
|
-
"text": "Reference to the platform"
|
|
119
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
120
120
|
},
|
|
121
121
|
"getter": false,
|
|
122
122
|
"setter": false
|
|
@@ -142,7 +142,7 @@ export class DocumentPicker {
|
|
|
142
142
|
"name": "inheritdoc",
|
|
143
143
|
"text": undefined
|
|
144
144
|
}],
|
|
145
|
-
"text": "The context this component
|
|
145
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
146
146
|
},
|
|
147
147
|
"getter": false,
|
|
148
148
|
"setter": false
|
|
@@ -419,7 +419,7 @@ export class FeedTimelineItem {
|
|
|
419
419
|
"name": "inheritdoc",
|
|
420
420
|
"text": undefined
|
|
421
421
|
}],
|
|
422
|
-
"text": "Reference to the platform"
|
|
422
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
423
423
|
},
|
|
424
424
|
"getter": false,
|
|
425
425
|
"setter": false
|
|
@@ -445,7 +445,7 @@ export class FeedTimelineItem {
|
|
|
445
445
|
"name": "inheritdoc",
|
|
446
446
|
"text": undefined
|
|
447
447
|
}],
|
|
448
|
-
"text": "The context this component
|
|
448
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
449
449
|
},
|
|
450
450
|
"getter": false,
|
|
451
451
|
"setter": false
|
|
@@ -227,7 +227,7 @@ export class Feed {
|
|
|
227
227
|
"name": "inheritdoc",
|
|
228
228
|
"text": undefined
|
|
229
229
|
}],
|
|
230
|
-
"text": "Reference to the platform"
|
|
230
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
231
231
|
},
|
|
232
232
|
"getter": false,
|
|
233
233
|
"setter": false
|
|
@@ -253,7 +253,7 @@ export class Feed {
|
|
|
253
253
|
"name": "inheritdoc",
|
|
254
254
|
"text": undefined
|
|
255
255
|
}],
|
|
256
|
-
"text": "The context this component
|
|
256
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
257
257
|
},
|
|
258
258
|
"getter": false,
|
|
259
259
|
"setter": false
|
|
@@ -189,7 +189,7 @@ export class InfoTile {
|
|
|
189
189
|
"optional": false,
|
|
190
190
|
"docs": {
|
|
191
191
|
"tags": [],
|
|
192
|
-
"text": "Reference to the platform"
|
|
192
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
193
193
|
},
|
|
194
194
|
"getter": false,
|
|
195
195
|
"setter": false
|
|
@@ -212,7 +212,7 @@ export class InfoTile {
|
|
|
212
212
|
"optional": false,
|
|
213
213
|
"docs": {
|
|
214
214
|
"tags": [],
|
|
215
|
-
"text": "The context this component
|
|
215
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
216
216
|
},
|
|
217
217
|
"getter": false,
|
|
218
218
|
"setter": false
|
|
@@ -127,7 +127,7 @@ export class KanbanGroup {
|
|
|
127
127
|
"name": "inheritdoc",
|
|
128
128
|
"text": undefined
|
|
129
129
|
}],
|
|
130
|
-
"text": "Reference to the platform"
|
|
130
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
131
131
|
},
|
|
132
132
|
"getter": false,
|
|
133
133
|
"setter": false
|
|
@@ -153,7 +153,7 @@ export class KanbanGroup {
|
|
|
153
153
|
"name": "inheritdoc",
|
|
154
154
|
"text": undefined
|
|
155
155
|
}],
|
|
156
|
-
"text": "The context this component
|
|
156
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
157
157
|
},
|
|
158
158
|
"getter": false,
|
|
159
159
|
"setter": false
|
|
@@ -164,7 +164,7 @@ export class KanbanItemComponent {
|
|
|
164
164
|
"name": "inheritdoc",
|
|
165
165
|
"text": undefined
|
|
166
166
|
}],
|
|
167
|
-
"text": "Reference to the platform"
|
|
167
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
168
168
|
},
|
|
169
169
|
"getter": false,
|
|
170
170
|
"setter": false
|
|
@@ -190,7 +190,7 @@ export class KanbanItemComponent {
|
|
|
190
190
|
"name": "inheritdoc",
|
|
191
191
|
"text": undefined
|
|
192
192
|
}],
|
|
193
|
-
"text": "The context this component
|
|
193
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
194
194
|
},
|
|
195
195
|
"getter": false,
|
|
196
196
|
"setter": false
|
|
@@ -72,7 +72,7 @@ export class Kanban {
|
|
|
72
72
|
"name": "inheritdoc",
|
|
73
73
|
"text": undefined
|
|
74
74
|
}],
|
|
75
|
-
"text": "Reference to the platform"
|
|
75
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
76
76
|
},
|
|
77
77
|
"getter": false,
|
|
78
78
|
"setter": false
|
|
@@ -98,7 +98,7 @@ export class Kanban {
|
|
|
98
98
|
"name": "inheritdoc",
|
|
99
99
|
"text": undefined
|
|
100
100
|
}],
|
|
101
|
-
"text": "The context this component
|
|
101
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
102
102
|
},
|
|
103
103
|
"getter": false,
|
|
104
104
|
"setter": false
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Operator } from "@limetech/lime-web-components";
|
|
2
|
-
import { getNormalizedProperties } from "./property-resolution";
|
|
3
|
-
import { getPropertyFromPath } from "./property-resolution";
|
|
2
|
+
import { getNormalizedProperties, getPropertyFromPath, validatePropertyPath, } from "./property-resolution";
|
|
4
3
|
/**
|
|
5
4
|
* Dynamic filter values and placeholders that are valid in Lime Query
|
|
6
5
|
*/
|
|
@@ -85,6 +84,46 @@ export function validatePlaceholder(value, activeLimetype, limetypes) {
|
|
|
85
84
|
};
|
|
86
85
|
}
|
|
87
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Validates a filter expression key (property path).
|
|
89
|
+
* Supports both regular property paths and placeholders.
|
|
90
|
+
*
|
|
91
|
+
* @param key - Property path to validate (e.g., "name", "company.name", "%activeObject%.name")
|
|
92
|
+
* @param limetypes - All limetype definitions
|
|
93
|
+
* @param limetype - The limetype being filtered
|
|
94
|
+
* @param activeLimetype - Active limetype for placeholder resolution
|
|
95
|
+
* @returns Validation result with error message if invalid
|
|
96
|
+
*/
|
|
97
|
+
export function validateFilterKey(key, limetypes, limetype, activeLimetype) {
|
|
98
|
+
// 1. Handle empty/missing keys
|
|
99
|
+
if (!key) {
|
|
100
|
+
return { valid: false, error: 'Filter key cannot be empty' };
|
|
101
|
+
}
|
|
102
|
+
// 2. Check if key is a placeholder
|
|
103
|
+
if (key.startsWith('%activeObject%')) {
|
|
104
|
+
const placeholderResult = validatePlaceholder(key, activeLimetype, limetypes);
|
|
105
|
+
if (!placeholderResult.valid) {
|
|
106
|
+
return placeholderResult;
|
|
107
|
+
}
|
|
108
|
+
// Extract property path after the placeholder and validate for hasMany/hasAndBelongsToMany
|
|
109
|
+
const propertyPath = key.replace(/^%activeObject%\.?/, '');
|
|
110
|
+
if (propertyPath && activeLimetype) {
|
|
111
|
+
const { error } = validatePropertyPath(limetypes, activeLimetype, propertyPath);
|
|
112
|
+
if (error) {
|
|
113
|
+
return { valid: false, error };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return placeholderResult;
|
|
117
|
+
}
|
|
118
|
+
// 3. Validate regular property path (including intermediate properties)
|
|
119
|
+
const { error } = validatePropertyPath(limetypes, limetype, key);
|
|
120
|
+
if (error) {
|
|
121
|
+
return { valid: false, error };
|
|
122
|
+
}
|
|
123
|
+
// validatePropertyPath always returns an error if property is undefined,
|
|
124
|
+
// so if we reach here, the property exists and is valid
|
|
125
|
+
return { valid: true };
|
|
126
|
+
}
|
|
88
127
|
/**
|
|
89
128
|
* Validate a response format against limetype schemas
|
|
90
129
|
* Throws errors for invalid property references
|
|
@@ -253,13 +292,19 @@ export function validatePropertySelection(selection, limetypes, limetype, visual
|
|
|
253
292
|
* @param filter
|
|
254
293
|
* @param activeLimetype
|
|
255
294
|
* @param limetypes
|
|
295
|
+
* @param limetype
|
|
256
296
|
*/
|
|
257
|
-
function validateComparisonExpression(filter, activeLimetype, limetypes) {
|
|
297
|
+
function validateComparisonExpression(filter, activeLimetype, limetypes, limetype) {
|
|
258
298
|
// Validate operator
|
|
259
299
|
const allValidOperators = Object.values(Operator);
|
|
260
300
|
if (!allValidOperators.includes(filter.op)) {
|
|
261
301
|
throw new Error(`Unsupported filter operator: ${filter.op}`);
|
|
262
302
|
}
|
|
303
|
+
// Validate filter key
|
|
304
|
+
const keyResult = validateFilterKey(filter.key, limetypes, limetype, activeLimetype);
|
|
305
|
+
if (!keyResult.valid) {
|
|
306
|
+
throw new Error(`Invalid filter key '${filter.key}': ${keyResult.error}`);
|
|
307
|
+
}
|
|
263
308
|
// Validate placeholder
|
|
264
309
|
const result = validatePlaceholder(filter.exp, activeLimetype, limetypes);
|
|
265
310
|
if (!result.valid) {
|
|
@@ -271,9 +316,10 @@ function validateComparisonExpression(filter, activeLimetype, limetypes) {
|
|
|
271
316
|
* @param filter
|
|
272
317
|
* @param activeLimetype
|
|
273
318
|
* @param limetypes
|
|
319
|
+
* @param limetype
|
|
274
320
|
* @param visualModeEnabled
|
|
275
321
|
*/
|
|
276
|
-
function validateGroupExpression(filter, activeLimetype, limetypes, visualModeEnabled) {
|
|
322
|
+
function validateGroupExpression(filter, activeLimetype, limetypes, limetype, visualModeEnabled) {
|
|
277
323
|
// Validate operator
|
|
278
324
|
if (filter.op !== Operator.AND &&
|
|
279
325
|
filter.op !== Operator.OR &&
|
|
@@ -282,12 +328,12 @@ function validateGroupExpression(filter, activeLimetype, limetypes, visualModeEn
|
|
|
282
328
|
}
|
|
283
329
|
// Recursively validate children
|
|
284
330
|
if (filter.op === Operator.NOT) {
|
|
285
|
-
validateFilterPlaceholders(filter.exp, activeLimetype, limetypes, visualModeEnabled);
|
|
331
|
+
validateFilterPlaceholders(filter.exp, activeLimetype, limetypes, limetype, visualModeEnabled);
|
|
286
332
|
}
|
|
287
333
|
else if (filter.op === Operator.AND || filter.op === Operator.OR) {
|
|
288
334
|
const expressions = filter.exp;
|
|
289
335
|
for (const expr of expressions) {
|
|
290
|
-
validateFilterPlaceholders(expr, activeLimetype, limetypes, visualModeEnabled);
|
|
336
|
+
validateFilterPlaceholders(expr, activeLimetype, limetypes, limetype, visualModeEnabled);
|
|
291
337
|
}
|
|
292
338
|
}
|
|
293
339
|
}
|
|
@@ -296,37 +342,51 @@ function validateGroupExpression(filter, activeLimetype, limetypes, visualModeEn
|
|
|
296
342
|
* @param filter Filter expression to validate
|
|
297
343
|
* @param activeLimetype The limetype of the active object
|
|
298
344
|
* @param limetypes Record of all available limetypes
|
|
345
|
+
* @param limetype The limetype being filtered
|
|
299
346
|
* @param visualModeEnabled Whether visual mode is enabled (affects validation)
|
|
300
347
|
*/
|
|
301
|
-
function validateFilterPlaceholders(filter, activeLimetype, limetypes, visualModeEnabled = true) {
|
|
348
|
+
function validateFilterPlaceholders(filter, activeLimetype, limetypes, limetype, visualModeEnabled = true) {
|
|
302
349
|
if (!filter) {
|
|
303
350
|
return;
|
|
304
351
|
}
|
|
305
352
|
if ('key' in filter) {
|
|
306
|
-
validateComparisonExpression(filter, activeLimetype, limetypes);
|
|
353
|
+
validateComparisonExpression(filter, activeLimetype, limetypes, limetype);
|
|
307
354
|
return;
|
|
308
355
|
}
|
|
309
356
|
if ('exp' in filter) {
|
|
310
|
-
validateGroupExpression(filter, activeLimetype, limetypes, visualModeEnabled);
|
|
357
|
+
validateGroupExpression(filter, activeLimetype, limetypes, limetype, visualModeEnabled);
|
|
311
358
|
}
|
|
312
359
|
}
|
|
313
360
|
/**
|
|
314
|
-
* Validate Lime Query filter and collect errors
|
|
361
|
+
* Validate Lime Query filter and collect errors and visual mode limitations
|
|
315
362
|
* @param filter The filter expression or group to validate
|
|
316
363
|
* @param activeLimetype Optional active object limetype for placeholder validation
|
|
317
364
|
* @param limetypes Record of all available limetypes
|
|
365
|
+
* @param limetype The limetype being filtered
|
|
318
366
|
* @param visualModeEnabled Whether visual mode is enabled
|
|
319
|
-
* @returns
|
|
367
|
+
* @returns Object with validation errors and visual mode limitations
|
|
320
368
|
*/
|
|
321
|
-
function validateLimeQueryFilterInternal(filter, activeLimetype, limetypes, visualModeEnabled) {
|
|
369
|
+
function validateLimeQueryFilterInternal(filter, activeLimetype, limetypes, limetype, visualModeEnabled) {
|
|
322
370
|
const errors = [];
|
|
371
|
+
const limitations = [];
|
|
323
372
|
try {
|
|
324
|
-
validateFilterPlaceholders(filter, activeLimetype, limetypes, visualModeEnabled);
|
|
373
|
+
validateFilterPlaceholders(filter, activeLimetype, limetypes, limetype, visualModeEnabled);
|
|
325
374
|
}
|
|
326
375
|
catch (error) {
|
|
327
|
-
|
|
376
|
+
const errorMessage = error.message;
|
|
377
|
+
// Invalid keys are BOTH spec violations AND rendering limitations:
|
|
378
|
+
// - Backend will reject them (validation error)
|
|
379
|
+
// - Visual mode can't show them in property selector (visual limitation)
|
|
380
|
+
if (errorMessage.includes('Invalid filter key') ||
|
|
381
|
+
errorMessage.includes('Cannot filter on many-relation')) {
|
|
382
|
+
errors.push(`Invalid filter: ${errorMessage}`);
|
|
383
|
+
limitations.push(errorMessage);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
errors.push(`Invalid filter: ${errorMessage}`);
|
|
387
|
+
}
|
|
328
388
|
}
|
|
329
|
-
return errors;
|
|
389
|
+
return { errors, limitations };
|
|
330
390
|
}
|
|
331
391
|
/**
|
|
332
392
|
* Validate orderBy specification
|
|
@@ -495,8 +555,9 @@ export function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, visua
|
|
|
495
555
|
}
|
|
496
556
|
// Validate filter
|
|
497
557
|
if (limeQuery.filter) {
|
|
498
|
-
const
|
|
499
|
-
validationErrors.push(...
|
|
558
|
+
const { errors, limitations } = validateLimeQueryFilterInternal(limeQuery.filter, activeLimetype, limetypes, limeQuery.limetype, visualModeEnabled);
|
|
559
|
+
validationErrors.push(...errors);
|
|
560
|
+
visualModeLimitations.push(...limitations);
|
|
500
561
|
}
|
|
501
562
|
// Validate responseFormat
|
|
502
563
|
if (limeQuery.responseFormat) {
|
|
@@ -133,7 +133,7 @@ export class LimetypeField {
|
|
|
133
133
|
"name": "inheritdoc",
|
|
134
134
|
"text": undefined
|
|
135
135
|
}],
|
|
136
|
-
"text": "Reference to the platform"
|
|
136
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
137
137
|
},
|
|
138
138
|
"getter": false,
|
|
139
139
|
"setter": false
|
|
@@ -159,7 +159,7 @@ export class LimetypeField {
|
|
|
159
159
|
"name": "inheritdoc",
|
|
160
160
|
"text": undefined
|
|
161
161
|
}],
|
|
162
|
-
"text": "The context this component
|
|
162
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
163
163
|
},
|
|
164
164
|
"getter": false,
|
|
165
165
|
"setter": false
|
|
@@ -59,3 +59,49 @@ export function getPropertyFromPath(limetypes, limetype, path) {
|
|
|
59
59
|
}
|
|
60
60
|
return property;
|
|
61
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Validates a property path to ensure no intermediate properties are hasMany or hasAndBelongsToMany relations.
|
|
64
|
+
* These relation types cannot be traversed in filter expressions.
|
|
65
|
+
* @param limetypes All limetype definitions
|
|
66
|
+
* @param limetype The starting limetype
|
|
67
|
+
* @param path The property path to validate (e.g., "company.name")
|
|
68
|
+
* @returns The property at the end of the path if valid, or undefined with error if invalid
|
|
69
|
+
*/
|
|
70
|
+
export function validatePropertyPath(limetypes, limetype, path) {
|
|
71
|
+
if (!path || !limetype || !limetypes) {
|
|
72
|
+
return { property: undefined };
|
|
73
|
+
}
|
|
74
|
+
const parts = path.split('.');
|
|
75
|
+
let currentType = limetypes[limetype];
|
|
76
|
+
let property;
|
|
77
|
+
for (let i = 0; i < parts.length; i++) {
|
|
78
|
+
const part = parts[i];
|
|
79
|
+
if (!currentType) {
|
|
80
|
+
return { property: undefined };
|
|
81
|
+
}
|
|
82
|
+
const normalizedProperties = getNormalizedProperties(currentType);
|
|
83
|
+
property = normalizedProperties[part];
|
|
84
|
+
if (!property) {
|
|
85
|
+
return {
|
|
86
|
+
property: undefined,
|
|
87
|
+
error: `Property '${part}' does not exist on limetype '${currentType.name}'`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// Check if this property is a hasMany/hasAndBelongsToMany relation
|
|
91
|
+
// These cannot be traversed in filter expressions
|
|
92
|
+
if (property.type === 'hasmany' ||
|
|
93
|
+
property.type === 'hasandbelongstomany') {
|
|
94
|
+
// Build the path up to this point for the error message
|
|
95
|
+
const invalidPath = parts.slice(0, i + 1).join('.');
|
|
96
|
+
return {
|
|
97
|
+
property: undefined,
|
|
98
|
+
error: `Cannot filter on many-relation '${invalidPath}'. Use a related limetype's filter instead.`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// If this is a relation, get the related limetype for next iteration
|
|
102
|
+
if (property.relation) {
|
|
103
|
+
currentType = property.relation.getLimetype();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return { property };
|
|
107
|
+
}
|
|
@@ -161,7 +161,7 @@ export class FileViewer {
|
|
|
161
161
|
"optional": false,
|
|
162
162
|
"docs": {
|
|
163
163
|
"tags": [],
|
|
164
|
-
"text": "Reference to the platform"
|
|
164
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
165
165
|
},
|
|
166
166
|
"getter": false,
|
|
167
167
|
"setter": false
|
|
@@ -184,7 +184,7 @@ export class FileViewer {
|
|
|
184
184
|
"optional": false,
|
|
185
185
|
"docs": {
|
|
186
186
|
"tags": [],
|
|
187
|
-
"text": "The context this component
|
|
187
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
188
188
|
},
|
|
189
189
|
"getter": false,
|
|
190
190
|
"setter": false
|
|
@@ -39,7 +39,7 @@ export class CrmComponentsLoader {
|
|
|
39
39
|
"name": "inheritdoc",
|
|
40
40
|
"text": undefined
|
|
41
41
|
}],
|
|
42
|
-
"text": "Reference to the platform"
|
|
42
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
43
43
|
},
|
|
44
44
|
"getter": false,
|
|
45
45
|
"setter": false
|
|
@@ -65,7 +65,7 @@ export class CrmComponentsLoader {
|
|
|
65
65
|
"name": "inheritdoc",
|
|
66
66
|
"text": undefined
|
|
67
67
|
}],
|
|
68
|
-
"text": "The context this component
|
|
68
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
69
69
|
},
|
|
70
70
|
"getter": false,
|
|
71
71
|
"setter": false
|