@fgv/ts-res-ui-components 5.0.0-21 → 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 +401 -155
- package/config/jest.setup.js +10 -0
- package/dist/ts-res-ui-components.d.ts +1657 -76
- 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 +118 -51
- package/lib/components/pickers/ResourcePicker/ResourcePickerTree.js +32 -10
- package/lib/components/pickers/ResourcePicker/index.js +4 -2
- 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 +8 -5
- 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 +850 -246
- 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/ResolutionTools.d.ts +2 -1
- package/lib/namespaces/ResolutionTools.js +2 -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/test/unit/workflows/resolutionWorkflows.test.d.ts +2 -0
- package/lib/test/unit/workflows/resourceCreation.test.d.ts +2 -0
- package/lib/test/unit/workflows/resultPatternExtensions.test.d.ts +2 -0
- package/lib/test/unit/workflows/validation.test.d.ts +2 -0
- package/lib/types/index.d.ts +387 -20
- package/lib/types/index.js +2 -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/resolutionEditing.js +2 -1
- package/lib/utils/resourceSelector.d.ts +97 -0
- package/lib/utils/resourceSelector.js +195 -0
- package/lib/utils/resourceSelectors.d.ts +146 -0
- package/lib/utils/resourceSelectors.js +233 -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 +118 -51
- package/lib-commonjs/components/pickers/ResourcePicker/ResourcePickerTree.js +32 -10
- package/lib-commonjs/components/pickers/ResourcePicker/index.js +4 -2
- 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 +8 -5
- package/lib-commonjs/contexts/ObservabilityContext.js +104 -0
- package/lib-commonjs/contexts/index.js +30 -0
- package/lib-commonjs/hooks/useResolutionState.js +849 -245
- 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/ResolutionTools.js +10 -1
- package/lib-commonjs/namespaces/index.js +3 -1
- package/lib-commonjs/types/index.js +10 -0
- 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/resolutionEditing.js +2 -1
- package/lib-commonjs/utils/resourceSelector.js +200 -0
- package/lib-commonjs/utils/resourceSelectors.js +242 -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 -444
- 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 -461
- package/src/components/pickers/ResourcePicker/index.tsx +0 -234
- 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 -893
- 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 -68
- 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 -1273
- 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/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
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Props for the HierarchyEditor component.
|
|
5
|
-
*
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export interface HierarchyEditorProps {
|
|
9
|
-
/** Current hierarchy mapping of child to parent relationships */
|
|
10
|
-
hierarchy: Record<string, string>;
|
|
11
|
-
/** Callback fired when the hierarchy is modified */
|
|
12
|
-
onChange: (hierarchy: Record<string, string>) => void;
|
|
13
|
-
/** Available values for child selection (when working with enumerated qualifier types) */
|
|
14
|
-
availableValues: string[];
|
|
15
|
-
/** Optional CSS class name for styling */
|
|
16
|
-
className?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Interactive editor for defining hierarchical relationships between qualifier values.
|
|
21
|
-
*
|
|
22
|
-
* The HierarchyEditor allows users to define parent-child relationships between qualifier values,
|
|
23
|
-
* enabling hierarchical resolution in the ts-res system. It provides an intuitive interface for
|
|
24
|
-
* creating, viewing, and managing value hierarchies with visual tree representation.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```tsx
|
|
28
|
-
* import { ConfigurationTools } from '@fgv/ts-res-ui-components';
|
|
29
|
-
*
|
|
30
|
-
* // Basic hierarchy editing for region qualifiers
|
|
31
|
-
* const [regionHierarchy, setRegionHierarchy] = useState({
|
|
32
|
-
* 'quebec': 'canada',
|
|
33
|
-
* 'ontario': 'canada',
|
|
34
|
-
* 'california': 'usa',
|
|
35
|
-
* 'texas': 'usa'
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* <ConfigurationTools.HierarchyEditor
|
|
39
|
-
* hierarchy={regionHierarchy}
|
|
40
|
-
* onChange={setRegionHierarchy}
|
|
41
|
-
* availableValues={['quebec', 'ontario', 'california', 'texas']}
|
|
42
|
-
* />
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```tsx
|
|
47
|
-
* // Hierarchy editing for language qualifiers with dynamic values
|
|
48
|
-
* const [languageHierarchy, setLanguageHierarchy] = useState({
|
|
49
|
-
* 'en-CA': 'en',
|
|
50
|
-
* 'en-US': 'en',
|
|
51
|
-
* 'fr-CA': 'fr',
|
|
52
|
-
* 'fr-FR': 'fr'
|
|
53
|
-
* });
|
|
54
|
-
*
|
|
55
|
-
* <ConfigurationTools.HierarchyEditor
|
|
56
|
-
* hierarchy={languageHierarchy}
|
|
57
|
-
* onChange={setLanguageHierarchy}
|
|
58
|
-
* availableValues={[]} // Allow free-form input
|
|
59
|
-
* className="my-hierarchy-editor"
|
|
60
|
-
* />
|
|
61
|
-
* ```
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```tsx
|
|
65
|
-
* // Integration with qualifier type configuration
|
|
66
|
-
* const QualifierTypeEditor = ({ qualifierType, onSave }) => {
|
|
67
|
-
* const [hierarchy, setHierarchy] = useState(qualifierType.hierarchy || {});
|
|
68
|
-
*
|
|
69
|
-
* const handleSave = () => {
|
|
70
|
-
* onSave({
|
|
71
|
-
* ...qualifierType,
|
|
72
|
-
* hierarchy: Object.keys(hierarchy).length > 0 ? hierarchy : undefined
|
|
73
|
-
* });
|
|
74
|
-
* };
|
|
75
|
-
*
|
|
76
|
-
* return (
|
|
77
|
-
* <div>
|
|
78
|
-
* <ConfigurationTools.HierarchyEditor
|
|
79
|
-
* hierarchy={hierarchy}
|
|
80
|
-
* onChange={setHierarchy}
|
|
81
|
-
* availableValues={qualifierType.enumeratedValues || []}
|
|
82
|
-
* />
|
|
83
|
-
* <button onClick={handleSave}>Save Qualifier Type</button>
|
|
84
|
-
* </div>
|
|
85
|
-
* );
|
|
86
|
-
* };
|
|
87
|
-
* ```
|
|
88
|
-
*
|
|
89
|
-
* @public
|
|
90
|
-
*/
|
|
91
|
-
export const HierarchyEditor: React.FC<HierarchyEditorProps> = ({
|
|
92
|
-
hierarchy,
|
|
93
|
-
onChange,
|
|
94
|
-
availableValues,
|
|
95
|
-
className = ''
|
|
96
|
-
}) => {
|
|
97
|
-
const [newChild, setNewChild] = useState('');
|
|
98
|
-
const [newParent, setNewParent] = useState('');
|
|
99
|
-
|
|
100
|
-
// Ensure hierarchy is a valid object with string values
|
|
101
|
-
const safeHierarchy = React.useMemo(() => {
|
|
102
|
-
if (!hierarchy || typeof hierarchy !== 'object') {
|
|
103
|
-
return {};
|
|
104
|
-
}
|
|
105
|
-
// Filter out any non-string values
|
|
106
|
-
const safe: Record<string, string> = {};
|
|
107
|
-
for (const [key, value] of Object.entries(hierarchy)) {
|
|
108
|
-
if (typeof value === 'string') {
|
|
109
|
-
safe[key] = value;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return safe;
|
|
113
|
-
}, [hierarchy]);
|
|
114
|
-
|
|
115
|
-
const handleAddRelationship = () => {
|
|
116
|
-
if (newChild && newParent && newChild !== newParent) {
|
|
117
|
-
const updatedHierarchy = { ...safeHierarchy, [newChild]: newParent };
|
|
118
|
-
onChange(updatedHierarchy);
|
|
119
|
-
setNewChild('');
|
|
120
|
-
setNewParent('');
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const handleRemoveRelationship = (child: string) => {
|
|
125
|
-
const updatedHierarchy = { ...safeHierarchy };
|
|
126
|
-
delete updatedHierarchy[child];
|
|
127
|
-
onChange(updatedHierarchy);
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
const getHierarchyTree = () => {
|
|
131
|
-
const roots = new Set(availableValues);
|
|
132
|
-
const children = new Set(Object.keys(safeHierarchy));
|
|
133
|
-
const parents = new Set(Object.values(safeHierarchy));
|
|
134
|
-
|
|
135
|
-
// Remove children from roots (they have parents)
|
|
136
|
-
children.forEach((child) => roots.delete(child));
|
|
137
|
-
|
|
138
|
-
// Add parents that aren't in available values (for display purposes)
|
|
139
|
-
parents.forEach((parent) => {
|
|
140
|
-
if (!availableValues.includes(parent)) {
|
|
141
|
-
roots.add(parent);
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
const buildTree = (value: string, level = 0): any => {
|
|
146
|
-
const childrenOfValue = Object.entries(safeHierarchy).filter(([, parent]) => parent === value);
|
|
147
|
-
return {
|
|
148
|
-
value,
|
|
149
|
-
level,
|
|
150
|
-
children: childrenOfValue.map(([child]) => buildTree(child, level + 1))
|
|
151
|
-
};
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
return Array.from(roots).map((root) => buildTree(root));
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const renderTree = (nodes: any[]): React.ReactNode => {
|
|
158
|
-
return nodes.map((node) => {
|
|
159
|
-
const parentValue = safeHierarchy[node.value];
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<div key={node.value} className="ml-4">
|
|
163
|
-
<div className="flex items-center space-x-2 py-1">
|
|
164
|
-
<span className="text-sm text-gray-700" style={{ marginLeft: `${node.level * 20}px` }}>
|
|
165
|
-
{node.level > 0 && '└─ '}
|
|
166
|
-
{node.value}
|
|
167
|
-
</span>
|
|
168
|
-
{parentValue && <span className="text-xs text-gray-500">→ {parentValue}</span>}
|
|
169
|
-
</div>
|
|
170
|
-
{node.children.length > 0 && renderTree(node.children)}
|
|
171
|
-
</div>
|
|
172
|
-
);
|
|
173
|
-
});
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
return (
|
|
177
|
-
<div className={className}>
|
|
178
|
-
<label className="block text-sm font-medium text-gray-700 mb-2">Value Hierarchy</label>
|
|
179
|
-
<div className="border border-gray-300 rounded-md p-3 bg-white">
|
|
180
|
-
{/* Add new relationship form */}
|
|
181
|
-
<div className="mb-4 p-3 bg-gray-50 rounded border">
|
|
182
|
-
<div className="text-sm font-medium text-gray-700 mb-2">Add Parent-Child Relationship</div>
|
|
183
|
-
<div className="grid grid-cols-3 gap-2 items-end">
|
|
184
|
-
<div>
|
|
185
|
-
<label className="block text-xs text-gray-600">Child Value</label>
|
|
186
|
-
{availableValues.length > 0 ? (
|
|
187
|
-
<select
|
|
188
|
-
value={newChild}
|
|
189
|
-
onChange={(e) => setNewChild(e.target.value)}
|
|
190
|
-
className="w-full text-sm rounded border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
|
191
|
-
>
|
|
192
|
-
<option value="">Select child...</option>
|
|
193
|
-
{availableValues.map((value) => (
|
|
194
|
-
<option key={value} value={value}>
|
|
195
|
-
{value}
|
|
196
|
-
</option>
|
|
197
|
-
))}
|
|
198
|
-
</select>
|
|
199
|
-
) : (
|
|
200
|
-
<input
|
|
201
|
-
type="text"
|
|
202
|
-
value={newChild}
|
|
203
|
-
onChange={(e) => setNewChild(e.target.value)}
|
|
204
|
-
placeholder="Enter child value"
|
|
205
|
-
className="w-full text-sm rounded border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
|
206
|
-
/>
|
|
207
|
-
)}
|
|
208
|
-
</div>
|
|
209
|
-
<div>
|
|
210
|
-
<label className="block text-xs text-gray-600">Parent Value</label>
|
|
211
|
-
<input
|
|
212
|
-
type="text"
|
|
213
|
-
value={newParent}
|
|
214
|
-
onChange={(e) => setNewParent(e.target.value)}
|
|
215
|
-
placeholder="Enter parent value"
|
|
216
|
-
className="w-full text-sm rounded border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
|
217
|
-
/>
|
|
218
|
-
</div>
|
|
219
|
-
<div>
|
|
220
|
-
<button
|
|
221
|
-
onClick={handleAddRelationship}
|
|
222
|
-
disabled={!newChild || !newParent || newChild === newParent}
|
|
223
|
-
className="w-full px-3 py-1 text-sm bg-blue-600 text-white rounded hover:bg-blue-700 disabled:bg-gray-300 disabled:cursor-not-allowed"
|
|
224
|
-
>
|
|
225
|
-
Add
|
|
226
|
-
</button>
|
|
227
|
-
</div>
|
|
228
|
-
</div>
|
|
229
|
-
<div className="text-xs text-gray-500 mt-1">
|
|
230
|
-
{availableValues.length > 0
|
|
231
|
-
? "Define which values are children of other values. The parent doesn't need to be in the enumerated values list."
|
|
232
|
-
: 'Define which values are children of other values. Enter any valid values for this qualifier type.'}
|
|
233
|
-
</div>
|
|
234
|
-
</div>
|
|
235
|
-
|
|
236
|
-
{/* Current relationships */}
|
|
237
|
-
{Object.keys(safeHierarchy).length > 0 && (
|
|
238
|
-
<div className="mb-4">
|
|
239
|
-
<div className="text-sm font-medium text-gray-700 mb-2">
|
|
240
|
-
Current Relationships ({Object.keys(safeHierarchy).length})
|
|
241
|
-
</div>
|
|
242
|
-
<div className="max-h-24 overflow-y-auto border border-gray-200 rounded bg-white p-2">
|
|
243
|
-
<div className="space-y-1">
|
|
244
|
-
{Object.entries(safeHierarchy).map(([child, parent]) => (
|
|
245
|
-
<div key={child} className="flex items-center justify-between bg-gray-50 px-2 py-1 rounded">
|
|
246
|
-
<span className="text-sm">
|
|
247
|
-
<span className="font-medium">{child}</span> →{' '}
|
|
248
|
-
<span className="text-gray-600">{parent}</span>
|
|
249
|
-
</span>
|
|
250
|
-
<button
|
|
251
|
-
onClick={() => handleRemoveRelationship(child)}
|
|
252
|
-
className="text-red-600 hover:text-red-800 text-xs ml-2 flex-shrink-0"
|
|
253
|
-
>
|
|
254
|
-
Remove
|
|
255
|
-
</button>
|
|
256
|
-
</div>
|
|
257
|
-
))}
|
|
258
|
-
</div>
|
|
259
|
-
</div>
|
|
260
|
-
</div>
|
|
261
|
-
)}
|
|
262
|
-
|
|
263
|
-
{/* Hierarchy visualization */}
|
|
264
|
-
{(availableValues.length > 0 || Object.keys(safeHierarchy).length > 0) && (
|
|
265
|
-
<div>
|
|
266
|
-
<div className="text-sm font-medium text-gray-700 mb-2">Hierarchy Tree</div>
|
|
267
|
-
<div className="bg-gray-50 border rounded max-h-32 overflow-y-auto">
|
|
268
|
-
<div className="p-2 text-sm font-mono">
|
|
269
|
-
{getHierarchyTree().length > 0 ? (
|
|
270
|
-
renderTree(getHierarchyTree())
|
|
271
|
-
) : (
|
|
272
|
-
<div className="text-gray-500 text-center py-2">
|
|
273
|
-
No hierarchy defined. Add relationships above to see the tree structure.
|
|
274
|
-
</div>
|
|
275
|
-
)}
|
|
276
|
-
</div>
|
|
277
|
-
</div>
|
|
278
|
-
</div>
|
|
279
|
-
)}
|
|
280
|
-
</div>
|
|
281
|
-
</div>
|
|
282
|
-
);
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
export default HierarchyEditor;
|