From df0e3d405f1bd71ae4fed07bb6f69fc6cc7f46b7 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 16 Oct 2024 12:29:04 -0400 Subject: [PATCH] EC2 instances empty state https://issues.redhat.com/browse/COST-5546 --- locales/data.json | 48 +++++++++++++++++- locales/translations.json | 12 +++-- package-lock.json | 50 +++++++++++++++++++ package.json | 1 + src/locales/messages.ts | 40 +++++++++++++-- .../page/noInstances/noInstances.styles.ts | 24 +++++++++ .../page/noInstances/noInstancesState.tsx | 49 ++++++++++++++++-- .../awsBreakdown/instances/instances.tsx | 1 + 8 files changed, 213 insertions(+), 12 deletions(-) create mode 100644 src/routes/components/page/noInstances/noInstances.styles.ts diff --git a/locales/data.json b/locales/data.json index bf3cae29b..8181dbc77 100644 --- a/locales/data.json +++ b/locales/data.json @@ -1103,6 +1103,18 @@ "value": "Clusters" } ], + "copied": [ + { + "type": 0, + "value": "Copied" + } + ], + "copy": [ + { + "type": 0, + "value": "Copy" + } + ], "cost": [ { "type": 0, @@ -10973,13 +10985,27 @@ "noInstancesDesc": [ { "type": 0, - "value": "Add an Amazon EC2 instance to see a total cost breakdown of your spend by instances." + "value": "To view the cost of EC2 instances, label your resources with the following tag and key value pair in the AWS console." + } + ], + "noInstancesMoreInfo": [ + { + "type": 0, + "value": "For more information, " + }, + { + "type": 1, + "value": "seeDocumentation" + }, + { + "type": 0, + "value": "." } ], "noInstancesTitle": [ { "type": 0, - "value": "No instances available" + "value": "View cost of EC2 instances" } ], "noMappedTags": [ @@ -12059,6 +12085,12 @@ "value": "Save" } ], + "seeDocumentation": [ + { + "type": 0, + "value": "see documentation" + } + ], "select": [ { "type": 0, @@ -12862,6 +12894,12 @@ "value": "Value" } ], + "tagKey": [ + { + "type": 0, + "value": "Tag key:" + } + ], "tagKeyChild": [ { "type": 0, @@ -13110,6 +13148,12 @@ "value": "Tag names" } ], + "tagValue": [ + { + "type": 0, + "value": "Tag value:" + } + ], "timeOfExport": [ { "type": 0, diff --git a/locales/translations.json b/locales/translations.json index 4a951916d..d16121044 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -71,6 +71,8 @@ "clusterId": "Cluster id", "clusterInfo": "Cluster information", "clusters": "Clusters", + "copied": "Copied", + "copy": "Copy", "cost": "Cost", "costBreakdownAriaDesc": "Breakdown of markup, raw, and usage costs", "costBreakdownAriaLabel": "A description of markup, raw cost and usage cost", @@ -412,8 +414,9 @@ "noDataStateRefresh": "Refresh this page", "noDataStateTitle": "Still processing the data", "noExportsStateTitle": "There are no export files available", - "noInstancesDesc": "Add an Amazon EC2 instance to see a total cost breakdown of your spend by instances.", - "noInstancesTitle": "No instances available", + "noInstancesDesc": "To view the cost of EC2 instances, label your resources with the following tag and key value pair in the AWS console.", + "noInstancesMoreInfo": "For more information, {seeDocumentation}.", + "noInstancesTitle": "View cost of EC2 instances", "noMappedTags": "No mapped tags", "noMappedTagsDesc": "Map multiple tags across data sources to be used as a single tag key for report grouping and filtering. {warning} Changes will be reflected within 24 hours. {learnMore}", "noMappedTagsWarning": "Tags must be enabled to be mapped.", @@ -539,6 +542,7 @@ "rhelMemoryUsageAndRequests": "Memory usage and requests", "rhelVolumeUsageAndRequests": "Volume usage and requests", "save": "Save", + "seeDocumentation": "see documentation", "select": "Select...", "selectAll": "Select all", "selectCategories": "Select categories to enable or disable", @@ -585,6 +589,7 @@ "tagHeadingKey": "Key", "tagHeadingTitle": "Tags ({value})", "tagHeadingValue": "Value", + "tagKey": "Tag key:", "tagKeyChild": "Child tag keys", "tagKeyParent": "Parent tag key", "tagKeyParentSource": "Parent integration", @@ -617,6 +622,7 @@ "tagMappingWizardSuccess": "Tag mapping successful", "tagMappingWizardSuccessDesc": "Your tag keys were successfully mapped. Changes will be reflected in report summarizations within 24 hours.", "tagNames": "Tag names", + "tagValue": "Tag value:", "timeOfExport": "Time of export", "to": "to", "toolBarBulkSelectAll": "Select all ({value} items)", @@ -642,4 +648,4 @@ "workerUnallocated": "Worker unallocated", "workerUnallocatedDesc": "Distribute unused and non-reserved resource costs to projects", "yes": "Yes" -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index c3473b480..9e6e670d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "@eslint/compat": "^1.2.0", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.12.0", + "@formatjs/cli": "^6.2.15", "@formatjs/ecma402-abstract": "^2.2.0", "@formatjs/fast-memoize": "^2.2.1", "@formatjs/intl-localematcher": "^0.5.5", @@ -862,6 +863,55 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@formatjs/cli": { + "version": "6.2.15", + "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-6.2.15.tgz", + "integrity": "sha512-s31YblAseSVqgFvY2EoIZaaEycifR/CadvMj1WcNvFvHK+2Xn02OuSX1jiKM/Nx29hX2x8k0raFJ6PtnXZgjtQ==", + "dev": true, + "license": "MIT", + "bin": { + "formatjs": "bin/formatjs" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "@glimmer/env": "^0.1.7", + "@glimmer/reference": "^0.91.1 || ^0.92.0", + "@glimmer/syntax": "^0.92.0", + "@glimmer/validator": "^0.92.0", + "@vue/compiler-core": "^3.4.0", + "content-tag": "^2.0.1", + "ember-template-recast": "^6.1.4", + "vue": "^3.4.0" + }, + "peerDependenciesMeta": { + "@glimmer/env": { + "optional": true + }, + "@glimmer/reference": { + "optional": true + }, + "@glimmer/syntax": { + "optional": true + }, + "@glimmer/validator": { + "optional": true + }, + "@vue/compiler-core": { + "optional": true + }, + "content-tag": { + "optional": true + }, + "ember-template-recast": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, "node_modules/@formatjs/ecma402-abstract": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.0.tgz", diff --git a/package.json b/package.json index 7f6d75470..c08e68aa1 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "@eslint/compat": "^1.2.0", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.12.0", + "@formatjs/cli": "^6.2.15", "@formatjs/ecma402-abstract": "^2.2.0", "@formatjs/fast-memoize": "^2.2.1", "@formatjs/intl-localematcher": "^0.5.5", diff --git a/src/locales/messages.ts b/src/locales/messages.ts index f42057b34..b853fb048 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -405,6 +405,16 @@ export default defineMessages({ description: 'Clusters', id: 'clusters', }, + copied: { + defaultMessage: 'Copied', + description: 'Copied', + id: 'copied', + }, + copy: { + defaultMessage: 'Copy', + description: 'Copy', + id: 'copy', + }, cost: { defaultMessage: 'Cost', description: 'Cost', @@ -2635,13 +2645,20 @@ export default defineMessages({ id: 'noExportsStateTitle', }, noInstancesDesc: { - defaultMessage: 'Add an Amazon EC2 instance to see a total cost breakdown of your spend by instances.', - description: 'Add an Amazon EC2 instance to see a total cost breakdown of your spend by instances.', + defaultMessage: + 'To view the cost of EC2 instances, label your resources with the following tag and key value pair in the AWS console.', + description: + 'To view the cost of EC2 instances, label your resources with the following tag and key value pair in the AWS console.', id: 'noInstancesDesc', }, + noInstancesMoreInfo: { + defaultMessage: 'For more information, {seeDocumentation}.', + description: 'For more information, see documentation.', + id: 'noInstancesMoreInfo', + }, noInstancesTitle: { - defaultMessage: 'No instances available', - description: 'No instances available', + defaultMessage: 'View cost of EC2 instances', + description: 'View cost of EC2 instances', id: 'noInstancesTitle', }, noMappedTags: { @@ -3314,6 +3331,11 @@ export default defineMessages({ description: 'Save', id: 'save', }, + seeDocumentation: { + defaultMessage: 'see documentation', + description: 'see documentation', + id: 'seeDocumentation', + }, select: { defaultMessage: 'Select...', description: 'Select...', @@ -3584,6 +3606,11 @@ export default defineMessages({ description: 'Value', id: 'tagHeadingValue', }, + tagKey: { + defaultMessage: 'Tag key:', + description: 'Tag keys', + id: 'tagKey', + }, tagKeyChild: { defaultMessage: 'Child tag keys', description: 'Child tag keys', @@ -3758,6 +3785,11 @@ export default defineMessages({ description: 'Tag Names', id: 'tagNames', }, + tagValue: { + defaultMessage: 'Tag value:', + description: 'Tag value', + id: 'tagValue', + }, timeOfExport: { defaultMessage: 'Time of export', description: 'Time of export', diff --git a/src/routes/components/page/noInstances/noInstances.styles.ts b/src/routes/components/page/noInstances/noInstances.styles.ts new file mode 100644 index 000000000..3990a0f51 --- /dev/null +++ b/src/routes/components/page/noInstances/noInstances.styles.ts @@ -0,0 +1,24 @@ +import global_spacer_lg from '@patternfly/react-tokens/dist/js/global_spacer_lg'; +import global_spacer_sm from '@patternfly/react-tokens/dist/js/global_spacer_sm'; +import global_spacer_xs from '@patternfly/react-tokens/dist/js/global_spacer_xs'; + +export const styles = { + clipboardContainer: { + textAlign: 'left', + }, + moreInfo: { + display: 'block', + }, + tagKey: { + marginTop: global_spacer_lg.var, + }, + tagKeyLabel: { + marginRight: global_spacer_sm.var, + }, + tagValue: { + marginTop: global_spacer_xs.var, + }, + tagValueLabel: { + marginRight: global_spacer_sm.var, + }, +} as { [className: string]: React.CSSProperties }; diff --git a/src/routes/components/page/noInstances/noInstancesState.tsx b/src/routes/components/page/noInstances/noInstancesState.tsx index 4a242d7b3..0e5d8bdde 100644 --- a/src/routes/components/page/noInstances/noInstancesState.tsx +++ b/src/routes/components/page/noInstances/noInstancesState.tsx @@ -1,16 +1,20 @@ import { + ClipboardCopy, EmptyState, EmptyStateBody, + EmptyStateFooter, EmptyStateHeader, EmptyStateIcon, EmptyStateVariant, } from '@patternfly/react-core'; -import { PlusCircleIcon } from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon'; +import { TagIcon } from '@patternfly/react-icons/dist/esm/icons/tag-icon'; import messages from 'locales/messages'; import React from 'react'; import type { WrappedComponentProps } from 'react-intl'; import { injectIntl } from 'react-intl'; +import { styles } from './noInstances.styles'; + interface NoInstancesStateOwnProps { // TBD... } @@ -25,10 +29,49 @@ class NoInstancesStateBase extends React.Component { } + icon={} headingLevel="h1" /> - {intl.formatMessage(messages.noInstancesDesc)} + +
{intl.formatMessage(messages.noInstancesDesc)}
+
+
+ {intl.formatMessage(messages.tagKey)} + + com_redhat_insights_cost_management + +
+
+ {intl.formatMessage(messages.tagValue)} + + ec2_compute + +
+
+
+ +
+ {intl.formatMessage(messages.noInstancesMoreInfo, { + seeDocumentation: ( + + {intl.formatMessage(messages.seeDocumentation)} + + ), + })} +
+
); } diff --git a/src/routes/details/awsBreakdown/instances/instances.tsx b/src/routes/details/awsBreakdown/instances/instances.tsx index 73aeb6d73..6d385f65d 100644 --- a/src/routes/details/awsBreakdown/instances/instances.tsx +++ b/src/routes/details/awsBreakdown/instances/instances.tsx @@ -311,6 +311,7 @@ const Instances: React.FC = ({ costType, currency }) => { if (!query.filter_by && !hasInstances && reportFetchStatus === FetchStatus.complete) { return ; } + return ; const computedItems = getComputedItems(); return (