From b746eca638094df49b3c84ab7af7398af6ae3ba1 Mon Sep 17 00:00:00 2001 From: kielosz Date: Wed, 3 Aug 2022 16:22:51 +0200 Subject: [PATCH] Make products optional Signed-off-by: kielosz --- .changeset/hot-crabs-wonder.md | 5 +++ plugins/cost-insights/README.md | 16 +++++-- plugins/cost-insights/config.d.ts | 2 +- .../CostInsightsPage/CostInsightsPage.tsx | 43 +++++++++++-------- plugins/cost-insights/src/hooks/useConfig.tsx | 30 +++++++------ plugins/cost-insights/src/utils/loading.ts | 1 - 6 files changed, 60 insertions(+), 37 deletions(-) create mode 100644 .changeset/hot-crabs-wonder.md diff --git a/.changeset/hot-crabs-wonder.md b/.changeset/hot-crabs-wonder.md new file mode 100644 index 0000000000..b39398bfc3 --- /dev/null +++ b/.changeset/hot-crabs-wonder.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +Make `products` field optional in the config diff --git a/plugins/cost-insights/README.md b/plugins/cost-insights/README.md index 824cf6f9fe..2b20da2f26 100644 --- a/plugins/cost-insights/README.md +++ b/plugins/cost-insights/README.md @@ -120,14 +120,24 @@ To expose the plugin to your users, you can integrate the `cost-insights` route ## Configuration -Cost Insights has only two required configuration fields: a map of cloud `products` for showing cost breakdowns and `engineerCost` - the average yearly cost of an engineer including benefits. Products must be defined as keys on the `products` field. +Cost Insights has only one required configuration field: `engineerCost` - the average yearly cost of an engineer including benefits. + +### Basic + +```yaml +## ./app-config.yaml +costInsights: + engineerCost: 200000 +``` + +### Products (Optional) + +For showing cost breakdowns you can define a map of cloud products. They must be defined as keys on the `products` field. A user-friendly name is **required**. You can optionally supply a product `icon` to display in Cost Insights navigation. See the [type file](https://github.com/backstage/backstage/blob/master/plugins/cost-insights/src/types/Icon.ts) for supported types and Material UI icon [mappings](https://github.com/backstage/backstage/blob/master/plugins/cost-insights/src/utils/navigation.tsx). **Note:** Product keys should be unique and camelCased. Backstage does not support underscores in configuration keys. -### Basic - ```yaml ## ./app-config.yaml costInsights: diff --git a/plugins/cost-insights/config.d.ts b/plugins/cost-insights/config.d.ts index 8438ca6561..4144b6d6a5 100644 --- a/plugins/cost-insights/config.d.ts +++ b/plugins/cost-insights/config.d.ts @@ -21,7 +21,7 @@ export interface Config { */ engineerCost: number; - products: { + products?: { [kind: string]: { /** * @visibility frontend diff --git a/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx b/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx index db5666768e..8fdfda936e 100644 --- a/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx +++ b/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx @@ -84,6 +84,7 @@ export const CostInsightsPage = () => { const accepted = useMemo(() => alerts.filter(isAlertAccepted), [alerts]); const dismissed = useMemo(() => alerts.filter(isAlertDismissed), [alerts]); + const isProductsDisplayed = !!config.products?.length; const isActionItemsDisplayed = !!active.length; const isAlertInsightsDisplayed = !!alerts.length; @@ -247,14 +248,16 @@ export const CostInsightsPage = () => { return ( - - - - - + {(isProductsDisplayed || isActionItemsDisplayed) && ( + + + + + + )} { - {!isAlertInsightsDisplayed && } - - - - - + {!isAlertInsightsDisplayed && isProductsDisplayed && } + {isProductsDisplayed && ( + + + + + + )} diff --git a/plugins/cost-insights/src/hooks/useConfig.tsx b/plugins/cost-insights/src/hooks/useConfig.tsx index 451a48b71f..236c142b3b 100644 --- a/plugins/cost-insights/src/hooks/useConfig.tsx +++ b/plugins/cost-insights/src/hooks/useConfig.tsx @@ -85,12 +85,15 @@ export const ConfigProvider = ({ children }: PropsWithChildren<{}>) => { useEffect(() => { function getProducts(): Product[] { - const products = c.getConfig('costInsights.products'); - return products.keys().map(key => ({ - kind: key, - name: products.getString(`${key}.name`), - aggregation: [0, 0], - })); + const products = c.getOptionalConfig('costInsights.products'); + if (products) { + return products.keys().map(key => ({ + kind: key, + name: products.getString(`${key}.name`), + aggregation: [0, 0], + })); + } + return []; } function getMetrics(): Metric[] { @@ -122,13 +125,14 @@ export const ConfigProvider = ({ children }: PropsWithChildren<{}>) => { } function getIcons(): Icon[] { - const products = c.getConfig('costInsights.products'); - const keys = products.keys(); - - return keys.map(k => ({ - kind: k, - component: getIcon(products.getOptionalString(`${k}.icon`)), - })); + const products = c.getOptionalConfig('costInsights.products'); + if (products) { + return products.keys().map(k => ({ + kind: k, + component: getIcon(products.getOptionalString(`${k}.icon`)), + })); + } + return []; } function getEngineerCost(): number { diff --git a/plugins/cost-insights/src/utils/loading.ts b/plugins/cost-insights/src/utils/loading.ts index 2a453a58f1..ce02644265 100644 --- a/plugins/cost-insights/src/utils/loading.ts +++ b/plugins/cost-insights/src/utils/loading.ts @@ -35,7 +35,6 @@ export enum DefaultLoadingAction { export const INITIAL_LOADING_ACTIONS = [ DefaultLoadingAction.UserGroups, DefaultLoadingAction.CostInsightsInitial, - DefaultLoadingAction.CostInsightsProducts, ]; export const getDefaultState = (loadingActions: string[]): Loading => {