@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,430 +0,0 @@
1
- /**
2
- * Command bar for DataGrid with row actions
3
- * Similar to Power Apps Model Driven Apps view command bar
4
- */
5
-
6
- import { useState, useCallback } from "react";
7
- import {
8
- Toolbar,
9
- ToolbarButton,
10
- ToolbarDivider,
11
- makeStyles,
12
- Tooltip,
13
- Menu,
14
- MenuTrigger,
15
- MenuPopover,
16
- MenuList,
17
- MenuItem,
18
- SplitButton,
19
- MenuButton,
20
- type MenuButtonProps,
21
- } from "@fluentui/react-components";
22
- import {
23
- Open20Regular,
24
- Link20Regular,
25
- CheckmarkCircle20Regular,
26
- DismissCircle20Regular,
27
- Delete20Regular,
28
- ColumnTriple20Regular,
29
- Play20Regular,
30
- DocumentBulletList20Regular,
31
- } from "@fluentui/react-icons";
32
- import { ExcelIcon } from "../../../../shared/components/ExcelIcon";
33
- import { EditColumnsPanel } from "./EditColumnsPanel";
34
- import {
35
- AddColumnsPanel,
36
- type AddColumnSelection,
37
- type RelatedEntityColumn,
38
- } from "./AddColumnsPanel";
39
- import type { LayoutColumn } from "../../model/layoutxml";
40
- import type { AttributeMetadata, RelationshipMetadata, WorkflowInfo } from "../../api/pptbClient";
41
-
42
- const useStyles = makeStyles({
43
- toolbar: {
44
- padding: "0",
45
- },
46
- splitButtonAppearance: {
47
- // Use subtle appearance for split buttons to match toolbar
48
- },
49
- });
50
-
51
- export interface CommandBarProps {
52
- selectedCount: number;
53
- onOpen?: () => void;
54
- onCopyUrl?: () => void;
55
- onActivate?: () => void;
56
- onDeactivate?: () => void;
57
- /** Delete selected records (or all if none selected) */
58
- onDelete?: () => void;
59
- /** Bulk delete (creates async job) */
60
- onBulkDelete?: () => void;
61
- /** Whether delete is available (user has privilege) */
62
- canDelete?: boolean;
63
- /** Whether bulk delete is available (user has privilege) */
64
- canBulkDelete?: boolean;
65
- /** Whether delete/bulk delete actions are disabled (e.g., aggregate query or 1-N relationship) */
66
- deleteDisabled?: boolean;
67
- /** Execute a specific workflow directly */
68
- onRunSpecificWorkflow?: (workflow: WorkflowInfo) => void;
69
- /** Whether workflow execution is available (user has privilege) */
70
- canRunWorkflow?: boolean;
71
- /** Whether workflow action is disabled (e.g., aggregate query or 1-N relationship) */
72
- workflowDisabled?: boolean;
73
- /** Fetch available workflows for the entity */
74
- onFetchWorkflows?: () => Promise<WorkflowInfo[]>;
75
- /** Export to Excel via Dataverse ExportToExcel API (requires saved view) */
76
- onExport?: () => void;
77
- /** Export to Excel locally using exceljs (no view required) */
78
- onExportLocal?: () => void;
79
- /** Whether server export is available (requires a saved view and export privilege) */
80
- canExport?: boolean;
81
- /** Whether export is in progress */
82
- isExporting?: boolean;
83
- /** Tooltip text to show when server export is disabled */
84
- exportDisabledReason?: string;
85
- /** Entity logical name */
86
- entityName?: string;
87
- /** Entity display name */
88
- entityDisplayName?: string;
89
- /** Current column layout */
90
- columns?: LayoutColumn[];
91
- /** Callback when columns are reordered */
92
- onReorderColumns?: (columns: LayoutColumn[]) => void;
93
- /** Callback when columns are removed */
94
- onRemoveColumn?: (columnName: string) => void;
95
- /** Available attributes from metadata for adding columns */
96
- availableAttributes?: AttributeMetadata[];
97
- /** Currently selected attributes in the query */
98
- selectedAttributes?: string[];
99
- /** Callback when user wants to add a column from root entity */
100
- onAddColumn?: (attributeName: string) => void;
101
- /** Callback when user wants to add columns from related entity */
102
- onAddRelatedColumns?: (columns: RelatedEntityColumn[]) => void;
103
- /** Lookup relationships (many-to-one) for related entity columns */
104
- lookupRelationships?: RelationshipMetadata[];
105
- /** One-to-many relationships for 1-N related entity columns */
106
- oneToManyRelationships?: RelationshipMetadata[];
107
- /** Whether relationship data is loading */
108
- isLoadingRelationships?: boolean;
109
- /** Callback to load attributes for a related entity */
110
- onLoadRelatedAttributes?: (entityLogicalName: string) => Promise<AttributeMetadata[]>;
111
- /** Callback to reset columns to default */
112
- onResetToDefault?: () => void;
113
- }
114
-
115
- export function ResultsCommandBar({
116
- selectedCount,
117
- onOpen,
118
- onCopyUrl,
119
- onActivate,
120
- onDeactivate,
121
- onDelete,
122
- onBulkDelete,
123
- canDelete = false,
124
- canBulkDelete = false,
125
- deleteDisabled = false,
126
- onRunSpecificWorkflow,
127
- canRunWorkflow = false,
128
- workflowDisabled = false,
129
- onFetchWorkflows,
130
- onExport,
131
- onExportLocal,
132
- canExport = false,
133
- isExporting = false,
134
- exportDisabledReason,
135
- entityName,
136
- entityDisplayName,
137
- columns,
138
- onReorderColumns,
139
- onRemoveColumn,
140
- availableAttributes,
141
- selectedAttributes,
142
- onAddColumn,
143
- onAddRelatedColumns,
144
- lookupRelationships,
145
- oneToManyRelationships,
146
- isLoadingRelationships,
147
- onLoadRelatedAttributes,
148
- onResetToDefault,
149
- }: CommandBarProps) {
150
- const styles = useStyles();
151
- const hasSelection = selectedCount > 0;
152
- const singleSelection = selectedCount === 1;
153
- const [editPanelOpen, setEditPanelOpen] = useState(false);
154
- const [addPanelOpen, setAddPanelOpen] = useState(false);
155
-
156
- // Workflow menu state
157
- const [workflows, setWorkflows] = useState<WorkflowInfo[]>([]);
158
- const [isLoadingWorkflows, setIsLoadingWorkflows] = useState(false);
159
- const [workflowsLoaded, setWorkflowsLoaded] = useState(false);
160
-
161
- // Load workflows when menu opens (lazy loading)
162
- const handleWorkflowMenuOpen = useCallback(async () => {
163
- if (workflowsLoaded || isLoadingWorkflows || !onFetchWorkflows) return;
164
-
165
- setIsLoadingWorkflows(true);
166
- try {
167
- const wfs = await onFetchWorkflows();
168
- setWorkflows(wfs);
169
- setWorkflowsLoaded(true);
170
- } catch (err) {
171
- console.error("Failed to load workflows:", err);
172
- } finally {
173
- setIsLoadingWorkflows(false);
174
- }
175
- }, [workflowsLoaded, isLoadingWorkflows, onFetchWorkflows]);
176
-
177
- const handleEditColumnsClick = useCallback(() => {
178
- setEditPanelOpen(true);
179
- }, []);
180
-
181
- const handleEditPanelClose = useCallback(() => {
182
- setEditPanelOpen(false);
183
- }, []);
184
-
185
- const handleAddPanelClose = useCallback(() => {
186
- setAddPanelOpen(false);
187
- }, []);
188
-
189
- const handleEditApply = useCallback(
190
- (updatedColumns: LayoutColumn[]) => {
191
- // Detect removed columns
192
- if (columns && onRemoveColumn) {
193
- const updatedNames = new Set(updatedColumns.map((c) => c.name));
194
- for (const col of columns) {
195
- if (!updatedNames.has(col.name)) {
196
- onRemoveColumn(col.name);
197
- }
198
- }
199
- }
200
- // Apply reordering
201
- onReorderColumns?.(updatedColumns);
202
- setEditPanelOpen(false);
203
- },
204
- [columns, onReorderColumns, onRemoveColumn]
205
- );
206
-
207
- const handleAddApply = useCallback(
208
- (selection: AddColumnSelection) => {
209
- // Add root entity attributes
210
- for (const attrName of selection.rootAttributes) {
211
- onAddColumn?.(attrName);
212
- }
213
- // Add related entity columns
214
- if (selection.relatedColumns.length > 0 && onAddRelatedColumns) {
215
- onAddRelatedColumns(selection.relatedColumns);
216
- }
217
- setAddPanelOpen(false);
218
- },
219
- [onAddColumn, onAddRelatedColumns]
220
- );
221
-
222
- const handleOpenAddFromEdit = useCallback(() => {
223
- setAddPanelOpen(true);
224
- }, []);
225
-
226
- return (
227
- <>
228
- <Toolbar className={styles.toolbar} size="medium" aria-label="Record actions">
229
- <ToolbarButton
230
- appearance="subtle"
231
- icon={<Open20Regular />}
232
- disabled={!singleSelection}
233
- onClick={onOpen}
234
- aria-label="Open record"
235
- >
236
- Open
237
- </ToolbarButton>
238
-
239
- <ToolbarButton
240
- appearance="subtle"
241
- icon={<Link20Regular />}
242
- disabled={!singleSelection}
243
- onClick={onCopyUrl}
244
- aria-label="Copy record URL"
245
- >
246
- Copy URL
247
- </ToolbarButton>
248
-
249
- <ToolbarDivider />
250
-
251
- {/* Activate/Deactivate buttons - always shown, disabled for now */}
252
- <ToolbarButton
253
- appearance="subtle"
254
- icon={<CheckmarkCircle20Regular />}
255
- disabled={true}
256
- onClick={onActivate}
257
- aria-label="Activate selected records"
258
- >
259
- Activate
260
- </ToolbarButton>
261
-
262
- <ToolbarButton
263
- appearance="subtle"
264
- icon={<DismissCircle20Regular />}
265
- disabled={true}
266
- onClick={onDeactivate}
267
- aria-label="Deactivate selected records"
268
- >
269
- Deactivate
270
- </ToolbarButton>
271
-
272
- <ToolbarDivider />
273
-
274
- {canDelete && (
275
- <Menu positioning="below-end">
276
- <MenuTrigger disableButtonEnhancement>
277
- {(triggerProps: MenuButtonProps) => (
278
- <SplitButton
279
- appearance="subtle"
280
- menuButton={triggerProps}
281
- primaryActionButton={{
282
- onClick: onDelete,
283
- disabled: deleteDisabled,
284
- }}
285
- disabled={deleteDisabled}
286
- icon={<Delete20Regular />}
287
- aria-label={
288
- hasSelection ? "Delete selected records" : "Delete all records from view"
289
- }
290
- >
291
- {hasSelection ? "Delete" : "Delete All"}
292
- </SplitButton>
293
- )}
294
- </MenuTrigger>
295
- <MenuPopover>
296
- <MenuList>
297
- <MenuItem icon={<Delete20Regular />} onClick={onDelete} disabled={deleteDisabled}>
298
- Delete{hasSelection ? ` (${selectedCount})` : " All"}
299
- </MenuItem>
300
- {canBulkDelete && (
301
- <MenuItem
302
- icon={<DocumentBulletList20Regular />}
303
- onClick={onBulkDelete}
304
- disabled={deleteDisabled}
305
- >
306
- Bulk Delete (Job)
307
- </MenuItem>
308
- )}
309
- </MenuList>
310
- </MenuPopover>
311
- </Menu>
312
- )}
313
-
314
- {canRunWorkflow && (
315
- <Menu
316
- positioning="below-end"
317
- onOpenChange={(_, data) => data.open && handleWorkflowMenuOpen()}
318
- >
319
- <MenuTrigger disableButtonEnhancement>
320
- <MenuButton
321
- appearance="subtle"
322
- icon={<Play20Regular />}
323
- disabled={!hasSelection || workflowDisabled}
324
- aria-label="Run workflow on selected records"
325
- >
326
- Run Workflow
327
- </MenuButton>
328
- </MenuTrigger>
329
- <MenuPopover>
330
- <MenuList>
331
- {isLoadingWorkflows && <MenuItem disabled>Loading workflows...</MenuItem>}
332
- {!isLoadingWorkflows && workflows.length === 0 && workflowsLoaded && (
333
- <MenuItem disabled>No workflows available</MenuItem>
334
- )}
335
- {!isLoadingWorkflows &&
336
- workflows.map((wf) => (
337
- <MenuItem
338
- key={wf.workflowid}
339
- icon={<Play20Regular />}
340
- onClick={() => onRunSpecificWorkflow?.(wf)}
341
- >
342
- {wf.name}
343
- </MenuItem>
344
- ))}
345
- </MenuList>
346
- </MenuPopover>
347
- </Menu>
348
- )}
349
-
350
- <ToolbarDivider />
351
-
352
- {/* Export Menu Button */}
353
- <Menu>
354
- <MenuTrigger disableButtonEnhancement>
355
- <Tooltip
356
- content={isExporting ? "Export in progress..." : "Export to Excel"}
357
- relationship="description"
358
- >
359
- <MenuButton
360
- appearance="subtle"
361
- icon={<ExcelIcon />}
362
- disabled={isExporting}
363
- aria-label="Export to Excel"
364
- >
365
- {isExporting ? "Exporting..." : "Export to Excel"}
366
- </MenuButton>
367
- </Tooltip>
368
- </MenuTrigger>
369
- <MenuPopover>
370
- <MenuList>
371
- <Tooltip
372
- content={
373
- canExport
374
- ? "Export using Dataverse API (all records)"
375
- : exportDisabledReason || "Save as a view first to enable server export"
376
- }
377
- relationship="description"
378
- positioning="before"
379
- >
380
- <MenuItem onClick={onExport} disabled={!canExport || isExporting}>
381
- Export (Server)
382
- </MenuItem>
383
- </Tooltip>
384
- <MenuItem onClick={onExportLocal} disabled={isExporting}>
385
- Export (Local)
386
- </MenuItem>
387
- </MenuList>
388
- </MenuPopover>
389
- </Menu>
390
-
391
- <ToolbarDivider />
392
-
393
- <ToolbarButton
394
- appearance="subtle"
395
- icon={<ColumnTriple20Regular />}
396
- onClick={handleEditColumnsClick}
397
- aria-label="Edit columns"
398
- >
399
- Edit columns
400
- </ToolbarButton>
401
- </Toolbar>
402
-
403
- {/* Edit Columns Panel */}
404
- <EditColumnsPanel
405
- open={editPanelOpen}
406
- columns={columns || []}
407
- entityDisplayName={entityDisplayName}
408
- onClose={handleEditPanelClose}
409
- onApply={handleEditApply}
410
- onAddColumns={handleOpenAddFromEdit}
411
- onResetToDefault={onResetToDefault}
412
- />
413
-
414
- {/* Add Columns Panel */}
415
- <AddColumnsPanel
416
- open={addPanelOpen}
417
- entityDisplayName={entityDisplayName}
418
- entityLogicalName={entityName}
419
- availableAttributes={availableAttributes}
420
- selectedAttributes={selectedAttributes}
421
- lookupRelationships={lookupRelationships}
422
- oneToManyRelationships={oneToManyRelationships}
423
- isLoadingRelationships={isLoadingRelationships}
424
- onLoadRelatedAttributes={onLoadRelatedAttributes}
425
- onClose={handleAddPanelClose}
426
- onApply={handleAddApply}
427
- />
428
- </>
429
- );
430
- }