@mohsinonxrm/pptb-fetchxml-studio 1.0.0 → 1.0.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.
Files changed (78) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +1 -1
  3. package/dist/assets/index-DD9fzkbz.js +232 -0
  4. package/dist/index.html +70 -0
  5. package/index.html +0 -1
  6. package/npm-shrinkwrap.json +6329 -0
  7. package/package.json +95 -51
  8. package/CHANGELOG.md +0 -120
  9. package/eslint.config.js +0 -23
  10. package/public/vite.svg +0 -1
  11. package/src/app/AppShell.tsx +0 -1733
  12. package/src/assets/20px-Microsoft_Office_Excel_(2025/342/200/223present).svg.png +0 -0
  13. package/src/assets/react.svg +0 -1
  14. package/src/features/fetchxml/api/dataverseMetadata.ts +0 -192
  15. package/src/features/fetchxml/api/excelExport.ts +0 -318
  16. package/src/features/fetchxml/api/formattedValues.ts +0 -107
  17. package/src/features/fetchxml/api/pptbClient.ts +0 -2635
  18. package/src/features/fetchxml/model/displaySettings.ts +0 -18
  19. package/src/features/fetchxml/model/fetchxml.ts +0 -346
  20. package/src/features/fetchxml/model/fetchxmlIntellisense.ts +0 -583
  21. package/src/features/fetchxml/model/fetchxmlParser.ts +0 -708
  22. package/src/features/fetchxml/model/layoutxml.ts +0 -372
  23. package/src/features/fetchxml/model/nodes.ts +0 -255
  24. package/src/features/fetchxml/model/operators.ts +0 -624
  25. package/src/features/fetchxml/model/treeUtils.ts +0 -174
  26. package/src/features/fetchxml/state/builderStore.tsx +0 -1160
  27. package/src/features/fetchxml/state/cache.ts +0 -393
  28. package/src/features/fetchxml/ui/Dialogs/BulkDeleteDialog.tsx +0 -352
  29. package/src/features/fetchxml/ui/Dialogs/DeleteConfirmDialog.tsx +0 -396
  30. package/src/features/fetchxml/ui/Dialogs/SaveViewDialog.tsx +0 -612
  31. package/src/features/fetchxml/ui/Dialogs/SolutionPicker.tsx +0 -114
  32. package/src/features/fetchxml/ui/Dialogs/WorkflowPickerDialog.tsx +0 -437
  33. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/AttributeEditor.tsx +0 -214
  34. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/ConditionEditor.tsx +0 -533
  35. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/FetchOptionsEditor.tsx +0 -296
  36. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/FilterEditor.tsx +0 -106
  37. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/LinkEntityEditor.tsx +0 -433
  38. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/OrderEditor.tsx +0 -161
  39. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/ValueOfPicker.tsx +0 -194
  40. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel.tsx +0 -225
  41. package/src/features/fetchxml/ui/LeftPane/TreeView.tsx +0 -604
  42. package/src/features/fetchxml/ui/RightPane/AddColumnsPanel.tsx +0 -800
  43. package/src/features/fetchxml/ui/RightPane/ColumnConfigDialog.tsx +0 -170
  44. package/src/features/fetchxml/ui/RightPane/DataGridCellRenderers.tsx +0 -356
  45. package/src/features/fetchxml/ui/RightPane/EditColumnsPanel.tsx +0 -372
  46. package/src/features/fetchxml/ui/RightPane/FetchXmlEditor.tsx +0 -399
  47. package/src/features/fetchxml/ui/RightPane/FormattedValueUtils.ts +0 -189
  48. package/src/features/fetchxml/ui/RightPane/LayoutXmlViewer.tsx +0 -171
  49. package/src/features/fetchxml/ui/RightPane/PreviewTabs.tsx +0 -471
  50. package/src/features/fetchxml/ui/RightPane/ResultsCommandBar.tsx +0 -430
  51. package/src/features/fetchxml/ui/RightPane/ResultsGrid.tsx +0 -983
  52. package/src/features/fetchxml/ui/RightPane/XmlTextArea.tsx +0 -65
  53. package/src/features/fetchxml/ui/Settings/SettingsDrawer.tsx +0 -175
  54. package/src/features/fetchxml/ui/Toolbar/EntitySelector.tsx +0 -788
  55. package/src/features/fetchxml/ui/Toolbar/LoadViewPicker.tsx +0 -274
  56. package/src/features/fetchxml/ui/Toolbar/SaveViewButton.tsx +0 -174
  57. package/src/main.tsx +0 -11
  58. package/src/shared/components/AttributePicker.tsx +0 -138
  59. package/src/shared/components/BetweenInputPicker.tsx +0 -120
  60. package/src/shared/components/BooleanValuePicker.tsx +0 -165
  61. package/src/shared/components/DateTimeInputPicker.tsx +0 -170
  62. package/src/shared/components/DynamicValueList.tsx +0 -128
  63. package/src/shared/components/ExcelIcon.tsx +0 -30
  64. package/src/shared/components/MultiValuePicker.tsx +0 -178
  65. package/src/shared/components/NumericInputPicker.tsx +0 -156
  66. package/src/shared/components/OptionSetValuePicker.tsx +0 -150
  67. package/src/shared/components/RelationshipPicker.tsx +0 -268
  68. package/src/shared/contexts/ThemeContext.tsx +0 -19
  69. package/src/shared/hooks/useAccessMode.ts +0 -77
  70. package/src/shared/hooks/useLazyMetadata.ts +0 -132
  71. package/src/shared/hooks/usePptbContext.ts +0 -170
  72. package/src/shared/hooks/usePublisherFilter.ts +0 -214
  73. package/src/shared/hooks/useSolutionFilter.ts +0 -162
  74. package/src/shared/utils/debug.ts +0 -87
  75. package/tsconfig.app.json +0 -28
  76. package/tsconfig.json +0 -7
  77. package/tsconfig.node.json +0 -26
  78. package/vite.config.ts +0 -7
@@ -1,372 +0,0 @@
1
- /**
2
- * LayoutXML Parser and Generator
3
- * Handles Dataverse view layout configuration
4
- *
5
- * LayoutXML structure:
6
- * <grid name="resultset" object="1" jump="name" select="1" icon="1" preview="1">
7
- * <row name="result" id="accountid">
8
- * <cell name="name" width="300" />
9
- * <cell name="primarycontactid" width="150" />
10
- * <cell name="createdon" width="125" />
11
- * </row>
12
- * </grid>
13
- */
14
-
15
- import type { FetchNode, AttributeNode, LinkEntityNode } from "./nodes";
16
-
17
- /**
18
- * Column configuration for a single column in the grid
19
- */
20
- export interface LayoutColumn {
21
- /** Attribute logical name */
22
- name: string;
23
- /** Column width in pixels */
24
- width: number;
25
- /** Link-entity alias if this column is from a related entity */
26
- linkEntityAlias?: string;
27
- /** Whether sorting is disabled for this column */
28
- disableSorting?: boolean;
29
- /** Image provider for icon columns */
30
- imageProviderName?: string;
31
- /** Original display name from metadata (for UI) */
32
- displayName?: string;
33
- }
34
-
35
- /**
36
- * Full layout configuration for the grid
37
- */
38
- export interface LayoutXmlConfig {
39
- /** Grid name (usually "resultset") */
40
- gridName: string;
41
- /** Entity type code */
42
- objectTypeCode?: number;
43
- /** Attribute to navigate to on double-click */
44
- jumpAttribute?: string;
45
- /** Row selection enabled */
46
- enableSelection?: boolean;
47
- /** Show entity icon */
48
- showIcon?: boolean;
49
- /** Enable row preview */
50
- enablePreview?: boolean;
51
- /** Primary ID attribute for the row */
52
- primaryIdAttribute?: string;
53
- /** Column configurations in display order */
54
- columns: LayoutColumn[];
55
- }
56
-
57
- /**
58
- * Default column widths based on attribute type
59
- */
60
- const DEFAULT_WIDTHS: Record<string, number> = {
61
- // Text types - wider
62
- String: 200,
63
- Memo: 250,
64
-
65
- // Numeric types - narrower
66
- Integer: 100,
67
- BigInt: 120,
68
- Decimal: 120,
69
- Double: 120,
70
- Money: 130,
71
-
72
- // Date/Time
73
- DateTime: 150,
74
-
75
- // Lookups - medium
76
- Lookup: 180,
77
- Customer: 180,
78
- Owner: 180,
79
-
80
- // Option sets - medium
81
- Picklist: 150,
82
- State: 100,
83
- Status: 120,
84
- MultiSelectPicklist: 200,
85
-
86
- // Boolean - narrow
87
- Boolean: 80,
88
-
89
- // Unique identifier - wide (GUIDs)
90
- Uniqueidentifier: 280,
91
-
92
- // Image - narrow
93
- Image: 60,
94
-
95
- // File - medium
96
- File: 150,
97
-
98
- // Default fallback
99
- default: 150,
100
- };
101
-
102
- /**
103
- * Get default width for an attribute type
104
- */
105
- export function getDefaultWidthForType(attributeType?: string): number {
106
- if (!attributeType) return DEFAULT_WIDTHS.default;
107
- return DEFAULT_WIDTHS[attributeType] ?? DEFAULT_WIDTHS.default;
108
- }
109
-
110
- /**
111
- * Parse a LayoutXML string into a LayoutXmlConfig
112
- */
113
- export function parseLayoutXml(xml: string): LayoutXmlConfig {
114
- const parser = new DOMParser();
115
- const doc = parser.parseFromString(xml, "text/xml");
116
-
117
- // Check for parsing errors
118
- const parseError = doc.querySelector("parsererror");
119
- if (parseError) {
120
- throw new Error(`Invalid LayoutXML: ${parseError.textContent}`);
121
- }
122
-
123
- const gridElement = doc.querySelector("grid");
124
- if (!gridElement) {
125
- throw new Error("Invalid LayoutXML: missing <grid> element");
126
- }
127
-
128
- const rowElement = doc.querySelector("row");
129
- const cellElements = doc.querySelectorAll("cell");
130
-
131
- const columns: LayoutColumn[] = [];
132
- cellElements.forEach((cell) => {
133
- const name = cell.getAttribute("name");
134
- const width = cell.getAttribute("width");
135
- const disableSorting = cell.getAttribute("disableSorting");
136
- const imageProviderName = cell.getAttribute("imageproviderwebresource");
137
-
138
- if (name) {
139
- columns.push({
140
- name,
141
- width: width ? parseInt(width, 10) : DEFAULT_WIDTHS.default,
142
- disableSorting: disableSorting === "1",
143
- imageProviderName: imageProviderName || undefined,
144
- });
145
- }
146
- });
147
-
148
- return {
149
- gridName: gridElement.getAttribute("name") || "resultset",
150
- objectTypeCode: gridElement.getAttribute("object")
151
- ? parseInt(gridElement.getAttribute("object")!, 10)
152
- : undefined,
153
- jumpAttribute: gridElement.getAttribute("jump") || undefined,
154
- enableSelection: gridElement.getAttribute("select") === "1",
155
- showIcon: gridElement.getAttribute("icon") === "1",
156
- enablePreview: gridElement.getAttribute("preview") === "1",
157
- primaryIdAttribute: rowElement?.getAttribute("id") || undefined,
158
- columns,
159
- };
160
- }
161
-
162
- /**
163
- * Generate LayoutXML string from a LayoutXmlConfig
164
- */
165
- export function generateLayoutXml(config: LayoutXmlConfig): string {
166
- const cells = config.columns
167
- .map((col) => {
168
- const attrs: string[] = [`name="${col.name}"`, `width="${col.width}"`];
169
- if (col.disableSorting) {
170
- attrs.push('disableSorting="1"');
171
- }
172
- if (col.imageProviderName) {
173
- attrs.push(`imageproviderwebresource="${col.imageProviderName}"`);
174
- }
175
- return ` <cell ${attrs.join(" ")} />`;
176
- })
177
- .join("\n");
178
-
179
- const gridAttrs: string[] = [`name="${config.gridName}"`];
180
- if (config.objectTypeCode !== undefined) {
181
- gridAttrs.push(`object="${config.objectTypeCode}"`);
182
- }
183
- if (config.jumpAttribute) {
184
- gridAttrs.push(`jump="${config.jumpAttribute}"`);
185
- }
186
- gridAttrs.push(`select="${config.enableSelection ? "1" : "0"}"`);
187
- gridAttrs.push(`icon="${config.showIcon ? "1" : "0"}"`);
188
- gridAttrs.push(`preview="${config.enablePreview ? "1" : "0"}"`);
189
-
190
- const rowId = config.primaryIdAttribute || "id";
191
-
192
- return `<grid ${gridAttrs.join(" ")}>
193
- <row name="result" id="${rowId}">
194
- ${cells}
195
- </row>
196
- </grid>`;
197
- }
198
-
199
- /**
200
- * Collect all attributes from a FetchXML query into column configs
201
- * Traverses root entity and all link-entities recursively
202
- */
203
- export function collectAttributesFromFetchXml(
204
- fetchQuery: FetchNode,
205
- attributeTypeMap?: Map<string, string>
206
- ): LayoutColumn[] {
207
- const columns: LayoutColumn[] = [];
208
-
209
- // Helper to get the column key for an attribute
210
- const getColumnKey = (attr: AttributeNode, linkAlias?: string): string => {
211
- // If attribute has an alias, use it
212
- if (attr.alias) return attr.alias;
213
- // If from link-entity with alias, prefix with alias
214
- if (linkAlias) return `${linkAlias}.${attr.name}`;
215
- // Otherwise just the attribute name
216
- return attr.name;
217
- };
218
-
219
- // Collect from root entity
220
- if (fetchQuery.entity.attributes) {
221
- for (const attr of fetchQuery.entity.attributes) {
222
- const columnKey = getColumnKey(attr);
223
- const attrType = attributeTypeMap?.get(attr.name);
224
- columns.push({
225
- name: columnKey,
226
- width: getDefaultWidthForType(attrType),
227
- });
228
- }
229
- }
230
-
231
- // Recursive function to collect from link-entities
232
- const collectFromLinkEntity = (link: LinkEntityNode) => {
233
- // Determine the alias for this link-entity
234
- const linkAlias = link.alias || link.name;
235
-
236
- // Collect attributes
237
- if (link.attributes) {
238
- for (const attr of link.attributes) {
239
- const columnKey = getColumnKey(attr, linkAlias);
240
- const attrType = attributeTypeMap?.get(`${link.name}.${attr.name}`);
241
- columns.push({
242
- name: columnKey,
243
- width: getDefaultWidthForType(attrType),
244
- linkEntityAlias: linkAlias,
245
- });
246
- }
247
- }
248
-
249
- // Recurse into nested link-entities
250
- if (link.links) {
251
- for (const nestedLink of link.links) {
252
- collectFromLinkEntity(nestedLink);
253
- }
254
- }
255
- };
256
-
257
- // Collect from all link-entities
258
- if (fetchQuery.entity.links) {
259
- for (const link of fetchQuery.entity.links) {
260
- collectFromLinkEntity(link);
261
- }
262
- }
263
-
264
- return columns;
265
- }
266
-
267
- /**
268
- * Generate a LayoutXmlConfig from a FetchXML query
269
- * Used when no layoutxml exists (custom FetchXML)
270
- */
271
- export function generateLayoutFromFetchXml(
272
- fetchQuery: FetchNode,
273
- attributeTypeMap?: Map<string, string>
274
- ): LayoutXmlConfig {
275
- const entityName = fetchQuery.entity.name;
276
- const columns = collectAttributesFromFetchXml(fetchQuery, attributeTypeMap);
277
-
278
- return {
279
- gridName: "resultset",
280
- jumpAttribute: columns.length > 0 ? columns[0].name : undefined,
281
- enableSelection: true,
282
- showIcon: true,
283
- enablePreview: true,
284
- primaryIdAttribute: `${entityName}id`,
285
- columns,
286
- };
287
- }
288
-
289
- /**
290
- * Merge existing layout with FetchXML changes
291
- * - Keeps existing column widths/order for columns that still exist
292
- * - Adds new columns from FetchXML at the end
293
- * - Removes columns no longer in FetchXML
294
- */
295
- export function mergeLayoutWithFetchXml(
296
- existingConfig: LayoutXmlConfig,
297
- fetchQuery: FetchNode,
298
- attributeTypeMap?: Map<string, string>
299
- ): LayoutXmlConfig {
300
- const fetchColumns = collectAttributesFromFetchXml(fetchQuery, attributeTypeMap);
301
- const fetchColumnNames = new Set(fetchColumns.map((c) => c.name));
302
- const existingColumnNames = new Set(existingConfig.columns.map((c) => c.name));
303
-
304
- // Keep existing columns that are still in FetchXML (preserves order and width)
305
- const mergedColumns: LayoutColumn[] = existingConfig.columns.filter((col) =>
306
- fetchColumnNames.has(col.name)
307
- );
308
-
309
- // Add new columns from FetchXML that weren't in existing layout
310
- for (const col of fetchColumns) {
311
- if (!existingColumnNames.has(col.name)) {
312
- mergedColumns.push(col);
313
- }
314
- }
315
-
316
- return {
317
- ...existingConfig,
318
- columns: mergedColumns,
319
- };
320
- }
321
-
322
- /**
323
- * Check if a LayoutXmlConfig matches the FetchXML attributes
324
- * Returns true if all FetchXML attributes are represented in the layout
325
- */
326
- export function isLayoutValidForFetchXml(config: LayoutXmlConfig, fetchQuery: FetchNode): boolean {
327
- const fetchColumns = collectAttributesFromFetchXml(fetchQuery);
328
- const layoutColumnNames = new Set(config.columns.map((c) => c.name));
329
-
330
- // Check if all FetchXML attributes are in the layout
331
- for (const col of fetchColumns) {
332
- if (!layoutColumnNames.has(col.name)) {
333
- return false;
334
- }
335
- }
336
-
337
- return true;
338
- }
339
-
340
- /**
341
- * Update a single column's width in the config
342
- */
343
- export function updateColumnWidth(
344
- config: LayoutXmlConfig,
345
- columnName: string,
346
- newWidth: number
347
- ): LayoutXmlConfig {
348
- return {
349
- ...config,
350
- columns: config.columns.map((col) =>
351
- col.name === columnName ? { ...col, width: newWidth } : col
352
- ),
353
- };
354
- }
355
-
356
- /**
357
- * Reorder columns in the config
358
- */
359
- export function reorderColumns(
360
- config: LayoutXmlConfig,
361
- fromIndex: number,
362
- toIndex: number
363
- ): LayoutXmlConfig {
364
- const columns = [...config.columns];
365
- const [removed] = columns.splice(fromIndex, 1);
366
- columns.splice(toIndex, 0, removed);
367
-
368
- return {
369
- ...config,
370
- columns,
371
- };
372
- }
@@ -1,255 +0,0 @@
1
- /**
2
- * TypeScript type definitions for FetchXML Studio tree nodes
3
- * Based on FetchXML XSD schema with all supported attributes
4
- */
5
-
6
- export type NodeId = string;
7
-
8
- /**
9
- * Root fetch node - top level query configuration
10
- */
11
- export interface FetchNode {
12
- id: NodeId;
13
- type: "fetch";
14
- entity: EntityNode;
15
- options: {
16
- aggregate?: boolean;
17
- distinct?: boolean;
18
- top?: number;
19
- count?: number;
20
- page?: number;
21
- pagingCookie?: string;
22
- returnTotalRecordCount?: boolean;
23
- noLock?: boolean;
24
- utcOffset?: number;
25
- latematerialize?: boolean;
26
- // Query optimization hints
27
- hints?: {
28
- forceOrder?: boolean;
29
- disableRowGoal?: boolean;
30
- enableOptimizerHotfixes?: boolean;
31
- loopJoin?: boolean;
32
- mergeJoin?: boolean;
33
- hashJoin?: boolean;
34
- noPerformanceSpool?: boolean;
35
- enableHistAmendmentForAscKeys?: boolean;
36
- };
37
- };
38
- }
39
-
40
- /**
41
- * Entity node - the root or linked table being queried
42
- */
43
- export interface EntityNode {
44
- id: NodeId;
45
- type: "entity";
46
- name: string; // logical name (e.g., 'account', 'contact')
47
- enablePrefiltering?: boolean;
48
- prefilterParameterName?: string;
49
- allAttributes?: AllAttributesNode;
50
- attributes: AttributeNode[];
51
- orders: OrderNode[];
52
- filters: FilterNode[];
53
- links: LinkEntityNode[];
54
- }
55
-
56
- /**
57
- * All-Attributes node - select all columns from entity
58
- */
59
- export interface AllAttributesNode {
60
- id: NodeId;
61
- type: "all-attributes";
62
- enabled: boolean; // toggle to include/exclude all attributes
63
- }
64
-
65
- /**
66
- * Attribute node - individual column selection
67
- */
68
- export interface AttributeNode {
69
- id: NodeId;
70
- type: "attribute";
71
- name: string; // logical attribute name
72
- alias?: string;
73
- groupby?: boolean;
74
- aggregate?: "sum" | "count" | "countcolumn" | "min" | "max" | "avg" | "rowaggregate";
75
- usertimezone?: boolean;
76
- dategrouping?: "day" | "week" | "month" | "quarter" | "year" | "fiscal-period" | "fiscal-year";
77
- }
78
-
79
- /**
80
- * Order node - sorting specification
81
- */
82
- export interface OrderNode {
83
- id: NodeId;
84
- type: "order";
85
- attribute: string; // logical attribute name
86
- descending?: boolean;
87
- entityname?: string; // for link-entity attributes, references the link alias
88
- }
89
-
90
- /**
91
- * Filter node - logical grouping of conditions
92
- */
93
- export interface FilterNode {
94
- id: NodeId;
95
- type: "filter";
96
- conjunction: "and" | "or"; // filter type
97
- hint?: "union"; // optimization hint for multi-table filters
98
- conditions: ConditionNode[];
99
- subfilters: FilterNode[]; // nested filters
100
- links: LinkEntityNode[]; // link-entities inside filter (for any/not any/all/not all)
101
- }
102
-
103
- /**
104
- * Condition node - individual filter criteria
105
- */
106
- export interface ConditionNode {
107
- id: NodeId;
108
- type: "condition";
109
- attribute: string; // logical attribute name
110
- operator: OperatorType;
111
- value?: string | number | boolean | (string | number)[] | null; // arrays for in/not-in operators
112
- aggregate?: "sum" | "count" | "countcolumn" | "min" | "max" | "avg"; // for aggregate filtering
113
- entityname?: string; // for link-entity filters, references the entity/link alias
114
- valueof?: string; // for cross-table column comparisons (references another attribute)
115
- }
116
-
117
- /**
118
- * Link-Entity node - join to related table
119
- */
120
- export interface LinkEntityNode {
121
- id: NodeId;
122
- type: "link-entity";
123
- name: string; // related entity logical name
124
- from: string; // attribute on related entity
125
- to: string; // attribute on current entity
126
- linkType: LinkType;
127
- alias?: string;
128
- intersect?: boolean; // for N:N relationships
129
- visible?: boolean; // include in query results
130
- relationshipType?: "1N" | "N1" | "NN"; // metadata hint for UI
131
- allAttributes?: AllAttributesNode;
132
- attributes: AttributeNode[];
133
- orders: OrderNode[];
134
- filters: FilterNode[];
135
- links: LinkEntityNode[]; // nested link-entities (max 15 total depth)
136
- }
137
-
138
- /**
139
- * Link types supported by FetchXML
140
- */
141
- export type LinkType =
142
- | "inner" // Inner join (default)
143
- | "outer" // Left outer join
144
- | "any" // Exists with ANY match in related
145
- | "not any" // NOT EXISTS with any match
146
- | "all" // ALL records match
147
- | "not all" // NOT ALL records match
148
- | "exists" // EXISTS (semi-join)
149
- | "in" // IN (similar to exists)
150
- | "matchfirstrowusingcrossapply"; // CROSS APPLY for first match
151
-
152
- /**
153
- * FetchXML operators (60+ supported)
154
- * Applicability depends on attribute type
155
- */
156
- export type OperatorType =
157
- // Comparison operators (all types)
158
- | "eq"
159
- | "ne"
160
- | "gt"
161
- | "ge"
162
- | "lt"
163
- | "le"
164
- // Null checks (all types)
165
- | "null"
166
- | "not-null"
167
- // String operators
168
- | "like"
169
- | "not-like"
170
- | "begins-with"
171
- | "not-begin-with"
172
- | "ends-with"
173
- | "not-end-with"
174
- // Collection operators
175
- | "in"
176
- | "not-in"
177
- | "between"
178
- | "not-between"
179
- | "contain-values"
180
- | "not-contain-values" // for multi-select picklist
181
- // Date relative operators
182
- | "yesterday"
183
- | "today"
184
- | "tomorrow"
185
- | "last-seven-days"
186
- | "last-week"
187
- | "this-week"
188
- | "next-week"
189
- | "next-seven-days"
190
- | "last-month"
191
- | "this-month"
192
- | "next-month"
193
- | "last-year"
194
- | "this-year"
195
- | "next-year"
196
- | "on"
197
- | "on-or-before"
198
- | "on-or-after"
199
- // Date range operators (require integer value for 'x')
200
- | "last-x-hours"
201
- | "next-x-hours"
202
- | "last-x-days"
203
- | "next-x-days"
204
- | "last-x-weeks"
205
- | "next-x-weeks"
206
- | "last-x-months"
207
- | "next-x-months"
208
- | "last-x-years"
209
- | "next-x-years"
210
- | "olderthan-x-minutes"
211
- | "olderthan-x-hours"
212
- | "olderthan-x-days"
213
- | "olderthan-x-weeks"
214
- | "olderthan-x-months"
215
- | "olderthan-x-years"
216
- // Fiscal period operators
217
- | "this-fiscal-year"
218
- | "this-fiscal-period"
219
- | "next-fiscal-year"
220
- | "next-fiscal-period"
221
- | "last-fiscal-year"
222
- | "last-fiscal-period"
223
- | "last-x-fiscal-years"
224
- | "last-x-fiscal-periods"
225
- | "next-x-fiscal-years"
226
- | "next-x-fiscal-periods"
227
- | "in-fiscal-year"
228
- | "in-fiscal-period"
229
- | "in-fiscal-period-and-year"
230
- | "in-or-before-fiscal-period-and-year"
231
- | "in-or-after-fiscal-period-and-year"
232
- // User/Business unit operators (for Lookup to systemuser/businessunit)
233
- | "eq-userid"
234
- | "ne-userid"
235
- | "eq-userteams"
236
- | "eq-useroruserteams"
237
- | "eq-useroruserhierarchy"
238
- | "eq-useroruserhierarchyandteams"
239
- | "eq-businessid"
240
- | "ne-businessid"
241
- | "eq-userlanguage"
242
- // Hierarchy operators (for hierarchical lookups)
243
- | "under"
244
- | "eq-or-under"
245
- | "not-under"
246
- | "above"
247
- | "eq-or-above";
248
-
249
- /**
250
- * Value node - for operators that accept multiple values (e.g., 'in')
251
- * Not a tree node, but used in FetchXML generation
252
- */
253
- export interface ValueNode {
254
- value: string | number | boolean;
255
- }