@fgv/ts-res-ui-components 5.1.0-2 → 5.1.0-20
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/lib/components/common/AppHeader.d.ts.map +1 -0
- package/lib/components/common/AppHeader.js.map +1 -0
- package/lib/components/common/AppLayout.d.ts.map +1 -0
- package/lib/components/common/AppLayout.js.map +1 -0
- package/lib/components/common/AppSidebar.d.ts.map +1 -0
- package/lib/components/common/AppSidebar.js.map +1 -0
- package/lib/components/common/NavigationWarningModal.d.ts.map +1 -0
- package/lib/components/common/NavigationWarningModal.js.map +1 -0
- package/lib/components/common/QualifierContextControl.d.ts.map +1 -0
- package/lib/components/common/QualifierContextControl.js.map +1 -0
- package/lib/components/common/ResolutionContextOptionsControl.d.ts.map +1 -0
- package/lib/components/common/ResolutionContextOptionsControl.js.map +1 -0
- package/lib/components/common/ResolutionResults/index.d.ts.map +1 -0
- package/lib/components/common/ResolutionResults/index.js.map +1 -0
- package/lib/components/common/ResourceListView.d.ts.map +1 -0
- package/lib/components/common/ResourceListView.js.map +1 -0
- package/lib/components/common/ResourcePickerOptionsControl.d.ts.map +1 -0
- package/lib/components/common/ResourcePickerOptionsControl.js.map +1 -0
- package/lib/components/common/ResourceTreeView.d.ts.map +1 -0
- package/lib/components/common/ResourceTreeView.js.map +1 -0
- package/lib/components/common/SourceResourceDetail/index.d.ts.map +1 -0
- package/lib/components/common/SourceResourceDetail/index.js.map +1 -0
- package/lib/components/forms/GenericQualifierTypeEditForm.d.ts.map +1 -0
- package/lib/components/forms/GenericQualifierTypeEditForm.js.map +1 -0
- package/lib/components/forms/HierarchyEditor.d.ts.map +1 -0
- package/lib/components/forms/HierarchyEditor.js.map +1 -0
- package/lib/components/forms/QualifierEditForm.d.ts.map +1 -0
- package/lib/components/forms/QualifierEditForm.js.map +1 -0
- package/lib/components/forms/QualifierTypeEditForm.d.ts.map +1 -0
- package/lib/components/forms/QualifierTypeEditForm.js.map +1 -0
- package/lib/components/forms/ResourceTypeEditForm.d.ts.map +1 -0
- package/lib/components/forms/ResourceTypeEditForm.js.map +1 -0
- package/lib/components/forms/index.d.ts.map +1 -0
- package/lib/components/forms/index.js.map +1 -0
- package/lib/components/orchestrator/ResourceOrchestrator.d.ts.map +1 -0
- package/lib/components/orchestrator/ResourceOrchestrator.js.map +1 -0
- package/lib/components/pickers/ResourcePicker/ResourceItem.d.ts.map +1 -0
- package/lib/components/pickers/ResourcePicker/ResourceItem.js.map +1 -0
- package/lib/components/pickers/ResourcePicker/ResourcePickerList.d.ts.map +1 -0
- package/lib/components/pickers/ResourcePicker/ResourcePickerList.js.map +1 -0
- package/lib/components/pickers/ResourcePicker/ResourcePickerTree.d.ts.map +1 -0
- package/lib/components/pickers/ResourcePicker/ResourcePickerTree.js.map +1 -0
- package/lib/components/pickers/ResourcePicker/index.d.ts.map +1 -0
- package/lib/components/pickers/ResourcePicker/index.js.map +1 -0
- package/lib/components/pickers/ResourcePicker/types.d.ts.map +1 -0
- package/lib/components/pickers/ResourcePicker/types.js.map +1 -0
- package/lib/components/pickers/ResourcePicker/utils/treeNavigation.d.ts.map +1 -0
- package/lib/components/pickers/ResourcePicker/utils/treeNavigation.js.map +1 -0
- package/lib/components/views/CompiledView/index.d.ts.map +1 -0
- package/lib/components/views/CompiledView/index.js.map +1 -0
- package/lib/components/views/ConfigurationView/index.d.ts.map +1 -0
- package/lib/components/views/ConfigurationView/index.js.map +1 -0
- package/lib/components/views/FilterView/index.d.ts.map +1 -0
- package/lib/components/views/FilterView/index.js.map +1 -0
- package/lib/components/views/GridView/EditableGridCell.d.ts.map +1 -0
- package/lib/components/views/GridView/EditableGridCell.js.map +1 -0
- package/lib/components/views/GridView/GridSelector.d.ts.map +1 -0
- package/lib/components/views/GridView/GridSelector.js.map +1 -0
- package/lib/components/views/GridView/MultiGridView.d.ts.map +1 -0
- package/lib/components/views/GridView/MultiGridView.js.map +1 -0
- package/lib/components/views/GridView/ResourceGrid.d.ts.map +1 -0
- package/lib/components/views/GridView/ResourceGrid.js.map +1 -0
- package/lib/components/views/GridView/SharedContextControls.d.ts.map +1 -0
- package/lib/components/views/GridView/SharedContextControls.js.map +1 -0
- package/lib/components/views/GridView/cells/BooleanCell.d.ts.map +1 -0
- package/lib/components/views/GridView/cells/BooleanCell.js.map +1 -0
- package/lib/components/views/GridView/cells/DropdownCell.d.ts.map +1 -0
- package/lib/components/views/GridView/cells/DropdownCell.js.map +1 -0
- package/lib/components/views/GridView/cells/StringCell.d.ts.map +1 -0
- package/lib/components/views/GridView/cells/StringCell.js.map +1 -0
- package/lib/components/views/GridView/cells/TriStateCell.d.ts.map +1 -0
- package/lib/components/views/GridView/cells/TriStateCell.js.map +1 -0
- package/lib/components/views/GridView/cells/index.d.ts.map +1 -0
- package/lib/components/views/GridView/cells/index.js.map +1 -0
- package/lib/components/views/GridView/index.d.ts.map +1 -0
- package/lib/components/views/GridView/index.js.map +1 -0
- package/lib/components/views/ImportView/index.d.ts.map +1 -0
- package/lib/components/views/ImportView/index.js.map +1 -0
- package/lib/components/views/MessagesWindow/index.d.ts.map +1 -0
- package/lib/components/views/MessagesWindow/index.js.map +1 -0
- package/lib/components/views/ResolutionView/EditableJsonView.d.ts.map +1 -0
- package/lib/components/views/ResolutionView/EditableJsonView.js.map +1 -0
- package/lib/components/views/ResolutionView/NewResourceModal.d.ts.map +1 -0
- package/lib/components/views/ResolutionView/NewResourceModal.js.map +1 -0
- package/lib/components/views/ResolutionView/UnifiedChangeControls.d.ts.map +1 -0
- package/lib/components/views/ResolutionView/UnifiedChangeControls.js.map +1 -0
- package/lib/components/views/ResolutionView/index.d.ts.map +1 -0
- package/lib/components/views/ResolutionView/index.js.map +1 -0
- package/lib/components/views/SourceView/index.d.ts.map +1 -0
- package/lib/components/views/SourceView/index.js.map +1 -0
- package/lib/contexts/ObservabilityContext.d.ts.map +1 -0
- package/lib/contexts/ObservabilityContext.js.map +1 -0
- package/lib/contexts/index.d.ts.map +1 -0
- package/lib/contexts/index.js.map +1 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/index.js.map +1 -0
- package/lib/hooks/useConfigurationState.d.ts.map +1 -0
- package/lib/hooks/useConfigurationState.js.map +1 -0
- package/lib/hooks/useFilterState.d.ts.map +1 -0
- package/lib/hooks/useFilterState.js.map +1 -0
- package/lib/hooks/useNavigationWarning.d.ts.map +1 -0
- package/lib/hooks/useNavigationWarning.js.map +1 -0
- package/lib/hooks/useResolutionState.d.ts.map +1 -0
- package/lib/hooks/useResolutionState.js.map +1 -0
- package/lib/hooks/useResourceData.d.ts.map +1 -0
- package/lib/hooks/useResourceData.js.map +1 -0
- package/lib/hooks/useSmartObservability.d.ts.map +1 -0
- package/lib/hooks/useSmartObservability.js.map +1 -0
- package/lib/hooks/useUrlParams.d.ts.map +1 -0
- package/lib/hooks/useUrlParams.js.map +1 -0
- package/lib/hooks/useViewState.d.ts.map +1 -0
- package/lib/hooks/useViewState.js.map +1 -0
- package/lib/index.browser.d.ts.map +1 -0
- package/lib/index.browser.js.map +1 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js.map +1 -0
- package/lib/namespaces/ConfigurationTools.d.ts.map +1 -0
- package/lib/namespaces/ConfigurationTools.js.map +1 -0
- package/lib/namespaces/DownloadTools.d.ts.map +1 -0
- package/lib/namespaces/DownloadTools.js.map +1 -0
- package/lib/namespaces/FilterTools.d.ts.map +1 -0
- package/lib/namespaces/FilterTools.js.map +1 -0
- package/lib/namespaces/GridTools.d.ts.map +1 -0
- package/lib/namespaces/GridTools.js.map +1 -0
- package/lib/namespaces/ImportTools.d.ts.map +1 -0
- package/lib/namespaces/ImportTools.js.map +1 -0
- package/lib/namespaces/ObservabilityTools.d.ts.map +1 -0
- package/lib/namespaces/ObservabilityTools.js.map +1 -0
- package/lib/namespaces/PickerTools.d.ts.map +1 -0
- package/lib/namespaces/PickerTools.js.map +1 -0
- package/lib/namespaces/ResolutionTools.d.ts.map +1 -0
- package/lib/namespaces/ResolutionTools.js.map +1 -0
- package/lib/namespaces/ResourceTools.d.ts.map +1 -0
- package/lib/namespaces/ResourceTools.js.map +1 -0
- package/lib/namespaces/TsResTools.d.ts.map +1 -0
- package/lib/namespaces/TsResTools.js.map +1 -0
- package/lib/namespaces/ViewStateTools.d.ts.map +1 -0
- package/lib/namespaces/ViewStateTools.js.map +1 -0
- package/lib/namespaces/ZipTools.d.ts.map +1 -0
- package/lib/namespaces/ZipTools.js.map +1 -0
- package/lib/namespaces/index.d.ts.map +1 -0
- package/lib/namespaces/index.js.map +1 -0
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils/cellValidation.d.ts.map +1 -0
- package/lib/utils/cellValidation.js.map +1 -0
- package/lib/utils/configurationUtils.d.ts.map +1 -0
- package/lib/utils/configurationUtils.js.map +1 -0
- package/lib/utils/downloadHelper.d.ts.map +1 -0
- package/lib/utils/downloadHelper.js.map +1 -0
- package/lib/utils/filterResources.d.ts.map +1 -0
- package/lib/utils/filterResources.js.map +1 -0
- package/lib/utils/observability/factories.d.ts.map +1 -0
- package/lib/utils/observability/factories.js.map +1 -0
- package/lib/utils/observability/implementations.d.ts.map +1 -0
- package/lib/utils/observability/implementations.js.map +1 -0
- package/lib/utils/observability/index.d.ts.map +1 -0
- package/lib/utils/observability/index.js.map +1 -0
- package/lib/utils/observability/interfaces.d.ts.map +1 -0
- package/lib/utils/observability/interfaces.js.map +1 -0
- package/lib/utils/resolutionEditing.d.ts.map +1 -0
- package/lib/utils/resolutionEditing.js.map +1 -0
- package/lib/utils/resolutionUtils.d.ts.map +1 -0
- package/lib/utils/resolutionUtils.js.map +1 -0
- package/lib/utils/resourceSelector.d.ts.map +1 -0
- package/lib/utils/resourceSelector.js.map +1 -0
- package/lib/utils/resourceSelectors.d.ts.map +1 -0
- package/lib/utils/resourceSelectors.js.map +1 -0
- package/lib/utils/tsResIntegration.d.ts.map +1 -0
- package/lib/utils/tsResIntegration.js.map +1 -0
- package/lib/utils/zipLoader/index.d.ts.map +1 -0
- package/lib/utils/zipLoader/index.js.map +1 -0
- package/lib/utils/zipLoader/zipProcessingHelpers.d.ts.map +1 -0
- package/lib/utils/zipLoader/zipProcessingHelpers.js.map +1 -0
- package/lib/utils/zipLoader/zipUtils.d.ts.map +1 -0
- package/lib/utils/zipLoader/zipUtils.js.map +1 -0
- package/package.json +25 -23
- package/dist/ts-res-ui-components.d.ts +0 -6795
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppHeader.d.ts","sourceRoot":"","sources":["../../../src/components/common/AppHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,eAAe;IACvB,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAexC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppHeader.js","sourceRoot":"","sources":["../../../src/components/common/AppHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B;;;GAGG;AACH,MAAM,SAAS,GAA8B,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE;IAC3F,MAAM,IAAI,GAAG,aAAa,CAAC;IAC3B,OAAO,CACL,gCAAQ,SAAS,EAAC,6CAA6C;QAC7D,6BAAK,SAAS,EAAC,6BAA6B;YAC1C,6BAAK,SAAS,EAAC,6BAA6B;gBAC1C,oBAAC,IAAI,IAAC,SAAS,EAAC,uBAAuB,GAAG;gBAC1C;oBACE,4BAAI,SAAS,EAAC,kCAAkC,IAAE,KAAK,CAAM;oBAC7D,2BAAG,SAAS,EAAC,uBAAuB,IAAE,WAAW,CAAK,CAClD,CACF,CACF,CACC,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import React from 'react';\n\ninterface IAppHeaderProps {\n icon: React.ComponentType<{ className?: string }>;\n title: string;\n description: string;\n}\n\n/**\n * Generic app header component with configurable icon, title, and description\n * @public\n */\nconst AppHeader: React.FC<IAppHeaderProps> = ({ icon: iconComponent, title, description }) => {\n const Icon = iconComponent;\n return (\n <header className=\"bg-white shadow-sm border-b border-gray-200\">\n <div className=\"container mx-auto px-4 py-4\">\n <div className=\"flex items-center space-x-3\">\n <Icon className=\"h-8 w-8 text-blue-600\" />\n <div>\n <h1 className=\"text-2xl font-bold text-gray-900\">{title}</h1>\n <p className=\"text-sm text-gray-600\">{description}</p>\n </div>\n </div>\n </div>\n </header>\n );\n};\n\nexport default AppHeader;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppLayout.d.ts","sourceRoot":"","sources":["../../../src/components/common/AppLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,UAAU,eAAe,CAAC,KAAK,GAAG,OAAO;IACvC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,EAAE,KAAK,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;IACpC,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,CAAC;IACpC,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC;QAC3B,YAAY,EAAE,KAAK,CAAC;QACpB,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;KACrC,CAAC,CAAC;CACJ;AAED;;;GAGG;AACH,QAAA,MAAM,SAAS,GAAI,KAAK,GAAG,OAAO,EAAG,yHAQlC,eAAe,CAAC,KAAK,CAAC,KAAG,KAAK,CAAC,YAoBjC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppLayout.js","sourceRoot":"","sources":["../../../src/components/common/AppLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAelD;;;GAGG;AACH,MAAM,SAAS,GAAG,CAAmB,EACnC,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,gBAAgB,EACF,EAAsB,EAAE;IAC/C,MAAM,MAAM,GAAG,eAAe,CAAC;IAC/B,MAAM,OAAO,GAAG,gBAAgB,CAAC;IACjC,OAAO,CACL,6BAAK,SAAS,EAAC,yBAAyB;QACtC,oBAAC,MAAM,OAAG;QAEV,6BAAK,SAAS,EAAC,MAAM;YACnB,oBAAC,OAAO,IAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,GAAI;YAEnE,8BAAM,SAAS,EAAC,wBAAwB;gBACtC,6BAAK,SAAS,EAAC,sBAAsB;oBACnC,6BAAK,SAAS,EAAC,sBAAsB,IAAE,QAAQ,CAAO;oBAEtD,oBAAC,cAAc,CAAC,cAAc,IAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAI,CACnF,CACD,CACH,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import React from 'react';\nimport { ViewStateTools } from '../../namespaces';\n\ninterface IAppLayoutProps<TTool = unknown> {\n children: React.ReactNode;\n selectedTool: TTool;\n onToolSelect: (tool: TTool) => void;\n messages: ViewStateTools.IMessage[];\n onClearMessages: () => void;\n header: React.ComponentType;\n sidebar: React.ComponentType<{\n selectedTool: TTool;\n onToolSelect: (tool: TTool) => void;\n }>;\n}\n\n/**\n * Generic app layout component with header, sidebar, main content area, and messages window\n * @public\n */\nconst AppLayout = <TTool = unknown,>({\n children,\n selectedTool,\n onToolSelect,\n messages,\n onClearMessages,\n header: headerComponent,\n sidebar: sidebarComponent\n}: IAppLayoutProps<TTool>): React.ReactElement => {\n const Header = headerComponent;\n const Sidebar = sidebarComponent;\n return (\n <div className=\"min-h-screen bg-gray-50\">\n <Header />\n\n <div className=\"flex\">\n <Sidebar selectedTool={selectedTool} onToolSelect={onToolSelect} />\n\n <main className=\"flex-1 overflow-hidden\">\n <div className=\"h-full flex flex-col\">\n <div className=\"flex-1 overflow-auto\">{children}</div>\n\n <ViewStateTools.MessagesWindow messages={messages} onClearMessages={onClearMessages} />\n </div>\n </main>\n </div>\n </div>\n );\n};\n\nexport default AppLayout;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppSidebar.d.ts","sourceRoot":"","sources":["../../../src/components/common/AppSidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,eAAe,CAAC,KAAK;IAC7B,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,gBAAgB,CAAC,KAAK;IAC9B,YAAY,EAAE,KAAK,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,QAAA,MAAM,UAAU,GAAI,KAAK,GAAG,OAAO,EAAG,8CAKnC,gBAAgB,CAAC,KAAK,CAAC,KAAG,KAAK,CAAC,YAkClC,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppSidebar.js","sourceRoot":"","sources":["../../../src/components/common/AppSidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAmB,EACpC,YAAY,EACZ,YAAY,EACZ,KAAK,EACL,KAAK,GAAG,OAAO,EACS,EAAsB,EAAE;IAChD,OAAO,CACL,+BAAO,SAAS,EAAC,2EAA2E;QAC1F,6BAAK,SAAS,EAAC,KAAK;YAClB,4BAAI,SAAS,EAAC,0CAA0C,IAAE,KAAK,CAAM;YACrE,6BAAK,SAAS,EAAC,WAAW,IACvB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBAClB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBACvB,MAAM,UAAU,GAAG,YAAY,KAAK,IAAI,CAAC,EAAE,CAAC;gBAE5C,OAAO,CACL,gCACE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EACpB,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EACpC,SAAS,EAAE,qDACT,UAAU;wBACR,CAAC,CAAC,iDAAiD;wBACnD,CAAC,CAAC,0DACN,EAAE;oBAEF,6BAAK,SAAS,EAAC,6BAA6B;wBAC1C,oBAAC,IAAI,IAAC,SAAS,EAAC,uBAAuB,GAAG;wBAC1C,6BAAK,SAAS,EAAC,gBAAgB;4BAC7B,6BAAK,SAAS,EAAC,qBAAqB,IAAE,IAAI,CAAC,IAAI,CAAO;4BACtD,6BAAK,SAAS,EAAC,4BAA4B,IAAE,IAAI,CAAC,WAAW,CAAO,CAChE,CACF,CACC,CACV,CAAC;YACJ,CAAC,CAAC,CACE,CACF,CACA,CACT,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import React from 'react';\n\ninterface IToolDefinition<TTool> {\n id: TTool;\n name: string;\n icon: React.ComponentType<{ className?: string }>;\n description: string;\n}\n\ninterface IAppSidebarProps<TTool> {\n selectedTool: TTool;\n onToolSelect: (tool: TTool) => void;\n tools: IToolDefinition<TTool>[];\n title?: string;\n}\n\n/**\n * Generic app sidebar component with configurable tools list\n * @public\n */\nconst AppSidebar = <TTool = unknown,>({\n selectedTool,\n onToolSelect,\n tools,\n title = 'Tools'\n}: IAppSidebarProps<TTool>): React.ReactElement => {\n return (\n <aside className=\"w-64 bg-white shadow-sm border-r border-gray-200 h-screen overflow-y-auto\">\n <div className=\"p-4\">\n <h2 className=\"text-lg font-semibold text-gray-900 mb-4\">{title}</h2>\n <nav className=\"space-y-2\">\n {tools.map((tool) => {\n const Icon = tool.icon;\n const isSelected = selectedTool === tool.id;\n\n return (\n <button\n key={String(tool.id)}\n onClick={() => onToolSelect(tool.id)}\n className={`w-full text-left p-3 rounded-lg transition-colors ${\n isSelected\n ? 'bg-blue-50 text-blue-700 border border-blue-200'\n : 'hover:bg-gray-50 text-gray-700 border border-transparent'\n }`}\n >\n <div className=\"flex items-center space-x-3\">\n <Icon className=\"h-5 w-5 flex-shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"font-medium text-sm\">{tool.name}</div>\n <div className=\"text-xs text-gray-500 mt-1\">{tool.description}</div>\n </div>\n </div>\n </button>\n );\n })}\n </nav>\n </div>\n </aside>\n );\n};\n\nexport default AppSidebar;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavigationWarningModal.d.ts","sourceRoot":"","sources":["../../../src/components/common/NavigationWarningModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,4BAA4B;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,QAAA,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CAgDlE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavigationWarningModal.js","sourceRoot":"","sources":["../../../src/components/common/NavigationWarningModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAUtE;;;GAGG;AACH,MAAM,sBAAsB,GAA2C,CAAC,EACtE,MAAM,EACN,QAAQ,EACR,SAAS,EACT,MAAM,EACN,iBAAiB,EAClB,EAAE,EAAE;IACH,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,OAAO,CACL,6BAAK,SAAS,EAAC,4EAA4E;QACzF,6BAAK,SAAS,EAAC,wDAAwD;YACrE,6BAAK,SAAS,EAAC,kCAAkC;gBAC/C,oBAAC,uBAAuB,IAAC,SAAS,EAAC,wBAAwB,GAAG;gBAC9D,4BAAI,SAAS,EAAC,mCAAmC,sBAAqB,CAClE;YAEN,2BAAG,SAAS,EAAC,4BAA4B,yEAErC;YAEJ,6BAAK,SAAS,EAAC,4BAA4B;gBACzC,gCACE,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAC,iLAAiL,aAGpL;gBAET,gCACE,OAAO,EAAE,SAAS,EAClB,SAAS,EAAC,iLAAiL,sBAGpL;gBAER,MAAM,IAAI,CACT,gCACE,OAAO,EAAE,MAAM,EACf,SAAS,EAAC,qLAAqL,sBAGxL,CACV,CACG,CACF,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,sBAAsB,CAAC","sourcesContent":["import React from 'react';\nimport { ExclamationTriangleIcon } from '@heroicons/react/24/outline';\n\ninterface INavigationWarningModalProps {\n isOpen: boolean;\n onCancel: () => void;\n onConfirm: () => void;\n onSave?: () => void;\n hasUnsavedChanges: boolean;\n}\n\n/**\n * Modal component for warning users about unsaved changes before navigation\n * @public\n */\nconst NavigationWarningModal: React.FC<INavigationWarningModalProps> = ({\n isOpen,\n onCancel,\n onConfirm,\n onSave,\n hasUnsavedChanges\n}) => {\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\n <div className=\"bg-white rounded-lg shadow-xl p-6 max-w-md w-full mx-4\">\n <div className=\"flex items-center space-x-3 mb-4\">\n <ExclamationTriangleIcon className=\"h-6 w-6 text-amber-500\" />\n <h3 className=\"text-lg font-medium text-gray-900\">Unsaved Changes</h3>\n </div>\n\n <p className=\"text-sm text-gray-600 mb-6\">\n You have unsaved configuration changes. What would you like to do?\n </p>\n\n <div className=\"flex justify-end space-x-3\">\n <button\n onClick={onCancel}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\"\n >\n Cancel\n </button>\n\n <button\n onClick={onConfirm}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\"\n >\n Discard Changes\n </button>\n\n {onSave && (\n <button\n onClick={onSave}\n className=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\"\n >\n Save & Continue\n </button>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default NavigationWarningModal;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QualifierContextControl.d.ts","sourceRoot":"","sources":["../../../src/components/common/QualifierContextControl.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAI5E;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,sDAAsD;IACtD,QAAQ,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACrE,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACvC,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuHG;AACH,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,6BAA6B,CA8N3E,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QualifierContextControl.js","sourceRoot":"","sources":["../../../src/components/common/QualifierContextControl.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useMemo } from 'react';\nimport { IProcessedResources, IQualifierControlOptions } from '../../types';\nimport { useObservability } from '../../contexts';\nimport { Converters } from '@fgv/ts-utils';\n\n/**\n * Props for the QualifierContextControl component.\n *\n * @public\n */\nexport interface IQualifierContextControlProps {\n /** Name of the qualifier being controlled */\n qualifierName: string;\n /** Current value of the qualifier */\n value: string | undefined;\n /** Callback fired when the qualifier value changes */\n onChange: (qualifierName: string, value: string | undefined) => void;\n /** Whether the control is disabled */\n disabled?: boolean;\n /** Placeholder text for empty value */\n placeholder?: string;\n /** Optional processed resources for auto-suggesting values */\n resources?: IProcessedResources | null;\n /** Optional CSS classes to apply to the control */\n className?: string;\n /** Extended options for controlling the qualifier behavior */\n options?: IQualifierControlOptions;\n}\n\n/**\n * A control component for managing individual qualifier context values.\n *\n * QualifierContextControl provides an interface for setting and modifying qualifier values\n * used in resource resolution context. It can optionally suggest values based on available\n * resources and supports both manual input and selection from predefined options.\n *\n * @example\n * ```tsx\n * import { ResolutionTools } from '@fgv/ts-res-ui-components';\n *\n * function QualifierSettings() {\n * const [context, setContext] = useState<Record<string, string | undefined>>({\n * language: 'en-US',\n * platform: undefined\n * });\n *\n * const handleQualifierChange = (name: string, value: string | undefined) => {\n * setContext(prev => ({ ...prev, [name]: value }));\n * };\n *\n * return (\n * <div>\n * <ResolutionTools.QualifierContextControl\n * qualifierName=\"language\"\n * value={context.language}\n * onChange={handleQualifierChange}\n * placeholder=\"Select language...\"\n * />\n * <ResolutionTools.QualifierContextControl\n * qualifierName=\"platform\"\n * value={context.platform}\n * onChange={handleQualifierChange}\n * placeholder=\"Select platform...\"\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using with processed resources for value suggestions\n * import { ResolutionTools, ResourceTools } from '@fgv/ts-res-ui-components';\n *\n * function SmartQualifierControl() {\n * const { state } = ResourceTools.useResourceData();\n * const [qualifierValue, setQualifierValue] = useState<string | undefined>();\n *\n * return (\n * <ResolutionTools.QualifierContextControl\n * qualifierName=\"region\"\n * value={qualifierValue}\n * onChange={(name, value) => setQualifierValue(value)}\n * resources={state.resources}\n * placeholder=\"Auto-suggested regions...\"\n * className=\"w-full\"\n * />\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using with host-managed values and custom options\n * import { ResolutionTools } from '@fgv/ts-res-ui-components';\n *\n * function HostControlledQualifier() {\n * return (\n * <ResolutionTools.QualifierContextControl\n * qualifierName=\"platform\"\n * value={undefined} // Ignored when hostValue is set\n * onChange={() => {}} // Called only when editable\n * options={{\n * editable: false,\n * hostValue: 'web',\n * showHostValue: true,\n * placeholder: 'Platform controlled by application',\n * className: 'border-blue-300'\n * }}\n * />\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using for selective visibility and editability\n * function ConditionalQualifierControls() {\n * const [userRole, setUserRole] = useState<'admin' | 'user'>('user');\n *\n * return (\n * <div>\n * <ResolutionTools.QualifierContextControl\n * qualifierName=\"environment\"\n * value={envValue}\n * onChange={handleEnvChange}\n * options={{\n * visible: userRole === 'admin', // Only visible to admins\n * editable: true,\n * placeholder: 'Select environment...'\n * }}\n * />\n * <ResolutionTools.QualifierContextControl\n * qualifierName=\"language\"\n * value={langValue}\n * onChange={handleLangChange}\n * options={{\n * visible: true,\n * editable: userRole === 'admin', // Only editable by admins\n * placeholder: userRole === 'admin' ? 'Select language...' : 'Language locked'\n * }}\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @public\n */\nexport const QualifierContextControl: React.FC<IQualifierContextControlProps> = ({\n qualifierName,\n value,\n onChange,\n disabled = false,\n placeholder,\n resources,\n className = '',\n options\n}) => {\n // Get observability context\n const o11y = useObservability();\n\n // Extract qualifier type information from system configuration\n const qualifierInfo = useMemo(() => {\n if (!resources?.system?.qualifiers) {\n return { hasEnumeratedValues: false, enumeratedValues: [] };\n }\n\n try {\n // Get qualifier declaration\n const qualifierResult = resources.system.qualifiers.validating.get(qualifierName);\n\n if (!qualifierResult.isSuccess()) {\n return { hasEnumeratedValues: false, enumeratedValues: [] };\n }\n\n const qualifier = qualifierResult.value;\n\n // Access the instantiated qualifier type\n if (qualifier.type) {\n const qualifierType = qualifier.type;\n\n // Get configuration JSON safely\n const configResult = qualifierType.getConfigurationJson();\n if (configResult.isSuccess()) {\n const config = configResult.value;\n\n // Extract enumerated values based on system type\n let enumeratedValues: string[] = [];\n let caseSensitive = true;\n\n if (config.systemType === 'literal' && config.configuration) {\n // Type-safe access to literal configuration\n const literalConfig = config.configuration;\n if (typeof literalConfig === 'object' && literalConfig !== null) {\n const literalConverter = Converters.object({\n enumeratedValues: Converters.arrayOf(Converters.string).optional(),\n caseSensitive: Converters.boolean.optional()\n });\n\n const conversionResult = literalConverter.convert(literalConfig);\n if (conversionResult.isSuccess()) {\n const convertedConfig = conversionResult.value;\n enumeratedValues = convertedConfig.enumeratedValues || [];\n caseSensitive = convertedConfig.caseSensitive !== false;\n }\n }\n } else if (config.systemType === 'territory' && config.configuration) {\n // Type-safe access to territory configuration\n const territoryConfig = config.configuration;\n if (typeof territoryConfig === 'object' && territoryConfig !== null) {\n const territoryConverter = Converters.object({\n allowedTerritories: Converters.arrayOf(Converters.string).optional()\n });\n\n const conversionResult = territoryConverter.convert(territoryConfig);\n if (conversionResult.isSuccess()) {\n const convertedConfig = conversionResult.value;\n enumeratedValues = convertedConfig.allowedTerritories || [];\n }\n }\n }\n\n if (enumeratedValues.length > 0) {\n return {\n hasEnumeratedValues: true,\n enumeratedValues,\n systemType: config.systemType || 'literal',\n caseSensitive\n };\n }\n }\n }\n\n return { hasEnumeratedValues: false, enumeratedValues: [] };\n } catch (error) {\n o11y.diag.warn(`Failed to extract qualifier type info for ${qualifierName}:`, error);\n return { hasEnumeratedValues: false, enumeratedValues: [] };\n }\n }, [qualifierName, resources?.system?.qualifiers]);\n\n // Apply options with defaults\n const isVisible = options?.visible ?? true;\n const isEditable = options?.editable ?? true;\n const hostValue = options?.hostValue;\n const showHostValue = options?.showHostValue ?? true;\n const customPlaceholder = options?.placeholder;\n const customClassName = options?.className || '';\n\n // Determine effective values\n const isEffectivelyDisabled = disabled || !isEditable;\n const effectiveValue = hostValue !== undefined ? hostValue ?? '' : value ?? '';\n const isHostManaged = hostValue !== undefined;\n\n // Determine placeholder text\n const effectivePlaceholder = customPlaceholder || placeholder || `Enter ${qualifierName} value`;\n\n const handleChange = (newValue: string): void => {\n // Only allow changes if not host-managed and editable\n if (!isHostManaged && isEditable) {\n onChange(qualifierName, newValue || undefined);\n }\n };\n\n const handleClear = (): void => {\n // Only allow clearing if not host-managed and editable\n if (!isHostManaged && isEditable) {\n onChange(qualifierName, undefined);\n }\n };\n\n const hasEnumeratedValues = qualifierInfo.hasEnumeratedValues && qualifierInfo.enumeratedValues.length > 0;\n\n // Don't render if not visible\n if (!isVisible) {\n return null;\n }\n\n return (\n <div className={`bg-white rounded border border-gray-200 p-2 ${className} ${customClassName}`}>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-sm font-medium text-gray-700 min-w-0 flex-shrink-0 flex items-center gap-1\">\n {qualifierName}:\n {isHostManaged && showHostValue && (\n <span\n className=\"text-[10px] px-1 py-0.5 rounded bg-blue-100 text-blue-700\"\n title=\"Host-managed value\"\n >\n HOST\n </span>\n )}\n {!isHostManaged && !isEditable && (\n <span\n className=\"text-[10px] px-1 py-0.5 rounded bg-gray-200 text-gray-700\"\n title=\"Locked by host or configuration\"\n >\n LOCKED\n </span>\n )}\n </label>\n <div className=\"flex-1 flex items-center gap-1\">\n {hasEnumeratedValues ? (\n // Dropdown for enumerated values\n <select\n value={effectiveValue}\n onChange={(e) => handleChange(e.target.value)}\n disabled={isEffectivelyDisabled}\n title={isHostManaged ? 'Host-managed value - controlled externally' : undefined}\n className={`flex-1 px-2 py-1 border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm min-w-0 ${\n isEffectivelyDisabled ? 'bg-gray-100 text-gray-400' : ''\n } ${isHostManaged ? 'border-blue-300 bg-blue-50' : ''}`}\n >\n <option value=\"\">\n {isHostManaged\n ? effectiveValue !== ''\n ? effectiveValue\n : '(undefined)'\n : isEffectivelyDisabled\n ? 'Disabled'\n : effectiveValue === ''\n ? '(undefined)'\n : effectivePlaceholder}\n </option>\n {qualifierInfo.enumeratedValues.map((enumValue: string) => (\n <option key={enumValue} value={enumValue}>\n {enumValue}\n </option>\n ))}\n </select>\n ) : (\n // Text input for non-enumerated values\n <input\n type=\"text\"\n value={effectiveValue}\n onChange={(e) => handleChange(e.target.value)}\n disabled={isEffectivelyDisabled}\n title={isHostManaged ? 'Host-managed value - controlled externally' : undefined}\n className={`flex-1 px-2 py-1 border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm min-w-0 ${\n isEffectivelyDisabled ? 'bg-gray-100 text-gray-400' : ''\n } ${isHostManaged ? 'border-blue-300 bg-blue-50' : ''}`}\n placeholder={\n isHostManaged && effectiveValue === ''\n ? '(undefined)'\n : isEffectivelyDisabled\n ? 'Disabled'\n : effectiveValue === ''\n ? '(undefined)'\n : effectivePlaceholder\n }\n />\n )}\n {!isEffectivelyDisabled && !isHostManaged && effectiveValue !== '' && (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"px-2 py-1 text-xs text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded transition-colors\"\n title=\"Set to undefined\"\n >\n ✕\n </button>\n )}\n </div>\n </div>\n {/* Show enumerated values indicator */}\n {hasEnumeratedValues && (\n <div className=\"mt-1 text-xs text-blue-600\">\n {qualifierInfo.enumeratedValues.length} predefined values\n </div>\n )}\n </div>\n );\n};\n\nexport default QualifierContextControl;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResolutionContextOptionsControl.d.ts","sourceRoot":"","sources":["../../../src/components/common/ResolutionContextOptionsControl.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAErD,OAAO,EAAE,yBAAyB,EAA4B,MAAM,aAAa,CAAC;AAElF;;;GAGG;AACH,MAAM,WAAW,qCAAqC;IACpD,8BAA8B;IAC9B,OAAO,EAAE,yBAAyB,CAAC;IACnC,mCAAmC;IACnC,eAAe,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC9D,6CAA6C;IAC7C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,gFAAgF;IAChF,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;IACzE,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2CAA2C;IAC3C,6BAA6B,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,+EAA+E;IAC/E,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,qDAAqD;IACrD,kCAAkC,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,+BAA+B,EAAE,KAAK,CAAC,EAAE,CAAC,qCAAqC,CAgY3F,CAAC;AAEF,eAAe,+BAA+B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResolutionContextOptionsControl.js","sourceRoot":"","sources":["../../../src/components/common/ResolutionContextOptionsControl.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useCallback } from 'react';\nimport { CogIcon, ChevronDownIcon, ChevronUpIcon, XMarkIcon } from '@heroicons/react/24/outline';\nimport { IResolutionContextOptions, IQualifierControlOptions } from '../../types';\n\n/**\n * Props for the ResolutionContextOptionsControl component.\n * @public\n */\nexport interface IResolutionContextOptionsControlProps {\n /** Current context options */\n options: IResolutionContextOptions;\n /** Callback when options change */\n onOptionsChange: (options: IResolutionContextOptions) => void;\n /** Available qualifiers for configuration */\n availableQualifiers?: string[];\n /** How to present the options control (default: 'hidden' for production use) */\n presentation?: 'hidden' | 'inline' | 'collapsible' | 'popup' | 'popover';\n /** Custom class name */\n className?: string;\n /** Title for the control section */\n title?: string;\n /** Editing/creation toggle - when provided, show UI to control it */\n allowResourceCreation?: boolean;\n /** Callback for editing/creation toggle */\n onAllowResourceCreationChange?: (allow: boolean) => void;\n /** Pending resources list visibility - when provided, show UI to control it */\n showPendingResourcesInList?: boolean;\n /** Callback for pending resources list visibility */\n onShowPendingResourcesInListChange?: (show: boolean) => void;\n}\n\n/**\n * Reusable control for configuring ResolutionView context options.\n *\n * Provides a clean interface for adjusting context behavior including:\n * - Visibility of context controls, current context display, and action buttons\n * - Per-qualifier options (visibility, editability, host values)\n * - Global defaults and appearance customization\n *\n * Can be rendered in multiple presentation modes:\n * - 'hidden': Not displayed (default for production)\n * - 'inline': Always expanded with full controls visible\n * - 'collapsible': Expandable/collapsible section\n * - 'popover': Small dropdown overlay\n * - 'popup': Full modal dialog\n *\n * @example\n * ```tsx\n * import { ResolutionContextOptionsControl } from '@fgv/ts-res-ui-components';\n *\n * function ContextConfiguration() {\n * const [contextOptions, setContextOptions] = useState<IResolutionContextOptions>({});\n *\n * return (\n * <ResolutionContextOptionsControl\n * options={contextOptions}\n * onOptionsChange={setContextOptions}\n * availableQualifiers={['language', 'platform', 'env']}\n * presentation=\"collapsible\"\n * title=\"Context Configuration\"\n * />\n * );\n * }\n * ```\n *\n * @public\n */\nexport const ResolutionContextOptionsControl: React.FC<IResolutionContextOptionsControlProps> = ({\n options,\n onOptionsChange,\n availableQualifiers = [],\n presentation = 'hidden',\n className = '',\n title = 'Context Options',\n allowResourceCreation,\n onAllowResourceCreationChange,\n showPendingResourcesInList,\n onShowPendingResourcesInListChange\n}) => {\n // Early return for hidden presentation\n if (presentation === 'hidden') {\n return null;\n }\n\n const [isExpanded, setIsExpanded] = useState(presentation === 'inline');\n const [showPopover, setShowPopover] = useState(false);\n\n const handleOptionChange = useCallback(\n <K extends keyof IResolutionContextOptions>(key: K, value: IResolutionContextOptions[K]) => {\n onOptionsChange({\n ...options,\n [key]: value\n });\n },\n [options, onOptionsChange]\n );\n\n const handleQualifierOptionChange = useCallback(\n (\n qualifierName: string,\n optionKey: keyof IQualifierControlOptions,\n value: boolean | string | undefined\n ) => {\n const currentQualifierOptions = options.qualifierOptions || {};\n const currentOptions = currentQualifierOptions[qualifierName] || {};\n\n const updatedQualifierOptions = {\n ...currentQualifierOptions,\n [qualifierName]: {\n ...currentOptions,\n [optionKey]: value\n }\n };\n\n handleOptionChange('qualifierOptions', updatedQualifierOptions);\n },\n [options.qualifierOptions, handleOptionChange]\n );\n\n const handleHostManagedValueChange = useCallback(\n (qualifierName: string, value: string | undefined) => {\n const currentHostValues = options.hostManagedValues || {};\n const updatedHostValues = {\n ...currentHostValues,\n [qualifierName]: value || undefined\n };\n\n // Remove undefined values to keep object clean\n if (value === undefined || value === '') {\n delete updatedHostValues[qualifierName];\n }\n\n handleOptionChange('hostManagedValues', updatedHostValues);\n },\n [options.hostManagedValues, handleOptionChange]\n );\n\n const renderControls = (): React.ReactElement => (\n <div className=\"space-y-4\">\n {/* Visibility Settings */}\n <div className=\"space-y-3\">\n <h4 className=\"text-sm font-medium text-gray-700\">Context Panel Visibility</h4>\n\n <div className=\"space-y-2\">\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={options.showContextControls !== false}\n onChange={(e) => handleOptionChange('showContextControls', e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Show Context Controls\n </label>\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={options.showCurrentContext !== false}\n onChange={(e) => handleOptionChange('showCurrentContext', e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Show Current Context Display\n </label>\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={options.showContextActions !== false}\n onChange={(e) => handleOptionChange('showContextActions', e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Show Context Action Buttons\n </label>\n </div>\n </div>\n\n {/* Global Defaults */}\n <div className=\"space-y-3 pt-3 border-t border-gray-200\">\n <h4 className=\"text-sm font-medium text-gray-700\">Global Defaults</h4>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={options.defaultQualifierVisible !== false}\n onChange={(e) => handleOptionChange('defaultQualifierVisible', e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Qualifiers Visible by Default\n </label>\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={options.defaultQualifierEditable !== false}\n onChange={(e) => handleOptionChange('defaultQualifierEditable', e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Qualifiers Editable by Default\n </label>\n </div>\n\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">Panel Title</label>\n <input\n type=\"text\"\n value={options.contextPanelTitle || ''}\n onChange={(e) => handleOptionChange('contextPanelTitle', e.target.value || undefined)}\n placeholder=\"Context Configuration\"\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n />\n </div>\n\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">Global Placeholder</label>\n <input\n type=\"text\"\n value={typeof options.globalPlaceholder === 'string' ? options.globalPlaceholder : ''}\n onChange={(e) => handleOptionChange('globalPlaceholder', e.target.value || undefined)}\n placeholder=\"Enter {qualifierName} value\"\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n />\n <p className=\"text-xs text-gray-500 mt-1\">Use {'{qualifierName}'} for dynamic qualifier names</p>\n </div>\n </div>\n\n {/* Editing & Creation (optional, when props provided) */}\n {(allowResourceCreation !== undefined || showPendingResourcesInList !== undefined) && (\n <div className=\"space-y-3 pt-3 border-t border-gray-200\">\n <h4 className=\"text-sm font-medium text-gray-700\">Editing & Creation</h4>\n {allowResourceCreation !== undefined && (\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={!!allowResourceCreation}\n onChange={(e) => onAllowResourceCreationChange?.(e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Allow Resource Creation\n </label>\n )}\n {showPendingResourcesInList !== undefined && (\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={!!showPendingResourcesInList}\n onChange={(e) => onShowPendingResourcesInListChange?.(e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Show Pending Resources In List\n </label>\n )}\n </div>\n )}\n\n {/* Per-Qualifier Configuration */}\n {availableQualifiers.length > 0 && (\n <div className=\"space-y-3 pt-3 border-t border-gray-200\">\n <h4 className=\"text-sm font-medium text-gray-700\">Per-Qualifier Settings</h4>\n\n <div className=\"space-y-3\">\n {availableQualifiers.map((qualifierName) => {\n const qualifierOptions = options.qualifierOptions?.[qualifierName] || {};\n const hostValue = options.hostManagedValues?.[qualifierName];\n\n return (\n <div key={qualifierName} className=\"border border-gray-200 rounded p-3\">\n <h5 className=\"text-xs font-medium text-gray-800 mb-2\">{qualifierName}</h5>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2 mb-2\">\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={qualifierOptions.visible !== false}\n onChange={(e) =>\n handleQualifierOptionChange(qualifierName, 'visible', e.target.checked)\n }\n className=\"mr-2 rounded\"\n />\n Visible\n </label>\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={qualifierOptions.editable !== false}\n onChange={(e) =>\n handleQualifierOptionChange(qualifierName, 'editable', e.target.checked)\n }\n className=\"mr-2 rounded\"\n />\n Editable\n </label>\n </div>\n\n <div className=\"space-y-2\">\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">\n Custom Placeholder\n </label>\n <input\n type=\"text\"\n value={qualifierOptions.placeholder || ''}\n onChange={(e) =>\n handleQualifierOptionChange(\n qualifierName,\n 'placeholder',\n e.target.value || undefined\n )\n }\n placeholder={`Enter ${qualifierName} value`}\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n />\n </div>\n\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">\n Host-Managed Value\n </label>\n <input\n type=\"text\"\n value={hostValue || ''}\n onChange={(e) => handleHostManagedValueChange(qualifierName, e.target.value)}\n placeholder=\"Leave empty for user control\"\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n />\n <p className=\"text-xs text-gray-500 mt-1\">\n When set, overrides user input and makes field readonly\n </p>\n </div>\n\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={qualifierOptions.showHostValue !== false}\n onChange={(e) =>\n handleQualifierOptionChange(qualifierName, 'showHostValue', e.target.checked)\n }\n className=\"mr-2 rounded\"\n />\n Show Host-Managed Indicator\n </label>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n );\n\n if (presentation === 'popover') {\n return (\n <div className={`relative ${className}`}>\n <button\n onClick={() => setShowPopover(!showPopover)}\n className=\"flex items-center px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <CogIcon className=\"w-3 h-3 mr-1\" />\n {title}\n <ChevronDownIcon className=\"w-3 h-3 ml-1\" />\n </button>\n\n {showPopover && (\n <>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-10\" onClick={() => setShowPopover(false)} />\n\n {/* Popover */}\n <div className=\"absolute top-full left-0 mt-1 w-96 bg-white border border-gray-200 rounded-lg shadow-lg z-20 p-4 max-h-96 overflow-y-auto\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-medium text-gray-900\">{title}</h3>\n <button\n onClick={() => setShowPopover(false)}\n className=\"p-1 text-gray-400 hover:text-gray-600\"\n >\n <XMarkIcon className=\"w-4 h-4\" />\n </button>\n </div>\n {renderControls()}\n </div>\n </>\n )}\n </div>\n );\n }\n\n if (presentation === 'collapsible') {\n return (\n <div className={`border border-gray-200 rounded-lg ${className}`}>\n <button\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"w-full flex items-center justify-between px-4 py-2 text-sm font-medium text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 rounded-t-lg\"\n >\n <span className=\"flex items-center\">\n <CogIcon className=\"w-4 h-4 mr-2\" />\n {title}\n </span>\n {isExpanded ? <ChevronUpIcon className=\"w-4 h-4\" /> : <ChevronDownIcon className=\"w-4 h-4\" />}\n </button>\n\n {isExpanded && <div className=\"p-4 border-t border-gray-200\">{renderControls()}</div>}\n </div>\n );\n }\n\n if (presentation === 'popup') {\n return (\n <div className={`relative ${className}`}>\n <button\n onClick={() => setShowPopover(!showPopover)}\n className=\"flex items-center px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <CogIcon className=\"w-3 h-3 mr-1\" />\n {title}\n <ChevronDownIcon className=\"w-3 h-3 ml-1\" />\n </button>\n\n {showPopover && (\n <>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-40\" onClick={() => setShowPopover(false)} />\n\n {/* Modal Popup */}\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div className=\"bg-white border border-gray-200 rounded-lg shadow-xl max-w-2xl w-full max-h-[80vh] overflow-y-auto\">\n <div className=\"flex items-center justify-between p-4 border-b border-gray-200\">\n <h3 className=\"text-lg font-medium text-gray-900\">{title}</h3>\n <button\n onClick={() => setShowPopover(false)}\n className=\"p-1 text-gray-400 hover:text-gray-600\"\n >\n <XMarkIcon className=\"w-5 h-5\" />\n </button>\n </div>\n <div className=\"p-4\">{renderControls()}</div>\n </div>\n </div>\n </>\n )}\n </div>\n );\n }\n\n // presentation === 'inline'\n return (\n <div className={`border border-gray-200 rounded-lg p-4 ${className}`}>\n <h3 className=\"text-sm font-medium text-gray-900 mb-3 flex items-center\">\n <CogIcon className=\"w-4 h-4 mr-2\" />\n {title}\n </h3>\n {renderControls()}\n </div>\n );\n};\n\nexport default ResolutionContextOptionsControl;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/common/ResolutionResults/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAG3C,OAAO,EAEL,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AAIxB;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,4CAA4C;IAC5C,MAAM,EAAE,iBAAiB,CAAC;IAC1B,iEAAiE;IACjE,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAC9C,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;IACvC,qDAAqD;IACrD,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,4DAA4D;IAC5D,qBAAqB,CAAC,EAAE,sBAAsB,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8GG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAwT/D,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/common/ResolutionResults/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useCallback } from 'react';\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { Result } from '@fgv/ts-utils';\nimport {\n ICandidateInfo,\n IResolutionActions,\n IResolutionState,\n IResourceEditorFactory,\n IResolutionResult\n} from '../../../types';\nimport { EditableJsonView } from '../../views/ResolutionView/EditableJsonView';\nimport { useObservability } from '../../../contexts';\n\n/**\n * Props for the ResolutionResults component.\n *\n * @public\n */\nexport interface IResolutionResultsProps {\n /** The resolution result data to display */\n result: IResolutionResult;\n /** View mode determining how resolution results are presented */\n viewMode: 'composed' | 'best' | 'all' | 'raw';\n /** Current context values used for resolution */\n contextValues: Record<string, string | undefined>;\n /** Optional resolution actions for interactive features */\n resolutionActions?: IResolutionActions;\n /** Optional resolution state for editing features */\n resolutionState?: IResolutionState;\n /** Optional factory for creating custom resource editors */\n resourceEditorFactory?: IResourceEditorFactory;\n}\n\n/**\n * A comprehensive component for displaying resource resolution results with multiple view modes.\n *\n * ResolutionResults provides a flexible interface for presenting resource resolution data\n * in various formats including composed values, best candidate selection, all candidates,\n * and raw resolution data. It supports interactive editing when provided with appropriate\n * actions and state, and can be customized with resource editor factories.\n *\n * @example\n * ```tsx\n * import { ResolutionResults, ObservabilityProvider } from '@fgv/ts-res-ui-components';\n *\n * function BasicResolutionDisplay() {\n * const [viewMode, setViewMode] = useState<'composed' | 'best' | 'all' | 'raw'>('composed');\n * const resolutionResult = { value: 'Hello World', candidates: [...] };\n * const context = { language: 'en-US', platform: 'web' };\n *\n * return (\n * <ObservabilityProvider>\n * <div>\n * <div className=\"view-controls\">\n * <button onClick={() => setViewMode('composed')}>Composed</button>\n * <button onClick={() => setViewMode('best')}>Best</button>\n * <button onClick={() => setViewMode('all')}>All</button>\n * <button onClick={() => setViewMode('raw')}>Raw</button>\n * </div>\n * <ResolutionResults\n * result={resolutionResult}\n * viewMode={viewMode}\n * contextValues={context}\n * />\n * </div>\n * </ObservabilityProvider>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using with resolution state and editing capabilities\n * import { ResolutionTools, ObservabilityProvider } from '@fgv/ts-res-ui-components';\n *\n * function InteractiveResolutionResults() {\n * const { state: resolutionState, actions: resolutionActions } = ResolutionTools.useResolutionState();\n *\n * const customEditorFactory = {\n * createEditor: (resourceId: string, value: JsonValue) => ({\n * success: true,\n * editor: MyCustomEditor\n * })\n * };\n *\n * return (\n * <ObservabilityProvider>\n * <ResolutionResults\n * result={resolutionState.currentResult}\n * viewMode={resolutionState.viewMode}\n * contextValues={resolutionState.context}\n * resolutionActions={resolutionActions}\n * resolutionState={resolutionState}\n * resourceEditorFactory={customEditorFactory}\n * />\n * </ObservabilityProvider>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Advanced usage with orchestrator integration\n * import { ResourceTools } from '@fgv/ts-res-ui-components';\n *\n * function OrchestratorResolutionDisplay() {\n * const { state, actions } = ResourceTools.useResourceData();\n * const [selectedResourceId, setSelectedResourceId] = useState<string | null>(null);\n *\n * const handleResourceResolve = async (resourceId: string) => {\n * const result = await actions.resolveResource(resourceId, state.resolutionState.context);\n * if (result.isSuccess()) {\n * setSelectedResourceId(resourceId);\n * }\n * };\n *\n * if (!selectedResourceId || !state.resolutionState.currentResult) {\n * return <div>Select a resource to see resolution results</div>;\n * }\n *\n * return (\n * <div className=\"resolution-display\">\n * <div className=\"resource-info\">\n * <h3>Resolution for: {selectedResourceId}</h3>\n * <p>Context: {JSON.stringify(state.resolutionState.context)}</p>\n * </div>\n * <ResolutionResults\n * result={state.resolutionState.currentResult}\n * viewMode={state.resolutionState.viewMode}\n * contextValues={state.resolutionState.context}\n * resolutionActions={{\n * ...state.resolutionState,\n * setViewMode: actions.setResolutionViewMode,\n * saveEdit: actions.saveResourceEdit\n * }}\n * resolutionState={state.resolutionState}\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @public\n */\nexport const ResolutionResults: React.FC<IResolutionResultsProps> = ({\n result,\n viewMode,\n contextValues,\n resolutionActions,\n resolutionState,\n resourceEditorFactory\n}) => {\n const o11y = useObservability();\n\n // Helper function to create the appropriate resource editor\n const createResourceEditor = useCallback(\n (\n value: JsonValue,\n resourceId: string,\n isEdited: boolean,\n editedValue: JsonValue | undefined,\n onSave?: (resourceId: string, editedValue: JsonValue, originalValue?: JsonValue) => Result<void>,\n onCancel?: (resourceId: string) => void,\n disabled?: boolean,\n className?: string\n ) => {\n // Try to get resource type from the result\n const resourceType = result?.resource?.resourceType?.key ?? 'unknown';\n\n // Try the factory first if provided\n if (resourceEditorFactory) {\n try {\n const factoryResult = resourceEditorFactory.createEditor(resourceId, resourceType, value);\n if (factoryResult.success) {\n const CustomEditor = factoryResult.editor;\n return (\n <CustomEditor\n value={value}\n resourceId={resourceId}\n isEdited={isEdited}\n editedValue={editedValue}\n onSave={onSave}\n onCancel={onCancel}\n disabled={disabled}\n className={className}\n />\n );\n } else {\n // Factory couldn't create editor, log and fall back to JSON editor\n if (factoryResult.message) {\n o11y.diag.info(`default-editor: Using default JSON editor - ${factoryResult.message}`);\n }\n // Continue to fallback JSON editor below\n }\n } catch (error) {\n // Factory threw an error, log and fall back to JSON editor\n o11y.diag.warn(\n `editor-factory: Failed to create editor - ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n // Continue to fallback JSON editor below\n }\n }\n\n // Fall back to the default JSON editor\n return (\n <EditableJsonView\n value={value}\n resourceId={resourceId}\n isEdited={isEdited}\n editedValue={editedValue}\n onSave={onSave}\n onCancel={onCancel}\n disabled={disabled}\n className={className}\n />\n );\n },\n [resourceEditorFactory, result, o11y]\n );\n\n if (!result.success) {\n return (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-4\">\n <h4 className=\"font-medium text-red-800 mb-2\">Resolution Failed</h4>\n <p className=\"text-sm text-red-600\">{result.error}</p>\n </div>\n );\n }\n\n if (viewMode === 'raw') {\n return (\n <div className=\"space-y-4\">\n <div>\n <h4 className=\"font-medium text-gray-800 mb-2\">Raw Resolution Data</h4>\n <pre className=\"text-xs bg-white p-3 rounded border overflow-x-auto\">\n {JSON.stringify(\n {\n context: contextValues,\n resource: result.resource\n ? {\n id: result.resource.id,\n candidateCount: result.resource.candidates.length\n }\n : null,\n bestCandidate: result.bestCandidate?.json,\n allCandidates: result.allCandidates?.map((c) => c.json),\n composedValue: result.composedValue,\n error: result.error\n },\n null,\n 2\n )}\n </pre>\n </div>\n </div>\n );\n }\n\n if (viewMode === 'composed') {\n return (\n <div className=\"space-y-4\">\n {result.composedValue ? (\n createResourceEditor(\n result.composedValue,\n result.resourceId,\n resolutionActions?.hasEdit?.(result.resourceId) || false,\n resolutionActions?.getEditedValue?.(result.resourceId),\n resolutionActions?.saveEdit,\n () => {}, // Could add cancel functionality if needed\n resolutionState?.isApplyingEdits || false\n )\n ) : (\n <div className=\"bg-yellow-50 border border-yellow-200 rounded p-3\">\n <p className=\"text-sm text-yellow-800\">No composed value available for the current context.</p>\n {result.error && <p className=\"text-xs text-yellow-600 mt-1\">{result.error}</p>}\n </div>\n )}\n\n {result.resource && (\n <div>\n <h4 className=\"font-medium text-gray-800 mb-2\">Resource Info</h4>\n <div className=\"bg-white p-3 rounded border text-sm\">\n <div>\n <strong>ID:</strong> {result.resource.id}\n </div>\n <div>\n <strong>Type:</strong> {result.resource.resourceType.key}\n </div>\n <div>\n <strong>Total Candidates:</strong> {result.resource.candidates.length}\n </div>\n </div>\n </div>\n )}\n </div>\n );\n }\n\n if (viewMode === 'best') {\n return (\n <div className=\"space-y-4\">\n <div>\n <h4 className=\"font-medium text-gray-800 mb-2\">Best Match</h4>\n {result.bestCandidate ? (\n <div className=\"bg-white p-3 rounded border border-green-200\">\n <div className=\"text-sm font-medium text-gray-700 mb-2\">\n Selected candidate for current context\n </div>\n <pre className=\"text-xs bg-gray-50 p-2 rounded overflow-x-auto\">\n {JSON.stringify(result.bestCandidate.json, null, 2)}\n </pre>\n </div>\n ) : (\n <div className=\"bg-yellow-50 border border-yellow-200 rounded p-3\">\n <p className=\"text-sm text-yellow-800\">No best candidate found for the current context.</p>\n {result.error && <p className=\"text-xs text-yellow-600 mt-1\">{result.error}</p>}\n </div>\n )}\n </div>\n </div>\n );\n }\n\n // 'all' view mode\n const regularMatchingCandidates =\n result.candidateDetails?.filter((c: ICandidateInfo) => c.matched && !c.isDefaultMatch) || [];\n const defaultMatchingCandidates =\n result.candidateDetails?.filter((c: ICandidateInfo) => c.matched && c.isDefaultMatch) || [];\n const nonMatchingCandidates = result.candidateDetails?.filter((c: ICandidateInfo) => !c.matched) || [];\n\n const getMatchTypeColor = (type: string): string => {\n switch (type) {\n case 'match':\n return 'bg-green-100 text-green-800';\n case 'matchAsDefault':\n return 'bg-amber-100 text-amber-800';\n case 'noMatch':\n return 'bg-red-100 text-red-800';\n default:\n return 'bg-gray-100 text-gray-800';\n }\n };\n\n const getMatchTypeIcon = (type: string): string => {\n switch (type) {\n case 'match':\n return '✓';\n case 'matchAsDefault':\n return '≈';\n case 'noMatch':\n return '✗';\n default:\n return '?';\n }\n };\n\n return (\n <div className=\"space-y-4\">\n {/* Regular Matching Candidates */}\n {regularMatchingCandidates.length > 0 && (\n <div>\n <h4 className=\"font-medium text-gray-800 mb-2\">Regular Matches</h4>\n <div className=\"space-y-2\">\n {regularMatchingCandidates.map((candidateInfo: ICandidateInfo, index: number) => (\n <div\n key={`regular-${candidateInfo.candidateIndex}`}\n className=\"bg-white p-3 rounded border border-green-200\"\n >\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"text-sm font-medium text-gray-700 flex items-center space-x-2\">\n <span>\n Candidate {candidateInfo.candidateIndex + 1} {index === 0 ? '(Best Match)' : ''}\n </span>\n <span\n className={`px-2 py-1 rounded text-xs ${getMatchTypeColor(candidateInfo.matchType)}`}\n >\n {getMatchTypeIcon(candidateInfo.matchType)} {candidateInfo.matchType}\n </span>\n </div>\n </div>\n <pre className=\"text-xs bg-gray-50 p-2 rounded overflow-x-auto\">\n {JSON.stringify(candidateInfo.candidate.json, null, 2)}\n </pre>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Default Matching Candidates */}\n {defaultMatchingCandidates.length > 0 && (\n <div>\n <h4 className=\"font-medium text-gray-800 mb-2\">Default Matches</h4>\n <div className=\"space-y-2\">\n {defaultMatchingCandidates.map((candidateInfo: ICandidateInfo) => (\n <div\n key={`default-${candidateInfo.candidateIndex}`}\n className=\"bg-white p-3 rounded border border-amber-200\"\n >\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"text-sm font-medium text-gray-700 flex items-center space-x-2\">\n <span>Candidate {candidateInfo.candidateIndex + 1}</span>\n <span\n className={`px-2 py-1 rounded text-xs ${getMatchTypeColor(candidateInfo.matchType)}`}\n >\n {getMatchTypeIcon(candidateInfo.matchType)} {candidateInfo.matchType}\n </span>\n </div>\n </div>\n <pre className=\"text-xs bg-gray-50 p-2 rounded overflow-x-auto\">\n {JSON.stringify(candidateInfo.candidate.json, null, 2)}\n </pre>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Show message when no matches */}\n {regularMatchingCandidates.length === 0 && defaultMatchingCandidates.length === 0 && (\n <div>\n <h4 className=\"font-medium text-gray-800 mb-2\">Matching Candidates</h4>\n <p className=\"text-sm text-gray-600\">No candidates matched the current context.</p>\n </div>\n )}\n\n {/* Non-matching Candidates */}\n {nonMatchingCandidates.length > 0 && (\n <div>\n <h4 className=\"font-medium text-gray-500 mb-2\">Non-matching Candidates</h4>\n <div className=\"space-y-2\">\n {nonMatchingCandidates.slice(0, 3).map((candidateInfo: ICandidateInfo) => (\n <div\n key={`non-matching-${candidateInfo.candidateIndex}`}\n className=\"bg-gray-50 p-3 rounded border border-gray-200 opacity-75\"\n >\n <div className=\"text-sm font-medium text-gray-500 mb-2\">\n Candidate {candidateInfo.candidateIndex + 1}\n </div>\n <pre className=\"text-xs bg-gray-100 p-2 rounded overflow-x-auto text-gray-600\">\n {JSON.stringify(candidateInfo.candidate.json, null, 2)}\n </pre>\n </div>\n ))}\n {nonMatchingCandidates.length > 3 && (\n <div className=\"text-center text-sm text-gray-500\">\n ... and {nonMatchingCandidates.length - 3} more non-matching candidates\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default ResolutionResults;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceListView.d.ts","sourceRoot":"","sources":["../../../src/components/common/ResourceListView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;;GAIG;AACH,UAAU,sBAAsB;IAC9B,mDAAmD;IACnD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,sDAAsD;IACtD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iDAAiD;IACjD,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAiD7D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceListView.js","sourceRoot":"","sources":["../../../src/components/common/ResourceListView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAoB/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAqC,CAAC,EACjE,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,GAAG,EAAE,EACf,SAAS,GAAG,EAAE,EACf,EAAE,EAAE;IACH,+BAA+B;IAC/B,MAAM,mBAAmB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC7C,MAAM,QAAQ,GAAG,UAAU;YACzB,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;YACjF,CAAC,CAAC,WAAW,CAAC;QAEhB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IAE9B,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,CACL,6BAAK,SAAS,EAAE,GAAG,SAAS,gCAAgC;YAC1D,+BAAI,UAAU,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,wBAAwB,CAAK,CAC7E,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,6BAAK,SAAS,EAAE,GAAG,SAAS,kBAAkB,IAC3C,mBAAmB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CACvC,6BACE,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,yGACT,kBAAkB,KAAK,UAAU,CAAC,CAAC,CAAC,2CAA2C,CAAC,CAAC,CAAC,EACpF,IACE,UAAU,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAC/F,EAAE,EACF,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC;QAE3C,oBAAC,gBAAgB,IAAC,SAAS,EAAC,2CAA2C,GAAG;QAC1E,8BACE,SAAS,EAAE,oBACT,kBAAkB,KAAK,UAAU,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,eACtE,EAAE,EACF,KAAK,EAAE,UAAU,IAEhB,UAAU,CACN,CACH,CACP,CAAC,CACE,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import React from 'react';\nimport { DocumentTextIcon } from '@heroicons/react/24/outline';\n\n/**\n * Props for the ResourceListView component.\n *\n * @public\n */\ninterface IResourceListViewProps {\n /** Array of resource IDs to display in the list */\n resourceIds: string[];\n /** Currently selected resource ID for highlighting */\n selectedResourceId: string | null;\n /** Callback fired when a resource is selected */\n onResourceSelect: (resourceId: string) => void;\n /** Optional search term to filter resources (case-insensitive) */\n searchTerm?: string;\n /** Optional CSS classes to apply to the container */\n className?: string;\n}\n\n/**\n * A flat list view component for displaying and selecting resources.\n *\n * ResourceListView provides a simple, scrollable list interface for browsing through\n * resource IDs with built-in search filtering, selection highlighting, and hover effects.\n * It's optimized for flat resource hierarchies and provides a clean, accessible interface.\n *\n * @example\n * ```tsx\n * import { ResourceListView } from '@fgv/ts-res-ui-components';\n *\n * function ResourceBrowser() {\n * const [selectedId, setSelectedId] = useState<string | null>(null);\n * const [searchTerm, setSearchTerm] = useState('');\n *\n * const resourceIds = ['user.welcome', 'user.goodbye', 'error.notFound', 'button.save'];\n *\n * return (\n * <div>\n * <input\n * type=\"text\"\n * placeholder=\"Search resources...\"\n * value={searchTerm}\n * onChange={(e) => setSearchTerm(e.target.value)}\n * />\n * <ResourceListView\n * resourceIds={resourceIds}\n * selectedResourceId={selectedId}\n * onResourceSelect={setSelectedId}\n * searchTerm={searchTerm}\n * className=\"h-64 border rounded\"\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using with orchestrator state\n * import { ResourceTools } from '@fgv/ts-res-ui-components';\n *\n * function OrchestratorResourceList() {\n * const { state, actions } = ResourceTools.useResourceData();\n * const resourceIds = state.resources?.summary?.resourceIds || [];\n *\n * return (\n * <ResourceListView\n * resourceIds={resourceIds}\n * selectedResourceId={state.selectedResourceId}\n * onResourceSelect={(id) => actions.selectResource(id)}\n * className=\"flex-1 min-h-0\"\n * />\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With search integration and custom handling\n * function SearchableResourceList({ resources, onResourceDetails }) {\n * const [searchTerm, setSearchTerm] = useState('');\n * const [selectedId, setSelectedId] = useState<string | null>(null);\n *\n * const handleResourceSelect = (resourceId: string) => {\n * setSelectedId(resourceId);\n * onResourceDetails(resourceId);\n * };\n *\n * return (\n * <div className=\"flex flex-col h-full\">\n * <div className=\"p-4 border-b\">\n * <input\n * type=\"search\"\n * placeholder=\"Filter resources...\"\n * value={searchTerm}\n * onChange={(e) => setSearchTerm(e.target.value)}\n * className=\"w-full px-3 py-2 border rounded-md\"\n * />\n * </div>\n * <ResourceListView\n * resourceIds={resources.map(r => r.id)}\n * selectedResourceId={selectedId}\n * onResourceSelect={handleResourceSelect}\n * searchTerm={searchTerm}\n * className=\"flex-1 min-h-0\"\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @public\n */\nexport const ResourceListView: React.FC<IResourceListViewProps> = ({\n resourceIds,\n selectedResourceId,\n onResourceSelect,\n searchTerm = '',\n className = ''\n}) => {\n // Filter and sort resource IDs\n const filteredResourceIds = React.useMemo(() => {\n const filtered = searchTerm\n ? resourceIds.filter((id) => id.toLowerCase().includes(searchTerm.toLowerCase()))\n : resourceIds;\n\n return filtered.sort();\n }, [resourceIds, searchTerm]);\n\n if (filteredResourceIds.length === 0) {\n return (\n <div className={`${className} p-4 text-center text-gray-500`}>\n <p>{searchTerm ? 'No resources match your search' : 'No resources available'}</p>\n </div>\n );\n }\n\n return (\n <div className={`${className} overflow-y-auto`}>\n {filteredResourceIds.map((resourceId) => (\n <div\n key={resourceId}\n className={`flex items-center px-3 py-2 cursor-pointer hover:bg-gray-100 border-b border-gray-100 last:border-b-0 ${\n selectedResourceId === resourceId ? 'bg-purple-50 border-l-2 border-purple-500' : ''\n } ${\n searchTerm && resourceId.toLowerCase().includes(searchTerm.toLowerCase()) ? 'bg-yellow-50' : ''\n }`}\n onClick={() => onResourceSelect(resourceId)}\n >\n <DocumentTextIcon className=\"w-4 h-4 text-green-500 mr-2 flex-shrink-0\" />\n <span\n className={`text-sm truncate ${\n selectedResourceId === resourceId ? 'font-medium text-purple-900' : 'text-gray-700'\n }`}\n title={resourceId}\n >\n {resourceId}\n </span>\n </div>\n ))}\n </div>\n );\n};\n\nexport default ResourceListView;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourcePickerOptionsControl.d.ts","sourceRoot":"","sources":["../../../src/components/common/ResourcePickerOptionsControl.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAErD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAEzE;;;GAGG;AACH,MAAM,WAAW,kCAAkC;IACjD,6BAA6B;IAC7B,OAAO,EAAE,sBAAsB,CAAC;IAChC,mCAAmC;IACnC,eAAe,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC3D,gFAAgF;IAChF,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;IACzE,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,4BAA4B,EAAE,KAAK,CAAC,EAAE,CAAC,kCAAkC,CAiTrF,CAAC;AAEF,eAAe,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourcePickerOptionsControl.js","sourceRoot":"","sources":["../../../src/components/common/ResourcePickerOptionsControl.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useCallback } from 'react';\nimport { CogIcon, ChevronDownIcon, ChevronUpIcon, XMarkIcon } from '@heroicons/react/24/outline';\nimport { IResourcePickerOptions } from '../pickers/ResourcePicker/types';\n\n/**\n * Props for the ResourcePickerOptionsControl component.\n * @public\n */\nexport interface IResourcePickerOptionsControlProps {\n /** Current picker options */\n options: IResourcePickerOptions;\n /** Callback when options change */\n onOptionsChange: (options: IResourcePickerOptions) => void;\n /** How to present the options control (default: 'hidden' for production use) */\n presentation?: 'hidden' | 'inline' | 'collapsible' | 'popup' | 'popover';\n /** Custom class name */\n className?: string;\n /** Available quick branch paths for selection */\n quickBranchPaths?: string[];\n /** Whether to show advanced options like branch isolation */\n showAdvanced?: boolean;\n /** Title for the control section */\n title?: string;\n}\n\n/**\n * Reusable control for configuring ResourcePicker options.\n *\n * Provides a clean interface for adjusting picker behavior including:\n * - View mode selection (list/tree)\n * - Search and view toggle settings\n * - Branch isolation configuration\n * - Quick path selection buttons\n *\n * Can be rendered in multiple presentation modes:\n * - 'hidden': Not displayed (default for production)\n * - 'inline': Always expanded with full controls visible\n * - 'collapsible': Expandable/collapsible section\n * - 'popover': Small dropdown overlay\n * - 'popup': Full modal dialog\n *\n * @public\n */\nexport const ResourcePickerOptionsControl: React.FC<IResourcePickerOptionsControlProps> = ({\n options,\n onOptionsChange,\n presentation = 'hidden',\n className = '',\n quickBranchPaths = ['strings', 'app', 'images', 'app.ui'],\n showAdvanced = true,\n title = 'Picker Options'\n}) => {\n // Early return for hidden presentation\n if (presentation === 'hidden') {\n return null;\n }\n\n const [isExpanded, setIsExpanded] = useState(presentation === 'inline');\n const [showPopover, setShowPopover] = useState(false);\n\n const handleOptionChange = useCallback(\n <K extends keyof IResourcePickerOptions>(key: K, value: IResourcePickerOptions[K]) => {\n onOptionsChange({\n ...options,\n [key]: value\n });\n },\n [options, onOptionsChange]\n );\n\n const handleQuickPathSelect = useCallback(\n (path: string) => {\n handleOptionChange('rootPath', path);\n },\n [handleOptionChange]\n );\n\n const clearRootPath = useCallback(() => {\n handleOptionChange('rootPath', undefined);\n handleOptionChange('hideRootNode', false);\n }, [handleOptionChange]);\n\n const renderControls = (): React.ReactElement => (\n <div className=\"space-y-4\">\n {/* Basic Settings */}\n <div className=\"space-y-3\">\n <h4 className=\"text-sm font-medium text-gray-700\">View Settings</h4>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">Default View</label>\n <select\n value={options.defaultView || 'list'}\n onChange={(e) => handleOptionChange('defaultView', e.target.value as 'list' | 'tree')}\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n >\n <option value=\"list\">List</option>\n <option value=\"tree\">Tree</option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">Search Scope</label>\n <select\n value={options.searchScope || 'all'}\n onChange={(e) => handleOptionChange('searchScope', e.target.value as 'all' | 'current-branch')}\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n disabled={!options.enableSearch}\n >\n <option value=\"all\">All Resources</option>\n <option value=\"current-branch\">Current Branch</option>\n </select>\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={options.enableSearch ?? true}\n onChange={(e) => handleOptionChange('enableSearch', e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Enable Search\n </label>\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={options.showViewToggle ?? true}\n onChange={(e) => handleOptionChange('showViewToggle', e.target.checked)}\n className=\"mr-2 rounded\"\n />\n Show View Toggle\n </label>\n </div>\n\n {options.enableSearch && (\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">Search Placeholder</label>\n <input\n type=\"text\"\n value={options.searchPlaceholder || ''}\n onChange={(e) => handleOptionChange('searchPlaceholder', e.target.value || undefined)}\n placeholder=\"Search resources...\"\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n />\n </div>\n )}\n </div>\n\n {/* Branch Isolation */}\n {showAdvanced && (\n <div className=\"space-y-3 pt-3 border-t border-gray-200\">\n <h4 className=\"text-sm font-medium text-gray-700\">Branch Isolation</h4>\n\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">Root Path</label>\n <input\n type=\"text\"\n value={options.rootPath || ''}\n onChange={(e) => handleOptionChange('rootPath', e.target.value || undefined)}\n placeholder=\"e.g., strings or app.ui\"\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n />\n <p className=\"text-xs text-gray-500 mt-1\">Show only resources under this path</p>\n </div>\n\n <div>\n <label className=\"flex items-center text-xs\">\n <input\n type=\"checkbox\"\n checked={options.hideRootNode ?? false}\n onChange={(e) => handleOptionChange('hideRootNode', e.target.checked)}\n className=\"mr-2 rounded\"\n disabled={!options.rootPath}\n />\n Hide Root Node\n </label>\n <p className=\"text-xs text-gray-500 mt-1 ml-5\">\n Show only children of root path (requires Root Path)\n </p>\n </div>\n\n {/* Quick Branch Selection */}\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-2\">Quick Paths</label>\n <div className=\"flex flex-wrap gap-1\">\n {quickBranchPaths.map((path) => (\n <button\n key={path}\n onClick={() => handleQuickPathSelect(path)}\n className={`px-2 py-1 text-xs rounded border ${\n options.rootPath === path\n ? 'bg-blue-100 border-blue-300 text-blue-700'\n : 'bg-gray-50 border-gray-300 text-gray-600 hover:bg-gray-100'\n }`}\n >\n {path}\n </button>\n ))}\n <button\n onClick={clearRootPath}\n className={`px-2 py-1 text-xs rounded border ${\n !options.rootPath\n ? 'bg-blue-100 border-blue-300 text-blue-700'\n : 'bg-gray-50 border-gray-300 text-gray-600 hover:bg-gray-100'\n }`}\n >\n Clear\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Display Settings */}\n <div className=\"space-y-3 pt-3 border-t border-gray-200\">\n <h4 className=\"text-sm font-medium text-gray-700\">Display</h4>\n\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">Empty Message</label>\n <input\n type=\"text\"\n value={options.emptyMessage || ''}\n onChange={(e) => handleOptionChange('emptyMessage', e.target.value || undefined)}\n placeholder=\"No resources available\"\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n />\n </div>\n\n <div>\n <label className=\"block text-xs font-medium text-gray-600 mb-1\">Height</label>\n <input\n type=\"text\"\n value={options.height || ''}\n onChange={(e) => handleOptionChange('height', e.target.value || undefined)}\n placeholder=\"600px\"\n className=\"w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500\"\n />\n <p className=\"text-xs text-gray-500 mt-1\">CSS height value (px, rem, %, etc.)</p>\n </div>\n </div>\n </div>\n );\n\n if (presentation === 'popover') {\n return (\n <div className={`relative ${className}`}>\n <button\n onClick={() => setShowPopover(!showPopover)}\n className=\"flex items-center px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <CogIcon className=\"w-3 h-3 mr-1\" />\n {title}\n <ChevronDownIcon className=\"w-3 h-3 ml-1\" />\n </button>\n\n {showPopover && (\n <>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-10\" onClick={() => setShowPopover(false)} />\n\n {/* Popover */}\n <div className=\"absolute top-full left-0 mt-1 w-80 bg-white border border-gray-200 rounded-lg shadow-lg z-20 p-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-medium text-gray-900\">{title}</h3>\n <button\n onClick={() => setShowPopover(false)}\n className=\"p-1 text-gray-400 hover:text-gray-600\"\n >\n <XMarkIcon className=\"w-4 h-4\" />\n </button>\n </div>\n {renderControls()}\n </div>\n </>\n )}\n </div>\n );\n }\n\n if (presentation === 'collapsible') {\n return (\n <div className={`border border-gray-200 rounded-lg ${className}`}>\n <button\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"w-full flex items-center justify-between px-4 py-2 text-sm font-medium text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 rounded-t-lg\"\n >\n <span className=\"flex items-center\">\n <CogIcon className=\"w-4 h-4 mr-2\" />\n {title}\n </span>\n {isExpanded ? <ChevronUpIcon className=\"w-4 h-4\" /> : <ChevronDownIcon className=\"w-4 h-4\" />}\n </button>\n\n {isExpanded && <div className=\"p-4 border-t border-gray-200\">{renderControls()}</div>}\n </div>\n );\n }\n\n if (presentation === 'popup') {\n return (\n <div className={`relative ${className}`}>\n <button\n onClick={() => setShowPopover(!showPopover)}\n className=\"flex items-center px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <CogIcon className=\"w-3 h-3 mr-1\" />\n {title}\n <ChevronDownIcon className=\"w-3 h-3 ml-1\" />\n </button>\n\n {showPopover && (\n <>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-40\" onClick={() => setShowPopover(false)} />\n\n {/* Modal Popup */}\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div className=\"bg-white border border-gray-200 rounded-lg shadow-xl max-w-md w-full max-h-96 overflow-y-auto\">\n <div className=\"flex items-center justify-between p-4 border-b border-gray-200\">\n <h3 className=\"text-lg font-medium text-gray-900\">{title}</h3>\n <button\n onClick={() => setShowPopover(false)}\n className=\"p-1 text-gray-400 hover:text-gray-600\"\n >\n <XMarkIcon className=\"w-5 h-5\" />\n </button>\n </div>\n <div className=\"p-4\">{renderControls()}</div>\n </div>\n </div>\n </>\n )}\n </div>\n );\n }\n\n // presentation === 'inline'\n return (\n <div className={`border border-gray-200 rounded-lg p-4 ${className}`}>\n <h3 className=\"text-sm font-medium text-gray-900 mb-3 flex items-center\">\n <CogIcon className=\"w-4 h-4 mr-2\" />\n {title}\n </h3>\n {renderControls()}\n </div>\n );\n};\n\nexport default ResourcePickerOptionsControl;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceTreeView.d.ts","sourceRoot":"","sources":["../../../src/components/common/ResourceTreeView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAQ9D,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGjD;;;;GAIG;AACH,UAAU,sBAAsB;IAC9B,mEAAmE;IACnE,SAAS,EAAE,SAAS,CAAC,sBAAsB,GAAG,OAAO,CAAC,0BAA0B,CAAC;IACjF,sDAAsD;IACtD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iDAAiD;IACjD,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkIG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAoP7D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceTreeView.js","sourceRoot":"","sources":["../../../src/components/common/ResourceTreeView.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useMemo, useCallback } from 'react';\nimport {\n ChevronRightIcon,\n ChevronDownIcon,\n DocumentTextIcon,\n FolderIcon,\n FolderOpenIcon\n} from '@heroicons/react/24/outline';\nimport { Resources, Runtime } from '@fgv/ts-res';\nimport { useObservability } from '../../contexts';\n\n/**\n * Props for the ResourceTreeView component.\n *\n * @public\n */\ninterface IResourceTreeViewProps {\n /** Resource manager or compiled collection to display as a tree */\n resources: Resources.ResourceManagerBuilder | Runtime.CompiledResourceCollection;\n /** Currently selected resource ID for highlighting */\n selectedResourceId: string | null;\n /** Callback fired when a resource is selected */\n onResourceSelect: (resourceId: string) => void;\n /** Optional search term to filter and highlight resources */\n searchTerm?: string;\n /** Optional CSS classes to apply to the container */\n className?: string;\n}\n\n/**\n * A hierarchical tree view component for displaying and navigating resource structures.\n *\n * ResourceTreeView provides an interactive tree interface for browsing resource hierarchies,\n * with support for expansion/collapse, search filtering, selection highlighting, and intelligent\n * tree navigation. It automatically builds the tree structure from ts-res resource managers\n * and supports both builder and compiled resource collections.\n *\n * @example\n * ```tsx\n * import { ResourceTreeView } from '@fgv/ts-res-ui-components';\n *\n * function HierarchicalResourceBrowser() {\n * const [selectedId, setSelectedId] = useState<string | null>(null);\n * const [searchTerm, setSearchTerm] = useState('');\n *\n * return (\n * <div className=\"flex flex-col h-full\">\n * <div className=\"p-4 border-b\">\n * <input\n * type=\"search\"\n * placeholder=\"Search in tree...\"\n * value={searchTerm}\n * onChange={(e) => setSearchTerm(e.target.value)}\n * className=\"w-full px-3 py-2 border rounded-md\"\n * />\n * </div>\n * <ResourceTreeView\n * resources={resourceManager}\n * selectedResourceId={selectedId}\n * onResourceSelect={setSelectedId}\n * searchTerm={searchTerm}\n * className=\"flex-1 min-h-0 p-2\"\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using with orchestrator state for integrated navigation\n * import { ResourceTools } from '@fgv/ts-res-ui-components';\n *\n * function OrchestratorTreeView() {\n * const { state, actions } = ResourceTools.useResourceData();\n * const [searchTerm, setSearchTerm] = useState('');\n *\n * if (!state.resources) {\n * return <div className=\"p-4 text-gray-500\">No resources loaded</div>;\n * }\n *\n * return (\n * <div className=\"h-full flex flex-col\">\n * <div className=\"flex items-center gap-2 p-2 border-b\">\n * <input\n * type=\"search\"\n * placeholder=\"Search resources...\"\n * value={searchTerm}\n * onChange={(e) => setSearchTerm(e.target.value)}\n * className=\"flex-1 px-3 py-1 text-sm border rounded\"\n * />\n * <span className=\"text-xs text-gray-500\">\n * {state.resources.summary?.resourceCount || 0} resources\n * </span>\n * </div>\n * <ResourceTreeView\n * resources={state.resources.resourceManager}\n * selectedResourceId={state.selectedResourceId}\n * onResourceSelect={(id) => actions.selectResource(id)}\n * searchTerm={searchTerm}\n * className=\"flex-1 min-h-0 overflow-auto\"\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Advanced usage with custom tree navigation\n * function AdvancedResourceTree({ resources, onResourceAction }) {\n * const [selectedId, setSelectedId] = useState<string | null>(null);\n * const [searchTerm, setSearchTerm] = useState('');\n *\n * const handleResourceSelect = (resourceId: string) => {\n * setSelectedId(resourceId);\n * onResourceAction('select', resourceId);\n * };\n *\n * const handleKeyDown = (event: React.KeyboardEvent) => {\n * if (event.key === 'Enter' && selectedId) {\n * onResourceAction('open', selectedId);\n * }\n * };\n *\n * return (\n * <div\n * className=\"resource-tree-container\"\n * onKeyDown={handleKeyDown}\n * tabIndex={0}\n * >\n * <div className=\"tree-header\">\n * <input\n * type=\"search\"\n * placeholder=\"Find resources in tree...\"\n * value={searchTerm}\n * onChange={(e) => setSearchTerm(e.target.value)}\n * />\n * <div className=\"tree-stats\">\n * {resources && (\n * <span>\n * Tree: {resources.getBuiltResourceTree().isSuccess() ? 'Built' : 'Error'}\n * </span>\n * )}\n * </div>\n * </div>\n * <ResourceTreeView\n * resources={resources}\n * selectedResourceId={selectedId}\n * onResourceSelect={handleResourceSelect}\n * searchTerm={searchTerm}\n * className=\"tree-content\"\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @public\n */\nexport const ResourceTreeView: React.FC<IResourceTreeViewProps> = ({\n resources,\n selectedResourceId,\n onResourceSelect,\n searchTerm = '',\n className = ''\n}) => {\n // Get observability context\n const o11y = useObservability();\n\n const [expandedNodes, setExpandedNodes] = useState<Set<string>>(new Set());\n\n // Build the tree structure from resources\n const treeData = useMemo(() => {\n if (!resources) return null;\n\n // Get the tree from the resources\n const treeResult = resources.getBuiltResourceTree();\n if (treeResult.isFailure()) {\n o11y.diag.error('Failed to build resource tree:', treeResult.message);\n return null;\n }\n\n return treeResult.value;\n }, [resources]);\n\n // Filter tree based on search term\n const filteredTree = useMemo(() => {\n if (!treeData || !searchTerm) return treeData;\n\n // Helper function to check if a node or its descendants match the search\n const markMatchingNodes = (\n node: Runtime.ResourceTree.IReadOnlyResourceTreeNode<unknown>,\n searchLower: string\n ): boolean => {\n const nodeIdLower = node.id.toLowerCase();\n let matches = nodeIdLower.includes(searchLower);\n\n if (!node.isLeaf && node.children) {\n // Check children recursively\n for (const child of node.children.values()) {\n if (markMatchingNodes(child, searchLower)) {\n matches = true;\n }\n }\n }\n\n return matches;\n };\n\n // Mark all matching nodes\n const searchLower = searchTerm.toLowerCase();\n for (const child of treeData.children.values()) {\n markMatchingNodes(child, searchLower);\n }\n\n return treeData;\n }, [treeData, searchTerm]);\n\n // Toggle node expansion\n const toggleNode = useCallback((nodeId: string) => {\n setExpandedNodes((prev) => {\n const newExpanded = new Set(prev);\n if (newExpanded.has(nodeId)) {\n newExpanded.delete(nodeId);\n } else {\n newExpanded.add(nodeId);\n }\n return newExpanded;\n });\n }, []);\n\n // Expand all nodes that contain search matches\n const expandMatchingNodes = useCallback(() => {\n if (!searchTerm || !filteredTree) return;\n\n const searchLower = searchTerm.toLowerCase();\n const nodesToExpand = new Set<string>();\n\n const checkNode = (node: Runtime.ResourceTree.IReadOnlyResourceTreeNode<unknown>): void => {\n if (node.id.toLowerCase().includes(searchLower)) {\n // Expand all parent nodes\n const parts = node.id.split('.');\n for (let i = 1; i < parts.length; i++) {\n nodesToExpand.add(parts.slice(0, i).join('.'));\n }\n }\n\n if (!node.isLeaf && node.children) {\n for (const child of node.children.values()) {\n checkNode(child);\n }\n }\n };\n\n for (const child of filteredTree.children.values()) {\n checkNode(child);\n }\n\n setExpandedNodes(nodesToExpand);\n }, [searchTerm, filteredTree]);\n\n // Auto-expand when search term changes\n React.useEffect(() => {\n if (searchTerm) {\n expandMatchingNodes();\n }\n }, [searchTerm, expandMatchingNodes]);\n\n // Render a single tree node\n const renderTreeNode = (\n node: Runtime.ResourceTree.IReadOnlyResourceTreeNode<Resources.Resource | Runtime.IResource>,\n level: number = 0\n ): React.ReactElement | null => {\n const isExpanded = expandedNodes.has(node.id);\n const isSelected = selectedResourceId === node.id;\n const nodeIdLower = node.id.toLowerCase();\n const searchLower = searchTerm.toLowerCase();\n const matchesSearch = !searchTerm || nodeIdLower.includes(searchLower);\n\n // Check if any children match\n let hasMatchingChildren = false;\n if (!node.isLeaf && node.children && searchTerm) {\n const checkChildren = (\n n: Runtime.ResourceTree.IReadOnlyResourceTreeNode<Resources.Resource | Runtime.IResource>\n ): boolean => {\n if (n.id.toLowerCase().includes(searchLower)) return true;\n if (!n.isLeaf && n.children) {\n for (const child of n.children.values()) {\n if (checkChildren(child)) return true;\n }\n }\n return false;\n };\n\n for (const child of node.children.values()) {\n if (checkChildren(child)) {\n hasMatchingChildren = true;\n break;\n }\n }\n }\n\n // Hide nodes that don't match search and don't have matching children\n if (searchTerm && !matchesSearch && !hasMatchingChildren) {\n return null;\n }\n\n return (\n <div key={node.id}>\n <div\n className={`flex items-center px-2 py-1 cursor-pointer hover:bg-gray-100 ${\n isSelected ? 'bg-purple-50 border-l-2 border-purple-500' : ''\n } ${matchesSearch && searchTerm ? 'bg-yellow-50' : ''}`}\n style={{ paddingLeft: `${level * 20 + 8}px` }}\n onClick={() => {\n if (node.isLeaf) {\n onResourceSelect(node.id);\n } else {\n toggleNode(node.id);\n }\n }}\n >\n {/* Expand/Collapse icon for branches */}\n {!node.isLeaf && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n toggleNode(node.id);\n }}\n className=\"mr-1 p-0.5 hover:bg-gray-200 rounded\"\n >\n {isExpanded ? (\n <ChevronDownIcon className=\"w-3 h-3 text-gray-600\" />\n ) : (\n <ChevronRightIcon className=\"w-3 h-3 text-gray-600\" />\n )}\n </button>\n )}\n\n {/* Folder or document icon */}\n {node.isLeaf ? (\n <DocumentTextIcon className=\"w-4 h-4 text-green-500 mr-2 flex-shrink-0\" />\n ) : isExpanded ? (\n <FolderOpenIcon className=\"w-4 h-4 text-blue-500 mr-2 flex-shrink-0\" />\n ) : (\n <FolderIcon className=\"w-4 h-4 text-blue-500 mr-2 flex-shrink-0\" />\n )}\n\n {/* Node name */}\n <span\n className={`text-sm truncate ${isSelected ? 'font-medium text-purple-900' : 'text-gray-700'} ${\n matchesSearch && searchTerm ? 'font-medium' : ''\n }`}\n title={node.id}\n >\n {node.name}\n </span>\n\n {/* Show child count for branches */}\n {!node.isLeaf && node.children && (\n <span className=\"ml-2 text-xs text-gray-500\">({node.children.size})</span>\n )}\n </div>\n\n {/* Render children if expanded */}\n {!node.isLeaf && node.children && isExpanded && (\n <div>\n {Array.from(node.children.values())\n .sort((a, b) => {\n // Sort folders first, then by name\n if (a.isLeaf !== b.isLeaf) {\n return a.isLeaf ? 1 : -1;\n }\n return a.name.localeCompare(b.name);\n })\n .map((child) => renderTreeNode(child, level + 1))}\n </div>\n )}\n </div>\n );\n };\n\n if (!filteredTree) {\n return (\n <div className={`${className} p-4 text-center text-gray-500`}>\n <p>No resources available</p>\n </div>\n );\n }\n\n return (\n <div className={`${className} overflow-y-auto`}>\n {Array.from(filteredTree.children.values())\n .sort((a, b) => {\n // Sort folders first, then by name\n if (a.isLeaf !== b.isLeaf) {\n return a.isLeaf ? 1 : -1;\n }\n return a.name.localeCompare(b.name);\n })\n .map((child) => renderTreeNode(child))}\n </div>\n );\n};\n\nexport default ResourceTreeView;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/common/SourceResourceDetail/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AACnD,OAAO,EAAuB,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAI1E;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,kBAAkB,EAAE,mBAAmB,CAAC;IACxC,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sDAAsD;IACtD,0BAA0B,CAAC,EAAE,mBAAmB,CAAC;IACjD,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACnD,sCAAsC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2FG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAqXrE,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/common/SourceResourceDetail/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { IResourceDetailData, IProcessedResources } from '../../../types';\nimport { Conditions, ResourceJson, Resources } from '@fgv/ts-res';\nimport { useObservability } from '../../../contexts';\n\n/**\n * Props for the SourceResourceDetail component.\n *\n * @public\n */\nexport interface ISourceResourceDetailProps {\n /** The resource ID to display details for */\n resourceId: string;\n /** Processed resources containing the resource data */\n processedResources: IProcessedResources;\n /** Optional CSS classes to apply to the container */\n className?: string;\n /** Optional title for the detail panel */\n title?: string;\n // Dual-resource comparison mode props\n /** Optional original resources for comparison mode */\n originalProcessedResources?: IProcessedResources;\n /** Optional filter context for comparison */\n filterContext?: Record<string, string | undefined>;\n /** Whether to show comparison view */\n showComparison?: boolean;\n // Configurable toggle labels\n /** Label for primary resource view (default: 'Current') */\n primaryLabel?: string;\n /** Label for secondary resource view (default: 'Original') */\n secondaryLabel?: string;\n}\n\n/**\n * A comprehensive component for displaying detailed information about a specific resource.\n *\n * SourceResourceDetail provides an in-depth view of a resource's properties, candidates,\n * conditions, and metadata. It supports both single resource display and comparison mode\n * for viewing differences between filtered and original resources. The component automatically\n * extracts and presents resource information in a structured, readable format.\n *\n * @example\n * ```tsx\n * import { SourceResourceDetail } from '@fgv/ts-res-ui-components';\n *\n * function ResourceInspector() {\n * const [selectedResourceId, setSelectedResourceId] = useState<string>('user.welcome');\n * const processedResources = useProcessedResources();\n *\n * return (\n * <SourceResourceDetail\n * resourceId={selectedResourceId}\n * processedResources={processedResources}\n * title=\"Resource Inspector\"\n * className=\"border rounded-lg p-4\"\n * />\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using comparison mode to show filtered vs original resources\n * import { SourceResourceDetail, FilterTools } from '@fgv/ts-res-ui-components';\n *\n * function FilteredResourceComparison() {\n * const { state: filterState } = FilterTools.useFilterState();\n * const originalResources = useOriginalResources();\n * const filteredResources = filterState.filteredResources;\n * const [selectedId, setSelectedId] = useState<string | null>(null);\n *\n * if (!selectedId) {\n * return <div>Select a resource to compare</div>;\n * }\n *\n * return (\n * <SourceResourceDetail\n * resourceId={selectedId}\n * processedResources={filteredResources}\n * originalProcessedResources={originalResources}\n * filterContext={filterState.appliedValues}\n * showComparison={true}\n * primaryLabel=\"Filtered\"\n * secondaryLabel=\"Original\"\n * title=\"Resource Comparison\"\n * className=\"comparison-panel\"\n * />\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Integration with orchestrator for comprehensive resource details\n * import { SourceResourceDetail, ResourceTools } from '@fgv/ts-res-ui-components';\n *\n * function OrchestratorResourceDetail() {\n * const { state, actions } = ResourceTools.useResourceData();\n *\n * if (!state.selectedResourceId || !state.resources) {\n * return <div className=\"p-4 text-gray-500\">No resource selected</div>;\n * }\n *\n * return (\n * <div className=\"resource-detail-container\">\n * <div className=\"detail-header\">\n * <h2>Resource: {state.selectedResourceId}</h2>\n * <button onClick={() => actions.selectResource(null)}>Clear</button>\n * </div>\n * <SourceResourceDetail\n * resourceId={state.selectedResourceId}\n * processedResources={state.resources}\n * originalProcessedResources={state.filterResult ? state.resources : undefined}\n * filterContext={state.filterState.appliedValues}\n * showComparison={!!state.filterResult}\n * title=\"Resource Details\"\n * className=\"detail-content\"\n * />\n * </div>\n * );\n * }\n * ```\n *\n * @public\n */\nexport const SourceResourceDetail: React.FC<ISourceResourceDetailProps> = ({\n resourceId,\n processedResources,\n className = '',\n title = 'Resource Details',\n originalProcessedResources,\n filterContext,\n showComparison = false,\n primaryLabel = 'Current',\n secondaryLabel = 'Original'\n}) => {\n const o11y = useObservability();\n const [resourceDetail, setResourceDetail] = useState<IResourceDetailData | null>(null);\n const [originalResourceDetail, setOriginalResourceDetail] = useState<IResourceDetailData | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [showFilteredView, setShowFilteredView] = useState(true);\n\n useEffect(() => {\n const loadResourceDetail = (): void => {\n setIsLoading(true);\n setError(null);\n\n try {\n // Helper function to extract resource detail from processed resources\n const extractResourceDetail = (\n resources: IProcessedResources,\n isOriginal = false\n ): IResourceDetailData | null => {\n const resourceManager = resources.system.resourceManager;\n const resourceResult = resourceManager.getBuiltResource(resourceId);\n\n if (!resourceResult.isSuccess()) {\n return null;\n }\n\n const resource = resourceResult.value;\n let candidateDetails: ResourceJson.Normalized.IChildResourceCandidateDecl[] = [];\n\n // Check if candidates have conditions property (ResourceManagerBuilder format)\n if (resource.candidates.length > 0 && 'conditions' in resource.candidates[0]) {\n // ResourceManagerBuilder format with full condition details\n candidateDetails = resource.candidates.map((candidate: Resources.ResourceCandidate) => ({\n json: candidate.json,\n conditions:\n candidate.conditions?.conditions?.map(\n (condition: Conditions.Condition): ResourceJson.Json.ILooseConditionDecl => ({\n qualifierName: condition.qualifier.name,\n operator: condition.operator,\n value: condition.value,\n priority: condition.priority,\n scoreAsDefault: condition.scoreAsDefault\n })\n ) || [],\n isPartial: candidate.isPartial,\n mergeMethod: candidate.mergeMethod\n }));\n } else {\n // IResourceManager format - extract conditions from compiled collection\n const compiledCollection = resources.compiledCollection;\n const compiledResource = compiledCollection?.resources?.find(\n (r: ResourceJson.Compiled.ICompiledResource) => r.id === resourceId\n );\n\n candidateDetails = resource.candidates.map(\n (candidate: Resources.ResourceCandidate, index: number) => {\n // Try to get conditions from the compiled collection\n let conditions: ResourceJson.Json.ILooseConditionDecl[] = [];\n\n if (compiledResource && compiledCollection) {\n const decision = compiledCollection.decisions?.[compiledResource.decision];\n if (decision?.conditionSets && index < decision.conditionSets.length) {\n const conditionSetIndex = decision.conditionSets[index];\n const conditionSet = compiledCollection.conditionSets?.[conditionSetIndex];\n\n if (conditionSet?.conditions) {\n conditions = conditionSet.conditions\n .map((condIndex: number): ResourceJson.Json.ILooseConditionDecl | null => {\n const condition = compiledCollection.conditions?.[condIndex];\n const qualifier = compiledCollection.qualifiers?.[condition?.qualifierIndex];\n return condition && qualifier\n ? {\n qualifierName: qualifier.name,\n operator: condition.operator,\n value: condition.value,\n priority: condition.priority || qualifier.defaultPriority || 500,\n scoreAsDefault: condition.scoreAsDefault\n }\n : null;\n })\n .filter((c): c is ResourceJson.Json.ILooseConditionDecl => c !== null);\n }\n }\n }\n\n return {\n json: candidate.json,\n conditions: conditions,\n isPartial: candidate.isPartial,\n mergeMethod: candidate.mergeMethod\n };\n }\n );\n }\n\n return {\n id: resource.id,\n resourceType: resource.resourceType.key || 'unknown',\n candidateCount: resource.candidates.length,\n candidates: candidateDetails\n };\n };\n\n // Load current/filtered resource detail\n const currentDetail = extractResourceDetail(processedResources, false);\n if (currentDetail) {\n setResourceDetail(currentDetail);\n } else {\n const errorMessage = `${resourceId}: Failed to load resource details`;\n setError(errorMessage);\n o11y.user.error(errorMessage);\n return;\n }\n\n // Load original resource detail if in comparison mode\n if (showComparison && originalProcessedResources) {\n const originalDetail = extractResourceDetail(originalProcessedResources, true);\n if (originalDetail) {\n setOriginalResourceDetail(originalDetail);\n }\n } else {\n setOriginalResourceDetail(null);\n }\n\n o11y.user.info(`${resourceId}: Resource details loaded successfully`);\n } catch (err) {\n const errorMsg = `${resourceId}: Error loading resource details - ${\n err instanceof Error ? err.message : String(err)\n }`;\n setError(errorMsg);\n o11y.user.error(errorMsg);\n } finally {\n setIsLoading(false);\n }\n };\n\n loadResourceDetail();\n }, [resourceId, processedResources, originalProcessedResources, showComparison, o11y]);\n\n if (isLoading) {\n return (\n <div className={`flex flex-col h-full ${className}`}>\n <h3 className=\"text-lg font-semibold text-gray-900 mb-4\">{title}</h3>\n <div className=\"flex-1 flex items-center justify-center border border-gray-200 rounded-lg bg-gray-50\">\n <div className=\"text-center\">\n <div className=\"animate-spin h-8 w-8 border-4 border-blue-600 border-t-transparent rounded-full mx-auto mb-4\"></div>\n <p className=\"text-gray-500\">Loading resource details...</p>\n </div>\n </div>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`flex flex-col h-full ${className}`}>\n <h3 className=\"text-lg font-semibold text-gray-900 mb-4\">{title}</h3>\n <div className=\"flex-1 border border-gray-200 rounded-lg p-4 bg-red-50\">\n <div className=\"text-center\">\n <p className=\"text-red-600 font-medium mb-2\">Error Loading Resource</p>\n <p className=\"text-red-500 text-sm\">{error}</p>\n </div>\n </div>\n </div>\n );\n }\n\n if (!resourceDetail) {\n return (\n <div className={`flex flex-col h-full ${className}`}>\n <h3 className=\"text-lg font-semibold text-gray-900 mb-4\">{title}</h3>\n <div className=\"flex-1 flex items-center justify-center border border-gray-200 rounded-lg bg-gray-50\">\n <p className=\"text-gray-500\">No resource details available</p>\n </div>\n </div>\n );\n }\n\n // Determine which resource detail to show and comparison state\n const currentDetail =\n showComparison && !showFilteredView && originalResourceDetail ? originalResourceDetail : resourceDetail;\n const isShowingPrimary = !showComparison || showFilteredView;\n\n return (\n <div className={`flex flex-col h-full ${className}`}>\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-lg font-semibold text-gray-900\">{title}</h3>\n {showComparison && originalResourceDetail && (\n <div className=\"flex items-center space-x-2\">\n <span className=\"text-xs text-gray-500\">View:</span>\n <button\n onClick={() => setShowFilteredView(false)}\n className={`px-2 py-1 text-xs rounded ${\n !showFilteredView\n ? 'bg-blue-100 text-blue-800 font-medium'\n : 'text-gray-600 hover:bg-gray-100'\n }`}\n >\n {secondaryLabel} ({originalResourceDetail.candidateCount})\n </button>\n <button\n onClick={() => setShowFilteredView(true)}\n className={`px-2 py-1 text-xs rounded ${\n showFilteredView\n ? 'bg-purple-100 text-purple-800 font-medium'\n : 'text-gray-600 hover:bg-gray-100'\n }`}\n >\n {primaryLabel} ({resourceDetail.candidateCount})\n </button>\n </div>\n )}\n </div>\n\n <div className=\"flex-1 overflow-y-auto border border-gray-200 rounded-lg p-4 bg-gray-50\">\n <div className=\"space-y-6\">\n {/* Resource Overview */}\n <div>\n <h4 className=\"font-medium text-gray-700 mb-3\">Resource Overview</h4>\n <div className=\"bg-white p-4 rounded-lg border space-y-3\">\n <div>\n <span className=\"text-sm font-medium text-gray-600\">Fully Qualified ID:</span>\n <code className=\"text-sm bg-gray-100 px-2 py-1 rounded ml-2 break-all\">\n {currentDetail.id}\n </code>\n </div>\n <div>\n <span className=\"text-sm font-medium text-gray-600\">Resource Type:</span>\n <span className=\"ml-2 text-sm\">{currentDetail.resourceType}</span>\n </div>\n <div>\n <span className=\"text-sm font-medium text-gray-600\">Candidate Count:</span>\n <span\n className={`ml-2 text-sm font-medium ${\n showComparison && originalResourceDetail\n ? currentDetail.candidateCount === 0\n ? 'text-red-600'\n : currentDetail.candidateCount <\n (isShowingPrimary\n ? originalResourceDetail.candidateCount\n : resourceDetail.candidateCount)\n ? 'text-amber-600'\n : 'text-green-600'\n : 'text-blue-600'\n }`}\n >\n {currentDetail.candidateCount}\n {showComparison &&\n originalResourceDetail &&\n currentDetail.candidateCount !==\n (isShowingPrimary\n ? originalResourceDetail.candidateCount\n : resourceDetail.candidateCount) && (\n <span className=\"text-gray-400 ml-1\">\n (was{' '}\n {isShowingPrimary\n ? originalResourceDetail.candidateCount\n : resourceDetail.candidateCount}\n )\n </span>\n )}\n </span>\n </div>\n {showComparison && filterContext && (\n <div>\n <span className=\"text-sm font-medium text-gray-600\">Filter Context:</span>\n <span className=\"ml-2 text-sm text-purple-700\">\n {Object.entries(filterContext)\n .filter(([, value]) => value !== undefined && value !== '')\n .map(([key, value]) => `${key}=${value}`)\n .join(', ') || 'No filters'}\n </span>\n </div>\n )}\n </div>\n </div>\n\n {/* Candidates */}\n <div>\n <h4 className=\"font-medium text-gray-700 mb-3\">\n {showComparison && !isShowingPrimary\n ? `${secondaryLabel} `\n : showComparison && isShowingPrimary\n ? `${primaryLabel} `\n : ''}\n Candidates ({currentDetail.candidates.length})\n </h4>\n {currentDetail.candidates.length > 0 ? (\n <div className=\"space-y-4\">\n {currentDetail.candidates.map((candidate, index) => (\n <div key={index} className=\"bg-white p-4 rounded-lg border\">\n <div className=\"flex items-center justify-between mb-3\">\n <h5 className=\"font-medium text-gray-800\">Candidate {index + 1}</h5>\n <div className=\"flex items-center space-x-2 text-xs\">\n {candidate.isPartial && (\n <span className=\"bg-yellow-100 text-yellow-800 px-2 py-1 rounded\">Partial</span>\n )}\n <span className=\"bg-gray-100 text-gray-700 px-2 py-1 rounded\">\n {candidate.mergeMethod}\n </span>\n </div>\n </div>\n\n {/* Conditions */}\n {(candidate.conditions?.length ?? 0) > 0 && (\n <div className=\"mb-3\">\n <h6 className=\"text-sm font-medium text-gray-600 mb-2\">Conditions:</h6>\n <div className=\"space-y-1\">\n {candidate.conditions?.map((condition, condIndex) => (\n <div\n key={condIndex}\n className=\"flex items-center text-xs bg-blue-50 px-2 py-1 rounded\"\n >\n <span className=\"font-medium text-blue-800\">{condition.qualifierName}</span>\n <span className=\"mx-1 text-blue-600\">{condition.operator}</span>\n <span className=\"text-blue-700\">{condition.value}</span>\n <div className=\"ml-auto flex items-center space-x-2\">\n <span className=\"text-blue-500\">priority: {condition.priority}</span>\n {condition.scoreAsDefault !== undefined && (\n <span className=\"text-amber-600 font-medium\">\n default: {condition.scoreAsDefault}\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {(candidate.conditions?.length ?? 0) === 0 && (\n <div className=\"mb-3\">\n <span className=\"text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded\">\n No conditions (default candidate)\n </span>\n </div>\n )}\n\n {/* JSON Content */}\n <div>\n <h6 className=\"text-sm font-medium text-gray-600 mb-2\">Content:</h6>\n <pre className=\"text-xs bg-gray-50 p-3 rounded border overflow-x-auto max-h-40\">\n {JSON.stringify(candidate.json, null, 2)}\n </pre>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"bg-red-50 border border-red-200 p-4 rounded-lg\">\n <p className=\"text-sm text-red-700 font-medium\">No candidates available</p>\n <p className=\"text-xs text-red-600 mt-1\">\n {showComparison\n ? 'This resource has been completely filtered out. Consider adjusting your filter criteria.'\n : 'This resource has no candidates defined.'}\n </p>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SourceResourceDetail;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenericQualifierTypeEditForm.d.ts","sourceRoot":"","sources":["../../../src/components/forms/GenericQualifierTypeEditForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAY,MAAM,aAAa,CAAC;AAIvD;;;;;GAKG;AACH,MAAM,WAAW,kCAAkC;IACjD,wEAAwE;IACxE,aAAa,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,uBAAuB,CAAC;IAC9D,kDAAkD;IAClD,MAAM,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC,MAAM,CAAC,uBAAuB,KAAK,IAAI,CAAC;IAC/E,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAcD;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,KAAK,CAAC,EAAE,CAAC,kCAAkC,CAgUrF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenericQualifierTypeEditForm.js","sourceRoot":"","sources":["../../../src/components/forms/GenericQualifierTypeEditForm.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useCallback, useEffect } from 'react';\nimport { XMarkIcon, InformationCircleIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline';\nimport { QualifierTypes, Validate } from '@fgv/ts-res';\nimport { JsonObject } from '@fgv/ts-json-base';\nimport { useObservability } from '../../contexts';\n\n/**\n * Props for the GenericQualifierTypeEditForm component.\n * Used for editing custom qualifier types with JSON configuration.\n *\n * @public\n */\nexport interface IGenericQualifierTypeEditFormProps {\n /** Existing qualifier type to edit (undefined for creating new type) */\n qualifierType?: QualifierTypes.Config.IAnyQualifierTypeConfig;\n /** Callback fired when qualifier type is saved */\n onSave: (qualifierType: QualifierTypes.Config.IAnyQualifierTypeConfig) => void;\n /** Callback fired when editing is cancelled */\n onCancel: () => void;\n /** Names of existing qualifier types to prevent duplicates */\n existingNames?: string[];\n}\n\ninterface IFormData {\n name: string;\n systemType: string;\n configuration: string; // JSON string\n}\n\ninterface IValidationErrors {\n name?: string;\n systemType?: string;\n configuration?: string;\n}\n\n/**\n * Form component for editing custom qualifier types with JSON configuration.\n * Provides a generic editor for qualifier types that don't use the built-in system types.\n *\n * @public\n */\nexport const GenericQualifierTypeEditForm: React.FC<IGenericQualifierTypeEditFormProps> = ({\n qualifierType,\n onSave,\n onCancel,\n existingNames = []\n}) => {\n const o11y = useObservability();\n const [formData, setFormData] = useState<IFormData>(() => {\n if (qualifierType) {\n return {\n name: qualifierType.name,\n systemType: qualifierType.systemType,\n configuration: JSON.stringify(qualifierType.configuration || {}, null, 2)\n };\n }\n return {\n name: '',\n systemType: '',\n configuration: JSON.stringify({}, null, 2)\n };\n });\n\n const [errors, setErrors] = useState<IValidationErrors>({});\n const [isJsonValid, setIsJsonValid] = useState(true);\n const [isFormValid, setIsFormValid] = useState(false);\n\n // Validate JSON configuration on every change\n useEffect(() => {\n try {\n JSON.parse(formData.configuration); // Validate JSON syntax\n setIsJsonValid(true);\n\n // Attempt to validate the configuration structure if we have both name and systemType\n if (formData.name && formData.systemType) {\n // For now, we'll just check basic structure\n // In the future, this could call validateConfigurationJson if we had a qualifier type instance\n setErrors((prev) => {\n const updated = { ...prev };\n delete updated.configuration;\n return updated;\n });\n } else {\n setErrors((prev) => {\n const updated = { ...prev };\n delete updated.configuration;\n return updated;\n });\n }\n } catch (error) {\n const qualifierTypeName = formData.name.trim() ?? 'unknown-qualifier-type';\n const errorMessage = error instanceof Error ? error.message : 'Invalid JSON';\n\n setIsJsonValid(false);\n setErrors((prev) => ({\n ...prev,\n configuration: `JSON Error: ${errorMessage}`\n }));\n\n o11y.diag.warn(`${qualifierTypeName}: JSON configuration parsing failed - ${errorMessage}`);\n }\n }, [formData.configuration, formData.name, formData.systemType, o11y]);\n\n const validateForm = useCallback((): boolean => {\n const newErrors: IValidationErrors = {};\n\n // Validate name\n if (!formData.name.trim()) {\n newErrors.name = 'Name is required';\n } else if (\n existingNames.includes(formData.name.trim()) &&\n (!qualifierType || qualifierType.name !== formData.name.trim())\n ) {\n newErrors.name = 'Name already exists';\n } else if (!Validate.isValidQualifierTypeName(formData.name)) {\n newErrors.name = `${formData.name}: Invalid qualifier type name`;\n }\n\n // Validate system type\n if (!formData.systemType.trim()) {\n newErrors.systemType = 'System type is required';\n } else if (!Validate.isValidQualifierTypeName(formData.systemType)) {\n newErrors.systemType = `${formData.systemType}: Invalid system type`;\n }\n\n // Validate JSON\n if (!isJsonValid) {\n newErrors.configuration = 'Valid JSON is required';\n }\n\n setErrors(newErrors);\n\n const hasErrors = Object.keys(newErrors).length > 0;\n const isValid = !hasErrors;\n\n setIsFormValid(isValid);\n\n if (hasErrors) {\n const qualifierTypeName = formData.name.trim() ?? 'unknown-qualifier-type';\n const errorList = Object.entries(newErrors)\n .map(([field, error]) => `${field}: ${error}`)\n .join(', ');\n o11y.diag.warn(`${qualifierTypeName}: Qualifier type validation failed - ${errorList}`);\n }\n\n return isValid;\n }, [formData, qualifierType, existingNames, isJsonValid, o11y]);\n\n // Trigger validation when form data changes\n useEffect(() => {\n validateForm();\n }, [formData, validateForm]);\n\n const handleSave = useCallback(() => {\n const qualifierTypeName = formData.name.trim() || 'qualifier-type';\n\n if (!validateForm()) {\n o11y.user.warn(`${qualifierTypeName}: Cannot save - validation errors present`);\n return;\n }\n\n try {\n const configuration = JSON.parse(formData.configuration) as JsonObject;\n const newQualifierType: QualifierTypes.Config.IAnyQualifierTypeConfig = {\n name: formData.name.trim(),\n systemType: formData.systemType.trim(),\n configuration\n };\n\n onSave(newQualifierType);\n o11y.user.success(\n `${qualifierTypeName}: Qualifier type ${qualifierType ? 'updated' : 'created'} successfully`\n );\n } catch (error) {\n const errorMessage = 'Failed to parse JSON configuration';\n setErrors((prev) => ({\n ...prev,\n configuration: errorMessage\n }));\n o11y.user.error(\n `${qualifierTypeName}: Save failed - ${error instanceof Error ? error.message : String(error)}`\n );\n o11y.diag.error(\n `${qualifierTypeName}: Save failed - ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }, [formData, validateForm, onSave, qualifierType, o11y]);\n\n const handleInputChange = useCallback(\n (field: keyof IFormData, value: string) => {\n setFormData((prev) => ({ ...prev, [field]: value }));\n // Clear error when user starts typing\n if (errors[field as keyof IValidationErrors]) {\n setErrors((prev) => {\n const updated = { ...prev };\n delete updated[field as keyof IValidationErrors];\n return updated;\n });\n }\n },\n [errors]\n );\n\n const formatJson = useCallback(() => {\n const qualifierTypeName = formData.name.trim() || 'qualifier-type';\n\n try {\n const parsed = JSON.parse(formData.configuration);\n const formatted = JSON.stringify(parsed, null, 2);\n setFormData((prev) => ({ ...prev, configuration: formatted }));\n o11y.user.info(`${qualifierTypeName}: JSON configuration formatted`);\n } catch (error) {\n // If JSON is invalid, don't format\n o11y.diag.warn(`${qualifierTypeName}: JSON formatting skipped - invalid JSON`);\n o11y.user.warn(`${qualifierTypeName}: JSON formatting skipped - invalid JSON`);\n }\n }, [formData.configuration, formData.name, o11y]);\n\n return (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50\">\n <div className=\"bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto\">\n {/* Header */}\n <div className=\"flex items-center justify-between p-6 border-b border-gray-200\">\n <div>\n <h3 className=\"text-lg font-semibold text-gray-900\">\n {qualifierType ? 'Edit Custom Qualifier Type' : 'Add Custom Qualifier Type'}\n </h3>\n <p className=\"text-sm text-gray-600 mt-1\">\n Configure a custom qualifier type with JSON configuration\n </p>\n </div>\n <button\n onClick={onCancel}\n className=\"p-2 text-gray-400 hover:text-gray-600 rounded-lg hover:bg-gray-100\"\n >\n <XMarkIcon className=\"w-6 h-6\" />\n </button>\n </div>\n\n {/* Form */}\n <div className=\"p-6 space-y-6\">\n {/* Name Field */}\n <div>\n <label htmlFor=\"qualifierTypeName\" className=\"block text-sm font-medium text-gray-700 mb-2\">\n Name\n </label>\n <input\n id=\"qualifierTypeName\"\n type=\"text\"\n value={formData.name}\n onChange={(e) => handleInputChange('name', e.target.value)}\n className={`w-full px-3 py-2 border rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${\n errors.name ? 'border-red-300 bg-red-50' : 'border-gray-300'\n }`}\n placeholder=\"Enter qualifier type name (e.g., 'custom-dimension')\"\n />\n {errors.name && (\n <div className=\"mt-1 flex items-center text-sm text-red-600\">\n <ExclamationTriangleIcon className=\"w-4 h-4 mr-1 flex-shrink-0\" />\n {errors.name}\n </div>\n )}\n </div>\n\n {/* System Type Field */}\n <div>\n <label htmlFor=\"systemType\" className=\"block text-sm font-medium text-gray-700 mb-2\">\n System Type\n </label>\n <input\n id=\"systemType\"\n type=\"text\"\n value={formData.systemType}\n onChange={(e) => handleInputChange('systemType', e.target.value)}\n className={`w-full px-3 py-2 border rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${\n errors.systemType ? 'border-red-300 bg-red-50' : 'border-gray-300'\n }`}\n placeholder=\"Enter system type (e.g., 'custom', 'dimension')\"\n />\n {errors.systemType && (\n <div className=\"mt-1 flex items-center text-sm text-red-600\">\n <ExclamationTriangleIcon className=\"w-4 h-4 mr-1 flex-shrink-0\" />\n {errors.systemType}\n </div>\n )}\n </div>\n\n {/* Configuration JSON Field */}\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <label htmlFor=\"configuration\" className=\"block text-sm font-medium text-gray-700\">\n Configuration (JSON)\n </label>\n <button\n type=\"button\"\n onClick={formatJson}\n disabled={!isJsonValid}\n className=\"text-xs text-blue-600 hover:text-blue-800 disabled:text-gray-400\"\n >\n Format JSON\n </button>\n </div>\n <textarea\n id=\"configuration\"\n rows={12}\n value={formData.configuration}\n onChange={(e) => handleInputChange('configuration', e.target.value)}\n className={`w-full px-3 py-2 border rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm ${\n errors.configuration ? 'border-red-300 bg-red-50' : 'border-gray-300'\n }`}\n placeholder='{\"property\": \"value\"}'\n />\n {errors.configuration && (\n <div className=\"mt-1 flex items-center text-sm text-red-600\">\n <ExclamationTriangleIcon className=\"w-4 h-4 mr-1 flex-shrink-0\" />\n {errors.configuration}\n </div>\n )}\n {isJsonValid && (\n <div className=\"mt-1 flex items-center text-sm text-green-600\">\n <InformationCircleIcon className=\"w-4 h-4 mr-1 flex-shrink-0\" />\n Valid JSON configuration\n </div>\n )}\n </div>\n\n {/* Help Text */}\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4\">\n <div className=\"flex items-start\">\n <InformationCircleIcon className=\"w-5 h-5 text-blue-500 mr-2 mt-0.5 flex-shrink-0\" />\n <div className=\"text-sm text-blue-700\">\n <p className=\"font-medium mb-1\">Custom Qualifier Types</p>\n <p>\n Custom qualifier types allow you to extend the system with your own validation logic. The\n configuration object can contain any valid JSON and will be passed to your custom qualifier\n type implementation.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-end gap-3 p-6 border-t border-gray-200\">\n <button\n onClick={onCancel}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2\"\n >\n Cancel\n </button>\n <button\n onClick={handleSave}\n disabled={!isFormValid}\n className=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {qualifierType ? 'Update' : 'Create'} Qualifier Type\n </button>\n </div>\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HierarchyEditor.d.ts","sourceRoot":"","sources":["../../../src/components/forms/HierarchyEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,oDAAoD;IACpD,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACtD,0FAA0F;IAC1F,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAgM3D,CAAC;AAEF,eAAe,eAAe,CAAC"}
|