@red-hat-developer-hub/plugin-cost-management 2.0.3-rc.4
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/CHANGELOG.md +25 -0
- package/README.md +152 -0
- package/app-config.dynamic.yaml +28 -0
- package/dist/Router.esm.js +21 -0
- package/dist/Router.esm.js.map +1 -0
- package/dist/apis.esm.js +14 -0
- package/dist/apis.esm.js.map +1 -0
- package/dist/components/BasePage.esm.js +29 -0
- package/dist/components/BasePage.esm.js.map +1 -0
- package/dist/components/InfoCardTitle.esm.js +9 -0
- package/dist/components/InfoCardTitle.esm.js.map +1 -0
- package/dist/components/PageLayout.esm.js +56 -0
- package/dist/components/PageLayout.esm.js.map +1 -0
- package/dist/components/filtersStyles.esm.js +32 -0
- package/dist/components/filtersStyles.esm.js.map +1 -0
- package/dist/components/icon/AnalyticsIcon.esm.js +11 -0
- package/dist/components/icon/AnalyticsIcon.esm.js.map +1 -0
- package/dist/components/icon/AnalyticsIconFilled.esm.js +9 -0
- package/dist/components/icon/AnalyticsIconFilled.esm.js.map +1 -0
- package/dist/components/icon/AnalyticsIconOutlined.esm.js +9 -0
- package/dist/components/icon/AnalyticsIconOutlined.esm.js.map +1 -0
- package/dist/components/icon/CostManagementIcon.esm.js +11 -0
- package/dist/components/icon/CostManagementIcon.esm.js.map +1 -0
- package/dist/components/icon/CostManagementIconFilled.esm.js +9 -0
- package/dist/components/icon/CostManagementIconFilled.esm.js.map +1 -0
- package/dist/components/icon/CostManagementIconOutlined.esm.js +9 -0
- package/dist/components/icon/CostManagementIconOutlined.esm.js.map +1 -0
- package/dist/constants/currencies.esm.js +36 -0
- package/dist/constants/currencies.esm.js.map +1 -0
- package/dist/hooks/usePatternFlyTheme.esm.js +22 -0
- package/dist/hooks/usePatternFlyTheme.esm.js.map +1 -0
- package/dist/hooks/useThemeBackgroundColor.esm.js +13 -0
- package/dist/hooks/useThemeBackgroundColor.esm.js.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.esm.js +9 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/pages/openshift/OpenShiftPage.esm.js +727 -0
- package/dist/pages/openshift/OpenShiftPage.esm.js.map +1 -0
- package/dist/pages/openshift/components/AutocompleteComponent.esm.js +65 -0
- package/dist/pages/openshift/components/AutocompleteComponent.esm.js.map +1 -0
- package/dist/pages/openshift/components/DownloadIconButton.esm.js +49 -0
- package/dist/pages/openshift/components/DownloadIconButton.esm.js.map +1 -0
- package/dist/pages/openshift/components/Filters.esm.js +360 -0
- package/dist/pages/openshift/components/Filters.esm.js.map +1 -0
- package/dist/pages/openshift/components/PageHeader.esm.js +31 -0
- package/dist/pages/openshift/components/PageHeader.esm.js.map +1 -0
- package/dist/pages/openshift/components/SelectComponent.esm.js +68 -0
- package/dist/pages/openshift/components/SelectComponent.esm.js.map +1 -0
- package/dist/pages/openshift/components/TableToolbar.esm.js +249 -0
- package/dist/pages/openshift/components/TableToolbar.esm.js.map +1 -0
- package/dist/pages/optimizations/OptimizationsPage.esm.js +205 -0
- package/dist/pages/optimizations/OptimizationsPage.esm.js.map +1 -0
- package/dist/pages/optimizations/components/ComboBox.esm.js +84 -0
- package/dist/pages/optimizations/components/ComboBox.esm.js.map +1 -0
- package/dist/pages/optimizations/components/Filters.esm.js +59 -0
- package/dist/pages/optimizations/components/Filters.esm.js.map +1 -0
- package/dist/pages/optimizations/components/TableToolbar.esm.js +40 -0
- package/dist/pages/optimizations/components/TableToolbar.esm.js.map +1 -0
- package/dist/pages/optimizations-breakdown/OptimizationsBreakdownPage.esm.js +211 -0
- package/dist/pages/optimizations-breakdown/OptimizationsBreakdownPage.esm.js.map +1 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.esm.js +132 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.esm.js.map +1 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.esm.js +37 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.esm.js.map +1 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.esm.js +50 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.esm.js.map +1 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.esm.js +26 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.esm.js.map +1 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.esm.js +51 -0
- package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.esm.js.map +1 -0
- 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 +388 -0
- 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 -0
- 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/data.json.esm.js +512 -0
- 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/data.json.esm.js.map +1 -0
- 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 +18 -0
- 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 -0
- 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 +72 -0
- 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 -0
- 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 +96 -0
- 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 -0
- 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 +74 -0
- 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 -0
- 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 +109 -0
- 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 -0
- 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 +25 -0
- 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 -0
- package/dist/pages/optimizations-breakdown/models/ChartEnums.esm.js +23 -0
- package/dist/pages/optimizations-breakdown/models/ChartEnums.esm.js.map +1 -0
- package/dist/pages/optimizations-breakdown/models/YamlCodeData.esm.js +129 -0
- package/dist/pages/optimizations-breakdown/models/YamlCodeData.esm.js.map +1 -0
- package/dist/plugin.esm.js +73 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +16 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/utils/dates.esm.js +37 -0
- package/dist/utils/dates.esm.js.map +1 -0
- package/package.json +110 -0
|
@@ -0,0 +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":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import intl from '../i18n/intl.esm.js';
|
|
2
|
+
import messages from '../i18n/messages.esm.js';
|
|
3
|
+
|
|
4
|
+
function getDatumDateRange(datums) {
|
|
5
|
+
let firstDay = 0;
|
|
6
|
+
for (let i = firstDay; i < datums.length; i++) {
|
|
7
|
+
if (datums[i]?.key && datums[i]?.y !== null) {
|
|
8
|
+
firstDay = i;
|
|
9
|
+
break;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
let lastDay = datums.length - 1;
|
|
13
|
+
for (let i = lastDay; i >= 0; i--) {
|
|
14
|
+
if (datums[i]?.key && datums[i].y !== null) {
|
|
15
|
+
lastDay = i;
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const start = new Date(datums[firstDay].key);
|
|
20
|
+
const end = new Date(datums[lastDay].key);
|
|
21
|
+
return [start, end];
|
|
22
|
+
}
|
|
23
|
+
function getDateRangeString(datums, key, isSameDate = false, noDataKey = messages.chartNoData) {
|
|
24
|
+
if (!(datums?.length && key)) {
|
|
25
|
+
return intl.formatMessage(noDataKey);
|
|
26
|
+
}
|
|
27
|
+
const [start, end] = getDatumDateRange(datums);
|
|
28
|
+
const dateRange = intl.formatDateTimeRange(isSameDate ? end : start, end, {
|
|
29
|
+
day: "numeric",
|
|
30
|
+
month: "short"
|
|
31
|
+
});
|
|
32
|
+
return intl.formatMessage(key, {
|
|
33
|
+
dateRange
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function getMinOrMaxY(datum, minOrMaxFn) {
|
|
37
|
+
let value;
|
|
38
|
+
if (datum.y0 !== void 0) {
|
|
39
|
+
value = minOrMaxFn(datum.y, datum.y0);
|
|
40
|
+
} else {
|
|
41
|
+
if (Array.isArray(datum.y)) {
|
|
42
|
+
if (datum.y[0] !== null) {
|
|
43
|
+
value = minOrMaxFn(...datum.y);
|
|
44
|
+
} else if (datum.yVal) {
|
|
45
|
+
value = datum.yVal;
|
|
46
|
+
} else {
|
|
47
|
+
value = null;
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
value = datum.y;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
function getMaxMinValues(datums) {
|
|
56
|
+
let max = null;
|
|
57
|
+
let min = null;
|
|
58
|
+
if (datums && datums.length) {
|
|
59
|
+
datums.forEach((datum) => {
|
|
60
|
+
const maxY = getMinOrMaxY(datum, Math.max);
|
|
61
|
+
const minY = getMinOrMaxY(datum, Math.min);
|
|
62
|
+
if (maxY !== null && (max === null || maxY > max)) {
|
|
63
|
+
max = maxY;
|
|
64
|
+
}
|
|
65
|
+
if (minY !== null && (min === null || minY < min)) {
|
|
66
|
+
min = minY;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return { max, min };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { getDateRangeString, getDatumDateRange, getMaxMinValues };
|
|
74
|
+
//# sourceMappingURL=chart-datum.esm.js.map
|
|
@@ -0,0 +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":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { getInteractiveLegendItemStyles } from '@patternfly/react-charts/victory';
|
|
2
|
+
import '../i18n/intl.esm.js';
|
|
3
|
+
import '../i18n/messages.esm.js';
|
|
4
|
+
import { getMaxMinValues } from './chart-datum.esm.js';
|
|
5
|
+
|
|
6
|
+
const isSeriesHidden = (hiddenSeries, index) => {
|
|
7
|
+
return hiddenSeries.has(index);
|
|
8
|
+
};
|
|
9
|
+
const getDomain = (series, hiddenSeries, groupedSeriesCount = 0) => {
|
|
10
|
+
const domain = { y: [0, 1] };
|
|
11
|
+
let maxValue = null;
|
|
12
|
+
let minValue = null;
|
|
13
|
+
if (series) {
|
|
14
|
+
let maybeEmptyHiddenSeries = hiddenSeries;
|
|
15
|
+
if (series.length - groupedSeriesCount === maybeEmptyHiddenSeries.size) {
|
|
16
|
+
domain.x = [0, 1];
|
|
17
|
+
maybeEmptyHiddenSeries = /* @__PURE__ */ new Set();
|
|
18
|
+
}
|
|
19
|
+
series.forEach((s, index) => {
|
|
20
|
+
if (!isSeriesHidden(maybeEmptyHiddenSeries, index) && s.data && s.data.length !== 0) {
|
|
21
|
+
const { max, min } = getMaxMinValues(s.data);
|
|
22
|
+
if (max !== null && (maxValue === null || max > maxValue)) {
|
|
23
|
+
maxValue = max;
|
|
24
|
+
}
|
|
25
|
+
if (min !== null && (minValue === null || min < minValue)) {
|
|
26
|
+
minValue = min;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (maxValue && minValue) {
|
|
32
|
+
const threshold = maxValue * 0.05;
|
|
33
|
+
const max = maxValue > 0 ? Math.ceil(maxValue + threshold) : 0;
|
|
34
|
+
const _min = minValue > 0 ? Math.max(0, Math.floor(minValue - threshold)) : 0;
|
|
35
|
+
const min = _min > 0 ? _min : 0;
|
|
36
|
+
if (max > 0) {
|
|
37
|
+
domain.y = [min, max];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return domain;
|
|
41
|
+
};
|
|
42
|
+
const getLegendData = (series, hiddenSeries, tooltip = false) => {
|
|
43
|
+
if (!series) {
|
|
44
|
+
return void 0;
|
|
45
|
+
}
|
|
46
|
+
const result = [];
|
|
47
|
+
series.forEach((s, index) => {
|
|
48
|
+
if (s.legendItem) {
|
|
49
|
+
const data = {
|
|
50
|
+
childName: s.childName,
|
|
51
|
+
...s.legendItem,
|
|
52
|
+
// name property
|
|
53
|
+
...tooltip && { name: s.legendItem.tooltip },
|
|
54
|
+
// Override name property for tooltip
|
|
55
|
+
...getInteractiveLegendItemStyles(hiddenSeries?.has(index))
|
|
56
|
+
// hidden styles
|
|
57
|
+
};
|
|
58
|
+
result.push(data);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
const getResizeObserver = (containerRef, handleResize) => {
|
|
64
|
+
const containerElement = containerRef;
|
|
65
|
+
const { ResizeObserver } = window;
|
|
66
|
+
let _resizeObserver;
|
|
67
|
+
if (containerElement && ResizeObserver) {
|
|
68
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
69
|
+
window.requestAnimationFrame(() => {
|
|
70
|
+
if (!Array.isArray(entries) || !entries.length) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
handleResize();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
resizeObserver.observe(containerElement);
|
|
77
|
+
_resizeObserver = () => resizeObserver.unobserve(containerElement);
|
|
78
|
+
} else {
|
|
79
|
+
handleResize();
|
|
80
|
+
window.addEventListener("resize", handleResize);
|
|
81
|
+
_resizeObserver = () => window.removeEventListener("resize", handleResize);
|
|
82
|
+
}
|
|
83
|
+
return () => {
|
|
84
|
+
if (_resizeObserver) {
|
|
85
|
+
_resizeObserver();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
const initHiddenSeries = (hiddenSeries, index) => {
|
|
90
|
+
const result = new Set(hiddenSeries);
|
|
91
|
+
if (!result.delete(index)) {
|
|
92
|
+
result.add(index);
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
};
|
|
96
|
+
const isDataAvailable = (series, hiddenSeries) => {
|
|
97
|
+
const unavailable = [];
|
|
98
|
+
if (series) {
|
|
99
|
+
series.forEach((s, index) => {
|
|
100
|
+
if (hiddenSeries && isSeriesHidden(hiddenSeries, index) || s.data && s.data.length === 0) {
|
|
101
|
+
unavailable.push(index);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return unavailable.length !== (series ? series.length : 0);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export { getDomain, getLegendData, getResizeObserver, initHiddenSeries, isDataAvailable, isSeriesHidden };
|
|
109
|
+
//# sourceMappingURL=chart-utils.esm.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import '../i18n/intl.esm.js';
|
|
2
|
+
import '../i18n/messages.esm.js';
|
|
3
|
+
|
|
4
|
+
const unitsLookupKey = (units) => {
|
|
5
|
+
const lookup = units ? units.replace(/[- ]/g, "_").toLocaleLowerCase("en-US") : "";
|
|
6
|
+
switch (lookup) {
|
|
7
|
+
case "cores":
|
|
8
|
+
case "ei":
|
|
9
|
+
case "eib":
|
|
10
|
+
case "gi":
|
|
11
|
+
case "gib":
|
|
12
|
+
case "ki":
|
|
13
|
+
case "kib":
|
|
14
|
+
case "m":
|
|
15
|
+
case "millicores":
|
|
16
|
+
case "mi":
|
|
17
|
+
case "mib":
|
|
18
|
+
return lookup;
|
|
19
|
+
default:
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { unitsLookupKey };
|
|
25
|
+
//# sourceMappingURL=format.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"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/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 { getLocale, intl } from '../i18n';\nimport messages from '../i18n/messages';\n\nexport interface FormatOptions {\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n}\n\nexport type Formatter = (\n value: number,\n units: string,\n options?: FormatOptions,\n) => string;\nexport type PercentageFormatter = (\n value: number,\n options?: FormatOptions,\n) => string;\ntype UnitsFormatter = (value: number, options?: FormatOptions) => string;\n\n// Returns the number of decimals for given string\nexport const countDecimals = (value: string, useLocale: boolean = true) => {\n const decimalSeparator = useLocale\n ? Number('1.1').toLocaleString(getLocale(), {}).substring(1, 2)\n : '.';\n const decimals = value.split(decimalSeparator);\n return decimals[1] ? decimals[1].length : 0;\n};\n\n// Currencies are formatted differently, depending on the locale you're using. For example, the dollar\n// sign may appear on the left or the right of the currency symbol for French Vs German.\n//\n// Using the ISO currency code AUD, $12.34 USD is formatted per the locales below.\n// See ICU currencies https://www.localeplanet.com/icu/currency.html\n//\n// en: A$12.34\n// fr: 12,34 $AU\n// de: 12,34 AU$\n//\n// Note: Some currencies do not have decimals, such as JPY, and some have 3 decimals such as IQD.\n// See https://docs.adyen.com/development-resources/currency-codes\nexport const formatCurrency: Formatter = (\n value: number,\n units: string,\n options: FormatOptions = {},\n) => {\n let fValue = value;\n // Don't show negative zero -- https://issues.redhat.com/browse/COST-3087\n if (!value || Number(value).toFixed(2) === '-0.00') {\n fValue = 0;\n }\n // Don't specify default fraction digits here, rely on react-intl instead\n return intl.formatNumber(fValue, {\n style: 'currency',\n currency: units ? units.toLocaleUpperCase('en-US') : 'USD',\n ...options,\n });\n};\n\nexport const formatCurrencyAbbreviation: Formatter = (value, units = 'USD') => {\n let fValue = value;\n if (!value) {\n fValue = 0;\n }\n\n // Derived from https://stackoverflow.com/questions/37799955/how-can-i-format-big-numbers-with-tolocalestring\n const abbreviationFormats = [\n { val: 1e15, symbol: 'quadrillion' },\n { val: 1e12, symbol: 'trillion' },\n { val: 1e9, symbol: 'billion' },\n { val: 1e6, symbol: 'million' },\n { val: 1e3, symbol: 'thousand' },\n ];\n\n // Find the proper format to use\n let format;\n if (abbreviationFormats) {\n format = abbreviationFormats.find(f => fValue >= f.val);\n }\n\n // Apply format and insert symbol next to the numeric portion of the formatted string\n if (format) {\n const { val, symbol } = format;\n return intl.formatMessage(messages.currencyAbbreviations, {\n symbol,\n value: formatCurrency(fValue / val, units, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }),\n });\n }\n\n // If no format was found, format value without abbreviation\n return formatCurrency(value, units, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n });\n};\n\n// Formats cost model rates with 0 to 10 decimals\n// https://issues.redhat.com/browse/COST-1884\nexport const formatCurrencyRate: Formatter = (\n value: number,\n units: string,\n options: FormatOptions = {\n minimumFractionDigits: 0,\n maximumFractionDigits: 10,\n },\n) => {\n return formatCurrency(value, units, options);\n};\n\n// Formats without currency symbol\nexport const formatCurrencyRaw: Formatter = (\n value: number,\n units: string,\n options: FormatOptions = {},\n) => {\n return formatCurrency(value, units, {\n currencyDisplay: 'code',\n ...options,\n } as any)\n .toString()\n .replace(units, '')\n .trim();\n};\n\n// Formats cost model rates with 0 to 10 decimals\n// https://issues.redhat.com/browse/COST-1884\nexport const formatCurrencyRateRaw: Formatter = (\n value: number,\n units: string,\n options: FormatOptions = {\n minimumFractionDigits: 0,\n maximumFractionDigits: 10,\n },\n) => {\n return formatCurrencyRaw(value, units, options);\n};\n\n// Returns i18n key for given units\nexport const unitsLookupKey = (units: string): string => {\n const lookup = units\n ? units.replace(/[- ]/g, '_').toLocaleLowerCase('en-US')\n : '';\n\n switch (lookup) {\n case 'cores':\n case 'ei':\n case 'eib':\n case 'gi':\n case 'gib':\n case 'ki':\n case 'kib':\n case 'm':\n case 'millicores':\n case 'mi':\n case 'mib':\n return lookup;\n default:\n return '';\n }\n};\n\nexport const formatUsage: UnitsFormatter = (\n value,\n options: FormatOptions = {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n },\n) => {\n return value?.toLocaleString(getLocale(), options);\n};\n\nconst unknownTypeFormatter = (value: number, options?: FormatOptions) => {\n return value?.toLocaleString(getLocale(), options);\n};\n\n// Returns formatted units or currency with given currency-code\nexport const formatUnits: Formatter = (value, units, options) => {\n const lookup = unitsLookupKey(units);\n const fValue = value || 0;\n\n switch (lookup) {\n case 'byte_ms':\n case 'core':\n case 'core_hours':\n case 'hour':\n case 'hrs':\n case 'gb':\n case 'gb_hours':\n case 'gb_mo':\n case 'gb_ms':\n case 'gibibyte_month':\n case 'ms':\n case 'tag_mo':\n case 'vm_hours':\n return formatUsage(fValue, options);\n default:\n return unknownTypeFormatter(fValue, options);\n }\n};\n\nexport const formatPercentage: PercentageFormatter = (\n value,\n options: FormatOptions = {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n },\n) => {\n return value?.toLocaleString(getLocale(), options);\n};\n\n// Formats cost model markup with 0 to 10 decimals\n// https://issues.redhat.com/browse/COST-1884\nexport const formatPercentageMarkup: PercentageFormatter = (\n value,\n options: FormatOptions = {\n minimumFractionDigits: 0,\n maximumFractionDigits: 10,\n },\n) => {\n return value?.toLocaleString(getLocale(), options);\n};\n\n// Format optimization metrics\nexport const formatOptimization: PercentageFormatter = (\n value,\n options: FormatOptions = {\n minimumFractionDigits: 0,\n maximumFractionDigits: 20, // Allow the API to set the number of decimal places\n },\n) => {\n return value?.toLocaleString(getLocale(), options);\n};\n\n// Returns true if given percentage or currency format is valid for current locale\nexport const isCurrencyFormatValid = (value: string) => {\n const decimalSeparator = intl.formatNumber(1.1).toString().replace(/1/g, '');\n\n // ^[0-9] The number must start with 0-9\n // \\d* The number can then have any number of any digits\n // (...)$ look at the next group from the end (...)$\n // (...)*(...)? Look for groups optionally. The first is for the comma, the second is for the decimal.\n // (,\\d{3}){1} Look for one occurrence of a comma followed by exactly three digits\n // \\.\\d Look for a decimal followed by any number of any digits\n //\n // See https://stackoverflow.com/questions/2227370/currency-validation\n const regex =\n decimalSeparator === '.'\n ? /^-?[0-9]\\d*(((,\\d{3}){1})*(\\.\\d*)?)$/\n : /^-?[0-9]\\d*(((\\.\\d{3}){1})*(,\\d*)?)$/;\n\n return regex.test(value);\n};\n\n// Returns true if given percentage is valid for current locale\nexport const isPercentageFormatValid = (value: string) => {\n return isCurrencyFormatValid(value);\n};\n\n// This function normalizes a given currency or percentage.\n//\n// Some locales us a comma as the decimal separator (e.g., \"1.234,56\" in German), which must be\n// replaced for APIs where USD decimal format is expected.\n//\n// Note that the group separator (e.g., \"1,234.56\" in USD) must also be removed when formatting\n// currencies and percentages to display in the browser's locale.\nexport const unFormat = (value: string) => {\n if (!value) {\n return value;\n }\n const groupSeparator = intl.formatNumber(1111).toString().replace(/1/g, '');\n const decimalSeparator = intl.formatNumber(1.1).toString().replace(/1/g, '');\n\n let rawValue = value\n .toString()\n .replace(groupSeparator === ',' ? /,/g : /\\./g, '');\n rawValue = rawValue.replace(decimalSeparator === '.' ? /\\./g : /,/g, '.');\n\n return Number.isNaN(rawValue) ? '0' : rawValue;\n};\n"],"names":[],"mappings":";;;AA4Ja,MAAA,cAAA,GAAiB,CAAC,KAA0B,KAAA;AACvD,EAAM,MAAA,MAAA,GAAS,QACX,KAAM,CAAA,OAAA,CAAQ,SAAS,GAAG,CAAA,CAAE,iBAAkB,CAAA,OAAO,CACrD,GAAA,EAAA;AAEJ,EAAA,QAAQ,MAAQ;AAAA,IACd,KAAK,OAAA;AAAA,IACL,KAAK,IAAA;AAAA,IACL,KAAK,KAAA;AAAA,IACL,KAAK,IAAA;AAAA,IACL,KAAK,KAAA;AAAA,IACL,KAAK,IAAA;AAAA,IACL,KAAK,KAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,YAAA;AAAA,IACL,KAAK,IAAA;AAAA,IACL,KAAK,KAAA;AACH,MAAO,OAAA,MAAA;AAAA,IACT;AACE,MAAO,OAAA,EAAA;AAAA;AAEb;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
var UsageType = /* @__PURE__ */ ((UsageType2) => {
|
|
2
|
+
UsageType2["cpuUsage"] = "cpuUsage";
|
|
3
|
+
UsageType2["memoryUsage"] = "memoryUsage";
|
|
4
|
+
return UsageType2;
|
|
5
|
+
})(UsageType || {});
|
|
6
|
+
var OptimizationType = /* @__PURE__ */ ((OptimizationType2) => {
|
|
7
|
+
OptimizationType2["cost"] = "cost";
|
|
8
|
+
OptimizationType2["performance"] = "performance";
|
|
9
|
+
return OptimizationType2;
|
|
10
|
+
})(OptimizationType || {});
|
|
11
|
+
var RecommendationType = /* @__PURE__ */ ((RecommendationType2) => {
|
|
12
|
+
RecommendationType2["cpu"] = "cpu";
|
|
13
|
+
RecommendationType2["memory"] = "memory";
|
|
14
|
+
return RecommendationType2;
|
|
15
|
+
})(RecommendationType || {});
|
|
16
|
+
var ResourceType = /* @__PURE__ */ ((ResourceType2) => {
|
|
17
|
+
ResourceType2["limits"] = "limits";
|
|
18
|
+
ResourceType2["requests"] = "requests";
|
|
19
|
+
return ResourceType2;
|
|
20
|
+
})(ResourceType || {});
|
|
21
|
+
|
|
22
|
+
export { OptimizationType, RecommendationType, ResourceType, UsageType };
|
|
23
|
+
//# sourceMappingURL=ChartEnums.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChartEnums.esm.js","sources":["../../../../src/pages/optimizations-breakdown/models/ChartEnums.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\nexport const enum UsageType {\n cpuUsage = 'cpuUsage',\n memoryUsage = 'memoryUsage',\n}\n\n// eslint-disable-next-line no-shadow\nexport type Interval = 'shortTerm' | 'mediumTerm' | 'longTerm';\n\n// eslint-disable-next-line no-shadow\nexport const enum OptimizationType {\n cost = 'cost',\n performance = 'performance',\n}\n\n// eslint-disable-next-line no-shadow\nexport const enum RecommendationType {\n cpu = 'cpu',\n memory = 'memory',\n}\n\n// eslint-disable-next-line no-shadow\nexport const enum ResourceType {\n limits = 'limits',\n requests = 'requests',\n}\n"],"names":["UsageType","OptimizationType","RecommendationType","ResourceType"],"mappings":"AAgBkB,IAAA,SAAA,qBAAAA,UAAX,KAAA;AACL,EAAAA,WAAA,UAAW,CAAA,GAAA,UAAA;AACX,EAAAA,WAAA,aAAc,CAAA,GAAA,aAAA;AAFE,EAAAA,OAAAA,UAAAA;AAAA,CAAA,EAAA,SAAA,IAAA,EAAA;AASA,IAAA,gBAAA,qBAAAC,iBAAX,KAAA;AACL,EAAAA,kBAAA,MAAO,CAAA,GAAA,MAAA;AACP,EAAAA,kBAAA,aAAc,CAAA,GAAA,aAAA;AAFE,EAAAA,OAAAA,iBAAAA;AAAA,CAAA,EAAA,gBAAA,IAAA,EAAA;AAMA,IAAA,kBAAA,qBAAAC,mBAAX,KAAA;AACL,EAAAA,oBAAA,KAAM,CAAA,GAAA,KAAA;AACN,EAAAA,oBAAA,QAAS,CAAA,GAAA,QAAA;AAFO,EAAAA,OAAAA,mBAAAA;AAAA,CAAA,EAAA,kBAAA,IAAA,EAAA;AAMA,IAAA,YAAA,qBAAAC,aAAX,KAAA;AACL,EAAAA,cAAA,QAAS,CAAA,GAAA,QAAA;AACT,EAAAA,cAAA,UAAW,CAAA,GAAA,UAAA;AAFK,EAAAA,OAAAA,aAAAA;AAAA,CAAA,EAAA,YAAA,IAAA,EAAA;;;;"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { isEmpty } from 'lodash';
|
|
2
|
+
|
|
3
|
+
const getPercentage = (currentVal, recommendedVal) => {
|
|
4
|
+
if (currentVal === 0) {
|
|
5
|
+
return 0;
|
|
6
|
+
}
|
|
7
|
+
const changeValue = recommendedVal - currentVal;
|
|
8
|
+
return parseFloat((changeValue / currentVal * 100).toFixed(2));
|
|
9
|
+
};
|
|
10
|
+
const getRecommendedValue = (currentValues, recommendedValues, key1, key2) => {
|
|
11
|
+
let currentVal = currentValues[key1]?.[key2]?.amount || 0;
|
|
12
|
+
const currentFormat = currentValues[key1]?.[key2]?.format || "";
|
|
13
|
+
let recommendedVal = recommendedValues[key1]?.[key2]?.amount || 0;
|
|
14
|
+
const recommendedFormat = recommendedValues[key1]?.[key2]?.format || "";
|
|
15
|
+
if (recommendedVal === 0) {
|
|
16
|
+
return "-";
|
|
17
|
+
}
|
|
18
|
+
if (currentFormat && recommendedFormat && currentFormat !== recommendedFormat) {
|
|
19
|
+
if (key2 === "cpu") {
|
|
20
|
+
const getMultiplier = (units) => {
|
|
21
|
+
return units === null || units === "cores" ? 1e3 : 1;
|
|
22
|
+
};
|
|
23
|
+
currentVal = currentVal * getMultiplier(currentFormat || "cores");
|
|
24
|
+
recommendedVal = recommendedVal * getMultiplier(recommendedFormat || "cores");
|
|
25
|
+
} else if (key2 === "memory") {
|
|
26
|
+
const getMultiplier = (units) => {
|
|
27
|
+
switch (units.toLocaleLowerCase("en-US")) {
|
|
28
|
+
case "ei":
|
|
29
|
+
return Math.pow(2, 60);
|
|
30
|
+
case "pi":
|
|
31
|
+
return Math.pow(2, 50);
|
|
32
|
+
case "ti":
|
|
33
|
+
return Math.pow(2, 40);
|
|
34
|
+
case "gi":
|
|
35
|
+
return Math.pow(2, 30);
|
|
36
|
+
case "mi":
|
|
37
|
+
return Math.pow(2, 20);
|
|
38
|
+
case "ki":
|
|
39
|
+
return Math.pow(2, 10);
|
|
40
|
+
default:
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
currentVal = currentVal * getMultiplier(currentFormat || "bytes");
|
|
45
|
+
recommendedVal = recommendedVal * getMultiplier(recommendedFormat || "byes");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const percentage = getPercentage(currentVal, recommendedVal);
|
|
49
|
+
const paddingValue = { cpu: 20, memory: 17 };
|
|
50
|
+
const percentageSign = percentage > 0 ? "+" : "";
|
|
51
|
+
const formattedRecommendedValue = `${recommendedVal}${recommendedFormat}`.padEnd(paddingValue[key2]);
|
|
52
|
+
const formattedPercentageValue = `# ${percentageSign}${percentage}%`;
|
|
53
|
+
return `${formattedRecommendedValue}${formattedPercentageValue}`;
|
|
54
|
+
};
|
|
55
|
+
const getRecommendedYAMLCodeData = (value, duration, type) => {
|
|
56
|
+
const currentValues = value?.recommendations?.current;
|
|
57
|
+
const recommendedValues = value?.recommendations?.recommendationTerms?.[duration]?.recommendationEngines?.[type]?.config;
|
|
58
|
+
if (currentValues && recommendedValues) {
|
|
59
|
+
const cpuLimitsValue = getRecommendedValue(
|
|
60
|
+
currentValues,
|
|
61
|
+
recommendedValues,
|
|
62
|
+
"limits",
|
|
63
|
+
"cpu"
|
|
64
|
+
);
|
|
65
|
+
const memoryLimitsValue = getRecommendedValue(
|
|
66
|
+
currentValues,
|
|
67
|
+
recommendedValues,
|
|
68
|
+
"limits",
|
|
69
|
+
"memory"
|
|
70
|
+
);
|
|
71
|
+
const cpuRequestsValue = getRecommendedValue(
|
|
72
|
+
currentValues,
|
|
73
|
+
recommendedValues,
|
|
74
|
+
"requests",
|
|
75
|
+
"cpu"
|
|
76
|
+
);
|
|
77
|
+
const memoryRequestsValue = getRecommendedValue(
|
|
78
|
+
currentValues,
|
|
79
|
+
recommendedValues,
|
|
80
|
+
"requests",
|
|
81
|
+
"memory"
|
|
82
|
+
);
|
|
83
|
+
const recommendedYAMLCodeData = {
|
|
84
|
+
limits: {
|
|
85
|
+
cpu: cpuLimitsValue,
|
|
86
|
+
memory: memoryLimitsValue
|
|
87
|
+
},
|
|
88
|
+
requests: {
|
|
89
|
+
cpu: cpuRequestsValue,
|
|
90
|
+
memory: memoryRequestsValue
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
return recommendedYAMLCodeData;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
limits: {
|
|
97
|
+
cpu: "",
|
|
98
|
+
memory: ""
|
|
99
|
+
},
|
|
100
|
+
requests: {
|
|
101
|
+
cpu: "",
|
|
102
|
+
memory: ""
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
const getCurrentYAMLCodeData = (value) => {
|
|
107
|
+
const cpuLimits = value?.recommendations?.current?.limits?.cpu;
|
|
108
|
+
const memoryLimits = value?.recommendations?.current?.limits?.memory;
|
|
109
|
+
const cpuRequests = value?.recommendations?.current?.requests?.cpu;
|
|
110
|
+
const memoryRequests = value?.recommendations?.current?.requests?.memory;
|
|
111
|
+
const cpuLimitsValue = isEmpty(cpuLimits) ? "-" : `${cpuLimits?.amount}${cpuLimits?.format}`;
|
|
112
|
+
const memoryLimitsValue = isEmpty(memoryLimits) ? "-" : `${memoryLimits?.amount}${memoryLimits?.format}`;
|
|
113
|
+
const cpuRequestsValue = isEmpty(cpuRequests) ? "-" : `${cpuRequests?.amount}${cpuRequests?.format}`;
|
|
114
|
+
const memoryRequestsValue = isEmpty(memoryRequests) ? "-" : `${memoryRequests?.amount}${memoryRequests?.format}`;
|
|
115
|
+
const currentYAMLCodeData = {
|
|
116
|
+
limits: {
|
|
117
|
+
cpu: cpuLimitsValue,
|
|
118
|
+
memory: memoryLimitsValue
|
|
119
|
+
},
|
|
120
|
+
requests: {
|
|
121
|
+
cpu: cpuRequestsValue,
|
|
122
|
+
memory: memoryRequestsValue
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
return currentYAMLCodeData;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export { getCurrentYAMLCodeData, getRecommendedYAMLCodeData };
|
|
129
|
+
//# sourceMappingURL=YamlCodeData.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YamlCodeData.esm.js","sources":["../../../../src/pages/optimizations-breakdown/models/YamlCodeData.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 { isEmpty } from 'lodash';\nimport type {\n RecommendationBoxPlots,\n RecommendationsRecommendationsCurrent,\n} from '@red-hat-developer-hub/plugin-cost-management-common/models';\nimport { Interval, OptimizationType } from './ChartEnums';\n\nexport interface YamlCodeData {\n limits: {\n cpu: number | string;\n memory: number | string;\n };\n requests: {\n cpu: number | string;\n memory: number | string;\n };\n}\n\nconst getPercentage = (currentVal: number, recommendedVal: number): number => {\n if (currentVal === 0) {\n return 0;\n }\n const changeValue = recommendedVal - currentVal;\n return parseFloat(((changeValue / currentVal) * 100).toFixed(2));\n};\n\nconst getRecommendedValue = (\n currentValues: RecommendationsRecommendationsCurrent,\n recommendedValues: RecommendationsRecommendationsCurrent,\n key1: 'limits' | 'requests',\n key2: 'cpu' | 'memory',\n): string => {\n let currentVal = currentValues[key1]?.[key2]?.amount || 0;\n const currentFormat = currentValues[key1]?.[key2]?.format || '';\n let recommendedVal = recommendedValues[key1]?.[key2]?.amount || 0;\n const recommendedFormat = recommendedValues[key1]?.[key2]?.format || '';\n\n if (recommendedVal === 0) {\n return '-';\n }\n\n // Convert units if not the same\n if (\n currentFormat &&\n recommendedFormat &&\n currentFormat !== recommendedFormat\n ) {\n if (key2 === 'cpu') {\n // Convert cores to millicores\n //\n // Note: units may be null to omit \"cores\" label for Kubernetes\n const getMultiplier = (units: string) => {\n return units === null || units === 'cores' ? 1000 : 1;\n };\n currentVal = currentVal * getMultiplier(currentFormat || 'cores');\n recommendedVal =\n recommendedVal * getMultiplier(recommendedFormat || 'cores');\n } else if (key2 === 'memory') {\n // Convert Gi, Mi, etc. to bytes\n //\n // See https://medium.com/swlh/understanding-kubernetes-resource-cpu-and-memory-units-30284b3cc866\n //\n // Ei = EiB = Exbibyte. 1Ei = 2⁶⁰ = 1,152,921,504,606,846,976 bytes\n // Pi = PiB = Pebibyte. 1Pi = 2⁵⁰ = 1,125,899,906,842,624 bytes\n // Ti = TiB = Tebibyte. 1Ti = 2⁴⁰ = 1,099,511,627,776 bytes\n // Gi = GiB = Gibibyte. 1Gi = 2³⁰ = 1,073,741,824 bytes\n // Mi = MiB = Mebibyte. 1Mi = 2²⁰ = 1,048,576 bytes\n // Ki = KiB = Kibibyte. 1Ki = 2¹⁰ = 1,024 bytes\n const getMultiplier = (units: string) => {\n switch (units.toLocaleLowerCase('en-US')) {\n case 'ei':\n return Math.pow(2, 60);\n case 'pi':\n return Math.pow(2, 50);\n case 'ti':\n return Math.pow(2, 40);\n case 'gi':\n return Math.pow(2, 30);\n case 'mi':\n return Math.pow(2, 20);\n case 'ki':\n return Math.pow(2, 10);\n default:\n return 1;\n }\n };\n currentVal = currentVal * getMultiplier(currentFormat || 'bytes');\n recommendedVal =\n recommendedVal * getMultiplier(recommendedFormat || 'byes');\n }\n }\n\n // Calculate percentage change\n const percentage: number = getPercentage(currentVal, recommendedVal);\n\n const paddingValue = { cpu: 20, memory: 17 };\n const percentageSign = percentage > 0 ? '+' : '';\n\n const formattedRecommendedValue =\n `${recommendedVal}${recommendedFormat}`.padEnd(paddingValue[key2]);\n const formattedPercentageValue = `# ${percentageSign}${percentage}%`;\n return `${formattedRecommendedValue}${formattedPercentageValue}`;\n};\n\nexport const getRecommendedYAMLCodeData = (\n value: RecommendationBoxPlots,\n duration: Interval,\n type: OptimizationType,\n): YamlCodeData => {\n const currentValues = value?.recommendations?.current;\n const recommendedValues =\n value?.recommendations?.recommendationTerms?.[duration]\n ?.recommendationEngines?.[type]?.config;\n\n if (currentValues && recommendedValues) {\n const cpuLimitsValue = getRecommendedValue(\n currentValues,\n recommendedValues,\n 'limits',\n 'cpu',\n );\n const memoryLimitsValue = getRecommendedValue(\n currentValues,\n recommendedValues,\n 'limits',\n 'memory',\n );\n\n const cpuRequestsValue = getRecommendedValue(\n currentValues,\n recommendedValues,\n 'requests',\n 'cpu',\n );\n const memoryRequestsValue = getRecommendedValue(\n currentValues,\n recommendedValues,\n 'requests',\n 'memory',\n );\n\n const recommendedYAMLCodeData: YamlCodeData = {\n limits: {\n cpu: cpuLimitsValue,\n memory: memoryLimitsValue,\n },\n requests: {\n cpu: cpuRequestsValue,\n memory: memoryRequestsValue,\n },\n };\n\n return recommendedYAMLCodeData;\n }\n\n return {\n limits: {\n cpu: '',\n memory: '',\n },\n requests: {\n cpu: '',\n memory: '',\n },\n };\n};\n\nexport const getCurrentYAMLCodeData = (\n value: RecommendationBoxPlots,\n): YamlCodeData => {\n // extract cpu & memory limits object\n const cpuLimits = value?.recommendations?.current?.limits?.cpu;\n const memoryLimits = value?.recommendations?.current?.limits?.memory;\n\n // extract cpu & memory requests object\n const cpuRequests = value?.recommendations?.current?.requests?.cpu;\n const memoryRequests = value?.recommendations?.current?.requests?.memory;\n\n // limits values\n const cpuLimitsValue = isEmpty(cpuLimits)\n ? '-'\n : `${cpuLimits?.amount}${cpuLimits?.format}`;\n const memoryLimitsValue = isEmpty(memoryLimits)\n ? '-'\n : `${memoryLimits?.amount}${memoryLimits?.format}`;\n\n // requests values\n const cpuRequestsValue = isEmpty(cpuRequests)\n ? '-'\n : `${cpuRequests?.amount}${cpuRequests?.format}`;\n const memoryRequestsValue = isEmpty(memoryRequests)\n ? '-'\n : `${memoryRequests?.amount}${memoryRequests?.format}`;\n\n const currentYAMLCodeData: YamlCodeData = {\n limits: {\n cpu: cpuLimitsValue,\n memory: memoryLimitsValue,\n },\n requests: {\n cpu: cpuRequestsValue,\n memory: memoryRequestsValue,\n },\n };\n\n return currentYAMLCodeData;\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createPlugin, createApiFactory, fetchApiRef, discoveryApiRef, identityApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
|
|
2
|
+
import { OptimizationsClient, OrchestratorSlimClient, CostManagementSlimClient } from '@red-hat-developer-hub/plugin-cost-management-common/clients';
|
|
3
|
+
import { optimizationsApiRef, orchestratorSlimApiRef, costManagementSlimApiRef } from './apis.esm.js';
|
|
4
|
+
import { optimizationsBreakdownRouteRef, openShiftRouteRef, rootRouteRef } from './routes.esm.js';
|
|
5
|
+
|
|
6
|
+
const resourceOptimizationPlugin = createPlugin({
|
|
7
|
+
id: "cost-management",
|
|
8
|
+
apis: [
|
|
9
|
+
createApiFactory({
|
|
10
|
+
api: optimizationsApiRef,
|
|
11
|
+
deps: {
|
|
12
|
+
discoveryApi: discoveryApiRef,
|
|
13
|
+
fetchApi: fetchApiRef
|
|
14
|
+
},
|
|
15
|
+
factory({ discoveryApi, fetchApi }) {
|
|
16
|
+
return new OptimizationsClient({
|
|
17
|
+
discoveryApi,
|
|
18
|
+
fetchApi
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}),
|
|
22
|
+
createApiFactory({
|
|
23
|
+
api: orchestratorSlimApiRef,
|
|
24
|
+
deps: {
|
|
25
|
+
discoveryApi: discoveryApiRef,
|
|
26
|
+
fetchApi: fetchApiRef,
|
|
27
|
+
identityApi: identityApiRef
|
|
28
|
+
},
|
|
29
|
+
factory({ discoveryApi, fetchApi, identityApi }) {
|
|
30
|
+
return new OrchestratorSlimClient({
|
|
31
|
+
discoveryApi,
|
|
32
|
+
fetchApi,
|
|
33
|
+
identityApi
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}),
|
|
37
|
+
createApiFactory({
|
|
38
|
+
api: costManagementSlimApiRef,
|
|
39
|
+
deps: {
|
|
40
|
+
discoveryApi: discoveryApiRef,
|
|
41
|
+
fetchApi: fetchApiRef
|
|
42
|
+
},
|
|
43
|
+
factory({ discoveryApi, fetchApi }) {
|
|
44
|
+
return new CostManagementSlimClient({
|
|
45
|
+
discoveryApi,
|
|
46
|
+
fetchApi
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
],
|
|
51
|
+
routes: {
|
|
52
|
+
root: rootRouteRef,
|
|
53
|
+
openShift: openShiftRouteRef,
|
|
54
|
+
breakdown: optimizationsBreakdownRouteRef
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const ResourceOptimizationPage = resourceOptimizationPlugin.provide(
|
|
58
|
+
createRoutableExtension({
|
|
59
|
+
name: "ResourceOptimizationPage",
|
|
60
|
+
component: () => import('./Router.esm.js').then((m) => m.Router),
|
|
61
|
+
mountPoint: rootRouteRef
|
|
62
|
+
})
|
|
63
|
+
);
|
|
64
|
+
const OpenShiftPage = resourceOptimizationPlugin.provide(
|
|
65
|
+
createRoutableExtension({
|
|
66
|
+
name: "OpenShiftPage",
|
|
67
|
+
component: () => import('./pages/openshift/OpenShiftPage.esm.js').then((m) => m.OpenShiftPage),
|
|
68
|
+
mountPoint: openShiftRouteRef
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
export { OpenShiftPage, ResourceOptimizationPage, resourceOptimizationPlugin };
|
|
73
|
+
//# sourceMappingURL=plugin.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.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 createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n} from '@backstage/core-plugin-api';\nimport {\n OptimizationsClient,\n OrchestratorSlimClient,\n CostManagementSlimClient,\n} from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport {\n optimizationsApiRef,\n orchestratorSlimApiRef,\n costManagementSlimApiRef,\n} from './apis';\nimport {\n optimizationsBreakdownRouteRef,\n openShiftRouteRef,\n rootRouteRef,\n} from './routes';\n\n/** @public */\nexport const resourceOptimizationPlugin = createPlugin({\n id: 'cost-management',\n apis: [\n createApiFactory({\n api: optimizationsApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory({ discoveryApi, fetchApi }) {\n return new OptimizationsClient({\n discoveryApi,\n fetchApi,\n });\n },\n }),\n createApiFactory({\n api: orchestratorSlimApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n identityApi: identityApiRef,\n },\n factory({ discoveryApi, fetchApi, identityApi }) {\n return new OrchestratorSlimClient({\n discoveryApi,\n fetchApi,\n identityApi,\n });\n },\n }),\n createApiFactory({\n api: costManagementSlimApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory({ discoveryApi, fetchApi }) {\n return new CostManagementSlimClient({\n discoveryApi,\n fetchApi,\n });\n },\n }),\n ],\n routes: {\n root: rootRouteRef,\n openShift: openShiftRouteRef,\n breakdown: optimizationsBreakdownRouteRef,\n },\n});\n\n/** @public */\nexport const ResourceOptimizationPage = resourceOptimizationPlugin.provide(\n createRoutableExtension({\n name: 'ResourceOptimizationPage',\n component: () => import('./Router').then(m => m.Router),\n mountPoint: rootRouteRef,\n }),\n);\n\n/** @public */\nexport const OpenShiftPage = resourceOptimizationPlugin.provide(\n createRoutableExtension({\n name: 'OpenShiftPage',\n component: () =>\n import('./pages/openshift/OpenShiftPage').then(m => m.OpenShiftPage),\n mountPoint: openShiftRouteRef,\n }),\n);\n"],"names":[],"mappings":";;;;;AAyCO,MAAM,6BAA6B,YAAa,CAAA;AAAA,EACrD,EAAI,EAAA,iBAAA;AAAA,EACJ,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,mBAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,YAAc,EAAA,eAAA;AAAA,QACd,QAAU,EAAA;AAAA,OACZ;AAAA,MACA,OAAQ,CAAA,EAAE,YAAc,EAAA,QAAA,EAAY,EAAA;AAClC,QAAA,OAAO,IAAI,mBAAoB,CAAA;AAAA,UAC7B,YAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA;AACH,KACD,CAAA;AAAA,IACD,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,sBAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,YAAc,EAAA,eAAA;AAAA,QACd,QAAU,EAAA,WAAA;AAAA,QACV,WAAa,EAAA;AAAA,OACf;AAAA,MACA,OAAQ,CAAA,EAAE,YAAc,EAAA,QAAA,EAAU,aAAe,EAAA;AAC/C,QAAA,OAAO,IAAI,sBAAuB,CAAA;AAAA,UAChC,YAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA;AACH,KACD,CAAA;AAAA,IACD,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,wBAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,YAAc,EAAA,eAAA;AAAA,QACd,QAAU,EAAA;AAAA,OACZ;AAAA,MACA,OAAQ,CAAA,EAAE,YAAc,EAAA,QAAA,EAAY,EAAA;AAClC,QAAA,OAAO,IAAI,wBAAyB,CAAA;AAAA,UAClC,YAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA;AACH,KACD;AAAA,GACH;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,YAAA;AAAA,IACN,SAAW,EAAA,iBAAA;AAAA,IACX,SAAW,EAAA;AAAA;AAEf,CAAC;AAGM,MAAM,2BAA2B,0BAA2B,CAAA,OAAA;AAAA,EACjE,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,0BAAA;AAAA,IACN,SAAA,EAAW,MAAM,OAAO,iBAAU,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,MAAM,CAAA;AAAA,IACtD,UAAY,EAAA;AAAA,GACb;AACH;AAGO,MAAM,gBAAgB,0BAA2B,CAAA,OAAA;AAAA,EACtD,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,eAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,wCAAiC,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,aAAa,CAAA;AAAA,IACrE,UAAY,EAAA;AAAA,GACb;AACH;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api';
|
|
2
|
+
|
|
3
|
+
const rootRouteRef = createRouteRef({
|
|
4
|
+
id: "ros.page.optimizations"
|
|
5
|
+
});
|
|
6
|
+
const openShiftRouteRef = createRouteRef({
|
|
7
|
+
id: "ros.page.openshift"
|
|
8
|
+
});
|
|
9
|
+
const optimizationsBreakdownRouteRef = createSubRouteRef({
|
|
10
|
+
id: "ros.page.breakdown",
|
|
11
|
+
parent: rootRouteRef,
|
|
12
|
+
path: "/:id/*"
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export { openShiftRouteRef, optimizationsBreakdownRouteRef, rootRouteRef };
|
|
16
|
+
//# sourceMappingURL=routes.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.esm.js","sources":["../src/routes.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 { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'ros.page.optimizations',\n});\n\nexport const openShiftRouteRef = createRouteRef({\n id: 'ros.page.openshift',\n});\n\nexport const optimizationsBreakdownRouteRef = createSubRouteRef({\n id: 'ros.page.breakdown',\n parent: rootRouteRef,\n path: '/:id/*',\n});\n"],"names":[],"mappings":";;AAkBO,MAAM,eAAe,cAAe,CAAA;AAAA,EACzC,EAAI,EAAA;AACN,CAAC;AAEM,MAAM,oBAAoB,cAAe,CAAA;AAAA,EAC9C,EAAI,EAAA;AACN,CAAC;AAEM,MAAM,iCAAiC,iBAAkB,CAAA;AAAA,EAC9D,EAAI,EAAA,oBAAA;AAAA,EACJ,MAAQ,EAAA,YAAA;AAAA,EACR,IAAM,EAAA;AACR,CAAC;;;;"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const getTimeFromNow = (lastDate = "N/A") => {
|
|
2
|
+
if (lastDate === "N/A") {
|
|
3
|
+
return lastDate;
|
|
4
|
+
}
|
|
5
|
+
const intl = new Intl.RelativeTimeFormat("en", { style: "long" });
|
|
6
|
+
const WEEK_IN_MILLIS = 6048e5;
|
|
7
|
+
const DAY_IN_MILLIS = 864e5;
|
|
8
|
+
const HOUR_IN_MILLIS = 36e5;
|
|
9
|
+
const MIN_IN_MILLIS = 6e4;
|
|
10
|
+
const SEC_IN_MILLIS = 1e3;
|
|
11
|
+
const getUTCTime = (date) => date.getTime() - date.getTimezoneOffset() * 6e4;
|
|
12
|
+
const currentUTCTime = getUTCTime(/* @__PURE__ */ new Date());
|
|
13
|
+
const lastUTCTime = lastDate ? getUTCTime(new Date(lastDate)) : currentUTCTime;
|
|
14
|
+
const diff = currentUTCTime - lastUTCTime;
|
|
15
|
+
if (Math.abs(diff) > WEEK_IN_MILLIS) {
|
|
16
|
+
return intl.format(Math.trunc(-(diff / WEEK_IN_MILLIS)), "week");
|
|
17
|
+
} else if (Math.abs(diff) > DAY_IN_MILLIS) {
|
|
18
|
+
return intl.format(Math.trunc(-(diff / DAY_IN_MILLIS)), "day");
|
|
19
|
+
} else if (Math.abs(diff) > HOUR_IN_MILLIS) {
|
|
20
|
+
return intl.format(
|
|
21
|
+
Math.trunc(-(diff % DAY_IN_MILLIS) / HOUR_IN_MILLIS),
|
|
22
|
+
"hour"
|
|
23
|
+
);
|
|
24
|
+
} else if (Math.abs(diff) > MIN_IN_MILLIS) {
|
|
25
|
+
return intl.format(
|
|
26
|
+
Math.trunc(-(diff % HOUR_IN_MILLIS) / MIN_IN_MILLIS),
|
|
27
|
+
"minute"
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
return intl.format(
|
|
31
|
+
Math.trunc(-(diff % MIN_IN_MILLIS) / SEC_IN_MILLIS),
|
|
32
|
+
"second"
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export { getTimeFromNow };
|
|
37
|
+
//# sourceMappingURL=dates.esm.js.map
|