@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.
- package/LICENSE +661 -0
- package/README.md +1 -1
- 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,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
package/tsconfig.node.json
DELETED
|
@@ -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
|
-
}
|