@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,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
- }