@harnessio/backstage-plugin-harness-ccm 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -5
- package/dist/esm/{OverviewCard-3e34b4e7.esm.js → OverviewCard-e9aad184.esm.js} +2 -2
- package/dist/esm/{OverviewCard-3e34b4e7.esm.js.map → OverviewCard-e9aad184.esm.js.map} +1 -1
- package/dist/esm/{index-38352c6f.esm.js → index-44451033.esm.js} +5 -4
- package/dist/esm/index-44451033.esm.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/dist/esm/index-38352c6f.esm.js.map +0 -1
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ Notes:
|
|
|
45
45
|
|
|
46
46
|
- Set the value of target to your on-prem URL if you are using the Harness on-prem offering
|
|
47
47
|
|
|
48
|
-
3.
|
|
48
|
+
3. In your Backstage `EntityPage.tsx` file, import `EntityCcmContent`, `isHarnessCcmAvailable`, and `EntityCcmOverviewCard` from `@harnessio/backstage-plugin-harness-ccm`:
|
|
49
49
|
|
|
50
50
|
```tsx
|
|
51
51
|
// In packages/app/src/components/catalog/EntityPage.tsx
|
|
@@ -53,17 +53,34 @@ Notes:
|
|
|
53
53
|
import {
|
|
54
54
|
isHarnessCcmAvailable,
|
|
55
55
|
EntityCcmContent,
|
|
56
|
+
EntityCcmOverviewCard,
|
|
56
57
|
} from '@harnessio/backstage-plugin-harness-ccm';
|
|
58
|
+
```
|
|
57
59
|
|
|
60
|
+
#### Add EntityCcmContent
|
|
61
|
+
Use the imported components to add the Harness CCM content to your entity page:
|
|
62
|
+
```tsx
|
|
58
63
|
const ccmContent = (
|
|
59
|
-
// ...
|
|
60
64
|
<EntitySwitch.Case if={isHarnessCcmAvailable}>
|
|
61
|
-
<
|
|
65
|
+
<EntityCcmContent />
|
|
62
66
|
</EntitySwitch.Case>
|
|
63
|
-
// ...
|
|
64
67
|
);
|
|
65
68
|
```
|
|
66
69
|
|
|
70
|
+
#### Add EntityCcmOverviewCard Widget
|
|
71
|
+
Add the EntityCcmOverviewCard to display an overview card:
|
|
72
|
+
```tsx
|
|
73
|
+
const overviewContent = (
|
|
74
|
+
<Grid container spacing={3}>
|
|
75
|
+
<Grid item md={6} xs={12}>
|
|
76
|
+
<EntityCcmOverviewCard variant="gridItem" />
|
|
77
|
+
</Grid>
|
|
78
|
+
</Grid>
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
67
84
|
4. Add required harness specific annotations to your software component's respective `catalog-info.yaml` file.
|
|
68
85
|
|
|
69
86
|
Here is an example: [catalog-info-new.yaml](../../examples/catalog-harness-ccm.yaml)
|
|
@@ -79,6 +96,7 @@ metadata:
|
|
|
79
96
|
|
|
80
97
|
## Features
|
|
81
98
|
|
|
82
|
-
-
|
|
99
|
+
- Link a Backstage service to a Harness Perspective to view resources in ways that better align with your business needs.
|
|
100
|
+
|
|
83
101
|
|
|
84
102
|
|
|
@@ -3,7 +3,7 @@ import { makeStyles, CircularProgress, Typography, Divider } from '@material-ui/
|
|
|
3
3
|
import { InfoCard, EmptyState } from '@backstage/core-components';
|
|
4
4
|
import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalog-react';
|
|
5
5
|
import { useApi, discoveryApiRef, useRouteRef } from '@backstage/core-plugin-api';
|
|
6
|
-
import { r as rootRouteRef, u as usePerspectiveUrlFromEntity, a as useResourceSlugFromEntity, b as useGetPerspective, A as AsyncStatus, D as DEFAULT_GROUP_BY, C as CE_DATE_FORMAT_INTERNAL, c as useFetchPerspectiveDetailsSummaryWithBudget, P as PERSPECTIVE_DETAILS_AGGREGATE, g as getViewFilterForId, d as getTimeFilters, e as getGMTEndDateTime, f as getGMTStartDateTime, h as getGroupByFilter, i as useFetchPerspectiveRecommendations, j as isHarnessCcmAvailable, p as perspectiveDefaultTimeRangeMapper, k as DATE_RANGE_SHORTCUTS } from './index-
|
|
6
|
+
import { r as rootRouteRef, u as usePerspectiveUrlFromEntity, a as useResourceSlugFromEntity, b as useGetPerspective, A as AsyncStatus, D as DEFAULT_GROUP_BY, C as CE_DATE_FORMAT_INTERNAL, c as useFetchPerspectiveDetailsSummaryWithBudget, P as PERSPECTIVE_DETAILS_AGGREGATE, g as getViewFilterForId, d as getTimeFilters, e as getGMTEndDateTime, f as getGMTStartDateTime, h as getGroupByFilter, i as useFetchPerspectiveRecommendations, j as isHarnessCcmAvailable, p as perspectiveDefaultTimeRangeMapper, k as DATE_RANGE_SHORTCUTS } from './index-44451033.esm.js';
|
|
7
7
|
import 'react-router';
|
|
8
8
|
import '@mui/icons-material/Launch';
|
|
9
9
|
import 'path-to-regexp';
|
|
@@ -173,4 +173,4 @@ function OverviewCard(props) {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
export { OverviewCard as default };
|
|
176
|
-
//# sourceMappingURL=OverviewCard-
|
|
176
|
+
//# sourceMappingURL=OverviewCard-e9aad184.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OverviewCard-3e34b4e7.esm.js","sources":["../../src/components/OverviewCard/OverviewCard.tsx"],"sourcesContent":["import React from 'react';\nimport {\n CircularProgress,\n Divider,\n makeStyles,\n Typography,\n} from '@material-ui/core';\nimport {\n InfoCard,\n InfoCardVariants,\n EmptyState,\n} from '@backstage/core-components';\nimport {\n MissingAnnotationEmptyState,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport {\n discoveryApiRef,\n useApi,\n useRouteRef,\n} from '@backstage/core-plugin-api';\n\nimport { isHarnessCcmAvailable } from '../Router';\nimport usePerspectiveUrlFromEntity from '../../hooks/usePerspectiveUrlEntity';\nimport { useResourceSlugFromEntity } from '../../hooks/useResourceSlugFromEntity';\nimport useFetchPerspectiveDetailsSummaryWithBudget from '../../api/useFetchPerspectiveDetailsSummaryWithBudget';\nimport {\n CE_DATE_FORMAT_INTERNAL,\n DATE_RANGE_SHORTCUTS,\n DEFAULT_GROUP_BY,\n getGMTEndDateTime,\n getGMTStartDateTime,\n getGroupByFilter,\n getTimeFilters,\n getViewFilterForId,\n PERSPECTIVE_DETAILS_AGGREGATE,\n perspectiveDefaultTimeRangeMapper,\n} from '../../utils/PerpsectiveUtils';\nimport { rootRouteRef } from '../../routes';\nimport useFetchPerspectiveRecommendations from '../../api/useFetchPerspectiveRecommendations';\nimport { AsyncStatus, K8sRecommendationFilterDtoInput } from '../../api/types';\nimport useGetPerspective from '../../hooks/useGetPerspective';\n\nconst useStyles = makeStyles({\n mainCtn: {\n display: 'flex',\n alignItems: 'center',\n gap: 20,\n minHeight: 157,\n },\n dataCtn: {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-evenly',\n height: '100%',\n },\n emptyState: {\n minHeight: 157,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n\nexport interface OverviewCardProps {\n variant?: InfoCardVariants;\n}\n\nfunction OverviewCard(props: OverviewCardProps) {\n const { variant } = props;\n\n const classes = useStyles();\n\n const { entity } = useEntity();\n const discoveryApi = useApi(discoveryApiRef);\n const backendBaseUrl = discoveryApi.getBaseUrl('proxy');\n const perspectivesPageRoute = useRouteRef(rootRouteRef);\n\n const perspectiveUrl = usePerspectiveUrlFromEntity();\n const {\n accountId,\n envFromUrl = '',\n perspectiveId,\n } = useResourceSlugFromEntity(perspectiveUrl);\n\n const { perspective: perspectiveData, status } = useGetPerspective({\n accountId,\n backendBaseUrl,\n perspectiveId,\n envFromUrl,\n });\n\n const isPerspectiveLoading = status === AsyncStatus.Loading;\n const isPerspectiveReady = !isPerspectiveLoading && perspectiveData;\n\n const groupBy =\n perspectiveData?.viewVisualization?.groupBy || DEFAULT_GROUP_BY;\n\n const viewTimeRangeType = perspectiveData?.viewTimeRange?.viewTimeRangeType;\n\n const dateRange =\n (viewTimeRangeType &&\n perspectiveDefaultTimeRangeMapper[viewTimeRangeType]) ||\n DATE_RANGE_SHORTCUTS.LAST_30_DAYS;\n\n const timeRange = {\n to: dateRange[1].format(CE_DATE_FORMAT_INTERNAL),\n from: dateRange[0].format(CE_DATE_FORMAT_INTERNAL),\n };\n\n const { perspectiveSummary, loading: isSummaryLoading } =\n useFetchPerspectiveDetailsSummaryWithBudget({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n aggregateFunction: PERSPECTIVE_DETAILS_AGGREGATE,\n filters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n groupBy: [getGroupByFilter(groupBy)],\n isClusterHourlyData: false,\n isClusterQuery: false,\n },\n lazy: !isPerspectiveReady,\n });\n\n const { perspectiveRecommendations, loading: areRecommendationsLoading } =\n useFetchPerspectiveRecommendations({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n filter: {\n perspectiveFilters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n minSaving: 1,\n offset: 0,\n limit: 10,\n } as unknown as K8sRecommendationFilterDtoInput,\n },\n lazy: !isPerspectiveReady,\n });\n\n if (!isHarnessCcmAvailable(entity)) {\n return (\n <InfoCard\n title=\"Cloud Cost Management\"\n variant={variant}\n cardClassName={classes.emptyState}\n >\n <MissingAnnotationEmptyState annotation=\"harness.io/perspective-url\" />\n </InfoCard>\n );\n }\n\n if (status === AsyncStatus.Forbidden) {\n return (\n <InfoCard\n title=\"Cloud Cost Management\"\n variant={variant}\n cardClassName={classes.emptyState}\n >\n <EmptyState\n title=\"\"\n missing=\"info\"\n description=\"You don't have access to view this Perspective\"\n />\n </InfoCard>\n );\n }\n\n const isSummaryLoaded = !isSummaryLoading && perspectiveSummary;\n\n if (isPerspectiveLoading || !isSummaryLoaded || areRecommendationsLoading) {\n return (\n <InfoCard\n title=\"Cloud Cost Management\"\n variant={variant}\n cardClassName={classes.emptyState}\n deepLink={{\n title: 'View Perspective',\n link: `${rootRouteRef}`,\n }}\n >\n <CircularProgress />\n </InfoCard>\n );\n }\n\n const totalCostStats = perspectiveSummary?.perspectiveTrendStats?.cost;\n const forecastedCostStats = perspectiveSummary?.perspectiveForecastCost?.cost;\n\n return (\n <InfoCard\n title=\"Cloud Cost Management\"\n variant={variant}\n cardClassName={classes.mainCtn}\n deepLink={{\n title: 'View Perspective',\n link: perspectivesPageRoute(),\n }}\n >\n <div className={classes.dataCtn}>\n <Typography variant=\"subtitle2\">\n {totalCostStats?.statsLabel}\n </Typography>\n <Typography variant=\"h4\">{totalCostStats?.statsValue}</Typography>\n <Typography variant=\"body2\">\n {totalCostStats?.statsDescription}\n </Typography>\n </div>\n <Divider orientation=\"vertical\" />\n <div className={classes.dataCtn}>\n <Typography variant=\"subtitle2\">\n {forecastedCostStats?.statsLabel}\n </Typography>\n <Typography variant=\"h4\">{forecastedCostStats?.statsValue}</Typography>\n <Typography variant=\"body2\">\n {forecastedCostStats?.statsDescription}\n </Typography>\n </div>\n <Divider orientation=\"vertical\" />\n <div className={classes.dataCtn}>\n <Typography variant=\"subtitle2\">Recommendations</Typography>\n <Typography variant=\"caption\">\n {perspectiveRecommendations?.recommendationStatsV2?.count}{' '}\n recommendation(s) saving upto\n </Typography>\n <Typography variant=\"h4\">{`$${perspectiveRecommendations?.recommendationStatsV2?.totalMonthlySaving.toLocaleString()}`}</Typography>\n <Typography variant=\"body2\">per month</Typography>\n </div>\n </InfoCard>\n );\n}\n\nexport default OverviewCard;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OverviewCard-e9aad184.esm.js","sources":["../../src/components/OverviewCard/OverviewCard.tsx"],"sourcesContent":["import React from 'react';\nimport {\n CircularProgress,\n Divider,\n makeStyles,\n Typography,\n} from '@material-ui/core';\nimport {\n InfoCard,\n InfoCardVariants,\n EmptyState,\n} from '@backstage/core-components';\nimport {\n MissingAnnotationEmptyState,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport {\n discoveryApiRef,\n useApi,\n useRouteRef,\n} from '@backstage/core-plugin-api';\n\nimport { isHarnessCcmAvailable } from '../Router';\nimport usePerspectiveUrlFromEntity from '../../hooks/usePerspectiveUrlEntity';\nimport { useResourceSlugFromEntity } from '../../hooks/useResourceSlugFromEntity';\nimport useFetchPerspectiveDetailsSummaryWithBudget from '../../api/useFetchPerspectiveDetailsSummaryWithBudget';\nimport {\n CE_DATE_FORMAT_INTERNAL,\n DATE_RANGE_SHORTCUTS,\n DEFAULT_GROUP_BY,\n getGMTEndDateTime,\n getGMTStartDateTime,\n getGroupByFilter,\n getTimeFilters,\n getViewFilterForId,\n PERSPECTIVE_DETAILS_AGGREGATE,\n perspectiveDefaultTimeRangeMapper,\n} from '../../utils/PerpsectiveUtils';\nimport { rootRouteRef } from '../../routes';\nimport useFetchPerspectiveRecommendations from '../../api/useFetchPerspectiveRecommendations';\nimport { AsyncStatus, K8sRecommendationFilterDtoInput } from '../../api/types';\nimport useGetPerspective from '../../hooks/useGetPerspective';\n\nconst useStyles = makeStyles({\n mainCtn: {\n display: 'flex',\n alignItems: 'center',\n gap: 20,\n minHeight: 157,\n },\n dataCtn: {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-evenly',\n height: '100%',\n },\n emptyState: {\n minHeight: 157,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n\nexport interface OverviewCardProps {\n variant?: InfoCardVariants;\n}\n\nfunction OverviewCard(props: OverviewCardProps) {\n const { variant } = props;\n\n const classes = useStyles();\n\n const { entity } = useEntity();\n const discoveryApi = useApi(discoveryApiRef);\n const backendBaseUrl = discoveryApi.getBaseUrl('proxy');\n const perspectivesPageRoute = useRouteRef(rootRouteRef);\n\n const perspectiveUrl = usePerspectiveUrlFromEntity();\n const {\n accountId,\n envFromUrl = '',\n perspectiveId,\n } = useResourceSlugFromEntity(perspectiveUrl);\n\n const { perspective: perspectiveData, status } = useGetPerspective({\n accountId,\n backendBaseUrl,\n perspectiveId,\n envFromUrl,\n });\n\n const isPerspectiveLoading = status === AsyncStatus.Loading;\n const isPerspectiveReady = !isPerspectiveLoading && perspectiveData;\n\n const groupBy =\n perspectiveData?.viewVisualization?.groupBy || DEFAULT_GROUP_BY;\n\n const viewTimeRangeType = perspectiveData?.viewTimeRange?.viewTimeRangeType;\n\n const dateRange =\n (viewTimeRangeType &&\n perspectiveDefaultTimeRangeMapper[viewTimeRangeType]) ||\n DATE_RANGE_SHORTCUTS.LAST_30_DAYS;\n\n const timeRange = {\n to: dateRange[1].format(CE_DATE_FORMAT_INTERNAL),\n from: dateRange[0].format(CE_DATE_FORMAT_INTERNAL),\n };\n\n const { perspectiveSummary, loading: isSummaryLoading } =\n useFetchPerspectiveDetailsSummaryWithBudget({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n aggregateFunction: PERSPECTIVE_DETAILS_AGGREGATE,\n filters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n groupBy: [getGroupByFilter(groupBy)],\n isClusterHourlyData: false,\n isClusterQuery: false,\n },\n lazy: !isPerspectiveReady,\n });\n\n const { perspectiveRecommendations, loading: areRecommendationsLoading } =\n useFetchPerspectiveRecommendations({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n filter: {\n perspectiveFilters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n minSaving: 1,\n offset: 0,\n limit: 10,\n } as unknown as K8sRecommendationFilterDtoInput,\n },\n lazy: !isPerspectiveReady,\n });\n\n if (!isHarnessCcmAvailable(entity)) {\n return (\n <InfoCard\n title=\"Cloud Cost Management\"\n variant={variant}\n cardClassName={classes.emptyState}\n >\n <MissingAnnotationEmptyState annotation=\"harness.io/perspective-url\" />\n </InfoCard>\n );\n }\n\n if (status === AsyncStatus.Forbidden) {\n return (\n <InfoCard\n title=\"Cloud Cost Management\"\n variant={variant}\n cardClassName={classes.emptyState}\n >\n <EmptyState\n title=\"\"\n missing=\"info\"\n description=\"You don't have access to view this Perspective\"\n />\n </InfoCard>\n );\n }\n\n const isSummaryLoaded = !isSummaryLoading && perspectiveSummary;\n\n if (isPerspectiveLoading || !isSummaryLoaded || areRecommendationsLoading) {\n return (\n <InfoCard\n title=\"Cloud Cost Management\"\n variant={variant}\n cardClassName={classes.emptyState}\n deepLink={{\n title: 'View Perspective',\n link: `${rootRouteRef}`,\n }}\n >\n <CircularProgress />\n </InfoCard>\n );\n }\n\n const totalCostStats = perspectiveSummary?.perspectiveTrendStats?.cost;\n const forecastedCostStats = perspectiveSummary?.perspectiveForecastCost?.cost;\n\n return (\n <InfoCard\n title=\"Cloud Cost Management\"\n variant={variant}\n cardClassName={classes.mainCtn}\n deepLink={{\n title: 'View Perspective',\n link: perspectivesPageRoute(),\n }}\n >\n <div className={classes.dataCtn}>\n <Typography variant=\"subtitle2\">\n {totalCostStats?.statsLabel}\n </Typography>\n <Typography variant=\"h4\">{totalCostStats?.statsValue}</Typography>\n <Typography variant=\"body2\">\n {totalCostStats?.statsDescription}\n </Typography>\n </div>\n <Divider orientation=\"vertical\" />\n <div className={classes.dataCtn}>\n <Typography variant=\"subtitle2\">\n {forecastedCostStats?.statsLabel}\n </Typography>\n <Typography variant=\"h4\">{forecastedCostStats?.statsValue}</Typography>\n <Typography variant=\"body2\">\n {forecastedCostStats?.statsDescription}\n </Typography>\n </div>\n <Divider orientation=\"vertical\" />\n <div className={classes.dataCtn}>\n <Typography variant=\"subtitle2\">Recommendations</Typography>\n <Typography variant=\"caption\">\n {perspectiveRecommendations?.recommendationStatsV2?.count}{' '}\n recommendation(s) saving upto\n </Typography>\n <Typography variant=\"h4\">{`$${perspectiveRecommendations?.recommendationStatsV2?.totalMonthlySaving.toLocaleString()}`}</Typography>\n <Typography variant=\"body2\">per month</Typography>\n </div>\n </InfoCard>\n );\n}\n\nexport default OverviewCard;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AA2CA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,GAAK,EAAA,EAAA;AAAA,IACL,SAAW,EAAA,GAAA;AAAA,GACb;AAAA,EACA,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,MAAA;AAAA,IACT,aAAe,EAAA,QAAA;AAAA,IACf,cAAgB,EAAA,cAAA;AAAA,IAChB,MAAQ,EAAA,MAAA;AAAA,GACV;AAAA,EACA,UAAY,EAAA;AAAA,IACV,SAAW,EAAA,GAAA;AAAA,IACX,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,GAClB;AACF,CAAC,CAAA,CAAA;AAMD,SAAS,aAAa,KAA0B,EAAA;AApEhD,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA;AAqEE,EAAM,MAAA,EAAE,SAAY,GAAA,KAAA,CAAA;AAEpB,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAE1B,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,SAAU,EAAA,CAAA;AAC7B,EAAM,MAAA,YAAA,GAAe,OAAO,eAAe,CAAA,CAAA;AAC3C,EAAM,MAAA,cAAA,GAAiB,YAAa,CAAA,UAAA,CAAW,OAAO,CAAA,CAAA;AACtD,EAAM,MAAA,qBAAA,GAAwB,YAAY,YAAY,CAAA,CAAA;AAEtD,EAAA,MAAM,iBAAiB,2BAA4B,EAAA,CAAA;AACnD,EAAM,MAAA;AAAA,IACJ,SAAA;AAAA,IACA,UAAa,GAAA,EAAA;AAAA,IACb,aAAA;AAAA,GACF,GAAI,0BAA0B,cAAc,CAAA,CAAA;AAE5C,EAAA,MAAM,EAAE,WAAA,EAAa,eAAiB,EAAA,MAAA,KAAW,iBAAkB,CAAA;AAAA,IACjE,SAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA,UAAA;AAAA,GACD,CAAA,CAAA;AAED,EAAM,MAAA,oBAAA,GAAuB,WAAW,WAAY,CAAA,OAAA,CAAA;AACpD,EAAM,MAAA,kBAAA,GAAqB,CAAC,oBAAwB,IAAA,eAAA,CAAA;AAEpD,EAAA,MAAM,OACJ,GAAA,CAAA,CAAA,EAAA,GAAA,eAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,eAAA,CAAiB,iBAAjB,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAoC,OAAW,KAAA,gBAAA,CAAA;AAEjD,EAAM,MAAA,iBAAA,GAAA,CAAoB,EAAiB,GAAA,eAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,eAAA,CAAA,aAAA,KAAjB,IAAgC,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,iBAAA,CAAA;AAE1D,EAAA,MAAM,SACH,GAAA,iBAAA,IACC,iCAAkC,CAAA,iBAAiB,KACrD,oBAAqB,CAAA,YAAA,CAAA;AAEvB,EAAA,MAAM,SAAY,GAAA;AAAA,IAChB,EAAI,EAAA,SAAA,CAAU,CAAC,CAAA,CAAE,OAAO,uBAAuB,CAAA;AAAA,IAC/C,IAAM,EAAA,SAAA,CAAU,CAAC,CAAA,CAAE,OAAO,uBAAuB,CAAA;AAAA,GACnD,CAAA;AAEA,EAAA,MAAM,EAAE,kBAAA,EAAoB,OAAS,EAAA,gBAAA,KACnC,2CAA4C,CAAA;AAAA,IAC1C,SAAA;AAAA,IACA,cAAA;AAAA,IACA,GAAK,EAAA,UAAA;AAAA,IACL,SAAW,EAAA;AAAA,MACT,iBAAmB,EAAA,6BAAA;AAAA,MACnB,OAAS,EAAA;AAAA,QACP,mBAAmB,aAAa,CAAA;AAAA,QAChC,GAAG,cAAA;AAAA,UACD,mBAAA,CAAoB,UAAU,IAAI,CAAA;AAAA,UAClC,iBAAA,CAAkB,UAAU,EAAE,CAAA;AAAA,SAChC;AAAA,OACF;AAAA,MACA,OAAS,EAAA,CAAC,gBAAiB,CAAA,OAAO,CAAC,CAAA;AAAA,MACnC,mBAAqB,EAAA,KAAA;AAAA,MACrB,cAAgB,EAAA,KAAA;AAAA,KAClB;AAAA,IACA,MAAM,CAAC,kBAAA;AAAA,GACR,CAAA,CAAA;AAEH,EAAA,MAAM,EAAE,0BAAA,EAA4B,OAAS,EAAA,yBAAA,KAC3C,kCAAmC,CAAA;AAAA,IACjC,SAAA;AAAA,IACA,cAAA;AAAA,IACA,GAAK,EAAA,UAAA;AAAA,IACL,SAAW,EAAA;AAAA,MACT,MAAQ,EAAA;AAAA,QACN,kBAAoB,EAAA;AAAA,UAClB,mBAAmB,aAAa,CAAA;AAAA,UAChC,GAAG,cAAA;AAAA,YACD,mBAAA,CAAoB,UAAU,IAAI,CAAA;AAAA,YAClC,iBAAA,CAAkB,UAAU,EAAE,CAAA;AAAA,WAChC;AAAA,SACF;AAAA,QACA,SAAW,EAAA,CAAA;AAAA,QACX,MAAQ,EAAA,CAAA;AAAA,QACR,KAAO,EAAA,EAAA;AAAA,OACT;AAAA,KACF;AAAA,IACA,MAAM,CAAC,kBAAA;AAAA,GACR,CAAA,CAAA;AAEH,EAAI,IAAA,CAAC,qBAAsB,CAAA,MAAM,CAAG,EAAA;AAClC,IACE,uBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,KAAM,EAAA,uBAAA;AAAA,QACN,OAAA;AAAA,QACA,eAAe,OAAQ,CAAA,UAAA;AAAA,OAAA;AAAA,sBAEvB,KAAA,CAAA,aAAA,CAAC,2BAA4B,EAAA,EAAA,UAAA,EAAW,4BAA6B,EAAA,CAAA;AAAA,KACvE,CAAA;AAAA,GAEJ;AAEA,EAAI,IAAA,MAAA,KAAW,YAAY,SAAW,EAAA;AACpC,IACE,uBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,KAAM,EAAA,uBAAA;AAAA,QACN,OAAA;AAAA,QACA,eAAe,OAAQ,CAAA,UAAA;AAAA,OAAA;AAAA,sBAEvB,KAAA,CAAA,aAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAM,EAAA,EAAA;AAAA,UACN,OAAQ,EAAA,MAAA;AAAA,UACR,WAAY,EAAA,gDAAA;AAAA,SAAA;AAAA,OACd;AAAA,KACF,CAAA;AAAA,GAEJ;AAEA,EAAM,MAAA,eAAA,GAAkB,CAAC,gBAAoB,IAAA,kBAAA,CAAA;AAE7C,EAAI,IAAA,oBAAA,IAAwB,CAAC,eAAA,IAAmB,yBAA2B,EAAA;AACzE,IACE,uBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,KAAM,EAAA,uBAAA;AAAA,QACN,OAAA;AAAA,QACA,eAAe,OAAQ,CAAA,UAAA;AAAA,QACvB,QAAU,EAAA;AAAA,UACR,KAAO,EAAA,kBAAA;AAAA,UACP,IAAA,EAAM,GAAG,YAAY,CAAA,CAAA;AAAA,SACvB;AAAA,OAAA;AAAA,0CAEC,gBAAiB,EAAA,IAAA,CAAA;AAAA,KACpB,CAAA;AAAA,GAEJ;AAEA,EAAM,MAAA,cAAA,GAAA,CAAiB,EAAoB,GAAA,kBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,kBAAA,CAAA,qBAAA,KAApB,IAA2C,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,CAAA;AAClE,EAAM,MAAA,mBAAA,GAAA,CAAsB,EAAoB,GAAA,kBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,kBAAA,CAAA,uBAAA,KAApB,IAA6C,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,CAAA;AAEzE,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAM,EAAA,uBAAA;AAAA,MACN,OAAA;AAAA,MACA,eAAe,OAAQ,CAAA,OAAA;AAAA,MACvB,QAAU,EAAA;AAAA,QACR,KAAO,EAAA,kBAAA;AAAA,QACP,MAAM,qBAAsB,EAAA;AAAA,OAC9B;AAAA,KAAA;AAAA,oBAEA,KAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,OAAA,EAAA,sCACrB,UAAW,EAAA,EAAA,OAAA,EAAQ,WACjB,EAAA,EAAA,cAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,cAAA,CAAgB,UACnB,CAAA,sCACC,UAAW,EAAA,EAAA,OAAA,EAAQ,IAAM,EAAA,EAAA,cAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,cAAA,CAAgB,UAAW,CAAA,kBACpD,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,OAAA,EAAA,EACjB,cAAgB,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,cAAA,CAAA,gBACnB,CACF,CAAA;AAAA,oBACA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,WAAA,EAAY,UAAW,EAAA,CAAA;AAAA,oBAChC,KAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,OAAA,EAAA,sCACrB,UAAW,EAAA,EAAA,OAAA,EAAQ,WACjB,EAAA,EAAA,mBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,mBAAA,CAAqB,UACxB,CAAA,sCACC,UAAW,EAAA,EAAA,OAAA,EAAQ,IAAM,EAAA,EAAA,mBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,mBAAA,CAAqB,UAAW,CAAA,kBACzD,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,OAAA,EAAA,EACjB,mBAAqB,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,mBAAA,CAAA,gBACxB,CACF,CAAA;AAAA,oBACA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,WAAA,EAAY,UAAW,EAAA,CAAA;AAAA,wCAC/B,KAAI,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,OAAA,EAAA,sCACrB,UAAW,EAAA,EAAA,OAAA,EAAQ,WAAY,EAAA,EAAA,iBAAe,mBAC9C,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAQ,SACjB,EAAA,EAAA,CAAA,EAAA,GAAA,0BAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,0BAAA,CAA4B,0BAA5B,IAAmD,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAO,GAAI,EAAA,+BAEjE,mBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAQ,IAAM,EAAA,EAAA,CAAA,CAAA,EAAA,CAAI,8EAA4B,qBAA5B,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAmD,kBAAmB,CAAA,cAAA,EAAgB,EAAG,CACvH,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,OAAQ,EAAA,OAAA,EAAA,EAAQ,WAAS,CACvC,CAAA;AAAA,GACF,CAAA;AAEJ;;;;"}
|
|
@@ -38,7 +38,7 @@ const EntityCcmOverviewCard = harnessCcmPlugin.provide(
|
|
|
38
38
|
createComponentExtension({
|
|
39
39
|
name: "EntityCcmOverviewCard",
|
|
40
40
|
component: {
|
|
41
|
-
lazy: () => import('./OverviewCard-
|
|
41
|
+
lazy: () => import('./OverviewCard-e9aad184.esm.js').then((m) => m.default)
|
|
42
42
|
}
|
|
43
43
|
})
|
|
44
44
|
);
|
|
@@ -127,7 +127,8 @@ function useFetcher({
|
|
|
127
127
|
} = useAsyncRetry(async () => {
|
|
128
128
|
if (!lazy) {
|
|
129
129
|
const query = new URLSearchParams({
|
|
130
|
-
routingId: `${accountId}
|
|
130
|
+
routingId: `${accountId}`,
|
|
131
|
+
accountIdentifier: `${accountId}`
|
|
131
132
|
});
|
|
132
133
|
const token = getSecureHarnessKey("token");
|
|
133
134
|
const auth = token ? `${token}` : "";
|
|
@@ -306,7 +307,7 @@ const useGetPerspective = ({
|
|
|
306
307
|
"Harness-Account": accountId
|
|
307
308
|
});
|
|
308
309
|
const resp = await fetch(
|
|
309
|
-
`${await backendBaseUrl}/harness/${envFromUrl}/gateway/ccm/api/perspective?perspectiveId=${perspectiveId}`,
|
|
310
|
+
`${await backendBaseUrl}/harness/${envFromUrl}/gateway/ccm/api/perspective?routingId=${accountId}&accountIdentifier=${accountId}&perspectiveId=${perspectiveId}`,
|
|
310
311
|
{
|
|
311
312
|
headers
|
|
312
313
|
}
|
|
@@ -1469,4 +1470,4 @@ var Router$1 = /*#__PURE__*/Object.freeze({
|
|
|
1469
1470
|
});
|
|
1470
1471
|
|
|
1471
1472
|
export { AsyncStatus as A, CE_DATE_FORMAT_INTERNAL as C, DEFAULT_GROUP_BY as D, EntityCcmContent as E, PERSPECTIVE_DETAILS_AGGREGATE as P, Router as R, useResourceSlugFromEntity as a, useGetPerspective as b, useFetchPerspectiveDetailsSummaryWithBudget as c, getTimeFilters as d, getGMTEndDateTime as e, getGMTStartDateTime as f, getViewFilterForId as g, getGroupByFilter as h, useFetchPerspectiveRecommendations as i, isHarnessCcmAvailable as j, DATE_RANGE_SHORTCUTS as k, EntityCcmOverviewCard as l, harnessCcmPlugin as m, perspectiveDefaultTimeRangeMapper as p, rootRouteRef as r, usePerspectiveUrlFromEntity as u };
|
|
1472
|
-
//# sourceMappingURL=index-
|
|
1473
|
+
//# sourceMappingURL=index-44451033.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-44451033.esm.js","sources":["../../src/routes.ts","../../src/plugin.ts","../../src/hooks/useResourceSlugFromEntity.tsx","../../src/utils/getHarnessToken.ts","../../src/hooks/useFetcher.tsx","../../src/gql/fetchPerspectiveDetailsWithBudgetSummary.ts","../../src/api/useFetchPerspectiveDetailsSummaryWithBudget.ts","../../src/api/types.ts","../../src/hooks/useGetPerspective.ts","../../src/hooks/usePerspectiveUrlEntity.ts","../../src/utils/PerpsectiveUtils.tsx","../../src/gql/fetchPerspectiveGrid.ts","../../src/api/useFetchPerspectiveGrid.ts","../../src/gql/fetchPerspectiveChart.ts","../../src/api/useFetchPerspectiveChart.ts","../../src/hooks/useGetLicense.ts","../../src/components/CostCard/CostCard.tsx","../../src/components/PerspectivesChart/PerspectivesChart.tsx","../../src/components/PerspectivesGrid/PerspectivesGrid.tsx","../../src/components/TimeFilter/TimeFilter.tsx","../../src/components/RecommendationsCard/RecommendationsCard.tsx","../../src/gql/fetchPerspectiveRecommendations.ts","../../src/api/useFetchPerspectiveRecommendations.ts","../../src/components/PerspectivesPage/PerspectivesPage.tsx","../../src/components/Router.tsx"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'harness-ccm',\n});\n","import {\n createComponentExtension,\n createPlugin,\n createRoutableExtension,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { OverviewCardProps } from './components/OverviewCard/OverviewCard';\n\nexport const harnessCcmPlugin = createPlugin({\n id: 'harness-ccm',\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport const EntityCcmContent = harnessCcmPlugin.provide(\n createRoutableExtension({\n name: 'HarnessCcmPage',\n component: () => import('./components/Router').then(m => m.Router),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const EntityCcmOverviewCard: (props: OverviewCardProps) => JSX.Element =\n harnessCcmPlugin.provide(\n createComponentExtension({\n name: 'EntityCcmOverviewCard',\n component: {\n lazy: () =>\n import('./components/OverviewCard/OverviewCard').then(m => m.default),\n },\n }),\n );\n","import { match } from 'path-to-regexp';\n\nexport const useResourceSlugFromEntity = (perspectiveUrl?: string) => {\n const cleanedString = perspectiveUrl?.split(' ')[0];\n let accountId;\n let orgId;\n let projectId;\n let perspectiveId;\n\n let urlMatch;\n\n const containsModule = perspectiveUrl?.includes('/module/');\n const containsAll = perspectiveUrl?.includes('/all/');\n\n if (containsModule) {\n urlMatch = match(\n '(.*)/account/:accountId/module/:module/perspectives/:perspectiveId/(.*)',\n {\n decode: decodeURIComponent,\n },\n );\n } else if (containsAll) {\n urlMatch = match(\n '(.*)/account/:accountId/all/:module/perspectives/:perspectiveId/(.*)',\n {\n decode: decodeURIComponent,\n },\n );\n } else {\n urlMatch = match(\n '(.*)/account/:accountId/:module/perspectives/:perspectiveId/(.*)',\n {\n decode: decodeURIComponent,\n },\n );\n }\n\n if (cleanedString) {\n const hostname = new URL(cleanedString).hostname;\n const baseUrl = new URL(cleanedString).origin;\n\n const envAB = hostname.split('.harness.io')[0];\n const envFromUrl = envAB.includes('qa') ? 'qa' : 'prod';\n\n const urlParams: any = urlMatch(cleanedString ?? '');\n\n if (urlParams) {\n accountId = urlParams.params.accountId;\n orgId = urlParams.params.orgId;\n projectId = urlParams.params.projectId;\n perspectiveId = urlParams.params.perspectiveId;\n }\n\n return {\n projectId,\n perspectiveId,\n orgId,\n accountId,\n urlParams,\n envFromUrl,\n cleanedString,\n baseUrl,\n };\n }\n\n return {};\n};\n","export function getSecureHarnessKey(key: string): string | undefined {\n try {\n const token = JSON.parse(decodeURI(atob(localStorage.getItem(key) || '')));\n return token ? `Bearer ${token}` : '';\n } catch (err) {\n // eslint-disable-next-line no-console\n console.log('Failed to read Harness tokens');\n return undefined;\n }\n}\n","import { useState } from 'react';\nimport useAsyncRetry from 'react-use/lib/useAsyncRetry';\nimport { getSecureHarnessKey } from '../utils/getHarnessToken';\n\nexport enum AsyncStatus {\n Init,\n Loading,\n Success,\n Error,\n Unauthorized,\n}\n\ninterface UseFetcherProps {\n accountId: string;\n body?: string;\n method: 'GET' | 'POST';\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetcherReturn<T> {\n data: T | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nfunction useFetcher<T>({\n accountId,\n body = '',\n method = 'POST',\n env,\n backendBaseUrl,\n lazy,\n}: UseFetcherProps): UseFetcherReturn<T> {\n const [status, setStatus] = useState(AsyncStatus.Init);\n\n const {\n value: data,\n loading,\n error,\n retry: refetch,\n } = useAsyncRetry(async (): Promise<T | undefined> => {\n if (!lazy) {\n const query = new URLSearchParams({\n routingId: `${accountId}`,\n accountIdentifier: `${accountId}`,\n });\n\n const token = getSecureHarnessKey('token');\n const auth = token ? `${token}` : '';\n\n const headers = new Headers({\n 'content-type': 'application/json',\n Authorization: auth,\n });\n\n setStatus(AsyncStatus.Loading);\n\n const response = await fetch(\n `${await backendBaseUrl}/harness/${env}/gateway/ccm/api/graphql?${query}`,\n {\n headers,\n method,\n body,\n },\n );\n\n if (response.status === 200) {\n const responseData = await response.json();\n setStatus(AsyncStatus.Success);\n return responseData;\n } else if (response.status === 401) {\n setStatus(AsyncStatus.Unauthorized);\n return undefined;\n }\n setStatus(AsyncStatus.Error);\n return undefined;\n }\n\n return undefined;\n }, [accountId, body, method, env, lazy]);\n\n return { status, data, loading, error, refetch };\n}\n\nexport default useFetcher;\n","export const fetchPerspectiveDetailsWithBudgetSummaryQuery = `\n query FetchPerspectiveDetailsSummaryWithBudget(\n $filters: [QLCEViewFilterWrapperInput]\n $aggregateFunction: [QLCEViewAggregationInput]\n $isClusterQuery: Boolean\n $isClusterHourlyData: Boolean = null\n $groupBy: [QLCEViewGroupByInput]\n $preferences: ViewPreferencesInput\n ) {\n perspectiveTrendStats(\n filters: $filters\n aggregateFunction: $aggregateFunction\n isClusterQuery: $isClusterQuery\n isClusterHourlyData: $isClusterHourlyData\n groupBy: $groupBy\n preferences: $preferences\n ) {\n cost {\n statsDescription\n statsLabel\n statsTrend\n statsValue\n value\n }\n idleCost {\n statsLabel\n statsValue\n value\n }\n unallocatedCost {\n statsLabel\n statsValue\n value\n }\n utilizedCost {\n statsLabel\n statsValue\n value\n }\n efficiencyScoreStats {\n statsLabel\n statsTrend\n statsValue\n }\n }\n perspectiveForecastCost(\n filters: $filters\n aggregateFunction: $aggregateFunction\n isClusterQuery: $isClusterQuery\n isClusterHourlyData: $isClusterHourlyData\n groupBy: $groupBy\n preferences: $preferences\n ) {\n cost {\n statsLabel\n statsTrend\n statsValue\n statsDescription\n value\n }\n }\n }\n`;\n","import {\n FetchPerspectiveDetailsSummaryWithBudgetQuery,\n FetchPerspectiveDetailsSummaryWithBudgetQueryVariables,\n} from './types';\nimport useFetcher, { AsyncStatus } from '../hooks/useFetcher';\nimport { fetchPerspectiveDetailsWithBudgetSummaryQuery } from '../gql/fetchPerspectiveDetailsWithBudgetSummary';\n\ninterface UseFetchPerspectiveDetailsSummaryWithBudgetProps {\n accountId: string;\n variables: Partial<FetchPerspectiveDetailsSummaryWithBudgetQueryVariables>;\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetchPerspectiveDetailsSummaryWithBudgetReturn {\n perspectiveSummary: FetchPerspectiveDetailsSummaryWithBudgetQuery | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nconst useFetchPerspectiveDetailsSummaryWithBudget = ({\n ...props\n}: UseFetchPerspectiveDetailsSummaryWithBudgetProps): UseFetchPerspectiveDetailsSummaryWithBudgetReturn => {\n const body = JSON.stringify({\n query: fetchPerspectiveDetailsWithBudgetSummaryQuery,\n variables: props.variables,\n });\n\n const { data, ...fetcherProps } = useFetcher<{\n data: FetchPerspectiveDetailsSummaryWithBudgetQuery;\n }>({\n ...props,\n method: 'POST',\n body,\n });\n\n return { perspectiveSummary: data?.data, ...fetcherProps };\n};\n\nexport default useFetchPerspectiveDetailsSummaryWithBudget;\n","export type Maybe<T> = T | null;\nexport type InputMaybe<T> = Maybe<T>;\nexport type Exact<T extends { [key: string]: unknown }> = {\n [K in keyof T]: T[K];\n};\n\nexport enum AsyncStatus {\n Init,\n Loading,\n Success,\n Error,\n Unauthorized,\n Forbidden,\n}\n\nexport type Scalars = {\n ID: string;\n String: string;\n Boolean: boolean;\n Int: number;\n Float: number;\n /** Built-in java.math.BigDecimal */\n BigDecimal: any;\n /** Built-in scalar representing an instant in time */\n Date: any;\n /** Long type */\n Long: any;\n /** Built-in scalar for map-like structures */\n Map_String_ContainerRecommendationScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_Map_String_StringScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_ObjectScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_ResourceRequirementScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_ServiceNowFieldValueNGScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_StringScalar: any;\n /** Built-in scalar representing a date-time with a UTC offset */\n OffsetDateTime: any;\n /** Built-in scalar representing a time with a UTC offset */\n OffsetTime: any;\n /** Use SPQR's SchemaPrinter to remove this from SDL */\n UNREPRESENTABLE: any;\n};\n\nexport type QlceViewFieldInputInput = {\n fieldId: Scalars['String'];\n fieldName: Scalars['String'];\n identifier: ViewFieldIdentifier;\n identifierName: InputMaybe<Scalars['String']>;\n};\n\nexport enum ViewFieldIdentifier {\n Aws = 'AWS',\n Azure = 'AZURE',\n BusinessMapping = 'BUSINESS_MAPPING',\n Cluster = 'CLUSTER',\n Common = 'COMMON',\n Custom = 'CUSTOM',\n Gcp = 'GCP',\n Label = 'LABEL',\n}\n\nexport enum QlceViewFilterOperator {\n Equals = 'EQUALS',\n In = 'IN',\n Like = 'LIKE',\n NotIn = 'NOT_IN',\n NotNull = 'NOT_NULL',\n Null = 'NULL',\n Search = 'SEARCH',\n}\n\nexport enum QlceViewTimeGroupType {\n Day = 'DAY',\n Hour = 'HOUR',\n Month = 'MONTH',\n Quarter = 'QUARTER',\n Week = 'WEEK',\n Year = 'YEAR',\n}\n\nexport type QlceViewTimeTruncGroupByInput = {\n resolution: QlceViewTimeGroupType;\n};\n\nexport type QlceViewFilterInput = {\n field: QlceViewFieldInputInput;\n operator: QlceViewFilterOperator;\n values: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n};\n\nexport type QlceViewRuleInput = {\n conditions: InputMaybe<Array<InputMaybe<QlceViewFilterInput>>>;\n};\n\nexport enum QlceViewTimeFilterOperator {\n After = 'AFTER',\n Before = 'BEFORE',\n}\n\nexport type QlceViewTimeFilterInput = {\n field: QlceViewFieldInputInput;\n operator: QlceViewTimeFilterOperator;\n value: Scalars['BigDecimal'];\n};\n\nexport type QlceViewFilterWrapperInput = {\n idFilter: InputMaybe<QlceViewFilterInput>;\n inExpressionFilter: InputMaybe<QlceInExpressionFilterInput>;\n ruleFilter: InputMaybe<QlceViewRuleInput>;\n timeFilter: InputMaybe<QlceViewTimeFilterInput>;\n viewMetadataFilter: InputMaybe<QlceViewMetadataFilterInput>;\n};\n\nexport type QlceViewGroupByInput = {\n entityGroupBy: InputMaybe<QlceViewFieldInputInput>;\n timeTruncGroupBy: InputMaybe<QlceViewTimeTruncGroupByInput>;\n};\n\nexport type QlceViewMetadataFilterInput = {\n isPreview: Scalars['Boolean'];\n viewId: Scalars['String'];\n};\n\nexport enum QlceViewAggregateOperation {\n Avg = 'AVG',\n Max = 'MAX',\n Min = 'MIN',\n Sum = 'SUM',\n}\n\nexport type QlceViewAggregationInput = {\n columnName: Scalars['String'];\n operationType: QlceViewAggregateOperation;\n};\n\nexport enum AwsViewPreferenceCost {\n Amortised = 'AMORTISED',\n Blended = 'BLENDED',\n Effective = 'EFFECTIVE',\n NetAmortised = 'NET_AMORTISED',\n Unblended = 'UNBLENDED',\n}\n\nexport type AwsViewPreferences = {\n __typename?: 'AWSViewPreferences';\n awsCost: Maybe<AwsViewPreferenceCost>;\n includeCredits: Maybe<Scalars['Boolean']>;\n includeDiscounts: Maybe<Scalars['Boolean']>;\n includeRefunds: Maybe<Scalars['Boolean']>;\n includeTaxes: Maybe<Scalars['Boolean']>;\n};\n\nexport type AwsViewPreferencesInput = {\n awsCost: InputMaybe<AwsViewPreferenceCost>;\n includeCredits: InputMaybe<Scalars['Boolean']>;\n includeDiscounts: InputMaybe<Scalars['Boolean']>;\n includeRefunds: InputMaybe<Scalars['Boolean']>;\n includeTaxes: InputMaybe<Scalars['Boolean']>;\n};\n\nexport enum AzureCostType {\n Actual = 'ACTUAL',\n Amortized = 'AMORTIZED',\n}\n\nexport type AzureViewPreferences = {\n __typename?: 'AzureViewPreferences';\n costType: Maybe<AzureCostType>;\n};\n\nexport type AzureViewPreferencesInput = {\n costType: InputMaybe<AzureCostType>;\n};\n\nexport type GcpViewPreferences = {\n __typename?: 'GCPViewPreferences';\n includeDiscounts: Maybe<Scalars['Boolean']>;\n includeTaxes: Maybe<Scalars['Boolean']>;\n};\n\nexport type GcpViewPreferencesInput = {\n includeDiscounts: InputMaybe<Scalars['Boolean']>;\n includeTaxes: InputMaybe<Scalars['Boolean']>;\n};\n\nexport type ViewPreferencesInput = {\n awsPreferences: InputMaybe<AwsViewPreferencesInput>;\n azureViewPreferences: InputMaybe<AzureViewPreferencesInput>;\n gcpPreferences: InputMaybe<GcpViewPreferencesInput>;\n includeOthers: InputMaybe<Scalars['Boolean']>;\n includeUnallocatedCost: InputMaybe<Scalars['Boolean']>;\n showAnomalies: InputMaybe<Scalars['Boolean']>;\n};\n\nexport type FetchPerspectiveDetailsSummaryWithBudgetQueryVariables = Exact<{\n filters: InputMaybe<\n | Array<InputMaybe<QlceViewFilterWrapperInput>>\n | InputMaybe<QlceViewFilterWrapperInput>\n >;\n aggregateFunction: InputMaybe<\n | Array<InputMaybe<QlceViewAggregationInput>>\n | InputMaybe<QlceViewAggregationInput>\n >;\n isClusterQuery: InputMaybe<Scalars['Boolean']>;\n isClusterHourlyData?: InputMaybe<Scalars['Boolean']>;\n groupBy: InputMaybe<\n Array<InputMaybe<QlceViewGroupByInput>> | InputMaybe<QlceViewGroupByInput>\n >;\n preferences: InputMaybe<ViewPreferencesInput>;\n}>;\n\nexport type QlceInExpressionFilterInput = {\n fields: Array<InputMaybe<QlceViewFieldInputInput>>;\n nullValueField: InputMaybe<Scalars['String']>;\n values: Array<InputMaybe<Array<InputMaybe<Scalars['String']>>>>;\n};\n\nexport type FetchPerspectiveDetailsSummaryWithBudgetQuery = {\n perspectiveTrendStats: {\n cost: {\n statsDescription: string;\n statsLabel: string;\n statsTrend: any | null;\n statsValue: string;\n value: any | null;\n } | null;\n idleCost: {\n statsLabel: string;\n statsValue: string;\n value: any | null;\n } | null;\n unallocatedCost: {\n statsLabel: string;\n statsValue: string;\n value: any | null;\n } | null;\n utilizedCost: {\n statsLabel: string;\n statsValue: string;\n value: any | null;\n } | null;\n efficiencyScoreStats: {\n statsLabel: string | null;\n statsTrend: any | null;\n statsValue: string | null;\n } | null;\n } | null;\n perspectiveForecastCost: {\n cost: {\n statsLabel: string;\n statsTrend: any | null;\n statsValue: string;\n statsDescription: string;\n value: any | null;\n } | null;\n } | null;\n};\n\nexport interface EmbeddedUser {\n email?: string;\n externalUserId?: string;\n name?: string;\n uuid?: string;\n}\n\nexport interface ViewCondition {\n type?: string;\n}\n\nexport interface ViewRule {\n viewConditions?: ViewCondition[];\n}\n\nexport interface ViewTimeRange {\n endTime?: number;\n startTime?: number;\n viewTimeRangeType?:\n | 'LAST_7'\n | 'LAST_30'\n | 'LAST_MONTH'\n | 'CURRENT_MONTH'\n | 'CUSTOM';\n}\n\nexport interface ViewField {\n fieldId?: string;\n fieldName?: string;\n identifier?:\n | 'CLUSTER'\n | 'AWS'\n | 'GCP'\n | 'AZURE'\n | 'COMMON'\n | 'CUSTOM'\n | 'BUSINESS_MAPPING'\n | 'LABEL';\n identifierName?: string;\n}\n\nexport interface ViewVisualization {\n chartType?: 'STACKED_TIME_SERIES' | 'STACKED_LINE_CHART';\n granularity?: 'DAY' | 'MONTH';\n groupBy?: ViewField;\n}\n\nexport interface CEView {\n accountId?: string;\n createdAt?: number;\n createdBy?: EmbeddedUser;\n dataSources?: (\n | 'CLUSTER'\n | 'AWS'\n | 'GCP'\n | 'AZURE'\n | 'COMMON'\n | 'CUSTOM'\n | 'BUSINESS_MAPPING'\n | 'LABEL'\n )[];\n folderId?: string;\n lastUpdatedAt?: number;\n lastUpdatedBy?: EmbeddedUser;\n name?: string;\n totalCost?: number;\n uuid?: string;\n viewPreferences?: ViewPreferencesInput;\n viewRules?: ViewRule[];\n viewState?: 'DRAFT' | 'COMPLETED';\n viewTimeRange?: ViewTimeRange;\n viewType?: 'SAMPLE' | 'CUSTOMER' | 'DEFAULT';\n viewVersion?: string;\n viewVisualization?: ViewVisualization;\n}\n\nexport type FetchperspectiveGridQueryVariables = Exact<{\n filters: InputMaybe<\n | Array<InputMaybe<QlceViewFilterWrapperInput>>\n | InputMaybe<QlceViewFilterWrapperInput>\n >;\n groupBy: InputMaybe<\n Array<InputMaybe<QlceViewGroupByInput>> | InputMaybe<QlceViewGroupByInput>\n >;\n limit: InputMaybe<Scalars['Int']>;\n offset: InputMaybe<Scalars['Int']>;\n aggregateFunction: InputMaybe<\n | Array<InputMaybe<QlceViewAggregationInput>>\n | InputMaybe<QlceViewAggregationInput>\n >;\n isClusterOnly: Scalars['Boolean'];\n isClusterHourlyData?: InputMaybe<Scalars['Boolean']>;\n preferences: InputMaybe<ViewPreferencesInput>;\n}>;\n\nexport type FetchperspectiveGridQuery = {\n __typename?: 'Query';\n perspectiveTotalCount: number | null;\n perspectiveGrid: {\n __typename?: 'PerspectiveEntityStatsData';\n data: Array<{\n __typename?: 'QLCEViewEntityStatsDataPoint';\n name: string | null;\n id: string | null;\n cost: any | null;\n costTrend: any | null;\n clusterPerspective?: boolean;\n clusterData?: {\n __typename?: 'ClusterData';\n appId: string | null;\n appName: string | null;\n avgCpuUtilization: number | null;\n avgMemoryUtilization: number | null;\n cloudProvider: string | null;\n cloudProviderId: string | null;\n cloudServiceName: string | null;\n clusterId: string | null;\n clusterName: string | null;\n clusterType: string | null;\n costTrend: number | null;\n cpuBillingAmount: number | null;\n cpuActualIdleCost: number | null;\n cpuUnallocatedCost: number | null;\n efficiencyScore: number;\n efficiencyScoreTrendPercentage: number;\n envId: string | null;\n envName: string | null;\n environment: string | null;\n id: string | null;\n idleCost: number | null;\n launchType: string | null;\n maxCpuUtilization: number | null;\n maxMemoryUtilization: number | null;\n memoryBillingAmount: number | null;\n memoryActualIdleCost: number | null;\n memoryUnallocatedCost: number | null;\n name: string | null;\n namespace: string | null;\n networkCost: number | null;\n prevBillingAmount: number | null;\n region: string | null;\n serviceId: string | null;\n serviceName: string | null;\n storageCost: number | null;\n storageActualIdleCost: number | null;\n storageRequest: number | null;\n storageUnallocatedCost: number | null;\n storageUtilizationValue: number | null;\n totalCost: number | null;\n trendType: string | null;\n type: string | null;\n unallocatedCost: number | null;\n workloadName: string | null;\n workloadType: string | null;\n } | null;\n instanceDetails?: {\n __typename?: 'InstanceDetails';\n name: string | null;\n id: string | null;\n nodeId: string | null;\n clusterName: string | null;\n clusterId: string | null;\n nodePoolName: string | null;\n cloudProviderInstanceId: string | null;\n podCapacity: string | null;\n totalCost: number;\n idleCost: number;\n systemCost: number;\n unallocatedCost: number;\n cpuAllocatable: number;\n memoryAllocatable: number;\n instanceCategory: string | null;\n machineType: string | null;\n createTime: any;\n deleteTime: any;\n memoryBillingAmount: number;\n cpuBillingAmount: number;\n memoryUnallocatedCost: number;\n cpuUnallocatedCost: number;\n memoryIdleCost: number;\n cpuIdleCost: number;\n } | null;\n storageDetails?: {\n __typename?: 'StorageDetails';\n id: string | null;\n instanceId: string | null;\n instanceName: string | null;\n claimName: string | null;\n claimNamespace: string | null;\n clusterName: string | null;\n clusterId: string | null;\n storageClass: string | null;\n volumeType: string | null;\n cloudProvider: string | null;\n region: string | null;\n storageCost: number;\n storageActualIdleCost: number;\n storageUnallocatedCost: number;\n capacity: number;\n storageRequest: number;\n storageUtilizationValue: number;\n createTime: any;\n deleteTime: any;\n } | null;\n } | null> | null;\n } | null;\n};\n\nexport type QlceViewEntityStatsDataPoint = {\n __typename?: 'QLCEViewEntityStatsDataPoint';\n clusterData: Maybe<ClusterData>;\n clusterPerspective: Scalars['Boolean'];\n cost: Maybe<Scalars['BigDecimal']>;\n costTrend: Maybe<Scalars['BigDecimal']>;\n id: Maybe<Scalars['String']>;\n instanceDetails: Maybe<InstanceDetails>;\n name: Maybe<Scalars['String']>;\n pricingSource: Maybe<Scalars['String']>;\n storageDetails: Maybe<StorageDetails>;\n};\n\nexport type ClusterData = {\n __typename?: 'ClusterData';\n appId: Maybe<Scalars['String']>;\n appName: Maybe<Scalars['String']>;\n avgCpuUtilization: Maybe<Scalars['Float']>;\n avgMemoryUtilization: Maybe<Scalars['Float']>;\n cloudProvider: Maybe<Scalars['String']>;\n cloudProviderId: Maybe<Scalars['String']>;\n cloudServiceName: Maybe<Scalars['String']>;\n clusterId: Maybe<Scalars['String']>;\n clusterName: Maybe<Scalars['String']>;\n clusterType: Maybe<Scalars['String']>;\n costTrend: Maybe<Scalars['Float']>;\n cpuActualIdleCost: Maybe<Scalars['Float']>;\n cpuBillingAmount: Maybe<Scalars['Float']>;\n cpuIdleCost: Maybe<Scalars['Float']>;\n cpuUnallocatedCost: Maybe<Scalars['Float']>;\n efficiencyScore: Scalars['Int'];\n efficiencyScoreTrendPercentage: Scalars['Int'];\n envId: Maybe<Scalars['String']>;\n envName: Maybe<Scalars['String']>;\n environment: Maybe<Scalars['String']>;\n id: Maybe<Scalars['String']>;\n idleCost: Maybe<Scalars['Float']>;\n instanceId: Maybe<Scalars['String']>;\n instanceName: Maybe<Scalars['String']>;\n instanceType: Maybe<Scalars['String']>;\n launchType: Maybe<Scalars['String']>;\n maxCpuUtilization: Maybe<Scalars['Float']>;\n maxMemoryUtilization: Maybe<Scalars['Float']>;\n memoryActualIdleCost: Maybe<Scalars['Float']>;\n memoryBillingAmount: Maybe<Scalars['Float']>;\n memoryIdleCost: Maybe<Scalars['Float']>;\n memoryUnallocatedCost: Maybe<Scalars['Float']>;\n name: Maybe<Scalars['String']>;\n namespace: Maybe<Scalars['String']>;\n networkCost: Maybe<Scalars['Float']>;\n prevBillingAmount: Maybe<Scalars['Float']>;\n region: Maybe<Scalars['String']>;\n serviceId: Maybe<Scalars['String']>;\n serviceName: Maybe<Scalars['String']>;\n storageActualIdleCost: Maybe<Scalars['Float']>;\n storageCost: Maybe<Scalars['Float']>;\n storageRequest: Maybe<Scalars['Float']>;\n storageUnallocatedCost: Maybe<Scalars['Float']>;\n storageUtilizationValue: Maybe<Scalars['Float']>;\n systemCost: Maybe<Scalars['Float']>;\n taskId: Maybe<Scalars['String']>;\n totalCost: Maybe<Scalars['Float']>;\n trendType: Maybe<Scalars['String']>;\n type: Maybe<Scalars['String']>;\n unallocatedCost: Maybe<Scalars['Float']>;\n workloadName: Maybe<Scalars['String']>;\n workloadType: Maybe<Scalars['String']>;\n};\n\nexport type InstanceDetails = {\n __typename?: 'InstanceDetails';\n cloudProviderInstanceId: Maybe<Scalars['String']>;\n clusterId: Maybe<Scalars['String']>;\n clusterName: Maybe<Scalars['String']>;\n cpuAllocatable: Scalars['Float'];\n cpuBillingAmount: Scalars['Float'];\n cpuIdleCost: Scalars['Float'];\n cpuRequested: Scalars['Float'];\n cpuUnallocatedCost: Scalars['Float'];\n cpuUnitPrice: Scalars['Float'];\n createTime: Scalars['Long'];\n deleteTime: Scalars['Long'];\n id: Maybe<Scalars['String']>;\n idleCost: Scalars['Float'];\n instanceCategory: Maybe<Scalars['String']>;\n machineType: Maybe<Scalars['String']>;\n memoryAllocatable: Scalars['Float'];\n memoryBillingAmount: Scalars['Float'];\n memoryIdleCost: Scalars['Float'];\n memoryRequested: Scalars['Float'];\n memoryUnallocatedCost: Scalars['Float'];\n memoryUnitPrice: Scalars['Float'];\n name: Maybe<Scalars['String']>;\n namespace: Maybe<Scalars['String']>;\n networkCost: Scalars['Float'];\n node: Maybe<Scalars['String']>;\n nodeId: Maybe<Scalars['String']>;\n nodePoolName: Maybe<Scalars['String']>;\n podCapacity: Maybe<Scalars['String']>;\n qosClass: Maybe<Scalars['String']>;\n storageActualIdleCost: Scalars['Float'];\n storageCost: Scalars['Float'];\n storageRequest: Scalars['Float'];\n storageUnallocatedCost: Scalars['Float'];\n storageUtilizationValue: Scalars['Float'];\n systemCost: Scalars['Float'];\n totalCost: Scalars['Float'];\n unallocatedCost: Scalars['Float'];\n workload: Maybe<Scalars['String']>;\n};\n\nexport type StorageDetails = {\n __typename?: 'StorageDetails';\n capacity: Scalars['Float'];\n claimName: Maybe<Scalars['String']>;\n claimNamespace: Maybe<Scalars['String']>;\n cloudProvider: Maybe<Scalars['String']>;\n clusterId: Maybe<Scalars['String']>;\n clusterName: Maybe<Scalars['String']>;\n createTime: Scalars['Long'];\n deleteTime: Scalars['Long'];\n id: Maybe<Scalars['String']>;\n instanceId: Maybe<Scalars['String']>;\n instanceName: Maybe<Scalars['String']>;\n region: Maybe<Scalars['String']>;\n storageActualIdleCost: Scalars['Float'];\n storageClass: Maybe<Scalars['String']>;\n storageCost: Scalars['Float'];\n storageRequest: Scalars['Float'];\n storageUnallocatedCost: Scalars['Float'];\n storageUtilizationValue: Scalars['Float'];\n volumeType: Maybe<Scalars['String']>;\n};\n\nexport type FetchPerspectiveTimeSeriesQueryVariables = Exact<{\n filters: InputMaybe<\n | Array<InputMaybe<QlceViewFilterWrapperInput>>\n | InputMaybe<QlceViewFilterWrapperInput>\n >;\n groupBy: InputMaybe<\n Array<InputMaybe<QlceViewGroupByInput>> | InputMaybe<QlceViewGroupByInput>\n >;\n limit: InputMaybe<Scalars['Int']>;\n preferences: InputMaybe<ViewPreferencesInput>;\n isClusterHourlyData?: InputMaybe<Scalars['Boolean']>;\n}>;\n\nexport type FetchPerspectiveTimeSeriesQuery = {\n __typename?: 'Query';\n perspectiveTimeSeriesStats: {\n __typename?: 'PerspectiveTimeSeriesData';\n stats: Array<{\n __typename?: 'TimeSeriesDataPoints';\n time: any;\n values: Array<{\n __typename?: 'DataPoint';\n value: any;\n key: {\n __typename?: 'Reference';\n id: string;\n name: string;\n type: string;\n };\n } | null>;\n } | null> | null;\n } | null;\n};\n\nexport type Reference = {\n __typename?: 'Reference';\n id: Scalars['String'];\n name: Scalars['String'];\n type: Scalars['String'];\n};\n\nexport type DataPoint = {\n __typename?: 'DataPoint';\n key: Reference;\n value: Scalars['BigDecimal'];\n};\n\nexport type TimeSeriesDataPoints = {\n __typename?: 'TimeSeriesDataPoints';\n time: Scalars['Long'];\n values: Array<Maybe<DataPoint>>;\n};\n\nexport enum CloudProvider {\n Aws = 'AWS',\n Azure = 'AZURE',\n Gcp = 'GCP',\n Ibm = 'IBM',\n OnPrem = 'ON_PREM',\n Unknown = 'UNKNOWN',\n}\n\nexport enum RecommendationState {\n Applied = 'APPLIED',\n Ignored = 'IGNORED',\n Open = 'OPEN',\n}\n\nexport enum ResourceType {\n AzureInstance = 'AZURE_INSTANCE',\n Ec2Instance = 'EC2_INSTANCE',\n EcsService = 'ECS_SERVICE',\n Governance = 'GOVERNANCE',\n NodePool = 'NODE_POOL',\n Workload = 'WORKLOAD',\n}\n\nexport type K8sRecommendationFilterDtoInput = {\n cloudProvider: InputMaybe<Array<InputMaybe<CloudProvider>>>;\n clusterNames: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n daysBack: InputMaybe<Scalars['Long']>;\n ids: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n limit: InputMaybe<Scalars['Long']>;\n minCost: InputMaybe<Scalars['Float']>;\n minSaving: InputMaybe<Scalars['Float']>;\n names: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n namespaces: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n offset: InputMaybe<Scalars['Long']>;\n perspectiveFilters: InputMaybe<Array<InputMaybe<QlceViewFilterWrapperInput>>>;\n recommendationStates: InputMaybe<Array<InputMaybe<RecommendationState>>>;\n resourceTypes: InputMaybe<Array<InputMaybe<ResourceType>>>;\n};\n\nexport type PerspectiveRecommendationsQueryVariables = Exact<{\n filter: InputMaybe<K8sRecommendationFilterDtoInput>;\n}>;\n\nexport type PerspectiveRecommendationsQuery = {\n __typename?: 'Query';\n recommendationStatsV2: {\n __typename?: 'RecommendationOverviewStats';\n totalMonthlyCost: number;\n totalMonthlySaving: number;\n count: number;\n } | null;\n};\n\nexport enum ViewTimeRangeType {\n CurrentMonth = 'CURRENT_MONTH',\n Custom = 'CUSTOM',\n Last_7 = 'LAST_7',\n Last_30 = 'LAST_30',\n LastMonth = 'LAST_MONTH',\n}\n","import useAsyncRetry from 'react-use/lib/useAsyncRetry';\nimport { useState } from 'react';\n\nimport { getSecureHarnessKey } from '../utils/getHarnessToken';\n\nimport { AsyncStatus, CEView } from '../api/types';\n\ninterface useGetFeatureEnvArgs {\n backendBaseUrl: Promise<string>;\n accountId: string;\n envFromUrl?: string;\n perspectiveId: string;\n}\n\nexport interface UseGetPerspectiveReturn {\n perspective?: CEView;\n status: AsyncStatus;\n}\n\nconst useGetPerspective = ({\n backendBaseUrl,\n accountId,\n perspectiveId,\n envFromUrl,\n}: useGetFeatureEnvArgs): UseGetPerspectiveReturn => {\n const [perspective, setPerspective] = useState<CEView>();\n const [status, setStatus] = useState<AsyncStatus>(AsyncStatus.Init);\n\n useAsyncRetry(async () => {\n setStatus(AsyncStatus.Loading);\n\n const token = getSecureHarnessKey('token');\n const headers = new Headers({\n 'content-type': 'application/json',\n Authorization: token ? `${token}` : '',\n 'Harness-Account': accountId,\n });\n const resp = await fetch(\n `${await backendBaseUrl}/harness/${envFromUrl}/gateway/ccm/api/perspective?routingId=${accountId}&accountIdentifier=${accountId}&perspectiveId=${perspectiveId}`,\n {\n headers,\n },\n );\n\n if (resp.status === 200) {\n const data = await resp.json();\n setPerspective(data.data);\n setStatus(AsyncStatus.Success);\n } else if (resp.status === 401) {\n setStatus(AsyncStatus.Unauthorized);\n } else if (resp.status === 403) {\n setStatus(AsyncStatus.Forbidden);\n } else {\n setStatus(AsyncStatus.Error);\n }\n }, [accountId, perspectiveId, envFromUrl]);\n\n return {\n perspective,\n status,\n };\n};\n\nexport default useGetPerspective;\n","import { useEntity } from '@backstage/plugin-catalog-react';\n\nconst usePerspectiveUrlFromEntity = () => {\n const { entity } = useEntity();\n\n return entity.metadata.annotations?.['harness.io/perspective-url'];\n};\n\nexport default usePerspectiveUrlFromEntity;\n","import dayjs from 'dayjs';\nimport utc from 'dayjs/plugin/utc';\nimport quarterOfYear from 'dayjs/plugin/quarterOfYear';\n\nimport {\n QlceViewAggregateOperation,\n QlceViewFieldInputInput,\n QlceViewFilterWrapperInput,\n QlceViewGroupByInput,\n QlceViewTimeFilterOperator,\n QlceViewTimeGroupType,\n ViewField,\n ViewFieldIdentifier,\n ViewTimeRangeType,\n ViewVisualization,\n} from '../api/types';\n\nexport const getViewFilterForId: (\n viewId: string,\n isPreview?: boolean,\n) => QlceViewFilterWrapperInput = (viewId: string, isPreview = false) => {\n return {\n viewMetadataFilter: { viewId: viewId, isPreview: isPreview },\n } as QlceViewFilterWrapperInput;\n};\n\nconst startTimeLabel = 'startTime';\n\nexport const CE_DATE_FORMAT_INTERNAL = 'YYYY-MM-DD';\nexport const CE_DATE_FORMAT_INTERNAL_MOMENT = `${CE_DATE_FORMAT_INTERNAL}THH:mm:ssZ`;\n\ndayjs.extend(utc);\ndayjs.extend(quarterOfYear);\n\nexport const todayInUTC = () => dayjs.utc();\n\nexport const LAST_30_DAYS_RANGE = [\n todayInUTC()\n .subtract(30, 'days')\n .startOf('day')\n .format(CE_DATE_FORMAT_INTERNAL),\n todayInUTC().endOf('day').format(CE_DATE_FORMAT_INTERNAL),\n];\n\nexport const DEFAULT_TIME_RANGE: TimeRangeFilterType = {\n to: LAST_30_DAYS_RANGE[1],\n from: LAST_30_DAYS_RANGE[0],\n};\n\nexport const getGMTStartDateTime = (str: string) =>\n dayjs(`${str}T00:00:00Z`, CE_DATE_FORMAT_INTERNAL_MOMENT).valueOf();\nexport const getGMTEndDateTime = (str: string) =>\n dayjs(`${str}T23:59:59Z`, CE_DATE_FORMAT_INTERNAL_MOMENT).valueOf();\n\nexport const getTimeFilters: (\n from: number,\n to: number,\n) => QlceViewFilterWrapperInput[] = (from, to) => {\n return [\n {\n timeFilter: {\n field: {\n fieldId: startTimeLabel,\n fieldName: startTimeLabel,\n identifier: ViewFieldIdentifier.Common,\n },\n operator: QlceViewTimeFilterOperator.After,\n value: from,\n },\n },\n {\n timeFilter: {\n field: {\n fieldId: startTimeLabel,\n fieldName: startTimeLabel,\n identifier: ViewFieldIdentifier.Common,\n },\n operator: QlceViewTimeFilterOperator.Before,\n value: to,\n },\n },\n ] as QlceViewFilterWrapperInput[];\n};\n\nexport const PERSPECTIVE_DETAILS_AGGREGATE = [\n { operationType: QlceViewAggregateOperation.Sum, columnName: 'cost' },\n { operationType: QlceViewAggregateOperation.Max, columnName: 'startTime' },\n { operationType: QlceViewAggregateOperation.Min, columnName: 'startTime' },\n];\n\nexport const DEFAULT_GROUP_BY = {\n fieldId: 'product',\n fieldName: 'Product',\n identifier: ViewFieldIdentifier.Common,\n identifierName: ViewFieldIdentifier.Common,\n};\n\nexport const getGroupByFilter: (\n groupBy: QlceViewFieldInputInput | ViewField,\n) => QlceViewGroupByInput = groupBy => {\n return {\n entityGroupBy: groupBy,\n } as QlceViewGroupByInput;\n};\n\nexport const clusterInfoUtil: (dataSources?: string[]) => {\n isClusterOnly: boolean;\n recommendationsEnabled: boolean;\n} = dataSources => {\n let isClusterOnly = false;\n let recommendationsEnabled = false;\n\n if (!dataSources?.length) {\n return { isClusterOnly, recommendationsEnabled };\n }\n\n if (\n dataSources.length === 1 &&\n dataSources[0] === ViewFieldIdentifier.Cluster\n ) {\n isClusterOnly = true;\n }\n\n if (!dataSources.includes(ViewFieldIdentifier.Gcp)) {\n recommendationsEnabled = true;\n }\n\n return { isClusterOnly, recommendationsEnabled };\n};\n\nexport const getTimeRangeFilter: (\n aggregation: QlceViewTimeGroupType | ViewVisualization['granularity'],\n) => QlceViewGroupByInput = aggregation => {\n return {\n timeTruncGroupBy: {\n resolution: aggregation,\n },\n } as QlceViewGroupByInput;\n};\n\nexport const DATE_RANGE_SHORTCUTS: Record<string, dayjs.Dayjs[]> = {\n LAST_7_DAYS: [\n todayInUTC().subtract(6, 'days').startOf('day'),\n todayInUTC().endOf('day'),\n ],\n LAST_30_DAYS: [\n todayInUTC().subtract(30, 'days').startOf('day'),\n todayInUTC().endOf('day'),\n ],\n CURRENT_MONTH: [\n todayInUTC().startOf('month').startOf('day'),\n todayInUTC().endOf('day'),\n ],\n THIS_MONTH: [\n todayInUTC().startOf('month').startOf('day'),\n todayInUTC().endOf('month').subtract(1, 'days'),\n ],\n THIS_YEAR: [todayInUTC().startOf('year'), todayInUTC().endOf('day')],\n LAST_MONTH: [\n todayInUTC().subtract(1, 'month').startOf('month'),\n todayInUTC().subtract(1, 'month').endOf('month'),\n ],\n LAST_YEAR: [\n todayInUTC().subtract(1, 'year').startOf('year'),\n todayInUTC().subtract(1, 'year').endOf('year'),\n ],\n LAST_3_MONTHS: [\n todayInUTC().subtract(3, 'months').startOf('month'),\n todayInUTC().subtract(1, 'month').endOf('month'),\n ],\n LAST_6_MONTHS: [\n todayInUTC().subtract(6, 'months').startOf('month'),\n todayInUTC().subtract(1, 'month').endOf('month'),\n ],\n LAST_12_MONTHS: [\n todayInUTC().subtract(12, 'months').startOf('month'),\n todayInUTC().subtract(1, 'month').endOf('month'),\n ],\n THIS_QUARTER: [todayInUTC().startOf('quarter'), todayInUTC().endOf('day')],\n LAST_QUARTER: [\n todayInUTC().subtract(1, 'quarter').startOf('quarter'),\n todayInUTC().subtract(1, 'quarter').endOf('quarter'),\n ],\n};\n\nexport enum DATE_RANGE_SHORTCUTS_NAME {\n 'LAST_7_DAYS' = 'LAST_7_DAYS',\n 'LAST_30_DAYS' = 'LAST_30_DAYS',\n 'CURRENT_MONTH' = 'CURRENT_MONTH',\n 'THIS_YEAR' = 'THIS_YEAR',\n 'LAST_MONTH' = 'LAST_MONTH',\n 'LAST_YEAR' = 'LAST_YEAR',\n 'LAST_3_MONTHS' = 'LAST_3_MONTHS',\n 'LAST_6_MONTHS' = 'LAST_6_MONTHS',\n 'LAST_12_MONTHS' = 'LAST_12_MONTHS',\n 'THIS_QUARTER' = 'THIS_QUARTER',\n 'LAST_QUARTER' = 'LAST_QUARTER',\n 'CUSTOM' = 'CUSTOM',\n}\n\nexport const DateLabelToDisplayTextMap: Record<string, string> = {\n [DATE_RANGE_SHORTCUTS_NAME.LAST_7_DAYS]: 'Last 7 Days',\n [DATE_RANGE_SHORTCUTS_NAME.CURRENT_MONTH]: 'This Month',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_30_DAYS]: 'Last 30 Days',\n [DATE_RANGE_SHORTCUTS_NAME.THIS_QUARTER]: 'This Quarter',\n [DATE_RANGE_SHORTCUTS_NAME.THIS_YEAR]: 'This Year',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_MONTH]: 'Last Month',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_QUARTER]: 'Last Quarter',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_YEAR]: 'Last Year',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_3_MONTHS]: 'Last 3 Months',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_6_MONTHS]: 'Last 6 Months',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_12_MONTHS]: 'Last 12 Months',\n};\n\nconst LAST_7_DAYS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_7_DAYS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_7_DAYS,\n dateFormat: ['MMM D', 'MMM D'],\n};\n\nconst LAST_30_DAYS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_30_DAYS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_30_DAYS,\n dateFormat: ['MMM YYYY'],\n};\n\nconst CURRENT_MONTH = {\n label: DATE_RANGE_SHORTCUTS_NAME.CURRENT_MONTH,\n dateRange: DATE_RANGE_SHORTCUTS.CURRENT_MONTH,\n dateFormat: ['MMM YYYY'],\n};\n\nconst THIS_QUARTER = {\n label: DATE_RANGE_SHORTCUTS_NAME.THIS_QUARTER,\n dateRange: DATE_RANGE_SHORTCUTS.THIS_QUARTER,\n dateFormat: ['MMM', 'MMM YYYY'],\n};\n\nconst THIS_YEAR = {\n label: DATE_RANGE_SHORTCUTS_NAME.THIS_YEAR,\n dateRange: DATE_RANGE_SHORTCUTS.THIS_YEAR,\n dateFormat: ['YYYY'],\n};\nconst LAST_MONTH = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_MONTH,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_MONTH,\n dateFormat: ['MMM YYYY'],\n};\nconst LAST_YEAR = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_YEAR,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_YEAR,\n dateFormat: ['YYYY'],\n};\nconst LAST_QUARTER = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_QUARTER,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_QUARTER,\n dateFormat: ['MMM', 'MMM YYYY'],\n};\nconst LAST_3_MONTHS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_3_MONTHS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_3_MONTHS,\n dateFormat: ['MMM YYYY', 'MMM YYYY'],\n};\nconst LAST_6_MONTHS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_6_MONTHS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_6_MONTHS,\n dateFormat: ['MMM YYYY', 'MMM YYYY'],\n};\n\nconst LAST_12_MONTHS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_12_MONTHS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_12_MONTHS,\n dateFormat: ['MMM YYYY', 'MMM YYYY'],\n};\n\nexport const RECOMMENDED_DATES = [LAST_7_DAYS, CURRENT_MONTH];\n\nexport const RELATIVE_DATES = [LAST_7_DAYS, LAST_30_DAYS];\n\nexport const CALENDAR_MONTH_DATES = [\n CURRENT_MONTH,\n THIS_QUARTER,\n THIS_YEAR,\n LAST_MONTH,\n LAST_QUARTER,\n LAST_YEAR,\n LAST_3_MONTHS,\n LAST_6_MONTHS,\n LAST_12_MONTHS,\n];\n\nexport interface TimeRangeFilterType {\n to: string;\n from: string;\n}\n\nexport const perspectiveDefaultTimeRangeMapper: Record<string, dayjs.Dayjs[]> =\n {\n [ViewTimeRangeType.Last_7]: DATE_RANGE_SHORTCUTS.LAST_7_DAYS,\n [ViewTimeRangeType.Last_30]: DATE_RANGE_SHORTCUTS.LAST_30_DAYS,\n [ViewTimeRangeType.LastMonth]: DATE_RANGE_SHORTCUTS.LAST_MONTH,\n [ViewTimeRangeType.CurrentMonth]: DATE_RANGE_SHORTCUTS.CURRENT_MONTH,\n };\n","export const fetchPerspectiveGridQuery = `query FetchperspectiveGrid(\n $filters: [QLCEViewFilterWrapperInput]\n $groupBy: [QLCEViewGroupByInput]\n $limit: Int\n $offset: Int\n $aggregateFunction: [QLCEViewAggregationInput]\n $isClusterOnly: Boolean!\n $isClusterHourlyData: Boolean = null\n $preferences: ViewPreferencesInput\n) {\n perspectiveGrid(\n aggregateFunction: $aggregateFunction\n filters: $filters\n groupBy: $groupBy\n limit: $limit\n offset: $offset\n preferences: $preferences\n isClusterHourlyData: $isClusterHourlyData\n sortCriteria: [{ sortType: COST, sortOrder: DESCENDING }]\n ) {\n data {\n name\n id\n cost\n costTrend\n clusterPerspective @include(if: $isClusterOnly)\n clusterData @include(if: $isClusterOnly) {\n appId\n appName\n avgCpuUtilization\n avgMemoryUtilization\n cloudProvider\n cloudProviderId\n cloudServiceName\n clusterId\n clusterName\n clusterType\n costTrend\n cpuBillingAmount\n cpuActualIdleCost\n cpuUnallocatedCost\n efficiencyScore\n efficiencyScoreTrendPercentage\n envId\n envName\n environment\n id\n idleCost\n launchType\n maxCpuUtilization\n maxMemoryUtilization\n memoryBillingAmount\n memoryActualIdleCost\n memoryUnallocatedCost\n name\n namespace\n networkCost\n prevBillingAmount\n region\n serviceId\n serviceName\n storageCost\n storageActualIdleCost\n storageRequest\n storageUnallocatedCost\n storageUtilizationValue\n totalCost\n trendType\n type\n unallocatedCost\n workloadName\n workloadType\n }\n instanceDetails @include(if: $isClusterOnly) {\n name\n id\n nodeId\n clusterName\n clusterId\n nodePoolName\n cloudProviderInstanceId\n podCapacity\n totalCost\n idleCost\n systemCost\n unallocatedCost\n cpuAllocatable\n memoryAllocatable\n instanceCategory\n machineType\n createTime\n deleteTime\n memoryBillingAmount\n cpuBillingAmount\n memoryUnallocatedCost\n cpuUnallocatedCost\n memoryIdleCost\n cpuIdleCost\n }\n storageDetails @include(if: $isClusterOnly) {\n id\n instanceId\n instanceName\n claimName\n claimNamespace\n clusterName\n clusterId\n storageClass\n volumeType\n cloudProvider\n region\n storageCost\n storageActualIdleCost\n storageUnallocatedCost\n capacity\n storageRequest\n storageUtilizationValue\n createTime\n deleteTime\n }\n }\n }\n perspectiveTotalCount(\n filters: $filters\n groupBy: $groupBy\n isClusterQuery: $isClusterOnly\n isClusterHourlyData: $isClusterHourlyData\n )\n}\n`;\n","import {\n FetchperspectiveGridQuery,\n FetchperspectiveGridQueryVariables,\n} from './types';\nimport useFetcher, { AsyncStatus } from '../hooks/useFetcher';\nimport { fetchPerspectiveGridQuery } from '../gql/fetchPerspectiveGrid';\n\ninterface UseFetchPerspectiveGridProps {\n accountId: string;\n variables: Partial<FetchperspectiveGridQueryVariables>;\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetchPerspectiveGridReturn {\n perspectiveGrid: FetchperspectiveGridQuery | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nconst useFetchPerspectiveGrid = ({\n ...props\n}: UseFetchPerspectiveGridProps): UseFetchPerspectiveGridReturn => {\n const body = JSON.stringify({\n query: fetchPerspectiveGridQuery,\n variables: props.variables,\n });\n\n const { data, ...fetcherProps } = useFetcher<{\n data: FetchperspectiveGridQuery;\n }>({\n ...props,\n method: 'POST',\n body,\n });\n\n return { perspectiveGrid: data?.data, ...fetcherProps };\n};\n\nexport default useFetchPerspectiveGrid;\n","export const fetchPerspectiveChartQuery = `query FetchPerspectiveTimeSeries(\n $filters: [QLCEViewFilterWrapperInput]\n $groupBy: [QLCEViewGroupByInput]\n $limit: Int\n $preferences: ViewPreferencesInput\n $isClusterHourlyData: Boolean = null\n) {\n perspectiveTimeSeriesStats(\n filters: $filters\n groupBy: $groupBy\n limit: $limit\n preferences: $preferences\n isClusterHourlyData: $isClusterHourlyData\n aggregateFunction: [{ operationType: SUM, columnName: \"cost\" }]\n sortCriteria: [{ sortType: COST, sortOrder: DESCENDING }]\n ) {\n stats {\n values {\n key {\n id\n name\n type\n }\n value\n }\n time\n }\n }\n}\n`;\n","import {\n FetchPerspectiveTimeSeriesQuery,\n FetchPerspectiveTimeSeriesQueryVariables,\n} from './types';\nimport useFetcher, { AsyncStatus } from '../hooks/useFetcher';\nimport { fetchPerspectiveChartQuery } from '../gql/fetchPerspectiveChart';\n\ninterface UseFetchPerspectiveChartProps {\n accountId: string;\n variables: Partial<FetchPerspectiveTimeSeriesQueryVariables>;\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetchPerspectiveChartReturn {\n perspectiveChart: FetchPerspectiveTimeSeriesQuery | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nconst useFetchPerspectiveChart = ({\n ...props\n}: UseFetchPerspectiveChartProps): UseFetchPerspectiveChartReturn => {\n const body = JSON.stringify({\n query: fetchPerspectiveChartQuery,\n variables: props.variables,\n });\n\n const { data, ...fetcherProps } = useFetcher<{\n data: FetchPerspectiveTimeSeriesQuery;\n }>({\n ...props,\n method: 'POST',\n body,\n });\n\n return { perspectiveChart: data?.data, ...fetcherProps };\n};\n\nexport default useFetchPerspectiveChart;\n","import { useState } from 'react';\nimport { getSecureHarnessKey } from '../utils/getHarnessToken';\nimport useAsyncRetry from 'react-use/lib/useAsyncRetry';\n\ninterface useGetLicenseWithAuthProps {\n env: string;\n accountId: string;\n backendBaseUrl: Promise<string>;\n}\nconst useGetLicense = ({\n backendBaseUrl,\n env,\n accountId,\n}: useGetLicenseWithAuthProps) => {\n const [licenses, setLicenses] = useState('SRM');\n\n useAsyncRetry(async () => {\n const token = getSecureHarnessKey('token');\n const value = token ? `${token}` : '';\n\n const headers = new Headers({\n Authorization: value,\n });\n\n const response = await fetch(\n `${await backendBaseUrl}/harness/${env}/gateway/ng/api/licenses/account?routingId=${accountId}&accountIdentifier=${accountId}`,\n {\n headers,\n },\n );\n\n if (response.status === 200) {\n const data = await response.json();\n if (data?.data?.allModuleLicenses?.CE?.length === 0) {\n setLicenses('NA');\n }\n } else if (response.status === 401) {\n setLicenses('Unauthorized');\n }\n }, [env, accountId]);\n\n return { licenses };\n};\n\nexport default useGetLicense;\n","import React from 'react';\nimport {\n Card,\n CardContent,\n CircularProgress,\n makeStyles,\n Typography,\n} from '@material-ui/core';\nimport ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';\nimport ArrowDropUpOutlinedIcon from '@mui/icons-material/ArrowDropUpOutlined';\n\nconst useStyles = makeStyles({\n costCtn: {\n padding: 20,\n },\n costCard: {\n minWidth: 250,\n minHeight: 130,\n },\n costDescription: {\n marginTop: 8,\n marginBottom: 8,\n },\n emptyState: {\n minWidth: 250,\n minHeight: 130,\n alignItems: 'center',\n justifyContent: 'center',\n },\n cardContent: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n },\n trendCtn: {\n display: 'flex',\n alignItems: 'center',\n },\n});\n\ninterface CostCardProps {\n isLoading: boolean;\n statsLabel: string;\n statsValue: string;\n statsDescription: string;\n statsTrend?: number;\n}\n\nconst CostCard: React.FC<CostCardProps> = ({\n isLoading,\n statsDescription,\n statsLabel,\n statsValue,\n statsTrend,\n}) => {\n const classes = useStyles();\n\n if (isLoading) {\n return (\n <Card className={classes.emptyState}>\n <CircularProgress />\n </Card>\n );\n }\n\n if (!statsValue) {\n return <></>;\n }\n\n return (\n <Card className={classes.costCard}>\n <CardContent className={classes.cardContent}>\n <div>\n <Typography variant=\"body2\">{statsLabel}</Typography>\n <Typography variant=\"h3\" className={classes.costDescription}>\n {statsValue}\n </Typography>\n <Typography variant=\"body2\">{statsDescription}</Typography>\n </div>\n {statsTrend ? (\n <div\n style={{ color: statsTrend >= 0 ? '#e43326' : '#4dc952' }}\n className={classes.trendCtn}\n >\n {statsTrend >= 0 ? (\n <ArrowDropUpOutlinedIcon style={{ color: '#e43326' }} />\n ) : (\n <ArrowDropDownOutlinedIcon style={{ color: '#4dc952' }} />\n )}\n {statsTrend < 0 ? statsTrend * -1 : statsTrend}%\n </div>\n ) : null}\n </CardContent>\n </Card>\n );\n};\n\nexport default CostCard;\n","import React from 'react';\nimport {\n BarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n ResponsiveContainer,\n AreaChart,\n Area,\n} from 'recharts';\nimport { CircularProgress, makeStyles } from '@material-ui/core';\nimport { TimeSeriesDataPoints, ViewVisualization } from '../../api/types';\n\nconst useStyles = makeStyles({\n chartCtn: {\n padding: 24,\n },\n emptyState: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n\nconst CE_COLOR_CONST_NEW = [\n '#0092E4', // Primary 6\n '#4947DD', // Blue 700\n '#42AB45', // Green 600\n '#FF832B', // Orange 500\n '#24807F', // Cloud Cost Management 300\n '#7D4DD3', // Purple 500\n '#FCC026', // Yellow 800\n '#EE5F54', // Red 400\n '#EE2A89', // Magenta 700\n '#954E02', // Brown\n '#0BC8D6', // Teal 500,\n '#7FB800', // Lime 500\n];\n\nconst OTHERS_COLOR_HEX = '#dae0ff';\n\nconst tickFormatter = (value: any) => `$${value.toLocaleString()}`;\n\ninterface PerspectivesChartProps {\n isLoading?: boolean;\n data: TimeSeriesDataPoints[];\n viewVisualization: ViewVisualization['chartType'];\n}\n\nconst PerspectivesChart: React.FC<PerspectivesChartProps> = ({\n isLoading,\n data,\n viewVisualization,\n}) => {\n const classes = useStyles();\n\n const formattedData = data?.map(stat => {\n const time = new Date(stat.time).toISOString().split('T')[0];\n const values = stat.values.reduce((acc, curr) => {\n (acc as any)[curr?.key.name || ''] = curr?.value;\n return acc;\n }, {});\n\n return { date: time, ...values };\n });\n\n const keys = Object.keys(formattedData[0] || {}).filter(\n key => key !== 'date',\n );\n\n if (isLoading) {\n return (\n <ResponsiveContainer\n width=\"100%\"\n height={500}\n className={classes.emptyState}\n >\n <CircularProgress />\n </ResponsiveContainer>\n );\n }\n\n return (\n <div className={classes.chartCtn}>\n <ResponsiveContainer width=\"100%\" height={500}>\n {viewVisualization === 'STACKED_TIME_SERIES' ? (\n <BarChart\n width={500}\n height={300}\n data={formattedData}\n margin={{\n top: 20,\n right: 30,\n left: 20,\n bottom: 5,\n }}\n >\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" />\n <YAxis tickFormatter={tickFormatter} />\n <Tooltip formatter={tickFormatter} />\n <Legend />\n {keys.map((key, idx) => (\n <Bar\n stackId=\"a\"\n key={key}\n dataKey={key}\n fill={\n key === 'Others'\n ? OTHERS_COLOR_HEX\n : CE_COLOR_CONST_NEW[idx % CE_COLOR_CONST_NEW.length]\n }\n />\n ))}\n </BarChart>\n ) : (\n <AreaChart\n width={730}\n height={250}\n data={formattedData}\n margin={{ top: 5, right: 30, left: 20, bottom: 5 }}\n >\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" />\n <YAxis tickFormatter={tickFormatter} />\n <Tooltip formatter={tickFormatter} />\n <Legend />\n {keys.map((key, idx) => (\n <Area\n type=\"monotone\"\n key={key}\n dataKey={key}\n fill={\n key === 'Others'\n ? OTHERS_COLOR_HEX\n : CE_COLOR_CONST_NEW[idx % CE_COLOR_CONST_NEW.length]\n }\n />\n ))}\n </AreaChart>\n )}\n </ResponsiveContainer>\n </div>\n );\n};\n\nexport default PerspectivesChart;\n","import React from 'react';\nimport { Typography } from '@material-ui/core';\nimport { Table, TableColumn } from '@backstage/core-components';\n\nimport ArrowDownwardOutlinedIcon from '@mui/icons-material/ArrowDownwardOutlined';\nimport ArrowUpwardOutlinedIcon from '@mui/icons-material/ArrowUpwardOutlined';\n\nimport { QlceViewEntityStatsDataPoint } from '../../api/types';\n\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n field: 'name',\n highlight: true,\n },\n {\n title: 'Cost',\n field: 'cost',\n render: (rowData: any) => (\n <Typography>\n {new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n }).format(rowData.cost)}\n </Typography>\n ),\n },\n {\n title: 'Cost Trend',\n field: 'costTrend',\n render: (rowData: any) => (\n <Typography>\n <div style={{ display: 'flex', alignItems: 'center' }}>\n {rowData.costTrend >= 0 ? (\n <ArrowUpwardOutlinedIcon style={{ color: '#e43326' }} />\n ) : (\n <ArrowDownwardOutlinedIcon style={{ color: '#4dc952' }} />\n )}\n {rowData.costTrend < 0 ? rowData.costTrend * -1 : rowData.costTrend}%\n </div>\n </Typography>\n ),\n },\n];\n\ninterface PerspectivesGridProps {\n isLoading: boolean;\n data: QlceViewEntityStatsDataPoint[];\n totalCount: number;\n page: number;\n handlePageChange: (page: number, pageSize: number) => void;\n}\n\nconst PerspectivesGrid: React.FC<PerspectivesGridProps> = ({\n isLoading,\n data,\n page,\n totalCount,\n handlePageChange,\n}) => {\n return (\n <div>\n <Table\n isLoading={isLoading}\n columns={columns}\n data={data}\n totalCount={\n (page + 1) * 15 < totalCount\n ? Number.MAX_VALUE\n : Number.MAX_SAFE_INTEGER\n }\n options={{\n search: false,\n paging: true,\n emptyRowsWhenPaging: false,\n paginationPosition: 'both',\n showFirstLastPageButtons: false,\n pageSize: Number.MAX_SAFE_INTEGER,\n pageSizeOptions: [],\n }}\n page={page > 0 ? 1 : 0}\n onPageChange={handlePageChange}\n localization={{\n pagination: {\n labelDisplayedRows: `(${page * 15 + 1} - ${\n (page + 1) * 15\n }) of ${totalCount}`,\n },\n }}\n />\n </div>\n );\n};\n\nexport default PerspectivesGrid;\n","import React, { useEffect, useState } from 'react';\nimport {\n Button,\n CircularProgress,\n Divider,\n makeStyles,\n Menu,\n MenuItem,\n Typography,\n} from '@material-ui/core';\n\nimport KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown';\n\nimport {\n CALENDAR_MONTH_DATES,\n CE_DATE_FORMAT_INTERNAL,\n DATE_RANGE_SHORTCUTS,\n DATE_RANGE_SHORTCUTS_NAME,\n DateLabelToDisplayTextMap,\n RECOMMENDED_DATES,\n RELATIVE_DATES,\n TimeRangeFilterType,\n} from '../../utils/PerpsectiveUtils';\nimport { Dayjs } from 'dayjs';\n\nconst useStyles = makeStyles({\n subHeader: {\n padding: '8px 16px',\n },\n dateCtn: {\n justifyContent: 'space-between',\n gap: 20,\n },\n dateRange: {\n color: '#b0b1c4',\n },\n divider: {\n margin: '8px 0px',\n },\n buttonCtn: {\n height: 36,\n },\n});\n\nconst DateRenderer = ({\n date,\n setTimeRange,\n setTimeLabel,\n handleClose,\n}: {\n date: {\n label: DATE_RANGE_SHORTCUTS_NAME;\n dateRange: Dayjs[];\n dateFormat: string[];\n };\n setTimeRange: (newValue: TimeRangeFilterType) => void;\n setTimeLabel: (newValue: DATE_RANGE_SHORTCUTS_NAME) => void;\n handleClose: () => void;\n}) => {\n const classes = useStyles();\n\n return (\n <MenuItem\n className={classes.dateCtn}\n onClick={() => {\n setTimeRange({\n from: date.dateRange[0].format(CE_DATE_FORMAT_INTERNAL),\n to: date.dateRange[1].format(CE_DATE_FORMAT_INTERNAL),\n });\n setTimeLabel(date.label);\n handleClose();\n }}\n >\n <span>{DateLabelToDisplayTextMap[date.label]}</span>\n <span>\n <Typography variant=\"body2\" className={classes.dateRange}>\n {`${date.dateRange[0].format(date.dateFormat[0])} ${\n date.dateFormat[1]\n ? `- ${date.dateRange[1].format(date.dateFormat[1])}`\n : ''\n }`}\n </Typography>\n </span>\n </MenuItem>\n );\n};\n\ninterface TimeFilterProps {\n isLoading?: boolean;\n timeRange: TimeRangeFilterType;\n setTimeRange: (newValue: TimeRangeFilterType) => void;\n}\n\nconst TimeFilter: React.FC<TimeFilterProps> = ({\n isLoading,\n timeRange,\n setTimeRange,\n}) => {\n const classes = useStyles();\n\n const [timeLabel, setTimeLabel] = useState<string>(\n DATE_RANGE_SHORTCUTS_NAME.LAST_30_DAYS,\n );\n\n useEffect(() => {\n if (!isLoading) {\n const filteredArray = Object.keys(DATE_RANGE_SHORTCUTS).filter(short => {\n const date = DATE_RANGE_SHORTCUTS[short];\n\n return (\n timeRange.from === date[0].format(CE_DATE_FORMAT_INTERNAL) &&\n timeRange.to === date[1].format(CE_DATE_FORMAT_INTERNAL)\n );\n });\n\n if (filteredArray.length) {\n setTimeLabel(filteredArray[0]);\n }\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isLoading]);\n\n const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);\n const open = Boolean(anchorEl);\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n const handleClose = () => {\n setAnchorEl(null);\n };\n\n return (\n <div>\n <Button\n id=\"basic-button\"\n aria-controls={open ? 'basic-menu' : undefined}\n aria-haspopup=\"true\"\n aria-expanded={open ? 'true' : undefined}\n onClick={handleClick}\n endIcon={<KeyboardArrowDown />}\n className={classes.buttonCtn}\n >\n {isLoading ? (\n <CircularProgress size={12} />\n ) : (\n DateLabelToDisplayTextMap[timeLabel]\n )}\n </Button>\n <Menu\n id=\"basic-menu\"\n anchorEl={anchorEl}\n open={open}\n onClose={handleClose}\n MenuListProps={{\n 'aria-labelledby': 'basic-button',\n }}\n >\n <Typography variant=\"subtitle2\" className={classes.subHeader}>\n Recommended\n </Typography>\n {RECOMMENDED_DATES.map(date => (\n <DateRenderer\n date={date}\n setTimeRange={setTimeRange}\n setTimeLabel={setTimeLabel}\n handleClose={handleClose}\n />\n ))}\n <Divider className={classes.divider} />\n <Typography variant=\"subtitle2\" className={classes.subHeader}>\n Relative\n </Typography>\n {RELATIVE_DATES.map(date => (\n <DateRenderer\n date={date}\n setTimeRange={setTimeRange}\n setTimeLabel={setTimeLabel}\n handleClose={handleClose}\n />\n ))}\n <Divider className={classes.divider} />\n <Typography variant=\"subtitle2\" className={classes.subHeader}>\n Calendar Months\n </Typography>\n {CALENDAR_MONTH_DATES.map(date => (\n <DateRenderer\n date={date}\n setTimeRange={setTimeRange}\n setTimeLabel={setTimeLabel}\n handleClose={handleClose}\n />\n ))}\n </Menu>\n </div>\n );\n};\n\nexport default TimeFilter;\n","import React from 'react';\nimport {\n Card,\n CardContent,\n CircularProgress,\n makeStyles,\n Typography,\n} from '@material-ui/core';\n\nconst useStyles = makeStyles({\n costCtn: {\n padding: 20,\n },\n costCard: {\n minWidth: 275,\n minHeight: 130,\n },\n emptyState: {\n minWidth: 275,\n minHeight: 130,\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n\ninterface RecommendationsCardProps {\n isLoading: boolean;\n totalSavings: number;\n recommendationsCount: number;\n}\n\nconst RecommendationsCard: React.FC<RecommendationsCardProps> = ({\n isLoading,\n totalSavings,\n recommendationsCount,\n}) => {\n const classes = useStyles();\n\n if (isLoading) {\n return (\n <Card className={classes.emptyState}>\n <CircularProgress />\n </Card>\n );\n }\n\n if (!totalSavings) {\n return <></>;\n }\n\n return (\n <Card className={classes.costCard}>\n <CardContent>\n <Typography variant=\"body2\">Recommendations</Typography>\n <Typography variant=\"caption\">\n {recommendationsCount} recommendation(s) saving upto\n </Typography>\n <Typography variant=\"h5\">{`$${totalSavings.toLocaleString()}`}</Typography>\n <Typography variant=\"body2\">per month</Typography>\n </CardContent>\n </Card>\n );\n};\n\nexport default RecommendationsCard;\n","export const fetchPerspectiveRecommendationsQuery = `query PerspectiveRecommendations($filter: K8sRecommendationFilterDTOInput) {\n recommendationStatsV2(filter: $filter) {\n totalMonthlyCost\n totalMonthlySaving\n count\n }\n}\n`;\n","import {\n PerspectiveRecommendationsQuery,\n PerspectiveRecommendationsQueryVariables,\n} from './types';\nimport useFetcher, { AsyncStatus } from '../hooks/useFetcher';\nimport { fetchPerspectiveRecommendationsQuery } from '../gql/fetchPerspectiveRecommendations';\n\ninterface UseFetchPerspectiveRecommendationsProps {\n accountId: string;\n variables: Partial<PerspectiveRecommendationsQueryVariables>;\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetchPerspectiveRecommendationsReturn {\n perspectiveRecommendations: PerspectiveRecommendationsQuery | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nconst useFetchPerspectiveRecommendations = ({\n ...props\n}: UseFetchPerspectiveRecommendationsProps): UseFetchPerspectiveRecommendationsReturn => {\n const body = JSON.stringify({\n query: fetchPerspectiveRecommendationsQuery,\n variables: props.variables,\n });\n\n const { data, ...fetcherProps } = useFetcher<{\n data: PerspectiveRecommendationsQuery;\n }>({\n ...props,\n method: 'POST',\n body,\n });\n\n return { perspectiveRecommendations: data?.data, ...fetcherProps };\n};\n\nexport default useFetchPerspectiveRecommendations;\n","import React, { useEffect, useState } from 'react';\nimport { EmptyState } from '@backstage/core-components';\nimport {\n Card,\n Grid,\n Link,\n makeStyles,\n Typography,\n Button,\n} from '@material-ui/core';\nimport { discoveryApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport LaunchIcon from '@mui/icons-material/Launch';\n\nimport { useResourceSlugFromEntity } from '../../hooks/useResourceSlugFromEntity';\nimport useFetchPerspectiveDetailsSummaryWithBudget from '../../api/useFetchPerspectiveDetailsSummaryWithBudget';\nimport useGetPerspective from '../../hooks/useGetPerspective';\n\nimport usePerspectiveUrlFromEntity from '../../hooks/usePerspectiveUrlEntity';\nimport {\n CE_DATE_FORMAT_INTERNAL,\n clusterInfoUtil,\n DATE_RANGE_SHORTCUTS,\n DEFAULT_GROUP_BY,\n DEFAULT_TIME_RANGE,\n getGMTEndDateTime,\n getGMTStartDateTime,\n getGroupByFilter,\n getTimeFilters,\n getTimeRangeFilter,\n getViewFilterForId,\n PERSPECTIVE_DETAILS_AGGREGATE,\n perspectiveDefaultTimeRangeMapper,\n TimeRangeFilterType,\n} from '../../utils/PerpsectiveUtils';\nimport {\n AsyncStatus,\n K8sRecommendationFilterDtoInput,\n QlceViewEntityStatsDataPoint,\n QlceViewTimeGroupType,\n TimeSeriesDataPoints,\n} from '../../api/types';\nimport useFetchPerspectiveGrid from '../../api/useFetchPerspectiveGrid';\nimport useFetchPerspectiveChart from '../../api/useFetchPerspectiveChart';\nimport useGetLicense from '../../hooks/useGetLicense';\n\nimport CostCard from '../CostCard';\nimport PerspectivesChart from '../PerspectivesChart/PerspectivesChart';\nimport PerspectivesGrid from '../PerspectivesGrid/PerspectivesGrid';\nimport TimeFilter from '../TimeFilter/TimeFilter';\nimport RecommendationsCard from '../RecommendationsCard';\nimport useFetchPerspectiveRecommendations from '../../api/useFetchPerspectiveRecommendations';\n\nconst useStyles = makeStyles({\n subHeader: {\n display: 'flex',\n flexDirection: 'row-reverse',\n marginBottom: 20,\n },\n chartAndGridCtn: {\n marginTop: 24,\n },\n linkCard: {\n padding: 20,\n height: 125,\n gap: 16,\n },\n linkCtn: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n },\n});\n\nconst PerspectivesPage: React.FC = () => {\n const classes = useStyles();\n const discoveryApi = useApi(discoveryApiRef);\n const backendBaseUrl = discoveryApi.getBaseUrl('proxy');\n\n const perspectiveUrl = usePerspectiveUrlFromEntity();\n const {\n accountId,\n envFromUrl = '',\n perspectiveId,\n baseUrl,\n } = useResourceSlugFromEntity(perspectiveUrl);\n\n const { perspective: perspectiveData, status } = useGetPerspective({\n accountId,\n backendBaseUrl,\n perspectiveId,\n envFromUrl,\n });\n\n const isPerspectiveLoading = status === AsyncStatus.Loading;\n\n const { isClusterOnly, recommendationsEnabled } = clusterInfoUtil(\n perspectiveData?.dataSources,\n );\n\n const [timeRange, setTimeRange] =\n useState<TimeRangeFilterType>(DEFAULT_TIME_RANGE);\n\n useEffect(() => {\n if (perspectiveData?.viewTimeRange) {\n const viewTimeRangeType =\n perspectiveData.viewTimeRange?.viewTimeRangeType;\n\n const dateRange =\n (viewTimeRangeType &&\n perspectiveDefaultTimeRangeMapper[viewTimeRangeType]) ||\n DATE_RANGE_SHORTCUTS.LAST_30_DAYS;\n\n setTimeRange({\n to: dateRange[1].format(CE_DATE_FORMAT_INTERNAL),\n from: dateRange[0].format(CE_DATE_FORMAT_INTERNAL),\n });\n }\n }, [perspectiveData]);\n\n const groupBy =\n perspectiveData?.viewVisualization?.groupBy || DEFAULT_GROUP_BY;\n const aggregation =\n perspectiveData?.viewVisualization?.granularity ||\n QlceViewTimeGroupType.Day;\n\n const isPerspectiveReady = !isPerspectiveLoading && perspectiveData;\n\n const { perspectiveSummary, loading: isSummaryLoading } =\n useFetchPerspectiveDetailsSummaryWithBudget({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n aggregateFunction: PERSPECTIVE_DETAILS_AGGREGATE,\n filters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n groupBy: [getGroupByFilter(groupBy)],\n isClusterHourlyData: false,\n isClusterQuery: false,\n preferences: perspectiveData?.viewPreferences,\n },\n lazy: !isPerspectiveReady,\n });\n\n const [page, setPage] = useState(0);\n\n const handleChangePage = (currentPage: number) => {\n setPage(currentPage);\n };\n\n const { perspectiveRecommendations, loading: areRecommendationsLoading } =\n useFetchPerspectiveRecommendations({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n filter: {\n perspectiveFilters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n minSaving: 1,\n offset: 0,\n limit: 10,\n } as unknown as K8sRecommendationFilterDtoInput,\n },\n lazy: !isPerspectiveReady,\n });\n\n const { perspectiveChart, loading: isChartLoading } =\n useFetchPerspectiveChart({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n filters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n groupBy: [getTimeRangeFilter(aggregation), getGroupByFilter(groupBy)],\n isClusterHourlyData: false,\n limit: 12,\n preferences: perspectiveData?.viewPreferences,\n },\n lazy: !isPerspectiveReady,\n });\n\n const { perspectiveGrid, loading: isGridLoading } = useFetchPerspectiveGrid({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n aggregateFunction: PERSPECTIVE_DETAILS_AGGREGATE,\n filters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n groupBy: [getGroupByFilter(groupBy)],\n isClusterHourlyData: false,\n isClusterOnly,\n preferences: perspectiveData?.viewPreferences,\n limit: 15,\n offset: page * 15,\n },\n lazy: !isPerspectiveReady,\n });\n\n const totalCostStats = perspectiveSummary?.perspectiveTrendStats?.cost;\n const forecastedCostStats = perspectiveSummary?.perspectiveForecastCost?.cost;\n\n const chartData = perspectiveChart?.perspectiveTimeSeriesStats\n ?.stats as TimeSeriesDataPoints[];\n const gridData = perspectiveGrid?.perspectiveGrid\n ?.data as QlceViewEntityStatsDataPoint[];\n\n const { licenses } = useGetLicense({\n backendBaseUrl,\n env: envFromUrl,\n accountId,\n });\n\n const getCcmGetStartedLink = () =>\n `${baseUrl}/ng/account/${accountId}/ce/home/trial`;\n\n if (licenses === 'NA') {\n return (\n <EmptyState\n title=\"Cloud Cost Management Module License not subscribed\"\n missing=\"info\"\n description=\"You need to have an active Cloud Cost Management Module License to view this page.\"\n action={\n <Button\n variant=\"contained\"\n color=\"primary\"\n target=\"_blank\"\n href={getCcmGetStartedLink()}\n >\n Get Started\n </Button>\n }\n />\n );\n } else if (licenses === 'Unauthorized') {\n return (\n <EmptyState\n title=\"Harness Cloud Cost Management\"\n missing=\"info\"\n description=\"The x-api-key is either missing or incorrect in app-config.yaml under proxy settings.\"\n />\n );\n }\n\n if (status === AsyncStatus.Forbidden) {\n return (\n <EmptyState\n title=\"Harness Cloud Cost Management\"\n missing=\"info\"\n description=\"You don't have access to view this Perspective\"\n />\n );\n }\n\n return (\n <div>\n <div className={classes.subHeader}>\n <TimeFilter\n isLoading={isPerspectiveLoading}\n timeRange={timeRange}\n setTimeRange={setTimeRange}\n />\n </div>\n <Grid container spacing={3} direction=\"row\">\n <Grid item>\n <CostCard\n isLoading={isSummaryLoading || isPerspectiveLoading}\n statsLabel={totalCostStats?.statsLabel || ''}\n statsValue={totalCostStats?.statsValue || ''}\n statsDescription={totalCostStats?.statsDescription || ''}\n statsTrend={totalCostStats?.statsTrend}\n />\n </Grid>\n <Grid item>\n <CostCard\n isLoading={isSummaryLoading || isPerspectiveLoading}\n statsLabel={forecastedCostStats?.statsLabel || ''}\n statsValue={forecastedCostStats?.statsValue || ''}\n statsDescription={forecastedCostStats?.statsDescription || ''}\n />\n </Grid>\n {recommendationsEnabled ? (\n <Grid item>\n <RecommendationsCard\n isLoading={areRecommendationsLoading}\n totalSavings={\n perspectiveRecommendations?.recommendationStatsV2\n ?.totalMonthlySaving || 0\n }\n recommendationsCount={\n perspectiveRecommendations?.recommendationStatsV2?.count || 0\n }\n />\n </Grid>\n ) : null}\n <div style={{ flexGrow: 1 }} />\n <Grid item>\n <Card className={classes.linkCard}>\n <Typography variant=\"h6\">Want to see a detailed view?</Typography>\n <Link\n href={perspectiveUrl}\n target=\"_blank\"\n className={classes.linkCtn}\n >\n Go to {perspectiveData?.name} Perspective{' '}\n <LaunchIcon fontSize=\"small\" />\n </Link>\n </Card>\n </Grid>\n </Grid>\n <Card className={classes.chartAndGridCtn}>\n <PerspectivesChart\n isLoading={isChartLoading || isPerspectiveLoading}\n viewVisualization={perspectiveData?.viewVisualization?.chartType}\n data={chartData || []}\n />\n <PerspectivesGrid\n isLoading={isGridLoading || isPerspectiveLoading}\n data={gridData || []}\n totalCount={perspectiveGrid?.perspectiveTotalCount || 0}\n page={page}\n handlePageChange={handleChangePage}\n />\n </Card>\n </div>\n );\n};\n\nexport default PerspectivesPage;\n","import React from 'react';\nimport { Routes, Route } from 'react-router';\nimport { Entity } from '@backstage/catalog-model';\nimport {\n MissingAnnotationEmptyState,\n useEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport PerspectivesPage from './PerspectivesPage';\n\n/** @public */\nexport const isHarnessCcmAvailable = (entity: Entity) =>\n Boolean(entity.metadata.annotations?.['harness.io/perspective-url']);\n\n/** @public */\nexport const Router = () => {\n const { entity } = useEntity();\n\n if (!isHarnessCcmAvailable(entity)) {\n return (\n <>\n <MissingAnnotationEmptyState annotation=\"harness.io/perspective-url\" />\n </>\n );\n }\n\n return (\n <Routes>\n <Route path=\"/\" element={<PerspectivesPage />} />\n </Routes>\n );\n};\n"],"names":["AsyncStatus","ViewFieldIdentifier","QlceViewTimeGroupType","QlceViewTimeFilterOperator","QlceViewAggregateOperation","ViewTimeRangeType","DATE_RANGE_SHORTCUTS_NAME","useStyles","_a"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -20,4 +20,6 @@ declare const isHarnessCcmAvailable: (entity: Entity) => boolean;
|
|
|
20
20
|
/** @public */
|
|
21
21
|
declare const Router: () => React__default.JSX.Element;
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
declare const rootRouteRef: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
24
|
+
|
|
25
|
+
export { EntityCcmContent, EntityCcmOverviewCard, Router, harnessCcmPlugin, isHarnessCcmAvailable, rootRouteRef };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { E as EntityCcmContent, l as EntityCcmOverviewCard, R as Router, m as harnessCcmPlugin, j as isHarnessCcmAvailable } from './esm/index-
|
|
1
|
+
export { E as EntityCcmContent, l as EntityCcmOverviewCard, R as Router, m as harnessCcmPlugin, j as isHarnessCcmAvailable, r as rootRouteRef } from './esm/index-44451033.esm.js';
|
|
2
2
|
import '@backstage/core-plugin-api';
|
|
3
3
|
import 'react';
|
|
4
4
|
import 'react-router';
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-38352c6f.esm.js","sources":["../../src/routes.ts","../../src/plugin.ts","../../src/hooks/useResourceSlugFromEntity.tsx","../../src/utils/getHarnessToken.ts","../../src/hooks/useFetcher.tsx","../../src/gql/fetchPerspectiveDetailsWithBudgetSummary.ts","../../src/api/useFetchPerspectiveDetailsSummaryWithBudget.ts","../../src/api/types.ts","../../src/hooks/useGetPerspective.ts","../../src/hooks/usePerspectiveUrlEntity.ts","../../src/utils/PerpsectiveUtils.tsx","../../src/gql/fetchPerspectiveGrid.ts","../../src/api/useFetchPerspectiveGrid.ts","../../src/gql/fetchPerspectiveChart.ts","../../src/api/useFetchPerspectiveChart.ts","../../src/hooks/useGetLicense.ts","../../src/components/CostCard/CostCard.tsx","../../src/components/PerspectivesChart/PerspectivesChart.tsx","../../src/components/PerspectivesGrid/PerspectivesGrid.tsx","../../src/components/TimeFilter/TimeFilter.tsx","../../src/components/RecommendationsCard/RecommendationsCard.tsx","../../src/gql/fetchPerspectiveRecommendations.ts","../../src/api/useFetchPerspectiveRecommendations.ts","../../src/components/PerspectivesPage/PerspectivesPage.tsx","../../src/components/Router.tsx"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'harness-ccm',\n});\n","import {\n createComponentExtension,\n createPlugin,\n createRoutableExtension,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { OverviewCardProps } from './components/OverviewCard/OverviewCard';\n\nexport const harnessCcmPlugin = createPlugin({\n id: 'harness-ccm',\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport const EntityCcmContent = harnessCcmPlugin.provide(\n createRoutableExtension({\n name: 'HarnessCcmPage',\n component: () => import('./components/Router').then(m => m.Router),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const EntityCcmOverviewCard: (props: OverviewCardProps) => JSX.Element =\n harnessCcmPlugin.provide(\n createComponentExtension({\n name: 'EntityCcmOverviewCard',\n component: {\n lazy: () =>\n import('./components/OverviewCard/OverviewCard').then(m => m.default),\n },\n }),\n );\n","import { match } from 'path-to-regexp';\n\nexport const useResourceSlugFromEntity = (perspectiveUrl?: string) => {\n const cleanedString = perspectiveUrl?.split(' ')[0];\n let accountId;\n let orgId;\n let projectId;\n let perspectiveId;\n\n let urlMatch;\n\n const containsModule = perspectiveUrl?.includes('/module/');\n const containsAll = perspectiveUrl?.includes('/all/');\n\n if (containsModule) {\n urlMatch = match(\n '(.*)/account/:accountId/module/:module/perspectives/:perspectiveId/(.*)',\n {\n decode: decodeURIComponent,\n },\n );\n } else if (containsAll) {\n urlMatch = match(\n '(.*)/account/:accountId/all/:module/perspectives/:perspectiveId/(.*)',\n {\n decode: decodeURIComponent,\n },\n );\n } else {\n urlMatch = match(\n '(.*)/account/:accountId/:module/perspectives/:perspectiveId/(.*)',\n {\n decode: decodeURIComponent,\n },\n );\n }\n\n if (cleanedString) {\n const hostname = new URL(cleanedString).hostname;\n const baseUrl = new URL(cleanedString).origin;\n\n const envAB = hostname.split('.harness.io')[0];\n const envFromUrl = envAB.includes('qa') ? 'qa' : 'prod';\n\n const urlParams: any = urlMatch(cleanedString ?? '');\n\n if (urlParams) {\n accountId = urlParams.params.accountId;\n orgId = urlParams.params.orgId;\n projectId = urlParams.params.projectId;\n perspectiveId = urlParams.params.perspectiveId;\n }\n\n return {\n projectId,\n perspectiveId,\n orgId,\n accountId,\n urlParams,\n envFromUrl,\n cleanedString,\n baseUrl,\n };\n }\n\n return {};\n};\n","export function getSecureHarnessKey(key: string): string | undefined {\n try {\n const token = JSON.parse(decodeURI(atob(localStorage.getItem(key) || '')));\n return token ? `Bearer ${token}` : '';\n } catch (err) {\n // eslint-disable-next-line no-console\n console.log('Failed to read Harness tokens');\n return undefined;\n }\n}\n","import { useState } from 'react';\nimport useAsyncRetry from 'react-use/lib/useAsyncRetry';\nimport { getSecureHarnessKey } from '../utils/getHarnessToken';\n\nexport enum AsyncStatus {\n Init,\n Loading,\n Success,\n Error,\n Unauthorized,\n}\n\ninterface UseFetcherProps {\n accountId: string;\n body?: string;\n method: 'GET' | 'POST';\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetcherReturn<T> {\n data: T | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nfunction useFetcher<T>({\n accountId,\n body = '',\n method = 'POST',\n env,\n backendBaseUrl,\n lazy,\n}: UseFetcherProps): UseFetcherReturn<T> {\n const [status, setStatus] = useState(AsyncStatus.Init);\n\n const {\n value: data,\n loading,\n error,\n retry: refetch,\n } = useAsyncRetry(async (): Promise<T | undefined> => {\n if (!lazy) {\n const query = new URLSearchParams({\n routingId: `${accountId}`,\n });\n\n const token = getSecureHarnessKey('token');\n const auth = token ? `${token}` : '';\n\n const headers = new Headers({\n 'content-type': 'application/json',\n Authorization: auth,\n });\n\n setStatus(AsyncStatus.Loading);\n\n const response = await fetch(\n `${await backendBaseUrl}/harness/${env}/gateway/ccm/api/graphql?${query}`,\n {\n headers,\n method,\n body,\n },\n );\n\n if (response.status === 200) {\n const responseData = await response.json();\n setStatus(AsyncStatus.Success);\n return responseData;\n } else if (response.status === 401) {\n setStatus(AsyncStatus.Unauthorized);\n return undefined;\n }\n setStatus(AsyncStatus.Error);\n return undefined;\n }\n\n return undefined;\n }, [accountId, body, method, env, lazy]);\n\n return { status, data, loading, error, refetch };\n}\n\nexport default useFetcher;\n","export const fetchPerspectiveDetailsWithBudgetSummaryQuery = `\n query FetchPerspectiveDetailsSummaryWithBudget(\n $filters: [QLCEViewFilterWrapperInput]\n $aggregateFunction: [QLCEViewAggregationInput]\n $isClusterQuery: Boolean\n $isClusterHourlyData: Boolean = null\n $groupBy: [QLCEViewGroupByInput]\n $preferences: ViewPreferencesInput\n ) {\n perspectiveTrendStats(\n filters: $filters\n aggregateFunction: $aggregateFunction\n isClusterQuery: $isClusterQuery\n isClusterHourlyData: $isClusterHourlyData\n groupBy: $groupBy\n preferences: $preferences\n ) {\n cost {\n statsDescription\n statsLabel\n statsTrend\n statsValue\n value\n }\n idleCost {\n statsLabel\n statsValue\n value\n }\n unallocatedCost {\n statsLabel\n statsValue\n value\n }\n utilizedCost {\n statsLabel\n statsValue\n value\n }\n efficiencyScoreStats {\n statsLabel\n statsTrend\n statsValue\n }\n }\n perspectiveForecastCost(\n filters: $filters\n aggregateFunction: $aggregateFunction\n isClusterQuery: $isClusterQuery\n isClusterHourlyData: $isClusterHourlyData\n groupBy: $groupBy\n preferences: $preferences\n ) {\n cost {\n statsLabel\n statsTrend\n statsValue\n statsDescription\n value\n }\n }\n }\n`;\n","import {\n FetchPerspectiveDetailsSummaryWithBudgetQuery,\n FetchPerspectiveDetailsSummaryWithBudgetQueryVariables,\n} from './types';\nimport useFetcher, { AsyncStatus } from '../hooks/useFetcher';\nimport { fetchPerspectiveDetailsWithBudgetSummaryQuery } from '../gql/fetchPerspectiveDetailsWithBudgetSummary';\n\ninterface UseFetchPerspectiveDetailsSummaryWithBudgetProps {\n accountId: string;\n variables: Partial<FetchPerspectiveDetailsSummaryWithBudgetQueryVariables>;\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetchPerspectiveDetailsSummaryWithBudgetReturn {\n perspectiveSummary: FetchPerspectiveDetailsSummaryWithBudgetQuery | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nconst useFetchPerspectiveDetailsSummaryWithBudget = ({\n ...props\n}: UseFetchPerspectiveDetailsSummaryWithBudgetProps): UseFetchPerspectiveDetailsSummaryWithBudgetReturn => {\n const body = JSON.stringify({\n query: fetchPerspectiveDetailsWithBudgetSummaryQuery,\n variables: props.variables,\n });\n\n const { data, ...fetcherProps } = useFetcher<{\n data: FetchPerspectiveDetailsSummaryWithBudgetQuery;\n }>({\n ...props,\n method: 'POST',\n body,\n });\n\n return { perspectiveSummary: data?.data, ...fetcherProps };\n};\n\nexport default useFetchPerspectiveDetailsSummaryWithBudget;\n","export type Maybe<T> = T | null;\nexport type InputMaybe<T> = Maybe<T>;\nexport type Exact<T extends { [key: string]: unknown }> = {\n [K in keyof T]: T[K];\n};\n\nexport enum AsyncStatus {\n Init,\n Loading,\n Success,\n Error,\n Unauthorized,\n Forbidden,\n}\n\nexport type Scalars = {\n ID: string;\n String: string;\n Boolean: boolean;\n Int: number;\n Float: number;\n /** Built-in java.math.BigDecimal */\n BigDecimal: any;\n /** Built-in scalar representing an instant in time */\n Date: any;\n /** Long type */\n Long: any;\n /** Built-in scalar for map-like structures */\n Map_String_ContainerRecommendationScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_Map_String_StringScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_ObjectScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_ResourceRequirementScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_ServiceNowFieldValueNGScalar: any;\n /** Built-in scalar for map-like structures */\n Map_String_StringScalar: any;\n /** Built-in scalar representing a date-time with a UTC offset */\n OffsetDateTime: any;\n /** Built-in scalar representing a time with a UTC offset */\n OffsetTime: any;\n /** Use SPQR's SchemaPrinter to remove this from SDL */\n UNREPRESENTABLE: any;\n};\n\nexport type QlceViewFieldInputInput = {\n fieldId: Scalars['String'];\n fieldName: Scalars['String'];\n identifier: ViewFieldIdentifier;\n identifierName: InputMaybe<Scalars['String']>;\n};\n\nexport enum ViewFieldIdentifier {\n Aws = 'AWS',\n Azure = 'AZURE',\n BusinessMapping = 'BUSINESS_MAPPING',\n Cluster = 'CLUSTER',\n Common = 'COMMON',\n Custom = 'CUSTOM',\n Gcp = 'GCP',\n Label = 'LABEL',\n}\n\nexport enum QlceViewFilterOperator {\n Equals = 'EQUALS',\n In = 'IN',\n Like = 'LIKE',\n NotIn = 'NOT_IN',\n NotNull = 'NOT_NULL',\n Null = 'NULL',\n Search = 'SEARCH',\n}\n\nexport enum QlceViewTimeGroupType {\n Day = 'DAY',\n Hour = 'HOUR',\n Month = 'MONTH',\n Quarter = 'QUARTER',\n Week = 'WEEK',\n Year = 'YEAR',\n}\n\nexport type QlceViewTimeTruncGroupByInput = {\n resolution: QlceViewTimeGroupType;\n};\n\nexport type QlceViewFilterInput = {\n field: QlceViewFieldInputInput;\n operator: QlceViewFilterOperator;\n values: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n};\n\nexport type QlceViewRuleInput = {\n conditions: InputMaybe<Array<InputMaybe<QlceViewFilterInput>>>;\n};\n\nexport enum QlceViewTimeFilterOperator {\n After = 'AFTER',\n Before = 'BEFORE',\n}\n\nexport type QlceViewTimeFilterInput = {\n field: QlceViewFieldInputInput;\n operator: QlceViewTimeFilterOperator;\n value: Scalars['BigDecimal'];\n};\n\nexport type QlceViewFilterWrapperInput = {\n idFilter: InputMaybe<QlceViewFilterInput>;\n inExpressionFilter: InputMaybe<QlceInExpressionFilterInput>;\n ruleFilter: InputMaybe<QlceViewRuleInput>;\n timeFilter: InputMaybe<QlceViewTimeFilterInput>;\n viewMetadataFilter: InputMaybe<QlceViewMetadataFilterInput>;\n};\n\nexport type QlceViewGroupByInput = {\n entityGroupBy: InputMaybe<QlceViewFieldInputInput>;\n timeTruncGroupBy: InputMaybe<QlceViewTimeTruncGroupByInput>;\n};\n\nexport type QlceViewMetadataFilterInput = {\n isPreview: Scalars['Boolean'];\n viewId: Scalars['String'];\n};\n\nexport enum QlceViewAggregateOperation {\n Avg = 'AVG',\n Max = 'MAX',\n Min = 'MIN',\n Sum = 'SUM',\n}\n\nexport type QlceViewAggregationInput = {\n columnName: Scalars['String'];\n operationType: QlceViewAggregateOperation;\n};\n\nexport enum AwsViewPreferenceCost {\n Amortised = 'AMORTISED',\n Blended = 'BLENDED',\n Effective = 'EFFECTIVE',\n NetAmortised = 'NET_AMORTISED',\n Unblended = 'UNBLENDED',\n}\n\nexport type AwsViewPreferences = {\n __typename?: 'AWSViewPreferences';\n awsCost: Maybe<AwsViewPreferenceCost>;\n includeCredits: Maybe<Scalars['Boolean']>;\n includeDiscounts: Maybe<Scalars['Boolean']>;\n includeRefunds: Maybe<Scalars['Boolean']>;\n includeTaxes: Maybe<Scalars['Boolean']>;\n};\n\nexport type AwsViewPreferencesInput = {\n awsCost: InputMaybe<AwsViewPreferenceCost>;\n includeCredits: InputMaybe<Scalars['Boolean']>;\n includeDiscounts: InputMaybe<Scalars['Boolean']>;\n includeRefunds: InputMaybe<Scalars['Boolean']>;\n includeTaxes: InputMaybe<Scalars['Boolean']>;\n};\n\nexport enum AzureCostType {\n Actual = 'ACTUAL',\n Amortized = 'AMORTIZED',\n}\n\nexport type AzureViewPreferences = {\n __typename?: 'AzureViewPreferences';\n costType: Maybe<AzureCostType>;\n};\n\nexport type AzureViewPreferencesInput = {\n costType: InputMaybe<AzureCostType>;\n};\n\nexport type GcpViewPreferences = {\n __typename?: 'GCPViewPreferences';\n includeDiscounts: Maybe<Scalars['Boolean']>;\n includeTaxes: Maybe<Scalars['Boolean']>;\n};\n\nexport type GcpViewPreferencesInput = {\n includeDiscounts: InputMaybe<Scalars['Boolean']>;\n includeTaxes: InputMaybe<Scalars['Boolean']>;\n};\n\nexport type ViewPreferencesInput = {\n awsPreferences: InputMaybe<AwsViewPreferencesInput>;\n azureViewPreferences: InputMaybe<AzureViewPreferencesInput>;\n gcpPreferences: InputMaybe<GcpViewPreferencesInput>;\n includeOthers: InputMaybe<Scalars['Boolean']>;\n includeUnallocatedCost: InputMaybe<Scalars['Boolean']>;\n showAnomalies: InputMaybe<Scalars['Boolean']>;\n};\n\nexport type FetchPerspectiveDetailsSummaryWithBudgetQueryVariables = Exact<{\n filters: InputMaybe<\n | Array<InputMaybe<QlceViewFilterWrapperInput>>\n | InputMaybe<QlceViewFilterWrapperInput>\n >;\n aggregateFunction: InputMaybe<\n | Array<InputMaybe<QlceViewAggregationInput>>\n | InputMaybe<QlceViewAggregationInput>\n >;\n isClusterQuery: InputMaybe<Scalars['Boolean']>;\n isClusterHourlyData?: InputMaybe<Scalars['Boolean']>;\n groupBy: InputMaybe<\n Array<InputMaybe<QlceViewGroupByInput>> | InputMaybe<QlceViewGroupByInput>\n >;\n preferences: InputMaybe<ViewPreferencesInput>;\n}>;\n\nexport type QlceInExpressionFilterInput = {\n fields: Array<InputMaybe<QlceViewFieldInputInput>>;\n nullValueField: InputMaybe<Scalars['String']>;\n values: Array<InputMaybe<Array<InputMaybe<Scalars['String']>>>>;\n};\n\nexport type FetchPerspectiveDetailsSummaryWithBudgetQuery = {\n perspectiveTrendStats: {\n cost: {\n statsDescription: string;\n statsLabel: string;\n statsTrend: any | null;\n statsValue: string;\n value: any | null;\n } | null;\n idleCost: {\n statsLabel: string;\n statsValue: string;\n value: any | null;\n } | null;\n unallocatedCost: {\n statsLabel: string;\n statsValue: string;\n value: any | null;\n } | null;\n utilizedCost: {\n statsLabel: string;\n statsValue: string;\n value: any | null;\n } | null;\n efficiencyScoreStats: {\n statsLabel: string | null;\n statsTrend: any | null;\n statsValue: string | null;\n } | null;\n } | null;\n perspectiveForecastCost: {\n cost: {\n statsLabel: string;\n statsTrend: any | null;\n statsValue: string;\n statsDescription: string;\n value: any | null;\n } | null;\n } | null;\n};\n\nexport interface EmbeddedUser {\n email?: string;\n externalUserId?: string;\n name?: string;\n uuid?: string;\n}\n\nexport interface ViewCondition {\n type?: string;\n}\n\nexport interface ViewRule {\n viewConditions?: ViewCondition[];\n}\n\nexport interface ViewTimeRange {\n endTime?: number;\n startTime?: number;\n viewTimeRangeType?:\n | 'LAST_7'\n | 'LAST_30'\n | 'LAST_MONTH'\n | 'CURRENT_MONTH'\n | 'CUSTOM';\n}\n\nexport interface ViewField {\n fieldId?: string;\n fieldName?: string;\n identifier?:\n | 'CLUSTER'\n | 'AWS'\n | 'GCP'\n | 'AZURE'\n | 'COMMON'\n | 'CUSTOM'\n | 'BUSINESS_MAPPING'\n | 'LABEL';\n identifierName?: string;\n}\n\nexport interface ViewVisualization {\n chartType?: 'STACKED_TIME_SERIES' | 'STACKED_LINE_CHART';\n granularity?: 'DAY' | 'MONTH';\n groupBy?: ViewField;\n}\n\nexport interface CEView {\n accountId?: string;\n createdAt?: number;\n createdBy?: EmbeddedUser;\n dataSources?: (\n | 'CLUSTER'\n | 'AWS'\n | 'GCP'\n | 'AZURE'\n | 'COMMON'\n | 'CUSTOM'\n | 'BUSINESS_MAPPING'\n | 'LABEL'\n )[];\n folderId?: string;\n lastUpdatedAt?: number;\n lastUpdatedBy?: EmbeddedUser;\n name?: string;\n totalCost?: number;\n uuid?: string;\n viewPreferences?: ViewPreferencesInput;\n viewRules?: ViewRule[];\n viewState?: 'DRAFT' | 'COMPLETED';\n viewTimeRange?: ViewTimeRange;\n viewType?: 'SAMPLE' | 'CUSTOMER' | 'DEFAULT';\n viewVersion?: string;\n viewVisualization?: ViewVisualization;\n}\n\nexport type FetchperspectiveGridQueryVariables = Exact<{\n filters: InputMaybe<\n | Array<InputMaybe<QlceViewFilterWrapperInput>>\n | InputMaybe<QlceViewFilterWrapperInput>\n >;\n groupBy: InputMaybe<\n Array<InputMaybe<QlceViewGroupByInput>> | InputMaybe<QlceViewGroupByInput>\n >;\n limit: InputMaybe<Scalars['Int']>;\n offset: InputMaybe<Scalars['Int']>;\n aggregateFunction: InputMaybe<\n | Array<InputMaybe<QlceViewAggregationInput>>\n | InputMaybe<QlceViewAggregationInput>\n >;\n isClusterOnly: Scalars['Boolean'];\n isClusterHourlyData?: InputMaybe<Scalars['Boolean']>;\n preferences: InputMaybe<ViewPreferencesInput>;\n}>;\n\nexport type FetchperspectiveGridQuery = {\n __typename?: 'Query';\n perspectiveTotalCount: number | null;\n perspectiveGrid: {\n __typename?: 'PerspectiveEntityStatsData';\n data: Array<{\n __typename?: 'QLCEViewEntityStatsDataPoint';\n name: string | null;\n id: string | null;\n cost: any | null;\n costTrend: any | null;\n clusterPerspective?: boolean;\n clusterData?: {\n __typename?: 'ClusterData';\n appId: string | null;\n appName: string | null;\n avgCpuUtilization: number | null;\n avgMemoryUtilization: number | null;\n cloudProvider: string | null;\n cloudProviderId: string | null;\n cloudServiceName: string | null;\n clusterId: string | null;\n clusterName: string | null;\n clusterType: string | null;\n costTrend: number | null;\n cpuBillingAmount: number | null;\n cpuActualIdleCost: number | null;\n cpuUnallocatedCost: number | null;\n efficiencyScore: number;\n efficiencyScoreTrendPercentage: number;\n envId: string | null;\n envName: string | null;\n environment: string | null;\n id: string | null;\n idleCost: number | null;\n launchType: string | null;\n maxCpuUtilization: number | null;\n maxMemoryUtilization: number | null;\n memoryBillingAmount: number | null;\n memoryActualIdleCost: number | null;\n memoryUnallocatedCost: number | null;\n name: string | null;\n namespace: string | null;\n networkCost: number | null;\n prevBillingAmount: number | null;\n region: string | null;\n serviceId: string | null;\n serviceName: string | null;\n storageCost: number | null;\n storageActualIdleCost: number | null;\n storageRequest: number | null;\n storageUnallocatedCost: number | null;\n storageUtilizationValue: number | null;\n totalCost: number | null;\n trendType: string | null;\n type: string | null;\n unallocatedCost: number | null;\n workloadName: string | null;\n workloadType: string | null;\n } | null;\n instanceDetails?: {\n __typename?: 'InstanceDetails';\n name: string | null;\n id: string | null;\n nodeId: string | null;\n clusterName: string | null;\n clusterId: string | null;\n nodePoolName: string | null;\n cloudProviderInstanceId: string | null;\n podCapacity: string | null;\n totalCost: number;\n idleCost: number;\n systemCost: number;\n unallocatedCost: number;\n cpuAllocatable: number;\n memoryAllocatable: number;\n instanceCategory: string | null;\n machineType: string | null;\n createTime: any;\n deleteTime: any;\n memoryBillingAmount: number;\n cpuBillingAmount: number;\n memoryUnallocatedCost: number;\n cpuUnallocatedCost: number;\n memoryIdleCost: number;\n cpuIdleCost: number;\n } | null;\n storageDetails?: {\n __typename?: 'StorageDetails';\n id: string | null;\n instanceId: string | null;\n instanceName: string | null;\n claimName: string | null;\n claimNamespace: string | null;\n clusterName: string | null;\n clusterId: string | null;\n storageClass: string | null;\n volumeType: string | null;\n cloudProvider: string | null;\n region: string | null;\n storageCost: number;\n storageActualIdleCost: number;\n storageUnallocatedCost: number;\n capacity: number;\n storageRequest: number;\n storageUtilizationValue: number;\n createTime: any;\n deleteTime: any;\n } | null;\n } | null> | null;\n } | null;\n};\n\nexport type QlceViewEntityStatsDataPoint = {\n __typename?: 'QLCEViewEntityStatsDataPoint';\n clusterData: Maybe<ClusterData>;\n clusterPerspective: Scalars['Boolean'];\n cost: Maybe<Scalars['BigDecimal']>;\n costTrend: Maybe<Scalars['BigDecimal']>;\n id: Maybe<Scalars['String']>;\n instanceDetails: Maybe<InstanceDetails>;\n name: Maybe<Scalars['String']>;\n pricingSource: Maybe<Scalars['String']>;\n storageDetails: Maybe<StorageDetails>;\n};\n\nexport type ClusterData = {\n __typename?: 'ClusterData';\n appId: Maybe<Scalars['String']>;\n appName: Maybe<Scalars['String']>;\n avgCpuUtilization: Maybe<Scalars['Float']>;\n avgMemoryUtilization: Maybe<Scalars['Float']>;\n cloudProvider: Maybe<Scalars['String']>;\n cloudProviderId: Maybe<Scalars['String']>;\n cloudServiceName: Maybe<Scalars['String']>;\n clusterId: Maybe<Scalars['String']>;\n clusterName: Maybe<Scalars['String']>;\n clusterType: Maybe<Scalars['String']>;\n costTrend: Maybe<Scalars['Float']>;\n cpuActualIdleCost: Maybe<Scalars['Float']>;\n cpuBillingAmount: Maybe<Scalars['Float']>;\n cpuIdleCost: Maybe<Scalars['Float']>;\n cpuUnallocatedCost: Maybe<Scalars['Float']>;\n efficiencyScore: Scalars['Int'];\n efficiencyScoreTrendPercentage: Scalars['Int'];\n envId: Maybe<Scalars['String']>;\n envName: Maybe<Scalars['String']>;\n environment: Maybe<Scalars['String']>;\n id: Maybe<Scalars['String']>;\n idleCost: Maybe<Scalars['Float']>;\n instanceId: Maybe<Scalars['String']>;\n instanceName: Maybe<Scalars['String']>;\n instanceType: Maybe<Scalars['String']>;\n launchType: Maybe<Scalars['String']>;\n maxCpuUtilization: Maybe<Scalars['Float']>;\n maxMemoryUtilization: Maybe<Scalars['Float']>;\n memoryActualIdleCost: Maybe<Scalars['Float']>;\n memoryBillingAmount: Maybe<Scalars['Float']>;\n memoryIdleCost: Maybe<Scalars['Float']>;\n memoryUnallocatedCost: Maybe<Scalars['Float']>;\n name: Maybe<Scalars['String']>;\n namespace: Maybe<Scalars['String']>;\n networkCost: Maybe<Scalars['Float']>;\n prevBillingAmount: Maybe<Scalars['Float']>;\n region: Maybe<Scalars['String']>;\n serviceId: Maybe<Scalars['String']>;\n serviceName: Maybe<Scalars['String']>;\n storageActualIdleCost: Maybe<Scalars['Float']>;\n storageCost: Maybe<Scalars['Float']>;\n storageRequest: Maybe<Scalars['Float']>;\n storageUnallocatedCost: Maybe<Scalars['Float']>;\n storageUtilizationValue: Maybe<Scalars['Float']>;\n systemCost: Maybe<Scalars['Float']>;\n taskId: Maybe<Scalars['String']>;\n totalCost: Maybe<Scalars['Float']>;\n trendType: Maybe<Scalars['String']>;\n type: Maybe<Scalars['String']>;\n unallocatedCost: Maybe<Scalars['Float']>;\n workloadName: Maybe<Scalars['String']>;\n workloadType: Maybe<Scalars['String']>;\n};\n\nexport type InstanceDetails = {\n __typename?: 'InstanceDetails';\n cloudProviderInstanceId: Maybe<Scalars['String']>;\n clusterId: Maybe<Scalars['String']>;\n clusterName: Maybe<Scalars['String']>;\n cpuAllocatable: Scalars['Float'];\n cpuBillingAmount: Scalars['Float'];\n cpuIdleCost: Scalars['Float'];\n cpuRequested: Scalars['Float'];\n cpuUnallocatedCost: Scalars['Float'];\n cpuUnitPrice: Scalars['Float'];\n createTime: Scalars['Long'];\n deleteTime: Scalars['Long'];\n id: Maybe<Scalars['String']>;\n idleCost: Scalars['Float'];\n instanceCategory: Maybe<Scalars['String']>;\n machineType: Maybe<Scalars['String']>;\n memoryAllocatable: Scalars['Float'];\n memoryBillingAmount: Scalars['Float'];\n memoryIdleCost: Scalars['Float'];\n memoryRequested: Scalars['Float'];\n memoryUnallocatedCost: Scalars['Float'];\n memoryUnitPrice: Scalars['Float'];\n name: Maybe<Scalars['String']>;\n namespace: Maybe<Scalars['String']>;\n networkCost: Scalars['Float'];\n node: Maybe<Scalars['String']>;\n nodeId: Maybe<Scalars['String']>;\n nodePoolName: Maybe<Scalars['String']>;\n podCapacity: Maybe<Scalars['String']>;\n qosClass: Maybe<Scalars['String']>;\n storageActualIdleCost: Scalars['Float'];\n storageCost: Scalars['Float'];\n storageRequest: Scalars['Float'];\n storageUnallocatedCost: Scalars['Float'];\n storageUtilizationValue: Scalars['Float'];\n systemCost: Scalars['Float'];\n totalCost: Scalars['Float'];\n unallocatedCost: Scalars['Float'];\n workload: Maybe<Scalars['String']>;\n};\n\nexport type StorageDetails = {\n __typename?: 'StorageDetails';\n capacity: Scalars['Float'];\n claimName: Maybe<Scalars['String']>;\n claimNamespace: Maybe<Scalars['String']>;\n cloudProvider: Maybe<Scalars['String']>;\n clusterId: Maybe<Scalars['String']>;\n clusterName: Maybe<Scalars['String']>;\n createTime: Scalars['Long'];\n deleteTime: Scalars['Long'];\n id: Maybe<Scalars['String']>;\n instanceId: Maybe<Scalars['String']>;\n instanceName: Maybe<Scalars['String']>;\n region: Maybe<Scalars['String']>;\n storageActualIdleCost: Scalars['Float'];\n storageClass: Maybe<Scalars['String']>;\n storageCost: Scalars['Float'];\n storageRequest: Scalars['Float'];\n storageUnallocatedCost: Scalars['Float'];\n storageUtilizationValue: Scalars['Float'];\n volumeType: Maybe<Scalars['String']>;\n};\n\nexport type FetchPerspectiveTimeSeriesQueryVariables = Exact<{\n filters: InputMaybe<\n | Array<InputMaybe<QlceViewFilterWrapperInput>>\n | InputMaybe<QlceViewFilterWrapperInput>\n >;\n groupBy: InputMaybe<\n Array<InputMaybe<QlceViewGroupByInput>> | InputMaybe<QlceViewGroupByInput>\n >;\n limit: InputMaybe<Scalars['Int']>;\n preferences: InputMaybe<ViewPreferencesInput>;\n isClusterHourlyData?: InputMaybe<Scalars['Boolean']>;\n}>;\n\nexport type FetchPerspectiveTimeSeriesQuery = {\n __typename?: 'Query';\n perspectiveTimeSeriesStats: {\n __typename?: 'PerspectiveTimeSeriesData';\n stats: Array<{\n __typename?: 'TimeSeriesDataPoints';\n time: any;\n values: Array<{\n __typename?: 'DataPoint';\n value: any;\n key: {\n __typename?: 'Reference';\n id: string;\n name: string;\n type: string;\n };\n } | null>;\n } | null> | null;\n } | null;\n};\n\nexport type Reference = {\n __typename?: 'Reference';\n id: Scalars['String'];\n name: Scalars['String'];\n type: Scalars['String'];\n};\n\nexport type DataPoint = {\n __typename?: 'DataPoint';\n key: Reference;\n value: Scalars['BigDecimal'];\n};\n\nexport type TimeSeriesDataPoints = {\n __typename?: 'TimeSeriesDataPoints';\n time: Scalars['Long'];\n values: Array<Maybe<DataPoint>>;\n};\n\nexport enum CloudProvider {\n Aws = 'AWS',\n Azure = 'AZURE',\n Gcp = 'GCP',\n Ibm = 'IBM',\n OnPrem = 'ON_PREM',\n Unknown = 'UNKNOWN',\n}\n\nexport enum RecommendationState {\n Applied = 'APPLIED',\n Ignored = 'IGNORED',\n Open = 'OPEN',\n}\n\nexport enum ResourceType {\n AzureInstance = 'AZURE_INSTANCE',\n Ec2Instance = 'EC2_INSTANCE',\n EcsService = 'ECS_SERVICE',\n Governance = 'GOVERNANCE',\n NodePool = 'NODE_POOL',\n Workload = 'WORKLOAD',\n}\n\nexport type K8sRecommendationFilterDtoInput = {\n cloudProvider: InputMaybe<Array<InputMaybe<CloudProvider>>>;\n clusterNames: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n daysBack: InputMaybe<Scalars['Long']>;\n ids: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n limit: InputMaybe<Scalars['Long']>;\n minCost: InputMaybe<Scalars['Float']>;\n minSaving: InputMaybe<Scalars['Float']>;\n names: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n namespaces: InputMaybe<Array<InputMaybe<Scalars['String']>>>;\n offset: InputMaybe<Scalars['Long']>;\n perspectiveFilters: InputMaybe<Array<InputMaybe<QlceViewFilterWrapperInput>>>;\n recommendationStates: InputMaybe<Array<InputMaybe<RecommendationState>>>;\n resourceTypes: InputMaybe<Array<InputMaybe<ResourceType>>>;\n};\n\nexport type PerspectiveRecommendationsQueryVariables = Exact<{\n filter: InputMaybe<K8sRecommendationFilterDtoInput>;\n}>;\n\nexport type PerspectiveRecommendationsQuery = {\n __typename?: 'Query';\n recommendationStatsV2: {\n __typename?: 'RecommendationOverviewStats';\n totalMonthlyCost: number;\n totalMonthlySaving: number;\n count: number;\n } | null;\n};\n\nexport enum ViewTimeRangeType {\n CurrentMonth = 'CURRENT_MONTH',\n Custom = 'CUSTOM',\n Last_7 = 'LAST_7',\n Last_30 = 'LAST_30',\n LastMonth = 'LAST_MONTH',\n}\n","import useAsyncRetry from 'react-use/lib/useAsyncRetry';\nimport { useState } from 'react';\n\nimport { getSecureHarnessKey } from '../utils/getHarnessToken';\n\nimport { AsyncStatus, CEView } from '../api/types';\n\ninterface useGetFeatureEnvArgs {\n backendBaseUrl: Promise<string>;\n accountId: string;\n envFromUrl?: string;\n perspectiveId: string;\n}\n\nexport interface UseGetPerspectiveReturn {\n perspective?: CEView;\n status: AsyncStatus;\n}\n\nconst useGetPerspective = ({\n backendBaseUrl,\n accountId,\n perspectiveId,\n envFromUrl,\n}: useGetFeatureEnvArgs): UseGetPerspectiveReturn => {\n const [perspective, setPerspective] = useState<CEView>();\n const [status, setStatus] = useState<AsyncStatus>(AsyncStatus.Init);\n\n useAsyncRetry(async () => {\n setStatus(AsyncStatus.Loading);\n\n const token = getSecureHarnessKey('token');\n const headers = new Headers({\n 'content-type': 'application/json',\n Authorization: token ? `${token}` : '',\n 'Harness-Account': accountId,\n });\n const resp = await fetch(\n `${await backendBaseUrl}/harness/${envFromUrl}/gateway/ccm/api/perspective?perspectiveId=${perspectiveId}`,\n {\n headers,\n },\n );\n\n if (resp.status === 200) {\n const data = await resp.json();\n setPerspective(data.data);\n setStatus(AsyncStatus.Success);\n } else if (resp.status === 401) {\n setStatus(AsyncStatus.Unauthorized);\n } else if (resp.status === 403) {\n setStatus(AsyncStatus.Forbidden);\n } else {\n setStatus(AsyncStatus.Error);\n }\n }, [accountId, perspectiveId, envFromUrl]);\n\n return {\n perspective,\n status,\n };\n};\n\nexport default useGetPerspective;\n","import { useEntity } from '@backstage/plugin-catalog-react';\n\nconst usePerspectiveUrlFromEntity = () => {\n const { entity } = useEntity();\n\n return entity.metadata.annotations?.['harness.io/perspective-url'];\n};\n\nexport default usePerspectiveUrlFromEntity;\n","import dayjs from 'dayjs';\nimport utc from 'dayjs/plugin/utc';\nimport quarterOfYear from 'dayjs/plugin/quarterOfYear';\n\nimport {\n QlceViewAggregateOperation,\n QlceViewFieldInputInput,\n QlceViewFilterWrapperInput,\n QlceViewGroupByInput,\n QlceViewTimeFilterOperator,\n QlceViewTimeGroupType,\n ViewField,\n ViewFieldIdentifier,\n ViewTimeRangeType,\n ViewVisualization,\n} from '../api/types';\n\nexport const getViewFilterForId: (\n viewId: string,\n isPreview?: boolean,\n) => QlceViewFilterWrapperInput = (viewId: string, isPreview = false) => {\n return {\n viewMetadataFilter: { viewId: viewId, isPreview: isPreview },\n } as QlceViewFilterWrapperInput;\n};\n\nconst startTimeLabel = 'startTime';\n\nexport const CE_DATE_FORMAT_INTERNAL = 'YYYY-MM-DD';\nexport const CE_DATE_FORMAT_INTERNAL_MOMENT = `${CE_DATE_FORMAT_INTERNAL}THH:mm:ssZ`;\n\ndayjs.extend(utc);\ndayjs.extend(quarterOfYear);\n\nexport const todayInUTC = () => dayjs.utc();\n\nexport const LAST_30_DAYS_RANGE = [\n todayInUTC()\n .subtract(30, 'days')\n .startOf('day')\n .format(CE_DATE_FORMAT_INTERNAL),\n todayInUTC().endOf('day').format(CE_DATE_FORMAT_INTERNAL),\n];\n\nexport const DEFAULT_TIME_RANGE: TimeRangeFilterType = {\n to: LAST_30_DAYS_RANGE[1],\n from: LAST_30_DAYS_RANGE[0],\n};\n\nexport const getGMTStartDateTime = (str: string) =>\n dayjs(`${str}T00:00:00Z`, CE_DATE_FORMAT_INTERNAL_MOMENT).valueOf();\nexport const getGMTEndDateTime = (str: string) =>\n dayjs(`${str}T23:59:59Z`, CE_DATE_FORMAT_INTERNAL_MOMENT).valueOf();\n\nexport const getTimeFilters: (\n from: number,\n to: number,\n) => QlceViewFilterWrapperInput[] = (from, to) => {\n return [\n {\n timeFilter: {\n field: {\n fieldId: startTimeLabel,\n fieldName: startTimeLabel,\n identifier: ViewFieldIdentifier.Common,\n },\n operator: QlceViewTimeFilterOperator.After,\n value: from,\n },\n },\n {\n timeFilter: {\n field: {\n fieldId: startTimeLabel,\n fieldName: startTimeLabel,\n identifier: ViewFieldIdentifier.Common,\n },\n operator: QlceViewTimeFilterOperator.Before,\n value: to,\n },\n },\n ] as QlceViewFilterWrapperInput[];\n};\n\nexport const PERSPECTIVE_DETAILS_AGGREGATE = [\n { operationType: QlceViewAggregateOperation.Sum, columnName: 'cost' },\n { operationType: QlceViewAggregateOperation.Max, columnName: 'startTime' },\n { operationType: QlceViewAggregateOperation.Min, columnName: 'startTime' },\n];\n\nexport const DEFAULT_GROUP_BY = {\n fieldId: 'product',\n fieldName: 'Product',\n identifier: ViewFieldIdentifier.Common,\n identifierName: ViewFieldIdentifier.Common,\n};\n\nexport const getGroupByFilter: (\n groupBy: QlceViewFieldInputInput | ViewField,\n) => QlceViewGroupByInput = groupBy => {\n return {\n entityGroupBy: groupBy,\n } as QlceViewGroupByInput;\n};\n\nexport const clusterInfoUtil: (dataSources?: string[]) => {\n isClusterOnly: boolean;\n recommendationsEnabled: boolean;\n} = dataSources => {\n let isClusterOnly = false;\n let recommendationsEnabled = false;\n\n if (!dataSources?.length) {\n return { isClusterOnly, recommendationsEnabled };\n }\n\n if (\n dataSources.length === 1 &&\n dataSources[0] === ViewFieldIdentifier.Cluster\n ) {\n isClusterOnly = true;\n }\n\n if (!dataSources.includes(ViewFieldIdentifier.Gcp)) {\n recommendationsEnabled = true;\n }\n\n return { isClusterOnly, recommendationsEnabled };\n};\n\nexport const getTimeRangeFilter: (\n aggregation: QlceViewTimeGroupType | ViewVisualization['granularity'],\n) => QlceViewGroupByInput = aggregation => {\n return {\n timeTruncGroupBy: {\n resolution: aggregation,\n },\n } as QlceViewGroupByInput;\n};\n\nexport const DATE_RANGE_SHORTCUTS: Record<string, dayjs.Dayjs[]> = {\n LAST_7_DAYS: [\n todayInUTC().subtract(6, 'days').startOf('day'),\n todayInUTC().endOf('day'),\n ],\n LAST_30_DAYS: [\n todayInUTC().subtract(30, 'days').startOf('day'),\n todayInUTC().endOf('day'),\n ],\n CURRENT_MONTH: [\n todayInUTC().startOf('month').startOf('day'),\n todayInUTC().endOf('day'),\n ],\n THIS_MONTH: [\n todayInUTC().startOf('month').startOf('day'),\n todayInUTC().endOf('month').subtract(1, 'days'),\n ],\n THIS_YEAR: [todayInUTC().startOf('year'), todayInUTC().endOf('day')],\n LAST_MONTH: [\n todayInUTC().subtract(1, 'month').startOf('month'),\n todayInUTC().subtract(1, 'month').endOf('month'),\n ],\n LAST_YEAR: [\n todayInUTC().subtract(1, 'year').startOf('year'),\n todayInUTC().subtract(1, 'year').endOf('year'),\n ],\n LAST_3_MONTHS: [\n todayInUTC().subtract(3, 'months').startOf('month'),\n todayInUTC().subtract(1, 'month').endOf('month'),\n ],\n LAST_6_MONTHS: [\n todayInUTC().subtract(6, 'months').startOf('month'),\n todayInUTC().subtract(1, 'month').endOf('month'),\n ],\n LAST_12_MONTHS: [\n todayInUTC().subtract(12, 'months').startOf('month'),\n todayInUTC().subtract(1, 'month').endOf('month'),\n ],\n THIS_QUARTER: [todayInUTC().startOf('quarter'), todayInUTC().endOf('day')],\n LAST_QUARTER: [\n todayInUTC().subtract(1, 'quarter').startOf('quarter'),\n todayInUTC().subtract(1, 'quarter').endOf('quarter'),\n ],\n};\n\nexport enum DATE_RANGE_SHORTCUTS_NAME {\n 'LAST_7_DAYS' = 'LAST_7_DAYS',\n 'LAST_30_DAYS' = 'LAST_30_DAYS',\n 'CURRENT_MONTH' = 'CURRENT_MONTH',\n 'THIS_YEAR' = 'THIS_YEAR',\n 'LAST_MONTH' = 'LAST_MONTH',\n 'LAST_YEAR' = 'LAST_YEAR',\n 'LAST_3_MONTHS' = 'LAST_3_MONTHS',\n 'LAST_6_MONTHS' = 'LAST_6_MONTHS',\n 'LAST_12_MONTHS' = 'LAST_12_MONTHS',\n 'THIS_QUARTER' = 'THIS_QUARTER',\n 'LAST_QUARTER' = 'LAST_QUARTER',\n 'CUSTOM' = 'CUSTOM',\n}\n\nexport const DateLabelToDisplayTextMap: Record<string, string> = {\n [DATE_RANGE_SHORTCUTS_NAME.LAST_7_DAYS]: 'Last 7 Days',\n [DATE_RANGE_SHORTCUTS_NAME.CURRENT_MONTH]: 'This Month',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_30_DAYS]: 'Last 30 Days',\n [DATE_RANGE_SHORTCUTS_NAME.THIS_QUARTER]: 'This Quarter',\n [DATE_RANGE_SHORTCUTS_NAME.THIS_YEAR]: 'This Year',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_MONTH]: 'Last Month',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_QUARTER]: 'Last Quarter',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_YEAR]: 'Last Year',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_3_MONTHS]: 'Last 3 Months',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_6_MONTHS]: 'Last 6 Months',\n [DATE_RANGE_SHORTCUTS_NAME.LAST_12_MONTHS]: 'Last 12 Months',\n};\n\nconst LAST_7_DAYS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_7_DAYS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_7_DAYS,\n dateFormat: ['MMM D', 'MMM D'],\n};\n\nconst LAST_30_DAYS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_30_DAYS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_30_DAYS,\n dateFormat: ['MMM YYYY'],\n};\n\nconst CURRENT_MONTH = {\n label: DATE_RANGE_SHORTCUTS_NAME.CURRENT_MONTH,\n dateRange: DATE_RANGE_SHORTCUTS.CURRENT_MONTH,\n dateFormat: ['MMM YYYY'],\n};\n\nconst THIS_QUARTER = {\n label: DATE_RANGE_SHORTCUTS_NAME.THIS_QUARTER,\n dateRange: DATE_RANGE_SHORTCUTS.THIS_QUARTER,\n dateFormat: ['MMM', 'MMM YYYY'],\n};\n\nconst THIS_YEAR = {\n label: DATE_RANGE_SHORTCUTS_NAME.THIS_YEAR,\n dateRange: DATE_RANGE_SHORTCUTS.THIS_YEAR,\n dateFormat: ['YYYY'],\n};\nconst LAST_MONTH = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_MONTH,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_MONTH,\n dateFormat: ['MMM YYYY'],\n};\nconst LAST_YEAR = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_YEAR,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_YEAR,\n dateFormat: ['YYYY'],\n};\nconst LAST_QUARTER = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_QUARTER,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_QUARTER,\n dateFormat: ['MMM', 'MMM YYYY'],\n};\nconst LAST_3_MONTHS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_3_MONTHS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_3_MONTHS,\n dateFormat: ['MMM YYYY', 'MMM YYYY'],\n};\nconst LAST_6_MONTHS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_6_MONTHS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_6_MONTHS,\n dateFormat: ['MMM YYYY', 'MMM YYYY'],\n};\n\nconst LAST_12_MONTHS = {\n label: DATE_RANGE_SHORTCUTS_NAME.LAST_12_MONTHS,\n dateRange: DATE_RANGE_SHORTCUTS.LAST_12_MONTHS,\n dateFormat: ['MMM YYYY', 'MMM YYYY'],\n};\n\nexport const RECOMMENDED_DATES = [LAST_7_DAYS, CURRENT_MONTH];\n\nexport const RELATIVE_DATES = [LAST_7_DAYS, LAST_30_DAYS];\n\nexport const CALENDAR_MONTH_DATES = [\n CURRENT_MONTH,\n THIS_QUARTER,\n THIS_YEAR,\n LAST_MONTH,\n LAST_QUARTER,\n LAST_YEAR,\n LAST_3_MONTHS,\n LAST_6_MONTHS,\n LAST_12_MONTHS,\n];\n\nexport interface TimeRangeFilterType {\n to: string;\n from: string;\n}\n\nexport const perspectiveDefaultTimeRangeMapper: Record<string, dayjs.Dayjs[]> =\n {\n [ViewTimeRangeType.Last_7]: DATE_RANGE_SHORTCUTS.LAST_7_DAYS,\n [ViewTimeRangeType.Last_30]: DATE_RANGE_SHORTCUTS.LAST_30_DAYS,\n [ViewTimeRangeType.LastMonth]: DATE_RANGE_SHORTCUTS.LAST_MONTH,\n [ViewTimeRangeType.CurrentMonth]: DATE_RANGE_SHORTCUTS.CURRENT_MONTH,\n };\n","export const fetchPerspectiveGridQuery = `query FetchperspectiveGrid(\n $filters: [QLCEViewFilterWrapperInput]\n $groupBy: [QLCEViewGroupByInput]\n $limit: Int\n $offset: Int\n $aggregateFunction: [QLCEViewAggregationInput]\n $isClusterOnly: Boolean!\n $isClusterHourlyData: Boolean = null\n $preferences: ViewPreferencesInput\n) {\n perspectiveGrid(\n aggregateFunction: $aggregateFunction\n filters: $filters\n groupBy: $groupBy\n limit: $limit\n offset: $offset\n preferences: $preferences\n isClusterHourlyData: $isClusterHourlyData\n sortCriteria: [{ sortType: COST, sortOrder: DESCENDING }]\n ) {\n data {\n name\n id\n cost\n costTrend\n clusterPerspective @include(if: $isClusterOnly)\n clusterData @include(if: $isClusterOnly) {\n appId\n appName\n avgCpuUtilization\n avgMemoryUtilization\n cloudProvider\n cloudProviderId\n cloudServiceName\n clusterId\n clusterName\n clusterType\n costTrend\n cpuBillingAmount\n cpuActualIdleCost\n cpuUnallocatedCost\n efficiencyScore\n efficiencyScoreTrendPercentage\n envId\n envName\n environment\n id\n idleCost\n launchType\n maxCpuUtilization\n maxMemoryUtilization\n memoryBillingAmount\n memoryActualIdleCost\n memoryUnallocatedCost\n name\n namespace\n networkCost\n prevBillingAmount\n region\n serviceId\n serviceName\n storageCost\n storageActualIdleCost\n storageRequest\n storageUnallocatedCost\n storageUtilizationValue\n totalCost\n trendType\n type\n unallocatedCost\n workloadName\n workloadType\n }\n instanceDetails @include(if: $isClusterOnly) {\n name\n id\n nodeId\n clusterName\n clusterId\n nodePoolName\n cloudProviderInstanceId\n podCapacity\n totalCost\n idleCost\n systemCost\n unallocatedCost\n cpuAllocatable\n memoryAllocatable\n instanceCategory\n machineType\n createTime\n deleteTime\n memoryBillingAmount\n cpuBillingAmount\n memoryUnallocatedCost\n cpuUnallocatedCost\n memoryIdleCost\n cpuIdleCost\n }\n storageDetails @include(if: $isClusterOnly) {\n id\n instanceId\n instanceName\n claimName\n claimNamespace\n clusterName\n clusterId\n storageClass\n volumeType\n cloudProvider\n region\n storageCost\n storageActualIdleCost\n storageUnallocatedCost\n capacity\n storageRequest\n storageUtilizationValue\n createTime\n deleteTime\n }\n }\n }\n perspectiveTotalCount(\n filters: $filters\n groupBy: $groupBy\n isClusterQuery: $isClusterOnly\n isClusterHourlyData: $isClusterHourlyData\n )\n}\n`;\n","import {\n FetchperspectiveGridQuery,\n FetchperspectiveGridQueryVariables,\n} from './types';\nimport useFetcher, { AsyncStatus } from '../hooks/useFetcher';\nimport { fetchPerspectiveGridQuery } from '../gql/fetchPerspectiveGrid';\n\ninterface UseFetchPerspectiveGridProps {\n accountId: string;\n variables: Partial<FetchperspectiveGridQueryVariables>;\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetchPerspectiveGridReturn {\n perspectiveGrid: FetchperspectiveGridQuery | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nconst useFetchPerspectiveGrid = ({\n ...props\n}: UseFetchPerspectiveGridProps): UseFetchPerspectiveGridReturn => {\n const body = JSON.stringify({\n query: fetchPerspectiveGridQuery,\n variables: props.variables,\n });\n\n const { data, ...fetcherProps } = useFetcher<{\n data: FetchperspectiveGridQuery;\n }>({\n ...props,\n method: 'POST',\n body,\n });\n\n return { perspectiveGrid: data?.data, ...fetcherProps };\n};\n\nexport default useFetchPerspectiveGrid;\n","export const fetchPerspectiveChartQuery = `query FetchPerspectiveTimeSeries(\n $filters: [QLCEViewFilterWrapperInput]\n $groupBy: [QLCEViewGroupByInput]\n $limit: Int\n $preferences: ViewPreferencesInput\n $isClusterHourlyData: Boolean = null\n) {\n perspectiveTimeSeriesStats(\n filters: $filters\n groupBy: $groupBy\n limit: $limit\n preferences: $preferences\n isClusterHourlyData: $isClusterHourlyData\n aggregateFunction: [{ operationType: SUM, columnName: \"cost\" }]\n sortCriteria: [{ sortType: COST, sortOrder: DESCENDING }]\n ) {\n stats {\n values {\n key {\n id\n name\n type\n }\n value\n }\n time\n }\n }\n}\n`;\n","import {\n FetchPerspectiveTimeSeriesQuery,\n FetchPerspectiveTimeSeriesQueryVariables,\n} from './types';\nimport useFetcher, { AsyncStatus } from '../hooks/useFetcher';\nimport { fetchPerspectiveChartQuery } from '../gql/fetchPerspectiveChart';\n\ninterface UseFetchPerspectiveChartProps {\n accountId: string;\n variables: Partial<FetchPerspectiveTimeSeriesQueryVariables>;\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetchPerspectiveChartReturn {\n perspectiveChart: FetchPerspectiveTimeSeriesQuery | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nconst useFetchPerspectiveChart = ({\n ...props\n}: UseFetchPerspectiveChartProps): UseFetchPerspectiveChartReturn => {\n const body = JSON.stringify({\n query: fetchPerspectiveChartQuery,\n variables: props.variables,\n });\n\n const { data, ...fetcherProps } = useFetcher<{\n data: FetchPerspectiveTimeSeriesQuery;\n }>({\n ...props,\n method: 'POST',\n body,\n });\n\n return { perspectiveChart: data?.data, ...fetcherProps };\n};\n\nexport default useFetchPerspectiveChart;\n","import { useState } from 'react';\nimport { getSecureHarnessKey } from '../utils/getHarnessToken';\nimport useAsyncRetry from 'react-use/lib/useAsyncRetry';\n\ninterface useGetLicenseWithAuthProps {\n env: string;\n accountId: string;\n backendBaseUrl: Promise<string>;\n}\nconst useGetLicense = ({\n backendBaseUrl,\n env,\n accountId,\n}: useGetLicenseWithAuthProps) => {\n const [licenses, setLicenses] = useState('SRM');\n\n useAsyncRetry(async () => {\n const token = getSecureHarnessKey('token');\n const value = token ? `${token}` : '';\n\n const headers = new Headers({\n Authorization: value,\n });\n\n const response = await fetch(\n `${await backendBaseUrl}/harness/${env}/gateway/ng/api/licenses/account?routingId=${accountId}&accountIdentifier=${accountId}`,\n {\n headers,\n },\n );\n\n if (response.status === 200) {\n const data = await response.json();\n if (data?.data?.allModuleLicenses?.CE?.length === 0) {\n setLicenses('NA');\n }\n } else if (response.status === 401) {\n setLicenses('Unauthorized');\n }\n }, [env, accountId]);\n\n return { licenses };\n};\n\nexport default useGetLicense;\n","import React from 'react';\nimport {\n Card,\n CardContent,\n CircularProgress,\n makeStyles,\n Typography,\n} from '@material-ui/core';\nimport ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';\nimport ArrowDropUpOutlinedIcon from '@mui/icons-material/ArrowDropUpOutlined';\n\nconst useStyles = makeStyles({\n costCtn: {\n padding: 20,\n },\n costCard: {\n minWidth: 250,\n minHeight: 130,\n },\n costDescription: {\n marginTop: 8,\n marginBottom: 8,\n },\n emptyState: {\n minWidth: 250,\n minHeight: 130,\n alignItems: 'center',\n justifyContent: 'center',\n },\n cardContent: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n },\n trendCtn: {\n display: 'flex',\n alignItems: 'center',\n },\n});\n\ninterface CostCardProps {\n isLoading: boolean;\n statsLabel: string;\n statsValue: string;\n statsDescription: string;\n statsTrend?: number;\n}\n\nconst CostCard: React.FC<CostCardProps> = ({\n isLoading,\n statsDescription,\n statsLabel,\n statsValue,\n statsTrend,\n}) => {\n const classes = useStyles();\n\n if (isLoading) {\n return (\n <Card className={classes.emptyState}>\n <CircularProgress />\n </Card>\n );\n }\n\n if (!statsValue) {\n return <></>;\n }\n\n return (\n <Card className={classes.costCard}>\n <CardContent className={classes.cardContent}>\n <div>\n <Typography variant=\"body2\">{statsLabel}</Typography>\n <Typography variant=\"h3\" className={classes.costDescription}>\n {statsValue}\n </Typography>\n <Typography variant=\"body2\">{statsDescription}</Typography>\n </div>\n {statsTrend ? (\n <div\n style={{ color: statsTrend >= 0 ? '#e43326' : '#4dc952' }}\n className={classes.trendCtn}\n >\n {statsTrend >= 0 ? (\n <ArrowDropUpOutlinedIcon style={{ color: '#e43326' }} />\n ) : (\n <ArrowDropDownOutlinedIcon style={{ color: '#4dc952' }} />\n )}\n {statsTrend < 0 ? statsTrend * -1 : statsTrend}%\n </div>\n ) : null}\n </CardContent>\n </Card>\n );\n};\n\nexport default CostCard;\n","import React from 'react';\nimport {\n BarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n ResponsiveContainer,\n AreaChart,\n Area,\n} from 'recharts';\nimport { CircularProgress, makeStyles } from '@material-ui/core';\nimport { TimeSeriesDataPoints, ViewVisualization } from '../../api/types';\n\nconst useStyles = makeStyles({\n chartCtn: {\n padding: 24,\n },\n emptyState: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n\nconst CE_COLOR_CONST_NEW = [\n '#0092E4', // Primary 6\n '#4947DD', // Blue 700\n '#42AB45', // Green 600\n '#FF832B', // Orange 500\n '#24807F', // Cloud Cost Management 300\n '#7D4DD3', // Purple 500\n '#FCC026', // Yellow 800\n '#EE5F54', // Red 400\n '#EE2A89', // Magenta 700\n '#954E02', // Brown\n '#0BC8D6', // Teal 500,\n '#7FB800', // Lime 500\n];\n\nconst OTHERS_COLOR_HEX = '#dae0ff';\n\nconst tickFormatter = (value: any) => `$${value.toLocaleString()}`;\n\ninterface PerspectivesChartProps {\n isLoading?: boolean;\n data: TimeSeriesDataPoints[];\n viewVisualization: ViewVisualization['chartType'];\n}\n\nconst PerspectivesChart: React.FC<PerspectivesChartProps> = ({\n isLoading,\n data,\n viewVisualization,\n}) => {\n const classes = useStyles();\n\n const formattedData = data?.map(stat => {\n const time = new Date(stat.time).toISOString().split('T')[0];\n const values = stat.values.reduce((acc, curr) => {\n (acc as any)[curr?.key.name || ''] = curr?.value;\n return acc;\n }, {});\n\n return { date: time, ...values };\n });\n\n const keys = Object.keys(formattedData[0] || {}).filter(\n key => key !== 'date',\n );\n\n if (isLoading) {\n return (\n <ResponsiveContainer\n width=\"100%\"\n height={500}\n className={classes.emptyState}\n >\n <CircularProgress />\n </ResponsiveContainer>\n );\n }\n\n return (\n <div className={classes.chartCtn}>\n <ResponsiveContainer width=\"100%\" height={500}>\n {viewVisualization === 'STACKED_TIME_SERIES' ? (\n <BarChart\n width={500}\n height={300}\n data={formattedData}\n margin={{\n top: 20,\n right: 30,\n left: 20,\n bottom: 5,\n }}\n >\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" />\n <YAxis tickFormatter={tickFormatter} />\n <Tooltip formatter={tickFormatter} />\n <Legend />\n {keys.map((key, idx) => (\n <Bar\n stackId=\"a\"\n key={key}\n dataKey={key}\n fill={\n key === 'Others'\n ? OTHERS_COLOR_HEX\n : CE_COLOR_CONST_NEW[idx % CE_COLOR_CONST_NEW.length]\n }\n />\n ))}\n </BarChart>\n ) : (\n <AreaChart\n width={730}\n height={250}\n data={formattedData}\n margin={{ top: 5, right: 30, left: 20, bottom: 5 }}\n >\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" />\n <YAxis tickFormatter={tickFormatter} />\n <Tooltip formatter={tickFormatter} />\n <Legend />\n {keys.map((key, idx) => (\n <Area\n type=\"monotone\"\n key={key}\n dataKey={key}\n fill={\n key === 'Others'\n ? OTHERS_COLOR_HEX\n : CE_COLOR_CONST_NEW[idx % CE_COLOR_CONST_NEW.length]\n }\n />\n ))}\n </AreaChart>\n )}\n </ResponsiveContainer>\n </div>\n );\n};\n\nexport default PerspectivesChart;\n","import React from 'react';\nimport { Typography } from '@material-ui/core';\nimport { Table, TableColumn } from '@backstage/core-components';\n\nimport ArrowDownwardOutlinedIcon from '@mui/icons-material/ArrowDownwardOutlined';\nimport ArrowUpwardOutlinedIcon from '@mui/icons-material/ArrowUpwardOutlined';\n\nimport { QlceViewEntityStatsDataPoint } from '../../api/types';\n\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n field: 'name',\n highlight: true,\n },\n {\n title: 'Cost',\n field: 'cost',\n render: (rowData: any) => (\n <Typography>\n {new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n }).format(rowData.cost)}\n </Typography>\n ),\n },\n {\n title: 'Cost Trend',\n field: 'costTrend',\n render: (rowData: any) => (\n <Typography>\n <div style={{ display: 'flex', alignItems: 'center' }}>\n {rowData.costTrend >= 0 ? (\n <ArrowUpwardOutlinedIcon style={{ color: '#e43326' }} />\n ) : (\n <ArrowDownwardOutlinedIcon style={{ color: '#4dc952' }} />\n )}\n {rowData.costTrend < 0 ? rowData.costTrend * -1 : rowData.costTrend}%\n </div>\n </Typography>\n ),\n },\n];\n\ninterface PerspectivesGridProps {\n isLoading: boolean;\n data: QlceViewEntityStatsDataPoint[];\n totalCount: number;\n page: number;\n handlePageChange: (page: number, pageSize: number) => void;\n}\n\nconst PerspectivesGrid: React.FC<PerspectivesGridProps> = ({\n isLoading,\n data,\n page,\n totalCount,\n handlePageChange,\n}) => {\n return (\n <div>\n <Table\n isLoading={isLoading}\n columns={columns}\n data={data}\n totalCount={\n (page + 1) * 15 < totalCount\n ? Number.MAX_VALUE\n : Number.MAX_SAFE_INTEGER\n }\n options={{\n search: false,\n paging: true,\n emptyRowsWhenPaging: false,\n paginationPosition: 'both',\n showFirstLastPageButtons: false,\n pageSize: Number.MAX_SAFE_INTEGER,\n pageSizeOptions: [],\n }}\n page={page > 0 ? 1 : 0}\n onPageChange={handlePageChange}\n localization={{\n pagination: {\n labelDisplayedRows: `(${page * 15 + 1} - ${\n (page + 1) * 15\n }) of ${totalCount}`,\n },\n }}\n />\n </div>\n );\n};\n\nexport default PerspectivesGrid;\n","import React, { useEffect, useState } from 'react';\nimport {\n Button,\n CircularProgress,\n Divider,\n makeStyles,\n Menu,\n MenuItem,\n Typography,\n} from '@material-ui/core';\n\nimport KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown';\n\nimport {\n CALENDAR_MONTH_DATES,\n CE_DATE_FORMAT_INTERNAL,\n DATE_RANGE_SHORTCUTS,\n DATE_RANGE_SHORTCUTS_NAME,\n DateLabelToDisplayTextMap,\n RECOMMENDED_DATES,\n RELATIVE_DATES,\n TimeRangeFilterType,\n} from '../../utils/PerpsectiveUtils';\nimport { Dayjs } from 'dayjs';\n\nconst useStyles = makeStyles({\n subHeader: {\n padding: '8px 16px',\n },\n dateCtn: {\n justifyContent: 'space-between',\n gap: 20,\n },\n dateRange: {\n color: '#b0b1c4',\n },\n divider: {\n margin: '8px 0px',\n },\n buttonCtn: {\n height: 36,\n },\n});\n\nconst DateRenderer = ({\n date,\n setTimeRange,\n setTimeLabel,\n handleClose,\n}: {\n date: {\n label: DATE_RANGE_SHORTCUTS_NAME;\n dateRange: Dayjs[];\n dateFormat: string[];\n };\n setTimeRange: (newValue: TimeRangeFilterType) => void;\n setTimeLabel: (newValue: DATE_RANGE_SHORTCUTS_NAME) => void;\n handleClose: () => void;\n}) => {\n const classes = useStyles();\n\n return (\n <MenuItem\n className={classes.dateCtn}\n onClick={() => {\n setTimeRange({\n from: date.dateRange[0].format(CE_DATE_FORMAT_INTERNAL),\n to: date.dateRange[1].format(CE_DATE_FORMAT_INTERNAL),\n });\n setTimeLabel(date.label);\n handleClose();\n }}\n >\n <span>{DateLabelToDisplayTextMap[date.label]}</span>\n <span>\n <Typography variant=\"body2\" className={classes.dateRange}>\n {`${date.dateRange[0].format(date.dateFormat[0])} ${\n date.dateFormat[1]\n ? `- ${date.dateRange[1].format(date.dateFormat[1])}`\n : ''\n }`}\n </Typography>\n </span>\n </MenuItem>\n );\n};\n\ninterface TimeFilterProps {\n isLoading?: boolean;\n timeRange: TimeRangeFilterType;\n setTimeRange: (newValue: TimeRangeFilterType) => void;\n}\n\nconst TimeFilter: React.FC<TimeFilterProps> = ({\n isLoading,\n timeRange,\n setTimeRange,\n}) => {\n const classes = useStyles();\n\n const [timeLabel, setTimeLabel] = useState<string>(\n DATE_RANGE_SHORTCUTS_NAME.LAST_30_DAYS,\n );\n\n useEffect(() => {\n if (!isLoading) {\n const filteredArray = Object.keys(DATE_RANGE_SHORTCUTS).filter(short => {\n const date = DATE_RANGE_SHORTCUTS[short];\n\n return (\n timeRange.from === date[0].format(CE_DATE_FORMAT_INTERNAL) &&\n timeRange.to === date[1].format(CE_DATE_FORMAT_INTERNAL)\n );\n });\n\n if (filteredArray.length) {\n setTimeLabel(filteredArray[0]);\n }\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isLoading]);\n\n const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);\n const open = Boolean(anchorEl);\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n const handleClose = () => {\n setAnchorEl(null);\n };\n\n return (\n <div>\n <Button\n id=\"basic-button\"\n aria-controls={open ? 'basic-menu' : undefined}\n aria-haspopup=\"true\"\n aria-expanded={open ? 'true' : undefined}\n onClick={handleClick}\n endIcon={<KeyboardArrowDown />}\n className={classes.buttonCtn}\n >\n {isLoading ? (\n <CircularProgress size={12} />\n ) : (\n DateLabelToDisplayTextMap[timeLabel]\n )}\n </Button>\n <Menu\n id=\"basic-menu\"\n anchorEl={anchorEl}\n open={open}\n onClose={handleClose}\n MenuListProps={{\n 'aria-labelledby': 'basic-button',\n }}\n >\n <Typography variant=\"subtitle2\" className={classes.subHeader}>\n Recommended\n </Typography>\n {RECOMMENDED_DATES.map(date => (\n <DateRenderer\n date={date}\n setTimeRange={setTimeRange}\n setTimeLabel={setTimeLabel}\n handleClose={handleClose}\n />\n ))}\n <Divider className={classes.divider} />\n <Typography variant=\"subtitle2\" className={classes.subHeader}>\n Relative\n </Typography>\n {RELATIVE_DATES.map(date => (\n <DateRenderer\n date={date}\n setTimeRange={setTimeRange}\n setTimeLabel={setTimeLabel}\n handleClose={handleClose}\n />\n ))}\n <Divider className={classes.divider} />\n <Typography variant=\"subtitle2\" className={classes.subHeader}>\n Calendar Months\n </Typography>\n {CALENDAR_MONTH_DATES.map(date => (\n <DateRenderer\n date={date}\n setTimeRange={setTimeRange}\n setTimeLabel={setTimeLabel}\n handleClose={handleClose}\n />\n ))}\n </Menu>\n </div>\n );\n};\n\nexport default TimeFilter;\n","import React from 'react';\nimport {\n Card,\n CardContent,\n CircularProgress,\n makeStyles,\n Typography,\n} from '@material-ui/core';\n\nconst useStyles = makeStyles({\n costCtn: {\n padding: 20,\n },\n costCard: {\n minWidth: 275,\n minHeight: 130,\n },\n emptyState: {\n minWidth: 275,\n minHeight: 130,\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n\ninterface RecommendationsCardProps {\n isLoading: boolean;\n totalSavings: number;\n recommendationsCount: number;\n}\n\nconst RecommendationsCard: React.FC<RecommendationsCardProps> = ({\n isLoading,\n totalSavings,\n recommendationsCount,\n}) => {\n const classes = useStyles();\n\n if (isLoading) {\n return (\n <Card className={classes.emptyState}>\n <CircularProgress />\n </Card>\n );\n }\n\n if (!totalSavings) {\n return <></>;\n }\n\n return (\n <Card className={classes.costCard}>\n <CardContent>\n <Typography variant=\"body2\">Recommendations</Typography>\n <Typography variant=\"caption\">\n {recommendationsCount} recommendation(s) saving upto\n </Typography>\n <Typography variant=\"h5\">{`$${totalSavings.toLocaleString()}`}</Typography>\n <Typography variant=\"body2\">per month</Typography>\n </CardContent>\n </Card>\n );\n};\n\nexport default RecommendationsCard;\n","export const fetchPerspectiveRecommendationsQuery = `query PerspectiveRecommendations($filter: K8sRecommendationFilterDTOInput) {\n recommendationStatsV2(filter: $filter) {\n totalMonthlyCost\n totalMonthlySaving\n count\n }\n}\n`;\n","import {\n PerspectiveRecommendationsQuery,\n PerspectiveRecommendationsQueryVariables,\n} from './types';\nimport useFetcher, { AsyncStatus } from '../hooks/useFetcher';\nimport { fetchPerspectiveRecommendationsQuery } from '../gql/fetchPerspectiveRecommendations';\n\ninterface UseFetchPerspectiveRecommendationsProps {\n accountId: string;\n variables: Partial<PerspectiveRecommendationsQueryVariables>;\n env: string;\n backendBaseUrl: Promise<string>;\n lazy?: boolean;\n}\n\ninterface UseFetchPerspectiveRecommendationsReturn {\n perspectiveRecommendations: PerspectiveRecommendationsQuery | undefined;\n status: AsyncStatus;\n error: Error | undefined;\n loading: boolean;\n refetch: () => void;\n}\n\nconst useFetchPerspectiveRecommendations = ({\n ...props\n}: UseFetchPerspectiveRecommendationsProps): UseFetchPerspectiveRecommendationsReturn => {\n const body = JSON.stringify({\n query: fetchPerspectiveRecommendationsQuery,\n variables: props.variables,\n });\n\n const { data, ...fetcherProps } = useFetcher<{\n data: PerspectiveRecommendationsQuery;\n }>({\n ...props,\n method: 'POST',\n body,\n });\n\n return { perspectiveRecommendations: data?.data, ...fetcherProps };\n};\n\nexport default useFetchPerspectiveRecommendations;\n","import React, { useEffect, useState } from 'react';\nimport { EmptyState } from '@backstage/core-components';\nimport {\n Card,\n Grid,\n Link,\n makeStyles,\n Typography,\n Button,\n} from '@material-ui/core';\nimport { discoveryApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport LaunchIcon from '@mui/icons-material/Launch';\n\nimport { useResourceSlugFromEntity } from '../../hooks/useResourceSlugFromEntity';\nimport useFetchPerspectiveDetailsSummaryWithBudget from '../../api/useFetchPerspectiveDetailsSummaryWithBudget';\nimport useGetPerspective from '../../hooks/useGetPerspective';\n\nimport usePerspectiveUrlFromEntity from '../../hooks/usePerspectiveUrlEntity';\nimport {\n CE_DATE_FORMAT_INTERNAL,\n clusterInfoUtil,\n DATE_RANGE_SHORTCUTS,\n DEFAULT_GROUP_BY,\n DEFAULT_TIME_RANGE,\n getGMTEndDateTime,\n getGMTStartDateTime,\n getGroupByFilter,\n getTimeFilters,\n getTimeRangeFilter,\n getViewFilterForId,\n PERSPECTIVE_DETAILS_AGGREGATE,\n perspectiveDefaultTimeRangeMapper,\n TimeRangeFilterType,\n} from '../../utils/PerpsectiveUtils';\nimport {\n AsyncStatus,\n K8sRecommendationFilterDtoInput,\n QlceViewEntityStatsDataPoint,\n QlceViewTimeGroupType,\n TimeSeriesDataPoints,\n} from '../../api/types';\nimport useFetchPerspectiveGrid from '../../api/useFetchPerspectiveGrid';\nimport useFetchPerspectiveChart from '../../api/useFetchPerspectiveChart';\nimport useGetLicense from '../../hooks/useGetLicense';\n\nimport CostCard from '../CostCard';\nimport PerspectivesChart from '../PerspectivesChart/PerspectivesChart';\nimport PerspectivesGrid from '../PerspectivesGrid/PerspectivesGrid';\nimport TimeFilter from '../TimeFilter/TimeFilter';\nimport RecommendationsCard from '../RecommendationsCard';\nimport useFetchPerspectiveRecommendations from '../../api/useFetchPerspectiveRecommendations';\n\nconst useStyles = makeStyles({\n subHeader: {\n display: 'flex',\n flexDirection: 'row-reverse',\n marginBottom: 20,\n },\n chartAndGridCtn: {\n marginTop: 24,\n },\n linkCard: {\n padding: 20,\n height: 125,\n gap: 16,\n },\n linkCtn: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n },\n});\n\nconst PerspectivesPage: React.FC = () => {\n const classes = useStyles();\n const discoveryApi = useApi(discoveryApiRef);\n const backendBaseUrl = discoveryApi.getBaseUrl('proxy');\n\n const perspectiveUrl = usePerspectiveUrlFromEntity();\n const {\n accountId,\n envFromUrl = '',\n perspectiveId,\n baseUrl,\n } = useResourceSlugFromEntity(perspectiveUrl);\n\n const { perspective: perspectiveData, status } = useGetPerspective({\n accountId,\n backendBaseUrl,\n perspectiveId,\n envFromUrl,\n });\n\n const isPerspectiveLoading = status === AsyncStatus.Loading;\n\n const { isClusterOnly, recommendationsEnabled } = clusterInfoUtil(\n perspectiveData?.dataSources,\n );\n\n const [timeRange, setTimeRange] =\n useState<TimeRangeFilterType>(DEFAULT_TIME_RANGE);\n\n useEffect(() => {\n if (perspectiveData?.viewTimeRange) {\n const viewTimeRangeType =\n perspectiveData.viewTimeRange?.viewTimeRangeType;\n\n const dateRange =\n (viewTimeRangeType &&\n perspectiveDefaultTimeRangeMapper[viewTimeRangeType]) ||\n DATE_RANGE_SHORTCUTS.LAST_30_DAYS;\n\n setTimeRange({\n to: dateRange[1].format(CE_DATE_FORMAT_INTERNAL),\n from: dateRange[0].format(CE_DATE_FORMAT_INTERNAL),\n });\n }\n }, [perspectiveData]);\n\n const groupBy =\n perspectiveData?.viewVisualization?.groupBy || DEFAULT_GROUP_BY;\n const aggregation =\n perspectiveData?.viewVisualization?.granularity ||\n QlceViewTimeGroupType.Day;\n\n const isPerspectiveReady = !isPerspectiveLoading && perspectiveData;\n\n const { perspectiveSummary, loading: isSummaryLoading } =\n useFetchPerspectiveDetailsSummaryWithBudget({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n aggregateFunction: PERSPECTIVE_DETAILS_AGGREGATE,\n filters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n groupBy: [getGroupByFilter(groupBy)],\n isClusterHourlyData: false,\n isClusterQuery: false,\n preferences: perspectiveData?.viewPreferences,\n },\n lazy: !isPerspectiveReady,\n });\n\n const [page, setPage] = useState(0);\n\n const handleChangePage = (currentPage: number) => {\n setPage(currentPage);\n };\n\n const { perspectiveRecommendations, loading: areRecommendationsLoading } =\n useFetchPerspectiveRecommendations({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n filter: {\n perspectiveFilters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n minSaving: 1,\n offset: 0,\n limit: 10,\n } as unknown as K8sRecommendationFilterDtoInput,\n },\n lazy: !isPerspectiveReady,\n });\n\n const { perspectiveChart, loading: isChartLoading } =\n useFetchPerspectiveChart({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n filters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n groupBy: [getTimeRangeFilter(aggregation), getGroupByFilter(groupBy)],\n isClusterHourlyData: false,\n limit: 12,\n preferences: perspectiveData?.viewPreferences,\n },\n lazy: !isPerspectiveReady,\n });\n\n const { perspectiveGrid, loading: isGridLoading } = useFetchPerspectiveGrid({\n accountId,\n backendBaseUrl,\n env: envFromUrl,\n variables: {\n aggregateFunction: PERSPECTIVE_DETAILS_AGGREGATE,\n filters: [\n getViewFilterForId(perspectiveId),\n ...getTimeFilters(\n getGMTStartDateTime(timeRange.from),\n getGMTEndDateTime(timeRange.to),\n ),\n ],\n groupBy: [getGroupByFilter(groupBy)],\n isClusterHourlyData: false,\n isClusterOnly,\n preferences: perspectiveData?.viewPreferences,\n limit: 15,\n offset: page * 15,\n },\n lazy: !isPerspectiveReady,\n });\n\n const totalCostStats = perspectiveSummary?.perspectiveTrendStats?.cost;\n const forecastedCostStats = perspectiveSummary?.perspectiveForecastCost?.cost;\n\n const chartData = perspectiveChart?.perspectiveTimeSeriesStats\n ?.stats as TimeSeriesDataPoints[];\n const gridData = perspectiveGrid?.perspectiveGrid\n ?.data as QlceViewEntityStatsDataPoint[];\n\n const { licenses } = useGetLicense({\n backendBaseUrl,\n env: envFromUrl,\n accountId,\n });\n\n const getCcmGetStartedLink = () =>\n `${baseUrl}/ng/account/${accountId}/ce/home/trial`;\n\n if (licenses === 'NA') {\n return (\n <EmptyState\n title=\"Cloud Cost Management Module License not subscribed\"\n missing=\"info\"\n description=\"You need to have an active Cloud Cost Management Module License to view this page.\"\n action={\n <Button\n variant=\"contained\"\n color=\"primary\"\n target=\"_blank\"\n href={getCcmGetStartedLink()}\n >\n Get Started\n </Button>\n }\n />\n );\n } else if (licenses === 'Unauthorized') {\n return (\n <EmptyState\n title=\"Harness Cloud Cost Management\"\n missing=\"info\"\n description=\"The x-api-key is either missing or incorrect in app-config.yaml under proxy settings.\"\n />\n );\n }\n\n if (status === AsyncStatus.Forbidden) {\n return (\n <EmptyState\n title=\"Harness Cloud Cost Management\"\n missing=\"info\"\n description=\"You don't have access to view this Perspective\"\n />\n );\n }\n\n return (\n <div>\n <div className={classes.subHeader}>\n <TimeFilter\n isLoading={isPerspectiveLoading}\n timeRange={timeRange}\n setTimeRange={setTimeRange}\n />\n </div>\n <Grid container spacing={3} direction=\"row\">\n <Grid item>\n <CostCard\n isLoading={isSummaryLoading || isPerspectiveLoading}\n statsLabel={totalCostStats?.statsLabel || ''}\n statsValue={totalCostStats?.statsValue || ''}\n statsDescription={totalCostStats?.statsDescription || ''}\n statsTrend={totalCostStats?.statsTrend}\n />\n </Grid>\n <Grid item>\n <CostCard\n isLoading={isSummaryLoading || isPerspectiveLoading}\n statsLabel={forecastedCostStats?.statsLabel || ''}\n statsValue={forecastedCostStats?.statsValue || ''}\n statsDescription={forecastedCostStats?.statsDescription || ''}\n />\n </Grid>\n {recommendationsEnabled ? (\n <Grid item>\n <RecommendationsCard\n isLoading={areRecommendationsLoading}\n totalSavings={\n perspectiveRecommendations?.recommendationStatsV2\n ?.totalMonthlySaving || 0\n }\n recommendationsCount={\n perspectiveRecommendations?.recommendationStatsV2?.count || 0\n }\n />\n </Grid>\n ) : null}\n <div style={{ flexGrow: 1 }} />\n <Grid item>\n <Card className={classes.linkCard}>\n <Typography variant=\"h6\">Want to see a detailed view?</Typography>\n <Link\n href={perspectiveUrl}\n target=\"_blank\"\n className={classes.linkCtn}\n >\n Go to {perspectiveData?.name} Perspective{' '}\n <LaunchIcon fontSize=\"small\" />\n </Link>\n </Card>\n </Grid>\n </Grid>\n <Card className={classes.chartAndGridCtn}>\n <PerspectivesChart\n isLoading={isChartLoading || isPerspectiveLoading}\n viewVisualization={perspectiveData?.viewVisualization?.chartType}\n data={chartData || []}\n />\n <PerspectivesGrid\n isLoading={isGridLoading || isPerspectiveLoading}\n data={gridData || []}\n totalCount={perspectiveGrid?.perspectiveTotalCount || 0}\n page={page}\n handlePageChange={handleChangePage}\n />\n </Card>\n </div>\n );\n};\n\nexport default PerspectivesPage;\n","import React from 'react';\nimport { Routes, Route } from 'react-router';\nimport { Entity } from '@backstage/catalog-model';\nimport {\n MissingAnnotationEmptyState,\n useEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport PerspectivesPage from './PerspectivesPage';\n\n/** @public */\nexport const isHarnessCcmAvailable = (entity: Entity) =>\n Boolean(entity.metadata.annotations?.['harness.io/perspective-url']);\n\n/** @public */\nexport const Router = () => {\n const { entity } = useEntity();\n\n if (!isHarnessCcmAvailable(entity)) {\n return (\n <>\n <MissingAnnotationEmptyState annotation=\"harness.io/perspective-url\" />\n </>\n );\n }\n\n return (\n <Routes>\n <Route path=\"/\" element={<PerspectivesPage />} />\n </Routes>\n );\n};\n"],"names":["AsyncStatus","ViewFieldIdentifier","QlceViewTimeGroupType","QlceViewTimeFilterOperator","QlceViewAggregateOperation","ViewTimeRangeType","DATE_RANGE_SHORTCUTS_NAME","useStyles","_a"],"mappings":"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"}
|