@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,393 +0,0 @@
1
- /**
2
- * Metadata cache with promise memoization
3
- * Prevents duplicate API calls for the same entity
4
- */
5
-
6
- import type {
7
- EntityMetadata,
8
- AttributeMetadata,
9
- RelationshipMetadata,
10
- Publisher,
11
- Solution,
12
- PublisherWithSolutions,
13
- } from "../api/pptbClient";
14
-
15
- interface CachedEntityData {
16
- metadata?: EntityMetadata;
17
- attributes?: AttributeMetadata[];
18
- relationships?: {
19
- oneToMany: RelationshipMetadata[];
20
- manyToOne: RelationshipMetadata[];
21
- manyToMany: RelationshipMetadata[];
22
- };
23
- }
24
-
25
- interface CacheEntry<T> {
26
- data?: T;
27
- promise?: Promise<T>;
28
- timestamp: number;
29
- }
30
-
31
- class MetadataCache {
32
- private entities: Map<string, CacheEntry<CachedEntityData>> = new Map();
33
- private allEntitiesCache: CacheEntry<EntityMetadata[]> | null = null;
34
- private allEntityMetadataCache: CacheEntry<EntityMetadata[]> | null = null; // Global AF-valid entities
35
- private publishersCache: CacheEntry<Publisher[]> | null = null;
36
- private publishersWithSolutionsCache: CacheEntry<PublisherWithSolutions[]> | null = null;
37
- private solutionsCache: Map<string, CacheEntry<Solution[]>> = new Map(); // keyed by sorted publisher IDs
38
- private filteredEntitiesCache: Map<string, CacheEntry<EntityMetadata[]>> = new Map(); // keyed by sorted solution IDs
39
- private solutionComponentsCache: Map<string, CacheEntry<string[]>> = new Map(); // Entity names per solution ID
40
-
41
- // Cache TTL: 5 minutes
42
- private readonly TTL = 5 * 60 * 1000;
43
-
44
- /**
45
- * Check if cache entry is stale
46
- */
47
- private isStale(timestamp: number): boolean {
48
- return Date.now() - timestamp > this.TTL;
49
- }
50
-
51
- /**
52
- * Get or create entity cache entry
53
- */
54
- private getEntityEntry(logicalName: string): CacheEntry<CachedEntityData> {
55
- if (!this.entities.has(logicalName)) {
56
- this.entities.set(logicalName, {
57
- data: {},
58
- timestamp: Date.now(),
59
- });
60
- }
61
- return this.entities.get(logicalName)!;
62
- }
63
-
64
- /**
65
- * Get all entities from cache
66
- */
67
- getAllEntities(): EntityMetadata[] | undefined {
68
- if (!this.allEntitiesCache || this.isStale(this.allEntitiesCache.timestamp)) {
69
- return undefined;
70
- }
71
- return this.allEntitiesCache.data;
72
- }
73
-
74
- /**
75
- * Set all entities in cache
76
- */
77
- setAllEntities(entities: EntityMetadata[]): void {
78
- this.allEntitiesCache = {
79
- data: entities,
80
- timestamp: Date.now(),
81
- };
82
- }
83
-
84
- /**
85
- * Get in-flight promise for all entities
86
- */
87
- getAllEntitiesPromise(): Promise<EntityMetadata[]> | undefined {
88
- return this.allEntitiesCache?.promise;
89
- }
90
-
91
- /**
92
- * Set in-flight promise for all entities
93
- */
94
- setAllEntitiesPromise(promise: Promise<EntityMetadata[]>): void {
95
- if (!this.allEntitiesCache) {
96
- this.allEntitiesCache = { timestamp: Date.now() };
97
- }
98
- this.allEntitiesCache.promise = promise;
99
- }
100
-
101
- /**
102
- * Clear in-flight promise for all entities
103
- */
104
- clearAllEntitiesPromise(): void {
105
- if (this.allEntitiesCache) {
106
- this.allEntitiesCache.promise = undefined;
107
- }
108
- }
109
-
110
- /**
111
- * Get global entity metadata cache (all AF-valid entities)
112
- */
113
- getAllEntityMetadata(): EntityMetadata[] | undefined {
114
- if (!this.allEntityMetadataCache || this.isStale(this.allEntityMetadataCache.timestamp)) {
115
- return undefined;
116
- }
117
- return this.allEntityMetadataCache.data;
118
- }
119
-
120
- /**
121
- * Set global entity metadata cache
122
- */
123
- setAllEntityMetadata(entities: EntityMetadata[]): void {
124
- this.allEntityMetadataCache = {
125
- data: entities,
126
- timestamp: Date.now(),
127
- };
128
- console.log("[Cache] Global entity metadata cached:", entities.length, "entities");
129
- }
130
-
131
- /**
132
- * Get in-flight promise for global entity metadata
133
- */
134
- getAllEntityMetadataPromise(): Promise<EntityMetadata[]> | undefined {
135
- return this.allEntityMetadataCache?.promise;
136
- }
137
-
138
- /**
139
- * Set in-flight promise for global entity metadata
140
- */
141
- setAllEntityMetadataPromise(promise: Promise<EntityMetadata[]>): void {
142
- if (!this.allEntityMetadataCache) {
143
- this.allEntityMetadataCache = { timestamp: Date.now() };
144
- }
145
- this.allEntityMetadataCache.promise = promise;
146
- }
147
-
148
- /**
149
- * Clear in-flight promise for global entity metadata
150
- */
151
- clearAllEntityMetadataPromise(): void {
152
- if (this.allEntityMetadataCache) {
153
- this.allEntityMetadataCache.promise = undefined;
154
- }
155
- }
156
-
157
- /**
158
- * Get entity metadata from cache
159
- */
160
- getEntityMetadata(logicalName: string): EntityMetadata | undefined {
161
- const entry = this.entities.get(logicalName);
162
- if (!entry || this.isStale(entry.timestamp)) {
163
- return undefined;
164
- }
165
- return entry.data?.metadata;
166
- }
167
-
168
- /**
169
- * Set entity metadata in cache
170
- */
171
- setEntityMetadata(logicalName: string, metadata: EntityMetadata): void {
172
- const entry = this.getEntityEntry(logicalName);
173
- if (!entry.data) entry.data = {};
174
- entry.data.metadata = metadata;
175
- entry.timestamp = Date.now();
176
- }
177
-
178
- /**
179
- * Get entity attributes from cache
180
- */
181
- getEntityAttributes(logicalName: string): AttributeMetadata[] | undefined {
182
- const entry = this.entities.get(logicalName);
183
- if (!entry || this.isStale(entry.timestamp)) {
184
- return undefined;
185
- }
186
- return entry.data?.attributes;
187
- }
188
-
189
- /**
190
- * Set entity attributes in cache
191
- */
192
- setEntityAttributes(logicalName: string, attributes: AttributeMetadata[]): void {
193
- const entry = this.getEntityEntry(logicalName);
194
- if (!entry.data) entry.data = {};
195
- entry.data.attributes = attributes;
196
- entry.timestamp = Date.now();
197
- }
198
-
199
- /**
200
- * Get entity relationships from cache
201
- */
202
- getEntityRelationships(logicalName: string):
203
- | {
204
- oneToMany: RelationshipMetadata[];
205
- manyToOne: RelationshipMetadata[];
206
- manyToMany: RelationshipMetadata[];
207
- }
208
- | undefined {
209
- const entry = this.entities.get(logicalName);
210
- if (!entry || this.isStale(entry.timestamp)) {
211
- return undefined;
212
- }
213
- return entry.data?.relationships;
214
- }
215
-
216
- /**
217
- * Set entity relationships in cache
218
- */
219
- setEntityRelationships(
220
- logicalName: string,
221
- relationships: {
222
- oneToMany: RelationshipMetadata[];
223
- manyToOne: RelationshipMetadata[];
224
- manyToMany: RelationshipMetadata[];
225
- }
226
- ): void {
227
- const entry = this.getEntityEntry(logicalName);
228
- if (!entry.data) entry.data = {};
229
- entry.data.relationships = relationships;
230
- entry.timestamp = Date.now();
231
- }
232
-
233
- /**
234
- * Check if there's an in-flight request for entity attributes
235
- */
236
- getAttributesPromise(logicalName: string): Promise<AttributeMetadata[]> | undefined {
237
- const entry = this.entities.get(logicalName);
238
- return entry?.promise as Promise<AttributeMetadata[]> | undefined;
239
- }
240
-
241
- /**
242
- * Set in-flight promise for entity attributes
243
- */
244
- setAttributesPromise(logicalName: string, promise: Promise<AttributeMetadata[]>): void {
245
- const entry = this.getEntityEntry(logicalName);
246
- entry.promise = promise as Promise<CachedEntityData>;
247
- }
248
-
249
- /**
250
- * Clear in-flight promise for entity attributes
251
- */
252
- clearAttributesPromise(logicalName: string): void {
253
- const entry = this.entities.get(logicalName);
254
- if (entry) {
255
- entry.promise = undefined;
256
- }
257
- }
258
-
259
- /**
260
- * Clear all cache
261
- */
262
- clear(): void {
263
- this.entities.clear();
264
- this.allEntitiesCache = null;
265
- this.publishersCache = null;
266
- this.solutionsCache.clear();
267
- this.filteredEntitiesCache.clear();
268
- }
269
-
270
- /**
271
- * Clear cache for specific entity
272
- */
273
- clearEntity(logicalName: string): void {
274
- this.entities.delete(logicalName);
275
- }
276
-
277
- /**
278
- * Get publishers from cache
279
- */
280
- getPublishers(): Publisher[] | undefined {
281
- if (!this.publishersCache || this.isStale(this.publishersCache.timestamp)) {
282
- return undefined;
283
- }
284
- return this.publishersCache.data;
285
- }
286
-
287
- /**
288
- * Set publishers in cache
289
- */
290
- setPublishers(publishers: Publisher[]): void {
291
- this.publishersCache = {
292
- data: publishers,
293
- timestamp: Date.now(),
294
- };
295
- }
296
-
297
- /**
298
- * Get publishers with solutions from cache (combined response)
299
- */
300
- getPublishersWithSolutions(): PublisherWithSolutions[] | undefined {
301
- if (
302
- !this.publishersWithSolutionsCache ||
303
- this.isStale(this.publishersWithSolutionsCache.timestamp)
304
- ) {
305
- return undefined;
306
- }
307
- return this.publishersWithSolutionsCache.data;
308
- }
309
-
310
- /**
311
- * Set publishers with solutions in cache (combined response)
312
- */
313
- setPublishersWithSolutions(publishersWithSolutions: PublisherWithSolutions[]): void {
314
- this.publishersWithSolutionsCache = {
315
- data: publishersWithSolutions,
316
- timestamp: Date.now(),
317
- };
318
- }
319
-
320
- /**
321
- * Get solutions from cache by publisher IDs
322
- */
323
- getSolutions(publisherIds: string[]): Solution[] | undefined {
324
- const key = publisherIds.sort().join(",");
325
- const entry = this.solutionsCache.get(key);
326
- if (!entry || this.isStale(entry.timestamp)) {
327
- return undefined;
328
- }
329
- return entry.data;
330
- }
331
-
332
- /**
333
- * Set solutions in cache by publisher IDs
334
- */
335
- setSolutions(publisherIds: string[], solutions: Solution[]): void {
336
- const key = publisherIds.sort().join(",");
337
- this.solutionsCache.set(key, {
338
- data: solutions,
339
- timestamp: Date.now(),
340
- });
341
- }
342
-
343
- /**
344
- * Get filtered entities from cache by solution IDs
345
- */
346
- getFilteredEntities(solutionIds: string[]): EntityMetadata[] | undefined {
347
- const key = solutionIds.sort().join(",");
348
- const entry = this.filteredEntitiesCache.get(key);
349
- if (!entry || this.isStale(entry.timestamp)) {
350
- return undefined;
351
- }
352
- return entry.data;
353
- }
354
-
355
- /**
356
- * Set filtered entities in cache by solution IDs
357
- */
358
- setFilteredEntities(solutionIds: string[], entities: EntityMetadata[]): void {
359
- const key = solutionIds.sort().join(",");
360
- this.filteredEntitiesCache.set(key, {
361
- data: entities,
362
- timestamp: Date.now(),
363
- });
364
- }
365
-
366
- /**
367
- * Get solution components (entity names) from cache by solution ID
368
- */
369
- getSolutionComponents(solutionId: string): string[] | undefined {
370
- const entry = this.solutionComponentsCache.get(solutionId);
371
- if (!entry || this.isStale(entry.timestamp)) {
372
- return undefined;
373
- }
374
- return entry.data;
375
- }
376
-
377
- /**
378
- * Set solution components (entity names) in cache by solution ID
379
- */
380
- setSolutionComponents(solutionId: string, entityNames: string[]): void {
381
- this.solutionComponentsCache.set(solutionId, {
382
- data: entityNames,
383
- timestamp: Date.now(),
384
- });
385
- console.log("[Cache] Solution components cached:", {
386
- solutionId,
387
- entityCount: entityNames.length,
388
- });
389
- }
390
- }
391
-
392
- // Singleton instance
393
- export const metadataCache = new MetadataCache();