@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.
Files changed (97) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +152 -0
  3. package/app-config.dynamic.yaml +28 -0
  4. package/dist/Router.esm.js +21 -0
  5. package/dist/Router.esm.js.map +1 -0
  6. package/dist/apis.esm.js +14 -0
  7. package/dist/apis.esm.js.map +1 -0
  8. package/dist/components/BasePage.esm.js +29 -0
  9. package/dist/components/BasePage.esm.js.map +1 -0
  10. package/dist/components/InfoCardTitle.esm.js +9 -0
  11. package/dist/components/InfoCardTitle.esm.js.map +1 -0
  12. package/dist/components/PageLayout.esm.js +56 -0
  13. package/dist/components/PageLayout.esm.js.map +1 -0
  14. package/dist/components/filtersStyles.esm.js +32 -0
  15. package/dist/components/filtersStyles.esm.js.map +1 -0
  16. package/dist/components/icon/AnalyticsIcon.esm.js +11 -0
  17. package/dist/components/icon/AnalyticsIcon.esm.js.map +1 -0
  18. package/dist/components/icon/AnalyticsIconFilled.esm.js +9 -0
  19. package/dist/components/icon/AnalyticsIconFilled.esm.js.map +1 -0
  20. package/dist/components/icon/AnalyticsIconOutlined.esm.js +9 -0
  21. package/dist/components/icon/AnalyticsIconOutlined.esm.js.map +1 -0
  22. package/dist/components/icon/CostManagementIcon.esm.js +11 -0
  23. package/dist/components/icon/CostManagementIcon.esm.js.map +1 -0
  24. package/dist/components/icon/CostManagementIconFilled.esm.js +9 -0
  25. package/dist/components/icon/CostManagementIconFilled.esm.js.map +1 -0
  26. package/dist/components/icon/CostManagementIconOutlined.esm.js +9 -0
  27. package/dist/components/icon/CostManagementIconOutlined.esm.js.map +1 -0
  28. package/dist/constants/currencies.esm.js +36 -0
  29. package/dist/constants/currencies.esm.js.map +1 -0
  30. package/dist/hooks/usePatternFlyTheme.esm.js +22 -0
  31. package/dist/hooks/usePatternFlyTheme.esm.js.map +1 -0
  32. package/dist/hooks/useThemeBackgroundColor.esm.js +13 -0
  33. package/dist/hooks/useThemeBackgroundColor.esm.js.map +1 -0
  34. package/dist/index.d.ts +71 -0
  35. package/dist/index.esm.js +9 -0
  36. package/dist/index.esm.js.map +1 -0
  37. package/dist/pages/openshift/OpenShiftPage.esm.js +727 -0
  38. package/dist/pages/openshift/OpenShiftPage.esm.js.map +1 -0
  39. package/dist/pages/openshift/components/AutocompleteComponent.esm.js +65 -0
  40. package/dist/pages/openshift/components/AutocompleteComponent.esm.js.map +1 -0
  41. package/dist/pages/openshift/components/DownloadIconButton.esm.js +49 -0
  42. package/dist/pages/openshift/components/DownloadIconButton.esm.js.map +1 -0
  43. package/dist/pages/openshift/components/Filters.esm.js +360 -0
  44. package/dist/pages/openshift/components/Filters.esm.js.map +1 -0
  45. package/dist/pages/openshift/components/PageHeader.esm.js +31 -0
  46. package/dist/pages/openshift/components/PageHeader.esm.js.map +1 -0
  47. package/dist/pages/openshift/components/SelectComponent.esm.js +68 -0
  48. package/dist/pages/openshift/components/SelectComponent.esm.js.map +1 -0
  49. package/dist/pages/openshift/components/TableToolbar.esm.js +249 -0
  50. package/dist/pages/openshift/components/TableToolbar.esm.js.map +1 -0
  51. package/dist/pages/optimizations/OptimizationsPage.esm.js +205 -0
  52. package/dist/pages/optimizations/OptimizationsPage.esm.js.map +1 -0
  53. package/dist/pages/optimizations/components/ComboBox.esm.js +84 -0
  54. package/dist/pages/optimizations/components/ComboBox.esm.js.map +1 -0
  55. package/dist/pages/optimizations/components/Filters.esm.js +59 -0
  56. package/dist/pages/optimizations/components/Filters.esm.js.map +1 -0
  57. package/dist/pages/optimizations/components/TableToolbar.esm.js +40 -0
  58. package/dist/pages/optimizations/components/TableToolbar.esm.js.map +1 -0
  59. package/dist/pages/optimizations-breakdown/OptimizationsBreakdownPage.esm.js +211 -0
  60. package/dist/pages/optimizations-breakdown/OptimizationsBreakdownPage.esm.js.map +1 -0
  61. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.esm.js +132 -0
  62. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.esm.js.map +1 -0
  63. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.esm.js +37 -0
  64. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.esm.js.map +1 -0
  65. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.esm.js +50 -0
  66. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.esm.js.map +1 -0
  67. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.esm.js +26 -0
  68. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.esm.js.map +1 -0
  69. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.esm.js +51 -0
  70. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.esm.js.map +1 -0
  71. 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
  72. 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
  73. 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
  74. 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
  75. 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
  76. 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
  77. 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
  78. 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
  79. 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
  80. 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
  81. 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
  82. 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
  83. 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
  84. 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
  85. 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
  86. 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
  87. package/dist/pages/optimizations-breakdown/models/ChartEnums.esm.js +23 -0
  88. package/dist/pages/optimizations-breakdown/models/ChartEnums.esm.js.map +1 -0
  89. package/dist/pages/optimizations-breakdown/models/YamlCodeData.esm.js +129 -0
  90. package/dist/pages/optimizations-breakdown/models/YamlCodeData.esm.js.map +1 -0
  91. package/dist/plugin.esm.js +73 -0
  92. package/dist/plugin.esm.js.map +1 -0
  93. package/dist/routes.esm.js +16 -0
  94. package/dist/routes.esm.js.map +1 -0
  95. package/dist/utils/dates.esm.js +37 -0
  96. package/dist/utils/dates.esm.js.map +1 -0
  97. package/package.json +110 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenShiftPage.esm.js","sources":["../../../src/pages/openshift/OpenShiftPage.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, useState, useCallback, useRef } from 'react';\nimport type { ExportFormat } from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport {\n Table,\n TableColumn,\n InfoCard,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport { BasePage } from '../../components/BasePage';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Filters } from './components/Filters';\nimport { Divider, useTheme } from '@material-ui/core';\nimport { PageHeader } from './components/PageHeader';\nimport { TableToolbar } from './components/TableToolbar';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { costManagementSlimApiRef } from '../../apis';\nimport useAsync from 'react-use/lib/useAsync';\nimport { CURRENCY_SYMBOLS } from '../../constants/currencies';\nimport { DownloadIconButton } from './components/DownloadIconButton';\n\nconst formatCurrency = (value: number, currencyCode: string): string => {\n const symbol = CURRENCY_SYMBOLS[currencyCode] || currencyCode;\n return `${symbol}${value.toLocaleString('en-US', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}`;\n};\n\ninterface ProjectCost {\n id: string;\n projectName: string;\n clusterId?: string;\n cost: number;\n costPercentage: number;\n monthOverMonthChange: number;\n monthOverMonthValue: number;\n includesOverhead: boolean;\n previousPeriodCost: number;\n infrastructureCost: number;\n infrastructureCostPercentage: number;\n supplementaryCost: number;\n supplementaryCostPercentage: number;\n}\n\n/**\n * Generates date range text based on time range selection\n * @param timeRange - 'month-to-date' or 'previous-month'\n * @returns Formatted string like \"December 1-3\" or \"November 1-30\"\n */\nfunction getDateRangeText(timeRange: string): string {\n const now = new Date();\n const currentMonth = now.getMonth();\n const currentYear = now.getFullYear();\n const currentDay = now.getDate();\n\n if (timeRange === 'month-to-date') {\n // Current month: MONTH 1-<CURRENT_DAY>\n const monthName = now.toLocaleString('en-US', { month: 'long' });\n return `${monthName} 1-${currentDay}`;\n }\n // Previous month: PREVIOUS_MONTH 1-<LAST_DAY>\n const prevMonth = currentMonth === 0 ? 11 : currentMonth - 1;\n const prevYear = currentMonth === 0 ? currentYear - 1 : currentYear;\n const prevMonthDate = new Date(prevYear, prevMonth + 1, 0); // Last day of previous month\n const lastDay = prevMonthDate.getDate();\n const monthName = prevMonthDate.toLocaleString('en-US', { month: 'long' });\n return `${monthName} 1-${lastDay}`;\n}\n\n/**\n * Configuration for building query parameters\n */\ninterface QueryParamsConfig {\n groupBy: string;\n selectedTag: string;\n overheadDistribution: string;\n timeRange: string;\n currency: string;\n showPlatformSum: boolean;\n filterBy: string;\n filterValue: string;\n filterOperation: string;\n selectedTagKey: string;\n selectedTagValue: string;\n sortField: string | null;\n sortDirection: 'asc' | 'desc';\n}\n\n/**\n * Options for building query parameters\n */\ninterface BuildQueryParamsOptions {\n /** Pagination limit - omit for download (uses 0) */\n limit?: number;\n /** Pagination offset - omit for download */\n offset?: number;\n /** Specific item name to filter by (for row-level download) */\n specificItemName?: string;\n}\n\n/**\n * Builds query parameters for cost management API requests\n * Shared between data fetching and download functionality\n */\nfunction buildCostManagementQueryParams(\n config: QueryParamsConfig,\n options: BuildQueryParamsOptions = {},\n): Record<string, string | number> {\n const {\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n } = config;\n\n const { limit, offset, specificItemName } = options;\n\n // Build group by parameter\n const groupByParam =\n groupBy === 'tag' ? `group_by[tag:${selectedTag}]` : `group_by[${groupBy}]`;\n\n // Determine delta parameter\n const deltaParam =\n groupBy === 'project' && overheadDistribution === 'distribute'\n ? 'distributed_cost'\n : 'cost';\n\n const timeScopeValue = timeRange === 'month-to-date' ? -1 : -2;\n\n const queryParams: Record<string, string | number> = {\n currency,\n delta: deltaParam,\n 'filter[resolution]': 'monthly',\n 'filter[time_scope_units]': 'month',\n 'filter[time_scope_value]': timeScopeValue,\n };\n\n // Add pagination if provided\n if (limit !== undefined) {\n queryParams['filter[limit]'] = limit;\n }\n if (offset !== undefined) {\n queryParams['filter[offset]'] = offset;\n }\n\n // Add category parameter when showPlatformSum is enabled\n if (showPlatformSum) {\n queryParams.category = 'Platform';\n }\n\n queryParams[groupByParam] = '*';\n\n // Handle filtering\n if (specificItemName) {\n // Filter for specific item (row-level download)\n queryParams[`filter[${groupBy}]`] = specificItemName;\n } else if (filterBy === 'tag' && selectedTagKey && selectedTagValue) {\n // Tag filtering\n if (filterOperation === 'exact') {\n queryParams[`filter[exact:tag:${selectedTagKey}]`] = selectedTagValue;\n } else if (filterOperation === 'excludes') {\n queryParams[`exclude[tag:${selectedTagKey}]`] = selectedTagValue;\n } else {\n queryParams[`filter[tag:${selectedTagKey}]`] = selectedTagValue;\n }\n } else if (filterValue) {\n // Regular filtering\n if (filterOperation === 'exact') {\n queryParams[`filter[exact:${filterBy}]`] = filterValue;\n } else if (filterOperation === 'excludes') {\n queryParams[`exclude[${filterBy}]`] = filterValue;\n } else {\n queryParams[`filter[${filterBy}]`] = filterValue;\n }\n }\n\n // Add sorting\n let apiSortField: string;\n if (sortField) {\n if (sortField === 'cost') {\n apiSortField = deltaParam;\n } else if (sortField === 'projectName') {\n apiSortField = groupBy;\n } else {\n apiSortField = deltaParam;\n }\n queryParams[`order_by[${apiSortField}]`] = sortDirection;\n } else {\n queryParams[`order_by[${deltaParam}]`] = 'desc';\n }\n\n return queryParams;\n}\n\n/** @public */\nexport function OpenShiftPage() {\n const api = useApi(costManagementSlimApiRef);\n const [groupBy, setGroupBy] = useState('project');\n const [overheadDistribution, setOverheadDistribution] =\n useState('distribute');\n const [timeRange, setTimeRange] = useState('month-to-date');\n const [currency, setCurrency] = useState('USD');\n const [filterBy, setFilterBy] = useState('project');\n const [filterOperation, setFilterOperation] = useState('includes');\n const [filterValue, setFilterValue] = useState('');\n const [showPlatformSum, setShowPlatformSum] = useState(false);\n const [selectedRows, setSelectedRows] = useState<Set<string>>(new Set());\n const [currentPage, setCurrentPage] = useState(0);\n const [pageSize, setPageSize] = useState(5);\n const [sortField, setSortField] = useState<string | null>(null);\n const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');\n const [tags, setTags] = useState<string[]>([]);\n const [selectedTag, setSelectedTag] = useState<string>('');\n const [selectedTagKey, setSelectedTagKey] = useState<string>('');\n const [selectedTagValue, setSelectedTagValue] = useState<string>('');\n const [showMonthOverMonthChange, setShowMonthOverMonthChange] =\n useState(true);\n const [showInfrastructureCost, setShowInfrastructureCost] = useState(false);\n const [showSupplementaryCost, setShowSupplementaryCost] = useState(false);\n const [isDownloading, setIsDownloading] = useState(false);\n const theme = useTheme();\n const isDarkMode = (theme.palette as any).mode === 'dark';\n\n // Ref to store display data for use in download handlers\n const displayDataRef = useRef<typeof displayData | null>(null);\n\n // Fetch tags on first load\n useAsync(async () => {\n try {\n const timeScopeValue = timeRange === 'month-to-date' ? -1 : -2;\n const response = await api.getOpenShiftTags(timeScopeValue);\n const tagsData = await response.json();\n setTags(tagsData.data || []);\n } catch {\n // Silently fail if tags can't be loaded\n setTags([]);\n }\n }, [api, timeRange]);\n\n // Build config object for query params builder (memoized to prevent unnecessary re-renders)\n const queryParamsConfig: QueryParamsConfig = useMemo(\n () => ({\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n }),\n [\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n ],\n );\n\n const {\n value: costData,\n loading,\n error,\n } = useAsync(async () => {\n // Don't make API call if groupBy is 'tag' but no tag is selected\n if (groupBy === 'tag' && !selectedTag) {\n return null;\n }\n\n const offset = currentPage * pageSize;\n const queryParams = buildCostManagementQueryParams(queryParamsConfig, {\n limit: pageSize,\n offset,\n });\n\n const response = await api.getCostManagementReport({\n query: queryParams,\n });\n return response.json();\n }, [\n currency,\n overheadDistribution,\n timeRange,\n groupBy,\n filterBy,\n filterValue,\n filterOperation,\n showPlatformSum,\n api,\n currentPage,\n pageSize,\n sortField,\n sortDirection,\n selectedTag,\n selectedTagKey,\n selectedTagValue,\n ]);\n\n const displayData = useMemo(() => {\n // If costData is null, return empty structure to keep table visible during loading\n if (!costData) {\n const today = new Date();\n const month =\n timeRange === 'previous-month'\n ? new Date(\n today.getFullYear(),\n today.getMonth() - 1,\n 1,\n ).toLocaleString('en-US', { month: 'long' })\n : today.toLocaleString('en-US', { month: 'long' });\n const endDate =\n timeRange === 'previous-month'\n ? new Date(today.getFullYear(), today.getMonth(), 0)\n .getDate()\n .toString()\n : today.getDate().toString();\n\n return {\n totalCost: 0,\n month,\n endDate,\n currencyCode: currency,\n projects: [],\n };\n }\n\n const arrayKey = `${groupBy}s` as keyof (typeof costData.data)[0];\n const groupedArray = costData.data?.[0]?.[arrayKey] as\n | Array<{ [key: string]: unknown; values: unknown[] }>\n | undefined;\n\n const projects =\n groupedArray?.map((item, index) => {\n const value =\n (item.values?.[0] as {\n cost?: {\n distributed?: { value?: number };\n total?: { value?: number };\n network_unattributed_distributed?: { value?: number };\n worker_unallocated_distributed?: { value?: number };\n platform_distributed?: { value?: number };\n storage_unattributed_distributed?: { value?: number };\n };\n infrastructure?: {\n total?: { value?: number };\n };\n supplementary?: {\n total?: { value?: number };\n };\n delta_percent?: number;\n delta_value?: number;\n }) || {};\n\n // For clusters, prefer values[0].clusters[0] (human-readable) over item.cluster (UUID)\n let itemName: string;\n let clusterId: string | undefined;\n if (groupBy === 'cluster') {\n const valueItem = item.values?.[0] as\n | { clusters?: string[]; cluster?: string }\n | undefined;\n const clustersArray = valueItem?.clusters;\n itemName =\n clustersArray && clustersArray.length > 0\n ? clustersArray[0]\n : (item.cluster as string) || 'Unknown';\n // Store the cluster UUID for display\n clusterId = (item.cluster as string) || undefined;\n } else {\n const nameField = groupBy as keyof typeof item;\n itemName = (item[nameField] as string) || 'Unknown';\n }\n\n const costField =\n groupBy === 'project' && overheadDistribution === 'distribute'\n ? 'distributed'\n : 'total';\n const costValue =\n value?.cost?.[costField as keyof typeof value.cost]?.value || 0;\n\n const deltaPercent = value?.delta_percent || 0;\n const deltaValue = value?.delta_value || 0;\n\n const infrastructureValue = value?.infrastructure?.total?.value || 0;\n const supplementaryValue = value?.supplementary?.total?.value || 0;\n\n return {\n id: `${index}`,\n projectName: itemName,\n clusterId,\n cost: costValue,\n costPercentage: 0,\n monthOverMonthChange: deltaPercent,\n monthOverMonthValue: Math.abs(deltaValue),\n includesOverhead:\n value?.cost?.network_unattributed_distributed?.value !== 0 ||\n value?.cost?.worker_unallocated_distributed?.value !== 0 ||\n value?.cost?.platform_distributed?.value !== 0 ||\n value?.cost?.storage_unattributed_distributed?.value !== 0,\n previousPeriodCost: costValue + Math.abs(deltaValue),\n infrastructureCost: infrastructureValue,\n infrastructureCostPercentage: 0,\n supplementaryCost: supplementaryValue,\n supplementaryCostPercentage: 0,\n };\n }) || [];\n\n const totalCost = costData.meta?.total?.cost?.total?.value || 0;\n const totalInfrastructureCost =\n costData.meta?.total?.infrastructure?.total?.value || 0;\n const totalSupplementaryCost =\n costData.meta?.total?.supplementary?.total?.value || 0;\n\n const currencyCode = costData.meta?.currency || currency;\n\n const projectsWithPercentage = projects.map(p => ({\n ...p,\n costPercentage: totalCost > 0 ? (p.cost / totalCost) * 100 : 0,\n infrastructureCostPercentage:\n totalInfrastructureCost > 0\n ? (p.infrastructureCost / totalInfrastructureCost) * 100\n : 0,\n supplementaryCostPercentage:\n totalSupplementaryCost > 0\n ? (p.supplementaryCost / totalSupplementaryCost) * 100\n : 0,\n }));\n\n let month: string;\n let endDate: string;\n\n if (timeRange === 'previous-month') {\n const today = new Date();\n const previousMonth = new Date(\n today.getFullYear(),\n today.getMonth() - 1,\n 1,\n );\n month = previousMonth.toLocaleString('en-US', { month: 'long' });\n const lastDayOfPreviousMonth = new Date(\n today.getFullYear(),\n today.getMonth(),\n 0,\n ).getDate();\n endDate = lastDayOfPreviousMonth.toString();\n } else {\n const today = new Date();\n month = today.toLocaleString('en-US', { month: 'long' });\n endDate = today.getDate().toString();\n }\n\n return {\n totalCost,\n month,\n endDate,\n currencyCode,\n projects: projectsWithPercentage,\n };\n }, [costData, currency, groupBy, overheadDistribution, timeRange]);\n\n // Update ref when displayData changes\n displayDataRef.current = displayData;\n\n /**\n * Builds query parameters for download request\n * @param specificItemName - Optional: specific item name to filter by (for row-level download)\n */\n const buildDownloadQueryParams = useCallback(\n (specificItemName?: string): Record<string, string | number> => {\n return buildCostManagementQueryParams(queryParamsConfig, {\n specificItemName,\n });\n },\n [queryParamsConfig],\n );\n\n /**\n * Handles download for header buttons (all data based on current filters)\n */\n const handleHeaderDownload = useCallback(\n async (format: ExportFormat) => {\n if (isDownloading) return;\n\n setIsDownloading(true);\n try {\n const queryParams = buildDownloadQueryParams();\n await api.downloadCostManagementReport({\n query: queryParams,\n format,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`Failed to download ${format}:`, err);\n } finally {\n setIsDownloading(false);\n }\n },\n [api, buildDownloadQueryParams, isDownloading],\n );\n\n /**\n * Handles download for row-level buttons (specific item)\n */\n const handleRowDownload = useCallback(\n async (itemName: string, format: ExportFormat) => {\n if (isDownloading) return;\n\n setIsDownloading(true);\n try {\n const queryParams = buildDownloadQueryParams(itemName);\n await api.downloadCostManagementReport({\n query: queryParams,\n format,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`Failed to download ${format} for ${itemName}:`, err);\n } finally {\n setIsDownloading(false);\n }\n },\n [api, buildDownloadQueryParams, isDownloading],\n );\n\n const handleRowSelect = useCallback(\n (rowId: string, isSelected: boolean) => {\n const newSelectedRows = new Set(selectedRows);\n if (isSelected) {\n newSelectedRows.add(rowId);\n } else {\n newSelectedRows.delete(rowId);\n }\n setSelectedRows(newSelectedRows);\n },\n [selectedRows],\n );\n\n const handleSelectAll = useCallback(\n (isSelected: boolean) => {\n if (isSelected && displayData) {\n setSelectedRows(\n new Set(displayData.projects.map(project => project.id)),\n );\n } else {\n setSelectedRows(new Set());\n }\n },\n [displayData],\n );\n\n const handlePageChange = useCallback((page: number, newPageSize: number) => {\n setCurrentPage(page);\n setPageSize(newPageSize);\n }, []);\n\n const handleRowsPerPageChange = useCallback((newPageSize: number) => {\n setPageSize(newPageSize);\n setCurrentPage(0);\n }, []);\n\n const totalCount = costData?.meta?.count || 0;\n\n const isAllSelected =\n displayData !== null &&\n selectedRows.size === displayData.projects.length &&\n displayData.projects.length > 0;\n const isIndeterminate =\n displayData !== null &&\n selectedRows.size > 0 &&\n selectedRows.size < displayData.projects.length;\n\n const columns = useMemo<TableColumn<ProjectCost>[]>(() => {\n const getChangeColor = (change: number) => {\n if (change < 0) return '#d32f2f';\n if (isDarkMode) return '#4BB543';\n return '#2e7d32';\n };\n\n const cols: TableColumn<ProjectCost>[] = [\n {\n title: (\n <div style={{ marginLeft: 0, paddingLeft: 0 }}>\n <input\n type=\"checkbox\"\n checked={isAllSelected}\n ref={input => {\n if (input) input.indeterminate = isIndeterminate;\n }}\n onChange={e => {\n e.stopPropagation();\n handleSelectAll(e.target.checked);\n }}\n style={{\n width: '18px',\n height: '18px',\n cursor: 'pointer',\n margin: 0,\n padding: 0,\n }}\n />\n </div>\n ),\n field: 'checkbox',\n sorting: false,\n width: '40px',\n cellStyle: {\n paddingLeft: '4px',\n paddingRight: '4px',\n },\n headerStyle: {\n paddingLeft: '4px',\n paddingRight: '4px',\n },\n render: data => (\n <div style={{ paddingRight: '4px' }}>\n <input\n type=\"checkbox\"\n checked={selectedRows.has(data.id)}\n onChange={e => handleRowSelect(data.id, e.target.checked)}\n style={{\n width: '18px',\n height: '18px',\n cursor: 'pointer',\n margin: 0,\n padding: 0,\n }}\n />\n </div>\n ),\n },\n {\n title: (\n <Typography variant=\"body2\" style={{ fontWeight: 'bold' }}>\n {groupBy.charAt(0).toLocaleUpperCase('en-US') + groupBy.slice(1)}{' '}\n name\n </Typography>\n ),\n field: 'projectName',\n cellStyle: { minWidth: 350 },\n headerStyle: { minWidth: 350 },\n render: data => (\n <div>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '8px',\n }}\n >\n <Typography variant=\"body2\">{data.projectName}</Typography>\n {groupBy === 'project' && data.includesOverhead && (\n <Typography\n variant=\"caption\"\n style={{\n padding: '2px 6px',\n backgroundColor: '#F5F5F5',\n border: '1px solid #D2D2D2',\n borderRadius: '16px',\n color: 'black',\n whiteSpace: 'nowrap',\n }}\n >\n Includes overhead\n </Typography>\n )}\n </div>\n {groupBy === 'cluster' && data.clusterId && (\n <Typography\n variant=\"caption\"\n style={{ color: '#666', display: 'block', marginTop: 10 }}\n >\n {data.clusterId}\n </Typography>\n )}\n </div>\n ),\n },\n ];\n\n if (showMonthOverMonthChange) {\n cols.push({\n title: 'Month over month change',\n field: 'monthOverMonthChange',\n sorting: false,\n render: data => (\n <div>\n <div\n style={{\n color: getChangeColor(data.monthOverMonthChange),\n }}\n >\n {Math.abs(data.monthOverMonthChange).toFixed(2)}%\n {data.monthOverMonthChange > 0 ? ' ▲' : ' ▼'}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {formatCurrency(\n data.monthOverMonthValue,\n displayData?.currencyCode || '',\n )}{' '}\n for {getDateRangeText(timeRange)}\n </div>\n </div>\n ),\n });\n }\n\n cols.push({\n title: 'Cost',\n field: 'cost',\n render: data => (\n <div>\n <div>\n {formatCurrency(data.cost, displayData?.currencyCode || '')}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.costPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n\n if (showInfrastructureCost) {\n cols.push({\n title: 'Infrastructure cost',\n field: 'infrastructureCost',\n render: data => (\n <div>\n <div>\n {formatCurrency(\n data.infrastructureCost,\n displayData?.currencyCode || '',\n )}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.infrastructureCostPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n }\n\n if (showSupplementaryCost) {\n cols.push({\n title: 'Supplementary cost',\n field: 'supplementaryCost',\n render: data => (\n <div>\n <div>\n {formatCurrency(\n data.supplementaryCost,\n displayData?.currencyCode || '',\n )}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.supplementaryCostPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n }\n\n cols.push({\n title: 'Actions',\n field: 'actions',\n sorting: false,\n render: data => (\n <div style={{ display: 'flex', gap: '8px' }}>\n <DownloadIconButton\n label=\"CSV\"\n variant={isDarkMode ? 'white' : 'black'}\n onClick={() => handleRowDownload(data.projectName, 'csv')}\n disabled={isDownloading}\n />\n <DownloadIconButton\n label=\"JSON\"\n variant={isDarkMode ? 'white' : 'black'}\n onClick={() => handleRowDownload(data.projectName, 'json')}\n disabled={isDownloading}\n />\n </div>\n ),\n });\n\n return cols;\n }, [\n handleRowSelect,\n handleRowDownload,\n isAllSelected,\n isIndeterminate,\n isDownloading,\n selectedRows,\n handleSelectAll,\n displayData?.currencyCode,\n groupBy,\n showMonthOverMonthChange,\n showInfrastructureCost,\n showSupplementaryCost,\n timeRange,\n isDarkMode,\n ]);\n\n const handleOrderChange = useCallback(\n (orderBy: number, orderDirection: 'asc' | 'desc') => {\n // If orderBy is -1, it means \"no sorting\" - ignore it to prevent removing sorting\n if (orderBy === -1) {\n return;\n }\n\n const column = columns[orderBy];\n if (\n column?.field &&\n column.field !== 'actions' &&\n column.sorting !== false\n ) {\n const newField = column.field as string;\n setSortField(newField);\n setSortDirection(orderDirection);\n\n setCurrentPage(0);\n }\n },\n [columns],\n );\n\n if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <BasePage pageTitle=\"\" withContentPadding>\n <PageHeader\n totalCost={displayData.totalCost}\n month={displayData.month}\n endDate={displayData.endDate}\n currencyCode={displayData.currencyCode}\n customStyle={{ marginTop: '-24px' }}\n />\n\n <Divider\n style={{\n marginBottom: 24,\n marginLeft: '-24px',\n marginRight: '-24px',\n width: 'calc(100% + 48px)',\n }}\n />\n\n <PageLayout>\n <PageLayout.Filters>\n <Filters\n groupBy={groupBy}\n overheadDistribution={overheadDistribution}\n timeRange={timeRange}\n currency={currency}\n filterBy={filterBy}\n filterOperation={filterOperation}\n filterValue={filterValue}\n tags={tags}\n onGroupByChange={value => {\n setGroupBy(value);\n setCurrentPage(0);\n if (value !== 'tag') {\n setSelectedTag('');\n }\n // Reset showPlatformSum when groupBy changes away from 'project'\n if (value !== 'project') {\n setShowPlatformSum(false);\n }\n // Sync filterBy with groupBy and reset filter value\n setFilterBy(value);\n setFilterValue('');\n // Reset tag-related filter fields\n setSelectedTagKey('');\n setSelectedTagValue('');\n }}\n selectedTag={selectedTag}\n onSelectedTagChange={value => {\n setSelectedTag(value);\n setCurrentPage(0);\n }}\n onOverheadDistributionChange={value => {\n setOverheadDistribution(value);\n setCurrentPage(0);\n }}\n onTimeRangeChange={value => {\n setTimeRange(value);\n setCurrentPage(0);\n }}\n onCurrencyChange={value => {\n setCurrency(value);\n setCurrentPage(0);\n }}\n onFilterByChange={value => {\n setFilterBy(value);\n setCurrentPage(0);\n // Clear tag-related selections when filterBy changes away from 'tag'\n if (value !== 'tag') {\n setSelectedTagKey('');\n setSelectedTagValue('');\n }\n }}\n onFilterOperationChange={value => {\n setFilterOperation(value);\n setCurrentPage(0);\n }}\n onFilterValueChange={value => {\n setFilterValue(value);\n setCurrentPage(0);\n }}\n selectedTagKey={selectedTagKey}\n selectedTagValue={selectedTagValue}\n onSelectedTagKeyChange={value => {\n setSelectedTagKey(value);\n setSelectedTagValue('');\n setCurrentPage(0);\n }}\n onSelectedTagValueChange={value => {\n setSelectedTagValue(value);\n setCurrentPage(0);\n }}\n />\n </PageLayout.Filters>\n <PageLayout.Table>\n <div style={{ flex: 1 }}>\n <InfoCard>\n <Table<ProjectCost>\n data={displayData?.projects || []}\n isLoading={loading}\n components={{\n Toolbar: () => (\n <TableToolbar\n showPlatformSum={showPlatformSum}\n setShowPlatformSum={setShowPlatformSum}\n projectsCount={displayData?.projects?.length || 0}\n groupBy={groupBy}\n showMonthOverMonthChange={showMonthOverMonthChange}\n setShowMonthOverMonthChange={setShowMonthOverMonthChange}\n showInfrastructureCost={showInfrastructureCost}\n setShowInfrastructureCost={setShowInfrastructureCost}\n showSupplementaryCost={showSupplementaryCost}\n setShowSupplementaryCost={setShowSupplementaryCost}\n onDownloadCsv={() => handleHeaderDownload('csv')}\n onDownloadJson={() => handleHeaderDownload('json')}\n isDownloading={isDownloading}\n />\n ),\n }}\n columns={columns}\n options={{\n paging: true,\n pageSize: pageSize,\n pageSizeOptions: [5, 10, 25, 50],\n search: false,\n sorting: true,\n padding: 'dense',\n thirdSortClick: false,\n }}\n totalCount={totalCount}\n page={currentPage}\n onPageChange={handlePageChange}\n onRowsPerPageChange={handleRowsPerPageChange}\n onOrderChange={handleOrderChange}\n style={{ outline: 'none' }}\n localization={{\n pagination: {\n labelRowsPerPage: 'rows',\n },\n }}\n />\n </InfoCard>\n </div>\n </PageLayout.Table>\n </PageLayout>\n </BasePage>\n );\n}\nOpenShiftPage.displayName = 'OpenShiftPage';\n"],"names":["monthName","month","endDate"],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ import { makeStyles } from '@material-ui/core/styles';
3
+ import Box from '@material-ui/core/Box';
4
+ import TextField from '@material-ui/core/TextField';
5
+ import Typography from '@material-ui/core/Typography';
6
+ import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
7
+ import { Autocomplete } from '@material-ui/lab';
8
+ import { useThemeBackgroundColor } from '../../../hooks/useThemeBackgroundColor.esm.js';
9
+
10
+ const useAutocompleteStyles = makeStyles(
11
+ {
12
+ root: {},
13
+ label: {},
14
+ input: { backgroundColor: "transparent" },
15
+ fullWidth: { width: "100%" }
16
+ },
17
+ { name: "AutocompleteComponent" }
18
+ );
19
+ function AutocompleteComponent(props) {
20
+ const classes = useAutocompleteStyles();
21
+ const { label, options, placeholder, className } = props;
22
+ const { backgroundColor } = useThemeBackgroundColor();
23
+ return /* @__PURE__ */ React.createElement(Box, { className: className ?? classes.root, pb: 1, pt: 1 }, /* @__PURE__ */ React.createElement(
24
+ Typography,
25
+ {
26
+ className: classes.label,
27
+ variant: "button",
28
+ component: "label",
29
+ style: { textTransform: "none" }
30
+ },
31
+ label
32
+ ), /* @__PURE__ */ React.createElement(
33
+ Autocomplete,
34
+ {
35
+ options,
36
+ multiple: Boolean(props.multiple),
37
+ value: props.value ?? (Boolean(props.multiple) ? [] : null),
38
+ onChange: (event, value, reason, details) => {
39
+ if (props.onChange) {
40
+ props.onChange(event, value, reason, details);
41
+ }
42
+ },
43
+ onInputChange: (event, value, reason) => {
44
+ if (props.onInputChange) {
45
+ props.onInputChange(event, value, reason);
46
+ }
47
+ },
48
+ loading: props.loading ?? false,
49
+ popupIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, { "data-testid": "expand-icon" }),
50
+ renderInput: (params) => /* @__PURE__ */ React.createElement(
51
+ TextField,
52
+ {
53
+ ...params,
54
+ variant: "outlined",
55
+ placeholder,
56
+ style: { backgroundColor }
57
+ }
58
+ ),
59
+ size: "medium"
60
+ }
61
+ ));
62
+ }
63
+
64
+ export { AutocompleteComponent };
65
+ //# sourceMappingURL=AutocompleteComponent.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutocompleteComponent.esm.js","sources":["../../../../src/pages/openshift/components/AutocompleteComponent.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 { makeStyles } from '@material-ui/core/styles';\nimport Box from '@material-ui/core/Box';\nimport TextField from '@material-ui/core/TextField';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport {\n Autocomplete,\n AutocompleteChangeDetails,\n AutocompleteChangeReason,\n} from '@material-ui/lab';\nimport { useThemeBackgroundColor } from '../../../hooks/useThemeBackgroundColor';\n\nconst useAutocompleteStyles = makeStyles(\n {\n root: {},\n label: {},\n input: { backgroundColor: 'transparent' },\n fullWidth: { width: '100%' },\n },\n { name: 'AutocompleteComponent' },\n);\n\ntype BaseProps = {\n label: string;\n options: string[];\n placeholder?: string;\n className?: string;\n};\n\ntype SingleProps = BaseProps & {\n multiple?: false;\n value?: string;\n onChange?: (\n event: React.ChangeEvent<{}>,\n value: string | null,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<string> | undefined,\n ) => void;\n onInputChange?: (\n event: React.ChangeEvent<{}>,\n value: string,\n reason: string,\n ) => void;\n loading?: boolean;\n};\n\ntype MultipleProps = BaseProps & {\n multiple: true;\n value?: string[];\n onChange?: (\n event: React.ChangeEvent<{}>,\n value: string[],\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<string> | undefined,\n ) => void;\n};\n\ntype AutocompleteComponentProps = SingleProps | MultipleProps;\n\n/** @public */\nexport function AutocompleteComponent(props: AutocompleteComponentProps) {\n const classes = useAutocompleteStyles();\n const { label, options, placeholder, className } = props;\n const { backgroundColor } = useThemeBackgroundColor();\n\n return (\n <Box className={className ?? classes.root} pb={1} pt={1}>\n <Typography\n className={classes.label}\n variant=\"button\"\n component=\"label\"\n style={{ textTransform: 'none' }}\n >\n {label}\n </Typography>\n <Autocomplete\n options={options}\n multiple={Boolean((props as MultipleProps).multiple)}\n value={\n (props as any).value ??\n (Boolean((props as MultipleProps).multiple) ? [] : null)\n }\n onChange={(event, value, reason, details) => {\n if (props.onChange) {\n // Cast is safe because the callback shape matches the multiple flag\n (props.onChange as any)(event, value, reason, details);\n }\n }}\n onInputChange={(event, value, reason) => {\n if ((props as SingleProps).onInputChange) {\n (props as SingleProps).onInputChange!(event, value, reason);\n }\n }}\n loading={(props as SingleProps).loading ?? false}\n popupIcon={<ExpandMoreIcon data-testid=\"expand-icon\" />}\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n placeholder={placeholder}\n style={{ backgroundColor }}\n />\n )}\n size=\"medium\"\n />\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AA6BA,MAAM,qBAAwB,GAAA,UAAA;AAAA,EAC5B;AAAA,IACE,MAAM,EAAC;AAAA,IACP,OAAO,EAAC;AAAA,IACR,KAAA,EAAO,EAAE,eAAA,EAAiB,aAAc,EAAA;AAAA,IACxC,SAAA,EAAW,EAAE,KAAA,EAAO,MAAO;AAAA,GAC7B;AAAA,EACA,EAAE,MAAM,uBAAwB;AAClC,CAAA;AAwCO,SAAS,sBAAsB,KAAmC,EAAA;AACvE,EAAA,MAAM,UAAU,qBAAsB,EAAA;AACtC,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,WAAA,EAAa,WAAc,GAAA,KAAA;AACnD,EAAM,MAAA,EAAE,eAAgB,EAAA,GAAI,uBAAwB,EAAA;AAEpD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,SAAW,EAAA,SAAA,IAAa,QAAQ,IAAM,EAAA,EAAA,EAAI,CAAG,EAAA,EAAA,EAAI,CACpD,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAQ,CAAA,KAAA;AAAA,MACnB,OAAQ,EAAA,QAAA;AAAA,MACR,SAAU,EAAA,OAAA;AAAA,MACV,KAAA,EAAO,EAAE,aAAA,EAAe,MAAO;AAAA,KAAA;AAAA,IAE9B;AAAA,GAEH,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,QAAA,EAAU,OAAS,CAAA,KAAA,CAAwB,QAAQ,CAAA;AAAA,MACnD,KAAA,EACG,MAAc,KACd,KAAA,OAAA,CAAS,MAAwB,QAAQ,CAAA,GAAI,EAAK,GAAA,IAAA,CAAA;AAAA,MAErD,QAAU,EAAA,CAAC,KAAO,EAAA,KAAA,EAAO,QAAQ,OAAY,KAAA;AAC3C,QAAA,IAAI,MAAM,QAAU,EAAA;AAElB,UAAC,KAAM,CAAA,QAAA,CAAiB,KAAO,EAAA,KAAA,EAAO,QAAQ,OAAO,CAAA;AAAA;AACvD,OACF;AAAA,MACA,aAAe,EAAA,CAAC,KAAO,EAAA,KAAA,EAAO,MAAW,KAAA;AACvC,QAAA,IAAK,MAAsB,aAAe,EAAA;AACxC,UAAC,KAAsB,CAAA,aAAA,CAAe,KAAO,EAAA,KAAA,EAAO,MAAM,CAAA;AAAA;AAC5D,OACF;AAAA,MACA,OAAA,EAAU,MAAsB,OAAW,IAAA,KAAA;AAAA,MAC3C,SAAW,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAe,EAAA,EAAA,aAAA,EAAY,aAAc,EAAA,CAAA;AAAA,MACrD,aAAa,CACX,MAAA,qBAAA,KAAA,CAAA,aAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UACE,GAAG,MAAA;AAAA,UACJ,OAAQ,EAAA,UAAA;AAAA,UACR,WAAA;AAAA,UACA,KAAA,EAAO,EAAE,eAAgB;AAAA;AAAA,OAC3B;AAAA,MAEF,IAAK,EAAA;AAAA;AAAA,GAET,CAAA;AAEJ;;;;"}
@@ -0,0 +1,49 @@
1
+ import Typography from '@material-ui/core/Typography';
2
+ import React from 'react';
3
+
4
+ const getColor = (variant, disabled) => {
5
+ if (disabled) return "#999999";
6
+ if (variant === "gray") return "#C7C7C7";
7
+ if (variant === "black") return "#000000";
8
+ if (variant === "white") return "#FFFFFF";
9
+ return "#C7C7C7";
10
+ };
11
+ function DownloadIconButton(props) {
12
+ const { label, variant, onClick, disabled } = props;
13
+ const color = getColor(variant, disabled);
14
+ return /* @__PURE__ */ React.createElement(
15
+ "div",
16
+ {
17
+ role: "button",
18
+ tabIndex: disabled ? -1 : 0,
19
+ onClick: disabled ? void 0 : onClick,
20
+ onKeyDown: disabled ? void 0 : (e) => {
21
+ if (e.key === "Enter" || e.key === " ") {
22
+ e.preventDefault();
23
+ onClick?.();
24
+ }
25
+ },
26
+ style: {
27
+ border: `2px solid ${color}`,
28
+ borderRadius: 2,
29
+ display: "flex",
30
+ alignItems: "center",
31
+ justifyContent: "center",
32
+ cursor: disabled ? "not-allowed" : "pointer",
33
+ paddingTop: 2,
34
+ opacity: disabled ? 0.6 : 1
35
+ }
36
+ },
37
+ /* @__PURE__ */ React.createElement(
38
+ Typography,
39
+ {
40
+ variant: "body2",
41
+ style: { color, fontSize: 9, fontWeight: "bold" }
42
+ },
43
+ label
44
+ )
45
+ );
46
+ }
47
+
48
+ export { DownloadIconButton };
49
+ //# sourceMappingURL=DownloadIconButton.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DownloadIconButton.esm.js","sources":["../../../../src/pages/openshift/components/DownloadIconButton.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 Typography from '@material-ui/core/Typography';\nimport React from 'react';\n\ntype DownloadIconButtonProps = {\n label: string;\n variant: 'gray' | 'black' | 'white';\n onClick?: () => void;\n disabled?: boolean;\n};\n\nconst getColor = (variant: 'gray' | 'black' | 'white', disabled?: boolean) => {\n if (disabled) return '#999999';\n if (variant === 'gray') return '#C7C7C7';\n if (variant === 'black') return '#000000';\n if (variant === 'white') return '#FFFFFF';\n return '#C7C7C7';\n};\n\nexport function DownloadIconButton(props: Readonly<DownloadIconButtonProps>) {\n const { label, variant, onClick, disabled } = props;\n const color = getColor(variant, disabled);\n\n return (\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onClick={disabled ? undefined : onClick}\n onKeyDown={\n disabled\n ? undefined\n : e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick?.();\n }\n }\n }\n style={{\n border: `2px solid ${color}`,\n borderRadius: 2,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: disabled ? 'not-allowed' : 'pointer',\n paddingTop: 2,\n opacity: disabled ? 0.6 : 1,\n }}\n >\n <Typography\n variant=\"body2\"\n style={{ color, fontSize: 9, fontWeight: 'bold' }}\n >\n {label}\n </Typography>\n </div>\n );\n}\n"],"names":[],"mappings":";;;AA0BA,MAAM,QAAA,GAAW,CAAC,OAAA,EAAqC,QAAuB,KAAA;AAC5E,EAAA,IAAI,UAAiB,OAAA,SAAA;AACrB,EAAI,IAAA,OAAA,KAAY,QAAe,OAAA,SAAA;AAC/B,EAAI,IAAA,OAAA,KAAY,SAAgB,OAAA,SAAA;AAChC,EAAI,IAAA,OAAA,KAAY,SAAgB,OAAA,SAAA;AAChC,EAAO,OAAA,SAAA;AACT,CAAA;AAEO,SAAS,mBAAmB,KAA0C,EAAA;AAC3E,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,UAAa,GAAA,KAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,QAAS,CAAA,OAAA,EAAS,QAAQ,CAAA;AAExC,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAK,EAAA,QAAA;AAAA,MACL,QAAA,EAAU,WAAW,EAAK,GAAA,CAAA;AAAA,MAC1B,OAAA,EAAS,WAAW,MAAY,GAAA,OAAA;AAAA,MAChC,SAAA,EACE,QACI,GAAA,MAAA,GACA,CAAK,CAAA,KAAA;AACH,QAAA,IAAI,CAAE,CAAA,GAAA,KAAQ,OAAW,IAAA,CAAA,CAAE,QAAQ,GAAK,EAAA;AACtC,UAAA,CAAA,CAAE,cAAe,EAAA;AACjB,UAAU,OAAA,IAAA;AAAA;AACZ,OACF;AAAA,MAEN,KAAO,EAAA;AAAA,QACL,MAAA,EAAQ,aAAa,KAAK,CAAA,CAAA;AAAA,QAC1B,YAAc,EAAA,CAAA;AAAA,QACd,OAAS,EAAA,MAAA;AAAA,QACT,UAAY,EAAA,QAAA;AAAA,QACZ,cAAgB,EAAA,QAAA;AAAA,QAChB,MAAA,EAAQ,WAAW,aAAgB,GAAA,SAAA;AAAA,QACnC,UAAY,EAAA,CAAA;AAAA,QACZ,OAAA,EAAS,WAAW,GAAM,GAAA;AAAA;AAC5B,KAAA;AAAA,oBAEA,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAQ,EAAA,OAAA;AAAA,QACR,OAAO,EAAE,KAAA,EAAO,QAAU,EAAA,CAAA,EAAG,YAAY,MAAO;AAAA,OAAA;AAAA,MAE/C;AAAA;AACH,GACF;AAEJ;;;;"}
@@ -0,0 +1,360 @@
1
+ import React, { useState, useMemo, useEffect, useCallback } from 'react';
2
+ import Box from '@material-ui/core/Box';
3
+ import Divider from '@material-ui/core/Divider';
4
+ import { makeStyles } from '@material-ui/core/styles';
5
+ import { useBaseFiltersStyles } from '../../../components/filtersStyles.esm.js';
6
+ import { SelectComponent } from './SelectComponent.esm.js';
7
+ import { AutocompleteComponent } from './AutocompleteComponent.esm.js';
8
+ import { useApi } from '@backstage/core-plugin-api';
9
+ import { costManagementSlimApiRef } from '../../../apis.esm.js';
10
+ import useAsync from 'react-use/lib/useAsync';
11
+ import debounce from 'lodash/debounce';
12
+ import { useThemeBackgroundColor } from '../../../hooks/useThemeBackgroundColor.esm.js';
13
+
14
+ const useFiltersStyles = makeStyles(
15
+ (theme) => ({
16
+ filters: {
17
+ "& > *": {
18
+ marginTop: theme.spacing(0)
19
+ }
20
+ },
21
+ filterSection: {
22
+ marginBottom: theme.spacing(0)
23
+ },
24
+ divider: {
25
+ margin: theme.spacing(2, 0)
26
+ }
27
+ }),
28
+ { name: "OpenShiftFilters" }
29
+ );
30
+ function Filters(props) {
31
+ const {
32
+ groupBy,
33
+ overheadDistribution,
34
+ timeRange,
35
+ currency,
36
+ filterBy,
37
+ filterOperation,
38
+ filterValue,
39
+ tags = [],
40
+ selectedTag = "",
41
+ selectedTagKey = "",
42
+ selectedTagValue = "",
43
+ onGroupByChange,
44
+ onOverheadDistributionChange,
45
+ onTimeRangeChange,
46
+ onCurrencyChange,
47
+ onFilterByChange,
48
+ onFilterOperationChange,
49
+ onFilterValueChange,
50
+ onSelectedTagChange,
51
+ onSelectedTagKeyChange,
52
+ onSelectedTagValueChange
53
+ } = props;
54
+ const baseClasses = useBaseFiltersStyles();
55
+ const classes = useFiltersStyles();
56
+ const api = useApi(costManagementSlimApiRef);
57
+ const { filterTableBackgroundColor } = useThemeBackgroundColor();
58
+ const [searchInput, setSearchInput] = useState("");
59
+ const [debouncedSearch, setDebouncedSearch] = useState("");
60
+ const debouncedSetSearch = useMemo(
61
+ () => debounce((value) => {
62
+ setDebouncedSearch(value);
63
+ }, 500),
64
+ []
65
+ );
66
+ useEffect(() => {
67
+ debouncedSetSearch(searchInput);
68
+ return () => {
69
+ debouncedSetSearch.cancel();
70
+ };
71
+ }, [searchInput, debouncedSetSearch]);
72
+ useEffect(() => {
73
+ setSearchInput("");
74
+ setDebouncedSearch("");
75
+ }, [filterBy]);
76
+ const { value: resourceOptions, loading: isLoadingOptions } = useAsync(async () => {
77
+ if (filterBy === "tag") {
78
+ if (!debouncedSearch.trim()) {
79
+ return tags;
80
+ }
81
+ const searchLower = debouncedSearch.toLocaleLowerCase("en-US");
82
+ return tags.filter(
83
+ (tag) => tag.toLocaleLowerCase("en-US").includes(searchLower)
84
+ );
85
+ }
86
+ if (!debouncedSearch.trim()) {
87
+ return [];
88
+ }
89
+ try {
90
+ let response;
91
+ switch (filterBy) {
92
+ case "project":
93
+ response = await api.searchOpenShiftProjects(debouncedSearch);
94
+ break;
95
+ case "cluster":
96
+ response = await api.searchOpenShiftClusters(debouncedSearch);
97
+ break;
98
+ case "node":
99
+ response = await api.searchOpenShiftNodes(debouncedSearch);
100
+ break;
101
+ default:
102
+ return [];
103
+ }
104
+ const data = await response.json();
105
+ return (data.data || []).map((item) => item.value);
106
+ } catch {
107
+ return [];
108
+ }
109
+ }, [filterBy, debouncedSearch, api, tags]);
110
+ const { value: tagValuesData, loading: isLoadingTagValues } = useAsync(async () => {
111
+ if (filterBy === "tag" && selectedTagKey) {
112
+ try {
113
+ const timeScopeValue = timeRange === "month-to-date" ? -1 : -2;
114
+ const response = await api.getOpenShiftTagValues(
115
+ selectedTagKey,
116
+ timeScopeValue
117
+ );
118
+ const data = await response.json();
119
+ const allValues = /* @__PURE__ */ new Set();
120
+ for (const item of data.data || []) {
121
+ if (item.values) {
122
+ for (const value of item.values) {
123
+ allValues.add(value);
124
+ }
125
+ }
126
+ }
127
+ return Array.from(allValues).sort(
128
+ (a, b) => a.localeCompare(b, "en-US")
129
+ );
130
+ } catch {
131
+ return [];
132
+ }
133
+ }
134
+ return [];
135
+ }, [filterBy, selectedTagKey, timeRange, api]);
136
+ const getFilterValueOptions = useMemo(() => {
137
+ const options = resourceOptions || [];
138
+ if (filterValue && !options.includes(filterValue)) {
139
+ return [filterValue, ...options];
140
+ }
141
+ return options;
142
+ }, [resourceOptions, filterValue]);
143
+ const handleInputChange = useCallback(
144
+ (_event, value, reason) => {
145
+ if (reason === "input") {
146
+ setSearchInput(value);
147
+ }
148
+ },
149
+ []
150
+ );
151
+ const currencyOptions = [
152
+ { label: "AUD (A$) - Australian Dollar", value: "AUD" },
153
+ { label: "BRL (R$) - Brazilian Real", value: "BRL" },
154
+ { label: "CAD (CA$) - Canadian Dollar", value: "CAD" },
155
+ { label: "CHF (CHF) - Swiss Franc", value: "CHF" },
156
+ { label: "CNY (CN\xA5) - Chinese Yuan", value: "CNY" },
157
+ { label: "CZK (K\u010D) - Czech Koruna", value: "CZK" },
158
+ { label: "DKK (DKK) - Danish Krone", value: "DKK" },
159
+ { label: "EUR (\u20AC) - Euro", value: "EUR" },
160
+ { label: "GBP (\xA3) - British Pound", value: "GBP" },
161
+ { label: "HKD (HK$) - Hong Kong Dollar", value: "HKD" },
162
+ { label: "INR (\u20B9) - Indian Rupee", value: "INR" },
163
+ { label: "JPY (\xA5) - Japanese Yen", value: "JPY" },
164
+ { label: "NGN (\u20A6) - Nigerian Naira", value: "NGN" },
165
+ { label: "NOK (NOK) - Norwegian Krone", value: "NOK" },
166
+ { label: "NZD (NZ$) - New Zealand Dollar", value: "NZD" },
167
+ { label: "SEK (SEK) - Swedish Krona", value: "SEK" },
168
+ { label: "SGD (SGD) - Singapore Dollar", value: "SGD" },
169
+ { label: "USD ($) - United States Dollar", value: "USD" },
170
+ { label: "ZAR (ZAR) - South African Rand", value: "ZAR" }
171
+ ];
172
+ return /* @__PURE__ */ React.createElement(Box, { className: baseClasses.root }, /* @__PURE__ */ React.createElement(Box, { className: `${baseClasses.filters} ${classes.filters}` }, /* @__PURE__ */ React.createElement("div", { className: classes.filterSection }, /* @__PURE__ */ React.createElement(Box, { p: 1, pt: 0 }, /* @__PURE__ */ React.createElement(
173
+ SelectComponent,
174
+ {
175
+ freeSolo: true,
176
+ selectOnFocus: true,
177
+ clearOnBlur: true,
178
+ handleHomeEndKeys: true,
179
+ filterSelectedOptions: true,
180
+ label: "Group by",
181
+ options: ["project", "cluster", "node", "tag"],
182
+ value: groupBy,
183
+ placeholder: "Group by",
184
+ onChange: (event) => onGroupByChange(event.target.value)
185
+ }
186
+ ), groupBy === "tag" && /* @__PURE__ */ React.createElement(Box, { p: 0, pt: 0 }, /* @__PURE__ */ React.createElement(
187
+ AutocompleteComponent,
188
+ {
189
+ label: "Choose key",
190
+ options: tags,
191
+ value: selectedTag,
192
+ placeholder: "Choose key",
193
+ loading: false,
194
+ onChange: (_event, value) => {
195
+ onSelectedTagChange(value ?? "");
196
+ }
197
+ }
198
+ )))), /* @__PURE__ */ React.createElement("div", { className: classes.filterSection }, /* @__PURE__ */ React.createElement(Box, { p: 1 }, /* @__PURE__ */ React.createElement(
199
+ SelectComponent,
200
+ {
201
+ freeSolo: true,
202
+ selectOnFocus: true,
203
+ clearOnBlur: true,
204
+ handleHomeEndKeys: true,
205
+ filterSelectedOptions: true,
206
+ label: "Overhead cost",
207
+ options: [
208
+ "Distribute through cost models",
209
+ "Don't distribute overhead costs"
210
+ ],
211
+ value: overheadDistribution === "distribute" ? "Distribute through cost models" : "Don't distribute overhead costs",
212
+ placeholder: "Overhead cost",
213
+ onChange: (event) => {
214
+ const value = event.target.value;
215
+ const mappedValue = value === "Distribute through cost models" ? "distribute" : "dont_distribute";
216
+ onOverheadDistributionChange(mappedValue);
217
+ }
218
+ }
219
+ ))), /* @__PURE__ */ React.createElement("div", { className: classes.filterSection }, /* @__PURE__ */ React.createElement(Box, { p: 1 }, /* @__PURE__ */ React.createElement(
220
+ SelectComponent,
221
+ {
222
+ freeSolo: true,
223
+ selectOnFocus: true,
224
+ clearOnBlur: true,
225
+ handleHomeEndKeys: true,
226
+ filterSelectedOptions: true,
227
+ label: "Time",
228
+ options: ["Month to date", "Previous month"],
229
+ value: timeRange === "month-to-date" ? "Month to date" : "Previous month",
230
+ placeholder: "Time",
231
+ onChange: (event) => {
232
+ const value = event.target.value;
233
+ const mappedValue = value === "Month to date" ? "month-to-date" : "previous-month";
234
+ onTimeRangeChange(mappedValue);
235
+ }
236
+ }
237
+ ))), /* @__PURE__ */ React.createElement(Box, { marginX: 2 }, /* @__PURE__ */ React.createElement(Divider, { className: classes.divider })), /* @__PURE__ */ React.createElement("div", { className: classes.filterSection }, /* @__PURE__ */ React.createElement(
238
+ "div",
239
+ {
240
+ style: {
241
+ backgroundColor: filterTableBackgroundColor,
242
+ padding: 16,
243
+ borderRadius: 8
244
+ }
245
+ },
246
+ /* @__PURE__ */ React.createElement("div", { style: { fontWeight: "bold", marginBottom: "8px" } }, "Filter table by"),
247
+ /* @__PURE__ */ React.createElement(
248
+ SelectComponent,
249
+ {
250
+ freeSolo: true,
251
+ selectOnFocus: true,
252
+ clearOnBlur: true,
253
+ handleHomeEndKeys: true,
254
+ filterSelectedOptions: true,
255
+ label: "",
256
+ options: ["project", "cluster", "node", "tag"],
257
+ value: filterBy,
258
+ placeholder: "",
259
+ onChange: (event) => {
260
+ const newFilterBy = event.target.value;
261
+ onFilterByChange(newFilterBy);
262
+ onFilterValueChange("");
263
+ if (newFilterBy !== "tag") {
264
+ onSelectedTagKeyChange("");
265
+ onSelectedTagValueChange("");
266
+ }
267
+ }
268
+ }
269
+ ),
270
+ /* @__PURE__ */ React.createElement(
271
+ SelectComponent,
272
+ {
273
+ freeSolo: true,
274
+ selectOnFocus: true,
275
+ clearOnBlur: true,
276
+ handleHomeEndKeys: true,
277
+ filterSelectedOptions: true,
278
+ label: "",
279
+ options: ["includes", "excludes", "exact"],
280
+ value: filterOperation,
281
+ placeholder: "",
282
+ onChange: (event) => {
283
+ onFilterOperationChange(event.target.value);
284
+ }
285
+ }
286
+ ),
287
+ filterBy === "tag" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
288
+ AutocompleteComponent,
289
+ {
290
+ label: "",
291
+ options: getFilterValueOptions,
292
+ value: selectedTagKey,
293
+ placeholder: "Select tag key",
294
+ loading: false,
295
+ onInputChange: handleInputChange,
296
+ onChange: (_event, value) => {
297
+ const tagKey = value ?? "";
298
+ onSelectedTagKeyChange(tagKey);
299
+ onSelectedTagValueChange("");
300
+ setSearchInput("");
301
+ setDebouncedSearch("");
302
+ }
303
+ }
304
+ ), selectedTagKey && /* @__PURE__ */ React.createElement(Box, { style: { marginTop: "-8px" } }, /* @__PURE__ */ React.createElement(
305
+ AutocompleteComponent,
306
+ {
307
+ label: "",
308
+ options: tagValuesData || [],
309
+ value: selectedTagValue,
310
+ placeholder: "Select tag value",
311
+ loading: isLoadingTagValues,
312
+ onChange: (_event, value) => {
313
+ onSelectedTagValueChange(value ?? "");
314
+ }
315
+ }
316
+ ))) : /* @__PURE__ */ React.createElement(
317
+ AutocompleteComponent,
318
+ {
319
+ label: "",
320
+ options: getFilterValueOptions,
321
+ value: filterValue,
322
+ placeholder: `Filter by ${filterBy || "project"}`,
323
+ loading: isLoadingOptions,
324
+ onInputChange: handleInputChange,
325
+ onChange: (_event, value) => {
326
+ onFilterValueChange(value ?? "");
327
+ setSearchInput("");
328
+ setDebouncedSearch("");
329
+ }
330
+ }
331
+ )
332
+ )), /* @__PURE__ */ React.createElement(Box, { marginX: 2 }, /* @__PURE__ */ React.createElement(Divider, { className: classes.divider })), /* @__PURE__ */ React.createElement("div", { className: classes.filterSection }, /* @__PURE__ */ React.createElement(Box, { p: 2 }, /* @__PURE__ */ React.createElement(
333
+ SelectComponent,
334
+ {
335
+ freeSolo: true,
336
+ selectOnFocus: true,
337
+ clearOnBlur: true,
338
+ handleHomeEndKeys: true,
339
+ filterSelectedOptions: true,
340
+ label: "Currency",
341
+ options: currencyOptions.map(
342
+ (value) => value.label
343
+ ),
344
+ value: currencyOptions.find(
345
+ (item) => item.value === currency
346
+ )?.label ?? "",
347
+ placeholder: "Select currency",
348
+ onChange: (event) => {
349
+ const selectedLabel = event.target.value;
350
+ const selectedCurrency = currencyOptions.find(
351
+ (item) => item.label === selectedLabel
352
+ )?.value ?? "";
353
+ onCurrencyChange(selectedCurrency);
354
+ }
355
+ }
356
+ )))));
357
+ }
358
+
359
+ export { Filters };
360
+ //# sourceMappingURL=Filters.esm.js.map