@electrolux-oss/plugin-infrawallet 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/api/InfraWalletApiClient.esm.js +4 -2
  2. package/dist/api/InfraWalletApiClient.esm.js.map +1 -1
  3. package/dist/api/functions.esm.js +15 -3
  4. package/dist/api/functions.esm.js.map +1 -1
  5. package/dist/components/ColumnsChartComponent/ColumnsChartComponent.esm.js +142 -173
  6. package/dist/components/ColumnsChartComponent/ColumnsChartComponent.esm.js.map +1 -1
  7. package/dist/components/CostReportsTableComponent/CostReportsTableComponent.esm.js +147 -91
  8. package/dist/components/CostReportsTableComponent/CostReportsTableComponent.esm.js.map +1 -1
  9. package/dist/components/EntityInfraWalletCard/EntityInfraWalletCard.esm.js +254 -0
  10. package/dist/components/EntityInfraWalletCard/EntityInfraWalletCard.esm.js.map +1 -0
  11. package/dist/components/EntityInfraWalletCard/index.esm.js +2 -0
  12. package/dist/components/EntityInfraWalletCard/index.esm.js.map +1 -0
  13. package/dist/components/ErrorsAlertComponent/ErrorsAlertComponent.esm.js +4 -4
  14. package/dist/components/ErrorsAlertComponent/ErrorsAlertComponent.esm.js.map +1 -1
  15. package/dist/components/FiltersComponent/FiltersComponent.esm.js +27 -27
  16. package/dist/components/FiltersComponent/FiltersComponent.esm.js.map +1 -1
  17. package/dist/components/InfraWalletAppData.esm.js +9 -0
  18. package/dist/components/InfraWalletAppData.esm.js.map +1 -0
  19. package/dist/components/MetricConfigurationComponent/MetricConfigurationComponent.esm.js +22 -10
  20. package/dist/components/MetricConfigurationComponent/MetricConfigurationComponent.esm.js.map +1 -1
  21. package/dist/components/PieChartComponent/PieChartComponent.esm.js +63 -59
  22. package/dist/components/PieChartComponent/PieChartComponent.esm.js.map +1 -1
  23. package/dist/components/ProviderIcons/ProviderIcons.esm.js +8 -8
  24. package/dist/components/ProviderIcons/ProviderIcons.esm.js.map +1 -1
  25. package/dist/components/ReportsComponent/ReportsComponent.esm.js +24 -20
  26. package/dist/components/ReportsComponent/ReportsComponent.esm.js.map +1 -1
  27. package/dist/components/SettingsComponent/SettingsComponent.esm.js +4 -4
  28. package/dist/components/SettingsComponent/SettingsComponent.esm.js.map +1 -1
  29. package/dist/components/index.esm.js +36 -0
  30. package/dist/components/index.esm.js.map +1 -0
  31. package/dist/index.d.ts +5 -1
  32. package/dist/index.esm.js +2 -1
  33. package/dist/index.esm.js.map +1 -1
  34. package/dist/plugin.esm.js +10 -2
  35. package/dist/plugin.esm.js.map +1 -1
  36. package/package.json +9 -11
@@ -38,7 +38,7 @@ class InfraWalletApiClient {
38
38
  }
39
39
  async getCostReports(filters, tags, groups, granularity, startTime, endTime) {
40
40
  const tagsString = tagsToString(tags);
41
- const url = `api/infrawallet/reports?&filters=${filters}&tags=${tagsString}&groups=${groups}&granularity=${granularity}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;
41
+ const url = `api/infrawallet/reports?granularity=${granularity}&groups=${groups}&filters=${filters}&tags=${tagsString}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;
42
42
  return await this.request(url);
43
43
  }
44
44
  async getTagKeys(provider, startTime, endTime) {
@@ -46,7 +46,9 @@ class InfraWalletApiClient {
46
46
  return await this.request(url);
47
47
  }
48
48
  async getTagValues(tag, startTime, endTime) {
49
- const url = `api/infrawallet/tag-values?provider=${tag.provider}&tag=${tag.key}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;
49
+ const provider = tag.provider;
50
+ const tagKey = tag.key;
51
+ const url = `api/infrawallet/tag-values?provider=${provider}&tag=${tagKey}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;
50
52
  return await this.request(url);
51
53
  }
52
54
  async getWalletByName(walletName) {
@@ -1 +1 @@
1
- {"version":3,"file":"InfraWalletApiClient.esm.js","sources":["../../src/api/InfraWalletApiClient.ts"],"sourcesContent":["import { ConfigApi, IdentityApi } from '@backstage/core-plugin-api';\nimport fetch from 'node-fetch';\nimport { InfraWalletApi } from './InfraWalletApi';\nimport {\n CostReportsResponse,\n GetWalletResponse,\n MetricConfigsResponse,\n MetricSetting,\n MetricsResponse,\n MetricsSettingResponse,\n Tag,\n TagResponse,\n} from './types';\nimport { tagsToString } from './functions';\n\n/** @public */\nexport class InfraWalletApiClient implements InfraWalletApi {\n private readonly identityApi: IdentityApi;\n private readonly backendUrl: string;\n\n constructor(options: { identityApi: IdentityApi; configApi: ConfigApi }) {\n this.identityApi = options.identityApi;\n this.backendUrl = options.configApi.getString('backend.baseUrl');\n }\n\n async request(path: string, method?: string, payload?: Record<string, string | undefined>) {\n const url = `${this.backendUrl}/${path}`;\n const { token: idToken } = await this.identityApi.getCredentials();\n const headers: Record<string, string> = idToken ? { Authorization: `Bearer ${idToken}` } : {};\n\n if (method !== undefined && method !== 'GET') {\n headers['Content-Type'] = 'application/json';\n }\n\n const request: any = {\n headers: headers,\n method: method ?? 'GET',\n };\n\n if (payload) {\n request.body = JSON.stringify(payload);\n }\n\n const response = await fetch(url, request);\n\n if (!response.ok) {\n const res = await response.text();\n const message = `Request failed with ${response.status} ${response.statusText}, ${res}`;\n throw new Error(message);\n }\n\n return await response.json();\n }\n\n async getCostReports(\n filters: string,\n tags: Tag[],\n groups: string,\n granularity: string,\n startTime: Date,\n endTime: Date,\n ): Promise<CostReportsResponse> {\n const tagsString = tagsToString(tags);\n const url = `api/infrawallet/reports?&filters=${filters}&tags=${tagsString}&groups=${groups}&granularity=${granularity}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getTagKeys(provider: string, startTime: Date, endTime: Date): Promise<TagResponse> {\n const url = `api/infrawallet/tag-keys?provider=${provider}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getTagValues(tag: Tag, startTime: Date, endTime: Date): Promise<TagResponse> {\n const url = `api/infrawallet/tag-values?provider=${tag.provider}&tag=${\n tag.key\n }&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getWalletByName(walletName: string): Promise<GetWalletResponse> {\n const url = `api/infrawallet/${walletName}`;\n return await this.request(url);\n }\n\n async getMetrics(walletName: string, granularity: string, startTime: Date, endTime: Date): Promise<MetricsResponse> {\n const url = `api/infrawallet/${walletName}/metrics?&granularity=${granularity}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getMetricConfigs(): Promise<MetricConfigsResponse> {\n const url = 'api/infrawallet/metric/metric_configs';\n return await this.request(url);\n }\n\n async getWalletMetricsSetting(walletName: string): Promise<MetricsSettingResponse> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url);\n }\n async updateWalletMetricSetting(\n walletName: string,\n metricSetting: MetricSetting,\n ): Promise<{ updated: boolean; status: number }> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url, 'PUT', metricSetting);\n }\n\n async deleteWalletMetricSetting(\n walletName: string,\n metricSetting: MetricSetting,\n ): Promise<{ deleted: boolean; status: number }> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url, 'DELETE', metricSetting);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InfraWalletApiClient.esm.js","sources":["../../src/api/InfraWalletApiClient.ts"],"sourcesContent":["import { ConfigApi, IdentityApi } from '@backstage/core-plugin-api';\nimport fetch from 'node-fetch';\nimport { InfraWalletApi } from './InfraWalletApi';\nimport {\n CostReportsResponse,\n GetWalletResponse,\n MetricConfigsResponse,\n MetricSetting,\n MetricsResponse,\n MetricsSettingResponse,\n Tag,\n TagResponse,\n} from './types';\nimport { tagsToString } from './functions';\n\n/** @public */\nexport class InfraWalletApiClient implements InfraWalletApi {\n private readonly identityApi: IdentityApi;\n private readonly backendUrl: string;\n\n constructor(options: { identityApi: IdentityApi; configApi: ConfigApi }) {\n this.identityApi = options.identityApi;\n this.backendUrl = options.configApi.getString('backend.baseUrl');\n }\n\n async request(path: string, method?: string, payload?: Record<string, string | undefined>) {\n const url = `${this.backendUrl}/${path}`;\n const { token: idToken } = await this.identityApi.getCredentials();\n const headers: Record<string, string> = idToken ? { Authorization: `Bearer ${idToken}` } : {};\n\n if (method !== undefined && method !== 'GET') {\n headers['Content-Type'] = 'application/json';\n }\n\n const request: any = {\n headers: headers,\n method: method ?? 'GET',\n };\n\n if (payload) {\n request.body = JSON.stringify(payload);\n }\n\n const response = await fetch(url, request);\n\n if (!response.ok) {\n const res = await response.text();\n const message = `Request failed with ${response.status} ${response.statusText}, ${res}`;\n throw new Error(message);\n }\n\n return await response.json();\n }\n\n async getCostReports(\n filters: string,\n tags: Tag[],\n groups: string,\n granularity: string,\n startTime: Date,\n endTime: Date,\n ): Promise<CostReportsResponse> {\n const tagsString = tagsToString(tags);\n const url = `api/infrawallet/reports?granularity=${granularity}&groups=${groups}&filters=${filters}&tags=${tagsString}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n\n return await this.request(url);\n }\n async getTagKeys(provider: string, startTime: Date, endTime: Date): Promise<TagResponse> {\n const url = `api/infrawallet/tag-keys?provider=${provider}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getTagValues(tag: Tag, startTime: Date, endTime: Date): Promise<TagResponse> {\n const provider = tag.provider;\n const tagKey = tag.key;\n const url = `api/infrawallet/tag-values?provider=${provider}&tag=${tagKey}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getWalletByName(walletName: string): Promise<GetWalletResponse> {\n const url = `api/infrawallet/${walletName}`;\n return await this.request(url);\n }\n\n async getMetrics(walletName: string, granularity: string, startTime: Date, endTime: Date): Promise<MetricsResponse> {\n const url = `api/infrawallet/${walletName}/metrics?&granularity=${granularity}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getMetricConfigs(): Promise<MetricConfigsResponse> {\n const url = 'api/infrawallet/metric/metric_configs';\n return await this.request(url);\n }\n\n async getWalletMetricsSetting(walletName: string): Promise<MetricsSettingResponse> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url);\n }\n async updateWalletMetricSetting(\n walletName: string,\n metricSetting: MetricSetting,\n ): Promise<{ updated: boolean; status: number }> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url, 'PUT', metricSetting);\n }\n\n async deleteWalletMetricSetting(\n walletName: string,\n metricSetting: MetricSetting,\n ): Promise<{ deleted: boolean; status: number }> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url, 'DELETE', metricSetting);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { parse, subMonths, format } from 'date-fns';
1
+ import { parse, subMonths, format, subDays } from 'date-fns';
2
2
  import { reduce } from 'lodash';
3
3
  import moment from 'moment';
4
4
 
@@ -16,7 +16,7 @@ const mergeCostReports = (reports, threshold) => {
16
16
  const mergedReports = reduce(
17
17
  reports,
18
18
  (accumulator, report) => {
19
- let keyName = "others";
19
+ let keyName = "Others";
20
20
  if (idsToBeKept.includes(report.id)) {
21
21
  keyName = report.id;
22
22
  }
@@ -149,6 +149,11 @@ const getPreviousMonth = (month) => {
149
149
  const previousMonth = subMonths(date, 1);
150
150
  return format(previousMonth, "yyyy-MM");
151
151
  };
152
+ const getPreviousDay = (day) => {
153
+ const date = parse(day, "yyyy-MM-dd", /* @__PURE__ */ new Date());
154
+ const previousDay = subDays(date, 1);
155
+ return format(previousDay, "yyyy-MM-dd");
156
+ };
152
157
  const getPeriodStrings = (granularity, startTime, endTime) => {
153
158
  const result = [];
154
159
  const current = moment(startTime);
@@ -163,6 +168,13 @@ const getPeriodStrings = (granularity, startTime, endTime) => {
163
168
  }
164
169
  return result;
165
170
  };
171
+ const formatCurrency = (number, currency) => {
172
+ return new Intl.NumberFormat("en-US", {
173
+ style: "currency",
174
+ currency: "USD",
175
+ notation: "compact"
176
+ }).format(number);
177
+ };
166
178
 
167
- export { aggregateCostReports, extractAccountInfo, extractProvider, filterCostReports, getAllReportTags, getPeriodStrings, getPreviousMonth, getReportKeyAndValues, mergeCostReports, tagExists, tagsToString };
179
+ export { aggregateCostReports, extractAccountInfo, extractProvider, filterCostReports, formatCurrency, getAllReportTags, getPeriodStrings, getPreviousDay, getPreviousMonth, getReportKeyAndValues, mergeCostReports, tagExists, tagsToString };
168
180
  //# sourceMappingURL=functions.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"functions.esm.js","sources":["../../src/api/functions.ts"],"sourcesContent":["import { format, parse, subMonths } from 'date-fns';\nimport { reduce } from 'lodash';\nimport moment from 'moment';\nimport { Report, Filters, Tag } from './types';\n\nexport const mergeCostReports = (reports: Report[], threshold: number): Report[] => {\n const totalCosts: { id: string; total: number }[] = [];\n reports.forEach(report => {\n let total = 0;\n Object.values(report.reports).forEach(v => {\n total += v as number;\n });\n totalCosts.push({ id: report.id, total: total });\n });\n const sortedTotalCosts = totalCosts.sort((a, b) => b.total - a.total);\n const idsToBeKept = sortedTotalCosts.slice(0, threshold).map(v => v.id);\n\n const mergedReports = reduce(\n reports,\n (accumulator: { [key: string]: Report }, report) => {\n let keyName = 'others';\n if (idsToBeKept.includes(report.id)) {\n keyName = report.id;\n }\n if (!accumulator[keyName]) {\n accumulator[keyName] = {\n id: keyName,\n reports: {},\n };\n }\n\n Object.keys(report.reports).forEach(key => {\n if (accumulator[keyName].reports[key]) {\n accumulator[keyName].reports[key] += report.reports[key];\n } else {\n accumulator[keyName].reports[key] = report.reports[key];\n }\n });\n return accumulator;\n },\n {},\n );\n\n return Object.values(mergedReports);\n};\n\nexport const filterCostReports = (reports: Report[], filters: Filters): Report[] => {\n const filteredReports = reports.filter(report => {\n let match = true;\n Object.keys(filters).forEach(key => {\n if (filters[key].length > 0 && !filters[key].includes(report[key] as string)) {\n match = false;\n }\n });\n return match;\n });\n\n return filteredReports;\n};\n\nexport const aggregateCostReports = (reports: Report[], aggregatedBy?: string): Report[] => {\n const aggregatedReports: { [key: string]: Report } = reduce(\n reports,\n (accumulator, report) => {\n let keyName: string = 'no value';\n if (aggregatedBy && aggregatedBy in report) {\n keyName = report[aggregatedBy] as string;\n } else if (aggregatedBy === 'none') {\n keyName = 'Total';\n }\n\n if (!accumulator[keyName]) {\n accumulator[keyName] = {\n id: keyName,\n provider: report.provider,\n reports: {},\n } as {\n id: string;\n reports: { [key: string]: number };\n [key: string]: any;\n };\n\n if (aggregatedBy !== undefined) {\n accumulator[keyName][aggregatedBy] = keyName;\n }\n }\n\n Object.keys(report.reports).forEach(key => {\n if (accumulator[keyName].reports[key]) {\n accumulator[keyName].reports[key] += report.reports[key];\n } else {\n accumulator[keyName].reports[key] = report.reports[key];\n }\n });\n return accumulator;\n },\n {} as { [key: string]: Report },\n );\n return Object.values(aggregatedReports);\n};\n\nexport const getReportKeyAndValues = (reports: Report[]): { [key: string]: string[] } => {\n const excludedKeys = ['id', 'reports'];\n const keyValueSets: { [key: string]: Set<string> } = {};\n reports.forEach(report => {\n Object.keys(report).forEach(key => {\n if (!excludedKeys.includes(key)) {\n if (keyValueSets[key] === undefined) {\n keyValueSets[key] = new Set<string>();\n }\n\n keyValueSets[key].add(report[key] as string);\n }\n });\n });\n\n const keyValues: { [key: string]: string[] } = {};\n Object.keys(keyValueSets).forEach((key: string) => {\n keyValues[key] = Array.from(keyValueSets[key]);\n });\n return keyValues;\n};\n\nexport const extractProvider = (input: string): string | undefined => {\n let provider = undefined;\n if (input && input.indexOf('/') !== -1) {\n provider = input.split('/')[0];\n }\n\n return provider;\n};\n\nexport const extractAccountInfo = (input: string): { accountName: string; accountId?: string } => {\n // try to match format: accountName (accountId), e.g. aws-dev (123456789012)\n const regex = /^(.*?)\\s*\\(([^)]+)\\)$/;\n const match = input.match(regex);\n\n if (match) {\n const accountName = match[1];\n const accountId = match[2];\n return { accountName: accountName, accountId: accountId };\n }\n\n return { accountName: input };\n};\n\n// check if targetTag exists in tags\nexport function tagExists(tags: Tag[], targetTag: Tag): boolean {\n return tags.some(\n tag => tag.provider === targetTag.provider && tag.key === targetTag.key && tag.value === targetTag.value,\n );\n}\n\n// convert Tag array to (provider1:key1=value1 OR provider2:key2=value2) format\nexport const tagsToString = (tags: Tag[]): string => {\n if (tags.length === 0) {\n return '()';\n }\n\n const keyValuePairs = tags.map(tag => `${tag.provider}:${tag.key}=${tag.value}`);\n return `(${keyValuePairs.join(' OR ')})`;\n};\n\nexport const getAllReportTags = (reports: Report[]): string[] => {\n const tags = new Set<string>();\n const reservedKeys = ['id', 'account', 'service', 'category', 'provider', 'reports'];\n reports.forEach(report => {\n Object.keys(report).forEach(key => {\n if (reservedKeys.indexOf(key) === -1) {\n tags.add(key);\n }\n });\n });\n return Array.from(tags);\n};\n\nexport const getPreviousMonth = (month: string): string => {\n const date = parse(month, 'yyyy-MM', new Date());\n const previousMonth = subMonths(date, 1);\n return format(previousMonth, 'yyyy-MM');\n};\n\nexport const getPeriodStrings = (granularity: string, startTime: Date, endTime: Date): string[] => {\n const result: string[] = [];\n const current = moment(startTime);\n\n while (current.isSameOrBefore(endTime) && current.isSameOrBefore(moment())) {\n if (granularity === 'monthly') {\n result.push(current.format('YYYY-MM'));\n current.add(1, 'months');\n } else {\n result.push(current.format('YYYY-MM-DD'));\n current.add(1, 'days');\n }\n }\n\n return result;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"functions.esm.js","sources":["../../src/api/functions.ts"],"sourcesContent":["import { format, parse, subDays, subMonths } from 'date-fns';\nimport { reduce } from 'lodash';\nimport moment from 'moment';\nimport { Filters, Report, Tag } from './types';\n\nexport const mergeCostReports = (reports: Report[], threshold: number): Report[] => {\n const totalCosts: { id: string; total: number }[] = [];\n reports.forEach(report => {\n let total = 0;\n Object.values(report.reports).forEach(v => {\n total += v as number;\n });\n totalCosts.push({ id: report.id, total: total });\n });\n const sortedTotalCosts = totalCosts.sort((a, b) => b.total - a.total);\n const idsToBeKept = sortedTotalCosts.slice(0, threshold).map(v => v.id);\n\n const mergedReports = reduce(\n reports,\n (accumulator: { [key: string]: Report }, report) => {\n let keyName = 'Others';\n if (idsToBeKept.includes(report.id)) {\n keyName = report.id;\n }\n if (!accumulator[keyName]) {\n accumulator[keyName] = {\n id: keyName,\n reports: {},\n };\n }\n\n Object.keys(report.reports).forEach(key => {\n if (accumulator[keyName].reports[key]) {\n accumulator[keyName].reports[key] += report.reports[key];\n } else {\n accumulator[keyName].reports[key] = report.reports[key];\n }\n });\n return accumulator;\n },\n {},\n );\n\n return Object.values(mergedReports);\n};\n\nexport const filterCostReports = (reports: Report[], filters: Filters): Report[] => {\n const filteredReports = reports.filter(report => {\n let match = true;\n Object.keys(filters).forEach(key => {\n if (filters[key].length > 0 && !filters[key].includes(report[key] as string)) {\n match = false;\n }\n });\n return match;\n });\n\n return filteredReports;\n};\n\nexport const aggregateCostReports = (reports: Report[], aggregatedBy?: string): Report[] => {\n const aggregatedReports: { [key: string]: Report } = reduce(\n reports,\n (accumulator, report) => {\n let keyName: string = 'no value';\n if (aggregatedBy && aggregatedBy in report) {\n keyName = report[aggregatedBy] as string;\n } else if (aggregatedBy === 'none') {\n keyName = 'Total';\n }\n\n if (!accumulator[keyName]) {\n accumulator[keyName] = {\n id: keyName,\n provider: report.provider,\n reports: {},\n } as {\n id: string;\n reports: { [key: string]: number };\n [key: string]: any;\n };\n\n if (aggregatedBy !== undefined) {\n accumulator[keyName][aggregatedBy] = keyName;\n }\n }\n\n Object.keys(report.reports).forEach(key => {\n if (accumulator[keyName].reports[key]) {\n accumulator[keyName].reports[key] += report.reports[key];\n } else {\n accumulator[keyName].reports[key] = report.reports[key];\n }\n });\n return accumulator;\n },\n {} as { [key: string]: Report },\n );\n return Object.values(aggregatedReports);\n};\n\nexport const getReportKeyAndValues = (reports: Report[]): { [key: string]: string[] } => {\n const excludedKeys = ['id', 'reports'];\n const keyValueSets: { [key: string]: Set<string> } = {};\n reports.forEach(report => {\n Object.keys(report).forEach(key => {\n if (!excludedKeys.includes(key)) {\n if (keyValueSets[key] === undefined) {\n keyValueSets[key] = new Set<string>();\n }\n\n keyValueSets[key].add(report[key] as string);\n }\n });\n });\n\n const keyValues: { [key: string]: string[] } = {};\n Object.keys(keyValueSets).forEach((key: string) => {\n keyValues[key] = Array.from(keyValueSets[key]);\n });\n return keyValues;\n};\n\nexport const extractProvider = (input: string): string | undefined => {\n let provider = undefined;\n if (input && input.indexOf('/') !== -1) {\n provider = input.split('/')[0];\n }\n\n return provider;\n};\n\nexport const extractAccountInfo = (input: string): { accountName: string; accountId?: string } => {\n // try to match format: accountName (accountId), e.g. aws-dev (123456789012)\n const regex = /^(.*?)\\s*\\(([^)]+)\\)$/;\n const match = input.match(regex);\n\n if (match) {\n const accountName = match[1];\n const accountId = match[2];\n return { accountName: accountName, accountId: accountId };\n }\n\n return { accountName: input };\n};\n\n// check if targetTag exists in tags\nexport function tagExists(tags: Tag[], targetTag: Tag): boolean {\n return tags.some(\n tag => tag.provider === targetTag.provider && tag.key === targetTag.key && tag.value === targetTag.value,\n );\n}\n\n// convert Tag array to (provider1:key1=value1 OR provider2:key2=value2) format\nexport const tagsToString = (tags: Tag[]): string => {\n if (tags.length === 0) {\n return '()';\n }\n\n const keyValuePairs = tags.map(tag => `${tag.provider}:${tag.key}=${tag.value}`);\n return `(${keyValuePairs.join(' OR ')})`;\n};\n\nexport const getAllReportTags = (reports: Report[]): string[] => {\n const tags = new Set<string>();\n const reservedKeys = ['id', 'account', 'service', 'category', 'provider', 'reports'];\n reports.forEach(report => {\n Object.keys(report).forEach(key => {\n if (reservedKeys.indexOf(key) === -1) {\n tags.add(key);\n }\n });\n });\n return Array.from(tags);\n};\n\nexport const getPreviousMonth = (month: string): string => {\n const date = parse(month, 'yyyy-MM', new Date());\n const previousMonth = subMonths(date, 1);\n return format(previousMonth, 'yyyy-MM');\n};\n\nexport const getPreviousDay = (day: string): string => {\n const date = parse(day, 'yyyy-MM-dd', new Date());\n const previousDay = subDays(date, 1);\n return format(previousDay, 'yyyy-MM-dd');\n};\n\nexport const getPeriodStrings = (granularity: string, startTime: Date, endTime: Date): string[] => {\n const result: string[] = [];\n const current = moment(startTime);\n\n while (current.isSameOrBefore(endTime) && current.isSameOrBefore(moment())) {\n if (granularity === 'monthly') {\n result.push(current.format('YYYY-MM'));\n current.add(1, 'months');\n } else {\n result.push(current.format('YYYY-MM-DD'));\n current.add(1, 'days');\n }\n }\n\n return result;\n};\n\nexport const formatCurrency = (number: number, currency?: string): string => {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: currency || 'USD',\n notation: 'compact',\n }).format(number);\n};\n"],"names":[],"mappings":"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"}
@@ -1,196 +1,165 @@
1
- import { Paper, Grid, Switch } from '@material-ui/core';
2
- import { useTheme, makeStyles } from '@material-ui/core/styles';
3
- import humanFormat from 'human-format';
1
+ import { Grid, Switch } from '@material-ui/core';
2
+ import Paper from '@mui/material/Paper';
3
+ import Skeleton from '@mui/material/Skeleton';
4
+ import { ResponsiveChartContainer, ChartsGrid, BarPlot, LinePlot, LineHighlightPlot, MarkPlot, ChartsXAxis, ChartsYAxis, ChartsTooltip, ChartsLegend, DefaultChartsLegend } from '@mui/x-charts';
4
5
  import React, { useState, useCallback, useEffect } from 'react';
5
- import Chart from 'react-apexcharts';
6
+ import { formatCurrency } from '../../api/functions.esm.js';
6
7
  import { colorList } from '../constants.esm.js';
7
8
 
8
9
  const ColumnsChartComponent = ({
10
+ granularity,
9
11
  granularitySetter,
10
12
  categories,
11
- series,
13
+ costs,
12
14
  metrics,
13
15
  height,
14
- thumbnail,
15
- dataPointSelectionHandler
16
+ highlightedItem,
17
+ highlightedItemSetter
16
18
  }) => {
17
- const defaultTheme = useTheme();
18
- const useStyles = makeStyles({
19
- fixedHeightPaper: {
20
- padding: "16px",
21
- display: "flex",
22
- flexDirection: "column",
23
- height: height ? height : 300
24
- },
25
- thumbnailPaper: {
26
- display: "flex",
27
- overflow: "hidden",
28
- flexDirection: "column",
29
- height: height ? height - 70 : 80
30
- }
31
- });
32
- const classes = useStyles();
19
+ const [costsSeries, setCostsSeries] = useState(void 0);
20
+ const [metricsSeries, setMetricsSeries] = useState(void 0);
33
21
  const [showMetrics, setShowMetrics] = useState(false);
34
- const [seriesArray, setSeriesArray] = useState([]);
35
- const [yaxisArray, setYaxisArray] = useState([]);
36
- const [strokeWidthArray, setStrokeWidthArray] = useState([]);
37
- const [strokeDashArray, setStrokeDashArray] = useState([]);
38
- const customScale = humanFormat.Scale.create(["", "K", "M", "B"], 1e3);
39
- const state = thumbnail ? {
40
- options: {
41
- chart: {
42
- animations: {
43
- enabled: false
44
- },
45
- zoom: {
46
- enabled: false
47
- },
48
- stacked: true,
49
- toolbar: {
50
- show: false
51
- },
52
- sparkline: {
53
- enabled: true
22
+ const [maxCostsYaxis, setMaxCostsYaxis] = useState(void 0);
23
+ const initChartCallback = useCallback(async () => {
24
+ setCostsSeries(void 0);
25
+ setMetricsSeries(void 0);
26
+ if (costs) {
27
+ const sums = [];
28
+ for (const s of costs) {
29
+ for (let i = 0; i < s.data.length; i++) {
30
+ if (sums[i] === void 0) {
31
+ sums[i] = 0;
32
+ }
33
+ sums[i] += s.data[i];
54
34
  }
55
- },
56
- xaxis: {
57
- categories
58
- },
59
- theme: {
60
- mode: defaultTheme.palette.type
35
+ }
36
+ setMaxCostsYaxis(Math.max(...sums));
37
+ setCostsSeries(
38
+ costs.map((s) => {
39
+ return {
40
+ id: s.name,
41
+ data: s.data,
42
+ type: "bar",
43
+ label: s.name,
44
+ yAxisId: "costsAxis",
45
+ valueFormatter: (value) => {
46
+ return formatCurrency(value ? value : 0);
47
+ },
48
+ highlightScope: { highlight: "series", fade: "global" },
49
+ stack: "total",
50
+ stackOrder: "descending"
51
+ };
52
+ })
53
+ );
54
+ }
55
+ if (metrics && showMetrics) {
56
+ setMetricsSeries(
57
+ metrics.map((s) => {
58
+ return {
59
+ data: s.data,
60
+ type: "line",
61
+ label: s.name,
62
+ curve: "natural",
63
+ yAxisId: "metricsAxis",
64
+ highlightScope: { highlight: "series", fade: "global" },
65
+ showMark: granularity === "monthly"
66
+ };
67
+ })
68
+ );
69
+ }
70
+ }, [costs, metrics, showMetrics, granularity]);
71
+ useEffect(() => {
72
+ initChartCallback();
73
+ }, [initChartCallback]);
74
+ return /* @__PURE__ */ React.createElement(
75
+ Paper,
76
+ {
77
+ sx: {
78
+ padding: "16px",
79
+ display: "flex",
80
+ flexDirection: "column",
81
+ height: height ? height : 300
61
82
  }
62
83
  },
63
- series
64
- } : {
65
- options: {
66
- chart: {
67
- animations: {
68
- enabled: false
69
- },
70
- stacked: true,
71
- toolbar: {
72
- show: false
84
+ /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "flex-end", spacing: 1 }, /* @__PURE__ */ React.createElement(Grid, { item: true }, "Monthly"), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Switch, { size: "small", onChange: (event) => granularitySetter(event.target.checked ? "daily" : "monthly") })), /* @__PURE__ */ React.createElement(Grid, { item: true }, "Daily"), /* @__PURE__ */ React.createElement(Grid, { item: true }, " | "), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Switch, { size: "small", checked: showMetrics, onChange: (_) => setShowMetrics((ori) => !ori) })), /* @__PURE__ */ React.createElement(Grid, { item: true }, "Show Metrics")),
85
+ costs && costsSeries ? /* @__PURE__ */ React.createElement(
86
+ ResponsiveChartContainer,
87
+ {
88
+ margin: {
89
+ bottom: 80
73
90
  },
74
- events: {
75
- dataPointSelection: dataPointSelectionHandler
76
- }
77
- },
78
- xaxis: {
79
- categories
80
- },
81
- stroke: {
82
- width: strokeWidthArray,
83
- dashArray: strokeDashArray,
84
- curve: "smooth"
85
- },
86
- yaxis: yaxisArray,
87
- dataLabels: {
88
- enabled: false
89
- },
90
- tooltip: {
91
- y: {
92
- formatter: (value, { seriesIndex }) => {
93
- if (!value) {
94
- return "";
95
- }
96
- const prefix = seriesIndex <= series.length - 1 ? "$" : "";
97
- return `${prefix}${humanFormat(value, {
98
- scale: customScale,
99
- separator: ""
100
- })}`;
91
+ series: [...costsSeries, ...metricsSeries ? metricsSeries : []],
92
+ xAxis: [
93
+ {
94
+ data: categories,
95
+ scaleType: "band"
101
96
  }
102
- },
103
- fixed: {
104
- enabled: true,
105
- position: "topRight"
97
+ ],
98
+ yAxis: [
99
+ {
100
+ id: "costsAxis",
101
+ max: maxCostsYaxis,
102
+ valueFormatter: (value) => formatCurrency(value)
103
+ },
104
+ {
105
+ id: "metricsAxis"
106
+ }
107
+ ],
108
+ colors: colorList,
109
+ highlightedItem: highlightedItem ? { seriesId: highlightedItem } : null,
110
+ onHighlightChange: (highlighted) => {
111
+ highlightedItemSetter(highlighted == null ? void 0 : highlighted.seriesId);
106
112
  }
107
113
  },
108
- legend: {
109
- showForSingleSeries: true
110
- },
111
- theme: {
112
- mode: defaultTheme.palette.type
113
- },
114
- // there are only 5 colors by default, here we extend it to 50 different colors
115
- colors: colorList
116
- },
117
- series: seriesArray
118
- };
119
- const initChartCallback = useCallback(async () => {
120
- const labelFormatter = (value) => {
121
- const scale = humanFormat.Scale.create(["", "K", "M", "B"], 1e3);
122
- if (typeof value !== "number" || isNaN(value)) {
123
- return "";
124
- }
125
- return `$${humanFormat(value, {
126
- scale,
127
- separator: ""
128
- })}`;
129
- };
130
- const strokeWidth = Array(series.length).fill(0);
131
- const seriesResult = series.map((s) => s);
132
- const yaxisResult = [
133
- {
134
- seriesName: series.map((s) => s.name),
135
- decimalsInFloat: 2,
136
- title: {
137
- text: "Costs in USD"
138
- },
139
- labels: {
140
- formatter: labelFormatter
141
- }
142
- }
143
- ];
144
- if (metrics && showMetrics) {
145
- const metricGroups = {};
146
- metrics.forEach((metric) => {
147
- strokeWidth.push(3);
148
- seriesResult.push(metric);
149
- if (metric.group) {
150
- if (!metricGroups[metric.group]) {
151
- metricGroups[metric.group] = {
152
- seriesName: [metric.name],
153
- decimalsInFloat: 2,
154
- opposite: true,
155
- forceNiceScale: true,
156
- title: {
157
- text: metric.group
158
- },
159
- labels: {
160
- formatter: labelFormatter
114
+ /* @__PURE__ */ React.createElement(ChartsGrid, { horizontal: true }),
115
+ /* @__PURE__ */ React.createElement(BarPlot, null),
116
+ /* @__PURE__ */ React.createElement(LinePlot, null),
117
+ /* @__PURE__ */ React.createElement(LineHighlightPlot, null),
118
+ /* @__PURE__ */ React.createElement(MarkPlot, null),
119
+ /* @__PURE__ */ React.createElement(ChartsXAxis, null),
120
+ /* @__PURE__ */ React.createElement(ChartsYAxis, null),
121
+ /* @__PURE__ */ React.createElement(ChartsTooltip, { trigger: "item" }),
122
+ /* @__PURE__ */ React.createElement(
123
+ ChartsLegend,
124
+ {
125
+ slots: {
126
+ legend: (props) => {
127
+ var _a;
128
+ const seriesToDisplay = [];
129
+ for (const s of props.seriesToDisplay) {
130
+ if (((_a = props.series.bar) == null ? void 0 : _a.seriesOrder) && props.series.bar.seriesOrder.indexOf(s.id) !== -1) {
131
+ seriesToDisplay.push(s);
132
+ }
161
133
  }
162
- };
163
- } else {
164
- metricGroups[metric.group].seriesName.push(metric.name);
165
- }
166
- } else {
167
- yaxisResult.push({
168
- seriesName: [metric.name],
169
- decimalsInFloat: 2,
170
- opposite: true,
171
- forceNiceScale: true,
172
- title: {
173
- text: metric.name
174
- },
175
- labels: {
176
- formatter: labelFormatter
134
+ return /* @__PURE__ */ React.createElement(
135
+ DefaultChartsLegend,
136
+ {
137
+ series: props.series,
138
+ seriesToDisplay,
139
+ drawingArea: props.drawingArea,
140
+ direction: "row",
141
+ position: { vertical: "bottom", horizontal: "middle" },
142
+ itemMarkHeight: 10,
143
+ itemMarkWidth: 10,
144
+ labelStyle: {
145
+ fontSize: "0.9em"
146
+ },
147
+ onItemClick: (_, legendItem) => {
148
+ const clickedLegend = legendItem.seriesId;
149
+ if (clickedLegend === highlightedItem) {
150
+ highlightedItemSetter(void 0);
151
+ } else {
152
+ highlightedItemSetter(clickedLegend);
153
+ }
154
+ }
155
+ }
156
+ );
177
157
  }
178
- });
158
+ }
179
159
  }
180
- });
181
- Object.values(metricGroups).forEach((group) => {
182
- yaxisResult.push(group);
183
- });
184
- }
185
- setSeriesArray(seriesResult);
186
- setYaxisArray(yaxisResult);
187
- setStrokeWidthArray(strokeWidth);
188
- setStrokeDashArray(Array(seriesResult.length).fill(0));
189
- }, [metrics, series, showMetrics]);
190
- useEffect(() => {
191
- initChartCallback();
192
- }, [initChartCallback]);
193
- return /* @__PURE__ */ React.createElement(Paper, { className: thumbnail ? classes.thumbnailPaper : classes.fixedHeightPaper }, /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "flex-end", spacing: 1 }, /* @__PURE__ */ React.createElement(Grid, { item: true }, "Monthly"), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Switch, { size: "small", onChange: (event) => granularitySetter(event.target.checked ? "daily" : "monthly") })), /* @__PURE__ */ React.createElement(Grid, { item: true }, "Daily"), /* @__PURE__ */ React.createElement(Grid, { item: true }, " | "), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Switch, { size: "small", checked: showMetrics, onChange: (_) => setShowMetrics((ori) => !ori) })), /* @__PURE__ */ React.createElement(Grid, { item: true }, "Show Metrics")), seriesArray && /* @__PURE__ */ React.createElement(Chart, { options: state.options, series: state.series, type: "line", height: height ? height - 70 : 230 }));
160
+ )
161
+ ) : /* @__PURE__ */ React.createElement("div", { style: { width: "60%", margin: "auto" } }, /* @__PURE__ */ React.createElement(Skeleton, null), /* @__PURE__ */ React.createElement(Skeleton, null), /* @__PURE__ */ React.createElement(Skeleton, null))
162
+ );
194
163
  };
195
164
 
196
165
  export { ColumnsChartComponent };
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnsChartComponent.esm.js","sources":["../../../src/components/ColumnsChartComponent/ColumnsChartComponent.tsx"],"sourcesContent":["import { Grid, Paper, Switch } from '@material-ui/core';\nimport { makeStyles, useTheme } from '@material-ui/core/styles';\nimport humanFormat from 'human-format';\nimport React, { FC, useCallback, useEffect, useState } from 'react';\nimport Chart from 'react-apexcharts';\nimport { colorList } from '../constants';\nimport { ColumnsChartComponentProps } from '../types';\n\ntype CurveType =\n | 'smooth'\n | 'straight'\n | 'stepline'\n | 'linestep'\n | 'monotoneCubic'\n | ('smooth' | 'straight' | 'stepline' | 'linestep' | 'monotoneCubic')[]\n | undefined;\n\nexport const ColumnsChartComponent: FC<ColumnsChartComponentProps> = ({\n granularitySetter,\n categories,\n series,\n metrics,\n height,\n thumbnail,\n dataPointSelectionHandler,\n}) => {\n const defaultTheme = useTheme();\n const useStyles = makeStyles({\n fixedHeightPaper: {\n padding: '16px',\n display: 'flex',\n flexDirection: 'column',\n height: height ? height : 300,\n },\n thumbnailPaper: {\n display: 'flex',\n overflow: 'hidden',\n flexDirection: 'column',\n height: height ? height - 70 : 80,\n },\n });\n const classes = useStyles();\n const [showMetrics, setShowMetrics] = useState<boolean>(false);\n const [seriesArray, setSeriesArray] = useState<any[]>([]);\n const [yaxisArray, setYaxisArray] = useState<any[]>([]);\n const [strokeWidthArray, setStrokeWidthArray] = useState<number[]>([]);\n const [strokeDashArray, setStrokeDashArray] = useState<number[]>([]);\n const customScale = humanFormat.Scale.create(['', 'K', 'M', 'B'], 1000);\n\n const state = thumbnail\n ? {\n options: {\n chart: {\n animations: {\n enabled: false,\n },\n zoom: {\n enabled: false,\n },\n stacked: true,\n toolbar: {\n show: false,\n },\n sparkline: {\n enabled: true,\n },\n },\n xaxis: {\n categories: categories,\n },\n theme: {\n mode: defaultTheme.palette.type,\n },\n },\n series: series,\n }\n : {\n options: {\n chart: {\n animations: {\n enabled: false,\n },\n stacked: true,\n toolbar: {\n show: false,\n },\n events: {\n dataPointSelection: dataPointSelectionHandler,\n },\n },\n xaxis: {\n categories: categories,\n },\n stroke: {\n width: strokeWidthArray,\n dashArray: strokeDashArray,\n curve: 'smooth' as CurveType,\n },\n yaxis: yaxisArray,\n dataLabels: {\n enabled: false,\n },\n tooltip: {\n y: {\n formatter: (value: number, { seriesIndex }: { seriesIndex: number }) => {\n if (!value) {\n return '';\n }\n const prefix = seriesIndex <= series.length - 1 ? '$' : '';\n return `${prefix}${humanFormat(value, {\n scale: customScale,\n separator: '',\n })}`;\n },\n },\n fixed: {\n enabled: true,\n position: 'topRight',\n },\n },\n legend: {\n showForSingleSeries: true,\n },\n theme: {\n mode: defaultTheme.palette.type,\n },\n // there are only 5 colors by default, here we extend it to 50 different colors\n colors: colorList,\n },\n series: seriesArray,\n };\n\n const initChartCallback = useCallback(async () => {\n const labelFormatter = (value: number): string => {\n const scale = humanFormat.Scale.create(['', 'K', 'M', 'B'], 1000);\n if (typeof value !== 'number' || isNaN(value)) {\n return '';\n }\n return `$${humanFormat(value, {\n scale: scale,\n separator: '',\n })}`;\n };\n\n const strokeWidth = Array<number>(series.length).fill(0);\n const seriesResult = series.map(s => s);\n const yaxisResult: any[] = [\n {\n seriesName: series.map(s => s.name),\n decimalsInFloat: 2,\n title: {\n text: 'Costs in USD',\n },\n labels: {\n formatter: labelFormatter,\n },\n },\n ];\n\n if (metrics && showMetrics) {\n const metricGroups: any = {};\n metrics.forEach(metric => {\n strokeWidth.push(3);\n seriesResult.push(metric);\n\n if (metric.group) {\n if (!metricGroups[metric.group]) {\n metricGroups[metric.group] = {\n seriesName: [metric.name],\n decimalsInFloat: 2,\n opposite: true,\n forceNiceScale: true,\n title: {\n text: metric.group,\n },\n labels: {\n formatter: labelFormatter,\n },\n };\n } else {\n // yaxis already exists, add the series to the existing one\n metricGroups[metric.group].seriesName.push(metric.name);\n }\n } else {\n // the metric does not have a group, create a separate yaxis for it\n yaxisResult.push({\n seriesName: [metric.name],\n decimalsInFloat: 2,\n opposite: true,\n forceNiceScale: true,\n title: {\n text: metric.name,\n },\n labels: {\n formatter: labelFormatter,\n },\n });\n }\n });\n Object.values(metricGroups).forEach((group: any) => {\n yaxisResult.push(group);\n });\n }\n\n setSeriesArray(seriesResult);\n setYaxisArray(yaxisResult);\n setStrokeWidthArray(strokeWidth);\n setStrokeDashArray(Array<number>(seriesResult.length).fill(0));\n }, [metrics, series, showMetrics]);\n\n useEffect(() => {\n initChartCallback();\n }, [initChartCallback]);\n\n return (\n <Paper className={thumbnail ? classes.thumbnailPaper : classes.fixedHeightPaper}>\n <Grid container justifyContent=\"flex-end\" spacing={1}>\n <Grid item>Monthly</Grid>\n <Grid item>\n <Switch size=\"small\" onChange={event => granularitySetter(event.target.checked ? 'daily' : 'monthly')} />\n </Grid>\n <Grid item>Daily</Grid>\n <Grid item> | </Grid>\n <Grid item>\n <Switch size=\"small\" checked={showMetrics} onChange={_ => setShowMetrics((ori: boolean) => !ori)} />\n </Grid>\n <Grid item>Show Metrics</Grid>\n </Grid>\n {seriesArray && (\n <Chart options={state.options} series={state.series} type=\"line\" height={height ? height - 70 : 230} />\n )}\n </Paper>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ColumnsChartComponent.esm.js","sources":["../../../src/components/ColumnsChartComponent/ColumnsChartComponent.tsx"],"sourcesContent":["import { Grid, Switch } from '@material-ui/core';\nimport Paper from '@mui/material/Paper';\nimport Skeleton from '@mui/material/Skeleton';\nimport {\n BarPlot,\n ChartsGrid,\n ChartsLegend,\n ChartsTooltip,\n ChartsXAxis,\n ChartsYAxis,\n DefaultChartsLegend,\n LineHighlightPlot,\n LinePlot,\n MarkPlot,\n ResponsiveChartContainer,\n} from '@mui/x-charts';\nimport React, { FC, useCallback, useEffect, useState } from 'react';\nimport { formatCurrency } from '../../api/functions';\nimport { colorList } from '../constants';\nimport { ColumnsChartComponentProps } from '../types';\n\nexport const ColumnsChartComponent: FC<ColumnsChartComponentProps> = ({\n granularity,\n granularitySetter,\n categories,\n costs,\n metrics,\n height,\n highlightedItem,\n highlightedItemSetter,\n}) => {\n const [costsSeries, setCostsSeries] = useState<any[] | undefined>(undefined);\n const [metricsSeries, setMetricsSeries] = useState<any[] | undefined>(undefined);\n const [showMetrics, setShowMetrics] = useState<boolean>(false);\n const [maxCostsYaxis, setMaxCostsYaxis] = useState<number | undefined>(undefined);\n\n const initChartCallback = useCallback(async () => {\n setCostsSeries(undefined);\n setMetricsSeries(undefined);\n\n if (costs) {\n const sums = [];\n for (const s of costs) {\n for (let i = 0; i < s.data.length; i++) {\n if (sums[i] === undefined) {\n sums[i] = 0;\n }\n sums[i] += s.data[i];\n }\n }\n setMaxCostsYaxis(Math.max(...sums));\n\n setCostsSeries(\n costs.map(s => {\n return {\n id: s.name,\n data: s.data,\n type: 'bar',\n label: s.name,\n yAxisId: 'costsAxis',\n valueFormatter: (value: number) => {\n return formatCurrency(value ? value : 0);\n },\n highlightScope: { highlight: 'series', fade: 'global' },\n stack: 'total',\n stackOrder: 'descending',\n };\n }),\n );\n }\n\n if (metrics && showMetrics) {\n setMetricsSeries(\n metrics.map(s => {\n return {\n data: s.data,\n type: 'line',\n label: s.name,\n curve: 'natural',\n yAxisId: 'metricsAxis',\n highlightScope: { highlight: 'series', fade: 'global' },\n showMark: granularity === 'monthly',\n };\n }),\n );\n }\n }, [costs, metrics, showMetrics, granularity]);\n\n useEffect(() => {\n initChartCallback();\n }, [initChartCallback]);\n\n return (\n <Paper\n sx={{\n padding: '16px',\n display: 'flex',\n flexDirection: 'column',\n height: height ? height : 300,\n }}\n >\n <Grid container justifyContent=\"flex-end\" spacing={1}>\n <Grid item>Monthly</Grid>\n <Grid item>\n <Switch size=\"small\" onChange={event => granularitySetter(event.target.checked ? 'daily' : 'monthly')} />\n </Grid>\n <Grid item>Daily</Grid>\n <Grid item> | </Grid>\n <Grid item>\n <Switch size=\"small\" checked={showMetrics} onChange={_ => setShowMetrics((ori: boolean) => !ori)} />\n </Grid>\n <Grid item>Show Metrics</Grid>\n </Grid>\n {costs && costsSeries ? (\n <ResponsiveChartContainer\n margin={{\n bottom: 80,\n }}\n series={[...costsSeries, ...(metricsSeries ? metricsSeries : [])]}\n xAxis={[\n {\n data: categories,\n scaleType: 'band',\n },\n ]}\n yAxis={[\n {\n id: 'costsAxis',\n max: maxCostsYaxis,\n valueFormatter: value => formatCurrency(value),\n },\n {\n id: 'metricsAxis',\n },\n ]}\n colors={colorList}\n highlightedItem={highlightedItem ? { seriesId: highlightedItem } : null}\n onHighlightChange={highlighted => {\n highlightedItemSetter(highlighted?.seriesId);\n }}\n >\n <ChartsGrid horizontal />\n <BarPlot />\n <LinePlot />\n <LineHighlightPlot />\n <MarkPlot />\n <ChartsXAxis />\n <ChartsYAxis />\n <ChartsTooltip trigger=\"item\" />\n <ChartsLegend\n slots={{\n legend: props => {\n // keep legend items for costs only (from bar chart)\n const seriesToDisplay = [];\n for (const s of props.seriesToDisplay) {\n if (props.series.bar?.seriesOrder && props.series.bar.seriesOrder.indexOf(s.id) !== -1) {\n seriesToDisplay.push(s);\n }\n }\n\n return (\n <DefaultChartsLegend\n series={props.series}\n seriesToDisplay={seriesToDisplay}\n drawingArea={props.drawingArea}\n direction=\"row\"\n position={{ vertical: 'bottom', horizontal: 'middle' }}\n itemMarkHeight={10}\n itemMarkWidth={10}\n labelStyle={{\n fontSize: '0.9em',\n }}\n onItemClick={(_, legendItem) => {\n // highlight the clicked item\n const clickedLegend = legendItem.seriesId;\n if (clickedLegend === highlightedItem) {\n highlightedItemSetter(undefined);\n } else {\n highlightedItemSetter(clickedLegend);\n }\n }}\n />\n );\n },\n }}\n />\n </ResponsiveChartContainer>\n ) : (\n <div style={{ width: '60%', margin: 'auto' }}>\n <Skeleton />\n <Skeleton />\n <Skeleton />\n </div>\n )}\n </Paper>\n );\n};\n"],"names":[],"mappings":"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"}