@red-hat-developer-hub/plugin-cost-management 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +28 -1
- package/dist/Router.esm.js +11 -11
- package/dist/Router.esm.js.map +1 -1
- package/dist/alpha.d.ts +136 -0
- package/dist/alpha.esm.js +108 -0
- package/dist/alpha.esm.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/pages/openshift/OpenShiftPage.esm.js +2 -0
- package/dist/pages/openshift/OpenShiftPage.esm.js.map +1 -1
- package/package.json +20 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @red-hat-developer-hub/plugin-cost-management
|
|
2
2
|
|
|
3
|
+
## 2.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ef3257c: Add a New Frontend System `/alpha` export so the plugin loads in RHDH 2.1, with Optimizations and Cost Management sidebar pages. Legacy PluginRoot exports are unchanged.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- @red-hat-developer-hub/plugin-cost-management-common@2.4.0
|
|
12
|
+
|
|
3
13
|
## 2.3.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -44,7 +44,34 @@ You can follow one of these options depending on your environment and how you ch
|
|
|
44
44
|
backend.add(import('@red-hat-developer-hub/plugin-cost-management-backend'));
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
1. Add the
|
|
47
|
+
1. Add the frontend plugin to your app.
|
|
48
|
+
|
|
49
|
+
**New Frontend System** (RHDH 2.1 / `app-next`):
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import costManagementPlugin from '@red-hat-developer-hub/plugin-cost-management/alpha';
|
|
53
|
+
|
|
54
|
+
const app = createApp({
|
|
55
|
+
features: [costManagementPlugin],
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Sidebar items come from the plugin: **Optimizations** (`/cost-management/optimizations`) and **Cost Management** (`/cost-management/openshift`). Optional overrides:
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
app:
|
|
63
|
+
extensions:
|
|
64
|
+
- page:cost-management:
|
|
65
|
+
config:
|
|
66
|
+
title: Optimizations
|
|
67
|
+
path: /cost-management/optimizations
|
|
68
|
+
- page:cost-management/openshift:
|
|
69
|
+
config:
|
|
70
|
+
title: Cost Management
|
|
71
|
+
path: /cost-management/openshift
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Legacy frontend** (`FlatRoutes`):
|
|
48
75
|
|
|
49
76
|
```ts
|
|
50
77
|
// packages/app/src/App.tsx
|
package/dist/Router.esm.js
CHANGED
|
@@ -3,25 +3,25 @@ import { ErrorPage } from '@backstage/core-components';
|
|
|
3
3
|
import { Routes, Route } from 'react-router-dom';
|
|
4
4
|
import { OptimizationsPage } from './pages/optimizations/OptimizationsPage.esm.js';
|
|
5
5
|
import { OptimizationsBreakdownPage } from './pages/optimizations-breakdown/OptimizationsBreakdownPage.esm.js';
|
|
6
|
-
import { OpenShiftPage } from './pages/openshift/OpenShiftPage.esm.js';
|
|
7
6
|
import { usePatternFlyTheme } from './hooks/usePatternFlyTheme.esm.js';
|
|
8
7
|
|
|
8
|
+
const notFound = /* @__PURE__ */ jsx(ErrorPage, { status: "404", statusMessage: "Page not found" });
|
|
9
|
+
function OptimizationsRouter() {
|
|
10
|
+
usePatternFlyTheme();
|
|
11
|
+
return /* @__PURE__ */ jsxs(Routes, { children: [
|
|
12
|
+
/* @__PURE__ */ jsx(Route, { path: "/", element: /* @__PURE__ */ jsx(OptimizationsPage, {}) }),
|
|
13
|
+
/* @__PURE__ */ jsx(Route, { path: "/:id/*", element: /* @__PURE__ */ jsx(OptimizationsBreakdownPage, {}) }),
|
|
14
|
+
/* @__PURE__ */ jsx(Route, { path: "*", element: notFound })
|
|
15
|
+
] });
|
|
16
|
+
}
|
|
9
17
|
function Router() {
|
|
10
18
|
usePatternFlyTheme();
|
|
11
19
|
return /* @__PURE__ */ jsxs(Routes, { children: [
|
|
12
20
|
/* @__PURE__ */ jsx(Route, { path: "/", element: /* @__PURE__ */ jsx(OptimizationsPage, {}) }),
|
|
13
|
-
/* @__PURE__ */ jsx(Route, { path: "/optimizations", element: /* @__PURE__ */ jsx(OptimizationsPage, {}) }),
|
|
14
|
-
/* @__PURE__ */ jsx(Route, { path: "/openshift", element: /* @__PURE__ */ jsx(OpenShiftPage, {}) }),
|
|
15
21
|
/* @__PURE__ */ jsx(Route, { path: "/:id/*", element: /* @__PURE__ */ jsx(OptimizationsBreakdownPage, {}) }),
|
|
16
|
-
/* @__PURE__ */ jsx(
|
|
17
|
-
Route,
|
|
18
|
-
{
|
|
19
|
-
path: "*",
|
|
20
|
-
element: /* @__PURE__ */ jsx(ErrorPage, { status: "404", statusMessage: "Page not found" })
|
|
21
|
-
}
|
|
22
|
-
)
|
|
22
|
+
/* @__PURE__ */ jsx(Route, { path: "*", element: notFound })
|
|
23
23
|
] });
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export { Router };
|
|
26
|
+
export { OptimizationsRouter, Router };
|
|
27
27
|
//# sourceMappingURL=Router.esm.js.map
|
package/dist/Router.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Router.esm.js","sources":["../src/Router.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorPage } from '@backstage/core-components';\nimport { Routes, Route } from 'react-router-dom';\nimport { OptimizationsPage } from './pages/optimizations/OptimizationsPage';\nimport { OptimizationsBreakdownPage } from './pages/optimizations-breakdown/OptimizationsBreakdownPage';\nimport {
|
|
1
|
+
{"version":3,"file":"Router.esm.js","sources":["../src/Router.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorPage } from '@backstage/core-components';\nimport { Routes, Route } from 'react-router-dom';\nimport { OptimizationsPage } from './pages/optimizations/OptimizationsPage';\nimport { OptimizationsBreakdownPage } from './pages/optimizations-breakdown/OptimizationsBreakdownPage';\nimport { usePatternFlyTheme } from './hooks/usePatternFlyTheme';\n\nconst notFound = <ErrorPage status=\"404\" statusMessage=\"Page not found\" />;\n\n/**\n * NFS Optimizations page loader: list + breakdown only.\n * OpenShift is a separate PageBlueprint, not a child of this mount.\n */\nexport function OptimizationsRouter() {\n usePatternFlyTheme();\n\n return (\n <Routes>\n <Route path=\"/\" element={<OptimizationsPage />} />\n <Route path=\"/:id/*\" element={<OptimizationsBreakdownPage />} />\n <Route path=\"*\" element={notFound} />\n </Routes>\n );\n}\n\n/** @public Legacy ResourceOptimizationPage mount (list + breakdown). */\nexport function Router() {\n usePatternFlyTheme();\n\n return (\n <Routes>\n <Route path=\"/\" element={<OptimizationsPage />} />\n <Route path=\"/:id/*\" element={<OptimizationsBreakdownPage />} />\n <Route path=\"*\" element={notFound} />\n </Routes>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAsBA,MAAM,2BAAW,GAAA,CAAC,SAAA,EAAA,EAAU,MAAA,EAAO,KAAA,EAAM,eAAc,gBAAA,EAAiB,CAAA;AAMjE,SAAS,mBAAA,GAAsB;AACpC,EAAA,kBAAA,EAAmB;AAEnB,EAAA,4BACG,MAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,SAAM,IAAA,EAAK,GAAA,EAAI,OAAA,kBAAS,GAAA,CAAC,qBAAkB,CAAA,EAAI,CAAA;AAAA,wBAC/C,KAAA,EAAA,EAAM,IAAA,EAAK,UAAS,OAAA,kBAAS,GAAA,CAAC,8BAA2B,CAAA,EAAI,CAAA;AAAA,oBAC9D,GAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAK,GAAA,EAAI,SAAS,QAAA,EAAU;AAAA,GAAA,EACrC,CAAA;AAEJ;AAGO,SAAS,MAAA,GAAS;AACvB,EAAA,kBAAA,EAAmB;AAEnB,EAAA,4BACG,MAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,SAAM,IAAA,EAAK,GAAA,EAAI,OAAA,kBAAS,GAAA,CAAC,qBAAkB,CAAA,EAAI,CAAA;AAAA,wBAC/C,KAAA,EAAA,EAAM,IAAA,EAAK,UAAS,OAAA,kBAAS,GAAA,CAAC,8BAA2B,CAAA,EAAI,CAAA;AAAA,oBAC9D,GAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAK,GAAA,EAAI,SAAS,QAAA,EAAU;AAAA,GAAA,EACrC,CAAA;AAEJ;;;;"}
|
package/dist/alpha.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
3
|
+
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Cost Management plugin for the Backstage new frontend system.
|
|
7
|
+
* @alpha
|
|
8
|
+
*/
|
|
9
|
+
declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{
|
|
10
|
+
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
11
|
+
openShift: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
12
|
+
breakdown: _backstage_core_plugin_api.SubRouteRef<_backstage_core_plugin_api.PathParams<"/:id/*">>;
|
|
13
|
+
}, {}, {
|
|
14
|
+
"api:cost-management/cost-management-slim": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
15
|
+
kind: "api";
|
|
16
|
+
name: "cost-management-slim";
|
|
17
|
+
config: {};
|
|
18
|
+
configInput: {};
|
|
19
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
20
|
+
inputs: {};
|
|
21
|
+
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
22
|
+
}>;
|
|
23
|
+
"api:cost-management/optimizations": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
24
|
+
kind: "api";
|
|
25
|
+
name: "optimizations";
|
|
26
|
+
config: {};
|
|
27
|
+
configInput: {};
|
|
28
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
29
|
+
inputs: {};
|
|
30
|
+
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
31
|
+
}>;
|
|
32
|
+
"api:cost-management/orchestrator-slim": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
33
|
+
kind: "api";
|
|
34
|
+
name: "orchestrator-slim";
|
|
35
|
+
config: {};
|
|
36
|
+
configInput: {};
|
|
37
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
38
|
+
inputs: {};
|
|
39
|
+
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
40
|
+
}>;
|
|
41
|
+
"icon-bundle:cost-management/cost-management-icons": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
42
|
+
kind: "icon-bundle";
|
|
43
|
+
name: "cost-management-icons";
|
|
44
|
+
config: {};
|
|
45
|
+
configInput: {};
|
|
46
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<{
|
|
47
|
+
[x: string]: _backstage_frontend_plugin_api.IconComponent | _backstage_frontend_plugin_api.IconElement;
|
|
48
|
+
}, "core.icons", {}>;
|
|
49
|
+
inputs: {};
|
|
50
|
+
params: {
|
|
51
|
+
icons: { [key in string]: _backstage_frontend_plugin_api.IconComponent | _backstage_frontend_plugin_api.IconElement; };
|
|
52
|
+
};
|
|
53
|
+
}>;
|
|
54
|
+
"page:cost-management": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
55
|
+
kind: "page";
|
|
56
|
+
name: undefined;
|
|
57
|
+
config: {
|
|
58
|
+
path: string | undefined;
|
|
59
|
+
title: string | undefined;
|
|
60
|
+
};
|
|
61
|
+
configInput: {
|
|
62
|
+
path?: string | undefined;
|
|
63
|
+
title?: string | undefined;
|
|
64
|
+
};
|
|
65
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
66
|
+
optional: true;
|
|
67
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.title", {
|
|
68
|
+
optional: true;
|
|
69
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
70
|
+
optional: true;
|
|
71
|
+
}>;
|
|
72
|
+
inputs: {
|
|
73
|
+
pages: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
74
|
+
optional: true;
|
|
75
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.title", {
|
|
76
|
+
optional: true;
|
|
77
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
78
|
+
optional: true;
|
|
79
|
+
}>, {
|
|
80
|
+
singleton: false;
|
|
81
|
+
optional: false;
|
|
82
|
+
internal: false;
|
|
83
|
+
}>;
|
|
84
|
+
};
|
|
85
|
+
params: {
|
|
86
|
+
path: string;
|
|
87
|
+
title?: string;
|
|
88
|
+
icon?: _backstage_frontend_plugin_api.IconElement;
|
|
89
|
+
loader?: () => Promise<react.JSX.Element>;
|
|
90
|
+
routeRef?: _backstage_frontend_plugin_api.RouteRef;
|
|
91
|
+
noHeader?: boolean;
|
|
92
|
+
};
|
|
93
|
+
}>;
|
|
94
|
+
"page:cost-management/openshift": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
95
|
+
kind: "page";
|
|
96
|
+
name: "openshift";
|
|
97
|
+
config: {
|
|
98
|
+
path: string | undefined;
|
|
99
|
+
title: string | undefined;
|
|
100
|
+
};
|
|
101
|
+
configInput: {
|
|
102
|
+
path?: string | undefined;
|
|
103
|
+
title?: string | undefined;
|
|
104
|
+
};
|
|
105
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
106
|
+
optional: true;
|
|
107
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.title", {
|
|
108
|
+
optional: true;
|
|
109
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
110
|
+
optional: true;
|
|
111
|
+
}>;
|
|
112
|
+
inputs: {
|
|
113
|
+
pages: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
114
|
+
optional: true;
|
|
115
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.title", {
|
|
116
|
+
optional: true;
|
|
117
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
118
|
+
optional: true;
|
|
119
|
+
}>, {
|
|
120
|
+
singleton: false;
|
|
121
|
+
optional: false;
|
|
122
|
+
internal: false;
|
|
123
|
+
}>;
|
|
124
|
+
};
|
|
125
|
+
params: {
|
|
126
|
+
path: string;
|
|
127
|
+
title?: string;
|
|
128
|
+
icon?: _backstage_frontend_plugin_api.IconElement;
|
|
129
|
+
loader?: () => Promise<react.JSX.Element>;
|
|
130
|
+
routeRef?: _backstage_frontend_plugin_api.RouteRef;
|
|
131
|
+
noHeader?: boolean;
|
|
132
|
+
};
|
|
133
|
+
}>;
|
|
134
|
+
}>;
|
|
135
|
+
|
|
136
|
+
export { _default as default };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { fetchApiRef, discoveryApiRef, identityApiRef } from '@backstage/core-plugin-api';
|
|
3
|
+
import { ApiBlueprint, createApiFactory, PageBlueprint, createFrontendPlugin } from '@backstage/frontend-plugin-api';
|
|
4
|
+
import { IconBundleBlueprint } from '@backstage/plugin-app-react';
|
|
5
|
+
import { OptimizationsClient, OrchestratorSlimClient, CostManagementSlimClient } from '@red-hat-developer-hub/plugin-cost-management-common/clients';
|
|
6
|
+
import { optimizationsApiRef, orchestratorSlimApiRef, costManagementSlimApiRef } from './apis.esm.js';
|
|
7
|
+
import '@material-ui/core/SvgIcon';
|
|
8
|
+
import { CostManagementIconOutlined } from './components/icon/CostManagementIconOutlined.esm.js';
|
|
9
|
+
import { rootRouteRef, openShiftRouteRef, optimizationsBreakdownRouteRef } from './routes.esm.js';
|
|
10
|
+
|
|
11
|
+
const optimizationsApi = ApiBlueprint.make({
|
|
12
|
+
name: "optimizations",
|
|
13
|
+
params: (defineParams) => defineParams(
|
|
14
|
+
createApiFactory({
|
|
15
|
+
api: optimizationsApiRef,
|
|
16
|
+
deps: {
|
|
17
|
+
discoveryApi: discoveryApiRef,
|
|
18
|
+
fetchApi: fetchApiRef
|
|
19
|
+
},
|
|
20
|
+
factory: ({ discoveryApi, fetchApi }) => new OptimizationsClient({
|
|
21
|
+
discoveryApi,
|
|
22
|
+
fetchApi
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
)
|
|
26
|
+
});
|
|
27
|
+
const orchestratorSlimApi = ApiBlueprint.make({
|
|
28
|
+
name: "orchestrator-slim",
|
|
29
|
+
params: (defineParams) => defineParams(
|
|
30
|
+
createApiFactory({
|
|
31
|
+
api: orchestratorSlimApiRef,
|
|
32
|
+
deps: {
|
|
33
|
+
discoveryApi: discoveryApiRef,
|
|
34
|
+
fetchApi: fetchApiRef,
|
|
35
|
+
identityApi: identityApiRef
|
|
36
|
+
},
|
|
37
|
+
factory: ({ discoveryApi, fetchApi, identityApi }) => new OrchestratorSlimClient({
|
|
38
|
+
discoveryApi,
|
|
39
|
+
fetchApi,
|
|
40
|
+
identityApi
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
)
|
|
44
|
+
});
|
|
45
|
+
const costManagementSlimApi = ApiBlueprint.make({
|
|
46
|
+
name: "cost-management-slim",
|
|
47
|
+
params: (defineParams) => defineParams(
|
|
48
|
+
createApiFactory({
|
|
49
|
+
api: costManagementSlimApiRef,
|
|
50
|
+
deps: {
|
|
51
|
+
discoveryApi: discoveryApiRef,
|
|
52
|
+
fetchApi: fetchApiRef
|
|
53
|
+
},
|
|
54
|
+
factory: ({ discoveryApi, fetchApi }) => new CostManagementSlimClient({
|
|
55
|
+
discoveryApi,
|
|
56
|
+
fetchApi
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
)
|
|
60
|
+
});
|
|
61
|
+
const costManagementIcons = IconBundleBlueprint.make({
|
|
62
|
+
name: "cost-management-icons",
|
|
63
|
+
params: {
|
|
64
|
+
icons: {
|
|
65
|
+
costManagementIconOutlined: CostManagementIconOutlined
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const optimizationsPage = PageBlueprint.make({
|
|
70
|
+
params: {
|
|
71
|
+
path: "/cost-management/optimizations",
|
|
72
|
+
routeRef: rootRouteRef,
|
|
73
|
+
title: "Optimizations",
|
|
74
|
+
icon: /* @__PURE__ */ jsx(CostManagementIconOutlined, {}),
|
|
75
|
+
noHeader: true,
|
|
76
|
+
loader: () => import('./Router.esm.js').then((m) => /* @__PURE__ */ jsx(m.OptimizationsRouter, {}))
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const openShiftPage = PageBlueprint.make({
|
|
80
|
+
name: "openshift",
|
|
81
|
+
params: {
|
|
82
|
+
path: "/cost-management/openshift",
|
|
83
|
+
routeRef: openShiftRouteRef,
|
|
84
|
+
title: "Cost Management",
|
|
85
|
+
icon: /* @__PURE__ */ jsx(CostManagementIconOutlined, {}),
|
|
86
|
+
noHeader: true,
|
|
87
|
+
loader: () => import('./pages/openshift/OpenShiftPage.esm.js').then((m) => /* @__PURE__ */ jsx(m.OpenShiftPage, {}))
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
var alpha = createFrontendPlugin({
|
|
91
|
+
pluginId: "cost-management",
|
|
92
|
+
extensions: [
|
|
93
|
+
optimizationsApi,
|
|
94
|
+
orchestratorSlimApi,
|
|
95
|
+
costManagementSlimApi,
|
|
96
|
+
costManagementIcons,
|
|
97
|
+
optimizationsPage,
|
|
98
|
+
openShiftPage
|
|
99
|
+
],
|
|
100
|
+
routes: {
|
|
101
|
+
root: rootRouteRef,
|
|
102
|
+
openShift: openShiftRouteRef,
|
|
103
|
+
breakdown: optimizationsBreakdownRouteRef
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export { alpha as default };
|
|
108
|
+
//# sourceMappingURL=alpha.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":["../src/alpha.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * New Frontend System entry (`./alpha`).\n *\n * @packageDocumentation\n */\n\nimport {\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n} from '@backstage/core-plugin-api';\nimport {\n ApiBlueprint,\n createApiFactory,\n createFrontendPlugin,\n PageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { IconBundleBlueprint } from '@backstage/plugin-app-react';\nimport {\n CostManagementSlimClient,\n OptimizationsClient,\n OrchestratorSlimClient,\n} from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport {\n costManagementSlimApiRef,\n optimizationsApiRef,\n orchestratorSlimApiRef,\n} from './apis';\nimport { CostManagementIconOutlined } from './components/icon';\nimport {\n optimizationsBreakdownRouteRef,\n openShiftRouteRef,\n rootRouteRef,\n} from './routes';\n\nconst optimizationsApi = ApiBlueprint.make({\n name: 'optimizations',\n params: defineParams =>\n defineParams(\n createApiFactory({\n api: optimizationsApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new OptimizationsClient({\n discoveryApi,\n fetchApi,\n }),\n }),\n ),\n});\n\nconst orchestratorSlimApi = ApiBlueprint.make({\n name: 'orchestrator-slim',\n params: defineParams =>\n defineParams(\n createApiFactory({\n api: orchestratorSlimApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, fetchApi, identityApi }) =>\n new OrchestratorSlimClient({\n discoveryApi,\n fetchApi,\n identityApi,\n }),\n }),\n ),\n});\n\nconst costManagementSlimApi = ApiBlueprint.make({\n name: 'cost-management-slim',\n params: defineParams =>\n defineParams(\n createApiFactory({\n api: costManagementSlimApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new CostManagementSlimClient({\n discoveryApi,\n fetchApi,\n }),\n }),\n ),\n});\n\nconst costManagementIcons = IconBundleBlueprint.make({\n name: 'cost-management-icons',\n params: {\n icons: {\n costManagementIconOutlined: CostManagementIconOutlined,\n },\n },\n});\n\nconst optimizationsPage = PageBlueprint.make({\n params: {\n path: '/cost-management/optimizations',\n routeRef: rootRouteRef,\n title: 'Optimizations',\n icon: <CostManagementIconOutlined />,\n noHeader: true,\n loader: () => import('./Router').then(m => <m.OptimizationsRouter />),\n },\n});\n\nconst openShiftPage = PageBlueprint.make({\n name: 'openshift',\n params: {\n path: '/cost-management/openshift',\n routeRef: openShiftRouteRef,\n title: 'Cost Management',\n icon: <CostManagementIconOutlined />,\n noHeader: true,\n loader: () =>\n import('./pages/openshift/OpenShiftPage').then(m => <m.OpenShiftPage />),\n },\n});\n\n/**\n * Cost Management plugin for the Backstage new frontend system.\n * @alpha\n */\nexport default createFrontendPlugin({\n pluginId: 'cost-management',\n extensions: [\n optimizationsApi,\n orchestratorSlimApi,\n costManagementSlimApi,\n costManagementIcons,\n optimizationsPage,\n openShiftPage,\n ],\n routes: {\n root: rootRouteRef,\n openShift: openShiftRouteRef,\n breakdown: optimizationsBreakdownRouteRef,\n },\n});\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ declare const AnalyticsIconOutlined: (props: SvgIconProps) => react_jsx_runtime.
|
|
|
48
48
|
*/
|
|
49
49
|
declare const AnalyticsIconFilled: (props: SvgIconProps) => react_jsx_runtime.JSX.Element;
|
|
50
50
|
|
|
51
|
-
/** @public */
|
|
51
|
+
/** @public Legacy ResourceOptimizationPage mount (list + breakdown). */
|
|
52
52
|
declare function Router(): react_jsx_runtime.JSX.Element;
|
|
53
53
|
|
|
54
54
|
/** @public */
|
|
@@ -10,6 +10,7 @@ import { PageHeader } from './components/PageHeader.esm.js';
|
|
|
10
10
|
import { TableToolbar } from './components/TableToolbar.esm.js';
|
|
11
11
|
import { useApi } from '@backstage/core-plugin-api';
|
|
12
12
|
import { costManagementSlimApiRef } from '../../apis.esm.js';
|
|
13
|
+
import { usePatternFlyTheme } from '../../hooks/usePatternFlyTheme.esm.js';
|
|
13
14
|
import useAsync from 'react-use/lib/useAsync';
|
|
14
15
|
import { CURRENCY_SYMBOLS } from '../../constants/currencies.esm.js';
|
|
15
16
|
import { DownloadIconButton } from './components/DownloadIconButton.esm.js';
|
|
@@ -109,6 +110,7 @@ function buildCostManagementQueryParams(config, options = {}) {
|
|
|
109
110
|
return queryParams;
|
|
110
111
|
}
|
|
111
112
|
function OpenShiftPage() {
|
|
113
|
+
usePatternFlyTheme();
|
|
112
114
|
const api = useApi(costManagementSlimApiRef);
|
|
113
115
|
const [groupBy, setGroupBy] = useState("project");
|
|
114
116
|
const [overheadDistribution, setOverheadDistribution] = useState("distribute");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenShiftPage.esm.js","sources":["../../../src/pages/openshift/OpenShiftPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useMemo, useState, useCallback, useRef } from 'react';\nimport type { ExportFormat } from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport {\n Table,\n TableColumn,\n InfoCard,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport { BasePage } from '../../components/BasePage';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Filters } from './components/Filters';\nimport { Divider, useTheme } from '@material-ui/core';\nimport { PageHeader } from './components/PageHeader';\nimport { TableToolbar } from './components/TableToolbar';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { costManagementSlimApiRef } from '../../apis';\nimport useAsync from 'react-use/lib/useAsync';\nimport { CURRENCY_SYMBOLS } from '../../constants/currencies';\nimport { DownloadIconButton } from './components/DownloadIconButton';\n\nconst formatCurrency = (value: number, currencyCode: string): string => {\n const symbol = CURRENCY_SYMBOLS[currencyCode] || currencyCode;\n return `${symbol}${value.toLocaleString('en-US', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}`;\n};\n\ninterface ProjectCost {\n id: string;\n projectName: string;\n clusterId?: string;\n cost: number;\n costPercentage: number;\n monthOverMonthChange: number;\n monthOverMonthValue: number;\n includesOverhead: boolean;\n previousPeriodCost: number;\n infrastructureCost: number;\n infrastructureCostPercentage: number;\n supplementaryCost: number;\n supplementaryCostPercentage: number;\n}\n\n/**\n * Generates date range text based on time range selection\n * @param timeRange - 'month-to-date' or 'previous-month'\n * @returns Formatted string like \"December 1-3\" or \"November 1-30\"\n */\nfunction getDateRangeText(timeRange: string): string {\n const now = new Date();\n const currentMonth = now.getMonth();\n const currentYear = now.getFullYear();\n const currentDay = now.getDate();\n\n if (timeRange === 'month-to-date') {\n // Current month: MONTH 1-<CURRENT_DAY>\n const monthName = now.toLocaleString('en-US', { month: 'long' });\n return `${monthName} 1-${currentDay}`;\n }\n // Previous month: PREVIOUS_MONTH 1-<LAST_DAY>\n const prevMonth = currentMonth === 0 ? 11 : currentMonth - 1;\n const prevYear = currentMonth === 0 ? currentYear - 1 : currentYear;\n const prevMonthDate = new Date(prevYear, prevMonth + 1, 0); // Last day of previous month\n const lastDay = prevMonthDate.getDate();\n const monthName = prevMonthDate.toLocaleString('en-US', { month: 'long' });\n return `${monthName} 1-${lastDay}`;\n}\n\n/**\n * Configuration for building query parameters\n */\ninterface QueryParamsConfig {\n groupBy: string;\n selectedTag: string;\n overheadDistribution: string;\n timeRange: string;\n currency: string;\n showPlatformSum: boolean;\n filterBy: string;\n filterValue: string;\n filterOperation: string;\n selectedTagKey: string;\n selectedTagValue: string;\n sortField: string | null;\n sortDirection: 'asc' | 'desc';\n}\n\n/**\n * Options for building query parameters\n */\ninterface BuildQueryParamsOptions {\n /** Pagination limit - omit for download (uses 0) */\n limit?: number;\n /** Pagination offset - omit for download */\n offset?: number;\n /** Specific item name to filter by (for row-level download) */\n specificItemName?: string;\n}\n\n/**\n * Builds query parameters for cost management API requests\n * Shared between data fetching and download functionality\n */\nfunction buildCostManagementQueryParams(\n config: QueryParamsConfig,\n options: BuildQueryParamsOptions = {},\n): Record<string, string | number> {\n const {\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n } = config;\n\n const { limit, offset, specificItemName } = options;\n\n // Build group by parameter\n const groupByParam =\n groupBy === 'tag' ? `group_by[tag:${selectedTag}]` : `group_by[${groupBy}]`;\n\n // Determine delta parameter\n const deltaParam =\n groupBy === 'project' && overheadDistribution === 'distribute'\n ? 'distributed_cost'\n : 'cost';\n\n const timeScopeValue = timeRange === 'month-to-date' ? -1 : -2;\n\n const queryParams: Record<string, string | number> = {\n currency,\n delta: deltaParam,\n 'filter[resolution]': 'monthly',\n 'filter[time_scope_units]': 'month',\n 'filter[time_scope_value]': timeScopeValue,\n };\n\n // Add pagination if provided\n if (limit !== undefined) {\n queryParams['filter[limit]'] = limit;\n }\n if (offset !== undefined) {\n queryParams['filter[offset]'] = offset;\n }\n\n // Add category parameter when showPlatformSum is enabled\n if (showPlatformSum) {\n queryParams.category = 'Platform';\n }\n\n queryParams[groupByParam] = '*';\n\n // Handle filtering\n if (specificItemName) {\n // Filter for specific item (row-level download)\n queryParams[`filter[${groupBy}]`] = specificItemName;\n } else if (filterBy === 'tag' && selectedTagKey && selectedTagValue) {\n // Tag filtering\n if (filterOperation === 'exact') {\n queryParams[`filter[exact:tag:${selectedTagKey}]`] = selectedTagValue;\n } else if (filterOperation === 'excludes') {\n queryParams[`exclude[tag:${selectedTagKey}]`] = selectedTagValue;\n } else {\n queryParams[`filter[tag:${selectedTagKey}]`] = selectedTagValue;\n }\n } else if (filterValue) {\n // Regular filtering\n if (filterOperation === 'exact') {\n queryParams[`filter[exact:${filterBy}]`] = filterValue;\n } else if (filterOperation === 'excludes') {\n queryParams[`exclude[${filterBy}]`] = filterValue;\n } else {\n queryParams[`filter[${filterBy}]`] = filterValue;\n }\n }\n\n // Add sorting\n let apiSortField: string;\n if (sortField) {\n if (sortField === 'cost') {\n apiSortField = deltaParam;\n } else if (sortField === 'projectName') {\n apiSortField = groupBy;\n } else {\n apiSortField = deltaParam;\n }\n queryParams[`order_by[${apiSortField}]`] = sortDirection;\n } else {\n queryParams[`order_by[${deltaParam}]`] = 'desc';\n }\n\n return queryParams;\n}\n\n/** @public */\nexport function OpenShiftPage() {\n const api = useApi(costManagementSlimApiRef);\n const [groupBy, setGroupBy] = useState('project');\n const [overheadDistribution, setOverheadDistribution] =\n useState('distribute');\n const [timeRange, setTimeRange] = useState('month-to-date');\n const [currency, setCurrency] = useState('USD');\n const [filterBy, setFilterBy] = useState('project');\n const [filterOperation, setFilterOperation] = useState('includes');\n const [filterValue, setFilterValue] = useState('');\n const [showPlatformSum, setShowPlatformSum] = useState(false);\n const [selectedRows, setSelectedRows] = useState<Set<string>>(new Set());\n const [currentPage, setCurrentPage] = useState(0);\n const [pageSize, setPageSize] = useState(5);\n const [sortField, setSortField] = useState<string | null>(null);\n const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');\n const [tags, setTags] = useState<string[]>([]);\n const [selectedTag, setSelectedTag] = useState<string>('');\n const [selectedTagKey, setSelectedTagKey] = useState<string>('');\n const [selectedTagValue, setSelectedTagValue] = useState<string>('');\n const [showMonthOverMonthChange, setShowMonthOverMonthChange] =\n useState(true);\n const [showInfrastructureCost, setShowInfrastructureCost] = useState(false);\n const [showSupplementaryCost, setShowSupplementaryCost] = useState(false);\n const [isDownloading, setIsDownloading] = useState(false);\n const theme = useTheme();\n const isDarkMode = (theme.palette as any).mode === 'dark';\n\n // Ref to store display data for use in download handlers\n const displayDataRef = useRef<typeof displayData | null>(null);\n\n // Fetch tags on first load\n useAsync(async () => {\n try {\n const timeScopeValue = timeRange === 'month-to-date' ? -1 : -2;\n const response = await api.getOpenShiftTags(timeScopeValue);\n const tagsData = await response.json();\n setTags(tagsData.data || []);\n } catch {\n // Silently fail if tags can't be loaded\n setTags([]);\n }\n }, [api, timeRange]);\n\n // Build config object for query params builder (memoized to prevent unnecessary re-renders)\n const queryParamsConfig: QueryParamsConfig = useMemo(\n () => ({\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n }),\n [\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n ],\n );\n\n const {\n value: costData,\n loading,\n error,\n } = useAsync(async () => {\n // Don't make API call if groupBy is 'tag' but no tag is selected\n if (groupBy === 'tag' && !selectedTag) {\n return null;\n }\n\n const offset = currentPage * pageSize;\n const queryParams = buildCostManagementQueryParams(queryParamsConfig, {\n limit: pageSize,\n offset,\n });\n\n const response = await api.getCostManagementReport({\n query: queryParams,\n });\n return response.json();\n }, [\n currency,\n overheadDistribution,\n timeRange,\n groupBy,\n filterBy,\n filterValue,\n filterOperation,\n showPlatformSum,\n api,\n currentPage,\n pageSize,\n sortField,\n sortDirection,\n selectedTag,\n selectedTagKey,\n selectedTagValue,\n ]);\n\n const displayData = useMemo(() => {\n // If costData is null, return empty structure to keep table visible during loading\n if (!costData) {\n const today = new Date();\n const month =\n timeRange === 'previous-month'\n ? new Date(\n today.getFullYear(),\n today.getMonth() - 1,\n 1,\n ).toLocaleString('en-US', { month: 'long' })\n : today.toLocaleString('en-US', { month: 'long' });\n const endDate =\n timeRange === 'previous-month'\n ? new Date(today.getFullYear(), today.getMonth(), 0)\n .getDate()\n .toString()\n : today.getDate().toString();\n\n return {\n totalCost: 0,\n month,\n endDate,\n currencyCode: currency,\n projects: [],\n };\n }\n\n const arrayKey = `${groupBy}s` as keyof (typeof costData.data)[0];\n const groupedArray = costData.data?.[0]?.[arrayKey] as\n | Array<{ [key: string]: unknown; values: unknown[] }>\n | undefined;\n\n const projects =\n groupedArray?.map((item, index) => {\n const value =\n (item.values?.[0] as {\n cost?: {\n distributed?: { value?: number };\n total?: { value?: number };\n network_unattributed_distributed?: { value?: number };\n worker_unallocated_distributed?: { value?: number };\n platform_distributed?: { value?: number };\n storage_unattributed_distributed?: { value?: number };\n };\n infrastructure?: {\n total?: { value?: number };\n };\n supplementary?: {\n total?: { value?: number };\n };\n delta_percent?: number;\n delta_value?: number;\n }) || {};\n\n // For clusters, prefer values[0].clusters[0] (human-readable) over item.cluster (UUID)\n let itemName: string;\n let clusterId: string | undefined;\n if (groupBy === 'cluster') {\n const valueItem = item.values?.[0] as\n | { clusters?: string[]; cluster?: string }\n | undefined;\n const clustersArray = valueItem?.clusters;\n itemName =\n clustersArray && clustersArray.length > 0\n ? clustersArray[0]\n : (item.cluster as string) || 'Unknown';\n // Store the cluster UUID for display\n clusterId = (item.cluster as string) || undefined;\n } else {\n const nameField = groupBy as keyof typeof item;\n itemName = (item[nameField] as string) || 'Unknown';\n }\n\n const costField =\n groupBy === 'project' && overheadDistribution === 'distribute'\n ? 'distributed'\n : 'total';\n const costValue =\n value?.cost?.[costField as keyof typeof value.cost]?.value || 0;\n\n const deltaPercent = value?.delta_percent || 0;\n const deltaValue = value?.delta_value || 0;\n\n const infrastructureValue = value?.infrastructure?.total?.value || 0;\n const supplementaryValue = value?.supplementary?.total?.value || 0;\n\n return {\n id: `${index}`,\n projectName: itemName,\n clusterId,\n cost: costValue,\n costPercentage: 0,\n monthOverMonthChange: deltaPercent,\n monthOverMonthValue: Math.abs(deltaValue),\n includesOverhead:\n value?.cost?.network_unattributed_distributed?.value !== 0 ||\n value?.cost?.worker_unallocated_distributed?.value !== 0 ||\n value?.cost?.platform_distributed?.value !== 0 ||\n value?.cost?.storage_unattributed_distributed?.value !== 0,\n previousPeriodCost: costValue + Math.abs(deltaValue),\n infrastructureCost: infrastructureValue,\n infrastructureCostPercentage: 0,\n supplementaryCost: supplementaryValue,\n supplementaryCostPercentage: 0,\n };\n }) || [];\n\n const totalCost = costData.meta?.total?.cost?.total?.value || 0;\n const totalInfrastructureCost =\n costData.meta?.total?.infrastructure?.total?.value || 0;\n const totalSupplementaryCost =\n costData.meta?.total?.supplementary?.total?.value || 0;\n\n const currencyCode = costData.meta?.currency || currency;\n\n const projectsWithPercentage = projects.map(p => ({\n ...p,\n costPercentage: totalCost > 0 ? (p.cost / totalCost) * 100 : 0,\n infrastructureCostPercentage:\n totalInfrastructureCost > 0\n ? (p.infrastructureCost / totalInfrastructureCost) * 100\n : 0,\n supplementaryCostPercentage:\n totalSupplementaryCost > 0\n ? (p.supplementaryCost / totalSupplementaryCost) * 100\n : 0,\n }));\n\n let month: string;\n let endDate: string;\n\n if (timeRange === 'previous-month') {\n const today = new Date();\n const previousMonth = new Date(\n today.getFullYear(),\n today.getMonth() - 1,\n 1,\n );\n month = previousMonth.toLocaleString('en-US', { month: 'long' });\n const lastDayOfPreviousMonth = new Date(\n today.getFullYear(),\n today.getMonth(),\n 0,\n ).getDate();\n endDate = lastDayOfPreviousMonth.toString();\n } else {\n const today = new Date();\n month = today.toLocaleString('en-US', { month: 'long' });\n endDate = today.getDate().toString();\n }\n\n return {\n totalCost,\n month,\n endDate,\n currencyCode,\n projects: projectsWithPercentage,\n };\n }, [costData, currency, groupBy, overheadDistribution, timeRange]);\n\n // Update ref when displayData changes\n displayDataRef.current = displayData;\n\n /**\n * Builds query parameters for download request\n * @param specificItemName - Optional: specific item name to filter by (for row-level download)\n */\n const buildDownloadQueryParams = useCallback(\n (specificItemName?: string): Record<string, string | number> => {\n return buildCostManagementQueryParams(queryParamsConfig, {\n specificItemName,\n });\n },\n [queryParamsConfig],\n );\n\n /**\n * Handles download for header buttons (all data based on current filters)\n */\n const handleHeaderDownload = useCallback(\n async (format: ExportFormat) => {\n if (isDownloading) return;\n\n setIsDownloading(true);\n try {\n const queryParams = buildDownloadQueryParams();\n await api.downloadCostManagementReport({\n query: queryParams,\n format,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`Failed to download ${format}:`, err);\n } finally {\n setIsDownloading(false);\n }\n },\n [api, buildDownloadQueryParams, isDownloading],\n );\n\n /**\n * Handles download for row-level buttons (specific item)\n */\n const handleRowDownload = useCallback(\n async (itemName: string, format: ExportFormat) => {\n if (isDownloading) return;\n\n setIsDownloading(true);\n try {\n const queryParams = buildDownloadQueryParams(itemName);\n await api.downloadCostManagementReport({\n query: queryParams,\n format,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`Failed to download ${format} for ${itemName}:`, err);\n } finally {\n setIsDownloading(false);\n }\n },\n [api, buildDownloadQueryParams, isDownloading],\n );\n\n const handleRowSelect = useCallback(\n (rowId: string, isSelected: boolean) => {\n const newSelectedRows = new Set(selectedRows);\n if (isSelected) {\n newSelectedRows.add(rowId);\n } else {\n newSelectedRows.delete(rowId);\n }\n setSelectedRows(newSelectedRows);\n },\n [selectedRows],\n );\n\n const handleSelectAll = useCallback(\n (isSelected: boolean) => {\n if (isSelected && displayData) {\n setSelectedRows(\n new Set(displayData.projects.map(project => project.id)),\n );\n } else {\n setSelectedRows(new Set());\n }\n },\n [displayData],\n );\n\n const handlePageChange = useCallback((page: number, newPageSize: number) => {\n setCurrentPage(page);\n setPageSize(newPageSize);\n }, []);\n\n const handleRowsPerPageChange = useCallback((newPageSize: number) => {\n setPageSize(newPageSize);\n setCurrentPage(0);\n }, []);\n\n const totalCount = costData?.meta?.count || 0;\n\n const isAllSelected =\n displayData !== null &&\n selectedRows.size === displayData.projects.length &&\n displayData.projects.length > 0;\n const isIndeterminate =\n displayData !== null &&\n selectedRows.size > 0 &&\n selectedRows.size < displayData.projects.length;\n\n const columns = useMemo<TableColumn<ProjectCost>[]>(() => {\n const getChangeColor = (change: number) => {\n if (change < 0) return '#d32f2f';\n if (isDarkMode) return '#4BB543';\n return '#2e7d32';\n };\n\n const cols: TableColumn<ProjectCost>[] = [\n {\n title: (\n <div style={{ marginLeft: 0, paddingLeft: 0 }}>\n <input\n type=\"checkbox\"\n checked={isAllSelected}\n ref={input => {\n if (input) input.indeterminate = isIndeterminate;\n }}\n onChange={e => {\n e.stopPropagation();\n handleSelectAll(e.target.checked);\n }}\n style={{\n width: '18px',\n height: '18px',\n cursor: 'pointer',\n margin: 0,\n padding: 0,\n }}\n />\n </div>\n ),\n field: 'checkbox',\n sorting: false,\n width: '40px',\n cellStyle: {\n paddingLeft: '4px',\n paddingRight: '4px',\n },\n headerStyle: {\n paddingLeft: '4px',\n paddingRight: '4px',\n },\n render: data => (\n <div style={{ paddingRight: '4px' }}>\n <input\n type=\"checkbox\"\n checked={selectedRows.has(data.id)}\n onChange={e => handleRowSelect(data.id, e.target.checked)}\n style={{\n width: '18px',\n height: '18px',\n cursor: 'pointer',\n margin: 0,\n padding: 0,\n }}\n />\n </div>\n ),\n },\n {\n title: (\n <Typography variant=\"body2\" style={{ fontWeight: 'bold' }}>\n {groupBy.charAt(0).toLocaleUpperCase('en-US') + groupBy.slice(1)}{' '}\n name\n </Typography>\n ),\n field: 'projectName',\n cellStyle: { minWidth: 350 },\n headerStyle: { minWidth: 350 },\n render: data => (\n <div>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '8px',\n }}\n >\n <Typography variant=\"body2\">{data.projectName}</Typography>\n {groupBy === 'project' && data.includesOverhead && (\n <Typography\n variant=\"caption\"\n style={{\n padding: '2px 6px',\n backgroundColor: '#F5F5F5',\n border: '1px solid #D2D2D2',\n borderRadius: '16px',\n color: 'black',\n whiteSpace: 'nowrap',\n }}\n >\n Includes overhead\n </Typography>\n )}\n </div>\n {groupBy === 'cluster' && data.clusterId && (\n <Typography\n variant=\"caption\"\n style={{ color: '#666', display: 'block', marginTop: 10 }}\n >\n {data.clusterId}\n </Typography>\n )}\n </div>\n ),\n },\n ];\n\n if (showMonthOverMonthChange) {\n cols.push({\n title: 'Month over month change',\n field: 'monthOverMonthChange',\n sorting: false,\n render: data => (\n <div>\n <div\n style={{\n color: getChangeColor(data.monthOverMonthChange),\n }}\n >\n {Math.abs(data.monthOverMonthChange).toFixed(2)}%\n {data.monthOverMonthChange > 0 ? ' ▲' : ' ▼'}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {formatCurrency(\n data.monthOverMonthValue,\n displayData?.currencyCode || '',\n )}{' '}\n for {getDateRangeText(timeRange)}\n </div>\n </div>\n ),\n });\n }\n\n cols.push({\n title: 'Cost',\n field: 'cost',\n render: data => (\n <div>\n <div>\n {formatCurrency(data.cost, displayData?.currencyCode || '')}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.costPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n\n if (showInfrastructureCost) {\n cols.push({\n title: 'Infrastructure cost',\n field: 'infrastructureCost',\n render: data => (\n <div>\n <div>\n {formatCurrency(\n data.infrastructureCost,\n displayData?.currencyCode || '',\n )}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.infrastructureCostPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n }\n\n if (showSupplementaryCost) {\n cols.push({\n title: 'Supplementary cost',\n field: 'supplementaryCost',\n render: data => (\n <div>\n <div>\n {formatCurrency(\n data.supplementaryCost,\n displayData?.currencyCode || '',\n )}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.supplementaryCostPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n }\n\n cols.push({\n title: 'Actions',\n field: 'actions',\n sorting: false,\n render: data => (\n <div style={{ display: 'flex', gap: '8px' }}>\n <DownloadIconButton\n label=\"CSV\"\n variant={isDarkMode ? 'white' : 'black'}\n onClick={() => handleRowDownload(data.projectName, 'csv')}\n disabled={isDownloading}\n />\n <DownloadIconButton\n label=\"JSON\"\n variant={isDarkMode ? 'white' : 'black'}\n onClick={() => handleRowDownload(data.projectName, 'json')}\n disabled={isDownloading}\n />\n </div>\n ),\n });\n\n return cols;\n }, [\n handleRowSelect,\n handleRowDownload,\n isAllSelected,\n isIndeterminate,\n isDownloading,\n selectedRows,\n handleSelectAll,\n displayData?.currencyCode,\n groupBy,\n showMonthOverMonthChange,\n showInfrastructureCost,\n showSupplementaryCost,\n timeRange,\n isDarkMode,\n ]);\n\n const handleOrderChange = useCallback(\n (orderBy: number, orderDirection: 'asc' | 'desc') => {\n // If orderBy is -1, it means \"no sorting\" - ignore it to prevent removing sorting\n if (orderBy === -1) {\n return;\n }\n\n const column = columns[orderBy];\n if (\n column?.field &&\n column.field !== 'actions' &&\n column.sorting !== false\n ) {\n const newField = column.field as string;\n setSortField(newField);\n setSortDirection(orderDirection);\n\n setCurrentPage(0);\n }\n },\n [columns],\n );\n\n if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <BasePage pageTitle=\"\" withContentPadding>\n <PageHeader\n totalCost={displayData.totalCost}\n month={displayData.month}\n endDate={displayData.endDate}\n currencyCode={displayData.currencyCode}\n customStyle={{ marginTop: '-24px' }}\n />\n\n <Divider\n style={{\n marginBottom: 24,\n marginLeft: '-24px',\n marginRight: '-24px',\n width: 'calc(100% + 48px)',\n }}\n />\n\n <PageLayout>\n <PageLayout.Filters>\n <Filters\n groupBy={groupBy}\n overheadDistribution={overheadDistribution}\n timeRange={timeRange}\n currency={currency}\n filterBy={filterBy}\n filterOperation={filterOperation}\n filterValue={filterValue}\n tags={tags}\n onGroupByChange={value => {\n setGroupBy(value);\n setCurrentPage(0);\n if (value !== 'tag') {\n setSelectedTag('');\n }\n // Reset showPlatformSum when groupBy changes away from 'project'\n if (value !== 'project') {\n setShowPlatformSum(false);\n }\n // Sync filterBy with groupBy and reset filter value\n setFilterBy(value);\n setFilterValue('');\n // Reset tag-related filter fields\n setSelectedTagKey('');\n setSelectedTagValue('');\n }}\n selectedTag={selectedTag}\n onSelectedTagChange={value => {\n setSelectedTag(value);\n setCurrentPage(0);\n }}\n onOverheadDistributionChange={value => {\n setOverheadDistribution(value);\n setCurrentPage(0);\n }}\n onTimeRangeChange={value => {\n setTimeRange(value);\n setCurrentPage(0);\n }}\n onCurrencyChange={value => {\n setCurrency(value);\n setCurrentPage(0);\n }}\n onFilterByChange={value => {\n setFilterBy(value);\n setCurrentPage(0);\n // Clear tag-related selections when filterBy changes away from 'tag'\n if (value !== 'tag') {\n setSelectedTagKey('');\n setSelectedTagValue('');\n }\n }}\n onFilterOperationChange={value => {\n setFilterOperation(value);\n setCurrentPage(0);\n }}\n onFilterValueChange={value => {\n setFilterValue(value);\n setCurrentPage(0);\n }}\n selectedTagKey={selectedTagKey}\n selectedTagValue={selectedTagValue}\n onSelectedTagKeyChange={value => {\n setSelectedTagKey(value);\n setSelectedTagValue('');\n setCurrentPage(0);\n }}\n onSelectedTagValueChange={value => {\n setSelectedTagValue(value);\n setCurrentPage(0);\n }}\n />\n </PageLayout.Filters>\n <PageLayout.Table>\n <div style={{ flex: 1 }}>\n <InfoCard>\n <Table<ProjectCost>\n data={displayData?.projects || []}\n isLoading={loading}\n components={{\n Toolbar: () => (\n <TableToolbar\n showPlatformSum={showPlatformSum}\n setShowPlatformSum={setShowPlatformSum}\n projectsCount={displayData?.projects?.length || 0}\n groupBy={groupBy}\n showMonthOverMonthChange={showMonthOverMonthChange}\n setShowMonthOverMonthChange={setShowMonthOverMonthChange}\n showInfrastructureCost={showInfrastructureCost}\n setShowInfrastructureCost={setShowInfrastructureCost}\n showSupplementaryCost={showSupplementaryCost}\n setShowSupplementaryCost={setShowSupplementaryCost}\n onDownloadCsv={() => handleHeaderDownload('csv')}\n onDownloadJson={() => handleHeaderDownload('json')}\n isDownloading={isDownloading}\n />\n ),\n }}\n columns={columns}\n options={{\n paging: true,\n pageSize: pageSize,\n pageSizeOptions: [5, 10, 25, 50],\n search: false,\n sorting: true,\n padding: 'dense',\n thirdSortClick: false,\n }}\n totalCount={totalCount}\n page={currentPage}\n onPageChange={handlePageChange}\n onRowsPerPageChange={handleRowsPerPageChange}\n onOrderChange={handleOrderChange}\n style={{ outline: 'none' }}\n localization={{\n pagination: {\n labelRowsPerPage: 'rows',\n },\n }}\n />\n </InfoCard>\n </div>\n </PageLayout.Table>\n </PageLayout>\n </BasePage>\n );\n}\nOpenShiftPage.displayName = 'OpenShiftPage';\n"],"names":["monthName","month","endDate"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OpenShiftPage.esm.js","sources":["../../../src/pages/openshift/OpenShiftPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useMemo, useState, useCallback, useRef } from 'react';\nimport type { ExportFormat } from '@red-hat-developer-hub/plugin-cost-management-common/clients';\nimport {\n Table,\n TableColumn,\n InfoCard,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport { BasePage } from '../../components/BasePage';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Filters } from './components/Filters';\nimport { Divider, useTheme } from '@material-ui/core';\nimport { PageHeader } from './components/PageHeader';\nimport { TableToolbar } from './components/TableToolbar';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { costManagementSlimApiRef } from '../../apis';\nimport { usePatternFlyTheme } from '../../hooks/usePatternFlyTheme';\nimport useAsync from 'react-use/lib/useAsync';\nimport { CURRENCY_SYMBOLS } from '../../constants/currencies';\nimport { DownloadIconButton } from './components/DownloadIconButton';\n\nconst formatCurrency = (value: number, currencyCode: string): string => {\n const symbol = CURRENCY_SYMBOLS[currencyCode] || currencyCode;\n return `${symbol}${value.toLocaleString('en-US', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}`;\n};\n\ninterface ProjectCost {\n id: string;\n projectName: string;\n clusterId?: string;\n cost: number;\n costPercentage: number;\n monthOverMonthChange: number;\n monthOverMonthValue: number;\n includesOverhead: boolean;\n previousPeriodCost: number;\n infrastructureCost: number;\n infrastructureCostPercentage: number;\n supplementaryCost: number;\n supplementaryCostPercentage: number;\n}\n\n/**\n * Generates date range text based on time range selection\n * @param timeRange - 'month-to-date' or 'previous-month'\n * @returns Formatted string like \"December 1-3\" or \"November 1-30\"\n */\nfunction getDateRangeText(timeRange: string): string {\n const now = new Date();\n const currentMonth = now.getMonth();\n const currentYear = now.getFullYear();\n const currentDay = now.getDate();\n\n if (timeRange === 'month-to-date') {\n // Current month: MONTH 1-<CURRENT_DAY>\n const monthName = now.toLocaleString('en-US', { month: 'long' });\n return `${monthName} 1-${currentDay}`;\n }\n // Previous month: PREVIOUS_MONTH 1-<LAST_DAY>\n const prevMonth = currentMonth === 0 ? 11 : currentMonth - 1;\n const prevYear = currentMonth === 0 ? currentYear - 1 : currentYear;\n const prevMonthDate = new Date(prevYear, prevMonth + 1, 0); // Last day of previous month\n const lastDay = prevMonthDate.getDate();\n const monthName = prevMonthDate.toLocaleString('en-US', { month: 'long' });\n return `${monthName} 1-${lastDay}`;\n}\n\n/**\n * Configuration for building query parameters\n */\ninterface QueryParamsConfig {\n groupBy: string;\n selectedTag: string;\n overheadDistribution: string;\n timeRange: string;\n currency: string;\n showPlatformSum: boolean;\n filterBy: string;\n filterValue: string;\n filterOperation: string;\n selectedTagKey: string;\n selectedTagValue: string;\n sortField: string | null;\n sortDirection: 'asc' | 'desc';\n}\n\n/**\n * Options for building query parameters\n */\ninterface BuildQueryParamsOptions {\n /** Pagination limit - omit for download (uses 0) */\n limit?: number;\n /** Pagination offset - omit for download */\n offset?: number;\n /** Specific item name to filter by (for row-level download) */\n specificItemName?: string;\n}\n\n/**\n * Builds query parameters for cost management API requests\n * Shared between data fetching and download functionality\n */\nfunction buildCostManagementQueryParams(\n config: QueryParamsConfig,\n options: BuildQueryParamsOptions = {},\n): Record<string, string | number> {\n const {\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n } = config;\n\n const { limit, offset, specificItemName } = options;\n\n // Build group by parameter\n const groupByParam =\n groupBy === 'tag' ? `group_by[tag:${selectedTag}]` : `group_by[${groupBy}]`;\n\n // Determine delta parameter\n const deltaParam =\n groupBy === 'project' && overheadDistribution === 'distribute'\n ? 'distributed_cost'\n : 'cost';\n\n const timeScopeValue = timeRange === 'month-to-date' ? -1 : -2;\n\n const queryParams: Record<string, string | number> = {\n currency,\n delta: deltaParam,\n 'filter[resolution]': 'monthly',\n 'filter[time_scope_units]': 'month',\n 'filter[time_scope_value]': timeScopeValue,\n };\n\n // Add pagination if provided\n if (limit !== undefined) {\n queryParams['filter[limit]'] = limit;\n }\n if (offset !== undefined) {\n queryParams['filter[offset]'] = offset;\n }\n\n // Add category parameter when showPlatformSum is enabled\n if (showPlatformSum) {\n queryParams.category = 'Platform';\n }\n\n queryParams[groupByParam] = '*';\n\n // Handle filtering\n if (specificItemName) {\n // Filter for specific item (row-level download)\n queryParams[`filter[${groupBy}]`] = specificItemName;\n } else if (filterBy === 'tag' && selectedTagKey && selectedTagValue) {\n // Tag filtering\n if (filterOperation === 'exact') {\n queryParams[`filter[exact:tag:${selectedTagKey}]`] = selectedTagValue;\n } else if (filterOperation === 'excludes') {\n queryParams[`exclude[tag:${selectedTagKey}]`] = selectedTagValue;\n } else {\n queryParams[`filter[tag:${selectedTagKey}]`] = selectedTagValue;\n }\n } else if (filterValue) {\n // Regular filtering\n if (filterOperation === 'exact') {\n queryParams[`filter[exact:${filterBy}]`] = filterValue;\n } else if (filterOperation === 'excludes') {\n queryParams[`exclude[${filterBy}]`] = filterValue;\n } else {\n queryParams[`filter[${filterBy}]`] = filterValue;\n }\n }\n\n // Add sorting\n let apiSortField: string;\n if (sortField) {\n if (sortField === 'cost') {\n apiSortField = deltaParam;\n } else if (sortField === 'projectName') {\n apiSortField = groupBy;\n } else {\n apiSortField = deltaParam;\n }\n queryParams[`order_by[${apiSortField}]`] = sortDirection;\n } else {\n queryParams[`order_by[${deltaParam}]`] = 'desc';\n }\n\n return queryParams;\n}\n\n/** @public */\nexport function OpenShiftPage() {\n usePatternFlyTheme();\n const api = useApi(costManagementSlimApiRef);\n const [groupBy, setGroupBy] = useState('project');\n const [overheadDistribution, setOverheadDistribution] =\n useState('distribute');\n const [timeRange, setTimeRange] = useState('month-to-date');\n const [currency, setCurrency] = useState('USD');\n const [filterBy, setFilterBy] = useState('project');\n const [filterOperation, setFilterOperation] = useState('includes');\n const [filterValue, setFilterValue] = useState('');\n const [showPlatformSum, setShowPlatformSum] = useState(false);\n const [selectedRows, setSelectedRows] = useState<Set<string>>(new Set());\n const [currentPage, setCurrentPage] = useState(0);\n const [pageSize, setPageSize] = useState(5);\n const [sortField, setSortField] = useState<string | null>(null);\n const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');\n const [tags, setTags] = useState<string[]>([]);\n const [selectedTag, setSelectedTag] = useState<string>('');\n const [selectedTagKey, setSelectedTagKey] = useState<string>('');\n const [selectedTagValue, setSelectedTagValue] = useState<string>('');\n const [showMonthOverMonthChange, setShowMonthOverMonthChange] =\n useState(true);\n const [showInfrastructureCost, setShowInfrastructureCost] = useState(false);\n const [showSupplementaryCost, setShowSupplementaryCost] = useState(false);\n const [isDownloading, setIsDownloading] = useState(false);\n const theme = useTheme();\n const isDarkMode = (theme.palette as any).mode === 'dark';\n\n // Ref to store display data for use in download handlers\n const displayDataRef = useRef<typeof displayData | null>(null);\n\n // Fetch tags on first load\n useAsync(async () => {\n try {\n const timeScopeValue = timeRange === 'month-to-date' ? -1 : -2;\n const response = await api.getOpenShiftTags(timeScopeValue);\n const tagsData = await response.json();\n setTags(tagsData.data || []);\n } catch {\n // Silently fail if tags can't be loaded\n setTags([]);\n }\n }, [api, timeRange]);\n\n // Build config object for query params builder (memoized to prevent unnecessary re-renders)\n const queryParamsConfig: QueryParamsConfig = useMemo(\n () => ({\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n }),\n [\n groupBy,\n selectedTag,\n overheadDistribution,\n timeRange,\n currency,\n showPlatformSum,\n filterBy,\n filterValue,\n filterOperation,\n selectedTagKey,\n selectedTagValue,\n sortField,\n sortDirection,\n ],\n );\n\n const {\n value: costData,\n loading,\n error,\n } = useAsync(async () => {\n // Don't make API call if groupBy is 'tag' but no tag is selected\n if (groupBy === 'tag' && !selectedTag) {\n return null;\n }\n\n const offset = currentPage * pageSize;\n const queryParams = buildCostManagementQueryParams(queryParamsConfig, {\n limit: pageSize,\n offset,\n });\n\n const response = await api.getCostManagementReport({\n query: queryParams,\n });\n return response.json();\n }, [\n currency,\n overheadDistribution,\n timeRange,\n groupBy,\n filterBy,\n filterValue,\n filterOperation,\n showPlatformSum,\n api,\n currentPage,\n pageSize,\n sortField,\n sortDirection,\n selectedTag,\n selectedTagKey,\n selectedTagValue,\n ]);\n\n const displayData = useMemo(() => {\n // If costData is null, return empty structure to keep table visible during loading\n if (!costData) {\n const today = new Date();\n const month =\n timeRange === 'previous-month'\n ? new Date(\n today.getFullYear(),\n today.getMonth() - 1,\n 1,\n ).toLocaleString('en-US', { month: 'long' })\n : today.toLocaleString('en-US', { month: 'long' });\n const endDate =\n timeRange === 'previous-month'\n ? new Date(today.getFullYear(), today.getMonth(), 0)\n .getDate()\n .toString()\n : today.getDate().toString();\n\n return {\n totalCost: 0,\n month,\n endDate,\n currencyCode: currency,\n projects: [],\n };\n }\n\n const arrayKey = `${groupBy}s` as keyof (typeof costData.data)[0];\n const groupedArray = costData.data?.[0]?.[arrayKey] as\n | Array<{ [key: string]: unknown; values: unknown[] }>\n | undefined;\n\n const projects =\n groupedArray?.map((item, index) => {\n const value =\n (item.values?.[0] as {\n cost?: {\n distributed?: { value?: number };\n total?: { value?: number };\n network_unattributed_distributed?: { value?: number };\n worker_unallocated_distributed?: { value?: number };\n platform_distributed?: { value?: number };\n storage_unattributed_distributed?: { value?: number };\n };\n infrastructure?: {\n total?: { value?: number };\n };\n supplementary?: {\n total?: { value?: number };\n };\n delta_percent?: number;\n delta_value?: number;\n }) || {};\n\n // For clusters, prefer values[0].clusters[0] (human-readable) over item.cluster (UUID)\n let itemName: string;\n let clusterId: string | undefined;\n if (groupBy === 'cluster') {\n const valueItem = item.values?.[0] as\n | { clusters?: string[]; cluster?: string }\n | undefined;\n const clustersArray = valueItem?.clusters;\n itemName =\n clustersArray && clustersArray.length > 0\n ? clustersArray[0]\n : (item.cluster as string) || 'Unknown';\n // Store the cluster UUID for display\n clusterId = (item.cluster as string) || undefined;\n } else {\n const nameField = groupBy as keyof typeof item;\n itemName = (item[nameField] as string) || 'Unknown';\n }\n\n const costField =\n groupBy === 'project' && overheadDistribution === 'distribute'\n ? 'distributed'\n : 'total';\n const costValue =\n value?.cost?.[costField as keyof typeof value.cost]?.value || 0;\n\n const deltaPercent = value?.delta_percent || 0;\n const deltaValue = value?.delta_value || 0;\n\n const infrastructureValue = value?.infrastructure?.total?.value || 0;\n const supplementaryValue = value?.supplementary?.total?.value || 0;\n\n return {\n id: `${index}`,\n projectName: itemName,\n clusterId,\n cost: costValue,\n costPercentage: 0,\n monthOverMonthChange: deltaPercent,\n monthOverMonthValue: Math.abs(deltaValue),\n includesOverhead:\n value?.cost?.network_unattributed_distributed?.value !== 0 ||\n value?.cost?.worker_unallocated_distributed?.value !== 0 ||\n value?.cost?.platform_distributed?.value !== 0 ||\n value?.cost?.storage_unattributed_distributed?.value !== 0,\n previousPeriodCost: costValue + Math.abs(deltaValue),\n infrastructureCost: infrastructureValue,\n infrastructureCostPercentage: 0,\n supplementaryCost: supplementaryValue,\n supplementaryCostPercentage: 0,\n };\n }) || [];\n\n const totalCost = costData.meta?.total?.cost?.total?.value || 0;\n const totalInfrastructureCost =\n costData.meta?.total?.infrastructure?.total?.value || 0;\n const totalSupplementaryCost =\n costData.meta?.total?.supplementary?.total?.value || 0;\n\n const currencyCode = costData.meta?.currency || currency;\n\n const projectsWithPercentage = projects.map(p => ({\n ...p,\n costPercentage: totalCost > 0 ? (p.cost / totalCost) * 100 : 0,\n infrastructureCostPercentage:\n totalInfrastructureCost > 0\n ? (p.infrastructureCost / totalInfrastructureCost) * 100\n : 0,\n supplementaryCostPercentage:\n totalSupplementaryCost > 0\n ? (p.supplementaryCost / totalSupplementaryCost) * 100\n : 0,\n }));\n\n let month: string;\n let endDate: string;\n\n if (timeRange === 'previous-month') {\n const today = new Date();\n const previousMonth = new Date(\n today.getFullYear(),\n today.getMonth() - 1,\n 1,\n );\n month = previousMonth.toLocaleString('en-US', { month: 'long' });\n const lastDayOfPreviousMonth = new Date(\n today.getFullYear(),\n today.getMonth(),\n 0,\n ).getDate();\n endDate = lastDayOfPreviousMonth.toString();\n } else {\n const today = new Date();\n month = today.toLocaleString('en-US', { month: 'long' });\n endDate = today.getDate().toString();\n }\n\n return {\n totalCost,\n month,\n endDate,\n currencyCode,\n projects: projectsWithPercentage,\n };\n }, [costData, currency, groupBy, overheadDistribution, timeRange]);\n\n // Update ref when displayData changes\n displayDataRef.current = displayData;\n\n /**\n * Builds query parameters for download request\n * @param specificItemName - Optional: specific item name to filter by (for row-level download)\n */\n const buildDownloadQueryParams = useCallback(\n (specificItemName?: string): Record<string, string | number> => {\n return buildCostManagementQueryParams(queryParamsConfig, {\n specificItemName,\n });\n },\n [queryParamsConfig],\n );\n\n /**\n * Handles download for header buttons (all data based on current filters)\n */\n const handleHeaderDownload = useCallback(\n async (format: ExportFormat) => {\n if (isDownloading) return;\n\n setIsDownloading(true);\n try {\n const queryParams = buildDownloadQueryParams();\n await api.downloadCostManagementReport({\n query: queryParams,\n format,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`Failed to download ${format}:`, err);\n } finally {\n setIsDownloading(false);\n }\n },\n [api, buildDownloadQueryParams, isDownloading],\n );\n\n /**\n * Handles download for row-level buttons (specific item)\n */\n const handleRowDownload = useCallback(\n async (itemName: string, format: ExportFormat) => {\n if (isDownloading) return;\n\n setIsDownloading(true);\n try {\n const queryParams = buildDownloadQueryParams(itemName);\n await api.downloadCostManagementReport({\n query: queryParams,\n format,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`Failed to download ${format} for ${itemName}:`, err);\n } finally {\n setIsDownloading(false);\n }\n },\n [api, buildDownloadQueryParams, isDownloading],\n );\n\n const handleRowSelect = useCallback(\n (rowId: string, isSelected: boolean) => {\n const newSelectedRows = new Set(selectedRows);\n if (isSelected) {\n newSelectedRows.add(rowId);\n } else {\n newSelectedRows.delete(rowId);\n }\n setSelectedRows(newSelectedRows);\n },\n [selectedRows],\n );\n\n const handleSelectAll = useCallback(\n (isSelected: boolean) => {\n if (isSelected && displayData) {\n setSelectedRows(\n new Set(displayData.projects.map(project => project.id)),\n );\n } else {\n setSelectedRows(new Set());\n }\n },\n [displayData],\n );\n\n const handlePageChange = useCallback((page: number, newPageSize: number) => {\n setCurrentPage(page);\n setPageSize(newPageSize);\n }, []);\n\n const handleRowsPerPageChange = useCallback((newPageSize: number) => {\n setPageSize(newPageSize);\n setCurrentPage(0);\n }, []);\n\n const totalCount = costData?.meta?.count || 0;\n\n const isAllSelected =\n displayData !== null &&\n selectedRows.size === displayData.projects.length &&\n displayData.projects.length > 0;\n const isIndeterminate =\n displayData !== null &&\n selectedRows.size > 0 &&\n selectedRows.size < displayData.projects.length;\n\n const columns = useMemo<TableColumn<ProjectCost>[]>(() => {\n const getChangeColor = (change: number) => {\n if (change < 0) return '#d32f2f';\n if (isDarkMode) return '#4BB543';\n return '#2e7d32';\n };\n\n const cols: TableColumn<ProjectCost>[] = [\n {\n title: (\n <div style={{ marginLeft: 0, paddingLeft: 0 }}>\n <input\n type=\"checkbox\"\n checked={isAllSelected}\n ref={input => {\n if (input) input.indeterminate = isIndeterminate;\n }}\n onChange={e => {\n e.stopPropagation();\n handleSelectAll(e.target.checked);\n }}\n style={{\n width: '18px',\n height: '18px',\n cursor: 'pointer',\n margin: 0,\n padding: 0,\n }}\n />\n </div>\n ),\n field: 'checkbox',\n sorting: false,\n width: '40px',\n cellStyle: {\n paddingLeft: '4px',\n paddingRight: '4px',\n },\n headerStyle: {\n paddingLeft: '4px',\n paddingRight: '4px',\n },\n render: data => (\n <div style={{ paddingRight: '4px' }}>\n <input\n type=\"checkbox\"\n checked={selectedRows.has(data.id)}\n onChange={e => handleRowSelect(data.id, e.target.checked)}\n style={{\n width: '18px',\n height: '18px',\n cursor: 'pointer',\n margin: 0,\n padding: 0,\n }}\n />\n </div>\n ),\n },\n {\n title: (\n <Typography variant=\"body2\" style={{ fontWeight: 'bold' }}>\n {groupBy.charAt(0).toLocaleUpperCase('en-US') + groupBy.slice(1)}{' '}\n name\n </Typography>\n ),\n field: 'projectName',\n cellStyle: { minWidth: 350 },\n headerStyle: { minWidth: 350 },\n render: data => (\n <div>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '8px',\n }}\n >\n <Typography variant=\"body2\">{data.projectName}</Typography>\n {groupBy === 'project' && data.includesOverhead && (\n <Typography\n variant=\"caption\"\n style={{\n padding: '2px 6px',\n backgroundColor: '#F5F5F5',\n border: '1px solid #D2D2D2',\n borderRadius: '16px',\n color: 'black',\n whiteSpace: 'nowrap',\n }}\n >\n Includes overhead\n </Typography>\n )}\n </div>\n {groupBy === 'cluster' && data.clusterId && (\n <Typography\n variant=\"caption\"\n style={{ color: '#666', display: 'block', marginTop: 10 }}\n >\n {data.clusterId}\n </Typography>\n )}\n </div>\n ),\n },\n ];\n\n if (showMonthOverMonthChange) {\n cols.push({\n title: 'Month over month change',\n field: 'monthOverMonthChange',\n sorting: false,\n render: data => (\n <div>\n <div\n style={{\n color: getChangeColor(data.monthOverMonthChange),\n }}\n >\n {Math.abs(data.monthOverMonthChange).toFixed(2)}%\n {data.monthOverMonthChange > 0 ? ' ▲' : ' ▼'}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {formatCurrency(\n data.monthOverMonthValue,\n displayData?.currencyCode || '',\n )}{' '}\n for {getDateRangeText(timeRange)}\n </div>\n </div>\n ),\n });\n }\n\n cols.push({\n title: 'Cost',\n field: 'cost',\n render: data => (\n <div>\n <div>\n {formatCurrency(data.cost, displayData?.currencyCode || '')}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.costPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n\n if (showInfrastructureCost) {\n cols.push({\n title: 'Infrastructure cost',\n field: 'infrastructureCost',\n render: data => (\n <div>\n <div>\n {formatCurrency(\n data.infrastructureCost,\n displayData?.currencyCode || '',\n )}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.infrastructureCostPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n }\n\n if (showSupplementaryCost) {\n cols.push({\n title: 'Supplementary cost',\n field: 'supplementaryCost',\n render: data => (\n <div>\n <div>\n {formatCurrency(\n data.supplementaryCost,\n displayData?.currencyCode || '',\n )}\n </div>\n <div style={{ fontSize: '0.75rem', color: '#666' }}>\n {data.supplementaryCostPercentage.toFixed(2)}% of cost\n </div>\n </div>\n ),\n });\n }\n\n cols.push({\n title: 'Actions',\n field: 'actions',\n sorting: false,\n render: data => (\n <div style={{ display: 'flex', gap: '8px' }}>\n <DownloadIconButton\n label=\"CSV\"\n variant={isDarkMode ? 'white' : 'black'}\n onClick={() => handleRowDownload(data.projectName, 'csv')}\n disabled={isDownloading}\n />\n <DownloadIconButton\n label=\"JSON\"\n variant={isDarkMode ? 'white' : 'black'}\n onClick={() => handleRowDownload(data.projectName, 'json')}\n disabled={isDownloading}\n />\n </div>\n ),\n });\n\n return cols;\n }, [\n handleRowSelect,\n handleRowDownload,\n isAllSelected,\n isIndeterminate,\n isDownloading,\n selectedRows,\n handleSelectAll,\n displayData?.currencyCode,\n groupBy,\n showMonthOverMonthChange,\n showInfrastructureCost,\n showSupplementaryCost,\n timeRange,\n isDarkMode,\n ]);\n\n const handleOrderChange = useCallback(\n (orderBy: number, orderDirection: 'asc' | 'desc') => {\n // If orderBy is -1, it means \"no sorting\" - ignore it to prevent removing sorting\n if (orderBy === -1) {\n return;\n }\n\n const column = columns[orderBy];\n if (\n column?.field &&\n column.field !== 'actions' &&\n column.sorting !== false\n ) {\n const newField = column.field as string;\n setSortField(newField);\n setSortDirection(orderDirection);\n\n setCurrentPage(0);\n }\n },\n [columns],\n );\n\n if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <BasePage pageTitle=\"\" withContentPadding>\n <PageHeader\n totalCost={displayData.totalCost}\n month={displayData.month}\n endDate={displayData.endDate}\n currencyCode={displayData.currencyCode}\n customStyle={{ marginTop: '-24px' }}\n />\n\n <Divider\n style={{\n marginBottom: 24,\n marginLeft: '-24px',\n marginRight: '-24px',\n width: 'calc(100% + 48px)',\n }}\n />\n\n <PageLayout>\n <PageLayout.Filters>\n <Filters\n groupBy={groupBy}\n overheadDistribution={overheadDistribution}\n timeRange={timeRange}\n currency={currency}\n filterBy={filterBy}\n filterOperation={filterOperation}\n filterValue={filterValue}\n tags={tags}\n onGroupByChange={value => {\n setGroupBy(value);\n setCurrentPage(0);\n if (value !== 'tag') {\n setSelectedTag('');\n }\n // Reset showPlatformSum when groupBy changes away from 'project'\n if (value !== 'project') {\n setShowPlatformSum(false);\n }\n // Sync filterBy with groupBy and reset filter value\n setFilterBy(value);\n setFilterValue('');\n // Reset tag-related filter fields\n setSelectedTagKey('');\n setSelectedTagValue('');\n }}\n selectedTag={selectedTag}\n onSelectedTagChange={value => {\n setSelectedTag(value);\n setCurrentPage(0);\n }}\n onOverheadDistributionChange={value => {\n setOverheadDistribution(value);\n setCurrentPage(0);\n }}\n onTimeRangeChange={value => {\n setTimeRange(value);\n setCurrentPage(0);\n }}\n onCurrencyChange={value => {\n setCurrency(value);\n setCurrentPage(0);\n }}\n onFilterByChange={value => {\n setFilterBy(value);\n setCurrentPage(0);\n // Clear tag-related selections when filterBy changes away from 'tag'\n if (value !== 'tag') {\n setSelectedTagKey('');\n setSelectedTagValue('');\n }\n }}\n onFilterOperationChange={value => {\n setFilterOperation(value);\n setCurrentPage(0);\n }}\n onFilterValueChange={value => {\n setFilterValue(value);\n setCurrentPage(0);\n }}\n selectedTagKey={selectedTagKey}\n selectedTagValue={selectedTagValue}\n onSelectedTagKeyChange={value => {\n setSelectedTagKey(value);\n setSelectedTagValue('');\n setCurrentPage(0);\n }}\n onSelectedTagValueChange={value => {\n setSelectedTagValue(value);\n setCurrentPage(0);\n }}\n />\n </PageLayout.Filters>\n <PageLayout.Table>\n <div style={{ flex: 1 }}>\n <InfoCard>\n <Table<ProjectCost>\n data={displayData?.projects || []}\n isLoading={loading}\n components={{\n Toolbar: () => (\n <TableToolbar\n showPlatformSum={showPlatformSum}\n setShowPlatformSum={setShowPlatformSum}\n projectsCount={displayData?.projects?.length || 0}\n groupBy={groupBy}\n showMonthOverMonthChange={showMonthOverMonthChange}\n setShowMonthOverMonthChange={setShowMonthOverMonthChange}\n showInfrastructureCost={showInfrastructureCost}\n setShowInfrastructureCost={setShowInfrastructureCost}\n showSupplementaryCost={showSupplementaryCost}\n setShowSupplementaryCost={setShowSupplementaryCost}\n onDownloadCsv={() => handleHeaderDownload('csv')}\n onDownloadJson={() => handleHeaderDownload('json')}\n isDownloading={isDownloading}\n />\n ),\n }}\n columns={columns}\n options={{\n paging: true,\n pageSize: pageSize,\n pageSizeOptions: [5, 10, 25, 50],\n search: false,\n sorting: true,\n padding: 'dense',\n thirdSortClick: false,\n }}\n totalCount={totalCount}\n page={currentPage}\n onPageChange={handlePageChange}\n onRowsPerPageChange={handleRowsPerPageChange}\n onOrderChange={handleOrderChange}\n style={{ outline: 'none' }}\n localization={{\n pagination: {\n labelRowsPerPage: 'rows',\n },\n }}\n />\n </InfoCard>\n </div>\n </PageLayout.Table>\n </PageLayout>\n </BasePage>\n );\n}\nOpenShiftPage.displayName = 'OpenShiftPage';\n"],"names":["monthName","month","endDate"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@red-hat-developer-hub/plugin-cost-management",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"backstage": {
|
|
5
5
|
"pluginId": "cost-management",
|
|
6
6
|
"pluginPackages": [
|
|
@@ -8,12 +8,17 @@
|
|
|
8
8
|
"@red-hat-developer-hub/plugin-cost-management-backend",
|
|
9
9
|
"@red-hat-developer-hub/plugin-cost-management-common"
|
|
10
10
|
],
|
|
11
|
-
"role": "frontend-plugin"
|
|
11
|
+
"role": "frontend-plugin",
|
|
12
|
+
"features": {
|
|
13
|
+
"./alpha": "@backstage/FrontendPlugin"
|
|
14
|
+
}
|
|
12
15
|
},
|
|
13
16
|
"configSchema": "config.schema.json",
|
|
14
17
|
"dependencies": {
|
|
15
18
|
"@backstage/core-components": "^0.18.13",
|
|
16
19
|
"@backstage/core-plugin-api": "^1.12.9",
|
|
20
|
+
"@backstage/frontend-plugin-api": "^0.18.0",
|
|
21
|
+
"@backstage/plugin-app-react": "^0.2.6",
|
|
17
22
|
"@backstage/plugin-permission-common": "^0.9.10",
|
|
18
23
|
"@backstage/plugin-permission-react": "^0.5.4",
|
|
19
24
|
"@backstage/theme": "^0.7.3",
|
|
@@ -23,7 +28,7 @@
|
|
|
23
28
|
"@material-ui/lab": "4.0.0-alpha.61",
|
|
24
29
|
"@patternfly/react-charts": "^8.3.0",
|
|
25
30
|
"@patternfly/react-tokens": "^6.1.0",
|
|
26
|
-
"@red-hat-developer-hub/plugin-cost-management-common": "^2.
|
|
31
|
+
"@red-hat-developer-hub/plugin-cost-management-common": "^2.4.0",
|
|
27
32
|
"date-fns": "^3.6.0",
|
|
28
33
|
"lodash": "^4.18.1",
|
|
29
34
|
"react-intl": "^6.6.8",
|
|
@@ -49,6 +54,8 @@
|
|
|
49
54
|
"@backstage/cli": "^0.36.5",
|
|
50
55
|
"@backstage/core-app-api": "^1.20.4",
|
|
51
56
|
"@backstage/dev-utils": "^1.1.26",
|
|
57
|
+
"@backstage/frontend-defaults": "^0.5.5",
|
|
58
|
+
"@backstage/frontend-test-utils": "^0.6.3",
|
|
52
59
|
"@backstage/plugin-search-react": "^1.11.7",
|
|
53
60
|
"@backstage/test-utils": "^1.7.21",
|
|
54
61
|
"@testing-library/dom": "^10.0.0",
|
|
@@ -66,6 +73,12 @@
|
|
|
66
73
|
"types": "./dist/index.d.ts",
|
|
67
74
|
"default": "./dist/index.esm.js"
|
|
68
75
|
},
|
|
76
|
+
"./alpha": {
|
|
77
|
+
"backstage": "@backstage/FrontendPlugin",
|
|
78
|
+
"import": "./dist/alpha.esm.js",
|
|
79
|
+
"types": "./dist/alpha.d.ts",
|
|
80
|
+
"default": "./dist/alpha.esm.js"
|
|
81
|
+
},
|
|
69
82
|
"./package.json": "./package.json"
|
|
70
83
|
},
|
|
71
84
|
"files": [
|
|
@@ -95,12 +108,16 @@
|
|
|
95
108
|
"postpack": "backstage-cli package postpack",
|
|
96
109
|
"prepack": "backstage-cli package prepack",
|
|
97
110
|
"start": "backstage-cli package start",
|
|
111
|
+
"start:legacy": "backstage-cli package start --entrypoint=dev/legacy.tsx",
|
|
98
112
|
"test": "backstage-cli package test"
|
|
99
113
|
},
|
|
100
114
|
"sideEffects": false,
|
|
101
115
|
"types": "./dist/index.d.ts",
|
|
102
116
|
"typesVersions": {
|
|
103
117
|
"*": {
|
|
118
|
+
"alpha": [
|
|
119
|
+
"dist/alpha.d.ts"
|
|
120
|
+
],
|
|
104
121
|
"package.json": [
|
|
105
122
|
"package.json"
|
|
106
123
|
]
|