@fgv/ts-res-ui-components 5.0.0-10

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 (231) hide show
  1. package/.rush/temp/03c8b056281d9db0a97d8a6e25eea798a160d393.tar.log +271 -0
  2. package/.rush/temp/chunked-rush-logs/ts-res-ui-components.build.chunks.jsonl +9 -0
  3. package/.rush/temp/operation/build/all.log +9 -0
  4. package/.rush/temp/operation/build/log-chunks.jsonl +9 -0
  5. package/.rush/temp/operation/build/state.json +3 -0
  6. package/.rush/temp/shrinkwrap-deps.json +1111 -0
  7. package/README.md +18 -0
  8. package/REFACTORING_PLAN.md +171 -0
  9. package/config/jest.config.json +16 -0
  10. package/config/jest.setup.js +64 -0
  11. package/config/rig.json +16 -0
  12. package/lib/components/common/QualifierContextControl.d.ts +14 -0
  13. package/lib/components/common/QualifierContextControl.d.ts.map +1 -0
  14. package/lib/components/common/QualifierContextControl.js +78 -0
  15. package/lib/components/common/QualifierContextControl.js.map +1 -0
  16. package/lib/components/common/ResourceListView.d.ts +11 -0
  17. package/lib/components/common/ResourceListView.d.ts.map +1 -0
  18. package/lib/components/common/ResourceListView.js +20 -0
  19. package/lib/components/common/ResourceListView.js.map +1 -0
  20. package/lib/components/common/ResourceTreeView.d.ts +12 -0
  21. package/lib/components/common/ResourceTreeView.d.ts.map +1 -0
  22. package/lib/components/common/ResourceTreeView.js +162 -0
  23. package/lib/components/common/ResourceTreeView.js.map +1 -0
  24. package/lib/components/forms/HierarchyEditor.d.ts +10 -0
  25. package/lib/components/forms/HierarchyEditor.d.ts.map +1 -0
  26. package/lib/components/forms/HierarchyEditor.js +106 -0
  27. package/lib/components/forms/HierarchyEditor.js.map +1 -0
  28. package/lib/components/forms/QualifierEditForm.d.ts +11 -0
  29. package/lib/components/forms/QualifierEditForm.d.ts.map +1 -0
  30. package/lib/components/forms/QualifierEditForm.js +181 -0
  31. package/lib/components/forms/QualifierEditForm.js.map +1 -0
  32. package/lib/components/forms/QualifierTypeEditForm.d.ts +10 -0
  33. package/lib/components/forms/QualifierTypeEditForm.d.ts.map +1 -0
  34. package/lib/components/forms/QualifierTypeEditForm.js +172 -0
  35. package/lib/components/forms/QualifierTypeEditForm.js.map +1 -0
  36. package/lib/components/forms/ResourceTypeEditForm.d.ts +10 -0
  37. package/lib/components/forms/ResourceTypeEditForm.d.ts.map +1 -0
  38. package/lib/components/forms/ResourceTypeEditForm.js +188 -0
  39. package/lib/components/forms/ResourceTypeEditForm.js.map +1 -0
  40. package/lib/components/forms/index.d.ts +9 -0
  41. package/lib/components/forms/index.d.ts.map +1 -0
  42. package/lib/components/forms/index.js +5 -0
  43. package/lib/components/forms/index.js.map +1 -0
  44. package/lib/components/orchestrator/ResourceOrchestrator.d.ts +14 -0
  45. package/lib/components/orchestrator/ResourceOrchestrator.d.ts.map +1 -0
  46. package/lib/components/orchestrator/ResourceOrchestrator.js +278 -0
  47. package/lib/components/orchestrator/ResourceOrchestrator.js.map +1 -0
  48. package/lib/components/views/CompiledView/index.d.ts +5 -0
  49. package/lib/components/views/CompiledView/index.d.ts.map +1 -0
  50. package/lib/components/views/CompiledView/index.js +595 -0
  51. package/lib/components/views/CompiledView/index.js.map +1 -0
  52. package/lib/components/views/ConfigurationView/index.d.ts +5 -0
  53. package/lib/components/views/ConfigurationView/index.d.ts.map +1 -0
  54. package/lib/components/views/ConfigurationView/index.js +363 -0
  55. package/lib/components/views/ConfigurationView/index.js.map +1 -0
  56. package/lib/components/views/FilterView/index.d.ts +5 -0
  57. package/lib/components/views/FilterView/index.d.ts.map +1 -0
  58. package/lib/components/views/FilterView/index.js +463 -0
  59. package/lib/components/views/FilterView/index.js.map +1 -0
  60. package/lib/components/views/ImportView/index.d.ts +5 -0
  61. package/lib/components/views/ImportView/index.d.ts.map +1 -0
  62. package/lib/components/views/ImportView/index.js +514 -0
  63. package/lib/components/views/ImportView/index.js.map +1 -0
  64. package/lib/components/views/ResolutionView/EditableJsonView.d.ts +21 -0
  65. package/lib/components/views/ResolutionView/EditableJsonView.d.ts.map +1 -0
  66. package/lib/components/views/ResolutionView/EditableJsonView.js +109 -0
  67. package/lib/components/views/ResolutionView/EditableJsonView.js.map +1 -0
  68. package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts +19 -0
  69. package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts.map +1 -0
  70. package/lib/components/views/ResolutionView/ResolutionEditControls.js +82 -0
  71. package/lib/components/views/ResolutionView/ResolutionEditControls.js.map +1 -0
  72. package/lib/components/views/ResolutionView/index.d.ts +5 -0
  73. package/lib/components/views/ResolutionView/index.d.ts.map +1 -0
  74. package/lib/components/views/ResolutionView/index.js +255 -0
  75. package/lib/components/views/ResolutionView/index.js.map +1 -0
  76. package/lib/components/views/SourceView/index.d.ts +5 -0
  77. package/lib/components/views/SourceView/index.d.ts.map +1 -0
  78. package/lib/components/views/SourceView/index.js +316 -0
  79. package/lib/components/views/SourceView/index.js.map +1 -0
  80. package/lib/components/views/ZipLoaderView/index.d.ts +5 -0
  81. package/lib/components/views/ZipLoaderView/index.d.ts.map +1 -0
  82. package/lib/components/views/ZipLoaderView/index.js +313 -0
  83. package/lib/components/views/ZipLoaderView/index.js.map +1 -0
  84. package/lib/hooks/useConfigurationState.d.ts +46 -0
  85. package/lib/hooks/useConfigurationState.d.ts.map +1 -0
  86. package/lib/hooks/useConfigurationState.js +239 -0
  87. package/lib/hooks/useConfigurationState.js.map +1 -0
  88. package/lib/hooks/useFilterState.d.ts +7 -0
  89. package/lib/hooks/useFilterState.d.ts.map +1 -0
  90. package/lib/hooks/useFilterState.js +80 -0
  91. package/lib/hooks/useFilterState.js.map +1 -0
  92. package/lib/hooks/useResolutionState.d.ts +8 -0
  93. package/lib/hooks/useResolutionState.d.ts.map +1 -0
  94. package/lib/hooks/useResolutionState.js +253 -0
  95. package/lib/hooks/useResolutionState.js.map +1 -0
  96. package/lib/hooks/useResourceData.d.ts +19 -0
  97. package/lib/hooks/useResourceData.d.ts.map +1 -0
  98. package/lib/hooks/useResourceData.js +368 -0
  99. package/lib/hooks/useResourceData.js.map +1 -0
  100. package/lib/hooks/useViewState.d.ts +10 -0
  101. package/lib/hooks/useViewState.d.ts.map +1 -0
  102. package/lib/hooks/useViewState.js +29 -0
  103. package/lib/hooks/useViewState.js.map +1 -0
  104. package/lib/index.d.ts +27 -0
  105. package/lib/index.d.ts.map +1 -0
  106. package/lib/index.js +34 -0
  107. package/lib/index.js.map +1 -0
  108. package/lib/test/helpers/testDataLoader.d.ts +37 -0
  109. package/lib/test/helpers/testDataLoader.d.ts.map +1 -0
  110. package/lib/test/helpers/testDataLoader.js +171 -0
  111. package/lib/test/helpers/testDataLoader.js.map +1 -0
  112. package/lib/test/unit/utils/configurationUtils.test.d.ts +2 -0
  113. package/lib/test/unit/utils/configurationUtils.test.d.ts.map +1 -0
  114. package/lib/test/unit/utils/configurationUtils.test.js +497 -0
  115. package/lib/test/unit/utils/configurationUtils.test.js.map +1 -0
  116. package/lib/test/unit/utils/fileProcessing.test.d.ts +2 -0
  117. package/lib/test/unit/utils/fileProcessing.test.d.ts.map +1 -0
  118. package/lib/test/unit/utils/fileProcessing.test.js +321 -0
  119. package/lib/test/unit/utils/fileProcessing.test.js.map +1 -0
  120. package/lib/test/unit/utils/filterResources.test.d.ts +2 -0
  121. package/lib/test/unit/utils/filterResources.test.d.ts.map +1 -0
  122. package/lib/test/unit/utils/filterResources.test.js +403 -0
  123. package/lib/test/unit/utils/filterResources.test.js.map +1 -0
  124. package/lib/test/unit/utils/resolutionEditing.test.d.ts +2 -0
  125. package/lib/test/unit/utils/resolutionEditing.test.d.ts.map +1 -0
  126. package/lib/test/unit/utils/resolutionEditing.test.js +439 -0
  127. package/lib/test/unit/utils/resolutionEditing.test.js.map +1 -0
  128. package/lib/test/unit/utils/resolutionUtils.test.d.ts +2 -0
  129. package/lib/test/unit/utils/resolutionUtils.test.d.ts.map +1 -0
  130. package/lib/test/unit/utils/resolutionUtils.test.js +397 -0
  131. package/lib/test/unit/utils/resolutionUtils.test.js.map +1 -0
  132. package/lib/test/unit/utils/tsResIntegration.test.d.ts +2 -0
  133. package/lib/test/unit/utils/tsResIntegration.test.d.ts.map +1 -0
  134. package/lib/test/unit/utils/tsResIntegration.test.js +376 -0
  135. package/lib/test/unit/utils/tsResIntegration.test.js.map +1 -0
  136. package/lib/types/index.d.ts +251 -0
  137. package/lib/types/index.d.ts.map +1 -0
  138. package/lib/types/index.js +2 -0
  139. package/lib/types/index.js.map +1 -0
  140. package/lib/utils/configurationUtils.d.ts +74 -0
  141. package/lib/utils/configurationUtils.d.ts.map +1 -0
  142. package/lib/utils/configurationUtils.js +359 -0
  143. package/lib/utils/configurationUtils.js.map +1 -0
  144. package/lib/utils/fileProcessing.d.ts +18 -0
  145. package/lib/utils/fileProcessing.d.ts.map +1 -0
  146. package/lib/utils/fileProcessing.js +142 -0
  147. package/lib/utils/fileProcessing.js.map +1 -0
  148. package/lib/utils/filterResources.d.ts +38 -0
  149. package/lib/utils/filterResources.d.ts.map +1 -0
  150. package/lib/utils/filterResources.js +153 -0
  151. package/lib/utils/filterResources.js.map +1 -0
  152. package/lib/utils/resolutionEditing.d.ts +58 -0
  153. package/lib/utils/resolutionEditing.d.ts.map +1 -0
  154. package/lib/utils/resolutionEditing.js +246 -0
  155. package/lib/utils/resolutionEditing.js.map +1 -0
  156. package/lib/utils/resolutionUtils.d.ts +28 -0
  157. package/lib/utils/resolutionUtils.d.ts.map +1 -0
  158. package/lib/utils/resolutionUtils.js +216 -0
  159. package/lib/utils/resolutionUtils.js.map +1 -0
  160. package/lib/utils/tsResIntegration.d.ts +71 -0
  161. package/lib/utils/tsResIntegration.d.ts.map +1 -0
  162. package/lib/utils/tsResIntegration.js +294 -0
  163. package/lib/utils/tsResIntegration.js.map +1 -0
  164. package/lib/utils/zipLoader/browserZipLoader.d.ts +48 -0
  165. package/lib/utils/zipLoader/browserZipLoader.d.ts.map +1 -0
  166. package/lib/utils/zipLoader/browserZipLoader.js +247 -0
  167. package/lib/utils/zipLoader/browserZipLoader.js.map +1 -0
  168. package/lib/utils/zipLoader/index.d.ts +8 -0
  169. package/lib/utils/zipLoader/index.d.ts.map +1 -0
  170. package/lib/utils/zipLoader/index.js +13 -0
  171. package/lib/utils/zipLoader/index.js.map +1 -0
  172. package/lib/utils/zipLoader/nodeZipBuilder.d.ts +55 -0
  173. package/lib/utils/zipLoader/nodeZipBuilder.d.ts.map +1 -0
  174. package/lib/utils/zipLoader/nodeZipBuilder.js +98 -0
  175. package/lib/utils/zipLoader/nodeZipBuilder.js.map +1 -0
  176. package/lib/utils/zipLoader/types.d.ts +139 -0
  177. package/lib/utils/zipLoader/types.d.ts.map +1 -0
  178. package/lib/utils/zipLoader/types.js +2 -0
  179. package/lib/utils/zipLoader/types.js.map +1 -0
  180. package/lib/utils/zipLoader/zipUtils.d.ts +53 -0
  181. package/lib/utils/zipLoader/zipUtils.d.ts.map +1 -0
  182. package/lib/utils/zipLoader/zipUtils.js +229 -0
  183. package/lib/utils/zipLoader/zipUtils.js.map +1 -0
  184. package/package.json +69 -0
  185. package/rush-logs/ts-res-ui-components.build.cache.log +3 -0
  186. package/rush-logs/ts-res-ui-components.build.log +9 -0
  187. package/src/components/common/QualifierContextControl.tsx +151 -0
  188. package/src/components/common/ResourceListView.tsx +63 -0
  189. package/src/components/common/ResourceTreeView.tsx +271 -0
  190. package/src/components/forms/HierarchyEditor.tsx +204 -0
  191. package/src/components/forms/QualifierEditForm.tsx +355 -0
  192. package/src/components/forms/QualifierTypeEditForm.tsx +347 -0
  193. package/src/components/forms/ResourceTypeEditForm.tsx +331 -0
  194. package/src/components/forms/index.ts +11 -0
  195. package/src/components/orchestrator/ResourceOrchestrator.tsx +372 -0
  196. package/src/components/views/CompiledView/index.tsx +922 -0
  197. package/src/components/views/ConfigurationView/index.tsx +800 -0
  198. package/src/components/views/FilterView/index.tsx +825 -0
  199. package/src/components/views/ImportView/index.tsx +717 -0
  200. package/src/components/views/ResolutionView/EditableJsonView.tsx +214 -0
  201. package/src/components/views/ResolutionView/ResolutionEditControls.tsx +170 -0
  202. package/src/components/views/ResolutionView/index.tsx +591 -0
  203. package/src/components/views/SourceView/index.tsx +536 -0
  204. package/src/components/views/ZipLoaderView/index.tsx +485 -0
  205. package/src/hooks/useConfigurationState.ts +374 -0
  206. package/src/hooks/useFilterState.ts +97 -0
  207. package/src/hooks/useResolutionState.ts +355 -0
  208. package/src/hooks/useResourceData.ts +467 -0
  209. package/src/hooks/useViewState.ts +44 -0
  210. package/src/index.ts +45 -0
  211. package/src/test/helpers/testDataLoader.ts +195 -0
  212. package/src/test/unit/utils/configurationUtils.test.ts +630 -0
  213. package/src/test/unit/utils/fileProcessing.test.ts +391 -0
  214. package/src/test/unit/utils/filterResources.test.ts +574 -0
  215. package/src/test/unit/utils/resolutionEditing.test.ts +556 -0
  216. package/src/test/unit/utils/resolutionUtils.test.ts +521 -0
  217. package/src/test/unit/utils/tsResIntegration.test.ts +433 -0
  218. package/src/types/index.ts +322 -0
  219. package/src/utils/configurationUtils.ts +424 -0
  220. package/src/utils/fileProcessing.ts +160 -0
  221. package/src/utils/filterResources.ts +206 -0
  222. package/src/utils/resolutionEditing.ts +319 -0
  223. package/src/utils/resolutionUtils.ts +289 -0
  224. package/src/utils/tsResIntegration.ts +440 -0
  225. package/src/utils/zipLoader/browserZipLoader.ts +319 -0
  226. package/src/utils/zipLoader/index.ts +26 -0
  227. package/src/utils/zipLoader/nodeZipBuilder.ts +153 -0
  228. package/src/utils/zipLoader/types.ts +175 -0
  229. package/src/utils/zipLoader/zipUtils.ts +266 -0
  230. package/temp/build/typescript/ts_gZid87Hu.json +1 -0
  231. package/tsconfig.json +15 -0
@@ -0,0 +1,372 @@
1
+ import React, { ReactNode, useCallback, useMemo, useState } from 'react';
2
+ import { Result } from '@fgv/ts-utils';
3
+ import { Config, Bundle } from '@fgv/ts-res';
4
+ import {
5
+ OrchestratorState,
6
+ OrchestratorActions,
7
+ ImportedDirectory,
8
+ ImportedFile,
9
+ ProcessedResources,
10
+ FilterState,
11
+ FilterResult,
12
+ Message
13
+ } from '../../types';
14
+ import { useResourceData } from '../../hooks/useResourceData';
15
+ import { useFilterState } from '../../hooks/useFilterState';
16
+ import { useViewState } from '../../hooks/useViewState';
17
+ import { useResolutionState } from '../../hooks/useResolutionState';
18
+ import { createSimpleContext } from '../../utils/tsResIntegration';
19
+ import {
20
+ createFilteredResourceManagerSimple,
21
+ analyzeFilteredResources,
22
+ hasFilterValues,
23
+ FilterResult as FilterUtilResult
24
+ } from '../../utils/filterResources';
25
+ import { Runtime } from '@fgv/ts-res';
26
+
27
+ export interface ResourceOrchestratorProps {
28
+ children: (orchestrator: { state: OrchestratorState; actions: OrchestratorActions }) => ReactNode;
29
+ initialConfiguration?: Config.Model.ISystemConfiguration;
30
+ onStateChange?: (state: Partial<OrchestratorState>) => void;
31
+ }
32
+
33
+ export const ResourceOrchestrator: React.FC<ResourceOrchestratorProps> = ({
34
+ children,
35
+ initialConfiguration,
36
+ onStateChange
37
+ }) => {
38
+ // Core hooks
39
+ const resourceData = useResourceData();
40
+ const filterState = useFilterState();
41
+ const viewState = useViewState();
42
+ // System update handler for resolution editing
43
+ const handleSystemUpdate = useCallback(
44
+ (updatedResources: ProcessedResources) => {
45
+ resourceData.actions.updateProcessedResources(updatedResources);
46
+ viewState.addMessage('success', 'Resource system updated with edits');
47
+ },
48
+ [resourceData.actions, viewState]
49
+ );
50
+
51
+ const resolutionData = useResolutionState(
52
+ resourceData.state.processedResources,
53
+ viewState.addMessage,
54
+ handleSystemUpdate
55
+ );
56
+
57
+ // Local state for filter results
58
+ const [filterResult, setFilterResult] = useState<FilterResult | null>(null);
59
+
60
+ // Track if filtering is in progress to prevent concurrent operations
61
+ const isFilteringInProgress = React.useRef(false);
62
+
63
+ // Initialize with configuration if provided
64
+ React.useEffect(() => {
65
+ if (initialConfiguration && !resourceData.state.activeConfiguration) {
66
+ resourceData.actions.applyConfiguration(initialConfiguration);
67
+ }
68
+ }, [initialConfiguration, resourceData.state.activeConfiguration, resourceData.actions]);
69
+
70
+ // Notify parent of state changes
71
+ React.useEffect(() => {
72
+ if (onStateChange) {
73
+ onStateChange({
74
+ resources: resourceData.state.processedResources,
75
+ configuration: resourceData.state.activeConfiguration,
76
+ filterState: filterState.state,
77
+ filterResult,
78
+ selectedResourceId: viewState.selectedResourceId,
79
+ isProcessing: resourceData.state.isProcessing,
80
+ error: resourceData.state.error,
81
+ messages: viewState.messages
82
+ });
83
+ }
84
+ }, [
85
+ resourceData.state,
86
+ filterState.state,
87
+ filterResult,
88
+ viewState.selectedResourceId,
89
+ viewState.messages,
90
+ onStateChange
91
+ ]);
92
+
93
+ // Internal filtering logic (used by both manual and automatic application)
94
+ const performFiltering = useCallback(
95
+ async (filterValues: Record<string, string | undefined>): Promise<FilterResult | null> => {
96
+ // Prevent concurrent filtering operations
97
+ if (isFilteringInProgress.current) {
98
+ console.log('Filtering already in progress, skipping...');
99
+ return null;
100
+ }
101
+
102
+ if (!resourceData.state.processedResources || !filterState.state.enabled) {
103
+ setFilterResult(null);
104
+ return null;
105
+ }
106
+
107
+ // Check if we have any filter values to work with
108
+ const hasFilterValues = Object.values(filterValues).some(
109
+ (value) => value !== undefined && value !== ''
110
+ );
111
+ if (!hasFilterValues) {
112
+ setFilterResult(null);
113
+ return null;
114
+ }
115
+
116
+ isFilteringInProgress.current = true;
117
+
118
+ try {
119
+ const { system } = resourceData.state.processedResources;
120
+
121
+ viewState.addMessage('info', 'Starting filtering process...');
122
+ console.log('Filtering with values:', filterValues);
123
+ console.log('Filter state:', filterState.state);
124
+
125
+ // Try the simplified filtering approach using provided values
126
+ let filteredResult = await createFilteredResourceManagerSimple(system, filterValues, {
127
+ partialContextMatch: true,
128
+ enableDebugLogging: true, // Enable debug logging to see what's happening
129
+ reduceQualifiers: filterState.state.reduceQualifiers
130
+ });
131
+
132
+ if (filteredResult.isFailure()) {
133
+ const result: FilterResult = {
134
+ success: false,
135
+ error: `Filtering failed: ${filteredResult.message}`
136
+ };
137
+ setFilterResult(result);
138
+ viewState.addMessage('error', `Filtering failed: ${filteredResult.message}`);
139
+ return result;
140
+ }
141
+
142
+ // Analyze filtered resources compared to original
143
+ const originalResources = resourceData.state.processedResources.summary.resourceIds || [];
144
+ console.log('Original resources count:', originalResources.length);
145
+
146
+ const analysis = analyzeFilteredResources(
147
+ originalResources,
148
+ filteredResult.value,
149
+ resourceData.state.processedResources
150
+ );
151
+
152
+ console.log('Analysis result:', {
153
+ success: analysis.success,
154
+ filteredResourcesCount: analysis.filteredResources.length,
155
+ warningsCount: analysis.warnings.length,
156
+ hasProcessedResources: !!analysis.processedResources
157
+ });
158
+
159
+ console.log(
160
+ 'Filtered resources breakdown:',
161
+ analysis.filteredResources.map((r) => ({
162
+ id: r.id,
163
+ originalCandidates: r.originalCandidateCount,
164
+ filteredCandidates: r.filteredCandidateCount,
165
+ reduction: r.originalCandidateCount - r.filteredCandidateCount,
166
+ hasWarning: r.hasWarning
167
+ }))
168
+ );
169
+
170
+ const result: FilterResult = {
171
+ success: true,
172
+ processedResources: analysis.processedResources,
173
+ filteredResources: analysis.filteredResources,
174
+ warnings: analysis.warnings
175
+ };
176
+
177
+ console.log('Setting filter result:', result);
178
+ setFilterResult(result);
179
+
180
+ if (analysis.warnings.length > 0) {
181
+ viewState.addMessage('warning', `Filtering completed with ${analysis.warnings.length} warning(s)`);
182
+ } else {
183
+ viewState.addMessage(
184
+ 'success',
185
+ `Filtering completed: ${analysis.filteredResources.length} resources`
186
+ );
187
+ }
188
+
189
+ return result;
190
+ } catch (error) {
191
+ const errorMessage = error instanceof Error ? error.message : String(error);
192
+ const result: FilterResult = {
193
+ success: false,
194
+ error: errorMessage
195
+ };
196
+ setFilterResult(result);
197
+ viewState.addMessage('error', `Filtering error: ${errorMessage}`);
198
+ return result;
199
+ } finally {
200
+ isFilteringInProgress.current = false;
201
+ }
202
+ },
203
+ [resourceData.state.processedResources, filterState.state, viewState]
204
+ );
205
+
206
+ // Manual apply filter action (for the Apply button)
207
+ const applyFilter = useCallback(async (): Promise<FilterResult | null> => {
208
+ // Capture the current values before applying them
209
+ const currentValues = { ...filterState.state.values };
210
+
211
+ // First apply the pending values to make them the applied values
212
+ filterState.actions.applyFilterValues();
213
+
214
+ // Then perform filtering with the captured values
215
+ const result = await performFiltering(currentValues);
216
+
217
+ return result;
218
+ }, [performFiltering, filterState.actions]);
219
+
220
+ // Reset filter action
221
+ const resetFilter = useCallback(() => {
222
+ setFilterResult(null);
223
+ filterState.actions.resetFilterValues();
224
+ viewState.addMessage('info', 'Filter reset');
225
+ }, [filterState.actions, viewState]);
226
+
227
+ // Automatically apply filter when applied filter values change
228
+ // TEMPORARILY DISABLED to fix responsiveness issue
229
+ // React.useEffect(() => {
230
+ // if (!resourceData.state.processedResources || !filterState.state.enabled) {
231
+ // setFilterResult(null);
232
+ // return;
233
+ // }
234
+
235
+ // const hasAppliedFilterValues = hasFilterValues(filterState.state.appliedValues);
236
+ // if (!hasAppliedFilterValues) {
237
+ // setFilterResult(null);
238
+ // return;
239
+ // }
240
+
241
+ // // Apply filter automatically when appliedValues change using the applied values
242
+ // performFiltering(filterState.state.appliedValues);
243
+ // }, [
244
+ // filterState.state.appliedValues,
245
+ // filterState.state.enabled,
246
+ // resourceData.state.processedResources,
247
+ // performFiltering
248
+ // ]);
249
+
250
+ // Combined state
251
+ const state: OrchestratorState = useMemo(
252
+ () => ({
253
+ resources: resourceData.state.processedResources,
254
+ configuration: resourceData.state.activeConfiguration,
255
+ filterState: filterState.state,
256
+ filterResult,
257
+ resolutionState: resolutionData.state,
258
+ selectedResourceId: viewState.selectedResourceId,
259
+ isProcessing: resourceData.state.isProcessing,
260
+ error: resourceData.state.error,
261
+ messages: viewState.messages
262
+ }),
263
+ [
264
+ resourceData.state,
265
+ filterState.state,
266
+ filterResult,
267
+ resolutionData.state,
268
+ viewState.selectedResourceId,
269
+ viewState.messages
270
+ ]
271
+ );
272
+
273
+ // Combined actions
274
+ const actions: OrchestratorActions = useMemo(
275
+ () => ({
276
+ // Resource management
277
+ importDirectory: async (directory: ImportedDirectory) => {
278
+ viewState.addMessage('info', 'Importing directory...');
279
+ await resourceData.actions.processDirectory(directory);
280
+ if (!resourceData.state.error) {
281
+ viewState.addMessage('success', 'Directory imported successfully');
282
+ } else {
283
+ viewState.addMessage('error', resourceData.state.error);
284
+ }
285
+ },
286
+ importDirectoryWithConfig: async (
287
+ directory: ImportedDirectory,
288
+ config: Config.Model.ISystemConfiguration
289
+ ) => {
290
+ viewState.addMessage('info', 'Importing directory with configuration...');
291
+ await resourceData.actions.processDirectoryWithConfig(directory, config);
292
+ if (!resourceData.state.error) {
293
+ viewState.addMessage('success', 'Directory imported successfully');
294
+ } else {
295
+ viewState.addMessage('error', resourceData.state.error);
296
+ }
297
+ },
298
+ importFiles: async (files: ImportedFile[]) => {
299
+ viewState.addMessage('info', 'Importing files...');
300
+ await resourceData.actions.processFiles(files);
301
+ if (!resourceData.state.error) {
302
+ viewState.addMessage('success', 'Files imported successfully');
303
+ }
304
+ },
305
+ importBundle: async (bundle: Bundle.IBundle) => {
306
+ viewState.addMessage('info', 'Importing bundle...');
307
+ await resourceData.actions.processBundleFile(bundle);
308
+ if (!resourceData.state.error) {
309
+ viewState.addMessage('success', 'Bundle imported successfully');
310
+ }
311
+ },
312
+ clearResources: () => {
313
+ resourceData.actions.reset();
314
+ setFilterResult(null);
315
+ viewState.addMessage('info', 'Resources cleared');
316
+ },
317
+
318
+ // Configuration management
319
+ updateConfiguration: (config: Config.Model.ISystemConfiguration) => {
320
+ resourceData.actions.applyConfiguration(config);
321
+ viewState.addMessage('info', 'Configuration updated');
322
+ },
323
+ applyConfiguration: (config: Config.Model.ISystemConfiguration) => {
324
+ resourceData.actions.applyConfiguration(config);
325
+ viewState.addMessage('success', 'Configuration applied');
326
+ },
327
+
328
+ // Filter management
329
+ updateFilterState: (updates: Partial<FilterState>) => {
330
+ if (updates.enabled !== undefined) {
331
+ filterState.actions.updateFilterEnabled(updates.enabled);
332
+ }
333
+ if (updates.values !== undefined) {
334
+ filterState.actions.updateFilterValues(updates.values);
335
+ }
336
+ if (updates.reduceQualifiers !== undefined) {
337
+ filterState.actions.updateReduceQualifiers(updates.reduceQualifiers);
338
+ }
339
+ },
340
+ applyFilter,
341
+ resetFilter,
342
+
343
+ // Resolution management
344
+ updateResolutionContext: resolutionData.actions.updateContextValue,
345
+ applyResolutionContext: resolutionData.actions.applyContext,
346
+ selectResourceForResolution: resolutionData.actions.selectResource,
347
+ setResolutionViewMode: resolutionData.actions.setViewMode,
348
+ resetResolutionCache: resolutionData.actions.resetCache,
349
+
350
+ // Resolution editing actions
351
+ saveResourceEdit: resolutionData.actions.saveEdit,
352
+ getEditedValue: resolutionData.actions.getEditedValue,
353
+ hasResourceEdit: resolutionData.actions.hasEdit,
354
+ clearResourceEdits: resolutionData.actions.clearEdits,
355
+ applyResourceEdits: resolutionData.actions.applyEdits,
356
+ discardResourceEdits: resolutionData.actions.discardEdits,
357
+
358
+ // UI state management
359
+ selectResource: viewState.selectResource,
360
+ addMessage: viewState.addMessage,
361
+ clearMessages: viewState.clearMessages,
362
+
363
+ // Resource resolution
364
+ resolveResource: resourceData.actions.resolveResource
365
+ }),
366
+ [resourceData.actions, filterState.actions, resolutionData.actions, viewState, applyFilter, resetFilter]
367
+ );
368
+
369
+ return <>{children({ state, actions })}</>;
370
+ };
371
+
372
+ export default ResourceOrchestrator;