@fgv/ts-res-ui-components 5.0.0-22 → 5.0.0-23
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/README.md +226 -175
- package/config/jest.setup.js +10 -0
- package/dist/ts-res-ui-components.d.ts +1406 -89
- package/lib/components/common/QualifierContextControl.js +4 -1
- package/lib/components/common/ResourceTreeView.js +4 -1
- package/lib/components/forms/GenericQualifierTypeEditForm.d.ts +26 -0
- package/lib/components/forms/GenericQualifierTypeEditForm.js +166 -0
- package/lib/components/forms/QualifierEditForm.d.ts +1 -1
- package/lib/components/forms/index.d.ts +2 -0
- package/lib/components/forms/index.js +1 -0
- package/lib/components/orchestrator/ResourceOrchestrator.d.ts +3 -0
- package/lib/components/orchestrator/ResourceOrchestrator.js +115 -50
- package/lib/components/pickers/ResourcePicker/ResourcePickerTree.js +6 -3
- package/lib/components/views/CompiledView/index.js +75 -16
- package/lib/components/views/ConfigurationView/index.js +94 -35
- package/lib/components/views/FilterView/index.js +7 -4
- package/lib/components/views/GridView/EditableGridCell.d.ts +76 -0
- package/lib/components/views/GridView/EditableGridCell.js +224 -0
- package/lib/components/views/GridView/GridSelector.d.ts +43 -0
- package/lib/components/views/GridView/GridSelector.js +89 -0
- package/lib/components/views/GridView/MultiGridView.d.ts +85 -0
- package/lib/components/views/GridView/MultiGridView.js +196 -0
- package/lib/components/views/GridView/ResourceGrid.d.ts +38 -0
- package/lib/components/views/GridView/ResourceGrid.js +232 -0
- package/lib/components/views/GridView/SharedContextControls.d.ts +47 -0
- package/lib/components/views/GridView/SharedContextControls.js +95 -0
- package/lib/components/views/GridView/cells/BooleanCell.d.ts +44 -0
- package/lib/components/views/GridView/cells/BooleanCell.js +49 -0
- package/lib/components/views/GridView/cells/DropdownCell.d.ts +58 -0
- package/lib/components/views/GridView/cells/DropdownCell.js +182 -0
- package/lib/components/views/GridView/cells/StringCell.d.ts +57 -0
- package/lib/components/views/GridView/cells/StringCell.js +106 -0
- package/lib/components/views/GridView/cells/TriStateCell.d.ts +54 -0
- package/lib/components/views/GridView/cells/TriStateCell.js +112 -0
- package/lib/components/views/GridView/cells/index.d.ts +15 -0
- package/lib/components/views/GridView/cells/index.js +11 -0
- package/lib/components/views/GridView/index.d.ts +53 -0
- package/lib/components/views/GridView/index.js +212 -0
- package/lib/components/views/ImportView/index.js +22 -19
- package/lib/components/views/MessagesWindow/index.js +4 -1
- package/lib/components/views/ResolutionView/index.js +7 -4
- package/lib/contexts/ObservabilityContext.d.ts +85 -0
- package/lib/contexts/ObservabilityContext.js +98 -0
- package/lib/contexts/index.d.ts +2 -0
- package/lib/contexts/index.js +24 -0
- package/lib/hooks/useConfigurationState.d.ts +3 -3
- package/lib/hooks/useResolutionState.js +15 -12
- package/lib/hooks/useResourceData.d.ts +7 -4
- package/lib/hooks/useResourceData.js +185 -184
- package/lib/index.d.ts +5 -1
- package/lib/index.js +8 -1
- package/lib/namespaces/GridTools.d.ts +136 -0
- package/lib/namespaces/GridTools.js +138 -0
- package/lib/namespaces/ObservabilityTools.d.ts +3 -0
- package/lib/namespaces/ObservabilityTools.js +23 -0
- package/lib/namespaces/index.d.ts +2 -0
- package/lib/namespaces/index.js +2 -0
- package/lib/test/integration/observability.integration.test.d.ts +2 -0
- package/lib/test/unit/hooks/useResourceData.test.d.ts +2 -0
- package/lib/test/unit/utils/downloadHelper.test.d.ts +2 -0
- package/lib/types/index.d.ts +263 -1
- package/lib/utils/cellValidation.d.ts +113 -0
- package/lib/utils/cellValidation.js +248 -0
- package/lib/utils/downloadHelper.d.ts +66 -0
- package/lib/utils/downloadHelper.js +195 -0
- package/lib/utils/observability/factories.d.ts +29 -0
- package/lib/utils/observability/factories.js +58 -0
- package/lib/utils/observability/implementations.d.ts +61 -0
- package/lib/utils/observability/implementations.js +103 -0
- package/lib/utils/observability/index.d.ts +4 -0
- package/lib/utils/observability/index.js +26 -0
- package/lib/utils/observability/interfaces.d.ts +30 -0
- package/lib/utils/observability/interfaces.js +23 -0
- package/lib/utils/resourceSelector.d.ts +97 -0
- package/lib/utils/resourceSelector.js +195 -0
- package/lib/utils/tsResIntegration.d.ts +6 -41
- package/lib/utils/tsResIntegration.js +20 -16
- package/lib/utils/zipLoader/zipProcessingHelpers.d.ts +3 -2
- package/lib/utils/zipLoader/zipProcessingHelpers.js +6 -5
- package/lib-commonjs/components/common/QualifierContextControl.js +4 -1
- package/lib-commonjs/components/common/ResourceTreeView.js +4 -1
- package/lib-commonjs/components/forms/GenericQualifierTypeEditForm.js +171 -0
- package/lib-commonjs/components/forms/index.js +3 -1
- package/lib-commonjs/components/orchestrator/ResourceOrchestrator.js +115 -50
- package/lib-commonjs/components/pickers/ResourcePicker/ResourcePickerTree.js +6 -3
- package/lib-commonjs/components/views/CompiledView/index.js +75 -16
- package/lib-commonjs/components/views/ConfigurationView/index.js +93 -34
- package/lib-commonjs/components/views/FilterView/index.js +7 -4
- package/lib-commonjs/components/views/GridView/EditableGridCell.js +232 -0
- package/lib-commonjs/components/views/GridView/GridSelector.js +94 -0
- package/lib-commonjs/components/views/GridView/MultiGridView.js +201 -0
- package/lib-commonjs/components/views/GridView/ResourceGrid.js +237 -0
- package/lib-commonjs/components/views/GridView/SharedContextControls.js +100 -0
- package/lib-commonjs/components/views/GridView/cells/BooleanCell.js +54 -0
- package/lib-commonjs/components/views/GridView/cells/DropdownCell.js +187 -0
- package/lib-commonjs/components/views/GridView/cells/StringCell.js +111 -0
- package/lib-commonjs/components/views/GridView/cells/TriStateCell.js +117 -0
- package/lib-commonjs/components/views/GridView/cells/index.js +18 -0
- package/lib-commonjs/components/views/GridView/index.js +217 -0
- package/lib-commonjs/components/views/ImportView/index.js +22 -19
- package/lib-commonjs/components/views/MessagesWindow/index.js +4 -1
- package/lib-commonjs/components/views/ResolutionView/index.js +7 -4
- package/lib-commonjs/contexts/ObservabilityContext.js +104 -0
- package/lib-commonjs/contexts/index.js +30 -0
- package/lib-commonjs/hooks/useResolutionState.js +15 -12
- package/lib-commonjs/hooks/useResourceData.js +184 -215
- package/lib-commonjs/index.js +15 -1
- package/lib-commonjs/namespaces/GridTools.js +161 -0
- package/lib-commonjs/namespaces/ObservabilityTools.js +33 -0
- package/lib-commonjs/namespaces/index.js +3 -1
- package/lib-commonjs/utils/cellValidation.js +253 -0
- package/lib-commonjs/utils/downloadHelper.js +198 -0
- package/lib-commonjs/utils/observability/factories.js +63 -0
- package/lib-commonjs/utils/observability/implementations.js +109 -0
- package/lib-commonjs/utils/observability/index.js +36 -0
- package/lib-commonjs/utils/observability/interfaces.js +24 -0
- package/lib-commonjs/utils/resourceSelector.js +200 -0
- package/lib-commonjs/utils/tsResIntegration.js +21 -16
- package/lib-commonjs/utils/zipLoader/zipProcessingHelpers.js +7 -5
- package/package.json +7 -7
- package/src/components/common/QualifierContextControl.tsx +0 -338
- package/src/components/common/ResolutionContextOptionsControl.tsx +0 -450
- package/src/components/common/ResolutionResults/index.tsx +0 -481
- package/src/components/common/ResourceListView.tsx +0 -167
- package/src/components/common/ResourcePickerOptionsControl.tsx +0 -351
- package/src/components/common/ResourceTreeView.tsx +0 -417
- package/src/components/common/SourceResourceDetail/index.tsx +0 -493
- package/src/components/forms/HierarchyEditor.tsx +0 -285
- package/src/components/forms/QualifierEditForm.tsx +0 -487
- package/src/components/forms/QualifierTypeEditForm.tsx +0 -458
- package/src/components/forms/ResourceTypeEditForm.tsx +0 -437
- package/src/components/forms/index.ts +0 -11
- package/src/components/orchestrator/ResourceOrchestrator.tsx +0 -446
- package/src/components/pickers/ResourcePicker/README.md +0 -570
- package/src/components/pickers/ResourcePicker/ResourceItem.tsx +0 -127
- package/src/components/pickers/ResourcePicker/ResourcePickerList.tsx +0 -114
- package/src/components/pickers/ResourcePicker/ResourcePickerTree.tsx +0 -481
- package/src/components/pickers/ResourcePicker/index.tsx +0 -239
- package/src/components/pickers/ResourcePicker/types.ts +0 -301
- package/src/components/pickers/ResourcePicker/utils/treeNavigation.ts +0 -210
- package/src/components/views/CompiledView/index.tsx +0 -1342
- package/src/components/views/ConfigurationView/index.tsx +0 -848
- package/src/components/views/FilterView/index.tsx +0 -681
- package/src/components/views/ImportView/index.tsx +0 -789
- package/src/components/views/MessagesWindow/index.tsx +0 -325
- package/src/components/views/ResolutionView/EditableJsonView.tsx +0 -386
- package/src/components/views/ResolutionView/NewResourceModal.tsx +0 -158
- package/src/components/views/ResolutionView/UnifiedChangeControls.tsx +0 -163
- package/src/components/views/ResolutionView/index.tsx +0 -751
- package/src/components/views/SourceView/index.tsx +0 -291
- package/src/hooks/useConfigurationState.ts +0 -436
- package/src/hooks/useFilterState.ts +0 -150
- package/src/hooks/useResolutionState.ts +0 -1690
- package/src/hooks/useResourceData.ts +0 -596
- package/src/hooks/useViewState.ts +0 -97
- package/src/index.ts +0 -68
- package/src/namespaces/ConfigurationTools.ts +0 -59
- package/src/namespaces/FilterTools.ts +0 -47
- package/src/namespaces/ImportTools.ts +0 -42
- package/src/namespaces/PickerTools.ts +0 -104
- package/src/namespaces/ResolutionTools.ts +0 -80
- package/src/namespaces/ResourceTools.ts +0 -106
- package/src/namespaces/TsResTools.ts +0 -49
- package/src/namespaces/ViewStateTools.ts +0 -91
- package/src/namespaces/ZipTools.ts +0 -49
- package/src/namespaces/index.ts +0 -49
- package/src/types/index.ts +0 -1384
- package/src/utils/configurationUtils.ts +0 -339
- package/src/utils/fileProcessing.ts +0 -164
- package/src/utils/filterResources.ts +0 -356
- package/src/utils/resolutionEditing.ts +0 -346
- package/src/utils/resolutionUtils.ts +0 -740
- package/src/utils/resourceSelectors.ts +0 -278
- package/src/utils/tsResIntegration.ts +0 -475
- package/src/utils/zipLoader/index.ts +0 -5
- package/src/utils/zipLoader/zipProcessingHelpers.ts +0 -46
- package/src/utils/zipLoader/zipUtils.ts +0 -7
package/README.md
CHANGED
|
@@ -19,20 +19,10 @@ This packlet is largely AI written, and it shows.
|
|
|
19
19
|
- **📊 Visualization**: Multiple views for exploring resource structures and compiled output
|
|
20
20
|
- **⚙️ Configuration**: Visual configuration management for qualifier types, qualifiers, and resource types
|
|
21
21
|
- **🎛️ Host Control**: Programmatic control of qualifier values and resource types
|
|
22
|
-
- **📁 File Handling**: Support for directory imports, ZIP files
|
|
22
|
+
- **📁 File Handling**: Support for directory imports, ZIP files, and bundle loading
|
|
23
|
+
- **🐛 Built-in Debugging**: Comprehensive logging and observability throughout operations
|
|
23
24
|
- **🎨 Modern UI**: Built with Tailwind CSS and Heroicons for a clean, responsive interface
|
|
24
25
|
|
|
25
|
-
### ZIP Archive Integration
|
|
26
|
-
|
|
27
|
-
This library now uses the **ts-res zip-archive packlet** as the single source of truth for all ZIP operations, providing:
|
|
28
|
-
|
|
29
|
-
- **Universal compatibility**: Works in both browser and Node.js environments using fflate
|
|
30
|
-
- **Standardized format**: Common ZIP bundle format across all ts-res tools
|
|
31
|
-
- **Simplified API**: Direct integration with ts-res ZIP archive functionality
|
|
32
|
-
- **Processing helpers**: Utilities to integrate ZIP data with ts-res-ui-components workflows
|
|
33
|
-
|
|
34
|
-
The `ImportView` component handles ZIP files automatically, and the `ZipTools` namespace provides processing helpers for custom ZIP workflows.
|
|
35
|
-
|
|
36
26
|
## Installation
|
|
37
27
|
|
|
38
28
|
```bash
|
|
@@ -56,178 +46,51 @@ This library requires the following peer dependencies:
|
|
|
56
46
|
|
|
57
47
|
## Quick Start
|
|
58
48
|
|
|
59
|
-
###
|
|
60
|
-
|
|
61
|
-
The recommended approach for programmatic resource creation:
|
|
62
|
-
|
|
63
|
-
```tsx
|
|
64
|
-
import { ResolutionTools } from '@fgv/ts-res-ui-components';
|
|
65
|
-
|
|
66
|
-
// Single atomic operation (recommended)
|
|
67
|
-
async function createResourceAtomic(actions) {
|
|
68
|
-
const result = await actions.createPendingResource({
|
|
69
|
-
id: 'platform.languages.az-AZ',
|
|
70
|
-
resourceTypeName: 'json',
|
|
71
|
-
json: { text: 'Welcome', locale: 'az-AZ' }
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
if (result.isSuccess()) {
|
|
75
|
-
console.log('Resource created successfully');
|
|
76
|
-
await actions.applyPendingResources();
|
|
77
|
-
} else {
|
|
78
|
-
console.error('Creation failed:', result.message);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Step-by-step workflow (if needed)
|
|
83
|
-
function createResourceStepByStep(actions) {
|
|
84
|
-
// 1) Start new resource
|
|
85
|
-
const startResult = actions.startNewResource({ defaultTypeName: 'json' });
|
|
86
|
-
if (!startResult.success) return;
|
|
87
|
-
|
|
88
|
-
// 2) Update resource ID
|
|
89
|
-
const idResult = actions.updateNewResourceId('platform.languages.az-AZ');
|
|
90
|
-
if (!idResult.success) return;
|
|
91
|
-
|
|
92
|
-
// 3) Select resource type (if step 1 didn't set it)
|
|
93
|
-
const typeResult = actions.selectResourceType('json');
|
|
94
|
-
if (!typeResult.success) return;
|
|
95
|
-
|
|
96
|
-
// 4) Update JSON content (optional, recommended)
|
|
97
|
-
const jsonResult = actions.updateNewResourceJson({
|
|
98
|
-
text: 'Welcome',
|
|
99
|
-
locale: 'az-AZ'
|
|
100
|
-
});
|
|
101
|
-
if (!jsonResult.success) return;
|
|
102
|
-
|
|
103
|
-
// 5) Save as pending
|
|
104
|
-
const saveResult = actions.saveNewResourceAsPending();
|
|
105
|
-
if (!saveResult.success) return;
|
|
106
|
-
|
|
107
|
-
// Note: Do NOT call saveResourceEdit for brand-new resources
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Minimal Editing App (Unified Apply)
|
|
49
|
+
### Basic Setup
|
|
112
50
|
|
|
113
51
|
```tsx
|
|
114
52
|
import React from 'react';
|
|
115
|
-
import { ResourceOrchestrator,
|
|
53
|
+
import { ResourceOrchestrator, ObservabilityProvider } from '@fgv/ts-res-ui-components';
|
|
116
54
|
|
|
117
|
-
|
|
55
|
+
function App() {
|
|
118
56
|
return (
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
resources={state.resources}
|
|
123
|
-
resolutionState={state.resolutionState}
|
|
124
|
-
resolutionActions={{
|
|
125
|
-
updateContextValue: actions.updateResolutionContext,
|
|
126
|
-
applyContext: actions.applyResolutionContext,
|
|
127
|
-
selectResource: actions.selectResourceForResolution,
|
|
128
|
-
setViewMode: actions.setResolutionViewMode,
|
|
129
|
-
resetCache: actions.resetResolutionCache,
|
|
130
|
-
saveEdit: actions.saveResourceEdit,
|
|
131
|
-
getEditedValue: actions.getEditedValue,
|
|
132
|
-
hasEdit: actions.hasResourceEdit,
|
|
133
|
-
clearEdits: actions.clearResourceEdits,
|
|
134
|
-
discardEdits: actions.discardResourceEdits,
|
|
135
|
-
// Enhanced resource creation actions with atomic API
|
|
136
|
-
createPendingResource: actions.createPendingResource,
|
|
137
|
-
startNewResource: actions.startNewResource,
|
|
138
|
-
updateNewResourceId: actions.updateNewResourceId,
|
|
139
|
-
selectResourceType: actions.selectResourceType,
|
|
140
|
-
updateNewResourceJson: actions.updateNewResourceJson,
|
|
141
|
-
saveNewResourceAsPending: actions.saveNewResourceAsPending,
|
|
142
|
-
cancelNewResource: actions.cancelNewResource,
|
|
143
|
-
removePendingResource: actions.removePendingResource,
|
|
144
|
-
markResourceForDeletion: actions.markResourceForDeletion,
|
|
145
|
-
applyPendingResources: actions.applyPendingResources,
|
|
146
|
-
discardPendingResources: actions.discardPendingResources
|
|
147
|
-
}}
|
|
148
|
-
allowResourceCreation
|
|
149
|
-
defaultResourceType="json"
|
|
150
|
-
showPendingResourcesInList
|
|
151
|
-
onMessage={actions.addMessage}
|
|
152
|
-
/>
|
|
153
|
-
)}
|
|
154
|
-
</ResourceOrchestrator>
|
|
57
|
+
<ObservabilityProvider>
|
|
58
|
+
<ResourceOrchestrator />
|
|
59
|
+
</ObservabilityProvider>
|
|
155
60
|
);
|
|
156
61
|
}
|
|
157
62
|
```
|
|
158
63
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
The `ResourceOrchestrator` component provides centralized state management for all ts-res UI functionality:
|
|
162
|
-
|
|
163
|
-
```tsx
|
|
164
|
-
import React from 'react';
|
|
165
|
-
import { ResourceOrchestrator, ImportView, SourceView } from '@fgv/ts-res-ui-components';
|
|
166
|
-
|
|
167
|
-
function App() {
|
|
168
|
-
return (
|
|
169
|
-
<ResourceOrchestrator>
|
|
170
|
-
{({ state, actions }) => (
|
|
171
|
-
<div className="min-h-screen bg-gray-50">
|
|
172
|
-
<div className="container mx-auto px-4 py-8">
|
|
173
|
-
<h1 className="text-3xl font-bold mb-8">Resource Manager</h1>
|
|
174
|
-
|
|
175
|
-
{!state.processedResources ? (
|
|
176
|
-
<ImportView
|
|
177
|
-
onImport={actions.importDirectory}
|
|
178
|
-
onBundleImport={actions.importBundle}
|
|
179
|
-
onZipImport={(zipData, config) => {
|
|
180
|
-
if (config) actions.applyConfiguration(config);
|
|
181
|
-
if (zipData.directory) actions.importDirectory(zipData.directory);
|
|
182
|
-
else if (zipData.files?.length) actions.importFiles(zipData.files);
|
|
183
|
-
}}
|
|
184
|
-
/>
|
|
185
|
-
) : (
|
|
186
|
-
<SourceView
|
|
187
|
-
resources={state.processedResources}
|
|
188
|
-
onExport={actions.exportData}
|
|
189
|
-
/>
|
|
190
|
-
)}
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
)}
|
|
194
|
-
</ResourceOrchestrator>
|
|
195
|
-
);
|
|
196
|
-
}
|
|
64
|
+
The `ResourceOrchestrator` provides a complete resource management interface with import, filtering, resolution, and editing capabilities. The `ObservabilityProvider` enables built-in logging and debugging features throughout the component tree.
|
|
197
65
|
|
|
198
|
-
|
|
199
|
-
```
|
|
66
|
+
## Core Concepts
|
|
200
67
|
|
|
201
|
-
###
|
|
68
|
+
### Resource Orchestrator
|
|
69
|
+
The central component that coordinates all resource operations. It manages the complete workflow:
|
|
202
70
|
|
|
203
|
-
|
|
71
|
+
- **Configuration Management**: Set up qualifier types, qualifiers, and resource types
|
|
72
|
+
- **Resource Import**: Load resources from files, ZIP archives, or bundles
|
|
73
|
+
- **Resource Filtering**: Filter resources by context to create deployment subsets
|
|
74
|
+
- **Resource Resolution**: Test how resources resolve for different contexts
|
|
75
|
+
- **Resource Editing**: Create and modify resources with real-time validation
|
|
204
76
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
import { useResourceData, SourceView } from '@fgv/ts-res-ui-components';
|
|
77
|
+
### Component Architecture
|
|
78
|
+
The library is organized into specialized namespaces, each containing related components and utilities:
|
|
208
79
|
|
|
209
|
-
|
|
210
|
-
|
|
80
|
+
- **FilterTools**: Resource filtering with context-aware capabilities
|
|
81
|
+
- **ResolutionTools**: Resource resolution testing and editing
|
|
82
|
+
- **ConfigurationTools**: System configuration management
|
|
83
|
+
- **GridTools**: Advanced data grid for tabular resource management
|
|
84
|
+
- **ImportTools**: File and archive import capabilities
|
|
85
|
+
- **ObservabilityTools**: Logging and debugging infrastructure
|
|
211
86
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
await actions.processFiles(importedFiles);
|
|
215
|
-
};
|
|
87
|
+
### Built-in Observability
|
|
88
|
+
All operations include comprehensive logging for debugging and user feedback:
|
|
216
89
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
{state.processedResources && (
|
|
222
|
-
<SourceView
|
|
223
|
-
resources={state.processedResources}
|
|
224
|
-
onExport={(data) => console.log('Export:', data)}
|
|
225
|
-
/>
|
|
226
|
-
)}
|
|
227
|
-
</div>
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
```
|
|
90
|
+
- **Diagnostic Logging**: Developer-focused information for troubleshooting
|
|
91
|
+
- **User Messaging**: User-friendly success/error notifications
|
|
92
|
+
- **Configurable Loggers**: Console output for development, silent for production
|
|
93
|
+
- **React Integration**: Observability context available throughout the component tree
|
|
231
94
|
|
|
232
95
|
## Architecture
|
|
233
96
|
|
|
@@ -1449,6 +1312,181 @@ All components accept a `className` prop for custom styling:
|
|
|
1449
1312
|
/>
|
|
1450
1313
|
```
|
|
1451
1314
|
|
|
1315
|
+
## Detailed Examples
|
|
1316
|
+
|
|
1317
|
+
### Canonical New Resource Flow
|
|
1318
|
+
|
|
1319
|
+
The recommended approach for programmatic resource creation:
|
|
1320
|
+
|
|
1321
|
+
```tsx
|
|
1322
|
+
import { ResolutionTools } from '@fgv/ts-res-ui-components';
|
|
1323
|
+
|
|
1324
|
+
// Single atomic operation (recommended)
|
|
1325
|
+
async function createResourceAtomic(actions) {
|
|
1326
|
+
const result = await actions.createPendingResource({
|
|
1327
|
+
id: 'platform.languages.az-AZ',
|
|
1328
|
+
resourceTypeName: 'json',
|
|
1329
|
+
json: { text: 'Welcome', locale: 'az-AZ' }
|
|
1330
|
+
});
|
|
1331
|
+
|
|
1332
|
+
if (result.isSuccess()) {
|
|
1333
|
+
console.log('Resource created successfully');
|
|
1334
|
+
await actions.applyPendingResources();
|
|
1335
|
+
} else {
|
|
1336
|
+
console.error('Creation failed:', result.message);
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
// Step-by-step workflow (if needed)
|
|
1341
|
+
function createResourceStepByStep(actions) {
|
|
1342
|
+
// 1) Start new resource
|
|
1343
|
+
const startResult = actions.startNewResource({ defaultTypeName: 'json' });
|
|
1344
|
+
if (!startResult.success) return;
|
|
1345
|
+
|
|
1346
|
+
// 2) Update resource ID
|
|
1347
|
+
const idResult = actions.updateNewResourceId('platform.languages.az-AZ');
|
|
1348
|
+
if (!idResult.success) return;
|
|
1349
|
+
|
|
1350
|
+
// 3) Select resource type (if step 1 didn't set it)
|
|
1351
|
+
const typeResult = actions.selectResourceType('json');
|
|
1352
|
+
if (!typeResult.success) return;
|
|
1353
|
+
|
|
1354
|
+
// 4) Update JSON content (optional, recommended)
|
|
1355
|
+
const jsonResult = actions.updateNewResourceJson({
|
|
1356
|
+
text: 'Welcome',
|
|
1357
|
+
locale: 'az-AZ'
|
|
1358
|
+
});
|
|
1359
|
+
if (!jsonResult.success) return;
|
|
1360
|
+
|
|
1361
|
+
// 5) Save as pending
|
|
1362
|
+
const saveResult = actions.saveNewResourceAsPending();
|
|
1363
|
+
if (!saveResult.success) return;
|
|
1364
|
+
|
|
1365
|
+
// Note: Do NOT call saveResourceEdit for brand-new resources
|
|
1366
|
+
}
|
|
1367
|
+
```
|
|
1368
|
+
|
|
1369
|
+
### Minimal Editing App (Unified Apply)
|
|
1370
|
+
|
|
1371
|
+
```tsx
|
|
1372
|
+
import React from 'react';
|
|
1373
|
+
import { ResourceOrchestrator, ResolutionView } from '@fgv/ts-res-ui-components';
|
|
1374
|
+
|
|
1375
|
+
export default function App() {
|
|
1376
|
+
return (
|
|
1377
|
+
<ResourceOrchestrator>
|
|
1378
|
+
{({ state, actions }) => (
|
|
1379
|
+
<ResolutionView
|
|
1380
|
+
resources={state.resources}
|
|
1381
|
+
resolutionState={state.resolutionState}
|
|
1382
|
+
resolutionActions={{
|
|
1383
|
+
updateContextValue: actions.updateResolutionContext,
|
|
1384
|
+
applyContext: actions.applyResolutionContext,
|
|
1385
|
+
selectResource: actions.selectResourceForResolution,
|
|
1386
|
+
setViewMode: actions.setResolutionViewMode,
|
|
1387
|
+
resetCache: actions.resetResolutionCache,
|
|
1388
|
+
saveEdit: actions.saveResourceEdit,
|
|
1389
|
+
getEditedValue: actions.getEditedValue,
|
|
1390
|
+
hasEdit: actions.hasResourceEdit,
|
|
1391
|
+
clearEdits: actions.clearResourceEdits,
|
|
1392
|
+
discardEdits: actions.discardResourceEdits,
|
|
1393
|
+
// Enhanced resource creation actions with atomic API
|
|
1394
|
+
createPendingResource: actions.createPendingResource,
|
|
1395
|
+
startNewResource: actions.startNewResource,
|
|
1396
|
+
updateNewResourceId: actions.updateNewResourceId,
|
|
1397
|
+
selectResourceType: actions.selectResourceType,
|
|
1398
|
+
updateNewResourceJson: actions.updateNewResourceJson,
|
|
1399
|
+
saveNewResourceAsPending: actions.saveNewResourceAsPending,
|
|
1400
|
+
cancelNewResource: actions.cancelNewResource,
|
|
1401
|
+
removePendingResource: actions.removePendingResource,
|
|
1402
|
+
markResourceForDeletion: actions.markResourceForDeletion,
|
|
1403
|
+
applyPendingResources: actions.applyPendingResources,
|
|
1404
|
+
discardPendingResources: actions.discardPendingResources
|
|
1405
|
+
}}
|
|
1406
|
+
allowResourceCreation
|
|
1407
|
+
defaultResourceType="json"
|
|
1408
|
+
showPendingResourcesInList
|
|
1409
|
+
onMessage={actions.addMessage}
|
|
1410
|
+
/>
|
|
1411
|
+
)}
|
|
1412
|
+
</ResourceOrchestrator>
|
|
1413
|
+
);
|
|
1414
|
+
}
|
|
1415
|
+
```
|
|
1416
|
+
|
|
1417
|
+
### Basic Usage with ResourceOrchestrator
|
|
1418
|
+
|
|
1419
|
+
The `ResourceOrchestrator` component provides centralized state management for all ts-res UI functionality:
|
|
1420
|
+
|
|
1421
|
+
```tsx
|
|
1422
|
+
import React from 'react';
|
|
1423
|
+
import { ResourceOrchestrator, ImportView, SourceView } from '@fgv/ts-res-ui-components';
|
|
1424
|
+
|
|
1425
|
+
function App() {
|
|
1426
|
+
return (
|
|
1427
|
+
<ResourceOrchestrator>
|
|
1428
|
+
{({ state, actions }) => (
|
|
1429
|
+
<div className="min-h-screen bg-gray-50">
|
|
1430
|
+
<div className="container mx-auto px-4 py-8">
|
|
1431
|
+
<h1 className="text-3xl font-bold mb-8">Resource Manager</h1>
|
|
1432
|
+
|
|
1433
|
+
{!state.processedResources ? (
|
|
1434
|
+
<ImportView
|
|
1435
|
+
onImport={actions.importDirectory}
|
|
1436
|
+
onBundleImport={actions.importBundle}
|
|
1437
|
+
onZipImport={(zipData, config) => {
|
|
1438
|
+
if (config) actions.applyConfiguration(config);
|
|
1439
|
+
if (zipData.directory) actions.importDirectory(zipData.directory);
|
|
1440
|
+
else if (zipData.files?.length) actions.importFiles(zipData.files);
|
|
1441
|
+
}}
|
|
1442
|
+
/>
|
|
1443
|
+
) : (
|
|
1444
|
+
<SourceView
|
|
1445
|
+
resources={state.processedResources}
|
|
1446
|
+
onExport={actions.exportData}
|
|
1447
|
+
/>
|
|
1448
|
+
)}
|
|
1449
|
+
</div>
|
|
1450
|
+
</div>
|
|
1451
|
+
)}
|
|
1452
|
+
</ResourceOrchestrator>
|
|
1453
|
+
);
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
export default App;
|
|
1457
|
+
```
|
|
1458
|
+
|
|
1459
|
+
### Using Individual Hooks
|
|
1460
|
+
|
|
1461
|
+
For more granular control, you can use individual hooks:
|
|
1462
|
+
|
|
1463
|
+
```tsx
|
|
1464
|
+
import React from 'react';
|
|
1465
|
+
import { useResourceData, SourceView } from '@fgv/ts-res-ui-components';
|
|
1466
|
+
|
|
1467
|
+
function MyResourceViewer() {
|
|
1468
|
+
const { state, actions } = useResourceData();
|
|
1469
|
+
|
|
1470
|
+
const handleFileImport = async (files: File[]) => {
|
|
1471
|
+
const importedFiles = await processFiles(files); // Your file processing logic
|
|
1472
|
+
await actions.processFiles(importedFiles);
|
|
1473
|
+
};
|
|
1474
|
+
|
|
1475
|
+
return (
|
|
1476
|
+
<div>
|
|
1477
|
+
{state.isProcessing && <div>Processing...</div>}
|
|
1478
|
+
{state.error && <div className="error">{state.error}</div>}
|
|
1479
|
+
{state.processedResources && (
|
|
1480
|
+
<SourceView
|
|
1481
|
+
resources={state.processedResources}
|
|
1482
|
+
onExport={(data) => console.log('Export:', data)}
|
|
1483
|
+
/>
|
|
1484
|
+
)}
|
|
1485
|
+
</div>
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1452
1490
|
## Advanced Usage
|
|
1453
1491
|
|
|
1454
1492
|
### Custom Resource Processing
|
|
@@ -1544,21 +1582,25 @@ For better organization and discoverability, utility functions are organized int
|
|
|
1544
1582
|
|
|
1545
1583
|
```tsx
|
|
1546
1584
|
import {
|
|
1547
|
-
FilterTools,
|
|
1548
|
-
ResolutionTools,
|
|
1585
|
+
FilterTools, // FilterView + filtering utilities
|
|
1586
|
+
ResolutionTools, // ResolutionView + resolution utilities
|
|
1549
1587
|
ConfigurationTools, // ConfigurationView + configuration utilities
|
|
1550
|
-
TsResTools,
|
|
1551
|
-
|
|
1552
|
-
ZipTools,
|
|
1553
|
-
|
|
1588
|
+
TsResTools, // SourceView, CompiledView + ts-res utilities
|
|
1589
|
+
ViewStateTools, // MessagesWindow + view state utilities
|
|
1590
|
+
ZipTools, // ImportView + ZIP processing helpers
|
|
1591
|
+
ObservabilityTools, // Observability context and loggers
|
|
1592
|
+
GridTools, // GridView + data grid utilities
|
|
1593
|
+
PickerTools, // ResourcePicker + picker utilities
|
|
1594
|
+
ImportTools // Import utilities and types
|
|
1554
1595
|
} from '@fgv/ts-res-ui-components';
|
|
1555
1596
|
|
|
1556
1597
|
// Use view components from namespaces
|
|
1557
1598
|
<FilterTools.FilterView {...filterProps} />
|
|
1558
1599
|
<ResolutionTools.ResolutionView {...resolutionProps} />
|
|
1559
|
-
<
|
|
1600
|
+
<ViewStateTools.MessagesWindow {...messageProps} />
|
|
1560
1601
|
<TsResTools.SourceView {...sourceProps} />
|
|
1561
1602
|
<ZipTools.ImportView {...importProps} />
|
|
1603
|
+
<GridTools.GridView {...gridProps} />
|
|
1562
1604
|
|
|
1563
1605
|
// Use utility functions from namespaces
|
|
1564
1606
|
const hasFilters = FilterTools.hasFilterValues(filterState.values);
|
|
@@ -1567,6 +1609,15 @@ const system = await TsResTools.createTsResSystemFromConfig(config);
|
|
|
1567
1609
|
|
|
1568
1610
|
// ZIP processing helpers for ts-res-ui-components integration
|
|
1569
1611
|
const processResult = await ZipTools.processZipLoadResult(zipData, config);
|
|
1612
|
+
|
|
1613
|
+
// Observability context and loggers
|
|
1614
|
+
const consoleContext = ObservabilityTools.createConsoleObservabilityContext('debug', 'info');
|
|
1615
|
+
const noOpContext = ObservabilityTools.createNoOpObservabilityContext();
|
|
1616
|
+
const customLogger = new ObservabilityTools.ConsoleUserLogger('info');
|
|
1617
|
+
|
|
1618
|
+
// Grid utilities and selectors
|
|
1619
|
+
const gridSelector = new GridTools.ResourceSelector();
|
|
1620
|
+
const validation = GridTools.validateCellValue(value, rules);
|
|
1570
1621
|
```
|
|
1571
1622
|
|
|
1572
1623
|
### Namespace Contents
|
package/config/jest.setup.js
CHANGED
|
@@ -53,6 +53,16 @@ global.URL = {
|
|
|
53
53
|
// Extend jest matchers (toBeInTheDocument, etc.)
|
|
54
54
|
require('@testing-library/jest-dom');
|
|
55
55
|
|
|
56
|
+
// Suppress console output in tests by providing a no-op logger
|
|
57
|
+
// This affects both direct console calls and components that use logger dependency injection
|
|
58
|
+
global.testLogger = () => {}; // No-op logger for tests
|
|
59
|
+
global.console = {
|
|
60
|
+
...console,
|
|
61
|
+
log: global.testLogger,
|
|
62
|
+
warn: global.testLogger,
|
|
63
|
+
error: console.error // Keep error for actual test failures
|
|
64
|
+
};
|
|
65
|
+
|
|
56
66
|
// Mock document methods for file export
|
|
57
67
|
global.document = {
|
|
58
68
|
createElement: jest.fn(() => ({
|