@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.
- package/LICENSE +661 -0
- package/dist/assets/index-DD9fzkbz.js +232 -0
- package/dist/index.html +70 -0
- package/index.html +0 -1
- package/npm-shrinkwrap.json +6329 -0
- package/package.json +95 -51
- package/CHANGELOG.md +0 -120
- package/eslint.config.js +0 -23
- package/public/vite.svg +0 -1
- package/src/app/AppShell.tsx +0 -1733
- package/src/assets/20px-Microsoft_Office_Excel_(2025/342/200/223present).svg.png +0 -0
- package/src/assets/react.svg +0 -1
- package/src/features/fetchxml/api/dataverseMetadata.ts +0 -192
- package/src/features/fetchxml/api/excelExport.ts +0 -318
- package/src/features/fetchxml/api/formattedValues.ts +0 -107
- package/src/features/fetchxml/api/pptbClient.ts +0 -2635
- package/src/features/fetchxml/model/displaySettings.ts +0 -18
- package/src/features/fetchxml/model/fetchxml.ts +0 -346
- package/src/features/fetchxml/model/fetchxmlIntellisense.ts +0 -583
- package/src/features/fetchxml/model/fetchxmlParser.ts +0 -708
- package/src/features/fetchxml/model/layoutxml.ts +0 -372
- package/src/features/fetchxml/model/nodes.ts +0 -255
- package/src/features/fetchxml/model/operators.ts +0 -624
- package/src/features/fetchxml/model/treeUtils.ts +0 -174
- package/src/features/fetchxml/state/builderStore.tsx +0 -1160
- package/src/features/fetchxml/state/cache.ts +0 -393
- package/src/features/fetchxml/ui/Dialogs/BulkDeleteDialog.tsx +0 -352
- package/src/features/fetchxml/ui/Dialogs/DeleteConfirmDialog.tsx +0 -396
- package/src/features/fetchxml/ui/Dialogs/SaveViewDialog.tsx +0 -612
- package/src/features/fetchxml/ui/Dialogs/SolutionPicker.tsx +0 -114
- package/src/features/fetchxml/ui/Dialogs/WorkflowPickerDialog.tsx +0 -437
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/AttributeEditor.tsx +0 -214
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/ConditionEditor.tsx +0 -533
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/FetchOptionsEditor.tsx +0 -296
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/FilterEditor.tsx +0 -106
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/LinkEntityEditor.tsx +0 -433
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/OrderEditor.tsx +0 -161
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/ValueOfPicker.tsx +0 -194
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel.tsx +0 -225
- package/src/features/fetchxml/ui/LeftPane/TreeView.tsx +0 -604
- package/src/features/fetchxml/ui/RightPane/AddColumnsPanel.tsx +0 -800
- package/src/features/fetchxml/ui/RightPane/ColumnConfigDialog.tsx +0 -170
- package/src/features/fetchxml/ui/RightPane/DataGridCellRenderers.tsx +0 -356
- package/src/features/fetchxml/ui/RightPane/EditColumnsPanel.tsx +0 -372
- package/src/features/fetchxml/ui/RightPane/FetchXmlEditor.tsx +0 -399
- package/src/features/fetchxml/ui/RightPane/FormattedValueUtils.ts +0 -189
- package/src/features/fetchxml/ui/RightPane/LayoutXmlViewer.tsx +0 -171
- package/src/features/fetchxml/ui/RightPane/PreviewTabs.tsx +0 -471
- package/src/features/fetchxml/ui/RightPane/ResultsCommandBar.tsx +0 -430
- package/src/features/fetchxml/ui/RightPane/ResultsGrid.tsx +0 -983
- package/src/features/fetchxml/ui/RightPane/XmlTextArea.tsx +0 -65
- package/src/features/fetchxml/ui/Settings/SettingsDrawer.tsx +0 -175
- package/src/features/fetchxml/ui/Toolbar/EntitySelector.tsx +0 -788
- package/src/features/fetchxml/ui/Toolbar/LoadViewPicker.tsx +0 -274
- package/src/features/fetchxml/ui/Toolbar/SaveViewButton.tsx +0 -174
- package/src/main.tsx +0 -11
- package/src/shared/components/AttributePicker.tsx +0 -138
- package/src/shared/components/BetweenInputPicker.tsx +0 -120
- package/src/shared/components/BooleanValuePicker.tsx +0 -165
- package/src/shared/components/DateTimeInputPicker.tsx +0 -170
- package/src/shared/components/DynamicValueList.tsx +0 -128
- package/src/shared/components/ExcelIcon.tsx +0 -30
- package/src/shared/components/MultiValuePicker.tsx +0 -178
- package/src/shared/components/NumericInputPicker.tsx +0 -156
- package/src/shared/components/OptionSetValuePicker.tsx +0 -150
- package/src/shared/components/RelationshipPicker.tsx +0 -268
- package/src/shared/contexts/ThemeContext.tsx +0 -19
- package/src/shared/hooks/useAccessMode.ts +0 -77
- package/src/shared/hooks/useLazyMetadata.ts +0 -132
- package/src/shared/hooks/usePptbContext.ts +0 -170
- package/src/shared/hooks/usePublisherFilter.ts +0 -214
- package/src/shared/hooks/useSolutionFilter.ts +0 -162
- package/src/shared/utils/debug.ts +0 -87
- package/tsconfig.app.json +0 -28
- package/tsconfig.json +0 -7
- package/tsconfig.node.json +0 -26
- 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
|
-
}
|