@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,296 +0,0 @@
1
- /**
2
- * Property editor for Fetch root node options
3
- * Controls query-level settings like aggregation, paging, distinct, etc.
4
- */
5
-
6
- import { useState } from "react";
7
- import {
8
- Field,
9
- Checkbox,
10
- Input,
11
- Label,
12
- Tooltip,
13
- Switch,
14
- makeStyles,
15
- tokens,
16
- TeachingPopover,
17
- TeachingPopoverBody,
18
- TeachingPopoverSurface,
19
- TeachingPopoverTitle,
20
- TeachingPopoverTrigger,
21
- TeachingPopoverFooter,
22
- } from "@fluentui/react-components";
23
- import { Info16Regular } from "@fluentui/react-icons";
24
- import type { FetchNode } from "../../../../model/nodes";
25
- import { useBuilder } from "../../../../state/builderStore";
26
-
27
- // Track if the teaching popover has been shown this session
28
- let hasShownRetrieveAllPopover = false;
29
-
30
- const useStyles = makeStyles({
31
- container: {
32
- display: "flex",
33
- flexDirection: "column",
34
- gap: tokens.spacingVerticalM,
35
- padding: tokens.spacingVerticalM,
36
- },
37
- section: {
38
- display: "flex",
39
- flexDirection: "column",
40
- gap: tokens.spacingVerticalS,
41
- },
42
- fieldWithTooltip: {
43
- display: "flex",
44
- alignItems: "center",
45
- gap: tokens.spacingHorizontalXS,
46
- },
47
- tooltipIcon: {
48
- color: tokens.colorNeutralForeground3,
49
- cursor: "help",
50
- },
51
- });
52
-
53
- interface FetchOptionsEditorProps {
54
- node: FetchNode;
55
- onUpdate: (updates: Record<string, unknown>) => void;
56
- }
57
-
58
- export function FetchOptionsEditor({ node, onUpdate }: FetchOptionsEditorProps) {
59
- const styles = useStyles();
60
- const { options } = node;
61
- const { retrieveAllRecords, setRetrieveAllRecords } = useBuilder();
62
-
63
- // TeachingPopover state - show once per session when first toggling on
64
- const [showTeachingPopover, setShowTeachingPopover] = useState(false);
65
-
66
- const handleRetrieveAllChange = (_: unknown, data: { checked: boolean }) => {
67
- // Show teaching popover the first time user enables this option
68
- if (data.checked && !hasShownRetrieveAllPopover) {
69
- setShowTeachingPopover(true);
70
- hasShownRetrieveAllPopover = true;
71
- }
72
- setRetrieveAllRecords(data.checked);
73
- };
74
-
75
- const handleCheckboxChange =
76
- (field: string) => (_: unknown, data: { checked: boolean | "mixed" }) => {
77
- onUpdate({ [field]: data.checked === true });
78
- };
79
-
80
- const handleNumberChange =
81
- (field: string, min?: number, max?: number) => (_: unknown, data: { value: string }) => {
82
- const value = data.value === "" ? undefined : Number(data.value);
83
- if (value !== undefined) {
84
- if ((min !== undefined && value < min) || (max !== undefined && value > max)) {
85
- return; // Ignore invalid values
86
- }
87
- }
88
- onUpdate({ [field]: value });
89
- };
90
-
91
- const handleTextChange = (field: string) => (_: unknown, data: { value: string }) => {
92
- onUpdate({ [field]: data.value || undefined });
93
- };
94
-
95
- return (
96
- <div className={styles.container}>
97
- {/* Execution Options Section */}
98
- <div className={styles.section}>
99
- <Label weight="semibold">Execution Options</Label>
100
-
101
- <Field>
102
- <div className={styles.fieldWithTooltip}>
103
- <TeachingPopover
104
- open={showTeachingPopover}
105
- onOpenChange={(_, data) => setShowTeachingPopover(data.open)}
106
- >
107
- <TeachingPopoverTrigger>
108
- <Switch
109
- checked={retrieveAllRecords}
110
- onChange={handleRetrieveAllChange}
111
- label="Retrieve All Records"
112
- />
113
- </TeachingPopoverTrigger>
114
- <TeachingPopoverSurface>
115
- <TeachingPopoverBody>
116
- <TeachingPopoverTitle>Retrieve All Records</TeachingPopoverTitle>
117
- <div>Fetches all pages progressively. Use with caution on large datasets.</div>
118
- </TeachingPopoverBody>
119
- <TeachingPopoverFooter
120
- primary={{ children: "Got it", onClick: () => setShowTeachingPopover(false) }}
121
- />
122
- </TeachingPopoverSurface>
123
- </TeachingPopover>
124
- <Tooltip
125
- content="Fetches all pages progressively. Use with caution on large datasets."
126
- relationship="description"
127
- >
128
- <Info16Regular className={styles.tooltipIcon} />
129
- </Tooltip>
130
- </div>
131
- </Field>
132
- </div>
133
-
134
- {/* Aggregation & Distinct Section */}
135
- <div className={styles.section}>
136
- <Label weight="semibold">Query Options</Label>
137
-
138
- <Field>
139
- <div className={styles.fieldWithTooltip}>
140
- <Checkbox
141
- checked={options.aggregate ?? false}
142
- onChange={handleCheckboxChange("aggregate")}
143
- label="Aggregate Query"
144
- />
145
- <Tooltip
146
- content="Enable for grouping and aggregation (SUM, COUNT, AVG, MIN, MAX). Requires grouped or aggregated attributes."
147
- relationship="description"
148
- >
149
- <Info16Regular className={styles.tooltipIcon} />
150
- </Tooltip>
151
- </div>
152
- </Field>
153
-
154
- <Field>
155
- <div className={styles.fieldWithTooltip}>
156
- <Checkbox
157
- checked={options.distinct ?? false}
158
- onChange={handleCheckboxChange("distinct")}
159
- label="Distinct Rows"
160
- />
161
- <Tooltip
162
- content="Return only unique rows. Useful to eliminate duplicates from joins or multi-value fields."
163
- relationship="description"
164
- >
165
- <Info16Regular className={styles.tooltipIcon} />
166
- </Tooltip>
167
- </div>
168
- </Field>
169
-
170
- <Field>
171
- <div className={styles.fieldWithTooltip}>
172
- <Checkbox
173
- checked={options.returnTotalRecordCount ?? false}
174
- onChange={handleCheckboxChange("returnTotalRecordCount")}
175
- label="Return Total Record Count"
176
- />
177
- <Tooltip
178
- content="Include total count of records matching query (ignoring paging). May impact performance."
179
- relationship="description"
180
- >
181
- <Info16Regular className={styles.tooltipIcon} />
182
- </Tooltip>
183
- </div>
184
- </Field>
185
-
186
- <Field>
187
- <div className={styles.fieldWithTooltip}>
188
- <Checkbox
189
- checked={options.noLock ?? false}
190
- onChange={handleCheckboxChange("noLock")}
191
- label="No Lock (Read Uncommitted)"
192
- />
193
- <Tooltip
194
- content="Use NOLOCK hint for better read performance. May return uncommitted data. Use cautiously."
195
- relationship="description"
196
- >
197
- <Info16Regular className={styles.tooltipIcon} />
198
- </Tooltip>
199
- </div>
200
- </Field>
201
- </div>
202
-
203
- {/* Paging Section */}
204
- <div className={styles.section}>
205
- <Label weight="semibold">Paging & Limits</Label>
206
-
207
- <Field label="Max Records (Top)">
208
- <div className={styles.fieldWithTooltip}>
209
- <Input
210
- type="number"
211
- min={1}
212
- value={options.top?.toString() ?? ""}
213
- onChange={handleNumberChange("top", 1)}
214
- placeholder="No limit"
215
- />
216
- <Tooltip
217
- content="Maximum records to return (LIMIT clause). Leave empty for all records."
218
- relationship="description"
219
- >
220
- <Info16Regular className={styles.tooltipIcon} />
221
- </Tooltip>
222
- </div>
223
- </Field>
224
-
225
- <Field label="Page Size (Count)">
226
- <div className={styles.fieldWithTooltip}>
227
- <Input
228
- type="number"
229
- min={1}
230
- max={5000}
231
- value={options.count?.toString() ?? ""}
232
- onChange={handleNumberChange("count", 1, 5000)}
233
- placeholder="Default: 5000"
234
- />
235
- <Tooltip
236
- content="Records per page for pagination. Max 5000. Used with Page Number."
237
- relationship="description"
238
- >
239
- <Info16Regular className={styles.tooltipIcon} />
240
- </Tooltip>
241
- </div>
242
- </Field>
243
-
244
- <Field label="Page Number">
245
- <div className={styles.fieldWithTooltip}>
246
- <Input
247
- type="number"
248
- min={1}
249
- value={options.page?.toString() ?? ""}
250
- onChange={handleNumberChange("page", 1)}
251
- placeholder="1"
252
- />
253
- <Tooltip
254
- content="Which page to retrieve. Starts at 1. Used with Page Size."
255
- relationship="description"
256
- >
257
- <Info16Regular className={styles.tooltipIcon} />
258
- </Tooltip>
259
- </div>
260
- </Field>
261
-
262
- <Field label="Paging Cookie" hint="Copy from previous query results for efficient paging">
263
- <Input
264
- value={options.pagingCookie ?? ""}
265
- onChange={handleTextChange("pagingCookie")}
266
- placeholder="<cookie>...</cookie>"
267
- />
268
- </Field>
269
- </div>
270
-
271
- {/* Advanced Section */}
272
- <div className={styles.section}>
273
- <Label weight="semibold">Advanced</Label>
274
-
275
- <Field label="UTC Offset (minutes)">
276
- <div className={styles.fieldWithTooltip}>
277
- <Input
278
- type="number"
279
- min={-720}
280
- max={720}
281
- value={options.utcOffset?.toString() ?? ""}
282
- onChange={handleNumberChange("utcOffset", -720, 720)}
283
- placeholder="0"
284
- />
285
- <Tooltip
286
- content="Timezone offset for datetime filters. Range: -720 to 720 minutes from UTC."
287
- relationship="description"
288
- >
289
- <Info16Regular className={styles.tooltipIcon} />
290
- </Tooltip>
291
- </div>
292
- </Field>
293
- </div>
294
- </div>
295
- );
296
- }
@@ -1,106 +0,0 @@
1
- /**
2
- * Property editor for Filter nodes
3
- * Controls logical grouping (AND/OR) of conditions
4
- */
5
-
6
- import {
7
- Field,
8
- Dropdown,
9
- Option,
10
- Input,
11
- Label,
12
- Tooltip,
13
- makeStyles,
14
- tokens,
15
- } from "@fluentui/react-components";
16
- import { Info16Regular } from "@fluentui/react-icons";
17
- import type { FilterNode } from "../../../../model/nodes";
18
-
19
- const useStyles = makeStyles({
20
- container: {
21
- display: "flex",
22
- flexDirection: "column",
23
- gap: tokens.spacingVerticalM,
24
- padding: tokens.spacingVerticalM,
25
- },
26
- section: {
27
- display: "flex",
28
- flexDirection: "column",
29
- gap: tokens.spacingVerticalS,
30
- },
31
- fieldWithTooltip: {
32
- display: "flex",
33
- alignItems: "center",
34
- gap: tokens.spacingHorizontalXS,
35
- },
36
- tooltipIcon: {
37
- color: tokens.colorNeutralForeground3,
38
- cursor: "help",
39
- },
40
- });
41
-
42
- interface FilterEditorProps {
43
- node: FilterNode;
44
- onUpdate: (updates: Record<string, unknown>) => void;
45
- }
46
-
47
- export function FilterEditor({ node, onUpdate }: FilterEditorProps) {
48
- const styles = useStyles();
49
-
50
- const handleDropdownChange = (field: string) => (_: unknown, data: { optionValue?: string }) => {
51
- onUpdate({ [field]: data.optionValue });
52
- };
53
-
54
- const handleTextChange = (field: string) => (_: unknown, data: { value: string }) => {
55
- onUpdate({ [field]: data.value || undefined });
56
- };
57
-
58
- return (
59
- <div className={styles.container}>
60
- {/* Basic Properties */}
61
- <div className={styles.section}>
62
- <Label weight="semibold">Filter Properties</Label>
63
-
64
- <Field label="Logical Operator" required>
65
- <div className={styles.fieldWithTooltip}>
66
- <Dropdown
67
- value={node.conjunction}
68
- selectedOptions={[node.conjunction]}
69
- onOptionSelect={handleDropdownChange("conjunction")}
70
- >
71
- <Option value="and">AND (all conditions must match)</Option>
72
- <Option value="or">OR (any condition can match)</Option>
73
- </Dropdown>
74
- <Tooltip
75
- content="AND: all child conditions/subfilters must be true. OR: at least one must be true."
76
- relationship="description"
77
- >
78
- <Info16Regular className={styles.tooltipIcon} />
79
- </Tooltip>
80
- </div>
81
- </Field>
82
- </div>
83
-
84
- {/* Advanced Section */}
85
- <div className={styles.section}>
86
- <Label weight="semibold">Advanced</Label>
87
-
88
- <Field label="Query Hint (optional)" hint="Performance optimization hint. Rarely needed.">
89
- <div className={styles.fieldWithTooltip}>
90
- <Input
91
- value={node.hint ?? ""}
92
- onChange={handleTextChange("hint")}
93
- placeholder="e.g., union"
94
- />
95
- <Tooltip
96
- content="Query optimizer hint. 'union' can improve performance for complex multi-table filters."
97
- relationship="description"
98
- >
99
- <Info16Regular className={styles.tooltipIcon} />
100
- </Tooltip>
101
- </div>
102
- </Field>
103
- </div>
104
- </div>
105
- );
106
- }