@mohsinonxrm/pptb-fetchxml-studio 1.0.0 → 1.0.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.
Files changed (77) hide show
  1. package/LICENSE +661 -0
  2. package/dist/assets/index-DD9fzkbz.js +232 -0
  3. package/dist/index.html +70 -0
  4. package/index.html +0 -1
  5. package/npm-shrinkwrap.json +6329 -0
  6. package/package.json +95 -51
  7. package/CHANGELOG.md +0 -120
  8. package/eslint.config.js +0 -23
  9. package/public/vite.svg +0 -1
  10. package/src/app/AppShell.tsx +0 -1733
  11. package/src/assets/20px-Microsoft_Office_Excel_(2025/342/200/223present).svg.png +0 -0
  12. package/src/assets/react.svg +0 -1
  13. package/src/features/fetchxml/api/dataverseMetadata.ts +0 -192
  14. package/src/features/fetchxml/api/excelExport.ts +0 -318
  15. package/src/features/fetchxml/api/formattedValues.ts +0 -107
  16. package/src/features/fetchxml/api/pptbClient.ts +0 -2635
  17. package/src/features/fetchxml/model/displaySettings.ts +0 -18
  18. package/src/features/fetchxml/model/fetchxml.ts +0 -346
  19. package/src/features/fetchxml/model/fetchxmlIntellisense.ts +0 -583
  20. package/src/features/fetchxml/model/fetchxmlParser.ts +0 -708
  21. package/src/features/fetchxml/model/layoutxml.ts +0 -372
  22. package/src/features/fetchxml/model/nodes.ts +0 -255
  23. package/src/features/fetchxml/model/operators.ts +0 -624
  24. package/src/features/fetchxml/model/treeUtils.ts +0 -174
  25. package/src/features/fetchxml/state/builderStore.tsx +0 -1160
  26. package/src/features/fetchxml/state/cache.ts +0 -393
  27. package/src/features/fetchxml/ui/Dialogs/BulkDeleteDialog.tsx +0 -352
  28. package/src/features/fetchxml/ui/Dialogs/DeleteConfirmDialog.tsx +0 -396
  29. package/src/features/fetchxml/ui/Dialogs/SaveViewDialog.tsx +0 -612
  30. package/src/features/fetchxml/ui/Dialogs/SolutionPicker.tsx +0 -114
  31. package/src/features/fetchxml/ui/Dialogs/WorkflowPickerDialog.tsx +0 -437
  32. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/AttributeEditor.tsx +0 -214
  33. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/ConditionEditor.tsx +0 -533
  34. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/FetchOptionsEditor.tsx +0 -296
  35. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/FilterEditor.tsx +0 -106
  36. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/LinkEntityEditor.tsx +0 -433
  37. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/OrderEditor.tsx +0 -161
  38. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/ValueOfPicker.tsx +0 -194
  39. package/src/features/fetchxml/ui/LeftPane/PropertiesPanel.tsx +0 -225
  40. package/src/features/fetchxml/ui/LeftPane/TreeView.tsx +0 -604
  41. package/src/features/fetchxml/ui/RightPane/AddColumnsPanel.tsx +0 -800
  42. package/src/features/fetchxml/ui/RightPane/ColumnConfigDialog.tsx +0 -170
  43. package/src/features/fetchxml/ui/RightPane/DataGridCellRenderers.tsx +0 -356
  44. package/src/features/fetchxml/ui/RightPane/EditColumnsPanel.tsx +0 -372
  45. package/src/features/fetchxml/ui/RightPane/FetchXmlEditor.tsx +0 -399
  46. package/src/features/fetchxml/ui/RightPane/FormattedValueUtils.ts +0 -189
  47. package/src/features/fetchxml/ui/RightPane/LayoutXmlViewer.tsx +0 -171
  48. package/src/features/fetchxml/ui/RightPane/PreviewTabs.tsx +0 -471
  49. package/src/features/fetchxml/ui/RightPane/ResultsCommandBar.tsx +0 -430
  50. package/src/features/fetchxml/ui/RightPane/ResultsGrid.tsx +0 -983
  51. package/src/features/fetchxml/ui/RightPane/XmlTextArea.tsx +0 -65
  52. package/src/features/fetchxml/ui/Settings/SettingsDrawer.tsx +0 -175
  53. package/src/features/fetchxml/ui/Toolbar/EntitySelector.tsx +0 -788
  54. package/src/features/fetchxml/ui/Toolbar/LoadViewPicker.tsx +0 -274
  55. package/src/features/fetchxml/ui/Toolbar/SaveViewButton.tsx +0 -174
  56. package/src/main.tsx +0 -11
  57. package/src/shared/components/AttributePicker.tsx +0 -138
  58. package/src/shared/components/BetweenInputPicker.tsx +0 -120
  59. package/src/shared/components/BooleanValuePicker.tsx +0 -165
  60. package/src/shared/components/DateTimeInputPicker.tsx +0 -170
  61. package/src/shared/components/DynamicValueList.tsx +0 -128
  62. package/src/shared/components/ExcelIcon.tsx +0 -30
  63. package/src/shared/components/MultiValuePicker.tsx +0 -178
  64. package/src/shared/components/NumericInputPicker.tsx +0 -156
  65. package/src/shared/components/OptionSetValuePicker.tsx +0 -150
  66. package/src/shared/components/RelationshipPicker.tsx +0 -268
  67. package/src/shared/contexts/ThemeContext.tsx +0 -19
  68. package/src/shared/hooks/useAccessMode.ts +0 -77
  69. package/src/shared/hooks/useLazyMetadata.ts +0 -132
  70. package/src/shared/hooks/usePptbContext.ts +0 -170
  71. package/src/shared/hooks/usePublisherFilter.ts +0 -214
  72. package/src/shared/hooks/useSolutionFilter.ts +0 -162
  73. package/src/shared/utils/debug.ts +0 -87
  74. package/tsconfig.app.json +0 -28
  75. package/tsconfig.json +0 -7
  76. package/tsconfig.node.json +0 -26
  77. package/vite.config.ts +0 -7
@@ -1,396 +0,0 @@
1
- /**
2
- * Delete Confirmation Dialog
3
- * Shows confirmation before deleting records
4
- * Supports batch delete with progress tracking and ETA
5
- */
6
-
7
- import { useCallback, useState, useEffect } from "react";
8
- import {
9
- Dialog,
10
- DialogSurface,
11
- DialogTitle,
12
- DialogBody,
13
- DialogContent,
14
- DialogActions,
15
- Button,
16
- Text,
17
- Spinner,
18
- makeStyles,
19
- tokens,
20
- ProgressBar,
21
- MessageBar,
22
- MessageBarBody,
23
- MessageBarTitle,
24
- } from "@fluentui/react-components";
25
- import {
26
- Warning20Regular,
27
- CheckmarkCircle20Regular,
28
- DismissCircle20Regular,
29
- } from "@fluentui/react-icons";
30
- import type { BatchDeleteProgress, BatchDeleteResult } from "../../api/pptbClient";
31
-
32
- const useStyles = makeStyles({
33
- content: {
34
- display: "flex",
35
- flexDirection: "column",
36
- gap: tokens.spacingVerticalM,
37
- },
38
- warningRow: {
39
- display: "flex",
40
- alignItems: "center",
41
- gap: tokens.spacingHorizontalS,
42
- color: tokens.colorPaletteRedForeground1,
43
- },
44
- successRow: {
45
- display: "flex",
46
- alignItems: "center",
47
- gap: tokens.spacingHorizontalS,
48
- color: tokens.colorPaletteGreenForeground1,
49
- },
50
- recordInfo: {
51
- backgroundColor: tokens.colorNeutralBackground3,
52
- padding: tokens.spacingVerticalS,
53
- borderRadius: tokens.borderRadiusMedium,
54
- },
55
- errorMessage: {
56
- color: tokens.colorPaletteRedForeground1,
57
- marginTop: tokens.spacingVerticalS,
58
- },
59
- progressSection: {
60
- display: "flex",
61
- flexDirection: "column",
62
- gap: tokens.spacingVerticalS,
63
- },
64
- progressStats: {
65
- display: "flex",
66
- justifyContent: "space-between",
67
- alignItems: "center",
68
- marginTop: tokens.spacingVerticalXS,
69
- },
70
- eta: {
71
- color: tokens.colorNeutralForeground3,
72
- fontSize: tokens.fontSizeBase200,
73
- },
74
- resultSummary: {
75
- display: "flex",
76
- flexDirection: "column",
77
- gap: tokens.spacingVerticalXS,
78
- },
79
- });
80
-
81
- export interface DeleteConfirmDialogProps {
82
- /** Whether the dialog is open */
83
- open: boolean;
84
- /** Record display name or description */
85
- recordName?: string;
86
- /** Entity display name */
87
- entityDisplayName?: string;
88
- /** Number of records to delete (for multi-select) */
89
- recordCount: number;
90
- /** Called when dialog is closed */
91
- onClose: () => void;
92
- /** Called when delete is confirmed - returns batch result for batch deletes */
93
- onConfirm: () => Promise<BatchDeleteResult | void>;
94
- /** Progress callback for batch deletes */
95
- onProgress?: BatchDeleteProgress;
96
- }
97
-
98
- type DialogState = "confirm" | "deleting" | "success" | "partial" | "error";
99
-
100
- export function DeleteConfirmDialog({
101
- open,
102
- recordName,
103
- entityDisplayName,
104
- recordCount,
105
- onClose,
106
- onConfirm,
107
- onProgress,
108
- }: DeleteConfirmDialogProps) {
109
- const styles = useStyles();
110
- const [state, setState] = useState<DialogState>("confirm");
111
- const [error, setError] = useState<string | null>(null);
112
- const [result, setResult] = useState<BatchDeleteResult | null>(null);
113
- const [progress, setProgress] = useState<BatchDeleteProgress | null>(null);
114
-
115
- // Update progress from prop
116
- useEffect(() => {
117
- if (onProgress) {
118
- setProgress(onProgress);
119
- }
120
- }, [onProgress]);
121
-
122
- const handleConfirm = useCallback(async () => {
123
- setState("deleting");
124
- setError(null);
125
- setProgress(null);
126
- setResult(null);
127
- try {
128
- const res = await onConfirm();
129
- if (res) {
130
- // Batch delete result
131
- setResult(res);
132
- if (res.failed === 0) {
133
- setState("success");
134
- } else if (res.succeeded === 0) {
135
- setState("error");
136
- setError(`All ${res.failed} delete(s) failed`);
137
- } else {
138
- setState("partial");
139
- }
140
- } else {
141
- // Simple delete (void return)
142
- setState("success");
143
- }
144
- } catch (err) {
145
- setError(err instanceof Error ? err.message : "Failed to delete record(s)");
146
- setState("error");
147
- }
148
- }, [onConfirm]);
149
-
150
- const handleClose = useCallback(() => {
151
- if (state !== "deleting") {
152
- setState("confirm");
153
- setError(null);
154
- setResult(null);
155
- setProgress(null);
156
- onClose();
157
- }
158
- }, [state, onClose]);
159
-
160
- /**
161
- * Intelligently format ETA based on duration:
162
- * - < 1 minute: show seconds
163
- * - < 1 hour: show minutes and seconds
164
- * - < 12 hours: show hours and minutes
165
- * - >= 12 hours: show estimated completion date/time
166
- */
167
- const formatEta = (seconds: number): string => {
168
- if (seconds < 60) {
169
- return `~${seconds}s remaining`;
170
- }
171
-
172
- const minutes = Math.floor(seconds / 60);
173
- const hours = Math.floor(minutes / 60);
174
-
175
- if (minutes < 60) {
176
- const secs = seconds % 60;
177
- return `~${minutes}m ${secs}s remaining`;
178
- }
179
-
180
- if (hours < 12) {
181
- const mins = minutes % 60;
182
- return `~${hours}h ${mins}m remaining`;
183
- }
184
-
185
- // >= 12 hours: show estimated completion date/time
186
- const completionDate = new Date(Date.now() + seconds * 1000);
187
- const isToday = completionDate.toDateString() === new Date().toDateString();
188
- const isTomorrow =
189
- completionDate.toDateString() === new Date(Date.now() + 86400000).toDateString();
190
-
191
- const timeStr = completionDate.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
192
-
193
- if (isToday) {
194
- return `Est. completion: today at ${timeStr}`;
195
- } else if (isTomorrow) {
196
- return `Est. completion: tomorrow at ${timeStr}`;
197
- } else {
198
- const dateStr = completionDate.toLocaleDateString([], { month: "short", day: "numeric" });
199
- return `Est. completion: ${dateStr} at ${timeStr}`;
200
- }
201
- };
202
-
203
- const isSingle = recordCount === 1;
204
- const title = isSingle ? "Delete Record" : `Delete ${recordCount} Records`;
205
- const message = isSingle
206
- ? `Are you sure you want to delete this ${entityDisplayName || "record"}?`
207
- : `Are you sure you want to delete ${recordCount} ${entityDisplayName || "records"}?`;
208
-
209
- const renderContent = () => {
210
- switch (state) {
211
- case "confirm":
212
- return (
213
- <>
214
- <div className={styles.warningRow}>
215
- <Warning20Regular />
216
- <Text weight="semibold">This action cannot be undone.</Text>
217
- </div>
218
-
219
- <Text>{message}</Text>
220
-
221
- {isSingle && recordName && (
222
- <div className={styles.recordInfo}>
223
- <Text weight="semibold">{recordName}</Text>
224
- </div>
225
- )}
226
- </>
227
- );
228
-
229
- case "deleting":
230
- return (
231
- <div className={styles.progressSection}>
232
- <MessageBar intent="info">
233
- <MessageBarBody>
234
- <MessageBarTitle>Deleting records...</MessageBarTitle>
235
- {progress && (
236
- <>
237
- Processing batch {progress.batchesCompleted} of {progress.totalBatches}
238
- </>
239
- )}
240
- </MessageBarBody>
241
- </MessageBar>
242
-
243
- {progress && (
244
- <>
245
- <ProgressBar value={progress.completed / progress.total} max={1} />
246
- <div className={styles.progressStats}>
247
- <Text size={200}>
248
- {progress.completed} of {progress.total} ({progress.succeeded} succeeded,{" "}
249
- {progress.failed} failed)
250
- </Text>
251
- {progress.estimatedSecondsRemaining !== undefined &&
252
- progress.estimatedSecondsRemaining > 0 && (
253
- <Text className={styles.eta}>
254
- {formatEta(progress.estimatedSecondsRemaining)}
255
- </Text>
256
- )}
257
- </div>
258
- </>
259
- )}
260
-
261
- {!progress && (
262
- <div
263
- style={{ display: "flex", alignItems: "center", gap: tokens.spacingHorizontalS }}
264
- >
265
- <Spinner size="small" />
266
- <Text>Deleting...</Text>
267
- </div>
268
- )}
269
- </div>
270
- );
271
-
272
- case "success":
273
- return (
274
- <>
275
- <div className={styles.successRow}>
276
- <CheckmarkCircle20Regular />
277
- <Text weight="semibold">
278
- {result
279
- ? `Successfully deleted ${result.succeeded} record(s)!`
280
- : "Record(s) deleted successfully!"}
281
- </Text>
282
- </div>
283
- </>
284
- );
285
-
286
- case "partial":
287
- return (
288
- <>
289
- <MessageBar intent="warning">
290
- <MessageBarBody>
291
- <MessageBarTitle>Partial Success</MessageBarTitle>
292
- {result && (
293
- <>
294
- {result.succeeded} of {result.succeeded + result.failed} records deleted.
295
- {result.failed} failed.
296
- </>
297
- )}
298
- </MessageBarBody>
299
- </MessageBar>
300
-
301
- {result && result.errors.length > 0 && (
302
- <div className={styles.resultSummary}>
303
- <Text weight="semibold" size={200}>
304
- Errors:
305
- </Text>
306
- {result.errors.slice(0, 5).map((err, i) => (
307
- <Text key={i} size={200} className={styles.errorMessage}>
308
- {err}
309
- </Text>
310
- ))}
311
- {result.errors.length > 5 && (
312
- <Text size={200} className={styles.errorMessage}>
313
- ...and {result.errors.length - 5} more errors
314
- </Text>
315
- )}
316
- </div>
317
- )}
318
- </>
319
- );
320
-
321
- case "error":
322
- return (
323
- <>
324
- <div className={styles.warningRow}>
325
- <DismissCircle20Regular />
326
- <Text weight="semibold">Delete Failed</Text>
327
- </div>
328
-
329
- <Text className={styles.errorMessage}>{error}</Text>
330
-
331
- {result && result.errors.length > 0 && (
332
- <div className={styles.resultSummary}>
333
- <Text weight="semibold" size={200}>
334
- Errors:
335
- </Text>
336
- {result.errors.slice(0, 5).map((err, i) => (
337
- <Text key={i} size={200} className={styles.errorMessage}>
338
- {err}
339
- </Text>
340
- ))}
341
- {result.errors.length > 5 && (
342
- <Text size={200} className={styles.errorMessage}>
343
- ...and {result.errors.length - 5} more errors
344
- </Text>
345
- )}
346
- </div>
347
- )}
348
- </>
349
- );
350
- }
351
- };
352
-
353
- const renderActions = () => {
354
- switch (state) {
355
- case "confirm":
356
- return (
357
- <>
358
- <Button appearance="secondary" onClick={handleClose}>
359
- Cancel
360
- </Button>
361
- <Button appearance="primary" onClick={handleConfirm}>
362
- Delete
363
- </Button>
364
- </>
365
- );
366
-
367
- case "deleting":
368
- return (
369
- <Button appearance="secondary" disabled>
370
- Cancel
371
- </Button>
372
- );
373
-
374
- case "success":
375
- case "partial":
376
- case "error":
377
- return (
378
- <Button appearance="primary" onClick={handleClose}>
379
- Close
380
- </Button>
381
- );
382
- }
383
- };
384
-
385
- return (
386
- <Dialog open={open} onOpenChange={(_, data) => !data.open && handleClose()}>
387
- <DialogSurface>
388
- <DialogTitle>{title}</DialogTitle>
389
- <DialogBody>
390
- <DialogContent className={styles.content}>{renderContent()}</DialogContent>
391
- </DialogBody>
392
- <DialogActions>{renderActions()}</DialogActions>
393
- </DialogSurface>
394
- </Dialog>
395
- );
396
- }