@red-hat-developer-hub/plugin-cost-management 2.0.3-rc.4 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Router.esm.js.map +1 -1
- package/dist/apis.esm.js.map +1 -1
- package/dist/components/BasePage.esm.js.map +1 -1
- package/dist/components/InfoCardTitle.esm.js.map +1 -1
- package/dist/components/PageLayout.esm.js.map +1 -1
- package/dist/components/filtersStyles.esm.js.map +1 -1
- package/dist/components/icon/AnalyticsIcon.esm.js.map +1 -1
- package/dist/components/icon/AnalyticsIconFilled.esm.js.map +1 -1
- package/dist/components/icon/AnalyticsIconOutlined.esm.js.map +1 -1
- package/dist/components/icon/CostManagementIcon.esm.js.map +1 -1
- package/dist/components/icon/CostManagementIconFilled.esm.js.map +1 -1
- package/dist/components/icon/CostManagementIconOutlined.esm.js.map +1 -1
- package/dist/constants/currencies.esm.js.map +1 -1
- package/dist/hooks/usePatternFlyTheme.esm.js.map +1 -1
- package/dist/hooks/useThemeBackgroundColor.esm.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/pages/openshift/OpenShiftPage.esm.js.map +1 -1
- package/dist/pages/openshift/components/AutocompleteComponent.esm.js.map +1 -1
- package/dist/pages/openshift/components/DownloadIconButton.esm.js.map +1 -1
- package/dist/pages/openshift/components/Filters.esm.js.map +1 -1
- package/dist/pages/openshift/components/PageHeader.esm.js.map +1 -1
- package/dist/pages/openshift/components/SelectComponent.esm.js.map +1 -1
- package/dist/pages/openshift/components/TableToolbar.esm.js.map +1 -1
- package/dist/pages/optimizations/OptimizationsPage.esm.js.map +1 -1
- package/dist/pages/optimizations/components/ComboBox.esm.js +8 -12
- package/dist/pages/optimizations/components/ComboBox.esm.js.map +1 -1
- package/dist/pages/optimizations/components/Filters.esm.js.map +1 -1
- package/dist/pages/optimizations/components/TableToolbar.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/OptimizationsBreakdownPage.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/OptimizationsBreakdownChart.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/intl.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/messages.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-data-format.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-datum.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-utils.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/format.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/models/ChartEnums.esm.js.map +1 -1
- package/dist/pages/optimizations-breakdown/models/YamlCodeData.esm.js.map +1 -1
- package/dist/plugin.esm.js.map +1 -1
- package/dist/routes.esm.js.map +1 -1
- package/dist/utils/dates.esm.js.map +1 -1
- package/package.json +19 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptimizationsBreakdownPage.esm.js","sources":["../../../src/pages/optimizations-breakdown/OptimizationsBreakdownPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { useLocation, useNavigate, useParams } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n TabbedLayout,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport type { RecommendationBoxPlots } from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport type { WorkflowUnavailableReason } from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport { getTimeFromNow } from '../../utils/dates';\nimport { BasePage } from '../../components/BasePage';\nimport { type Interval, OptimizationType } from './models/ChartEnums';\nimport { OptimizationEngineTab } from './components/optimization-engine-tab/OptimizationEngineTab';\nimport {\n getCurrentYAMLCodeData,\n getRecommendedYAMLCodeData,\n} from './models/YamlCodeData';\nimport { optimizationsApiRef, orchestratorSlimApiRef } from '../../apis';\nimport type { WorkflowInputDataSchema } from './models/WorkflowInputDataSchema';\n\nconst getContainerData = (value: RecommendationBoxPlots) => [\n { key: 'Cluster', value: value?.clusterAlias },\n { key: 'Project', value: value?.project },\n { key: 'Workload', value: value?.workload },\n { key: 'Type', value: value?.workloadType },\n {\n key: 'Last reported',\n value: getTimeFromNow(value?.lastReported?.toString()),\n },\n];\n\n/**\n * Adapts recommendation data into the input schema required for the optimization workflow.\n *\n * This function extracts and transforms resource recommendations (CPU/memory, limits/requests)\n * from the provided `RecommendationBoxPlots` data structure, mapping them into a\n * `WorkflowInputDataSchema` object suitable for workflow consumption.\n *\n * - Converts memory values from mebibytes to bytes where necessary.\n * - Populates cluster, namespace, workload, and container information if available.\n * - Handles both `limits` and `requests` for CPU and memory resources.\n *\n * @param recommendationData - The recommendation data containing resource suggestions and metadata.\n * @param timeRange - The interval term for which recommendations are being adapted.\n * @param optimizationType - The type of optimization engine to use for extracting recommendations.\n * @param type - Specifies the 'limits' or 'requests' resource values.\n * @param resource - Specifies the resource type, either 'cpu' or 'memory'.\n * @returns A `WorkflowInputDataSchema` object populated with the adapted recommendation data.\n */\nconst adaptRecommendationsDataToWorkflowInputData = (\n recommendationData: RecommendationBoxPlots,\n timeRange: Interval,\n optimizationType: OptimizationType,\n): WorkflowInputDataSchema => {\n if (\n !recommendationData.clusterAlias ||\n !recommendationData.project ||\n !recommendationData.workloadType ||\n !recommendationData.workload ||\n !recommendationData.container\n ) {\n throw new Error('Invalid recommendation data');\n }\n\n const workflowInputData: WorkflowInputDataSchema = {\n clusterName: recommendationData.clusterAlias,\n resourceType: recommendationData.workloadType.toLocaleLowerCase(\n 'en-US',\n ) as WorkflowInputDataSchema['resourceType'],\n resourceNamespace: recommendationData.project,\n resourceName: recommendationData.workload,\n containerName: recommendationData.container,\n containerResources: {},\n };\n\n const config =\n recommendationData.recommendations?.recommendationTerms?.[timeRange]\n ?.recommendationEngines?.[optimizationType]?.config;\n\n if (config && config.limits) {\n workflowInputData.containerResources.limits = {};\n if (config.limits.cpu) {\n workflowInputData.containerResources.limits.cpu =\n config.limits.cpu.amount;\n }\n\n if (\n config.limits.memory &&\n typeof config.limits.memory.amount === 'number'\n ) {\n workflowInputData.containerResources.limits.memory = Math.round(\n config.limits.memory.amount * 1024 * 1024,\n );\n }\n }\n\n if (config && config.requests) {\n workflowInputData.containerResources.requests = {};\n if (config.requests.cpu) {\n workflowInputData.containerResources.requests.cpu =\n config.requests.cpu.amount;\n }\n\n if (\n config.requests.memory &&\n typeof config.requests.memory.amount === 'number'\n ) {\n workflowInputData.containerResources.requests.memory = Math.round(\n config.requests.memory.amount * 1024 * 1024,\n );\n }\n }\n\n return workflowInputData;\n};\n\nexport const OptimizationsBreakdownPage = () => {\n const [recommendationTerm, setRecommendationTerm] =\n useState<Interval>('shortTerm');\n const location = useLocation();\n const navigate = useNavigate();\n const { id } = useParams();\n const configApi = useApi(configApiRef);\n const workflowIdRef = useRef<string>(\n configApi.getOptionalString('costManagement.optimizationWorkflowId') ?? '',\n );\n const workflowUnavailableReasonRef = useRef<\n WorkflowUnavailableReason | undefined\n >(undefined);\n const workflowErrorMessageRef = useRef<string | undefined>(undefined);\n const orchestratorSlimApi = useApi(orchestratorSlimApiRef);\n const optimizationsApi = useApi(optimizationsApiRef);\n const {\n value: recommendationsData,\n loading,\n error,\n } = useAsync(async () => {\n const availabilityResult =\n await orchestratorSlimApi.checkWorkflowAvailability(\n workflowIdRef.current,\n );\n if (availabilityResult.available) {\n workflowUnavailableReasonRef.current = undefined;\n workflowErrorMessageRef.current = undefined;\n } else {\n workflowIdRef.current = '';\n workflowUnavailableReasonRef.current = availabilityResult.reason;\n workflowErrorMessageRef.current = availabilityResult.errorMessage;\n }\n\n const apiQuery = {\n path: {\n recommendationId: id!,\n },\n query: {},\n };\n\n const response = await optimizationsApi.getRecommendationById(apiQuery);\n return await response.json();\n }, []);\n\n const optimizationType = useMemo(() => {\n return location.pathname.endsWith('performance')\n ? OptimizationType.performance\n : OptimizationType.cost;\n }, [location.pathname]);\n\n const recommendedConfiguration = useMemo(\n () =>\n getRecommendedYAMLCodeData(\n recommendationsData!,\n recommendationTerm,\n optimizationType,\n ),\n [recommendationsData, recommendationTerm, optimizationType],\n );\n\n const currentConfiguration = useMemo(\n () => getCurrentYAMLCodeData(recommendationsData!),\n [recommendationsData],\n );\n\n const [applyError, setApplyError] = useState<Error | undefined>(undefined);\n\n const handleApplyRecommendation = useCallback(() => {\n if (!recommendationsData) {\n return;\n }\n\n setApplyError(undefined);\n try {\n const workflowId = workflowIdRef.current;\n const data = adaptRecommendationsDataToWorkflowInputData(\n recommendationsData,\n recommendationTerm,\n optimizationType,\n );\n orchestratorSlimApi\n .executeWorkflow(workflowId, { inputData: data })\n .then(response => {\n navigate(`/orchestrator/instances/${response.id}`);\n })\n .catch(err => {\n setApplyError(err instanceof Error ? err : new Error(String(err)));\n });\n } catch {\n return;\n }\n }, [\n navigate,\n optimizationType,\n orchestratorSlimApi,\n recommendationTerm,\n recommendationsData,\n ]);\n\n const handleRecommendationTermChange = useCallback(\n (\n event: React.ChangeEvent<{\n name?: string;\n value: unknown;\n }>,\n ) => {\n setRecommendationTerm(event.target.value as Interval);\n },\n [],\n );\n\n const containerData = useMemo(\n () => getContainerData(recommendationsData!),\n [recommendationsData],\n );\n\n if (loading) {\n return <Progress />;\n }\n\n if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <BasePage\n pageThemeId=\"tool\"\n pageTitle={recommendationsData!.container!}\n pageType=\"Optimizations\"\n pageTypeLink=\"/cost-management/optimizations\"\n >\n {applyError && <ResponseErrorPanel error={applyError} />}\n <TabbedLayout>\n <TabbedLayout.Route path=\"/cost?\" title=\"Cost optimizations\">\n <OptimizationEngineTab\n optimizationType={OptimizationType.cost}\n chartData={recommendationsData!}\n containerData={containerData}\n recommendationTerm={recommendationTerm}\n currentConfiguration={currentConfiguration}\n recommendedConfiguration={recommendedConfiguration}\n onRecommendationTermChange={handleRecommendationTermChange}\n onApplyRecommendation={handleApplyRecommendation}\n workflowId={workflowIdRef.current}\n workflowUnavailableReason={workflowUnavailableReasonRef.current}\n workflowErrorMessage={workflowErrorMessageRef.current}\n />\n </TabbedLayout.Route>\n\n <TabbedLayout.Route\n path=\"/performance\"\n title=\"Performance optimizations\"\n >\n <OptimizationEngineTab\n optimizationType={OptimizationType.performance}\n chartData={recommendationsData!}\n containerData={containerData}\n recommendationTerm={recommendationTerm}\n currentConfiguration={currentConfiguration}\n recommendedConfiguration={recommendedConfiguration}\n onRecommendationTermChange={handleRecommendationTermChange}\n onApplyRecommendation={handleApplyRecommendation}\n workflowId={workflowIdRef.current}\n workflowUnavailableReason={workflowUnavailableReasonRef.current}\n workflowErrorMessage={workflowErrorMessageRef.current}\n />\n </TabbedLayout.Route>\n </TabbedLayout>\n </BasePage>\n );\n};\nOptimizationsBreakdownPage.displayName = 'OptimizationsBreakdownPage';\n"],"names":[],"mappings":";;;;;;;;;;;;AAsCA,MAAM,gBAAA,GAAmB,CAAC,KAAkC,KAAA;AAAA,EAC1D,EAAE,GAAA,EAAK,SAAW,EAAA,KAAA,EAAO,OAAO,YAAa,EAAA;AAAA,EAC7C,EAAE,GAAA,EAAK,SAAW,EAAA,KAAA,EAAO,OAAO,OAAQ,EAAA;AAAA,EACxC,EAAE,GAAA,EAAK,UAAY,EAAA,KAAA,EAAO,OAAO,QAAS,EAAA;AAAA,EAC1C,EAAE,GAAA,EAAK,MAAQ,EAAA,KAAA,EAAO,OAAO,YAAa,EAAA;AAAA,EAC1C;AAAA,IACE,GAAK,EAAA,eAAA;AAAA,IACL,KAAO,EAAA,cAAA,CAAe,KAAO,EAAA,YAAA,EAAc,UAAU;AAAA;AAEzD,CAAA;AAoBA,MAAM,2CAA8C,GAAA,CAClD,kBACA,EAAA,SAAA,EACA,gBAC4B,KAAA;AAC5B,EAAA,IACE,CAAC,kBAAA,CAAmB,YACpB,IAAA,CAAC,mBAAmB,OACpB,IAAA,CAAC,kBAAmB,CAAA,YAAA,IACpB,CAAC,kBAAA,CAAmB,QACpB,IAAA,CAAC,mBAAmB,SACpB,EAAA;AACA,IAAM,MAAA,IAAI,MAAM,6BAA6B,CAAA;AAAA;AAG/C,EAAA,MAAM,iBAA6C,GAAA;AAAA,IACjD,aAAa,kBAAmB,CAAA,YAAA;AAAA,IAChC,YAAA,EAAc,mBAAmB,YAAa,CAAA,iBAAA;AAAA,MAC5C;AAAA,KACF;AAAA,IACA,mBAAmB,kBAAmB,CAAA,OAAA;AAAA,IACtC,cAAc,kBAAmB,CAAA,QAAA;AAAA,IACjC,eAAe,kBAAmB,CAAA,SAAA;AAAA,IAClC,oBAAoB;AAAC,GACvB;AAEA,EAAM,MAAA,MAAA,GACJ,mBAAmB,eAAiB,EAAA,mBAAA,GAAsB,SAAS,CAC/D,EAAA,qBAAA,GAAwB,gBAAgB,CAAG,EAAA,MAAA;AAEjD,EAAI,IAAA,MAAA,IAAU,OAAO,MAAQ,EAAA;AAC3B,IAAkB,iBAAA,CAAA,kBAAA,CAAmB,SAAS,EAAC;AAC/C,IAAI,IAAA,MAAA,CAAO,OAAO,GAAK,EAAA;AACrB,MAAA,iBAAA,CAAkB,kBAAmB,CAAA,MAAA,CAAO,GAC1C,GAAA,MAAA,CAAO,OAAO,GAAI,CAAA,MAAA;AAAA;AAGtB,IACE,IAAA,MAAA,CAAO,OAAO,MACd,IAAA,OAAO,OAAO,MAAO,CAAA,MAAA,CAAO,WAAW,QACvC,EAAA;AACA,MAAkB,iBAAA,CAAA,kBAAA,CAAmB,MAAO,CAAA,MAAA,GAAS,IAAK,CAAA,KAAA;AAAA,QACxD,MAAO,CAAA,MAAA,CAAO,MAAO,CAAA,MAAA,GAAS,IAAO,GAAA;AAAA,OACvC;AAAA;AACF;AAGF,EAAI,IAAA,MAAA,IAAU,OAAO,QAAU,EAAA;AAC7B,IAAkB,iBAAA,CAAA,kBAAA,CAAmB,WAAW,EAAC;AACjD,IAAI,IAAA,MAAA,CAAO,SAAS,GAAK,EAAA;AACvB,MAAA,iBAAA,CAAkB,kBAAmB,CAAA,QAAA,CAAS,GAC5C,GAAA,MAAA,CAAO,SAAS,GAAI,CAAA,MAAA;AAAA;AAGxB,IACE,IAAA,MAAA,CAAO,SAAS,MAChB,IAAA,OAAO,OAAO,QAAS,CAAA,MAAA,CAAO,WAAW,QACzC,EAAA;AACA,MAAkB,iBAAA,CAAA,kBAAA,CAAmB,QAAS,CAAA,MAAA,GAAS,IAAK,CAAA,KAAA;AAAA,QAC1D,MAAO,CAAA,QAAA,CAAS,MAAO,CAAA,MAAA,GAAS,IAAO,GAAA;AAAA,OACzC;AAAA;AACF;AAGF,EAAO,OAAA,iBAAA;AACT,CAAA;AAEO,MAAM,6BAA6B,MAAM;AAC9C,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAC9C,SAAmB,WAAW,CAAA;AAChC,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAM,MAAA,EAAE,EAAG,EAAA,GAAI,SAAU,EAAA;AACzB,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,aAAgB,GAAA,MAAA;AAAA,IACpB,SAAA,CAAU,iBAAkB,CAAA,uCAAuC,CAAK,IAAA;AAAA,GAC1E;AACA,EAAM,MAAA,4BAAA,GAA+B,OAEnC,MAAS,CAAA;AACX,EAAM,MAAA,uBAAA,GAA0B,OAA2B,MAAS,CAAA;AACpE,EAAM,MAAA,mBAAA,GAAsB,OAAO,sBAAsB,CAAA;AACzD,EAAM,MAAA,gBAAA,GAAmB,OAAO,mBAAmB,CAAA;AACnD,EAAM,MAAA;AAAA,IACJ,KAAO,EAAA,mBAAA;AAAA,IACP,OAAA;AAAA,IACA;AAAA,GACF,GAAI,SAAS,YAAY;AACvB,IAAM,MAAA,kBAAA,GACJ,MAAM,mBAAoB,CAAA,yBAAA;AAAA,MACxB,aAAc,CAAA;AAAA,KAChB;AACF,IAAA,IAAI,mBAAmB,SAAW,EAAA;AAChC,MAAA,4BAAA,CAA6B,OAAU,GAAA,MAAA;AACvC,MAAA,uBAAA,CAAwB,OAAU,GAAA,MAAA;AAAA,KAC7B,MAAA;AACL,MAAA,aAAA,CAAc,OAAU,GAAA,EAAA;AACxB,MAAA,4BAAA,CAA6B,UAAU,kBAAmB,CAAA,MAAA;AAC1D,MAAA,uBAAA,CAAwB,UAAU,kBAAmB,CAAA,YAAA;AAAA;AAGvD,IAAA,MAAM,QAAW,GAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,gBAAkB,EAAA;AAAA,OACpB;AAAA,MACA,OAAO;AAAC,KACV;AAEA,IAAA,MAAM,QAAW,GAAA,MAAM,gBAAiB,CAAA,qBAAA,CAAsB,QAAQ,CAAA;AACtE,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA,GAC7B,EAAG,EAAE,CAAA;AAEL,EAAM,MAAA,gBAAA,GAAmB,QAAQ,MAAM;AACrC,IAAA,OAAO,SAAS,QAAS,CAAA,QAAA,CAAS,aAAa,CAC3C,GAAA,gBAAA,CAAiB,cACjB,gBAAiB,CAAA,IAAA;AAAA,GACpB,EAAA,CAAC,QAAS,CAAA,QAAQ,CAAC,CAAA;AAEtB,EAAA,MAAM,wBAA2B,GAAA,OAAA;AAAA,IAC/B,MACE,0BAAA;AAAA,MACE,mBAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACF;AAAA,IACF,CAAC,mBAAqB,EAAA,kBAAA,EAAoB,gBAAgB;AAAA,GAC5D;AAEA,EAAA,MAAM,oBAAuB,GAAA,OAAA;AAAA,IAC3B,MAAM,uBAAuB,mBAAoB,CAAA;AAAA,IACjD,CAAC,mBAAmB;AAAA,GACtB;AAEA,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAA4B,MAAS,CAAA;AAEzE,EAAM,MAAA,yBAAA,GAA4B,YAAY,MAAM;AAClD,IAAA,IAAI,CAAC,mBAAqB,EAAA;AACxB,MAAA;AAAA;AAGF,IAAA,aAAA,CAAc,MAAS,CAAA;AACvB,IAAI,IAAA;AACF,MAAA,MAAM,aAAa,aAAc,CAAA,OAAA;AACjC,MAAA,MAAM,IAAO,GAAA,2CAAA;AAAA,QACX,mBAAA;AAAA,QACA,kBAAA;AAAA,QACA;AAAA,OACF;AACA,MACG,mBAAA,CAAA,eAAA,CAAgB,YAAY,EAAE,SAAA,EAAW,MAAM,CAAA,CAC/C,KAAK,CAAY,QAAA,KAAA;AAChB,QAAS,QAAA,CAAA,CAAA,wBAAA,EAA2B,QAAS,CAAA,EAAE,CAAE,CAAA,CAAA;AAAA,OAClD,CACA,CAAA,KAAA,CAAM,CAAO,GAAA,KAAA;AACZ,QAAc,aAAA,CAAA,GAAA,YAAe,QAAQ,GAAM,GAAA,IAAI,MAAM,MAAO,CAAA,GAAG,CAAC,CAAC,CAAA;AAAA,OAClE,CAAA;AAAA,KACG,CAAA,MAAA;AACN,MAAA;AAAA;AACF,GACC,EAAA;AAAA,IACD,QAAA;AAAA,IACA,gBAAA;AAAA,IACA,mBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,8BAAiC,GAAA,WAAA;AAAA,IACrC,CACE,KAIG,KAAA;AACH,MAAsB,qBAAA,CAAA,KAAA,CAAM,OAAO,KAAiB,CAAA;AAAA,KACtD;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,aAAgB,GAAA,OAAA;AAAA,IACpB,MAAM,iBAAiB,mBAAoB,CAAA;AAAA,IAC3C,CAAC,mBAAmB;AAAA,GACtB;AAEA,EAAA,IAAI,OAAS,EAAA;AACX,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA;AAAA;AAGnB,EAAA,IAAI,KAAO,EAAA;AACT,IAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,sBAAmB,KAAc,EAAA,CAAA;AAAA;AAG3C,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,WAAY,EAAA,MAAA;AAAA,MACZ,WAAW,mBAAqB,CAAA,SAAA;AAAA,MAChC,QAAS,EAAA,eAAA;AAAA,MACT,YAAa,EAAA;AAAA,KAAA;AAAA,IAEZ,UAAc,oBAAA,KAAA,CAAA,aAAA,CAAC,kBAAmB,EAAA,EAAA,KAAA,EAAO,UAAY,EAAA,CAAA;AAAA,oBACtD,KAAA,CAAA,aAAA,CAAC,oCACE,KAAA,CAAA,aAAA,CAAA,YAAA,CAAa,OAAb,EAAmB,IAAA,EAAK,QAAS,EAAA,KAAA,EAAM,oBACtC,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,qBAAA;AAAA,MAAA;AAAA,QACC,kBAAkB,gBAAiB,CAAA,IAAA;AAAA,QACnC,SAAW,EAAA,mBAAA;AAAA,QACX,aAAA;AAAA,QACA,kBAAA;AAAA,QACA,oBAAA;AAAA,QACA,wBAAA;AAAA,QACA,0BAA4B,EAAA,8BAAA;AAAA,QAC5B,qBAAuB,EAAA,yBAAA;AAAA,QACvB,YAAY,aAAc,CAAA,OAAA;AAAA,QAC1B,2BAA2B,4BAA6B,CAAA,OAAA;AAAA,QACxD,sBAAsB,uBAAwB,CAAA;AAAA;AAAA,KAElD,CAEA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,YAAa,CAAA,KAAA;AAAA,MAAb;AAAA,QACC,IAAK,EAAA,cAAA;AAAA,QACL,KAAM,EAAA;AAAA,OAAA;AAAA,sBAEN,KAAA,CAAA,aAAA;AAAA,QAAC,qBAAA;AAAA,QAAA;AAAA,UACC,kBAAkB,gBAAiB,CAAA,WAAA;AAAA,UACnC,SAAW,EAAA,mBAAA;AAAA,UACX,aAAA;AAAA,UACA,kBAAA;AAAA,UACA,oBAAA;AAAA,UACA,wBAAA;AAAA,UACA,0BAA4B,EAAA,8BAAA;AAAA,UAC5B,qBAAuB,EAAA,yBAAA;AAAA,UACvB,YAAY,aAAc,CAAA,OAAA;AAAA,UAC1B,2BAA2B,4BAA6B,CAAA,OAAA;AAAA,UACxD,sBAAsB,uBAAwB,CAAA;AAAA;AAAA;AAChD,KAEJ;AAAA,GACF;AAEJ;AACA,0BAAA,CAA2B,WAAc,GAAA,4BAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"OptimizationsBreakdownPage.esm.js","sources":["../../../src/pages/optimizations-breakdown/OptimizationsBreakdownPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { useLocation, useNavigate, useParams } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n TabbedLayout,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport type { RecommendationBoxPlots } from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport type { WorkflowUnavailableReason } from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport { getTimeFromNow } from '../../utils/dates';\nimport { BasePage } from '../../components/BasePage';\nimport { type Interval, OptimizationType } from './models/ChartEnums';\nimport { OptimizationEngineTab } from './components/optimization-engine-tab/OptimizationEngineTab';\nimport {\n getCurrentYAMLCodeData,\n getRecommendedYAMLCodeData,\n} from './models/YamlCodeData';\nimport { optimizationsApiRef, orchestratorSlimApiRef } from '../../apis';\nimport type { WorkflowInputDataSchema } from './models/WorkflowInputDataSchema';\n\nconst getContainerData = (value: RecommendationBoxPlots) => [\n { key: 'Cluster', value: value?.clusterAlias },\n { key: 'Project', value: value?.project },\n { key: 'Workload', value: value?.workload },\n { key: 'Type', value: value?.workloadType },\n {\n key: 'Last reported',\n value: getTimeFromNow(value?.lastReported?.toString()),\n },\n];\n\n/**\n * Adapts recommendation data into the input schema required for the optimization workflow.\n *\n * This function extracts and transforms resource recommendations (CPU/memory, limits/requests)\n * from the provided `RecommendationBoxPlots` data structure, mapping them into a\n * `WorkflowInputDataSchema` object suitable for workflow consumption.\n *\n * - Converts memory values from mebibytes to bytes where necessary.\n * - Populates cluster, namespace, workload, and container information if available.\n * - Handles both `limits` and `requests` for CPU and memory resources.\n *\n * @param recommendationData - The recommendation data containing resource suggestions and metadata.\n * @param timeRange - The interval term for which recommendations are being adapted.\n * @param optimizationType - The type of optimization engine to use for extracting recommendations.\n * @param type - Specifies the 'limits' or 'requests' resource values.\n * @param resource - Specifies the resource type, either 'cpu' or 'memory'.\n * @returns A `WorkflowInputDataSchema` object populated with the adapted recommendation data.\n */\nconst adaptRecommendationsDataToWorkflowInputData = (\n recommendationData: RecommendationBoxPlots,\n timeRange: Interval,\n optimizationType: OptimizationType,\n): WorkflowInputDataSchema => {\n if (\n !recommendationData.clusterAlias ||\n !recommendationData.project ||\n !recommendationData.workloadType ||\n !recommendationData.workload ||\n !recommendationData.container\n ) {\n throw new Error('Invalid recommendation data');\n }\n\n const workflowInputData: WorkflowInputDataSchema = {\n clusterName: recommendationData.clusterAlias,\n resourceType: recommendationData.workloadType.toLocaleLowerCase(\n 'en-US',\n ) as WorkflowInputDataSchema['resourceType'],\n resourceNamespace: recommendationData.project,\n resourceName: recommendationData.workload,\n containerName: recommendationData.container,\n containerResources: {},\n };\n\n const config =\n recommendationData.recommendations?.recommendationTerms?.[timeRange]\n ?.recommendationEngines?.[optimizationType]?.config;\n\n if (config && config.limits) {\n workflowInputData.containerResources.limits = {};\n if (config.limits.cpu) {\n workflowInputData.containerResources.limits.cpu =\n config.limits.cpu.amount;\n }\n\n if (\n config.limits.memory &&\n typeof config.limits.memory.amount === 'number'\n ) {\n workflowInputData.containerResources.limits.memory = Math.round(\n config.limits.memory.amount * 1024 * 1024,\n );\n }\n }\n\n if (config && config.requests) {\n workflowInputData.containerResources.requests = {};\n if (config.requests.cpu) {\n workflowInputData.containerResources.requests.cpu =\n config.requests.cpu.amount;\n }\n\n if (\n config.requests.memory &&\n typeof config.requests.memory.amount === 'number'\n ) {\n workflowInputData.containerResources.requests.memory = Math.round(\n config.requests.memory.amount * 1024 * 1024,\n );\n }\n }\n\n return workflowInputData;\n};\n\nexport const OptimizationsBreakdownPage = () => {\n const [recommendationTerm, setRecommendationTerm] =\n useState<Interval>('shortTerm');\n const location = useLocation();\n const navigate = useNavigate();\n const { id } = useParams();\n const configApi = useApi(configApiRef);\n const workflowIdRef = useRef<string>(\n configApi.getOptionalString('costManagement.optimizationWorkflowId') ?? '',\n );\n const workflowUnavailableReasonRef = useRef<\n WorkflowUnavailableReason | undefined\n >(undefined);\n const workflowErrorMessageRef = useRef<string | undefined>(undefined);\n const orchestratorSlimApi = useApi(orchestratorSlimApiRef);\n const optimizationsApi = useApi(optimizationsApiRef);\n const {\n value: recommendationsData,\n loading,\n error,\n } = useAsync(async () => {\n const availabilityResult =\n await orchestratorSlimApi.checkWorkflowAvailability(\n workflowIdRef.current,\n );\n if (availabilityResult.available) {\n workflowUnavailableReasonRef.current = undefined;\n workflowErrorMessageRef.current = undefined;\n } else {\n workflowIdRef.current = '';\n workflowUnavailableReasonRef.current = availabilityResult.reason;\n workflowErrorMessageRef.current = availabilityResult.errorMessage;\n }\n\n const apiQuery = {\n path: {\n recommendationId: id!,\n },\n query: {},\n };\n\n const response = await optimizationsApi.getRecommendationById(apiQuery);\n return await response.json();\n }, []);\n\n const optimizationType = useMemo(() => {\n return location.pathname.endsWith('performance')\n ? OptimizationType.performance\n : OptimizationType.cost;\n }, [location.pathname]);\n\n const recommendedConfiguration = useMemo(\n () =>\n getRecommendedYAMLCodeData(\n recommendationsData!,\n recommendationTerm,\n optimizationType,\n ),\n [recommendationsData, recommendationTerm, optimizationType],\n );\n\n const currentConfiguration = useMemo(\n () => getCurrentYAMLCodeData(recommendationsData!),\n [recommendationsData],\n );\n\n const [applyError, setApplyError] = useState<Error | undefined>(undefined);\n\n const handleApplyRecommendation = useCallback(() => {\n if (!recommendationsData) {\n return;\n }\n\n setApplyError(undefined);\n try {\n const workflowId = workflowIdRef.current;\n const data = adaptRecommendationsDataToWorkflowInputData(\n recommendationsData,\n recommendationTerm,\n optimizationType,\n );\n orchestratorSlimApi\n .executeWorkflow(workflowId, { inputData: data })\n .then(response => {\n navigate(`/orchestrator/instances/${response.id}`);\n })\n .catch(err => {\n setApplyError(err instanceof Error ? err : new Error(String(err)));\n });\n } catch {\n return;\n }\n }, [\n navigate,\n optimizationType,\n orchestratorSlimApi,\n recommendationTerm,\n recommendationsData,\n ]);\n\n const handleRecommendationTermChange = useCallback(\n (\n event: React.ChangeEvent<{\n name?: string;\n value: unknown;\n }>,\n ) => {\n setRecommendationTerm(event.target.value as Interval);\n },\n [],\n );\n\n const containerData = useMemo(\n () => getContainerData(recommendationsData!),\n [recommendationsData],\n );\n\n if (loading) {\n return <Progress />;\n }\n\n if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <BasePage\n pageThemeId=\"tool\"\n pageTitle={recommendationsData!.container!}\n pageType=\"Optimizations\"\n pageTypeLink=\"/cost-management/optimizations\"\n >\n {applyError && <ResponseErrorPanel error={applyError} />}\n <TabbedLayout>\n <TabbedLayout.Route path=\"/cost?\" title=\"Cost optimizations\">\n <OptimizationEngineTab\n optimizationType={OptimizationType.cost}\n chartData={recommendationsData!}\n containerData={containerData}\n recommendationTerm={recommendationTerm}\n currentConfiguration={currentConfiguration}\n recommendedConfiguration={recommendedConfiguration}\n onRecommendationTermChange={handleRecommendationTermChange}\n onApplyRecommendation={handleApplyRecommendation}\n workflowId={workflowIdRef.current}\n workflowUnavailableReason={workflowUnavailableReasonRef.current}\n workflowErrorMessage={workflowErrorMessageRef.current}\n />\n </TabbedLayout.Route>\n\n <TabbedLayout.Route\n path=\"/performance\"\n title=\"Performance optimizations\"\n >\n <OptimizationEngineTab\n optimizationType={OptimizationType.performance}\n chartData={recommendationsData!}\n containerData={containerData}\n recommendationTerm={recommendationTerm}\n currentConfiguration={currentConfiguration}\n recommendedConfiguration={recommendedConfiguration}\n onRecommendationTermChange={handleRecommendationTermChange}\n onApplyRecommendation={handleApplyRecommendation}\n workflowId={workflowIdRef.current}\n workflowUnavailableReason={workflowUnavailableReasonRef.current}\n workflowErrorMessage={workflowErrorMessageRef.current}\n />\n </TabbedLayout.Route>\n </TabbedLayout>\n </BasePage>\n );\n};\nOptimizationsBreakdownPage.displayName = 'OptimizationsBreakdownPage';\n"],"names":[],"mappings":";;;;;;;;;;;;AAsCA,MAAM,gBAAA,GAAmB,CAAC,KAAA,KAAkC;AAAA,EAC1D,EAAE,GAAA,EAAK,SAAA,EAAW,KAAA,EAAO,OAAO,YAAA,EAAa;AAAA,EAC7C,EAAE,GAAA,EAAK,SAAA,EAAW,KAAA,EAAO,OAAO,OAAA,EAAQ;AAAA,EACxC,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,OAAO,QAAA,EAAS;AAAA,EAC1C,EAAE,GAAA,EAAK,MAAA,EAAQ,KAAA,EAAO,OAAO,YAAA,EAAa;AAAA,EAC1C;AAAA,IACE,GAAA,EAAK,eAAA;AAAA,IACL,KAAA,EAAO,cAAA,CAAe,KAAA,EAAO,YAAA,EAAc,UAAU;AAAA;AAEzD,CAAA;AAoBA,MAAM,2CAAA,GAA8C,CAClD,kBAAA,EACA,SAAA,EACA,gBAAA,KAC4B;AAC5B,EAAA,IACE,CAAC,kBAAA,CAAmB,YAAA,IACpB,CAAC,mBAAmB,OAAA,IACpB,CAAC,kBAAA,CAAmB,YAAA,IACpB,CAAC,kBAAA,CAAmB,QAAA,IACpB,CAAC,mBAAmB,SAAA,EACpB;AACA,IAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAAA,EAC/C;AAEA,EAAA,MAAM,iBAAA,GAA6C;AAAA,IACjD,aAAa,kBAAA,CAAmB,YAAA;AAAA,IAChC,YAAA,EAAc,mBAAmB,YAAA,CAAa,iBAAA;AAAA,MAC5C;AAAA,KACF;AAAA,IACA,mBAAmB,kBAAA,CAAmB,OAAA;AAAA,IACtC,cAAc,kBAAA,CAAmB,QAAA;AAAA,IACjC,eAAe,kBAAA,CAAmB,SAAA;AAAA,IAClC,oBAAoB;AAAC,GACvB;AAEA,EAAA,MAAM,MAAA,GACJ,mBAAmB,eAAA,EAAiB,mBAAA,GAAsB,SAAS,CAAA,EAC/D,qBAAA,GAAwB,gBAAgB,CAAA,EAAG,MAAA;AAEjD,EAAA,IAAI,MAAA,IAAU,OAAO,MAAA,EAAQ;AAC3B,IAAA,iBAAA,CAAkB,kBAAA,CAAmB,SAAS,EAAC;AAC/C,IAAA,IAAI,MAAA,CAAO,OAAO,GAAA,EAAK;AACrB,MAAA,iBAAA,CAAkB,kBAAA,CAAmB,MAAA,CAAO,GAAA,GAC1C,MAAA,CAAO,OAAO,GAAA,CAAI,MAAA;AAAA,IACtB;AAEA,IAAA,IACE,MAAA,CAAO,OAAO,MAAA,IACd,OAAO,OAAO,MAAA,CAAO,MAAA,CAAO,WAAW,QAAA,EACvC;AACA,MAAA,iBAAA,CAAkB,kBAAA,CAAmB,MAAA,CAAO,MAAA,GAAS,IAAA,CAAK,KAAA;AAAA,QACxD,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,IAAA,GAAO;AAAA,OACvC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,IAAU,OAAO,QAAA,EAAU;AAC7B,IAAA,iBAAA,CAAkB,kBAAA,CAAmB,WAAW,EAAC;AACjD,IAAA,IAAI,MAAA,CAAO,SAAS,GAAA,EAAK;AACvB,MAAA,iBAAA,CAAkB,kBAAA,CAAmB,QAAA,CAAS,GAAA,GAC5C,MAAA,CAAO,SAAS,GAAA,CAAI,MAAA;AAAA,IACxB;AAEA,IAAA,IACE,MAAA,CAAO,SAAS,MAAA,IAChB,OAAO,OAAO,QAAA,CAAS,MAAA,CAAO,WAAW,QAAA,EACzC;AACA,MAAA,iBAAA,CAAkB,kBAAA,CAAmB,QAAA,CAAS,MAAA,GAAS,IAAA,CAAK,KAAA;AAAA,QAC1D,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,MAAA,GAAS,IAAA,GAAO;AAAA,OACzC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,iBAAA;AACT,CAAA;AAEO,MAAM,6BAA6B,MAAM;AAC9C,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAC9C,SAAmB,WAAW,CAAA;AAChC,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,EAAE,EAAA,EAAG,GAAI,SAAA,EAAU;AACzB,EAAA,MAAM,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,aAAA,GAAgB,MAAA;AAAA,IACpB,SAAA,CAAU,iBAAA,CAAkB,uCAAuC,CAAA,IAAK;AAAA,GAC1E;AACA,EAAA,MAAM,4BAAA,GAA+B,OAEnC,MAAS,CAAA;AACX,EAAA,MAAM,uBAAA,GAA0B,OAA2B,MAAS,CAAA;AACpE,EAAA,MAAM,mBAAA,GAAsB,OAAO,sBAAsB,CAAA;AACzD,EAAA,MAAM,gBAAA,GAAmB,OAAO,mBAAmB,CAAA;AACnD,EAAA,MAAM;AAAA,IACJ,KAAA,EAAO,mBAAA;AAAA,IACP,OAAA;AAAA,IACA;AAAA,GACF,GAAI,SAAS,YAAY;AACvB,IAAA,MAAM,kBAAA,GACJ,MAAM,mBAAA,CAAoB,yBAAA;AAAA,MACxB,aAAA,CAAc;AAAA,KAChB;AACF,IAAA,IAAI,mBAAmB,SAAA,EAAW;AAChC,MAAA,4BAAA,CAA6B,OAAA,GAAU,MAAA;AACvC,MAAA,uBAAA,CAAwB,OAAA,GAAU,MAAA;AAAA,IACpC,CAAA,MAAO;AACL,MAAA,aAAA,CAAc,OAAA,GAAU,EAAA;AACxB,MAAA,4BAAA,CAA6B,UAAU,kBAAA,CAAmB,MAAA;AAC1D,MAAA,uBAAA,CAAwB,UAAU,kBAAA,CAAmB,YAAA;AAAA,IACvD;AAEA,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,gBAAA,EAAkB;AAAA,OACpB;AAAA,MACA,OAAO;AAAC,KACV;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,gBAAA,CAAiB,qBAAA,CAAsB,QAAQ,CAAA;AACtE,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,gBAAA,GAAmB,QAAQ,MAAM;AACrC,IAAA,OAAO,SAAS,QAAA,CAAS,QAAA,CAAS,aAAa,CAAA,GAC3C,gBAAA,CAAiB,cACjB,gBAAA,CAAiB,IAAA;AAAA,EACvB,CAAA,EAAG,CAAC,QAAA,CAAS,QAAQ,CAAC,CAAA;AAEtB,EAAA,MAAM,wBAAA,GAA2B,OAAA;AAAA,IAC/B,MACE,0BAAA;AAAA,MACE,mBAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACF;AAAA,IACF,CAAC,mBAAA,EAAqB,kBAAA,EAAoB,gBAAgB;AAAA,GAC5D;AAEA,EAAA,MAAM,oBAAA,GAAuB,OAAA;AAAA,IAC3B,MAAM,uBAAuB,mBAAoB,CAAA;AAAA,IACjD,CAAC,mBAAmB;AAAA,GACtB;AAEA,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAA4B,MAAS,CAAA;AAEzE,EAAA,MAAM,yBAAA,GAA4B,YAAY,MAAM;AAClD,IAAA,IAAI,CAAC,mBAAA,EAAqB;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,aAAA,CAAc,MAAS,CAAA;AACvB,IAAA,IAAI;AACF,MAAA,MAAM,aAAa,aAAA,CAAc,OAAA;AACjC,MAAA,MAAM,IAAA,GAAO,2CAAA;AAAA,QACX,mBAAA;AAAA,QACA,kBAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,mBAAA,CACG,eAAA,CAAgB,YAAY,EAAE,SAAA,EAAW,MAAM,CAAA,CAC/C,KAAK,CAAA,QAAA,KAAY;AAChB,QAAA,QAAA,CAAS,CAAA,wBAAA,EAA2B,QAAA,CAAS,EAAE,CAAA,CAAE,CAAA;AAAA,MACnD,CAAC,CAAA,CACA,KAAA,CAAM,CAAA,GAAA,KAAO;AACZ,QAAA,aAAA,CAAc,GAAA,YAAe,QAAQ,GAAA,GAAM,IAAI,MAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,MACnE,CAAC,CAAA;AAAA,IACL,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AAAA,EACF,CAAA,EAAG;AAAA,IACD,QAAA;AAAA,IACA,gBAAA;AAAA,IACA,mBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,8BAAA,GAAiC,WAAA;AAAA,IACrC,CACE,KAAA,KAIG;AACH,MAAA,qBAAA,CAAsB,KAAA,CAAM,OAAO,KAAiB,CAAA;AAAA,IACtD,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,aAAA,GAAgB,OAAA;AAAA,IACpB,MAAM,iBAAiB,mBAAoB,CAAA;AAAA,IAC3C,CAAC,mBAAmB;AAAA,GACtB;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,2CAAQ,QAAA,EAAA,IAAS,CAAA;AAAA,EACnB;AAEA,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,uBAAO,KAAA,CAAA,aAAA,CAAC,sBAAmB,KAAA,EAAc,CAAA;AAAA,EAC3C;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAY,MAAA;AAAA,MACZ,WAAW,mBAAA,CAAqB,SAAA;AAAA,MAChC,QAAA,EAAS,eAAA;AAAA,MACT,YAAA,EAAa;AAAA,KAAA;AAAA,IAEZ,UAAA,oBAAc,KAAA,CAAA,aAAA,CAAC,kBAAA,EAAA,EAAmB,KAAA,EAAO,UAAA,EAAY,CAAA;AAAA,oBACtD,KAAA,CAAA,aAAA,CAAC,oCACC,KAAA,CAAA,aAAA,CAAC,YAAA,CAAa,OAAb,EAAmB,IAAA,EAAK,QAAA,EAAS,KAAA,EAAM,oBAAA,EAAA,kBACtC,KAAA,CAAA,aAAA;AAAA,MAAC,qBAAA;AAAA,MAAA;AAAA,QACC,kBAAkB,gBAAA,CAAiB,IAAA;AAAA,QACnC,SAAA,EAAW,mBAAA;AAAA,QACX,aAAA;AAAA,QACA,kBAAA;AAAA,QACA,oBAAA;AAAA,QACA,wBAAA;AAAA,QACA,0BAAA,EAA4B,8BAAA;AAAA,QAC5B,qBAAA,EAAuB,yBAAA;AAAA,QACvB,YAAY,aAAA,CAAc,OAAA;AAAA,QAC1B,2BAA2B,4BAAA,CAA6B,OAAA;AAAA,QACxD,sBAAsB,uBAAA,CAAwB;AAAA;AAAA,KAElD,CAAA,kBAEA,KAAA,CAAA,aAAA;AAAA,MAAC,YAAA,CAAa,KAAA;AAAA,MAAb;AAAA,QACC,IAAA,EAAK,cAAA;AAAA,QACL,KAAA,EAAM;AAAA,OAAA;AAAA,sBAEN,KAAA,CAAA,aAAA;AAAA,QAAC,qBAAA;AAAA,QAAA;AAAA,UACC,kBAAkB,gBAAA,CAAiB,WAAA;AAAA,UACnC,SAAA,EAAW,mBAAA;AAAA,UACX,aAAA;AAAA,UACA,kBAAA;AAAA,UACA,oBAAA;AAAA,UACA,wBAAA;AAAA,UACA,0BAAA,EAA4B,8BAAA;AAAA,UAC5B,qBAAA,EAAuB,yBAAA;AAAA,UACvB,YAAY,aAAA,CAAc,OAAA;AAAA,UAC1B,2BAA2B,4BAAA,CAA6B,OAAA;AAAA,UACxD,sBAAsB,uBAAA,CAAwB;AAAA;AAAA;AAChD,KAEJ;AAAA,GACF;AAEJ;AACA,0BAAA,CAA2B,WAAA,GAAc,4BAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptimizationEngineTab.esm.js","sources":["../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback, useMemo, useState } from 'react';\nimport {\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n Grid,\n Tooltip,\n} from '@material-ui/core';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { rosApplyPermission } from '@red-hat-developer-hub/plugin-cost-management-common/permissions';\nimport type { WorkflowUnavailableReason } from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport { RecommendationType } from '../../models/ChartEnums';\nimport { ChartInfoCard } from './components/chart-info-card/ChartInfoCard';\nimport { CodeInfoCard } from './components/CodeInfoCard';\nimport { ContainerInfoCard } from './components/ContainerInfoCard';\n\ntype ContainerInfoCardProps = Parameters<typeof ContainerInfoCard>[0];\ntype CodeInfoCardProps = Parameters<typeof CodeInfoCard>[0];\ntype ChartInfoCardProps = Parameters<typeof ChartInfoCard>[0];\n\nconst DEFAULT_WORKFLOW_MESSAGES: Record<WorkflowUnavailableReason, string> = {\n not_configured: 'No workflow configured to apply recommendations',\n not_found: 'Workflow not found',\n access_denied: 'You do not have permission to access this workflow',\n service_unavailable: 'Workflow service is currently unavailable',\n};\n\ninterface OptimizationEngineTabProps extends ContainerInfoCardProps {\n currentConfiguration: CodeInfoCardProps['yamlCodeData'];\n recommendedConfiguration: CodeInfoCardProps['yamlCodeData'];\n chartData: ChartInfoCardProps['chartData'];\n optimizationType: ChartInfoCardProps['optimizationType'];\n onApplyRecommendation?: React.MouseEventHandler<HTMLButtonElement>;\n workflowId?: string;\n workflowUnavailableReason?: WorkflowUnavailableReason;\n workflowErrorMessage?: string;\n}\n\nexport const OptimizationEngineTab = ({\n workflowId,\n workflowErrorMessage,\n workflowUnavailableReason,\n onApplyRecommendation,\n ...restProps\n}: OptimizationEngineTabProps) => {\n const isWorkflowAvailable = !!workflowId;\n const [confirmOpen, setConfirmOpen] = useState(false);\n\n const { loading: permLoading, allowed: canApply } = usePermission({\n permission: rosApplyPermission,\n });\n\n const isButtonDisabled =\n !isWorkflowAvailable || permLoading || canApply === false;\n\n const tooltipMessage = useMemo(() => {\n if (canApply === false) {\n return 'You do not have permission to apply recommendations';\n }\n if (isWorkflowAvailable) {\n return '';\n }\n if (workflowErrorMessage) {\n return workflowErrorMessage;\n }\n if (workflowUnavailableReason) {\n return DEFAULT_WORKFLOW_MESSAGES[workflowUnavailableReason];\n }\n return DEFAULT_WORKFLOW_MESSAGES.not_configured;\n }, [\n canApply,\n isWorkflowAvailable,\n workflowErrorMessage,\n workflowUnavailableReason,\n ]);\n\n const handleApplyClick = useCallback(() => {\n setConfirmOpen(true);\n }, []);\n\n const handleConfirmCancel = useCallback(() => {\n setConfirmOpen(false);\n }, []);\n\n const handleConfirmApply = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n setConfirmOpen(false);\n onApplyRecommendation?.(event);\n },\n [onApplyRecommendation],\n );\n\n return (\n <Grid container>\n <Grid item xs={12}>\n <ContainerInfoCard\n containerData={restProps.containerData}\n recommendationTerm={restProps.recommendationTerm}\n onRecommendationTermChange={restProps.onRecommendationTermChange}\n />\n </Grid>\n\n <Grid item xs={6}>\n <CodeInfoCard\n cardTitle=\"Current configuration\"\n yamlCodeData={restProps.currentConfiguration}\n />\n </Grid>\n <Grid item xs={6}>\n <CodeInfoCard\n cardTitle=\"Recommended configuration\"\n showCopyCodeButton\n yamlCodeData={restProps.recommendedConfiguration}\n action={\n <Tooltip\n title={tooltipMessage}\n disableHoverListener={!isButtonDisabled}\n disableFocusListener={!isButtonDisabled}\n disableTouchListener={!isButtonDisabled}\n >\n <Box component=\"span\" display=\"inline-block\">\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleApplyClick}\n disabled={isButtonDisabled}\n >\n Apply recommendation\n </Button>\n </Box>\n </Tooltip>\n }\n />\n </Grid>\n\n <Grid item xs={6}>\n <ChartInfoCard\n title=\"CPU utilization\"\n chartData={restProps.chartData}\n recommendationTerm={restProps.recommendationTerm}\n optimizationType={restProps.optimizationType}\n resourceType={RecommendationType.cpu}\n />\n </Grid>\n <Grid item xs={6}>\n <ChartInfoCard\n title=\"Memory utilization\"\n chartData={restProps.chartData}\n recommendationTerm={restProps.recommendationTerm}\n optimizationType={restProps.optimizationType}\n resourceType={RecommendationType.memory}\n />\n </Grid>\n\n <Dialog open={confirmOpen} onClose={handleConfirmCancel}>\n <DialogTitle>Apply recommendation?</DialogTitle>\n <DialogContent>\n <DialogContentText>\n This will execute a workflow to modify the resource configuration on\n the target cluster. This action cannot be easily undone. Are you\n sure you want to proceed?\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button onClick={handleConfirmCancel} color=\"default\">\n Cancel\n </Button>\n <Button\n onClick={handleConfirmApply}\n color=\"primary\"\n variant=\"contained\"\n >\n Apply\n </Button>\n </DialogActions>\n </Dialog>\n </Grid>\n );\n};\nOptimizationEngineTab.displayName = 'OptimizationEngineTab';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OptimizationEngineTab.esm.js","sources":["../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback, useMemo, useState } from 'react';\nimport {\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n Grid,\n Tooltip,\n} from '@material-ui/core';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { rosApplyPermission } from '@red-hat-developer-hub/plugin-cost-management-common/permissions';\nimport type { WorkflowUnavailableReason } from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport { RecommendationType } from '../../models/ChartEnums';\nimport { ChartInfoCard } from './components/chart-info-card/ChartInfoCard';\nimport { CodeInfoCard } from './components/CodeInfoCard';\nimport { ContainerInfoCard } from './components/ContainerInfoCard';\n\ntype ContainerInfoCardProps = Parameters<typeof ContainerInfoCard>[0];\ntype CodeInfoCardProps = Parameters<typeof CodeInfoCard>[0];\ntype ChartInfoCardProps = Parameters<typeof ChartInfoCard>[0];\n\nconst DEFAULT_WORKFLOW_MESSAGES: Record<WorkflowUnavailableReason, string> = {\n not_configured: 'No workflow configured to apply recommendations',\n not_found: 'Workflow not found',\n access_denied: 'You do not have permission to access this workflow',\n service_unavailable: 'Workflow service is currently unavailable',\n};\n\ninterface OptimizationEngineTabProps extends ContainerInfoCardProps {\n currentConfiguration: CodeInfoCardProps['yamlCodeData'];\n recommendedConfiguration: CodeInfoCardProps['yamlCodeData'];\n chartData: ChartInfoCardProps['chartData'];\n optimizationType: ChartInfoCardProps['optimizationType'];\n onApplyRecommendation?: React.MouseEventHandler<HTMLButtonElement>;\n workflowId?: string;\n workflowUnavailableReason?: WorkflowUnavailableReason;\n workflowErrorMessage?: string;\n}\n\nexport const OptimizationEngineTab = ({\n workflowId,\n workflowErrorMessage,\n workflowUnavailableReason,\n onApplyRecommendation,\n ...restProps\n}: OptimizationEngineTabProps) => {\n const isWorkflowAvailable = !!workflowId;\n const [confirmOpen, setConfirmOpen] = useState(false);\n\n const { loading: permLoading, allowed: canApply } = usePermission({\n permission: rosApplyPermission,\n });\n\n const isButtonDisabled =\n !isWorkflowAvailable || permLoading || canApply === false;\n\n const tooltipMessage = useMemo(() => {\n if (canApply === false) {\n return 'You do not have permission to apply recommendations';\n }\n if (isWorkflowAvailable) {\n return '';\n }\n if (workflowErrorMessage) {\n return workflowErrorMessage;\n }\n if (workflowUnavailableReason) {\n return DEFAULT_WORKFLOW_MESSAGES[workflowUnavailableReason];\n }\n return DEFAULT_WORKFLOW_MESSAGES.not_configured;\n }, [\n canApply,\n isWorkflowAvailable,\n workflowErrorMessage,\n workflowUnavailableReason,\n ]);\n\n const handleApplyClick = useCallback(() => {\n setConfirmOpen(true);\n }, []);\n\n const handleConfirmCancel = useCallback(() => {\n setConfirmOpen(false);\n }, []);\n\n const handleConfirmApply = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n setConfirmOpen(false);\n onApplyRecommendation?.(event);\n },\n [onApplyRecommendation],\n );\n\n return (\n <Grid container>\n <Grid item xs={12}>\n <ContainerInfoCard\n containerData={restProps.containerData}\n recommendationTerm={restProps.recommendationTerm}\n onRecommendationTermChange={restProps.onRecommendationTermChange}\n />\n </Grid>\n\n <Grid item xs={6}>\n <CodeInfoCard\n cardTitle=\"Current configuration\"\n yamlCodeData={restProps.currentConfiguration}\n />\n </Grid>\n <Grid item xs={6}>\n <CodeInfoCard\n cardTitle=\"Recommended configuration\"\n showCopyCodeButton\n yamlCodeData={restProps.recommendedConfiguration}\n action={\n <Tooltip\n title={tooltipMessage}\n disableHoverListener={!isButtonDisabled}\n disableFocusListener={!isButtonDisabled}\n disableTouchListener={!isButtonDisabled}\n >\n <Box component=\"span\" display=\"inline-block\">\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleApplyClick}\n disabled={isButtonDisabled}\n >\n Apply recommendation\n </Button>\n </Box>\n </Tooltip>\n }\n />\n </Grid>\n\n <Grid item xs={6}>\n <ChartInfoCard\n title=\"CPU utilization\"\n chartData={restProps.chartData}\n recommendationTerm={restProps.recommendationTerm}\n optimizationType={restProps.optimizationType}\n resourceType={RecommendationType.cpu}\n />\n </Grid>\n <Grid item xs={6}>\n <ChartInfoCard\n title=\"Memory utilization\"\n chartData={restProps.chartData}\n recommendationTerm={restProps.recommendationTerm}\n optimizationType={restProps.optimizationType}\n resourceType={RecommendationType.memory}\n />\n </Grid>\n\n <Dialog open={confirmOpen} onClose={handleConfirmCancel}>\n <DialogTitle>Apply recommendation?</DialogTitle>\n <DialogContent>\n <DialogContentText>\n This will execute a workflow to modify the resource configuration on\n the target cluster. This action cannot be easily undone. Are you\n sure you want to proceed?\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button onClick={handleConfirmCancel} color=\"default\">\n Cancel\n </Button>\n <Button\n onClick={handleConfirmApply}\n color=\"primary\"\n variant=\"contained\"\n >\n Apply\n </Button>\n </DialogActions>\n </Dialog>\n </Grid>\n );\n};\nOptimizationEngineTab.displayName = 'OptimizationEngineTab';\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeInfoCard.esm.js","sources":["../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useMemo } from 'react';\nimport YAML from 'yaml';\nimport { CodeSnippet, InfoCard } from '@backstage/core-components';\nimport { YamlCodeData } from '../../../models/YamlCodeData';\nimport { InfoCardTitle } from '../../../../../components/InfoCardTitle';\n\nconst generateYAMLCode = (yamlCodeData?: YamlCodeData) => {\n const yamlCode = {\n limits: {\n cpu: yamlCodeData?.limits.cpu ?? '-',\n memory: yamlCodeData?.limits.memory ?? '-',\n },\n requests: {\n cpu: yamlCodeData?.requests.cpu ?? '-',\n memory: yamlCodeData?.requests.memory ?? '-',\n },\n };\n\n const yamlCodeString = YAML.stringify(yamlCode).replace(/\"/g, ''); // prettify;\n\n return yamlCodeString;\n};\n\ntype InfoCardProps = Parameters<typeof InfoCard>[0];\n\ninterface CodeInfoCardProps {\n cardTitle: string;\n showCopyCodeButton?: boolean;\n yamlCodeData?: YamlCodeData;\n action?: InfoCardProps['action'];\n}\n\nexport const CodeInfoCard: React.FC<CodeInfoCardProps> = props => {\n const { cardTitle, showCopyCodeButton = false, yamlCodeData } = props;\n\n const YAMLCode = useMemo(\n () => generateYAMLCode(yamlCodeData),\n [yamlCodeData],\n );\n\n return (\n <InfoCard title={<InfoCardTitle title={cardTitle} />} action={props.action}>\n <CodeSnippet\n text={YAMLCode}\n language=\"yaml\"\n showCopyCodeButton={showCopyCodeButton}\n />\n </InfoCard>\n );\n};\n"],"names":[],"mappings":";;;;;AAsBA,MAAM,gBAAA,GAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"CodeInfoCard.esm.js","sources":["../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useMemo } from 'react';\nimport YAML from 'yaml';\nimport { CodeSnippet, InfoCard } from '@backstage/core-components';\nimport { YamlCodeData } from '../../../models/YamlCodeData';\nimport { InfoCardTitle } from '../../../../../components/InfoCardTitle';\n\nconst generateYAMLCode = (yamlCodeData?: YamlCodeData) => {\n const yamlCode = {\n limits: {\n cpu: yamlCodeData?.limits.cpu ?? '-',\n memory: yamlCodeData?.limits.memory ?? '-',\n },\n requests: {\n cpu: yamlCodeData?.requests.cpu ?? '-',\n memory: yamlCodeData?.requests.memory ?? '-',\n },\n };\n\n const yamlCodeString = YAML.stringify(yamlCode).replace(/\"/g, ''); // prettify;\n\n return yamlCodeString;\n};\n\ntype InfoCardProps = Parameters<typeof InfoCard>[0];\n\ninterface CodeInfoCardProps {\n cardTitle: string;\n showCopyCodeButton?: boolean;\n yamlCodeData?: YamlCodeData;\n action?: InfoCardProps['action'];\n}\n\nexport const CodeInfoCard: React.FC<CodeInfoCardProps> = props => {\n const { cardTitle, showCopyCodeButton = false, yamlCodeData } = props;\n\n const YAMLCode = useMemo(\n () => generateYAMLCode(yamlCodeData),\n [yamlCodeData],\n );\n\n return (\n <InfoCard title={<InfoCardTitle title={cardTitle} />} action={props.action}>\n <CodeSnippet\n text={YAMLCode}\n language=\"yaml\"\n showCopyCodeButton={showCopyCodeButton}\n />\n </InfoCard>\n );\n};\n"],"names":[],"mappings":";;;;;AAsBA,MAAM,gBAAA,GAAmB,CAAC,YAAA,KAAgC;AACxD,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,MAAA,EAAQ;AAAA,MACN,GAAA,EAAK,YAAA,EAAc,MAAA,CAAO,GAAA,IAAO,GAAA;AAAA,MACjC,MAAA,EAAQ,YAAA,EAAc,MAAA,CAAO,MAAA,IAAU;AAAA,KACzC;AAAA,IACA,QAAA,EAAU;AAAA,MACR,GAAA,EAAK,YAAA,EAAc,QAAA,CAAS,GAAA,IAAO,GAAA;AAAA,MACnC,MAAA,EAAQ,YAAA,EAAc,QAAA,CAAS,MAAA,IAAU;AAAA;AAC3C,GACF;AAEA,EAAA,MAAM,iBAAiB,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA,CAAE,OAAA,CAAQ,MAAM,EAAE,CAAA;AAEhE,EAAA,OAAO,cAAA;AACT,CAAA;AAWO,MAAM,eAA4C,CAAA,KAAA,KAAS;AAChE,EAAA,MAAM,EAAE,SAAA,EAAW,kBAAA,GAAqB,KAAA,EAAO,cAAa,GAAI,KAAA;AAEhE,EAAA,MAAM,QAAA,GAAW,OAAA;AAAA,IACf,MAAM,iBAAiB,YAAY,CAAA;AAAA,IACnC,CAAC,YAAY;AAAA,GACf;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,QAAA,EAAA,EAAS,KAAA,kBAAO,KAAA,CAAA,aAAA,CAAC,aAAA,EAAA,EAAc,OAAO,SAAA,EAAW,CAAA,EAAI,MAAA,EAAQ,KAAA,CAAM,MAAA,EAAA,kBAClE,KAAA,CAAA,aAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,QAAA;AAAA,MACN,QAAA,EAAS,MAAA;AAAA,MACT;AAAA;AAAA,GAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContainerInfoCard.esm.js","sources":["../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { InfoCard } from '@backstage/core-components';\nimport {\n Grid,\n Typography,\n FormControl,\n Select,\n MenuItem,\n InputLabel,\n makeStyles,\n} from '@material-ui/core';\nimport { Interval } from '../../../models/ChartEnums';\n\nconst useStyles = makeStyles(theme => ({\n value: {\n fontWeight: 'bold',\n overflow: 'hidden',\n lineHeight: '24px',\n wordBreak: 'break-word',\n },\n label: {\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n fontSize: '10px',\n fontWeight: 'bold',\n letterSpacing: 0.5,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n },\n}));\n\ninterface ContainerInfoCardProps {\n containerData: Array<{ key: string; value?: string }>;\n onRecommendationTermChange: (\n event: React.ChangeEvent<{\n name?: string;\n value: unknown;\n }>,\n child: React.ReactNode,\n ) => void;\n recommendationTerm: Interval;\n}\n\nexport const ContainerInfoCard = (props: ContainerInfoCardProps) => {\n const classes = useStyles();\n\n return (\n <InfoCard\n title=\"Details\"\n action={\n <FormControl variant=\"outlined\" style={{ top: '0.4rem' }}>\n <InputLabel id=\"term-label\">Term</InputLabel>\n <Select\n labelId=\"term-label\"\n id=\"term\"\n value={props.recommendationTerm}\n onChange={props.onRecommendationTermChange}\n label=\"Term\"\n >\n <MenuItem value=\"shortTerm\">Last 24 hrs</MenuItem>\n <MenuItem value=\"mediumTerm\">Last 7 days</MenuItem>\n <MenuItem value=\"longTerm\">Last 15 days</MenuItem>\n </Select>\n </FormControl>\n }\n >\n <Grid container spacing={2}>\n {props.containerData.map(item => [\n <Grid item xs={2} key={item.key}>\n <Typography variant=\"h2\" className={classes.label}>\n {item.key}\n </Typography>\n <Typography variant=\"body1\" className={classes.value}>\n {item.value}\n </Typography>\n </Grid>,\n ])}\n </Grid>\n </InfoCard>\n );\n};\nContainerInfoCard.displayName = 'ContainerInfoCard';\n"],"names":[],"mappings":";;;;AA6BA,MAAM,SAAA,GAAY,WAAW,
|
|
1
|
+
{"version":3,"file":"ContainerInfoCard.esm.js","sources":["../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { InfoCard } from '@backstage/core-components';\nimport {\n Grid,\n Typography,\n FormControl,\n Select,\n MenuItem,\n InputLabel,\n makeStyles,\n} from '@material-ui/core';\nimport { Interval } from '../../../models/ChartEnums';\n\nconst useStyles = makeStyles(theme => ({\n value: {\n fontWeight: 'bold',\n overflow: 'hidden',\n lineHeight: '24px',\n wordBreak: 'break-word',\n },\n label: {\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n fontSize: '10px',\n fontWeight: 'bold',\n letterSpacing: 0.5,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n },\n}));\n\ninterface ContainerInfoCardProps {\n containerData: Array<{ key: string; value?: string }>;\n onRecommendationTermChange: (\n event: React.ChangeEvent<{\n name?: string;\n value: unknown;\n }>,\n child: React.ReactNode,\n ) => void;\n recommendationTerm: Interval;\n}\n\nexport const ContainerInfoCard = (props: ContainerInfoCardProps) => {\n const classes = useStyles();\n\n return (\n <InfoCard\n title=\"Details\"\n action={\n <FormControl variant=\"outlined\" style={{ top: '0.4rem' }}>\n <InputLabel id=\"term-label\">Term</InputLabel>\n <Select\n labelId=\"term-label\"\n id=\"term\"\n value={props.recommendationTerm}\n onChange={props.onRecommendationTermChange}\n label=\"Term\"\n >\n <MenuItem value=\"shortTerm\">Last 24 hrs</MenuItem>\n <MenuItem value=\"mediumTerm\">Last 7 days</MenuItem>\n <MenuItem value=\"longTerm\">Last 15 days</MenuItem>\n </Select>\n </FormControl>\n }\n >\n <Grid container spacing={2}>\n {props.containerData.map(item => [\n <Grid item xs={2} key={item.key}>\n <Typography variant=\"h2\" className={classes.label}>\n {item.key}\n </Typography>\n <Typography variant=\"body1\" className={classes.value}>\n {item.value}\n </Typography>\n </Grid>,\n ])}\n </Grid>\n </InfoCard>\n );\n};\nContainerInfoCard.displayName = 'ContainerInfoCard';\n"],"names":[],"mappings":";;;;AA6BA,MAAM,SAAA,GAAY,WAAW,CAAA,KAAA,MAAU;AAAA,EACrC,KAAA,EAAO;AAAA,IACL,UAAA,EAAY,MAAA;AAAA,IACZ,QAAA,EAAU,QAAA;AAAA,IACV,UAAA,EAAY,MAAA;AAAA,IACZ,SAAA,EAAW;AAAA,GACb;AAAA,EACA,KAAA,EAAO;AAAA,IACL,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAAA,IAC1B,aAAA,EAAe,WAAA;AAAA,IACf,QAAA,EAAU,MAAA;AAAA,IACV,UAAA,EAAY,MAAA;AAAA,IACZ,aAAA,EAAe,GAAA;AAAA,IACf,QAAA,EAAU,QAAA;AAAA,IACV,UAAA,EAAY;AAAA;AAEhB,CAAA,CAAE,CAAA;AAcK,MAAM,iBAAA,GAAoB,CAAC,KAAA,KAAkC;AAClE,EAAA,MAAM,UAAU,SAAA,EAAU;AAE1B,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,SAAA;AAAA,MACN,MAAA,kBACE,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,OAAA,EAAQ,YAAW,KAAA,EAAO,EAAE,GAAA,EAAK,QAAA,sBAC5C,KAAA,CAAA,aAAA,CAAC,UAAA,EAAA,EAAW,EAAA,EAAG,YAAA,EAAA,EAAa,MAAI,CAAA,kBAChC,KAAA,CAAA,aAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,YAAA;AAAA,UACR,EAAA,EAAG,MAAA;AAAA,UACH,OAAO,KAAA,CAAM,kBAAA;AAAA,UACb,UAAU,KAAA,CAAM,0BAAA;AAAA,UAChB,KAAA,EAAM;AAAA,SAAA;AAAA,wBAEN,KAAA,CAAA,aAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,WAAA,EAAA,EAAY,aAAW,CAAA;AAAA,wBACvC,KAAA,CAAA,aAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,YAAA,EAAA,EAAa,aAAW,CAAA;AAAA,wBACxC,KAAA,CAAA,aAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,UAAA,EAAA,EAAW,cAAY;AAAA,OAE3C;AAAA,KAAA;AAAA,oBAGF,KAAA,CAAA,aAAA,CAAC,QAAK,SAAA,EAAS,IAAA,EAAC,SAAS,CAAA,EAAA,EACtB,KAAA,CAAM,aAAA,CAAc,GAAA,CAAI,CAAA,IAAA,KAAQ;AAAA,sBAC/B,KAAA,CAAA,aAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,CAAA,EAAG,GAAA,EAAK,IAAA,CAAK,GAAA,EAAA,kBAC1B,KAAA,CAAA,aAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,KAAA,EAAA,EACzC,IAAA,CAAK,GACR,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,KAAA,EAAA,EAC5C,IAAA,CAAK,KACR,CACF;AAAA,KACD,CACH;AAAA,GACF;AAEJ;AACA,iBAAA,CAAkB,WAAA,GAAc,mBAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartInfoCard.esm.js","sources":["../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useMemo } from 'react';\nimport { InfoCard } from '@backstage/core-components';\nimport type { RecommendationBoxPlots } from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport {\n UsageType,\n RecommendationType,\n OptimizationType,\n Interval,\n} from '../../../../models/ChartEnums';\nimport { InfoCardTitle } from '../../../../../../components/InfoCardTitle';\nimport { IntlBreakdownChart } from './components/IntlBreakdownChart';\n\ninterface ChartInfoCardProps {\n title: React.ReactNode;\n recommendationTerm: Interval;\n chartData: RecommendationBoxPlots;\n resourceType: RecommendationType;\n optimizationType: OptimizationType;\n}\n\nexport const ChartInfoCard = (props: ChartInfoCardProps) => {\n const usageType = useMemo(\n () =>\n props.resourceType === 'cpu' ? UsageType.cpuUsage : UsageType.memoryUsage,\n [props.resourceType],\n );\n\n return (\n <InfoCard title={<InfoCardTitle title={props.title} />}>\n <IntlBreakdownChart\n recommendationTerm={props.recommendationTerm}\n value={props.chartData}\n usageType={usageType}\n recommendationType={props.resourceType}\n optimizationType={props.optimizationType}\n />\n </InfoCard>\n );\n};\nChartInfoCard.displayName = 'ChartInfoCard';\n"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"ChartInfoCard.esm.js","sources":["../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useMemo } from 'react';\nimport { InfoCard } from '@backstage/core-components';\nimport type { RecommendationBoxPlots } from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport {\n UsageType,\n RecommendationType,\n OptimizationType,\n Interval,\n} from '../../../../models/ChartEnums';\nimport { InfoCardTitle } from '../../../../../../components/InfoCardTitle';\nimport { IntlBreakdownChart } from './components/IntlBreakdownChart';\n\ninterface ChartInfoCardProps {\n title: React.ReactNode;\n recommendationTerm: Interval;\n chartData: RecommendationBoxPlots;\n resourceType: RecommendationType;\n optimizationType: OptimizationType;\n}\n\nexport const ChartInfoCard = (props: ChartInfoCardProps) => {\n const usageType = useMemo(\n () =>\n props.resourceType === 'cpu' ? UsageType.cpuUsage : UsageType.memoryUsage,\n [props.resourceType],\n );\n\n return (\n <InfoCard title={<InfoCardTitle title={props.title} />}>\n <IntlBreakdownChart\n recommendationTerm={props.recommendationTerm}\n value={props.chartData}\n usageType={usageType}\n recommendationType={props.resourceType}\n optimizationType={props.optimizationType}\n />\n </InfoCard>\n );\n};\nChartInfoCard.displayName = 'ChartInfoCard';\n"],"names":[],"mappings":";;;;;;AAoCO,MAAM,aAAA,GAAgB,CAAC,KAAA,KAA8B;AAC1D,EAAA,MAAM,SAAA,GAAY,OAAA;AAAA,IAChB,MACE,KAAA,CAAM,YAAA,KAAiB,KAAA,GAAQ,SAAA,CAAU,WAAW,SAAA,CAAU,WAAA;AAAA,IAChE,CAAC,MAAM,YAAY;AAAA,GACrB;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,YAAS,KAAA,kBAAO,KAAA,CAAA,aAAA,CAAC,iBAAc,KAAA,EAAO,KAAA,CAAM,OAAO,CAAA,EAAA,kBAClD,KAAA,CAAA,aAAA;AAAA,IAAC,kBAAA;AAAA,IAAA;AAAA,MACC,oBAAoB,KAAA,CAAM,kBAAA;AAAA,MAC1B,OAAO,KAAA,CAAM,SAAA;AAAA,MACb,SAAA;AAAA,MACA,oBAAoB,KAAA,CAAM,YAAA;AAAA,MAC1B,kBAAkB,KAAA,CAAM;AAAA;AAAA,GAE5B,CAAA;AAEJ;AACA,aAAA,CAAc,WAAA,GAAc,eAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlBreakdownChart.esm.js","sources":["../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { IntlProvider } from 'react-intl';\nimport { RecommendationBoxPlots } from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport {\n Interval,\n OptimizationType,\n RecommendationType,\n ResourceType,\n UsageType,\n} from '../../../../../models/ChartEnums';\nimport {\n createRecommendationDatum,\n createUsageDatum,\n} from './intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-data-format';\nimport { OptimizationsBreakdownChart } from './intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/OptimizationsBreakdownChart';\nimport messagesData from './intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/data.json';\n\nexport const IntlBreakdownChart = (props: {\n usageType: UsageType;\n recommendationType: RecommendationType;\n optimizationType: OptimizationType;\n recommendationTerm: Interval;\n value: RecommendationBoxPlots;\n}) => {\n const {\n usageType,\n recommendationType,\n optimizationType,\n recommendationTerm,\n value,\n } = props;\n\n const usageDatum = createUsageDatum(\n usageType,\n recommendationTerm,\n value.recommendations,\n );\n\n const limitDatum = createRecommendationDatum(\n recommendationTerm,\n usageDatum,\n recommendationType,\n ResourceType.limits,\n optimizationType,\n value.recommendations,\n );\n\n const requestDatum = createRecommendationDatum(\n recommendationTerm,\n usageDatum,\n recommendationType,\n ResourceType.requests,\n optimizationType,\n value.recommendations,\n );\n\n return (\n <IntlProvider locale=\"en\" messages={messagesData.en}>\n <OptimizationsBreakdownChart\n baseHeight={350}\n name={`utilization-${usageType}`}\n limitData={limitDatum}\n requestData={requestDatum}\n usageData={usageDatum}\n />\n </IntlProvider>\n );\n};\nIntlBreakdownChart.displayName = 'IntlBreakdownChart';\n"],"names":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"IntlBreakdownChart.esm.js","sources":["../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { IntlProvider } from 'react-intl';\nimport { RecommendationBoxPlots } from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport {\n Interval,\n OptimizationType,\n RecommendationType,\n ResourceType,\n UsageType,\n} from '../../../../../models/ChartEnums';\nimport {\n createRecommendationDatum,\n createUsageDatum,\n} from './intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-data-format';\nimport { OptimizationsBreakdownChart } from './intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/OptimizationsBreakdownChart';\nimport messagesData from './intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/data.json';\n\nexport const IntlBreakdownChart = (props: {\n usageType: UsageType;\n recommendationType: RecommendationType;\n optimizationType: OptimizationType;\n recommendationTerm: Interval;\n value: RecommendationBoxPlots;\n}) => {\n const {\n usageType,\n recommendationType,\n optimizationType,\n recommendationTerm,\n value,\n } = props;\n\n const usageDatum = createUsageDatum(\n usageType,\n recommendationTerm,\n value.recommendations,\n );\n\n const limitDatum = createRecommendationDatum(\n recommendationTerm,\n usageDatum,\n recommendationType,\n ResourceType.limits,\n optimizationType,\n value.recommendations,\n );\n\n const requestDatum = createRecommendationDatum(\n recommendationTerm,\n usageDatum,\n recommendationType,\n ResourceType.requests,\n optimizationType,\n value.recommendations,\n );\n\n return (\n <IntlProvider locale=\"en\" messages={messagesData.en}>\n <OptimizationsBreakdownChart\n baseHeight={350}\n name={`utilization-${usageType}`}\n limitData={limitDatum}\n requestData={requestDatum}\n usageData={usageDatum}\n />\n </IntlProvider>\n );\n};\nIntlBreakdownChart.displayName = 'IntlBreakdownChart';\n"],"names":[],"mappings":";;;;;;;AAiCO,MAAM,kBAAA,GAAqB,CAAC,KAAA,KAM7B;AACJ,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,kBAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF,GAAI,KAAA;AAEJ,EAAA,MAAM,UAAA,GAAa,gBAAA;AAAA,IACjB,SAAA;AAAA,IACA,kBAAA;AAAA,IACA,KAAA,CAAM;AAAA,GACR;AAEA,EAAA,MAAM,UAAA,GAAa,yBAAA;AAAA,IACjB,kBAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,YAAA,CAAa,MAAA;AAAA,IACb,gBAAA;AAAA,IACA,KAAA,CAAM;AAAA,GACR;AAEA,EAAA,MAAM,YAAA,GAAe,yBAAA;AAAA,IACnB,kBAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,YAAA,CAAa,QAAA;AAAA,IACb,gBAAA;AAAA,IACA,KAAA,CAAM;AAAA,GACR;AAEA,EAAA,2CACG,YAAA,EAAA,EAAa,MAAA,EAAO,IAAA,EAAK,QAAA,EAAU,aAAa,EAAA,EAAA,kBAC/C,KAAA,CAAA,aAAA;AAAA,IAAC,2BAAA;AAAA,IAAA;AAAA,MACC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,eAAe,SAAS,CAAA,CAAA;AAAA,MAC9B,SAAA,EAAW,UAAA;AAAA,MACX,WAAA,EAAa,YAAA;AAAA,MACb,SAAA,EAAW;AAAA;AAAA,GAEf,CAAA;AAEJ;AACA,kBAAA,CAAmB,WAAA,GAAc,oBAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptimizationsBreakdownChart.esm.js","sources":["../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/OptimizationsBreakdownChart.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n Chart,\n ChartArea,\n ChartAxis,\n ChartBoxPlot,\n ChartLegend,\n ChartLegendTooltip,\n ChartScatter,\n createContainer,\n getInteractiveLegendEvents,\n ChartThemeColor,\n} from '@patternfly/react-charts/victory';\nimport { chart_color_blue_100 } from '@patternfly/react-tokens/dist/js/chart_color_blue_100';\nimport { chart_color_blue_200 } from '@patternfly/react-tokens/dist/js/chart_color_blue_200';\nimport { chart_color_blue_400 } from '@patternfly/react-tokens/dist/js/chart_color_blue_400';\nimport { chart_color_red_orange_200 } from '@patternfly/react-tokens/dist/js/chart_color_red_orange_200';\nimport { ChartSeries } from './types/ChartSeries';\nimport {\n getDomain,\n getLegendData,\n getResizeObserver,\n initHiddenSeries,\n isDataAvailable,\n isSeriesHidden,\n} from './utils/chart-utils';\nimport messages from './i18n/messages';\nimport { unitsLookupKey } from './utils/format';\nimport { getDateRangeString } from './utils/chart-datum';\n\nconst useOptimizationsBreakdownChartStyles = makeStyles(() => ({\n chartOverride: {\n '& > div > div > svg': {\n overflow: 'visible',\n },\n },\n}));\n\nexport const chartStyles = {\n limit: {\n fill: 'none',\n },\n limitColorScale: [chart_color_red_orange_200.value],\n request: {\n fill: 'none',\n },\n requestColorScale: [chart_color_blue_400.value],\n usageColorScale: [chart_color_blue_100.value, chart_color_blue_200.value],\n};\n\ninterface OptimizationsBreakdownChartOwnProps {\n baseHeight: number;\n limitData?: any;\n name?: string;\n padding?: any;\n requestData?: any;\n usageData?: any;\n}\n\ntype OptimizationsBreakdownChartProps = OptimizationsBreakdownChartOwnProps;\n\nconst OptimizationsBreakdownChart: React.FC<\n OptimizationsBreakdownChartProps\n> = ({ baseHeight, name, limitData, padding, requestData, usageData }) => {\n const [containerRef] = useState(React.createRef<HTMLDivElement>());\n const [cursorVoronoiContainer, setCursorVoronoiContainer] = useState<any>();\n const [extraHeight, setExtraHeight] = useState(0);\n const [hiddenSeries, setHiddenSeries] = useState(new Set<number>());\n const [series, setSeries] = useState<ChartSeries[]>();\n const [width, setWidth] = useState(0);\n\n const intl = useIntl();\n const classes = useOptimizationsBreakdownChartStyles();\n\n // Clone original container. See https://issues.redhat.com/browse/COST-762\n const cloneContainer = () => {\n const legendData = getLegendData(series, hiddenSeries, true);\n // Force extra space for line wrapping\n legendData?.push(\n {\n childName: 'usage',\n name: '',\n symbol: {\n fill: 'none',\n },\n },\n {\n childName: 'usage',\n name: '',\n symbol: {\n fill: 'none',\n },\n },\n );\n return cursorVoronoiContainer\n ? React.cloneElement(cursorVoronoiContainer, {\n disable: !isDataAvailable(series, hiddenSeries),\n labelComponent: (\n <ChartLegendTooltip\n legendData={legendData}\n title={datum => `${datum.x}`}\n />\n ),\n } as any)\n : undefined;\n };\n\n const getLimitChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'limit') {\n return (\n <ChartArea\n data={!hiddenSeries.has(index) ? serie.data : [{ y: null }]}\n interpolation=\"monotoneX\"\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getRequestChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'request') {\n return (\n <ChartArea\n data={!hiddenSeries.has(index) ? serie.data : [{ y: null }]}\n interpolation=\"monotoneX\"\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getScatterChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'scatter') {\n return (\n <ChartScatter\n data={!hiddenSeries.has(index - 1) ? serie.data : [{ y: null }]}\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getUsageChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'usage') {\n return (\n <ChartBoxPlot\n boxWidth={width < 475 ? 15 : undefined}\n data={!hiddenSeries.has(index) ? serie.data : [{ y: [null] }]}\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n // Returns groups of chart names associated with each data series\n const getChartNames = () => {\n const result: (string | string[] | undefined)[] = [];\n\n if (series) {\n series.forEach(serie => {\n // Each group of chart names are hidden / shown together\n if (serie.childName === 'usage') {\n result.push([serie.childName, 'scatter']);\n } else if (serie.childName !== 'scatter') {\n result.push(serie.childName);\n }\n });\n }\n return result as any;\n };\n\n const getPadding = useCallback(() => {\n return padding\n ? padding\n : {\n bottom: 75 + extraHeight, // Maintain chart aspect ratio\n left: 50,\n right: 50,\n top: 10,\n };\n }, [extraHeight, padding]);\n\n // Hide each data series individually\n const handleOnLegendClick = (index: number) => {\n const newHiddenSeries = initHiddenSeries(hiddenSeries, index);\n setHiddenSeries(newHiddenSeries);\n };\n\n // Returns CursorVoronoiContainer component\n const getCursorVoronoiContainer = useCallback(() => {\n // Note: Container order is important\n const CursorVoronoiContainer: any = createContainer('voronoi', 'cursor');\n\n const labelFormatter = (datum: {\n childName: string;\n _min: undefined;\n _max: undefined;\n _median: undefined;\n _q1: undefined;\n _q3: undefined;\n yVal: null;\n units: string;\n y: any[];\n }) => {\n const formatValue = (val: undefined | null) =>\n val !== undefined ? val : '';\n if (datum.childName === 'scatter') {\n return null;\n } else if (\n datum.childName === 'usage' &&\n (datum._min !== undefined ||\n datum._max !== undefined ||\n datum._median !== undefined ||\n datum._q1 !== undefined ||\n datum._q3 !== undefined ||\n datum.yVal !== null)\n ) {\n return intl.formatMessage(messages.chartUsageTooltip, {\n br: '\\n',\n min: formatValue(datum._min !== undefined ? datum._min : datum.yVal),\n max: formatValue(datum._max !== undefined ? datum._max : datum.yVal),\n median: formatValue(\n datum._median !== undefined ? datum._median : datum.yVal,\n ),\n q1: formatValue(datum._q1 !== undefined ? datum._q1 : datum.yVal),\n q3: formatValue(datum._q3 !== undefined ? datum._q3 : datum.yVal),\n units: intl.formatMessage(messages.units, {\n units: unitsLookupKey(datum.units),\n }),\n });\n }\n\n // With box plot, datum.y will be an array\n const yVal = Array.isArray(datum.y) ? datum.y[0] : datum.y;\n let units = datum.units;\n\n /**\n * The recommendations API intentionally omits CPU request and limit units when \"cores\".\n *\n * The yaml format for the resource units needs to adhere to the Kubernetes standard that is outlined here\n * https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n *\n * Example. \"45 millicores\" is represented as \"45m\", 64 MiB is represented as \"64Mi\",\n * 2.3 cores is represented as \"2.3\" (Note cores is not specified)\n */\n if (\n (datum.childName === 'limit' || datum.childName === 'request') &&\n datum.units === ''\n ) {\n units = unitsLookupKey('cores');\n }\n return yVal !== null\n ? intl.formatMessage(messages.valueUnits, {\n value: yVal,\n units: intl.formatMessage(messages.units, {\n units: unitsLookupKey(units),\n }),\n })\n : intl.formatMessage(messages.chartNoData);\n };\n\n return (\n <CursorVoronoiContainer\n cursorDimension=\"x\"\n labels={({ datum }: any) => labelFormatter(datum)}\n mouseFollowTooltips\n voronoiDimension=\"x\"\n voronoiPadding={getPadding()}\n />\n );\n }, [getPadding, intl]);\n\n // Returns onMouseOver, onMouseOut, and onClick events for the interactive legend\n const getEvents = () => {\n const result = getInteractiveLegendEvents({\n chartNames: getChartNames(),\n isHidden: index => isSeriesHidden(hiddenSeries, index),\n legendName: `${name}-legend`,\n onLegendClick: props => handleOnLegendClick(props.index),\n });\n return result;\n };\n\n const getHeight = () => {\n return baseHeight + extraHeight;\n };\n\n const getLegend = () => {\n return (\n <ChartLegend\n data={getLegendData(series, hiddenSeries)}\n gutter={20}\n name={`${name}-legend`}\n y={320}\n />\n );\n };\n\n const handleLegendAllowWrap = (value: number) => {\n if (value !== extraHeight) {\n setExtraHeight(value);\n }\n };\n\n const handleOnResize = useCallback(() => {\n const { clientWidth = 0 } = containerRef.current || {};\n\n if (clientWidth !== width) {\n setWidth(clientWidth);\n }\n }, [containerRef, width]);\n\n const initDatum = useCallback(() => {\n // Show all legends, regardless of data size\n\n const newSeries: ChartSeries[] = [];\n if (requestData && requestData.length) {\n newSeries.push({\n childName: 'request',\n data: requestData,\n legendItem: {\n name: getDateRangeString(\n requestData,\n messages.recommendedRequest,\n true,\n ),\n symbol: {\n fill: chartStyles.requestColorScale[0],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.request),\n },\n style: {\n data: {\n ...chartStyles.request,\n stroke: chartStyles.requestColorScale[0],\n },\n },\n });\n }\n if (limitData && limitData.length) {\n newSeries.push({\n childName: 'limit',\n data: limitData,\n legendItem: {\n name: getDateRangeString(limitData, messages.recommendedLimit, true),\n symbol: {\n fill: chartStyles.limitColorScale[0],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.limit),\n },\n style: {\n data: {\n ...chartStyles.limit,\n stroke: chartStyles.limitColorScale[0],\n },\n },\n });\n }\n if (usageData && usageData.length) {\n const boxPlotData: any[] = [];\n usageData.map((datum: any) => {\n if (datum.y.every((val: any, _i: any, arr: any[]) => val === arr[0])) {\n boxPlotData.push({\n ...datum,\n yVal: datum.y[0],\n y: [null],\n });\n } else {\n boxPlotData.push(datum);\n }\n });\n newSeries.push({\n childName: 'usage',\n data: boxPlotData as any,\n legendItem: {\n name: getDateRangeString(usageData, messages.actualUsage),\n symbol: {\n fill: chartStyles.usageColorScale[1],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.usage),\n },\n style: {\n median: {\n stroke: chartStyles.usageColorScale[0],\n },\n q1: {\n fill: chartStyles.usageColorScale[1],\n },\n q3: {\n fill: chartStyles.usageColorScale[1],\n },\n } as any,\n });\n\n // Show dots in place of box plot when all values are equal\n const scatterData: any[] = [];\n usageData.map((datum: any) => {\n if (datum.y.every((val: any, _i: any, arr: any[]) => val === arr[0])) {\n scatterData.push({\n ...datum,\n y: datum.y[0],\n });\n } else {\n scatterData.push({\n ...datum,\n y: null,\n });\n }\n });\n newSeries.push({\n childName: 'scatter',\n data: scatterData as any,\n style: {\n data: { fill: chartStyles.usageColorScale[1] },\n } as any,\n });\n }\n setSeries(newSeries);\n setCursorVoronoiContainer(getCursorVoronoiContainer());\n setHiddenSeries(new Set());\n }, [getCursorVoronoiContainer, intl, limitData, requestData, usageData]);\n\n useMemo(() => {\n initDatum();\n }, [initDatum]);\n\n useEffect(() => {\n const unobserve = getResizeObserver(containerRef.current, handleOnResize);\n return () => {\n if (unobserve) {\n unobserve();\n }\n };\n }, [containerRef, handleOnResize]);\n\n const chartHeight = getHeight();\n\n return (\n <div className={classes.chartOverride} ref={containerRef}>\n <div style={{ height: chartHeight }}>\n <Chart\n key={`chart-${name}`}\n containerComponent={cloneContainer()}\n domain={getDomain(series, hiddenSeries, 1)}\n domainPadding={{ x: [30, 30] }}\n events={getEvents()}\n height={chartHeight}\n legendAllowWrap={handleLegendAllowWrap}\n legendComponent={getLegend()}\n legendPosition=\"bottom\"\n name={name}\n padding={getPadding()}\n width={width}\n // PatternFly will handle theming automatically when pf-v6-theme-dark is applied\n themeColor={ChartThemeColor.default}\n >\n <ChartAxis fixLabelOverlap />\n <ChartAxis dependentAxis showGrid />\n {getRequestChart()}\n {getLimitChart()}\n {getScatterChart()}\n {getUsageChart()}\n </Chart>\n </div>\n </div>\n );\n};\n\nexport { OptimizationsBreakdownChart };\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OptimizationsBreakdownChart.esm.js","sources":["../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/OptimizationsBreakdownChart.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n Chart,\n ChartArea,\n ChartAxis,\n ChartBoxPlot,\n ChartLegend,\n ChartLegendTooltip,\n ChartScatter,\n createContainer,\n getInteractiveLegendEvents,\n ChartThemeColor,\n} from '@patternfly/react-charts/victory';\nimport { chart_color_blue_100 } from '@patternfly/react-tokens/dist/js/chart_color_blue_100';\nimport { chart_color_blue_200 } from '@patternfly/react-tokens/dist/js/chart_color_blue_200';\nimport { chart_color_blue_400 } from '@patternfly/react-tokens/dist/js/chart_color_blue_400';\nimport { chart_color_red_orange_200 } from '@patternfly/react-tokens/dist/js/chart_color_red_orange_200';\nimport { ChartSeries } from './types/ChartSeries';\nimport {\n getDomain,\n getLegendData,\n getResizeObserver,\n initHiddenSeries,\n isDataAvailable,\n isSeriesHidden,\n} from './utils/chart-utils';\nimport messages from './i18n/messages';\nimport { unitsLookupKey } from './utils/format';\nimport { getDateRangeString } from './utils/chart-datum';\n\nconst useOptimizationsBreakdownChartStyles = makeStyles(() => ({\n chartOverride: {\n '& > div > div > svg': {\n overflow: 'visible',\n },\n },\n}));\n\nexport const chartStyles = {\n limit: {\n fill: 'none',\n },\n limitColorScale: [chart_color_red_orange_200.value],\n request: {\n fill: 'none',\n },\n requestColorScale: [chart_color_blue_400.value],\n usageColorScale: [chart_color_blue_100.value, chart_color_blue_200.value],\n};\n\ninterface OptimizationsBreakdownChartOwnProps {\n baseHeight: number;\n limitData?: any;\n name?: string;\n padding?: any;\n requestData?: any;\n usageData?: any;\n}\n\ntype OptimizationsBreakdownChartProps = OptimizationsBreakdownChartOwnProps;\n\nconst OptimizationsBreakdownChart: React.FC<\n OptimizationsBreakdownChartProps\n> = ({ baseHeight, name, limitData, padding, requestData, usageData }) => {\n const [containerRef] = useState(React.createRef<HTMLDivElement>());\n const [cursorVoronoiContainer, setCursorVoronoiContainer] = useState<any>();\n const [extraHeight, setExtraHeight] = useState(0);\n const [hiddenSeries, setHiddenSeries] = useState(new Set<number>());\n const [series, setSeries] = useState<ChartSeries[]>();\n const [width, setWidth] = useState(0);\n\n const intl = useIntl();\n const classes = useOptimizationsBreakdownChartStyles();\n\n // Clone original container. See https://issues.redhat.com/browse/COST-762\n const cloneContainer = () => {\n const legendData = getLegendData(series, hiddenSeries, true);\n // Force extra space for line wrapping\n legendData?.push(\n {\n childName: 'usage',\n name: '',\n symbol: {\n fill: 'none',\n },\n },\n {\n childName: 'usage',\n name: '',\n symbol: {\n fill: 'none',\n },\n },\n );\n return cursorVoronoiContainer\n ? React.cloneElement(cursorVoronoiContainer, {\n disable: !isDataAvailable(series, hiddenSeries),\n labelComponent: (\n <ChartLegendTooltip\n legendData={legendData}\n title={datum => `${datum.x}`}\n />\n ),\n } as any)\n : undefined;\n };\n\n const getLimitChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'limit') {\n return (\n <ChartArea\n data={!hiddenSeries.has(index) ? serie.data : [{ y: null }]}\n interpolation=\"monotoneX\"\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getRequestChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'request') {\n return (\n <ChartArea\n data={!hiddenSeries.has(index) ? serie.data : [{ y: null }]}\n interpolation=\"monotoneX\"\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getScatterChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'scatter') {\n return (\n <ChartScatter\n data={!hiddenSeries.has(index - 1) ? serie.data : [{ y: null }]}\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getUsageChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'usage') {\n return (\n <ChartBoxPlot\n boxWidth={width < 475 ? 15 : undefined}\n data={!hiddenSeries.has(index) ? serie.data : [{ y: [null] }]}\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n // Returns groups of chart names associated with each data series\n const getChartNames = () => {\n const result: (string | string[] | undefined)[] = [];\n\n if (series) {\n series.forEach(serie => {\n // Each group of chart names are hidden / shown together\n if (serie.childName === 'usage') {\n result.push([serie.childName, 'scatter']);\n } else if (serie.childName !== 'scatter') {\n result.push(serie.childName);\n }\n });\n }\n return result as any;\n };\n\n const getPadding = useCallback(() => {\n return padding\n ? padding\n : {\n bottom: 75 + extraHeight, // Maintain chart aspect ratio\n left: 50,\n right: 50,\n top: 10,\n };\n }, [extraHeight, padding]);\n\n // Hide each data series individually\n const handleOnLegendClick = (index: number) => {\n const newHiddenSeries = initHiddenSeries(hiddenSeries, index);\n setHiddenSeries(newHiddenSeries);\n };\n\n // Returns CursorVoronoiContainer component\n const getCursorVoronoiContainer = useCallback(() => {\n // Note: Container order is important\n const CursorVoronoiContainer: any = createContainer('voronoi', 'cursor');\n\n const labelFormatter = (datum: {\n childName: string;\n _min: undefined;\n _max: undefined;\n _median: undefined;\n _q1: undefined;\n _q3: undefined;\n yVal: null;\n units: string;\n y: any[];\n }) => {\n const formatValue = (val: undefined | null) =>\n val !== undefined ? val : '';\n if (datum.childName === 'scatter') {\n return null;\n } else if (\n datum.childName === 'usage' &&\n (datum._min !== undefined ||\n datum._max !== undefined ||\n datum._median !== undefined ||\n datum._q1 !== undefined ||\n datum._q3 !== undefined ||\n datum.yVal !== null)\n ) {\n return intl.formatMessage(messages.chartUsageTooltip, {\n br: '\\n',\n min: formatValue(datum._min !== undefined ? datum._min : datum.yVal),\n max: formatValue(datum._max !== undefined ? datum._max : datum.yVal),\n median: formatValue(\n datum._median !== undefined ? datum._median : datum.yVal,\n ),\n q1: formatValue(datum._q1 !== undefined ? datum._q1 : datum.yVal),\n q3: formatValue(datum._q3 !== undefined ? datum._q3 : datum.yVal),\n units: intl.formatMessage(messages.units, {\n units: unitsLookupKey(datum.units),\n }),\n });\n }\n\n // With box plot, datum.y will be an array\n const yVal = Array.isArray(datum.y) ? datum.y[0] : datum.y;\n let units = datum.units;\n\n /**\n * The recommendations API intentionally omits CPU request and limit units when \"cores\".\n *\n * The yaml format for the resource units needs to adhere to the Kubernetes standard that is outlined here\n * https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n *\n * Example. \"45 millicores\" is represented as \"45m\", 64 MiB is represented as \"64Mi\",\n * 2.3 cores is represented as \"2.3\" (Note cores is not specified)\n */\n if (\n (datum.childName === 'limit' || datum.childName === 'request') &&\n datum.units === ''\n ) {\n units = unitsLookupKey('cores');\n }\n return yVal !== null\n ? intl.formatMessage(messages.valueUnits, {\n value: yVal,\n units: intl.formatMessage(messages.units, {\n units: unitsLookupKey(units),\n }),\n })\n : intl.formatMessage(messages.chartNoData);\n };\n\n return (\n <CursorVoronoiContainer\n cursorDimension=\"x\"\n labels={({ datum }: any) => labelFormatter(datum)}\n mouseFollowTooltips\n voronoiDimension=\"x\"\n voronoiPadding={getPadding()}\n />\n );\n }, [getPadding, intl]);\n\n // Returns onMouseOver, onMouseOut, and onClick events for the interactive legend\n const getEvents = () => {\n const result = getInteractiveLegendEvents({\n chartNames: getChartNames(),\n isHidden: index => isSeriesHidden(hiddenSeries, index),\n legendName: `${name}-legend`,\n onLegendClick: props => handleOnLegendClick(props.index),\n });\n return result;\n };\n\n const getHeight = () => {\n return baseHeight + extraHeight;\n };\n\n const getLegend = () => {\n return (\n <ChartLegend\n data={getLegendData(series, hiddenSeries)}\n gutter={20}\n name={`${name}-legend`}\n y={320}\n />\n );\n };\n\n const handleLegendAllowWrap = (value: number) => {\n if (value !== extraHeight) {\n setExtraHeight(value);\n }\n };\n\n const handleOnResize = useCallback(() => {\n const { clientWidth = 0 } = containerRef.current || {};\n\n if (clientWidth !== width) {\n setWidth(clientWidth);\n }\n }, [containerRef, width]);\n\n const initDatum = useCallback(() => {\n // Show all legends, regardless of data size\n\n const newSeries: ChartSeries[] = [];\n if (requestData && requestData.length) {\n newSeries.push({\n childName: 'request',\n data: requestData,\n legendItem: {\n name: getDateRangeString(\n requestData,\n messages.recommendedRequest,\n true,\n ),\n symbol: {\n fill: chartStyles.requestColorScale[0],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.request),\n },\n style: {\n data: {\n ...chartStyles.request,\n stroke: chartStyles.requestColorScale[0],\n },\n },\n });\n }\n if (limitData && limitData.length) {\n newSeries.push({\n childName: 'limit',\n data: limitData,\n legendItem: {\n name: getDateRangeString(limitData, messages.recommendedLimit, true),\n symbol: {\n fill: chartStyles.limitColorScale[0],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.limit),\n },\n style: {\n data: {\n ...chartStyles.limit,\n stroke: chartStyles.limitColorScale[0],\n },\n },\n });\n }\n if (usageData && usageData.length) {\n const boxPlotData: any[] = [];\n usageData.map((datum: any) => {\n if (datum.y.every((val: any, _i: any, arr: any[]) => val === arr[0])) {\n boxPlotData.push({\n ...datum,\n yVal: datum.y[0],\n y: [null],\n });\n } else {\n boxPlotData.push(datum);\n }\n });\n newSeries.push({\n childName: 'usage',\n data: boxPlotData as any,\n legendItem: {\n name: getDateRangeString(usageData, messages.actualUsage),\n symbol: {\n fill: chartStyles.usageColorScale[1],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.usage),\n },\n style: {\n median: {\n stroke: chartStyles.usageColorScale[0],\n },\n q1: {\n fill: chartStyles.usageColorScale[1],\n },\n q3: {\n fill: chartStyles.usageColorScale[1],\n },\n } as any,\n });\n\n // Show dots in place of box plot when all values are equal\n const scatterData: any[] = [];\n usageData.map((datum: any) => {\n if (datum.y.every((val: any, _i: any, arr: any[]) => val === arr[0])) {\n scatterData.push({\n ...datum,\n y: datum.y[0],\n });\n } else {\n scatterData.push({\n ...datum,\n y: null,\n });\n }\n });\n newSeries.push({\n childName: 'scatter',\n data: scatterData as any,\n style: {\n data: { fill: chartStyles.usageColorScale[1] },\n } as any,\n });\n }\n setSeries(newSeries);\n setCursorVoronoiContainer(getCursorVoronoiContainer());\n setHiddenSeries(new Set());\n }, [getCursorVoronoiContainer, intl, limitData, requestData, usageData]);\n\n useMemo(() => {\n initDatum();\n }, [initDatum]);\n\n useEffect(() => {\n const unobserve = getResizeObserver(containerRef.current, handleOnResize);\n return () => {\n if (unobserve) {\n unobserve();\n }\n };\n }, [containerRef, handleOnResize]);\n\n const chartHeight = getHeight();\n\n return (\n <div className={classes.chartOverride} ref={containerRef}>\n <div style={{ height: chartHeight }}>\n <Chart\n key={`chart-${name}`}\n containerComponent={cloneContainer()}\n domain={getDomain(series, hiddenSeries, 1)}\n domainPadding={{ x: [30, 30] }}\n events={getEvents()}\n height={chartHeight}\n legendAllowWrap={handleLegendAllowWrap}\n legendComponent={getLegend()}\n legendPosition=\"bottom\"\n name={name}\n padding={getPadding()}\n width={width}\n // PatternFly will handle theming automatically when pf-v6-theme-dark is applied\n themeColor={ChartThemeColor.default}\n >\n <ChartAxis fixLabelOverlap />\n <ChartAxis dependentAxis showGrid />\n {getRequestChart()}\n {getLimitChart()}\n {getScatterChart()}\n {getUsageChart()}\n </Chart>\n </div>\n </div>\n );\n};\n\nexport { OptimizationsBreakdownChart };\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intl.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/intl.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createIntl, createIntlCache } from 'react-intl';\n\n// eslint-disable-next-line no-restricted-imports\nimport messages from './data.json';\n\nconst locale = window.navigator.language.split(/[-_]/)[0] || 'en';\nexport const getLocale = () => {\n return locale;\n};\n\nconst cache = createIntlCache();\n\nconst intl = createIntl(\n {\n defaultLocale: 'en',\n locale,\n // eslint-disable-next-line no-console\n onError: console.log,\n messages: messages.en,\n },\n cache,\n);\n\nexport default intl;\n"],"names":["messages"],"mappings":";;;AAqBA,MAAM,MAAA,GAAS,OAAO,
|
|
1
|
+
{"version":3,"file":"intl.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/intl.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createIntl, createIntlCache } from 'react-intl';\n\n// eslint-disable-next-line no-restricted-imports\nimport messages from './data.json';\n\nconst locale = window.navigator.language.split(/[-_]/)[0] || 'en';\nexport const getLocale = () => {\n return locale;\n};\n\nconst cache = createIntlCache();\n\nconst intl = createIntl(\n {\n defaultLocale: 'en',\n locale,\n // eslint-disable-next-line no-console\n onError: console.log,\n messages: messages.en,\n },\n cache,\n);\n\nexport default intl;\n"],"names":["messages"],"mappings":";;;AAqBA,MAAM,MAAA,GAAS,OAAO,SAAA,CAAU,QAAA,CAAS,MAAM,MAAM,CAAA,CAAE,CAAC,CAAA,IAAK,IAAA;AAK7D,MAAM,QAAQ,eAAA,EAAgB;AAE9B,MAAM,IAAA,GAAO,UAAA;AAAA,EACX;AAAA,IACE,aAAA,EAAe,IAAA;AAAA,IACf,MAAA;AAAA;AAAA,IAEA,SAAS,OAAA,CAAQ,GAAA;AAAA,IACjB,UAAUA,YAAA,CAAS;AAAA,GACrB;AAAA,EACA;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/messages.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { defineMessages } from 'react-intl';\n\nexport default defineMessages({\n chartNoData: {\n defaultMessage: 'no data',\n description: 'no data',\n id: 'chartNoData',\n },\n chartCostForecastConeTooltip: {\n defaultMessage: '{value0} - {value1}',\n description: 'Cost forecast confidence min/max tooltip',\n id: 'chartCostForecastConeTooltip',\n },\n currencyAbbreviations: {\n defaultMessage:\n '{symbol, select, ' +\n 'billion {{value} B} ' +\n 'million {{value} M} ' +\n 'quadrillion {{value} q} ' +\n 'thousand {{value} K} ' +\n 'trillion {{value} t} ' +\n 'other {}}',\n description: 'str.match(/([\\\\D]*)([\\\\d.,]+)([\\\\D]*)/)',\n id: 'currencyAbbreviations',\n },\n unitTooltips: {\n defaultMessage:\n '{units, select, ' +\n 'byte_ms {{value} Byte-ms} ' +\n 'core_hours {{value} core-hours} ' +\n 'gb {{value} GB} ' +\n 'gb_hours {{value} GB-hours} ' +\n 'gb_mo {{value} GB-month} ' +\n 'gb_ms {{value} GB-ms} ' +\n 'gibibyte_month {{value} GiB-month} ' +\n 'hour {{value} hours} ' +\n 'hrs {{value} hours} ' +\n 'ms {{value} milliseconds} ' +\n 'vm_hours {{value} VM-hours} ' +\n 'other {{value}}}',\n description: 'return value and unit based on key: \"units\"',\n id: 'unitTooltips',\n },\n chartUsageTooltip: {\n defaultMessage:\n 'Min: {min} {units}, Max: {max} {units}{br}Median: {median} {units}{br}Q1: {q1} {units}, Q3: {q3} {units}',\n description:\n 'Min: {min} {units}, Max: {max} {units}{br}Median: {median} {units}{br}Q1: {q1} {units}, Q3: {q3} {units}',\n id: 'chartUsageTooltip',\n },\n units: {\n defaultMessage:\n '{units, select, ' +\n 'cores {cores} ' +\n 'ei {Ei} ' +\n 'eib {EiB} ' +\n 'gi {Gi} ' +\n 'gib {GiB} ' +\n 'ki {Ki} ' +\n 'kib {KiB} ' +\n 'mi {Mi} ' +\n 'mib {MiB} ' +\n 'm {m} ' +\n 'millicores {millicores} ' +\n 'other {}}',\n description: 'return the proper unit label based on key: \"units\"',\n id: 'units',\n },\n limit: {\n defaultMessage: 'Limit',\n description: 'Limit',\n id: 'limit',\n },\n recommendedLimit: {\n defaultMessage: 'Recommended limit ({dateRange})',\n description: 'Recommended limit (Jan 1-31)',\n id: 'recommendedLimit',\n },\n recommendedRequest: {\n defaultMessage: 'Recommended request ({dateRange})',\n description: 'Recommended request (Jan 1-31)',\n id: 'recommendedRequest',\n },\n request: {\n defaultMessage: 'Request',\n description: 'Request',\n id: 'request',\n },\n actualUsage: {\n defaultMessage: 'Actual usage ({dateRange})',\n description: 'Actual usage (Jan 1-31)',\n id: 'actualUsage',\n },\n usage: {\n defaultMessage: 'Usage',\n description: 'Usage',\n id: 'usage',\n },\n valueUnits: {\n defaultMessage: '{value} {units}',\n description: '{value} {units}',\n id: 'valueUnits',\n },\n});\n"],"names":[],"mappings":";;AAkBA,eAAe,
|
|
1
|
+
{"version":3,"file":"messages.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/messages.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { defineMessages } from 'react-intl';\n\nexport default defineMessages({\n chartNoData: {\n defaultMessage: 'no data',\n description: 'no data',\n id: 'chartNoData',\n },\n chartCostForecastConeTooltip: {\n defaultMessage: '{value0} - {value1}',\n description: 'Cost forecast confidence min/max tooltip',\n id: 'chartCostForecastConeTooltip',\n },\n currencyAbbreviations: {\n defaultMessage:\n '{symbol, select, ' +\n 'billion {{value} B} ' +\n 'million {{value} M} ' +\n 'quadrillion {{value} q} ' +\n 'thousand {{value} K} ' +\n 'trillion {{value} t} ' +\n 'other {}}',\n description: 'str.match(/([\\\\D]*)([\\\\d.,]+)([\\\\D]*)/)',\n id: 'currencyAbbreviations',\n },\n unitTooltips: {\n defaultMessage:\n '{units, select, ' +\n 'byte_ms {{value} Byte-ms} ' +\n 'core_hours {{value} core-hours} ' +\n 'gb {{value} GB} ' +\n 'gb_hours {{value} GB-hours} ' +\n 'gb_mo {{value} GB-month} ' +\n 'gb_ms {{value} GB-ms} ' +\n 'gibibyte_month {{value} GiB-month} ' +\n 'hour {{value} hours} ' +\n 'hrs {{value} hours} ' +\n 'ms {{value} milliseconds} ' +\n 'vm_hours {{value} VM-hours} ' +\n 'other {{value}}}',\n description: 'return value and unit based on key: \"units\"',\n id: 'unitTooltips',\n },\n chartUsageTooltip: {\n defaultMessage:\n 'Min: {min} {units}, Max: {max} {units}{br}Median: {median} {units}{br}Q1: {q1} {units}, Q3: {q3} {units}',\n description:\n 'Min: {min} {units}, Max: {max} {units}{br}Median: {median} {units}{br}Q1: {q1} {units}, Q3: {q3} {units}',\n id: 'chartUsageTooltip',\n },\n units: {\n defaultMessage:\n '{units, select, ' +\n 'cores {cores} ' +\n 'ei {Ei} ' +\n 'eib {EiB} ' +\n 'gi {Gi} ' +\n 'gib {GiB} ' +\n 'ki {Ki} ' +\n 'kib {KiB} ' +\n 'mi {Mi} ' +\n 'mib {MiB} ' +\n 'm {m} ' +\n 'millicores {millicores} ' +\n 'other {}}',\n description: 'return the proper unit label based on key: \"units\"',\n id: 'units',\n },\n limit: {\n defaultMessage: 'Limit',\n description: 'Limit',\n id: 'limit',\n },\n recommendedLimit: {\n defaultMessage: 'Recommended limit ({dateRange})',\n description: 'Recommended limit (Jan 1-31)',\n id: 'recommendedLimit',\n },\n recommendedRequest: {\n defaultMessage: 'Recommended request ({dateRange})',\n description: 'Recommended request (Jan 1-31)',\n id: 'recommendedRequest',\n },\n request: {\n defaultMessage: 'Request',\n description: 'Request',\n id: 'request',\n },\n actualUsage: {\n defaultMessage: 'Actual usage ({dateRange})',\n description: 'Actual usage (Jan 1-31)',\n id: 'actualUsage',\n },\n usage: {\n defaultMessage: 'Usage',\n description: 'Usage',\n id: 'usage',\n },\n valueUnits: {\n defaultMessage: '{value} {units}',\n description: '{value} {units}',\n id: 'valueUnits',\n },\n});\n"],"names":[],"mappings":";;AAkBA,eAAe,cAAA,CAAe;AAAA,EAC5B,WAAA,EAAa;AAAA,IACX,cAAA,EAAgB,SAAA;AAAA,IAChB,WAAA,EAAa,SAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,4BAAA,EAA8B;AAAA,IAC5B,cAAA,EAAgB,qBAAA;AAAA,IAChB,WAAA,EAAa,0CAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,qBAAA,EAAuB;AAAA,IACrB,cAAA,EACE,sIAAA;AAAA,IAOF,WAAA,EAAa,yCAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,cAAA,EACE,yTAAA;AAAA,IAaF,WAAA,EAAa,6CAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,iBAAA,EAAmB;AAAA,IACjB,cAAA,EACE,0GAAA;AAAA,IACF,WAAA,EACE,0GAAA;AAAA,IACF,EAAA,EAAI;AAAA,GACN;AAAA,EACA,KAAA,EAAO;AAAA,IACL,cAAA,EACE,+IAAA;AAAA,IAaF,WAAA,EAAa,oDAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,KAAA,EAAO;AAAA,IACL,cAAA,EAAgB,OAAA;AAAA,IAChB,WAAA,EAAa,OAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,gBAAA,EAAkB;AAAA,IAChB,cAAA,EAAgB,iCAAA;AAAA,IAChB,WAAA,EAAa,8BAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,kBAAA,EAAoB;AAAA,IAClB,cAAA,EAAgB,mCAAA;AAAA,IAChB,WAAA,EAAa,gCAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,OAAA,EAAS;AAAA,IACP,cAAA,EAAgB,SAAA;AAAA,IAChB,WAAA,EAAa,SAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,WAAA,EAAa;AAAA,IACX,cAAA,EAAgB,4BAAA;AAAA,IAChB,WAAA,EAAa,yBAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,KAAA,EAAO;AAAA,IACL,cAAA,EAAgB,OAAA;AAAA,IAChB,WAAA,EAAa,OAAA;AAAA,IACb,EAAA,EAAI;AAAA,GACN;AAAA,EACA,UAAA,EAAY;AAAA,IACV,cAAA,EAAgB,iBAAA;AAAA,IAChB,WAAA,EAAa,iBAAA;AAAA,IACb,EAAA,EAAI;AAAA;AAER,CAAC,CAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-data-format.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-data-format.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n LongTermRecommendationBoxPlots,\n MediumTermRecommendationBoxPlots,\n RecommendationBoxPlotsRecommendations,\n ShortTermRecommendationBoxPlots,\n} from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport {\n Interval,\n OptimizationType,\n RecommendationType,\n ResourceType,\n UsageType,\n} from '../../../../../../../../../../../models/ChartEnums';\nimport { format } from 'date-fns';\n\nexport const getRecommendationTerm = (\n interval: Interval,\n recommendations?: RecommendationBoxPlotsRecommendations,\n):\n | ShortTermRecommendationBoxPlots\n | MediumTermRecommendationBoxPlots\n | LongTermRecommendationBoxPlots => {\n let result;\n // eslint-disable-next-line default-case\n switch (interval) {\n case 'shortTerm':\n result = recommendations?.recommendationTerms?.shortTerm;\n break;\n case 'mediumTerm':\n result = recommendations?.recommendationTerms?.mediumTerm;\n break;\n case 'longTerm':\n result = recommendations?.recommendationTerms?.longTerm;\n break;\n }\n\n return result || {};\n};\n\nexport const createUsageDatum = (\n usageType: UsageType,\n currentInterval: Interval,\n recommendations?: RecommendationBoxPlotsRecommendations,\n) => {\n const datum = [];\n\n if (recommendations) {\n const term = getRecommendationTerm(currentInterval, recommendations);\n const plotsData = term?.plots?.plotsData || {};\n\n for (const key of Object.keys(plotsData)) {\n const data = plotsData?.[key]?.[usageType];\n const date = new Date(key);\n const xVal =\n currentInterval === 'shortTerm'\n ? format(date, 'kk:mm')\n : format(date, 'MMM d');\n datum.push({\n key,\n name: usageType,\n units: data?.format,\n x: xVal,\n y: data ? [data.min, data.median, data.max, data.q1, data.q3] : [null],\n });\n }\n }\n\n // Pad dates if plots_data is missing\n if (datum.length === 0 && recommendations?.monitoringEndTime) {\n if (currentInterval === 'shortTerm') {\n const today = new Date(recommendations?.monitoringEndTime);\n for (let hour = 24; hour > 0; hour -= 6) {\n today.setHours(today.getHours() - hour);\n datum.push({\n key: today.toDateString(),\n name: usageType,\n x: format(today, 'kk:mm'),\n y: [null],\n });\n }\n } else {\n for (let day = currentInterval === 'longTerm' ? 15 : 7; day > 0; day--) {\n const today = new Date(recommendations?.monitoringEndTime);\n today.setDate(today.getDate() - day);\n datum.push({\n key: today.toDateString(),\n name: usageType,\n x: format(today, 'MMM d'),\n y: [null],\n });\n }\n }\n }\n return datum;\n};\n\nexport const createRecommendationDatum = (\n currentInterval: Interval,\n usageDatum: any,\n recommendationType: RecommendationType,\n resourceType: ResourceType,\n optimizationType: OptimizationType,\n recommendations?: RecommendationBoxPlotsRecommendations,\n) => {\n const term = getRecommendationTerm(currentInterval, recommendations);\n const values =\n term?.recommendationEngines?.[optimizationType]?.config?.[resourceType]?.[\n recommendationType\n ];\n\n const datum: any[] = [];\n\n if (values) {\n usageDatum.forEach((data: any) => {\n datum.push({\n ...data,\n name: resourceType,\n y: values.amount,\n units: values.format,\n });\n });\n }\n\n return datum.length\n ? [\n {\n ...datum[0],\n key: undefined, // Don't use date here\n x: 0, // Extends threshold lines to chart edge\n },\n ...datum,\n {\n ...datum[0],\n key: undefined, // Don't use date here\n x: 100,\n },\n ]\n : [];\n};\n"],"names":[],"mappings":";;AA+
|
|
1
|
+
{"version":3,"file":"chart-data-format.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-data-format.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n LongTermRecommendationBoxPlots,\n MediumTermRecommendationBoxPlots,\n RecommendationBoxPlotsRecommendations,\n ShortTermRecommendationBoxPlots,\n} from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport {\n Interval,\n OptimizationType,\n RecommendationType,\n ResourceType,\n UsageType,\n} from '../../../../../../../../../../../models/ChartEnums';\nimport { format } from 'date-fns';\n\nexport const getRecommendationTerm = (\n interval: Interval,\n recommendations?: RecommendationBoxPlotsRecommendations,\n):\n | ShortTermRecommendationBoxPlots\n | MediumTermRecommendationBoxPlots\n | LongTermRecommendationBoxPlots => {\n let result;\n // eslint-disable-next-line default-case\n switch (interval) {\n case 'shortTerm':\n result = recommendations?.recommendationTerms?.shortTerm;\n break;\n case 'mediumTerm':\n result = recommendations?.recommendationTerms?.mediumTerm;\n break;\n case 'longTerm':\n result = recommendations?.recommendationTerms?.longTerm;\n break;\n }\n\n return result || {};\n};\n\nexport const createUsageDatum = (\n usageType: UsageType,\n currentInterval: Interval,\n recommendations?: RecommendationBoxPlotsRecommendations,\n) => {\n const datum = [];\n\n if (recommendations) {\n const term = getRecommendationTerm(currentInterval, recommendations);\n const plotsData = term?.plots?.plotsData || {};\n\n for (const key of Object.keys(plotsData)) {\n const data = plotsData?.[key]?.[usageType];\n const date = new Date(key);\n const xVal =\n currentInterval === 'shortTerm'\n ? format(date, 'kk:mm')\n : format(date, 'MMM d');\n datum.push({\n key,\n name: usageType,\n units: data?.format,\n x: xVal,\n y: data ? [data.min, data.median, data.max, data.q1, data.q3] : [null],\n });\n }\n }\n\n // Pad dates if plots_data is missing\n if (datum.length === 0 && recommendations?.monitoringEndTime) {\n if (currentInterval === 'shortTerm') {\n const today = new Date(recommendations?.monitoringEndTime);\n for (let hour = 24; hour > 0; hour -= 6) {\n today.setHours(today.getHours() - hour);\n datum.push({\n key: today.toDateString(),\n name: usageType,\n x: format(today, 'kk:mm'),\n y: [null],\n });\n }\n } else {\n for (let day = currentInterval === 'longTerm' ? 15 : 7; day > 0; day--) {\n const today = new Date(recommendations?.monitoringEndTime);\n today.setDate(today.getDate() - day);\n datum.push({\n key: today.toDateString(),\n name: usageType,\n x: format(today, 'MMM d'),\n y: [null],\n });\n }\n }\n }\n return datum;\n};\n\nexport const createRecommendationDatum = (\n currentInterval: Interval,\n usageDatum: any,\n recommendationType: RecommendationType,\n resourceType: ResourceType,\n optimizationType: OptimizationType,\n recommendations?: RecommendationBoxPlotsRecommendations,\n) => {\n const term = getRecommendationTerm(currentInterval, recommendations);\n const values =\n term?.recommendationEngines?.[optimizationType]?.config?.[resourceType]?.[\n recommendationType\n ];\n\n const datum: any[] = [];\n\n if (values) {\n usageDatum.forEach((data: any) => {\n datum.push({\n ...data,\n name: resourceType,\n y: values.amount,\n units: values.format,\n });\n });\n }\n\n return datum.length\n ? [\n {\n ...datum[0],\n key: undefined, // Don't use date here\n x: 0, // Extends threshold lines to chart edge\n },\n ...datum,\n {\n ...datum[0],\n key: undefined, // Don't use date here\n x: 100,\n },\n ]\n : [];\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-datum.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-datum.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { MessageDescriptor } from '@formatjs/intl/src/types';\nimport { formatCurrency, unitsLookupKey } from './format';\nimport messages from '../i18n/messages';\nimport { intl } from '../i18n';\n\nexport interface FormatOptions {\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n}\n\nexport interface ChartDatum {\n childName?: string;\n date?: string;\n key: string | number;\n name?: string | number;\n show?: boolean;\n tooltip?: string;\n units: string;\n x: string | number;\n y: number;\n y0?: number;\n}\n\nexport function getDatumDateRange(datums: ChartDatum[]): [Date, Date] {\n // Find the first populated (non-null) day\n let firstDay = 0;\n for (let i = firstDay; i < datums.length; i++) {\n if (datums[i]?.key && datums[i]?.y !== null) {\n firstDay = i;\n break;\n }\n }\n\n // Find the last populated (non-null) day\n let lastDay = datums.length - 1;\n for (let i = lastDay; i >= 0; i--) {\n if (datums[i]?.key && datums[i].y !== null) {\n lastDay = i;\n break;\n }\n }\n\n const start = new Date(datums[firstDay].key);\n const end = new Date(datums[lastDay].key);\n return [start, end];\n}\n\nexport function getDateRangeString(\n datums: ChartDatum[],\n key: MessageDescriptor,\n isSameDate: boolean = false,\n noDataKey: MessageDescriptor = messages.chartNoData,\n) {\n if (!(datums?.length && key)) {\n return intl.formatMessage(noDataKey);\n }\n\n const [start, end] = getDatumDateRange(datums);\n const dateRange = intl.formatDateTimeRange(isSameDate ? end : start, end, {\n day: 'numeric',\n month: 'short',\n });\n return intl.formatMessage(key, {\n dateRange,\n });\n}\n\nfunction getMinOrMaxY<F extends Math['max']>(\n datum: ChartDatum,\n minOrMaxFn: F,\n): number | null {\n let value: number | null;\n\n if (datum.y0 !== undefined) {\n value = minOrMaxFn(datum.y, datum.y0) as number;\n } else {\n if (Array.isArray(datum.y)) {\n if (datum.y[0] !== null) {\n value = minOrMaxFn(...datum.y);\n } else if ((datum as any).yVal) {\n // yVal still remains a mistery...\n // For boxplot, which is hidden via `datum.y[0] = null` when all values are equal\n value = (datum as any).yVal;\n } else {\n value = null;\n }\n } else {\n value = datum.y;\n }\n }\n\n return value;\n}\n\nexport function getMaxMinValues(datums: ChartDatum[]) {\n let max: number | null = null;\n let min: number | null = null;\n if (datums && datums.length) {\n datums.forEach(datum => {\n const maxY = getMinOrMaxY(datum, Math.max);\n const minY = getMinOrMaxY(datum, Math.min);\n\n if (maxY !== null && (max === null || maxY > max)) {\n max = maxY;\n }\n if (minY !== null && (min === null || minY < min)) {\n min = minY;\n }\n });\n }\n return { max, min };\n}\n\nexport function getTooltipContent(\n formatter: (arg0: number, arg1: string, arg2: FormatOptions) => any,\n) {\n return function labelFormatter(\n value: number,\n unit: string,\n options: FormatOptions = {},\n ) {\n const lookup = unitsLookupKey(unit);\n if (lookup) {\n return intl.formatMessage(messages.unitTooltips, {\n units: lookup,\n value: formatter(value, unit, options),\n });\n }\n return formatCurrency(value, unit, options);\n };\n}\n"],"names":[],"mappings":";;;AAuCO,SAAS,kBAAkB,
|
|
1
|
+
{"version":3,"file":"chart-datum.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-datum.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { MessageDescriptor } from '@formatjs/intl/src/types';\nimport { formatCurrency, unitsLookupKey } from './format';\nimport messages from '../i18n/messages';\nimport { intl } from '../i18n';\n\nexport interface FormatOptions {\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n}\n\nexport interface ChartDatum {\n childName?: string;\n date?: string;\n key: string | number;\n name?: string | number;\n show?: boolean;\n tooltip?: string;\n units: string;\n x: string | number;\n y: number;\n y0?: number;\n}\n\nexport function getDatumDateRange(datums: ChartDatum[]): [Date, Date] {\n // Find the first populated (non-null) day\n let firstDay = 0;\n for (let i = firstDay; i < datums.length; i++) {\n if (datums[i]?.key && datums[i]?.y !== null) {\n firstDay = i;\n break;\n }\n }\n\n // Find the last populated (non-null) day\n let lastDay = datums.length - 1;\n for (let i = lastDay; i >= 0; i--) {\n if (datums[i]?.key && datums[i].y !== null) {\n lastDay = i;\n break;\n }\n }\n\n const start = new Date(datums[firstDay].key);\n const end = new Date(datums[lastDay].key);\n return [start, end];\n}\n\nexport function getDateRangeString(\n datums: ChartDatum[],\n key: MessageDescriptor,\n isSameDate: boolean = false,\n noDataKey: MessageDescriptor = messages.chartNoData,\n) {\n if (!(datums?.length && key)) {\n return intl.formatMessage(noDataKey);\n }\n\n const [start, end] = getDatumDateRange(datums);\n const dateRange = intl.formatDateTimeRange(isSameDate ? end : start, end, {\n day: 'numeric',\n month: 'short',\n });\n return intl.formatMessage(key, {\n dateRange,\n });\n}\n\nfunction getMinOrMaxY<F extends Math['max']>(\n datum: ChartDatum,\n minOrMaxFn: F,\n): number | null {\n let value: number | null;\n\n if (datum.y0 !== undefined) {\n value = minOrMaxFn(datum.y, datum.y0) as number;\n } else {\n if (Array.isArray(datum.y)) {\n if (datum.y[0] !== null) {\n value = minOrMaxFn(...datum.y);\n } else if ((datum as any).yVal) {\n // yVal still remains a mistery...\n // For boxplot, which is hidden via `datum.y[0] = null` when all values are equal\n value = (datum as any).yVal;\n } else {\n value = null;\n }\n } else {\n value = datum.y;\n }\n }\n\n return value;\n}\n\nexport function getMaxMinValues(datums: ChartDatum[]) {\n let max: number | null = null;\n let min: number | null = null;\n if (datums && datums.length) {\n datums.forEach(datum => {\n const maxY = getMinOrMaxY(datum, Math.max);\n const minY = getMinOrMaxY(datum, Math.min);\n\n if (maxY !== null && (max === null || maxY > max)) {\n max = maxY;\n }\n if (minY !== null && (min === null || minY < min)) {\n min = minY;\n }\n });\n }\n return { max, min };\n}\n\nexport function getTooltipContent(\n formatter: (arg0: number, arg1: string, arg2: FormatOptions) => any,\n) {\n return function labelFormatter(\n value: number,\n unit: string,\n options: FormatOptions = {},\n ) {\n const lookup = unitsLookupKey(unit);\n if (lookup) {\n return intl.formatMessage(messages.unitTooltips, {\n units: lookup,\n value: formatter(value, unit, options),\n });\n }\n return formatCurrency(value, unit, options);\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-utils.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInteractiveLegendItemStyles } from '@patternfly/react-charts/victory';\nimport { intl } from '../i18n';\nimport messages from '../i18n/messages';\nimport type { FormatOptions, Formatter } from './format';\nimport type { DomainTuple, VictoryStyleInterface } from 'victory-core';\n\nimport { getMaxMinValues, getTooltipContent } from './chart-datum';\n\nexport interface ChartData {\n childName?: string;\n units?: string;\n}\n\nexport interface ChartLegendItem {\n childName?: string;\n name?: string;\n symbol?: any;\n tooltip?: string;\n}\n\nexport interface ChartSeries {\n childName?: string;\n data?: [ChartData];\n legendItem?: ChartLegendItem;\n style?: VictoryStyleInterface;\n}\n\n// Returns groups of chart names associated with each data series\nexport const getChartNames = (series: ChartSeries[]) => {\n const result: (string | undefined)[] = [];\n\n if (series) {\n series.forEach(serie => {\n // Each group of chart names are hidden / shown together\n result.push(serie.childName);\n });\n }\n return result;\n};\n\n// Returns true if data series is hidden\nexport const isSeriesHidden = (hiddenSeries: Set<number>, index: number) => {\n return hiddenSeries.has(index);\n};\n\n// Note: A series may be grouped in order to be hidden / shown together\nexport const getDomain = (\n series: ChartSeries[] | undefined,\n hiddenSeries: Set<number>,\n groupedSeriesCount = 0,\n) => {\n const domain: { x?: DomainTuple; y?: DomainTuple } = { y: [0, 1] };\n let maxValue: number | null = null;\n let minValue: number | null = null;\n\n if (series) {\n // Don't use zero domain\n let maybeEmptyHiddenSeries = hiddenSeries;\n if (series.length - groupedSeriesCount === maybeEmptyHiddenSeries.size) {\n domain.x = [0, 1];\n maybeEmptyHiddenSeries = new Set();\n }\n series.forEach((s: any, index) => {\n if (\n !isSeriesHidden(maybeEmptyHiddenSeries, index) &&\n s.data &&\n s.data.length !== 0\n ) {\n const { max, min } = getMaxMinValues(s.data);\n if (max !== null && (maxValue === null || max > maxValue)) {\n maxValue = max;\n }\n if (min !== null && (minValue === null || min < minValue)) {\n minValue = min;\n }\n }\n });\n }\n\n if (maxValue && minValue) {\n const threshold = maxValue * 0.05;\n const max = maxValue > 0 ? Math.ceil(maxValue + threshold) : 0;\n const _min =\n minValue > 0 ? Math.max(0, Math.floor(minValue - threshold)) : 0;\n const min = _min > 0 ? _min : 0;\n\n if (max > 0) {\n domain.y = [min, max];\n }\n }\n\n return domain;\n};\n\n// Returns legend data styled per hiddenSeries\nexport const getLegendData = (\n series?: ChartSeries[],\n hiddenSeries?: Set<number>,\n tooltip: boolean = false,\n) => {\n if (!series) {\n return undefined;\n }\n\n const result: any = [];\n\n series.forEach((s, index) => {\n if (s.legendItem) {\n const data = {\n childName: s.childName,\n ...s.legendItem, // name property\n ...(tooltip && { name: s.legendItem.tooltip }), // Override name property for tooltip\n ...getInteractiveLegendItemStyles(hiddenSeries?.has(index)), // hidden styles\n };\n\n result.push(data);\n }\n });\n\n return result;\n};\n\n// Note: Forecast is expected to use both datum.y and datum.y0\nexport const getTooltipLabel = (\n datum: any,\n formatter: Formatter,\n formatOptions: FormatOptions,\n) => {\n const tooltipFormatter = getTooltipContent(formatter);\n const dy =\n datum.y !== undefined && datum.y !== null\n ? tooltipFormatter(datum.y, datum.units, formatOptions)\n : undefined;\n const dy0 =\n datum.y0 !== undefined && datum.y0 !== null\n ? tooltipFormatter(datum.y0, datum.units, formatOptions)\n : undefined;\n\n if (dy !== undefined && dy0 !== undefined) {\n return intl.formatMessage(messages.chartCostForecastConeTooltip, {\n value0: dy0,\n value1: dy,\n });\n }\n return dy !== undefined ? dy : intl.formatMessage(messages.chartNoData);\n};\n\nexport const getResizeObserver = (\n containerRef: HTMLDivElement | null,\n handleResize: () => void,\n) => {\n const containerElement = containerRef;\n const { ResizeObserver } = window as any;\n let _resizeObserver: any;\n\n if (containerElement && ResizeObserver) {\n const resizeObserver = new ResizeObserver((entries: string | any[]) => {\n // We wrap it in requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded\n window.requestAnimationFrame(() => {\n if (!Array.isArray(entries) || !entries.length) {\n return;\n }\n handleResize();\n });\n });\n resizeObserver.observe(containerElement);\n _resizeObserver = () => resizeObserver.unobserve(containerElement);\n } else {\n handleResize();\n window.addEventListener('resize', handleResize);\n _resizeObserver = () => window.removeEventListener('resize', handleResize);\n }\n\n return () => {\n if (_resizeObserver) {\n _resizeObserver();\n }\n };\n};\n\nexport const initHiddenSeries = (hiddenSeries: Set<number>, index: number) => {\n const result = new Set(hiddenSeries);\n if (!result.delete(index)) {\n result.add(index);\n }\n return result;\n};\n\n// Returns true if at least one data series is available\nexport const isDataAvailable = (\n series?: ChartSeries[],\n hiddenSeries?: Set<number>,\n) => {\n const unavailable = []; // API data may not be available (e.g., on 1st of month)\n\n if (series) {\n series.forEach((s: any, index) => {\n if (\n (hiddenSeries && isSeriesHidden(hiddenSeries, index)) ||\n (s.data && s.data.length === 0)\n ) {\n unavailable.push(index);\n }\n });\n }\n return unavailable.length !== (series ? series.length : 0);\n};\n\n// Returns true if data series is hidden\nexport const isDataHidden = (\n series: ChartSeries[],\n hiddenSeries: Set<number>,\n data: any,\n) => {\n if (data && data.length) {\n for (const key of hiddenSeries.keys()) {\n let dataChildName;\n let serieChildName;\n\n for (const item of data) {\n if (item.childName) {\n dataChildName = item.childName;\n break;\n }\n }\n\n if (series && key && series[key]?.data) {\n const seriesData = series[key]?.data;\n if (seriesData) {\n for (const item of seriesData) {\n if (item.childName) {\n serieChildName = item.childName;\n break;\n }\n }\n }\n }\n\n if (serieChildName && dataChildName && serieChildName === dataChildName) {\n return true;\n }\n }\n }\n return false;\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-utils.esm.js","sources":["../../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInteractiveLegendItemStyles } from '@patternfly/react-charts/victory';\nimport { intl } from '../i18n';\nimport messages from '../i18n/messages';\nimport type { FormatOptions, Formatter } from './format';\nimport type { DomainTuple, VictoryStyleInterface } from 'victory-core';\n\nimport { getMaxMinValues, getTooltipContent } from './chart-datum';\n\nexport interface ChartData {\n childName?: string;\n units?: string;\n}\n\nexport interface ChartLegendItem {\n childName?: string;\n name?: string;\n symbol?: any;\n tooltip?: string;\n}\n\nexport interface ChartSeries {\n childName?: string;\n data?: [ChartData];\n legendItem?: ChartLegendItem;\n style?: VictoryStyleInterface;\n}\n\n// Returns groups of chart names associated with each data series\nexport const getChartNames = (series: ChartSeries[]) => {\n const result: (string | undefined)[] = [];\n\n if (series) {\n series.forEach(serie => {\n // Each group of chart names are hidden / shown together\n result.push(serie.childName);\n });\n }\n return result;\n};\n\n// Returns true if data series is hidden\nexport const isSeriesHidden = (hiddenSeries: Set<number>, index: number) => {\n return hiddenSeries.has(index);\n};\n\n// Note: A series may be grouped in order to be hidden / shown together\nexport const getDomain = (\n series: ChartSeries[] | undefined,\n hiddenSeries: Set<number>,\n groupedSeriesCount = 0,\n) => {\n const domain: { x?: DomainTuple; y?: DomainTuple } = { y: [0, 1] };\n let maxValue: number | null = null;\n let minValue: number | null = null;\n\n if (series) {\n // Don't use zero domain\n let maybeEmptyHiddenSeries = hiddenSeries;\n if (series.length - groupedSeriesCount === maybeEmptyHiddenSeries.size) {\n domain.x = [0, 1];\n maybeEmptyHiddenSeries = new Set();\n }\n series.forEach((s: any, index) => {\n if (\n !isSeriesHidden(maybeEmptyHiddenSeries, index) &&\n s.data &&\n s.data.length !== 0\n ) {\n const { max, min } = getMaxMinValues(s.data);\n if (max !== null && (maxValue === null || max > maxValue)) {\n maxValue = max;\n }\n if (min !== null && (minValue === null || min < minValue)) {\n minValue = min;\n }\n }\n });\n }\n\n if (maxValue && minValue) {\n const threshold = maxValue * 0.05;\n const max = maxValue > 0 ? Math.ceil(maxValue + threshold) : 0;\n const _min =\n minValue > 0 ? Math.max(0, Math.floor(minValue - threshold)) : 0;\n const min = _min > 0 ? _min : 0;\n\n if (max > 0) {\n domain.y = [min, max];\n }\n }\n\n return domain;\n};\n\n// Returns legend data styled per hiddenSeries\nexport const getLegendData = (\n series?: ChartSeries[],\n hiddenSeries?: Set<number>,\n tooltip: boolean = false,\n) => {\n if (!series) {\n return undefined;\n }\n\n const result: any = [];\n\n series.forEach((s, index) => {\n if (s.legendItem) {\n const data = {\n childName: s.childName,\n ...s.legendItem, // name property\n ...(tooltip && { name: s.legendItem.tooltip }), // Override name property for tooltip\n ...getInteractiveLegendItemStyles(hiddenSeries?.has(index)), // hidden styles\n };\n\n result.push(data);\n }\n });\n\n return result;\n};\n\n// Note: Forecast is expected to use both datum.y and datum.y0\nexport const getTooltipLabel = (\n datum: any,\n formatter: Formatter,\n formatOptions: FormatOptions,\n) => {\n const tooltipFormatter = getTooltipContent(formatter);\n const dy =\n datum.y !== undefined && datum.y !== null\n ? tooltipFormatter(datum.y, datum.units, formatOptions)\n : undefined;\n const dy0 =\n datum.y0 !== undefined && datum.y0 !== null\n ? tooltipFormatter(datum.y0, datum.units, formatOptions)\n : undefined;\n\n if (dy !== undefined && dy0 !== undefined) {\n return intl.formatMessage(messages.chartCostForecastConeTooltip, {\n value0: dy0,\n value1: dy,\n });\n }\n return dy !== undefined ? dy : intl.formatMessage(messages.chartNoData);\n};\n\nexport const getResizeObserver = (\n containerRef: HTMLDivElement | null,\n handleResize: () => void,\n) => {\n const containerElement = containerRef;\n const { ResizeObserver } = window as any;\n let _resizeObserver: any;\n\n if (containerElement && ResizeObserver) {\n const resizeObserver = new ResizeObserver((entries: string | any[]) => {\n // We wrap it in requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded\n window.requestAnimationFrame(() => {\n if (!Array.isArray(entries) || !entries.length) {\n return;\n }\n handleResize();\n });\n });\n resizeObserver.observe(containerElement);\n _resizeObserver = () => resizeObserver.unobserve(containerElement);\n } else {\n handleResize();\n window.addEventListener('resize', handleResize);\n _resizeObserver = () => window.removeEventListener('resize', handleResize);\n }\n\n return () => {\n if (_resizeObserver) {\n _resizeObserver();\n }\n };\n};\n\nexport const initHiddenSeries = (hiddenSeries: Set<number>, index: number) => {\n const result = new Set(hiddenSeries);\n if (!result.delete(index)) {\n result.add(index);\n }\n return result;\n};\n\n// Returns true if at least one data series is available\nexport const isDataAvailable = (\n series?: ChartSeries[],\n hiddenSeries?: Set<number>,\n) => {\n const unavailable = []; // API data may not be available (e.g., on 1st of month)\n\n if (series) {\n series.forEach((s: any, index) => {\n if (\n (hiddenSeries && isSeriesHidden(hiddenSeries, index)) ||\n (s.data && s.data.length === 0)\n ) {\n unavailable.push(index);\n }\n });\n }\n return unavailable.length !== (series ? series.length : 0);\n};\n\n// Returns true if data series is hidden\nexport const isDataHidden = (\n series: ChartSeries[],\n hiddenSeries: Set<number>,\n data: any,\n) => {\n if (data && data.length) {\n for (const key of hiddenSeries.keys()) {\n let dataChildName;\n let serieChildName;\n\n for (const item of data) {\n if (item.childName) {\n dataChildName = item.childName;\n break;\n }\n }\n\n if (series && key && series[key]?.data) {\n const seriesData = series[key]?.data;\n if (seriesData) {\n for (const item of seriesData) {\n if (item.childName) {\n serieChildName = item.childName;\n break;\n }\n }\n }\n }\n\n if (serieChildName && dataChildName && serieChildName === dataChildName) {\n return true;\n }\n }\n }\n return false;\n};\n"],"names":[],"mappings":"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"}
|