@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.
- package/.rush/temp/03c8b056281d9db0a97d8a6e25eea798a160d393.tar.log +271 -0
- package/.rush/temp/chunked-rush-logs/ts-res-ui-components.build.chunks.jsonl +9 -0
- package/.rush/temp/operation/build/all.log +9 -0
- package/.rush/temp/operation/build/log-chunks.jsonl +9 -0
- package/.rush/temp/operation/build/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +1111 -0
- package/README.md +18 -0
- package/REFACTORING_PLAN.md +171 -0
- package/config/jest.config.json +16 -0
- package/config/jest.setup.js +64 -0
- package/config/rig.json +16 -0
- package/lib/components/common/QualifierContextControl.d.ts +14 -0
- package/lib/components/common/QualifierContextControl.d.ts.map +1 -0
- package/lib/components/common/QualifierContextControl.js +78 -0
- package/lib/components/common/QualifierContextControl.js.map +1 -0
- package/lib/components/common/ResourceListView.d.ts +11 -0
- package/lib/components/common/ResourceListView.d.ts.map +1 -0
- package/lib/components/common/ResourceListView.js +20 -0
- package/lib/components/common/ResourceListView.js.map +1 -0
- package/lib/components/common/ResourceTreeView.d.ts +12 -0
- package/lib/components/common/ResourceTreeView.d.ts.map +1 -0
- package/lib/components/common/ResourceTreeView.js +162 -0
- package/lib/components/common/ResourceTreeView.js.map +1 -0
- package/lib/components/forms/HierarchyEditor.d.ts +10 -0
- package/lib/components/forms/HierarchyEditor.d.ts.map +1 -0
- package/lib/components/forms/HierarchyEditor.js +106 -0
- package/lib/components/forms/HierarchyEditor.js.map +1 -0
- package/lib/components/forms/QualifierEditForm.d.ts +11 -0
- package/lib/components/forms/QualifierEditForm.d.ts.map +1 -0
- package/lib/components/forms/QualifierEditForm.js +181 -0
- package/lib/components/forms/QualifierEditForm.js.map +1 -0
- package/lib/components/forms/QualifierTypeEditForm.d.ts +10 -0
- package/lib/components/forms/QualifierTypeEditForm.d.ts.map +1 -0
- package/lib/components/forms/QualifierTypeEditForm.js +172 -0
- package/lib/components/forms/QualifierTypeEditForm.js.map +1 -0
- package/lib/components/forms/ResourceTypeEditForm.d.ts +10 -0
- package/lib/components/forms/ResourceTypeEditForm.d.ts.map +1 -0
- package/lib/components/forms/ResourceTypeEditForm.js +188 -0
- package/lib/components/forms/ResourceTypeEditForm.js.map +1 -0
- package/lib/components/forms/index.d.ts +9 -0
- package/lib/components/forms/index.d.ts.map +1 -0
- package/lib/components/forms/index.js +5 -0
- package/lib/components/forms/index.js.map +1 -0
- package/lib/components/orchestrator/ResourceOrchestrator.d.ts +14 -0
- package/lib/components/orchestrator/ResourceOrchestrator.d.ts.map +1 -0
- package/lib/components/orchestrator/ResourceOrchestrator.js +278 -0
- package/lib/components/orchestrator/ResourceOrchestrator.js.map +1 -0
- package/lib/components/views/CompiledView/index.d.ts +5 -0
- package/lib/components/views/CompiledView/index.d.ts.map +1 -0
- package/lib/components/views/CompiledView/index.js +595 -0
- package/lib/components/views/CompiledView/index.js.map +1 -0
- package/lib/components/views/ConfigurationView/index.d.ts +5 -0
- package/lib/components/views/ConfigurationView/index.d.ts.map +1 -0
- package/lib/components/views/ConfigurationView/index.js +363 -0
- package/lib/components/views/ConfigurationView/index.js.map +1 -0
- package/lib/components/views/FilterView/index.d.ts +5 -0
- package/lib/components/views/FilterView/index.d.ts.map +1 -0
- package/lib/components/views/FilterView/index.js +463 -0
- package/lib/components/views/FilterView/index.js.map +1 -0
- package/lib/components/views/ImportView/index.d.ts +5 -0
- package/lib/components/views/ImportView/index.d.ts.map +1 -0
- package/lib/components/views/ImportView/index.js +514 -0
- package/lib/components/views/ImportView/index.js.map +1 -0
- package/lib/components/views/ResolutionView/EditableJsonView.d.ts +21 -0
- package/lib/components/views/ResolutionView/EditableJsonView.d.ts.map +1 -0
- package/lib/components/views/ResolutionView/EditableJsonView.js +109 -0
- package/lib/components/views/ResolutionView/EditableJsonView.js.map +1 -0
- package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts +19 -0
- package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts.map +1 -0
- package/lib/components/views/ResolutionView/ResolutionEditControls.js +82 -0
- package/lib/components/views/ResolutionView/ResolutionEditControls.js.map +1 -0
- package/lib/components/views/ResolutionView/index.d.ts +5 -0
- package/lib/components/views/ResolutionView/index.d.ts.map +1 -0
- package/lib/components/views/ResolutionView/index.js +255 -0
- package/lib/components/views/ResolutionView/index.js.map +1 -0
- package/lib/components/views/SourceView/index.d.ts +5 -0
- package/lib/components/views/SourceView/index.d.ts.map +1 -0
- package/lib/components/views/SourceView/index.js +316 -0
- package/lib/components/views/SourceView/index.js.map +1 -0
- package/lib/components/views/ZipLoaderView/index.d.ts +5 -0
- package/lib/components/views/ZipLoaderView/index.d.ts.map +1 -0
- package/lib/components/views/ZipLoaderView/index.js +313 -0
- package/lib/components/views/ZipLoaderView/index.js.map +1 -0
- package/lib/hooks/useConfigurationState.d.ts +46 -0
- package/lib/hooks/useConfigurationState.d.ts.map +1 -0
- package/lib/hooks/useConfigurationState.js +239 -0
- package/lib/hooks/useConfigurationState.js.map +1 -0
- package/lib/hooks/useFilterState.d.ts +7 -0
- package/lib/hooks/useFilterState.d.ts.map +1 -0
- package/lib/hooks/useFilterState.js +80 -0
- package/lib/hooks/useFilterState.js.map +1 -0
- package/lib/hooks/useResolutionState.d.ts +8 -0
- package/lib/hooks/useResolutionState.d.ts.map +1 -0
- package/lib/hooks/useResolutionState.js +253 -0
- package/lib/hooks/useResolutionState.js.map +1 -0
- package/lib/hooks/useResourceData.d.ts +19 -0
- package/lib/hooks/useResourceData.d.ts.map +1 -0
- package/lib/hooks/useResourceData.js +368 -0
- package/lib/hooks/useResourceData.js.map +1 -0
- package/lib/hooks/useViewState.d.ts +10 -0
- package/lib/hooks/useViewState.d.ts.map +1 -0
- package/lib/hooks/useViewState.js +29 -0
- package/lib/hooks/useViewState.js.map +1 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +34 -0
- package/lib/index.js.map +1 -0
- package/lib/test/helpers/testDataLoader.d.ts +37 -0
- package/lib/test/helpers/testDataLoader.d.ts.map +1 -0
- package/lib/test/helpers/testDataLoader.js +171 -0
- package/lib/test/helpers/testDataLoader.js.map +1 -0
- package/lib/test/unit/utils/configurationUtils.test.d.ts +2 -0
- package/lib/test/unit/utils/configurationUtils.test.d.ts.map +1 -0
- package/lib/test/unit/utils/configurationUtils.test.js +497 -0
- package/lib/test/unit/utils/configurationUtils.test.js.map +1 -0
- package/lib/test/unit/utils/fileProcessing.test.d.ts +2 -0
- package/lib/test/unit/utils/fileProcessing.test.d.ts.map +1 -0
- package/lib/test/unit/utils/fileProcessing.test.js +321 -0
- package/lib/test/unit/utils/fileProcessing.test.js.map +1 -0
- package/lib/test/unit/utils/filterResources.test.d.ts +2 -0
- package/lib/test/unit/utils/filterResources.test.d.ts.map +1 -0
- package/lib/test/unit/utils/filterResources.test.js +403 -0
- package/lib/test/unit/utils/filterResources.test.js.map +1 -0
- package/lib/test/unit/utils/resolutionEditing.test.d.ts +2 -0
- package/lib/test/unit/utils/resolutionEditing.test.d.ts.map +1 -0
- package/lib/test/unit/utils/resolutionEditing.test.js +439 -0
- package/lib/test/unit/utils/resolutionEditing.test.js.map +1 -0
- package/lib/test/unit/utils/resolutionUtils.test.d.ts +2 -0
- package/lib/test/unit/utils/resolutionUtils.test.d.ts.map +1 -0
- package/lib/test/unit/utils/resolutionUtils.test.js +397 -0
- package/lib/test/unit/utils/resolutionUtils.test.js.map +1 -0
- package/lib/test/unit/utils/tsResIntegration.test.d.ts +2 -0
- package/lib/test/unit/utils/tsResIntegration.test.d.ts.map +1 -0
- package/lib/test/unit/utils/tsResIntegration.test.js +376 -0
- package/lib/test/unit/utils/tsResIntegration.test.js.map +1 -0
- package/lib/types/index.d.ts +251 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +2 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils/configurationUtils.d.ts +74 -0
- package/lib/utils/configurationUtils.d.ts.map +1 -0
- package/lib/utils/configurationUtils.js +359 -0
- package/lib/utils/configurationUtils.js.map +1 -0
- package/lib/utils/fileProcessing.d.ts +18 -0
- package/lib/utils/fileProcessing.d.ts.map +1 -0
- package/lib/utils/fileProcessing.js +142 -0
- package/lib/utils/fileProcessing.js.map +1 -0
- package/lib/utils/filterResources.d.ts +38 -0
- package/lib/utils/filterResources.d.ts.map +1 -0
- package/lib/utils/filterResources.js +153 -0
- package/lib/utils/filterResources.js.map +1 -0
- package/lib/utils/resolutionEditing.d.ts +58 -0
- package/lib/utils/resolutionEditing.d.ts.map +1 -0
- package/lib/utils/resolutionEditing.js +246 -0
- package/lib/utils/resolutionEditing.js.map +1 -0
- package/lib/utils/resolutionUtils.d.ts +28 -0
- package/lib/utils/resolutionUtils.d.ts.map +1 -0
- package/lib/utils/resolutionUtils.js +216 -0
- package/lib/utils/resolutionUtils.js.map +1 -0
- package/lib/utils/tsResIntegration.d.ts +71 -0
- package/lib/utils/tsResIntegration.d.ts.map +1 -0
- package/lib/utils/tsResIntegration.js +294 -0
- package/lib/utils/tsResIntegration.js.map +1 -0
- package/lib/utils/zipLoader/browserZipLoader.d.ts +48 -0
- package/lib/utils/zipLoader/browserZipLoader.d.ts.map +1 -0
- package/lib/utils/zipLoader/browserZipLoader.js +247 -0
- package/lib/utils/zipLoader/browserZipLoader.js.map +1 -0
- package/lib/utils/zipLoader/index.d.ts +8 -0
- package/lib/utils/zipLoader/index.d.ts.map +1 -0
- package/lib/utils/zipLoader/index.js +13 -0
- package/lib/utils/zipLoader/index.js.map +1 -0
- package/lib/utils/zipLoader/nodeZipBuilder.d.ts +55 -0
- package/lib/utils/zipLoader/nodeZipBuilder.d.ts.map +1 -0
- package/lib/utils/zipLoader/nodeZipBuilder.js +98 -0
- package/lib/utils/zipLoader/nodeZipBuilder.js.map +1 -0
- package/lib/utils/zipLoader/types.d.ts +139 -0
- package/lib/utils/zipLoader/types.d.ts.map +1 -0
- package/lib/utils/zipLoader/types.js +2 -0
- package/lib/utils/zipLoader/types.js.map +1 -0
- package/lib/utils/zipLoader/zipUtils.d.ts +53 -0
- package/lib/utils/zipLoader/zipUtils.d.ts.map +1 -0
- package/lib/utils/zipLoader/zipUtils.js +229 -0
- package/lib/utils/zipLoader/zipUtils.js.map +1 -0
- package/package.json +69 -0
- package/rush-logs/ts-res-ui-components.build.cache.log +3 -0
- package/rush-logs/ts-res-ui-components.build.log +9 -0
- package/src/components/common/QualifierContextControl.tsx +151 -0
- package/src/components/common/ResourceListView.tsx +63 -0
- package/src/components/common/ResourceTreeView.tsx +271 -0
- package/src/components/forms/HierarchyEditor.tsx +204 -0
- package/src/components/forms/QualifierEditForm.tsx +355 -0
- package/src/components/forms/QualifierTypeEditForm.tsx +347 -0
- package/src/components/forms/ResourceTypeEditForm.tsx +331 -0
- package/src/components/forms/index.ts +11 -0
- package/src/components/orchestrator/ResourceOrchestrator.tsx +372 -0
- package/src/components/views/CompiledView/index.tsx +922 -0
- package/src/components/views/ConfigurationView/index.tsx +800 -0
- package/src/components/views/FilterView/index.tsx +825 -0
- package/src/components/views/ImportView/index.tsx +717 -0
- package/src/components/views/ResolutionView/EditableJsonView.tsx +214 -0
- package/src/components/views/ResolutionView/ResolutionEditControls.tsx +170 -0
- package/src/components/views/ResolutionView/index.tsx +591 -0
- package/src/components/views/SourceView/index.tsx +536 -0
- package/src/components/views/ZipLoaderView/index.tsx +485 -0
- package/src/hooks/useConfigurationState.ts +374 -0
- package/src/hooks/useFilterState.ts +97 -0
- package/src/hooks/useResolutionState.ts +355 -0
- package/src/hooks/useResourceData.ts +467 -0
- package/src/hooks/useViewState.ts +44 -0
- package/src/index.ts +45 -0
- package/src/test/helpers/testDataLoader.ts +195 -0
- package/src/test/unit/utils/configurationUtils.test.ts +630 -0
- package/src/test/unit/utils/fileProcessing.test.ts +391 -0
- package/src/test/unit/utils/filterResources.test.ts +574 -0
- package/src/test/unit/utils/resolutionEditing.test.ts +556 -0
- package/src/test/unit/utils/resolutionUtils.test.ts +521 -0
- package/src/test/unit/utils/tsResIntegration.test.ts +433 -0
- package/src/types/index.ts +322 -0
- package/src/utils/configurationUtils.ts +424 -0
- package/src/utils/fileProcessing.ts +160 -0
- package/src/utils/filterResources.ts +206 -0
- package/src/utils/resolutionEditing.ts +319 -0
- package/src/utils/resolutionUtils.ts +289 -0
- package/src/utils/tsResIntegration.ts +440 -0
- package/src/utils/zipLoader/browserZipLoader.ts +319 -0
- package/src/utils/zipLoader/index.ts +26 -0
- package/src/utils/zipLoader/nodeZipBuilder.ts +153 -0
- package/src/utils/zipLoader/types.ts +175 -0
- package/src/utils/zipLoader/zipUtils.ts +266 -0
- package/temp/build/typescript/ts_gZid87Hu.json +1 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/views/ConfigurationView/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useCallback, useRef } from 'react';\nimport {\n CogIcon,\n DocumentTextIcon,\n PlusIcon,\n TrashIcon,\n ArrowDownTrayIcon,\n ArrowUpTrayIcon,\n ExclamationTriangleIcon,\n CheckCircleIcon,\n InformationCircleIcon,\n EyeIcon,\n PencilIcon\n} from '@heroicons/react/24/outline';\nimport { ConfigurationViewProps } from '../../../types';\nimport { useConfigurationState } from '../../../hooks/useConfigurationState';\nimport { Config, QualifierTypes, Qualifiers, ResourceTypes } from '@fgv/ts-res';\nimport { QualifierTypeEditForm } from '../../forms/QualifierTypeEditForm';\nimport { QualifierEditForm } from '../../forms/QualifierEditForm';\nimport { ResourceTypeEditForm } from '../../forms/ResourceTypeEditForm';\n\nexport const ConfigurationView: React.FC<ConfigurationViewProps> = ({\n configuration,\n onConfigurationChange,\n onSave,\n hasUnsavedChanges,\n onMessage,\n className = ''\n}) => {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [editingQualifierType, setEditingQualifierType] = useState<{\n item: QualifierTypes.Config.ISystemQualifierTypeConfig;\n index: number;\n } | null>(null);\n const [editingQualifier, setEditingQualifier] = useState<{\n item: Qualifiers.IQualifierDecl;\n index: number;\n } | null>(null);\n const [editingResourceType, setEditingResourceType] = useState<{\n item: ResourceTypes.Config.IResourceTypeConfig;\n index: number;\n } | null>(null);\n const [showAddQualifierType, setShowAddQualifierType] = useState(false);\n const [showAddQualifier, setShowAddQualifier] = useState(false);\n const [showAddResourceType, setShowAddResourceType] = useState(false);\n\n const { state, actions, templates } = useConfigurationState(\n configuration || undefined,\n onConfigurationChange,\n hasUnsavedChanges\n ? undefined\n : (changes) => {\n // Only notify if we weren't already told there are unsaved changes\n }\n );\n\n // Handle file import\n const handleFileImport = useCallback(\n (files: FileList | null) => {\n if (!files || files.length === 0) return;\n\n const file = files[0];\n const reader = new FileReader();\n\n reader.onload = (e) => {\n const content = e.target?.result as string;\n if (content) {\n const result = actions.importFromJson(content);\n if (result.isSuccess()) {\n onMessage?.('success', `Configuration imported from ${file.name}`);\n } else {\n onMessage?.('error', `Import failed: ${result.message}`);\n }\n }\n };\n\n reader.onerror = () => {\n onMessage?.('error', `Failed to read file: ${file.name}`);\n };\n\n reader.readAsText(file);\n },\n [actions, onMessage]\n );\n\n // Handle export\n const handleExport = useCallback(() => {\n const result = actions.exportToJson({ format: 'json', pretty: true });\n if (result.isSuccess()) {\n const blob = new Blob([result.value], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'ts-res-configuration.json';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n onMessage?.('success', 'Configuration exported successfully');\n } else {\n onMessage?.('error', `Export failed: ${result.message}`);\n }\n }, [actions, onMessage]);\n\n // Handle template loading\n const handleLoadTemplate = useCallback(\n (templateId: string) => {\n const result = actions.loadTemplate(templateId);\n if (result.isSuccess()) {\n const template = templates.find((t) => t.id === templateId);\n onMessage?.('success', `Loaded template: ${template?.name}`);\n } else {\n onMessage?.('error', `Failed to load template: ${result.message}`);\n }\n },\n [actions, templates, onMessage]\n );\n\n // Handle save\n const handleSave = useCallback(() => {\n if (onSave) {\n onSave(state.currentConfiguration);\n actions.applyConfiguration();\n onMessage?.('success', 'Configuration saved successfully');\n }\n }, [onSave, state.currentConfiguration, actions, onMessage]);\n\n if (!configuration && !state.currentConfiguration) {\n return (\n <div className={`p-6 ${className}`}>\n <div className=\"flex items-center space-x-3 mb-6\">\n <CogIcon className=\"h-8 w-8 text-blue-600\" />\n <h2 className=\"text-2xl font-bold text-gray-900\">Configuration</h2>\n </div>\n\n <div className=\"bg-white rounded-lg shadow-sm border border-gray-200 p-8 text-center\">\n <div className=\"max-w-2xl mx-auto\">\n <h3 className=\"text-xl font-semibold text-gray-900 mb-4\">No Configuration Available</h3>\n <p className=\"text-gray-600 mb-6\">\n Load a configuration to manage qualifiers, qualifier types, and resource types.\n </p>\n <div className=\"bg-blue-50 rounded-lg p-4\">\n <p className=\"text-sm text-blue-800\">\n <strong>Configuration Manager:</strong> Define and manage system configurations for resource\n management, including qualifiers, qualifier types, and resource types.\n </p>\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div className={`p-6 ${className}`}>\n <div className=\"flex items-center justify-between mb-6\">\n <div className=\"flex items-center space-x-3\">\n <CogIcon className=\"h-8 w-8 text-blue-600\" />\n <h2 className=\"text-2xl font-bold text-gray-900\">Configuration</h2>\n {state.hasUnsavedChanges && (\n <span className=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800\">\n Unsaved Changes\n </span>\n )}\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Template Selection */}\n <select\n onChange={(e) => e.target.value && handleLoadTemplate(e.target.value)}\n value=\"\"\n className=\"px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <option value=\"\">Load Template...</option>\n {templates.map((template) => (\n <option key={template.id} value={template.id}>\n {template.name}\n </option>\n ))}\n </select>\n\n {/* Import Button */}\n <button\n onClick={() => fileInputRef.current?.click()}\n className=\"inline-flex items-center px-3 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <ArrowUpTrayIcon className=\"w-4 h-4 mr-2\" />\n Import\n </button>\n\n {/* Export Button */}\n <button\n onClick={handleExport}\n className=\"inline-flex items-center px-3 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <ArrowDownTrayIcon className=\"w-4 h-4 mr-2\" />\n Export\n </button>\n\n {/* View Toggle */}\n <button\n onClick={actions.toggleJsonView}\n className={`inline-flex items-center px-3 py-2 border rounded-md text-sm font-medium focus:outline-none focus:ring-2 focus:ring-blue-500 ${\n state.isJsonView\n ? 'border-blue-600 text-blue-600 bg-blue-50'\n : 'border-gray-300 text-gray-700 bg-white hover:bg-gray-50'\n }`}\n >\n {state.isJsonView ? (\n <>\n <PencilIcon className=\"w-4 h-4 mr-2\" />\n Form View\n </>\n ) : (\n <>\n <EyeIcon className=\"w-4 h-4 mr-2\" />\n JSON View\n </>\n )}\n </button>\n\n {/* Save Button */}\n {onSave && (\n <button\n onClick={handleSave}\n disabled={!state.hasUnsavedChanges}\n className={`inline-flex items-center px-4 py-2 border border-transparent rounded-md text-sm font-medium ${\n state.hasUnsavedChanges\n ? 'text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500'\n : 'text-gray-400 bg-gray-200 cursor-not-allowed'\n }`}\n >\n Save\n </button>\n )}\n </div>\n </div>\n\n {/* Validation Status */}\n {!state.validation.isValid && (\n <div className=\"mb-6 bg-red-50 border border-red-200 rounded-lg p-4\">\n <div className=\"flex items-center space-x-2 text-red-600 mb-2\">\n <ExclamationTriangleIcon className=\"w-5 h-5\" />\n <span className=\"font-medium\">Configuration Issues</span>\n </div>\n <ul className=\"text-sm text-red-700 space-y-1\">\n {state.validation.errors.map((error, index) => (\n <li key={index}>• {error}</li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Warnings */}\n {state.validation.warnings.length > 0 && (\n <div className=\"mb-6 bg-yellow-50 border border-yellow-200 rounded-lg p-4\">\n <div className=\"flex items-center space-x-2 text-yellow-600 mb-2\">\n <InformationCircleIcon className=\"w-5 h-5\" />\n <span className=\"font-medium\">Configuration Warnings</span>\n </div>\n <ul className=\"text-sm text-yellow-700 space-y-1\">\n {state.validation.warnings.map((warning, index) => (\n <li key={index}>• {warning}</li>\n ))}\n </ul>\n </div>\n )}\n\n <div className=\"bg-white rounded-lg shadow-sm border border-gray-200\">\n {state.isJsonView ? (\n // JSON Editor View\n <div className=\"p-6\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-lg font-semibold text-gray-900\">JSON Configuration</h3>\n <button\n onClick={() => {\n const result = actions.applyJsonChanges();\n if (result.isSuccess()) {\n onMessage?.('success', 'JSON changes applied');\n } else {\n onMessage?.('error', `JSON error: ${result.message}`);\n }\n }}\n disabled={!!state.jsonError}\n className={`px-4 py-2 rounded-md text-sm font-medium ${\n state.jsonError\n ? 'bg-gray-200 text-gray-400 cursor-not-allowed'\n : 'bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500'\n }`}\n >\n Apply Changes\n </button>\n </div>\n\n {state.jsonError && (\n <div className=\"mb-4 bg-red-50 border border-red-200 rounded-lg p-3\">\n <p className=\"text-sm text-red-700\">{state.jsonError}</p>\n </div>\n )}\n\n <textarea\n value={state.jsonString}\n onChange={(e) => actions.updateJsonString(e.target.value)}\n className=\"w-full h-96 px-3 py-2 border border-gray-300 rounded-md font-mono text-sm focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"Enter JSON configuration...\"\n />\n </div>\n ) : (\n // Form View\n <div>\n {/* Tab Navigation */}\n <div className=\"border-b border-gray-200\">\n <nav className=\"-mb-px flex space-x-8 px-6\">\n {[\n {\n key: 'qualifiers' as const,\n label: 'Qualifiers',\n count: state.currentConfiguration.qualifiers?.length || 0\n },\n {\n key: 'qualifierTypes' as const,\n label: 'Qualifier Types',\n count: state.currentConfiguration.qualifierTypes?.length || 0\n },\n {\n key: 'resourceTypes' as const,\n label: 'Resource Types',\n count: state.currentConfiguration.resourceTypes?.length || 0\n }\n ].map((tab) => (\n <button\n key={tab.key}\n onClick={() => actions.setActiveTab(tab.key)}\n className={`py-4 px-1 border-b-2 font-medium text-sm whitespace-nowrap ${\n state.activeTab === tab.key\n ? 'border-blue-600 text-blue-600'\n : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'\n }`}\n >\n {tab.label}\n <span className=\"ml-2 bg-gray-100 text-gray-900 rounded-full px-2.5 py-0.5 text-xs font-medium\">\n {tab.count}\n </span>\n </button>\n ))}\n </nav>\n </div>\n\n {/* Tab Content */}\n <div className=\"p-6\">\n {state.activeTab === 'qualifiers' && (\n <QualifiersPanel\n qualifiers={state.currentConfiguration.qualifiers || []}\n qualifierTypes={state.currentConfiguration.qualifierTypes || []}\n onUpdateItem={actions.updateQualifier}\n onRemove={actions.removeQualifier}\n onShowAdd={() => setShowAddQualifier(true)}\n onEdit={(item, index) => setEditingQualifier({ item, index })}\n />\n )}\n\n {state.activeTab === 'qualifierTypes' && (\n <QualifierTypesPanel\n qualifierTypes={state.currentConfiguration.qualifierTypes || []}\n onUpdateItem={actions.updateQualifierType}\n onRemove={actions.removeQualifierType}\n onShowAdd={() => setShowAddQualifierType(true)}\n onEdit={(item, index) => setEditingQualifierType({ item, index })}\n />\n )}\n\n {state.activeTab === 'resourceTypes' && (\n <ResourceTypesPanel\n resourceTypes={state.currentConfiguration.resourceTypes || []}\n onUpdateItem={actions.updateResourceType}\n onRemove={actions.removeResourceType}\n onShowAdd={() => setShowAddResourceType(true)}\n onEdit={(item, index) => setEditingResourceType({ item, index })}\n />\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* Hidden file input */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".json\"\n onChange={(e) => handleFileImport(e.target.files)}\n className=\"hidden\"\n />\n\n {/* Edit Modals */}\n {showAddQualifierType && (\n <QualifierTypeEditForm\n onSave={(qualifierType) => {\n actions.addQualifierType(qualifierType);\n setShowAddQualifierType(false);\n onMessage?.('success', `Added qualifier type: ${qualifierType.name}`);\n }}\n onCancel={() => setShowAddQualifierType(false)}\n existingNames={(state.currentConfiguration.qualifierTypes || []).map((qt) => qt.name)}\n />\n )}\n\n {editingQualifierType && (\n <QualifierTypeEditForm\n qualifierType={editingQualifierType.item}\n onSave={(qualifierType) => {\n actions.updateQualifierType(editingQualifierType.index, qualifierType);\n setEditingQualifierType(null);\n onMessage?.('success', `Updated qualifier type: ${qualifierType.name}`);\n }}\n onCancel={() => setEditingQualifierType(null)}\n existingNames={(state.currentConfiguration.qualifierTypes || [])\n .filter((_, i) => i !== editingQualifierType.index)\n .map((qt) => qt.name)}\n />\n )}\n\n {showAddQualifier && (\n <QualifierEditForm\n qualifierTypes={state.currentConfiguration.qualifierTypes || []}\n onSave={(qualifier) => {\n actions.addQualifier(qualifier);\n setShowAddQualifier(false);\n onMessage?.('success', `Added qualifier: ${qualifier.name}`);\n }}\n onCancel={() => setShowAddQualifier(false)}\n existingNames={(state.currentConfiguration.qualifiers || []).map((q) => q.name)}\n />\n )}\n\n {editingQualifier && (\n <QualifierEditForm\n qualifier={editingQualifier.item}\n qualifierTypes={state.currentConfiguration.qualifierTypes || []}\n onSave={(qualifier) => {\n actions.updateQualifier(editingQualifier.index, qualifier);\n setEditingQualifier(null);\n onMessage?.('success', `Updated qualifier: ${qualifier.name}`);\n }}\n onCancel={() => setEditingQualifier(null)}\n existingNames={(state.currentConfiguration.qualifiers || [])\n .filter((_, i) => i !== editingQualifier.index)\n .map((q) => q.name)}\n />\n )}\n\n {showAddResourceType && (\n <ResourceTypeEditForm\n onSave={(resourceType) => {\n actions.addResourceType(resourceType);\n setShowAddResourceType(false);\n onMessage?.('success', `Added resource type: ${resourceType.name}`);\n }}\n onCancel={() => setShowAddResourceType(false)}\n existingNames={(state.currentConfiguration.resourceTypes || []).map((rt) => rt.name)}\n />\n )}\n\n {editingResourceType && (\n <ResourceTypeEditForm\n resourceType={editingResourceType.item}\n onSave={(resourceType) => {\n actions.updateResourceType(editingResourceType.index, resourceType);\n setEditingResourceType(null);\n onMessage?.('success', `Updated resource type: ${resourceType.name}`);\n }}\n onCancel={() => setEditingResourceType(null)}\n existingNames={(state.currentConfiguration.resourceTypes || [])\n .filter((_, i) => i !== editingResourceType.index)\n .map((rt) => rt.name)}\n />\n )}\n </div>\n );\n};\n\n// Comprehensive panel components with full editing capabilities\ninterface QualifierTypesPanelProps {\n qualifierTypes: QualifierTypes.Config.ISystemQualifierTypeConfig[];\n onUpdateItem: (index: number, qualifierType: QualifierTypes.Config.ISystemQualifierTypeConfig) => void;\n onRemove: (index: number) => void;\n onShowAdd: () => void;\n onEdit: (item: QualifierTypes.Config.ISystemQualifierTypeConfig, index: number) => void;\n}\n\nconst QualifierTypesPanel: React.FC<QualifierTypesPanelProps> = ({\n qualifierTypes,\n onRemove,\n onShowAdd,\n onEdit\n}) => {\n const getConfigurationSummary = (type: QualifierTypes.Config.ISystemQualifierTypeConfig): string => {\n if (!type.configuration) return 'No configuration';\n const config = type.configuration as any;\n const details: string[] = [];\n\n if (config.allowContextList) details.push('Context List');\n if (type.systemType === 'literal') {\n if (config.caseSensitive === false) details.push('Case Insensitive');\n if (config.enumeratedValues?.length) details.push(`${config.enumeratedValues.length} values`);\n }\n if (type.systemType === 'territory') {\n if (config.acceptLowercase) details.push('Accept Lowercase');\n if (config.allowedTerritories?.length) details.push(`${config.allowedTerritories.length} territories`);\n }\n\n return details.length > 0 ? details.join(', ') : 'Default settings';\n };\n\n return (\n <div>\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-lg font-semibold text-gray-900\">Qualifier Types</h3>\n <button\n onClick={onShowAdd}\n className=\"inline-flex items-center px-3 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700\"\n >\n <PlusIcon className=\"w-4 h-4 mr-2\" />\n Add Type\n </button>\n </div>\n\n {qualifierTypes.length === 0 ? (\n <div className=\"text-center py-8 text-gray-500\">\n <CogIcon className=\"w-12 h-12 mx-auto mb-4 text-gray-400\" />\n <p>No qualifier types defined</p>\n <p className=\"text-sm\">Add a qualifier type to get started</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {qualifierTypes.map((type, index) => (\n <div\n key={index}\n className=\"bg-gray-50 p-4 rounded-lg border border-gray-200 hover:border-gray-300 transition-colors\"\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex-1\">\n <div className=\"flex items-center space-x-2 mb-2\">\n <h4 className=\"font-medium text-gray-900\">{type.name}</h4>\n <span\n className={`px-2 py-1 text-xs font-medium rounded-full ${\n type.systemType === 'language'\n ? 'bg-blue-100 text-blue-800'\n : type.systemType === 'territory'\n ? 'bg-green-100 text-green-800'\n : 'bg-purple-100 text-purple-800'\n }`}\n >\n {type.systemType}\n </span>\n </div>\n <p className=\"text-sm text-gray-600 mb-2\">{getConfigurationSummary(type)}</p>\n </div>\n <div className=\"flex items-center space-x-2 ml-4\">\n <button\n onClick={() => onEdit(type, index)}\n className=\"p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded\"\n title=\"Edit qualifier type\"\n >\n <PencilIcon className=\"w-4 h-4\" />\n </button>\n <button\n onClick={() => onRemove(index)}\n className=\"p-1.5 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded\"\n title=\"Delete qualifier type\"\n >\n <TrashIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n\ninterface QualifiersPanelProps {\n qualifiers: Qualifiers.IQualifierDecl[];\n qualifierTypes: QualifierTypes.Config.ISystemQualifierTypeConfig[];\n onUpdateItem: (index: number, qualifier: Qualifiers.IQualifierDecl) => void;\n onRemove: (index: number) => void;\n onShowAdd: () => void;\n onEdit: (item: Qualifiers.IQualifierDecl, index: number) => void;\n}\n\nconst QualifiersPanel: React.FC<QualifiersPanelProps> = ({\n qualifiers,\n qualifierTypes,\n onRemove,\n onShowAdd,\n onEdit\n}) => {\n // Sort qualifiers by priority (highest first)\n const sortedQualifiers = [...qualifiers].sort((a, b) => b.defaultPriority - a.defaultPriority);\n\n const getQualifierSummary = (qualifier: Qualifiers.IQualifierDecl): string => {\n const qualifierType = qualifierTypes.find((qt) => qt.name === qualifier.typeName);\n const details: string[] = [];\n\n if (qualifier.token) details.push(`Token: ${qualifier.token}`);\n if (qualifier.defaultValue) details.push(`Default: ${qualifier.defaultValue}`);\n if (qualifier.tokenIsOptional) details.push('Optional Token');\n if (qualifierType) details.push(`System: ${qualifierType.systemType}`);\n\n return details.join(' • ');\n };\n\n return (\n <div>\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-lg font-semibold text-gray-900\">Qualifiers</h3>\n <button\n onClick={onShowAdd}\n disabled={qualifierTypes.length === 0}\n className=\"inline-flex items-center px-3 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed\"\n title={qualifierTypes.length === 0 ? 'Add qualifier types first' : 'Add qualifier'}\n >\n <PlusIcon className=\"w-4 h-4 mr-2\" />\n Add Qualifier\n </button>\n </div>\n\n {qualifierTypes.length === 0 ? (\n <div className=\"text-center py-8 text-gray-500\">\n <ExclamationTriangleIcon className=\"w-12 h-12 mx-auto mb-4 text-amber-400\" />\n <p>No qualifier types available</p>\n <p className=\"text-sm\">Create qualifier types first before adding qualifiers</p>\n </div>\n ) : qualifiers.length === 0 ? (\n <div className=\"text-center py-8 text-gray-500\">\n <CogIcon className=\"w-12 h-12 mx-auto mb-4 text-gray-400\" />\n <p>No qualifiers defined</p>\n <p className=\"text-sm\">Add a qualifier to get started</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {sortedQualifiers.map((qualifier, index) => {\n const originalIndex = qualifiers.findIndex((q) => q === qualifier);\n const qualifierType = qualifierTypes.find((qt) => qt.name === qualifier.typeName);\n\n return (\n <div\n key={originalIndex}\n className=\"bg-gray-50 p-4 rounded-lg border border-gray-200 hover:border-gray-300 transition-colors\"\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"flex-1\">\n {/* Header line with name, type, and token */}\n <div className=\"flex items-center space-x-3 mb-2\">\n <h4 className=\"font-medium text-gray-900\">{qualifier.name}</h4>\n <span className=\"text-gray-600 text-sm\">{qualifier.typeName}</span>\n {qualifier.token && (\n <span className=\"px-2 py-1 text-xs font-medium bg-purple-100 text-purple-700 rounded\">\n token: {qualifier.token}\n </span>\n )}\n {!qualifierType && (\n <span className=\"px-2 py-1 text-xs font-medium bg-red-100 text-red-800 rounded-full\">\n Missing Type\n </span>\n )}\n </div>\n {/* Bottom line with type and priority */}\n <div className=\"flex items-center justify-between text-sm text-gray-600\">\n <span>Type: {qualifier.typeName}</span>\n <span>Priority: {qualifier.defaultPriority}</span>\n </div>\n </div>\n <div className=\"flex items-center space-x-2 ml-4\">\n <button\n onClick={() => onEdit(qualifier, originalIndex)}\n className=\"p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded\"\n title=\"Edit qualifier\"\n >\n <PencilIcon className=\"w-4 h-4\" />\n </button>\n <button\n onClick={() => onRemove(originalIndex)}\n className=\"p-1.5 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded\"\n title=\"Delete qualifier\"\n >\n <TrashIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n};\n\ninterface ResourceTypesPanelProps {\n resourceTypes: ResourceTypes.Config.IResourceTypeConfig[];\n onUpdateItem: (index: number, resourceType: ResourceTypes.Config.IResourceTypeConfig) => void;\n onRemove: (index: number) => void;\n onShowAdd: () => void;\n onEdit: (item: ResourceTypes.Config.IResourceTypeConfig, index: number) => void;\n}\n\nconst ResourceTypesPanel: React.FC<ResourceTypesPanelProps> = ({\n resourceTypes,\n onRemove,\n onShowAdd,\n onEdit\n}) => {\n const getTypeNameBadgeColor = (typeName: string): string => {\n switch (typeName) {\n case 'string':\n return 'bg-blue-100 text-blue-800';\n case 'object':\n return 'bg-green-100 text-green-800';\n case 'array':\n return 'bg-purple-100 text-purple-800';\n case 'number':\n return 'bg-yellow-100 text-yellow-800';\n case 'boolean':\n return 'bg-red-100 text-red-800';\n default:\n return 'bg-gray-100 text-gray-800';\n }\n };\n\n return (\n <div>\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-lg font-semibold text-gray-900\">Resource Types</h3>\n <button\n onClick={onShowAdd}\n className=\"inline-flex items-center px-3 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700\"\n >\n <PlusIcon className=\"w-4 h-4 mr-2\" />\n Add Type\n </button>\n </div>\n\n {resourceTypes.length === 0 ? (\n <div className=\"text-center py-8 text-gray-500\">\n <CogIcon className=\"w-12 h-12 mx-auto mb-4 text-gray-400\" />\n <p>No resource types defined</p>\n <p className=\"text-sm\">Add a resource type to get started</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {resourceTypes.map((type, index) => (\n <div\n key={index}\n className=\"bg-gray-50 p-4 rounded-lg border border-gray-200 hover:border-gray-300 transition-colors\"\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex-1\">\n <div className=\"flex items-center space-x-2 mb-2\">\n <h4 className=\"font-medium text-gray-900\">{type.name}</h4>\n <span\n className={`px-2 py-1 text-xs font-medium rounded-full ${getTypeNameBadgeColor(\n type.typeName\n )}`}\n >\n {type.typeName}\n </span>\n </div>\n <p className=\"text-sm text-gray-600\">\n Defines how resources of this type are processed and validated\n </p>\n </div>\n <div className=\"flex items-center space-x-2 ml-4\">\n <button\n onClick={() => onEdit(type, index)}\n className=\"p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded\"\n title=\"Edit resource type\"\n >\n <PencilIcon className=\"w-4 h-4\" />\n </button>\n <button\n onClick={() => onRemove(index)}\n className=\"p-1.5 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded\"\n title=\"Delete resource type\"\n >\n <TrashIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n\nexport default ConfigurationView;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/views/FilterView/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAe9D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAcjD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAqfhD,CAAC;AAsSF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
import React, { useState, useMemo, useCallback } from 'react';
|
|
2
|
+
import { FunnelIcon, DocumentTextIcon, ExclamationTriangleIcon, CheckIcon, XMarkIcon, ListBulletIcon, FolderIcon } from '@heroicons/react/24/outline';
|
|
3
|
+
import { QualifierContextControl } from '../../common/QualifierContextControl';
|
|
4
|
+
import { ResourceTreeView } from '../../common/ResourceTreeView';
|
|
5
|
+
export const FilterView = ({ resources, filterState, filterActions, filterResult, onFilterResult, onMessage, className = '' }) => {
|
|
6
|
+
// Local UI state
|
|
7
|
+
const [selectedResourceId, setSelectedResourceId] = useState(null);
|
|
8
|
+
const [showFilteredJsonView, setShowFilteredJsonView] = useState(false);
|
|
9
|
+
const [viewMode, setViewMode] = useState('list');
|
|
10
|
+
// Available qualifiers from system configuration or compiled collection
|
|
11
|
+
const availableQualifiers = useMemo(() => {
|
|
12
|
+
if (resources?.compiledCollection.qualifiers) {
|
|
13
|
+
return resources.compiledCollection.qualifiers.map((q) => q.name);
|
|
14
|
+
}
|
|
15
|
+
// Fallback to default qualifiers if no compiled collection
|
|
16
|
+
return ['language', 'territory', 'currentTerritory', 'role', 'env'];
|
|
17
|
+
}, [resources?.compiledCollection.qualifiers]);
|
|
18
|
+
// Handle filter value changes using the shared component's callback pattern
|
|
19
|
+
const handleQualifierChange = useCallback((qualifierName, value) => {
|
|
20
|
+
const newValues = { ...filterState.values, [qualifierName]: value };
|
|
21
|
+
filterActions.updateFilterValues(newValues);
|
|
22
|
+
}, [filterState.values, filterActions]);
|
|
23
|
+
// Check if we have any applied filter values set
|
|
24
|
+
const hasAppliedFilterValues = useMemo(() => {
|
|
25
|
+
if (!filterState.appliedValues)
|
|
26
|
+
return false;
|
|
27
|
+
return Object.values(filterState.appliedValues).some((value) => value !== undefined && value !== '');
|
|
28
|
+
}, [filterState.appliedValues]);
|
|
29
|
+
// Determine if filtering is active (enabled AND has applied values)
|
|
30
|
+
const isFilteringActive = filterState.enabled && hasAppliedFilterValues;
|
|
31
|
+
// Simplified filter summary
|
|
32
|
+
const getFilterSummary = useCallback((values) => {
|
|
33
|
+
const activeFilters = Object.entries(values)
|
|
34
|
+
.filter(([, value]) => value !== undefined && value !== '')
|
|
35
|
+
.map(([key, value]) => `${key}=${value}`);
|
|
36
|
+
return activeFilters.length > 0 ? activeFilters.join(', ') : 'No filters';
|
|
37
|
+
}, []);
|
|
38
|
+
// Get filtered resource collection data (simplified)
|
|
39
|
+
const getFilteredResourceCollectionData = useCallback(() => {
|
|
40
|
+
if (!filterResult?.processedResources?.system.resourceManager) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const resourceManager = filterResult.processedResources.system.resourceManager;
|
|
44
|
+
// Check if this is a ResourceManagerBuilder (has getResourceCollectionDecl method)
|
|
45
|
+
if ('getResourceCollectionDecl' in resourceManager) {
|
|
46
|
+
const collectionResult = resourceManager.getResourceCollectionDecl();
|
|
47
|
+
if (collectionResult.isSuccess()) {
|
|
48
|
+
return {
|
|
49
|
+
...collectionResult.value,
|
|
50
|
+
metadata: {
|
|
51
|
+
exportedAt: new Date().toISOString(),
|
|
52
|
+
totalResources: filterResult.processedResources.resourceCount,
|
|
53
|
+
type: 'ts-res-filtered-resource-collection',
|
|
54
|
+
filterContext: filterState.appliedValues,
|
|
55
|
+
reduceQualifiers: filterState.reduceQualifiers
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
onMessage?.('error', `Failed to get filtered resource collection: ${collectionResult.message}`);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (filterResult.processedResources.compiledCollection) {
|
|
65
|
+
// For IResourceManager from bundles, use the compiled collection directly
|
|
66
|
+
return {
|
|
67
|
+
resources: filterResult.processedResources.compiledCollection.resources || [],
|
|
68
|
+
metadata: {
|
|
69
|
+
exportedAt: new Date().toISOString(),
|
|
70
|
+
totalResources: filterResult.processedResources.resourceCount,
|
|
71
|
+
type: 'ts-res-filtered-resource-collection',
|
|
72
|
+
filterContext: filterState.appliedValues,
|
|
73
|
+
reduceQualifiers: filterState.reduceQualifiers
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
onMessage?.('error', 'Filtered resource collection data not available');
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}, [filterResult, onMessage, filterState.appliedValues, filterState.reduceQualifiers]);
|
|
82
|
+
// Export filtered resource collection data
|
|
83
|
+
const handleExportFilteredData = useCallback(() => {
|
|
84
|
+
try {
|
|
85
|
+
const collectionData = getFilteredResourceCollectionData();
|
|
86
|
+
if (!collectionData) {
|
|
87
|
+
onMessage?.('error', 'No filtered collection data available to export');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const filterSummary = getFilterSummary(filterState.appliedValues);
|
|
91
|
+
// Use onExport callback instead of direct file download for flexibility
|
|
92
|
+
// onExport?.(collectionData, 'json');
|
|
93
|
+
onMessage?.('success', 'Filtered resource collection exported successfully');
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
onMessage?.('error', `Failed to export filtered resource collection: ${error instanceof Error ? error.message : String(error)}`);
|
|
97
|
+
}
|
|
98
|
+
}, [getFilteredResourceCollectionData, onMessage, filterState.appliedValues, getFilterSummary]);
|
|
99
|
+
// Get resources to display (filtered or original) - now uses orchestrator's filterResult
|
|
100
|
+
const displayResources = useMemo(() => {
|
|
101
|
+
console.log('FilterView displayResources calculation:', {
|
|
102
|
+
hasResources: !!resources,
|
|
103
|
+
isFilteringActive,
|
|
104
|
+
filterResultExists: !!filterResult,
|
|
105
|
+
filterResultSuccess: filterResult?.success,
|
|
106
|
+
filterResultCount: filterResult?.filteredResources?.length,
|
|
107
|
+
appliedValues: filterState.appliedValues,
|
|
108
|
+
hasAppliedFilterValues
|
|
109
|
+
});
|
|
110
|
+
if (!resources)
|
|
111
|
+
return [];
|
|
112
|
+
let resourceList = [];
|
|
113
|
+
if (isFilteringActive && filterResult?.success && filterResult.filteredResources) {
|
|
114
|
+
console.log('Using filtered resources:', filterResult.filteredResources.length);
|
|
115
|
+
console.log('Filtered resource details:', filterResult.filteredResources.map((r) => ({
|
|
116
|
+
id: r.id,
|
|
117
|
+
original: r.originalCandidateCount,
|
|
118
|
+
filtered: r.filteredCandidateCount,
|
|
119
|
+
hasWarning: r.hasWarning
|
|
120
|
+
})));
|
|
121
|
+
resourceList = filterResult.filteredResources;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// Return original resources
|
|
125
|
+
console.log('Using original resources');
|
|
126
|
+
const originalResources = resources.summary.resourceIds || [];
|
|
127
|
+
resourceList = originalResources.map((id) => {
|
|
128
|
+
const resourceResult = resources.system.resourceManager.getBuiltResource(id);
|
|
129
|
+
const candidateCount = resourceResult.isSuccess() ? resourceResult.value.candidates.length : 0;
|
|
130
|
+
return {
|
|
131
|
+
id,
|
|
132
|
+
originalCandidateCount: candidateCount,
|
|
133
|
+
filteredCandidateCount: candidateCount,
|
|
134
|
+
hasWarning: false
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
// Sort resources alphabetically by id
|
|
139
|
+
return resourceList.sort((a, b) => a.id.localeCompare(b.id));
|
|
140
|
+
}, [resources, isFilteringActive, filterResult]);
|
|
141
|
+
// Handle filter value changes
|
|
142
|
+
const handleFilterChange = useCallback((qualifierName, value) => {
|
|
143
|
+
const newValues = { ...filterState.values, [qualifierName]: value };
|
|
144
|
+
filterActions.updateFilterValues(newValues);
|
|
145
|
+
}, [filterState.values, filterActions]);
|
|
146
|
+
// Handle resource selection
|
|
147
|
+
const handleResourceSelect = useCallback((resourceId) => {
|
|
148
|
+
setSelectedResourceId(resourceId);
|
|
149
|
+
}, []);
|
|
150
|
+
// Handle filter toggle
|
|
151
|
+
const handleFilterToggle = useCallback((enabled) => {
|
|
152
|
+
filterActions.updateFilterEnabled(enabled);
|
|
153
|
+
if (!enabled) {
|
|
154
|
+
onMessage?.('info', 'Filtering disabled - showing all resources');
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
onMessage?.('info', 'Filtering enabled - set qualifier values and click Apply to filter resources');
|
|
158
|
+
}
|
|
159
|
+
}, [filterActions, onMessage]);
|
|
160
|
+
// Handle apply filter values
|
|
161
|
+
const handleApplyFilter = useCallback(() => {
|
|
162
|
+
filterActions.applyFilterValues();
|
|
163
|
+
onMessage?.('info', 'Filter applied - processing resources...');
|
|
164
|
+
}, [filterActions, onMessage]);
|
|
165
|
+
// Handle reset filter values
|
|
166
|
+
const handleResetFilter = useCallback(() => {
|
|
167
|
+
filterActions.resetFilterValues();
|
|
168
|
+
onMessage?.('info', 'Filter values reset');
|
|
169
|
+
}, [filterActions, onMessage]);
|
|
170
|
+
if (!resources) {
|
|
171
|
+
return (React.createElement("div", { className: `p-6 ${className}` },
|
|
172
|
+
React.createElement("div", { className: "flex items-center space-x-3 mb-6" },
|
|
173
|
+
React.createElement(FunnelIcon, { className: "h-8 w-8 text-purple-600" }),
|
|
174
|
+
React.createElement("h2", { className: "text-2xl font-bold text-gray-900" }, "Filter Tool")),
|
|
175
|
+
React.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-8 text-center" },
|
|
176
|
+
React.createElement("div", { className: "max-w-2xl mx-auto" },
|
|
177
|
+
React.createElement("h3", { className: "text-xl font-semibold text-gray-900 mb-4" }, "No Resources Loaded"),
|
|
178
|
+
React.createElement("p", { className: "text-gray-600 mb-6" }, "Import resources first to use the filter tool for context-based resource filtering."),
|
|
179
|
+
React.createElement("div", { className: "bg-purple-50 rounded-lg p-4" },
|
|
180
|
+
React.createElement("p", { className: "text-sm text-purple-800" },
|
|
181
|
+
React.createElement("strong", null, "Filter Tool:"),
|
|
182
|
+
" Allows you to filter resources based on partial context matching, creating focused subsets for analysis and testing."))))));
|
|
183
|
+
}
|
|
184
|
+
return (React.createElement("div", { className: `p-6 ${className}` },
|
|
185
|
+
React.createElement("div", { className: "flex items-center space-x-3 mb-6" },
|
|
186
|
+
React.createElement(FunnelIcon, { className: "h-8 w-8 text-purple-600" }),
|
|
187
|
+
React.createElement("h2", { className: "text-2xl font-bold text-gray-900" }, "Filter Tool")),
|
|
188
|
+
React.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-6" },
|
|
189
|
+
React.createElement("div", { className: "mb-6" },
|
|
190
|
+
React.createElement("div", { className: "flex items-center justify-between mb-4" },
|
|
191
|
+
React.createElement("h3", { className: "text-lg font-semibold text-gray-900" }, "Filter Controls"),
|
|
192
|
+
React.createElement("div", { className: "flex items-center justify-between" },
|
|
193
|
+
React.createElement("div", { className: "flex items-center space-x-4" },
|
|
194
|
+
React.createElement("label", { className: "flex items-center" },
|
|
195
|
+
React.createElement("input", { type: "checkbox", checked: filterState.enabled, onChange: (e) => handleFilterToggle(e.target.checked), className: "rounded border-gray-300 text-purple-600 focus:ring-purple-500" }),
|
|
196
|
+
React.createElement("span", { className: "ml-2 text-sm text-gray-700" }, "Enable Filtering")),
|
|
197
|
+
React.createElement("label", { className: "flex items-center", title: "Remove perfectly matching qualifier conditions from filtered resources to create cleaner bundles for comparison" },
|
|
198
|
+
React.createElement("input", { type: "checkbox", checked: filterState.reduceQualifiers, onChange: (e) => filterActions.updateReduceQualifiers(e.target.checked), disabled: !filterState.enabled, className: "rounded border-gray-300 text-purple-600 focus:ring-purple-500 disabled:text-gray-400" }),
|
|
199
|
+
React.createElement("span", { className: `ml-2 text-sm ${!filterState.enabled ? 'text-gray-400' : 'text-gray-700'}` }, "Reduce Qualifiers")),
|
|
200
|
+
isFilteringActive && (React.createElement("span", { className: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800" },
|
|
201
|
+
"Active",
|
|
202
|
+
filterState.reduceQualifiers ? ' + Reducing' : '')),
|
|
203
|
+
filterState.hasPendingChanges && filterState.enabled && (React.createElement("span", { className: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-800" }, "Pending Changes"))),
|
|
204
|
+
filterState.enabled && (React.createElement("div", { className: "flex items-center space-x-2" },
|
|
205
|
+
React.createElement("button", { onClick: handleResetFilter, className: "inline-flex items-center px-3 py-1.5 text-xs font-medium text-gray-700 bg-gray-100 border border-gray-300 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-purple-500" },
|
|
206
|
+
React.createElement(XMarkIcon, { className: "h-4 w-4 mr-1" }),
|
|
207
|
+
"Reset"),
|
|
208
|
+
React.createElement("button", { onClick: handleApplyFilter, disabled: !filterState.hasPendingChanges, className: `inline-flex items-center px-3 py-1.5 text-xs font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500 ${filterState.hasPendingChanges
|
|
209
|
+
? 'text-white bg-purple-600 hover:bg-purple-700'
|
|
210
|
+
: 'text-gray-400 bg-gray-300 cursor-not-allowed'}` },
|
|
211
|
+
React.createElement(CheckIcon, { className: "h-4 w-4 mr-1" }),
|
|
212
|
+
"Apply")))))),
|
|
213
|
+
React.createElement("div", { className: "mb-6" },
|
|
214
|
+
React.createElement("h3", { className: "text-lg font-semibold text-gray-900 mb-4" }, "Context Filters"),
|
|
215
|
+
React.createElement("div", { className: "bg-gray-50 rounded-lg p-4" },
|
|
216
|
+
React.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3" }, availableQualifiers.map((qualifierName) => (React.createElement(QualifierContextControl, { key: qualifierName, qualifierName: qualifierName, value: filterState.values[qualifierName], onChange: handleQualifierChange, disabled: !filterState.enabled, placeholder: `Filter by ${qualifierName}`, resources: resources })))),
|
|
217
|
+
filterState.enabled && (React.createElement("div", { className: "mt-3 text-sm text-gray-600" },
|
|
218
|
+
React.createElement("div", { className: "flex items-center justify-between" },
|
|
219
|
+
React.createElement("div", { className: "space-y-1" },
|
|
220
|
+
React.createElement("p", null,
|
|
221
|
+
React.createElement("strong", null, "Pending:"),
|
|
222
|
+
" ",
|
|
223
|
+
getFilterSummary(filterState.values)),
|
|
224
|
+
isFilteringActive && (React.createElement("p", null,
|
|
225
|
+
React.createElement("strong", null, "Applied:"),
|
|
226
|
+
" ",
|
|
227
|
+
getFilterSummary(filterState.appliedValues))))),
|
|
228
|
+
filterResult && !filterResult.success && filterResult.error && (React.createElement("p", { className: "text-red-600 text-xs mt-1" },
|
|
229
|
+
React.createElement("strong", null, "Error:"),
|
|
230
|
+
" ",
|
|
231
|
+
filterResult.error)))))),
|
|
232
|
+
React.createElement("div", { className: "flex flex-col md:flex-row gap-6 h-[600px]" },
|
|
233
|
+
React.createElement("div", { className: "md:w-1/2 flex flex-col" },
|
|
234
|
+
React.createElement("div", { className: "flex items-center justify-between mb-4" },
|
|
235
|
+
React.createElement("div", null,
|
|
236
|
+
React.createElement("h3", { className: "text-lg font-semibold text-gray-900" }, isFilteringActive ? 'Filtered Resources' : 'All Resources'),
|
|
237
|
+
React.createElement("div", { className: "flex items-center space-x-2 text-sm text-gray-500 mt-1" },
|
|
238
|
+
React.createElement("span", null,
|
|
239
|
+
displayResources.length,
|
|
240
|
+
" resources"),
|
|
241
|
+
isFilteringActive && displayResources.some((r) => r.hasWarning) && (React.createElement(React.Fragment, null,
|
|
242
|
+
React.createElement("span", null, "\u2022"),
|
|
243
|
+
React.createElement("span", { className: "text-amber-600 flex items-center" },
|
|
244
|
+
React.createElement(ExclamationTriangleIcon, { className: "h-4 w-4 mr-1" }),
|
|
245
|
+
displayResources.filter((r) => r.hasWarning).length,
|
|
246
|
+
" warnings"))))),
|
|
247
|
+
React.createElement("div", { className: "flex items-center space-x-1 bg-gray-100 rounded-lg p-1" },
|
|
248
|
+
React.createElement("button", { onClick: () => setViewMode('list'), className: `flex items-center px-2 py-1 text-xs font-medium rounded ${viewMode === 'list'
|
|
249
|
+
? 'bg-white text-gray-900 shadow-sm'
|
|
250
|
+
: 'text-gray-600 hover:text-gray-900'}`, title: "List View" },
|
|
251
|
+
React.createElement(ListBulletIcon, { className: "h-4 w-4" }),
|
|
252
|
+
React.createElement("span", { className: "ml-1" }, "List")),
|
|
253
|
+
React.createElement("button", { onClick: () => setViewMode('tree'), className: `flex items-center px-2 py-1 text-xs font-medium rounded ${viewMode === 'tree'
|
|
254
|
+
? 'bg-white text-gray-900 shadow-sm'
|
|
255
|
+
: 'text-gray-600 hover:text-gray-900'}`, title: "Tree View" },
|
|
256
|
+
React.createElement(FolderIcon, { className: "h-4 w-4" }),
|
|
257
|
+
React.createElement("span", { className: "ml-1" }, "Tree")))),
|
|
258
|
+
React.createElement("div", { className: "flex-1 overflow-y-auto border border-gray-200 rounded-lg bg-gray-50" }, viewMode === 'tree' && resources?.system.resourceManager ? (React.createElement(ResourceTreeView, { resources: resources.system.resourceManager, selectedResourceId: selectedResourceId, onResourceSelect: handleResourceSelect, searchTerm: "", className: "" })) : (displayResources.map((resource) => (React.createElement("div", { key: resource.id, className: `flex items-center justify-between px-3 py-2 cursor-pointer hover:bg-gray-100 border-b border-gray-100 last:border-b-0 ${selectedResourceId === resource.id ? 'bg-purple-50 border-r-2 border-purple-500' : ''}`, onClick: () => handleResourceSelect(resource.id) },
|
|
259
|
+
React.createElement("div", { className: "flex items-center space-x-2 flex-1 min-w-0" },
|
|
260
|
+
React.createElement(DocumentTextIcon, { className: "w-4 h-4 text-green-500 flex-shrink-0" }),
|
|
261
|
+
React.createElement("span", { className: `text-sm truncate ${selectedResourceId === resource.id ? 'font-medium text-purple-900' : 'text-gray-700'}` }, resource.id)),
|
|
262
|
+
React.createElement("div", { className: "flex items-center space-x-2 flex-shrink-0" },
|
|
263
|
+
isFilteringActive && (React.createElement("div", { className: "flex items-center space-x-1 text-xs" },
|
|
264
|
+
React.createElement("span", { className: "text-gray-400" }, resource.originalCandidateCount),
|
|
265
|
+
React.createElement("span", { className: "text-gray-400" }, "\u2192"),
|
|
266
|
+
React.createElement("span", { className: `font-medium ${resource.filteredCandidateCount === 0
|
|
267
|
+
? 'text-red-600'
|
|
268
|
+
: resource.filteredCandidateCount < resource.originalCandidateCount
|
|
269
|
+
? 'text-amber-600'
|
|
270
|
+
: 'text-green-600'}` }, resource.filteredCandidateCount))),
|
|
271
|
+
!isFilteringActive && (React.createElement("span", { className: "text-xs text-gray-500" },
|
|
272
|
+
resource.originalCandidateCount,
|
|
273
|
+
" candidates")),
|
|
274
|
+
resource.hasWarning && (React.createElement(ExclamationTriangleIcon, { className: "h-4 w-4 text-amber-500", title: "No matching candidates" }))))))))),
|
|
275
|
+
React.createElement("div", { className: "md:w-1/2 flex flex-col" },
|
|
276
|
+
React.createElement("div", { className: "flex items-center justify-between mb-4" },
|
|
277
|
+
React.createElement("h3", { className: "text-lg font-semibold text-gray-900" }, "Resource Details")),
|
|
278
|
+
React.createElement("div", { className: "flex-1 overflow-y-auto border border-gray-200 rounded-lg p-4 bg-gray-50" }, !selectedResourceId ? (React.createElement("div", { className: "flex items-center justify-center h-full" },
|
|
279
|
+
React.createElement("div", { className: "text-center" },
|
|
280
|
+
React.createElement(FunnelIcon, { className: "h-12 w-12 text-gray-400 mx-auto mb-4" }),
|
|
281
|
+
React.createElement("p", { className: "text-gray-500" }, "Select a resource to view details"),
|
|
282
|
+
isFilteringActive && (React.createElement("p", { className: "text-sm text-gray-400 mt-2" }, "Showing resources that match your filter criteria"))))) : (React.createElement(FilteredResourceDetail, { resourceId: selectedResourceId, processedResources: resources, filterResult: filterResult, isFilteringActive: isFilteringActive, filterContext: filterState.appliedValues, onMessage: onMessage }))))))));
|
|
283
|
+
};
|
|
284
|
+
const FilteredResourceDetail = ({ resourceId, processedResources, filterResult, isFilteringActive, filterContext, onMessage }) => {
|
|
285
|
+
const [resourceDetail, setResourceDetail] = useState(null);
|
|
286
|
+
const [filteredResourceDetail, setFilteredResourceDetail] = useState(null);
|
|
287
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
288
|
+
const [error, setError] = useState(null);
|
|
289
|
+
const [showFilteredView, setShowFilteredView] = useState(true);
|
|
290
|
+
React.useEffect(() => {
|
|
291
|
+
const loadResourceDetails = () => {
|
|
292
|
+
setIsLoading(true);
|
|
293
|
+
setError(null);
|
|
294
|
+
try {
|
|
295
|
+
// Load original resource details
|
|
296
|
+
const resourceManager = processedResources.system.resourceManager;
|
|
297
|
+
const resourceResult = resourceManager.getBuiltResource(resourceId);
|
|
298
|
+
if (resourceResult.isSuccess()) {
|
|
299
|
+
const resource = resourceResult.value;
|
|
300
|
+
const originalDetail = {
|
|
301
|
+
id: resource.id,
|
|
302
|
+
resourceType: resource.resourceType.key,
|
|
303
|
+
candidateCount: resource.candidates.length,
|
|
304
|
+
candidates: resource.candidates.map((candidate) => ({
|
|
305
|
+
json: candidate.json,
|
|
306
|
+
conditions: candidate.conditions.conditions.map((condition) => ({
|
|
307
|
+
qualifier: condition.qualifier.name,
|
|
308
|
+
operator: condition.operator,
|
|
309
|
+
value: condition.value,
|
|
310
|
+
priority: condition.priority,
|
|
311
|
+
scoreAsDefault: condition.scoreAsDefault
|
|
312
|
+
})),
|
|
313
|
+
isPartial: candidate.isPartial,
|
|
314
|
+
mergeMethod: candidate.mergeMethod
|
|
315
|
+
}))
|
|
316
|
+
};
|
|
317
|
+
setResourceDetail(originalDetail);
|
|
318
|
+
// Load filtered resource details if filtering is active
|
|
319
|
+
if (isFilteringActive && filterResult?.processedResources) {
|
|
320
|
+
const filteredResourceManager = filterResult.processedResources.system.resourceManager;
|
|
321
|
+
const filteredResourceResult = filteredResourceManager.getBuiltResource(resourceId);
|
|
322
|
+
if (filteredResourceResult.isSuccess()) {
|
|
323
|
+
const filteredResource = filteredResourceResult.value;
|
|
324
|
+
const filteredDetail = {
|
|
325
|
+
id: filteredResource.id,
|
|
326
|
+
resourceType: filteredResource.resourceType.key,
|
|
327
|
+
candidateCount: filteredResource.candidates.length,
|
|
328
|
+
candidates: filteredResource.candidates.map((candidate) => ({
|
|
329
|
+
json: candidate.json,
|
|
330
|
+
conditions: candidate.conditions.conditions.map((condition) => ({
|
|
331
|
+
qualifier: condition.qualifier.name,
|
|
332
|
+
operator: condition.operator,
|
|
333
|
+
value: condition.value,
|
|
334
|
+
priority: condition.priority,
|
|
335
|
+
scoreAsDefault: condition.scoreAsDefault
|
|
336
|
+
})),
|
|
337
|
+
isPartial: candidate.isPartial,
|
|
338
|
+
mergeMethod: candidate.mergeMethod
|
|
339
|
+
}))
|
|
340
|
+
};
|
|
341
|
+
setFilteredResourceDetail(filteredDetail);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
onMessage?.('info', `Loaded details for resource: ${resourceId}`);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
setError(`Failed to load resource details: ${resourceResult.message}`);
|
|
348
|
+
onMessage?.('error', `Failed to load resource details: ${resourceResult.message}`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
catch (err) {
|
|
352
|
+
const errorMsg = `Error loading resource details: ${err instanceof Error ? err.message : String(err)}`;
|
|
353
|
+
setError(errorMsg);
|
|
354
|
+
onMessage?.('error', errorMsg);
|
|
355
|
+
}
|
|
356
|
+
finally {
|
|
357
|
+
setIsLoading(false);
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
loadResourceDetails();
|
|
361
|
+
}, [resourceId, processedResources, filterResult, isFilteringActive, onMessage]);
|
|
362
|
+
if (isLoading) {
|
|
363
|
+
return (React.createElement("div", { className: "bg-white rounded-lg border border-gray-200 p-4" },
|
|
364
|
+
React.createElement("h4", { className: "font-medium text-gray-900 mb-2" }, "Resource Details"),
|
|
365
|
+
React.createElement("div", { className: "flex items-center justify-center py-8" },
|
|
366
|
+
React.createElement("div", { className: "text-center" },
|
|
367
|
+
React.createElement("div", { className: "animate-spin h-6 w-6 border-2 border-purple-600 border-t-transparent rounded-full mx-auto mb-2" }),
|
|
368
|
+
React.createElement("p", { className: "text-sm text-gray-500" }, "Loading resource details...")))));
|
|
369
|
+
}
|
|
370
|
+
if (error) {
|
|
371
|
+
return (React.createElement("div", { className: "bg-white rounded-lg border border-red-200 p-4" },
|
|
372
|
+
React.createElement("h4", { className: "font-medium text-red-900 mb-2" }, "Resource Details"),
|
|
373
|
+
React.createElement("div", { className: "bg-red-50 p-3 rounded" },
|
|
374
|
+
React.createElement("p", { className: "text-sm text-red-600" }, error))));
|
|
375
|
+
}
|
|
376
|
+
if (!resourceDetail) {
|
|
377
|
+
return (React.createElement("div", { className: "bg-white rounded-lg border border-gray-200 p-4" },
|
|
378
|
+
React.createElement("h4", { className: "font-medium text-gray-900 mb-2" }, "Resource Details"),
|
|
379
|
+
React.createElement("p", { className: "text-sm text-gray-500" }, "No resource details available")));
|
|
380
|
+
}
|
|
381
|
+
const currentDetail = showFilteredView && filteredResourceDetail ? filteredResourceDetail : resourceDetail;
|
|
382
|
+
const isShowingFiltered = showFilteredView && filteredResourceDetail;
|
|
383
|
+
return (React.createElement("div", { className: "bg-white rounded-lg border border-gray-200 p-4" },
|
|
384
|
+
React.createElement("div", { className: "flex items-center justify-between mb-4" },
|
|
385
|
+
React.createElement("h4", { className: "font-medium text-gray-900" }, "Resource Details"),
|
|
386
|
+
isFilteringActive && filteredResourceDetail && (React.createElement("div", { className: "flex items-center space-x-2" },
|
|
387
|
+
React.createElement("span", { className: "text-xs text-gray-500" }, "View:"),
|
|
388
|
+
React.createElement("button", { onClick: () => setShowFilteredView(false), className: `px-2 py-1 text-xs rounded ${!showFilteredView
|
|
389
|
+
? 'bg-blue-100 text-blue-800 font-medium'
|
|
390
|
+
: 'text-gray-600 hover:bg-gray-100'}` },
|
|
391
|
+
"Original (",
|
|
392
|
+
resourceDetail.candidateCount,
|
|
393
|
+
")"),
|
|
394
|
+
React.createElement("button", { onClick: () => setShowFilteredView(true), className: `px-2 py-1 text-xs rounded ${showFilteredView
|
|
395
|
+
? 'bg-purple-100 text-purple-800 font-medium'
|
|
396
|
+
: 'text-gray-600 hover:bg-gray-100'}` },
|
|
397
|
+
"Filtered (",
|
|
398
|
+
filteredResourceDetail.candidateCount,
|
|
399
|
+
")")))),
|
|
400
|
+
React.createElement("div", { className: "space-y-4" },
|
|
401
|
+
React.createElement("div", null,
|
|
402
|
+
React.createElement("div", { className: "bg-gray-50 p-3 rounded border space-y-2" },
|
|
403
|
+
React.createElement("div", { className: "flex items-center space-x-2" },
|
|
404
|
+
React.createElement("span", { className: "text-sm font-medium text-gray-600" }, "Resource ID:"),
|
|
405
|
+
React.createElement("code", { className: "text-sm bg-white px-2 py-1 rounded border break-all" }, currentDetail.id)),
|
|
406
|
+
React.createElement("div", { className: "flex items-center space-x-2" },
|
|
407
|
+
React.createElement("span", { className: "text-sm font-medium text-gray-600" }, "Type:"),
|
|
408
|
+
React.createElement("span", { className: "text-sm" }, currentDetail.resourceType)),
|
|
409
|
+
React.createElement("div", { className: "flex items-center space-x-2" },
|
|
410
|
+
React.createElement("span", { className: "text-sm font-medium text-gray-600" }, "Candidates:"),
|
|
411
|
+
React.createElement("span", { className: `text-sm font-medium ${isShowingFiltered && currentDetail.candidateCount === 0
|
|
412
|
+
? 'text-red-600'
|
|
413
|
+
: isShowingFiltered && currentDetail.candidateCount < resourceDetail.candidateCount
|
|
414
|
+
? 'text-amber-600'
|
|
415
|
+
: 'text-green-600'}` },
|
|
416
|
+
currentDetail.candidateCount,
|
|
417
|
+
isShowingFiltered && currentDetail.candidateCount !== resourceDetail.candidateCount && (React.createElement("span", { className: "text-gray-400 ml-1" },
|
|
418
|
+
"(was ",
|
|
419
|
+
resourceDetail.candidateCount,
|
|
420
|
+
")")))),
|
|
421
|
+
isFilteringActive && (React.createElement("div", { className: "flex items-start space-x-2" },
|
|
422
|
+
React.createElement("span", { className: "text-sm font-medium text-gray-600" }, "Filter:"),
|
|
423
|
+
React.createElement("span", { className: "text-sm text-purple-700" }, Object.entries(filterContext)
|
|
424
|
+
.filter(([, value]) => value !== undefined && value !== '')
|
|
425
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
426
|
+
.join(', ') || 'No filters'))))),
|
|
427
|
+
currentDetail.candidates.length > 0 ? (React.createElement("div", null,
|
|
428
|
+
React.createElement("h5", { className: "font-medium text-gray-700 mb-2" },
|
|
429
|
+
isShowingFiltered ? 'Filtered ' : '',
|
|
430
|
+
"Candidates (",
|
|
431
|
+
currentDetail.candidates.length,
|
|
432
|
+
")"),
|
|
433
|
+
React.createElement("div", { className: "space-y-3 max-h-96 overflow-y-auto" }, currentDetail.candidates.map((candidate, index) => (React.createElement("div", { key: index, className: "bg-gray-50 p-3 rounded border" },
|
|
434
|
+
React.createElement("div", { className: "flex items-center justify-between mb-2" },
|
|
435
|
+
React.createElement("h6", { className: "font-medium text-gray-800 text-sm" },
|
|
436
|
+
"Candidate ",
|
|
437
|
+
index + 1),
|
|
438
|
+
React.createElement("div", { className: "flex items-center space-x-2 text-xs" },
|
|
439
|
+
candidate.isPartial && (React.createElement("span", { className: "bg-yellow-100 text-yellow-800 px-2 py-0.5 rounded" }, "Partial")),
|
|
440
|
+
React.createElement("span", { className: "bg-gray-200 text-gray-700 px-2 py-0.5 rounded" }, candidate.mergeMethod))),
|
|
441
|
+
candidate.conditions.length > 0 ? (React.createElement("div", { className: "mb-2" },
|
|
442
|
+
React.createElement("h6", { className: "text-xs font-medium text-gray-600 mb-1" }, "Conditions:"),
|
|
443
|
+
React.createElement("div", { className: "space-y-1" }, candidate.conditions.map((condition, condIndex) => (React.createElement("div", { key: condIndex, className: "flex items-center justify-between text-xs bg-blue-50 px-2 py-1 rounded" },
|
|
444
|
+
React.createElement("div", { className: "flex items-center space-x-1" },
|
|
445
|
+
React.createElement("span", { className: "font-medium text-blue-800" }, condition.qualifier),
|
|
446
|
+
React.createElement("span", { className: "text-blue-600" }, condition.operator),
|
|
447
|
+
React.createElement("span", { className: "text-blue-700" }, condition.value)),
|
|
448
|
+
React.createElement("div", { className: "flex items-center space-x-2 text-xs" },
|
|
449
|
+
React.createElement("span", { className: "text-blue-500" },
|
|
450
|
+
"p:",
|
|
451
|
+
condition.priority),
|
|
452
|
+
condition.scoreAsDefault !== undefined && (React.createElement("span", { className: "text-amber-600 font-medium" },
|
|
453
|
+
"d:",
|
|
454
|
+
condition.scoreAsDefault))))))))) : (React.createElement("div", { className: "mb-2" },
|
|
455
|
+
React.createElement("span", { className: "text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded" }, "No conditions (default)"))),
|
|
456
|
+
React.createElement("div", null,
|
|
457
|
+
React.createElement("h6", { className: "text-xs font-medium text-gray-600 mb-1" }, "Content:"),
|
|
458
|
+
React.createElement("pre", { className: "text-xs bg-white p-2 rounded border overflow-x-auto max-h-32 overflow-y-auto" }, JSON.stringify(candidate.json, null, 2))))))))) : (React.createElement("div", { className: "bg-red-50 border border-red-200 p-3 rounded" },
|
|
459
|
+
React.createElement("p", { className: "text-sm text-red-700 font-medium" }, "No candidates match the filter"),
|
|
460
|
+
React.createElement("p", { className: "text-xs text-red-600 mt-1" }, "This resource has been completely filtered out. Consider adjusting your filter criteria."))))));
|
|
461
|
+
};
|
|
462
|
+
export default FilterView;
|
|
463
|
+
//# sourceMappingURL=index.js.map
|