@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,214 +0,0 @@
1
- /**
2
- * Hook for Full Filter Mode: Publisher → Solution → Entities
3
- * Loads publishers with solutions in one call (optimized), manages selection,
4
- * resolves entities from selected solutions
5
- */
6
-
7
- import { useState, useEffect, useCallback } from "react";
8
- import {
9
- getPublishersWithSolutions,
10
- getSolutionComponents,
11
- filterCachedEntitiesByNames,
12
- type Solution,
13
- type EntityMetadata,
14
- type PublisherWithSolutions,
15
- } from "../../features/fetchxml/api/pptbClient";
16
- import { metadataCache } from "../../features/fetchxml/state/cache";
17
-
18
- export function usePublisherFilter() {
19
- // Publishers with solutions (combined)
20
- const [publishersWithSolutions, setPublishersWithSolutions] = useState<PublisherWithSolutions[]>(
21
- []
22
- );
23
- const [publishersLoading, setPublishersLoading] = useState(false);
24
- const [publishersError, setPublishersError] = useState<string | null>(null);
25
-
26
- // Selected publishers
27
- const [selectedPublisherIds, setSelectedPublisherIds] = useState<string[]>([]);
28
-
29
- // Solutions (filtered by selected publishers)
30
- const [solutions, setSolutions] = useState<Solution[]>([]);
31
-
32
- // Selected solutions
33
- const [selectedSolutionIds, setSelectedSolutionIds] = useState<string[]>([]);
34
-
35
- // Entities
36
- const [entities, setEntities] = useState<EntityMetadata[]>([]);
37
- const [entitiesLoading, setEntitiesLoading] = useState(false);
38
- const [entitiesError, setEntitiesError] = useState<string | null>(null);
39
-
40
- // Load publishers with solutions on mount (optimized single call)
41
- useEffect(() => {
42
- let mounted = true;
43
- const abortController = new AbortController();
44
-
45
- async function loadPublishersWithSolutions() {
46
- // Check cache
47
- const cached = metadataCache.getPublishersWithSolutions();
48
- if (cached) {
49
- setPublishersWithSolutions(cached);
50
- return;
51
- }
52
-
53
- try {
54
- setPublishersLoading(true);
55
- setPublishersError(null);
56
-
57
- const data = await getPublishersWithSolutions();
58
-
59
- if (mounted) {
60
- setPublishersWithSolutions(data);
61
- metadataCache.setPublishersWithSolutions(data);
62
- }
63
- } catch (err) {
64
- if (mounted && !abortController.signal.aborted) {
65
- setPublishersError(err instanceof Error ? err.message : String(err));
66
- }
67
- } finally {
68
- if (mounted) {
69
- setPublishersLoading(false);
70
- }
71
- }
72
- }
73
-
74
- loadPublishersWithSolutions();
75
-
76
- return () => {
77
- mounted = false;
78
- abortController.abort();
79
- };
80
- }, []);
81
-
82
- // Filter solutions when publishers are selected
83
- useEffect(() => {
84
- if (!selectedPublisherIds.length) {
85
- setSolutions([]);
86
- // Clear selected solutions when all publishers are deselected
87
- setSelectedSolutionIds([]);
88
- return;
89
- }
90
-
91
- // Filter solutions from the combined response (union from all selected publishers)
92
- const selectedPublisherSet = new Set(selectedPublisherIds);
93
- const filteredSolutions = publishersWithSolutions
94
- .filter((pws) => selectedPublisherSet.has(pws.publisher.publisherid))
95
- .flatMap((pws) => pws.solutions);
96
-
97
- setSolutions(filteredSolutions);
98
-
99
- // Validate selected solutions - keep only those still in filtered list
100
- setSelectedSolutionIds((currentSelected) => {
101
- if (currentSelected.length === 0) return currentSelected;
102
-
103
- const availableSolutionIds = new Set(filteredSolutions.map((s) => s.solutionid));
104
- const validSolutionIds = currentSelected.filter((id) => availableSolutionIds.has(id));
105
-
106
- // Only update if the list changed (prevent unnecessary re-renders)
107
- if (validSolutionIds.length === currentSelected.length) {
108
- return currentSelected;
109
- }
110
-
111
- return validSolutionIds;
112
- });
113
- }, [selectedPublisherIds, publishersWithSolutions]);
114
-
115
- // Load entities when solutions are selected
116
- useEffect(() => {
117
- if (!selectedSolutionIds.length) {
118
- setEntities([]);
119
- setEntitiesError(null);
120
- return;
121
- }
122
-
123
- let mounted = true;
124
- const abortController = new AbortController();
125
-
126
- async function loadEntities() {
127
- // Check cache
128
- const cached = metadataCache.getFilteredEntities(selectedSolutionIds);
129
- if (cached) {
130
- setEntities(cached);
131
- return;
132
- }
133
-
134
- try {
135
- setEntitiesLoading(true);
136
- setEntitiesError(null);
137
-
138
- console.log("[usePublisherFilter] Loading entities for solutions:", selectedSolutionIds);
139
-
140
- // Get solution components (entities only) - cached per solution
141
- const components = await getSolutionComponents(selectedSolutionIds);
142
- console.log("[usePublisherFilter] Solution components received:", {
143
- solutionIds: selectedSolutionIds,
144
- componentCount: components.length,
145
- components: components.slice(0, 10),
146
- });
147
-
148
- // Extract unique entity logical names
149
- const logicalNames = Array.from(
150
- new Set(components.map((c) => c.msdyn_name).filter(Boolean))
151
- );
152
-
153
- console.log("[usePublisherFilter] Unique entity logical names extracted:", {
154
- count: logicalNames.length,
155
- names: logicalNames,
156
- });
157
-
158
- // Filter from global cached metadata (instant, no API call)
159
- const data = filterCachedEntitiesByNames(logicalNames);
160
- console.log("[usePublisherFilter] Filtered entities from cache:", {
161
- count: data.length,
162
- entities: data.map((e) => e.LogicalName),
163
- });
164
-
165
- if (mounted) {
166
- setEntities(data);
167
- metadataCache.setFilteredEntities(selectedSolutionIds, data);
168
- }
169
- } catch (err) {
170
- if (mounted && !abortController.signal.aborted) {
171
- setEntitiesError(err instanceof Error ? err.message : String(err));
172
- }
173
- } finally {
174
- if (mounted) {
175
- setEntitiesLoading(false);
176
- }
177
- }
178
- }
179
-
180
- loadEntities();
181
-
182
- return () => {
183
- mounted = false;
184
- abortController.abort();
185
- };
186
- }, [selectedSolutionIds]);
187
-
188
- const updateSelectedPublishers = useCallback((ids: string[]) => {
189
- setSelectedPublisherIds(ids);
190
- }, []);
191
-
192
- const updateSelectedSolutions = useCallback((ids: string[]) => {
193
- setSelectedSolutionIds(ids);
194
- }, []);
195
-
196
- return {
197
- // Publishers (extracted from combined response)
198
- publishers: publishersWithSolutions.map((pws) => pws.publisher),
199
- publishersLoading,
200
- publishersError,
201
- selectedPublisherIds,
202
- updateSelectedPublishers,
203
-
204
- // Solutions (filtered by selected publishers)
205
- solutions,
206
- selectedSolutionIds,
207
- updateSelectedSolutions,
208
-
209
- // Entities
210
- entities,
211
- entitiesLoading,
212
- entitiesError,
213
- };
214
- }
@@ -1,162 +0,0 @@
1
- /**
2
- * Hook for Solutions-Only Mode: Solution → Entities
3
- * Loads all solutions with entities, manages selection, resolves entities
4
- */
5
-
6
- import { useState, useEffect, useCallback } from "react";
7
- import {
8
- getAllSolutionsWithEntities,
9
- getSolutionComponents,
10
- filterCachedEntitiesByNames,
11
- type Solution,
12
- type EntityMetadata,
13
- } from "../../features/fetchxml/api/pptbClient";
14
- import { metadataCache } from "../../features/fetchxml/state/cache";
15
-
16
- export function useSolutionFilter() {
17
- // Solutions
18
- const [solutions, setSolutions] = useState<Solution[]>([]);
19
- const [solutionsLoading, setSolutionsLoading] = useState(false);
20
- const [solutionsError, setSolutionsError] = useState<string | null>(null);
21
-
22
- // Selected solutions
23
- const [selectedSolutionIds, setSelectedSolutionIds] = useState<string[]>([]);
24
-
25
- // Entities
26
- const [entities, setEntities] = useState<EntityMetadata[]>([]);
27
- const [entitiesLoading, setEntitiesLoading] = useState(false);
28
- const [entitiesError, setEntitiesError] = useState<string | null>(null);
29
-
30
- // Load all solutions on mount (no publisher filter)
31
- useEffect(() => {
32
- let mounted = true;
33
- const abortController = new AbortController();
34
-
35
- async function loadSolutions() {
36
- // Check cache (use empty array as key for "all solutions")
37
- const cached = metadataCache.getSolutions([]);
38
- if (cached) {
39
- setSolutions(cached);
40
- return;
41
- }
42
-
43
- try {
44
- setSolutionsLoading(true);
45
- setSolutionsError(null);
46
-
47
- const data = await getAllSolutionsWithEntities();
48
-
49
- if (mounted) {
50
- setSolutions(data);
51
- metadataCache.setSolutions([], data);
52
- }
53
- } catch (err) {
54
- if (mounted && !abortController.signal.aborted) {
55
- setSolutionsError(err instanceof Error ? err.message : String(err));
56
- }
57
- } finally {
58
- if (mounted) {
59
- setSolutionsLoading(false);
60
- }
61
- }
62
- }
63
-
64
- loadSolutions();
65
-
66
- return () => {
67
- mounted = false;
68
- abortController.abort();
69
- };
70
- }, []);
71
-
72
- // Load entities when solutions are selected
73
- useEffect(() => {
74
- if (!selectedSolutionIds.length) {
75
- setEntities([]);
76
- setEntitiesError(null);
77
- return;
78
- }
79
-
80
- let mounted = true;
81
- const abortController = new AbortController();
82
-
83
- async function loadEntities() {
84
- // Check cache
85
- const cached = metadataCache.getFilteredEntities(selectedSolutionIds);
86
- if (cached) {
87
- setEntities(cached);
88
- return;
89
- }
90
-
91
- try {
92
- setEntitiesLoading(true);
93
- setEntitiesError(null);
94
-
95
- console.log("[useSolutionFilter] Loading entities for solutions:", selectedSolutionIds);
96
-
97
- // Get solution components (entities only) - cached per solution
98
- const components = await getSolutionComponents(selectedSolutionIds);
99
- console.log("[useSolutionFilter] Solution components received:", {
100
- solutionIds: selectedSolutionIds,
101
- componentCount: components.length,
102
- components: components.slice(0, 10),
103
- });
104
-
105
- // Extract unique entity logical names
106
- const logicalNames = Array.from(
107
- new Set(components.map((c) => c.msdyn_name).filter(Boolean))
108
- );
109
-
110
- console.log("[useSolutionFilter] Unique entity logical names extracted:", {
111
- count: logicalNames.length,
112
- names: logicalNames,
113
- });
114
-
115
- // Filter from global cached metadata (instant, no API call)
116
- const data = filterCachedEntitiesByNames(logicalNames);
117
- console.log("[useSolutionFilter] Filtered entities from cache:", {
118
- count: data.length,
119
- entities: data.map((e) => e.LogicalName),
120
- });
121
-
122
- if (mounted) {
123
- setEntities(data);
124
- metadataCache.setFilteredEntities(selectedSolutionIds, data);
125
- }
126
- } catch (err) {
127
- if (mounted && !abortController.signal.aborted) {
128
- setEntitiesError(err instanceof Error ? err.message : String(err));
129
- }
130
- } finally {
131
- if (mounted) {
132
- setEntitiesLoading(false);
133
- }
134
- }
135
- }
136
-
137
- loadEntities();
138
-
139
- return () => {
140
- mounted = false;
141
- abortController.abort();
142
- };
143
- }, [selectedSolutionIds]);
144
-
145
- const updateSelectedSolutions = useCallback((ids: string[]) => {
146
- setSelectedSolutionIds(ids);
147
- }, []);
148
-
149
- return {
150
- // Solutions
151
- solutions,
152
- solutionsLoading,
153
- solutionsError,
154
- selectedSolutionIds,
155
- updateSelectedSolutions,
156
-
157
- // Entities
158
- entities,
159
- entitiesLoading,
160
- entitiesError,
161
- };
162
- }
@@ -1,87 +0,0 @@
1
- /**
2
- * Debug utility for conditional logging
3
- * Set flags to true to enable logging for specific features
4
- */
5
-
6
- // Feature flags for debugging
7
- const DEBUG_FLAGS = {
8
- treeExpansion: false, // Tree auto-expansion when nodes are selected
9
- relationshipPicker: false, // Relationship picker loading and selection
10
- linkEntityEditor: false, // Link entity editor behavior
11
- propertiesPanel: false, // Properties panel parent entity resolution
12
- metadataAPI: true, // Metadata API calls and responses
13
- fetchXmlAPI: true, // FetchXML query execution and results
14
- publisherAPI: true, // Publisher API calls
15
- solutionAPI: true, // Solution API calls
16
- solutionComponentAPI: true, // Solution component API calls
17
- viewAPI: true, // View (savedquery/userquery) API calls
18
- exportAPI: true, // Export to Excel API calls
19
- recordAPI: true, // Record CRUD operations
20
- workflowAPI: true, // Workflow execution
21
- } as const;
22
-
23
- type DebugCategory = keyof typeof DEBUG_FLAGS;
24
-
25
- /**
26
- * Conditional logger that only logs when the feature flag is enabled
27
- */
28
- export function debugLog(category: DebugCategory, message: string, ...args: unknown[]): void {
29
- if (DEBUG_FLAGS[category]) {
30
- console.log(`[DEBUG:${category}] ${message}`, ...args);
31
- }
32
- }
33
-
34
- /**
35
- * Conditional warning logger
36
- */
37
- export function debugWarn(category: DebugCategory, message: string, ...args: unknown[]): void {
38
- if (DEBUG_FLAGS[category]) {
39
- console.warn(`[DEBUG:${category}] ${message}`, ...args);
40
- }
41
- }
42
-
43
- /**
44
- * Enable debugging for a specific category
45
- * Usage: enableDebug('treeExpansion')
46
- */
47
- export function enableDebug(category: DebugCategory): void {
48
- (DEBUG_FLAGS as Record<string, boolean>)[category] = true;
49
- console.log(`✅ Debug enabled for: ${category}`);
50
- }
51
-
52
- /**
53
- * Disable debugging for a specific category
54
- */
55
- export function disableDebug(category: DebugCategory): void {
56
- (DEBUG_FLAGS as Record<string, boolean>)[category] = false;
57
- console.log(`❌ Debug disabled for: ${category}`);
58
- }
59
-
60
- /**
61
- * Enable all debugging
62
- * Usage (in browser console): window.enableAllDebug()
63
- */
64
- export function enableAllDebug(): void {
65
- Object.keys(DEBUG_FLAGS).forEach((key) => {
66
- (DEBUG_FLAGS as Record<string, boolean>)[key] = true;
67
- });
68
- console.log("✅ All debugging enabled");
69
- }
70
-
71
- /**
72
- * Disable all debugging
73
- */
74
- export function disableAllDebug(): void {
75
- Object.keys(DEBUG_FLAGS).forEach((key) => {
76
- (DEBUG_FLAGS as Record<string, boolean>)[key] = false;
77
- });
78
- console.log("❌ All debugging disabled");
79
- }
80
-
81
- // Expose to window for easy access in browser console
82
- if (typeof window !== "undefined") {
83
- (window as unknown as Record<string, unknown>).enableDebug = enableDebug;
84
- (window as unknown as Record<string, unknown>).disableDebug = disableDebug;
85
- (window as unknown as Record<string, unknown>).enableAllDebug = enableAllDebug;
86
- (window as unknown as Record<string, unknown>).disableAllDebug = disableAllDebug;
87
- }
package/tsconfig.app.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
- "target": "ES2022",
5
- "useDefineForClassFields": true,
6
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
- "module": "ESNext",
8
- "types": ["vite/client"],
9
- "skipLibCheck": true,
10
-
11
- /* Bundler mode */
12
- "moduleResolution": "bundler",
13
- "allowImportingTsExtensions": true,
14
- "verbatimModuleSyntax": true,
15
- "moduleDetection": "force",
16
- "noEmit": true,
17
- "jsx": "react-jsx",
18
-
19
- /* Linting */
20
- "strict": true,
21
- "noUnusedLocals": true,
22
- "noUnusedParameters": true,
23
- "erasableSyntaxOnly": true,
24
- "noFallthroughCasesInSwitch": true,
25
- "noUncheckedSideEffectImports": true
26
- },
27
- "include": ["src"]
28
- }
package/tsconfig.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "files": [],
3
- "references": [
4
- { "path": "./tsconfig.app.json" },
5
- { "path": "./tsconfig.node.json" }
6
- ]
7
- }
@@ -1,26 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
- "target": "ES2023",
5
- "lib": ["ES2023"],
6
- "module": "ESNext",
7
- "types": ["node"],
8
- "skipLibCheck": true,
9
-
10
- /* Bundler mode */
11
- "moduleResolution": "bundler",
12
- "allowImportingTsExtensions": true,
13
- "verbatimModuleSyntax": true,
14
- "moduleDetection": "force",
15
- "noEmit": true,
16
-
17
- /* Linting */
18
- "strict": true,
19
- "noUnusedLocals": true,
20
- "noUnusedParameters": true,
21
- "erasableSyntaxOnly": true,
22
- "noFallthroughCasesInSwitch": true,
23
- "noUncheckedSideEffectImports": true
24
- },
25
- "include": ["vite.config.ts"]
26
- }
package/vite.config.ts DELETED
@@ -1,7 +0,0 @@
1
- import { defineConfig } from "vite";
2
- import react from "@vitejs/plugin-react";
3
-
4
- // https://vite.dev/config/
5
- export default defineConfig({
6
- plugins: [react()],
7
- });