Skip to content

Commit

Permalink
Details pages: Show previous data when current month is unavailable
Browse files Browse the repository at this point in the history
  • Loading branch information
dlabrecq committed Oct 3, 2024
1 parent 1ad53f9 commit e36dd8d
Show file tree
Hide file tree
Showing 74 changed files with 1,540 additions and 528 deletions.
14 changes: 14 additions & 0 deletions locales/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -10880,6 +10880,20 @@
"value": "No"
}
],
"noCurrentData": [
{
"type": 0,
"value": "No data available for "
},
{
"type": 1,
"value": "dateRange"
},
{
"type": 0,
"value": ". You are viewing data for the previous month."
}
],
"noDataForDate": [
{
"type": 0,
Expand Down
1 change: 1 addition & 0 deletions locales/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@
"networkUnattributedDistributedDesc": "Costs associated with ingress and egress network traffic for individual nodes.",
"next": "next",
"no": "No",
"noCurrentData": "No data available for {dateRange}. You are viewing data for the previous month.",
"noDataForDate": "No data available for {dateRange}",
"noDataStateDesc": "We have detected an integration, but we are not done processing the incoming data. {status}The time to process could take up to 24 hours. Try refreshing the page at a later time.",
"noDataStateRefresh": "Refresh this page",
Expand Down
8 changes: 8 additions & 0 deletions src/components/featureToggle/featureToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const enum FeatureToggle {
accountInfoEmptyState = 'cost-management.ui.account-info-empty-state', // https://issues.redhat.com/browse/COST-5335
awsEc2Instances = 'cost-management.ui.aws-ec2-instances', // https://issues.redhat.com/browse/COST-4855
debug = 'cost-management.ui.debug',
detailsDateRange = 'cost-management.ui.details-date-range', // https://issues.redhat.com/browse/COST-5563
exports = 'cost-management.ui.exports', // Async exports https://issues.redhat.com/browse/COST-2223
finsights = 'cost-management.ui.finsights', // RHEL support for FINsights https://issues.redhat.com/browse/COST-3306
ibm = 'cost-management.ui.ibm', // IBM https://issues.redhat.com/browse/COST-935
Expand All @@ -31,6 +32,10 @@ export const useIsDebugToggleEnabled = () => {
return useIsToggleEnabled(FeatureToggle.debug);
};

export const useIsDetailsDateRangeToggleEnabled = () => {
return useIsToggleEnabled(FeatureToggle.detailsDateRange);
};

export const useIsExportsToggleEnabled = () => {
return useIsToggleEnabled(FeatureToggle.exports);
};
Expand All @@ -55,6 +60,7 @@ export const useFeatureToggle = () => {
const isAccountInfoEmptyStateToggleEnabled = useIsAccountInfoEmptyStateToggleEnabled();
const isAwsEc2InstancesToggleEnabled = useIsAwsEc2InstancesToggleEnabled();
const isDebugToggleEnabled = useIsDebugToggleEnabled();
const isDetailsDateRangeToggleEnabled = useIsDetailsDateRangeToggleEnabled();
const isExportsToggleEnabled = useIsExportsToggleEnabled();
const isFinsightsToggleEnabled = useIsFinsightsToggleEnabled();
const isIbmToggleEnabled = useIsIbmToggleEnabled();
Expand All @@ -73,6 +79,7 @@ export const useFeatureToggle = () => {
isAccountInfoEmptyStateToggleEnabled,
isAwsEc2InstancesToggleEnabled,
isDebugToggleEnabled,
isDetailsDateRangeToggleEnabled,
isExportsToggleEnabled,
isFinsightsToggleEnabled,
isIbmToggleEnabled,
Expand All @@ -87,6 +94,7 @@ export const useFeatureToggle = () => {
isAccountInfoEmptyStateToggleEnabled,
isAwsEc2InstancesToggleEnabled,
isDebugToggleEnabled,
isDetailsDateRangeToggleEnabled,
isExportsToggleEnabled,
isFinsightsToggleEnabled,
isIbmToggleEnabled,
Expand Down
5 changes: 5 additions & 0 deletions src/locales/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,11 @@ export default defineMessages({
description: 'No',
id: 'no',
},
noCurrentData: {
defaultMessage: 'No data available for {dateRange}. You are viewing data for the previous month.',
description: 'No data available for Jan 1-31. You are viewing data for the previous month.',
id: 'noCurrentData',
},
noDataForDate: {
defaultMessage: 'No data available for {dateRange}',
description: 'No data available for Jan 1-31',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,12 @@ class HistoricalTrendChartBase extends React.Component<HistoricalTrendChartProps
series.map((s, index) => {
return this.getChart(s, index);
})}
<ChartAxis label={xAxisLabel} style={chartStyles.xAxis} tickValues={[1, midDate, endDate]} />
<ChartAxis
fixAxisLabelHeight
label={xAxisLabel}
style={chartStyles.xAxis}
tickValues={[1, midDate, endDate]}
/>
<ChartAxis dependentAxis label={yAxisLabel} style={chartStyles.yAxis} />
</Chart>
</div>
Expand Down
21 changes: 13 additions & 8 deletions src/routes/components/export/exportModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ export interface ExportModalOwnProps {
showAggregateType?: boolean; // Monthly resolution filters are not valid with date range
showFormatType?: boolean; // Format type; CVS / JSON
showTimeScope?: boolean; // timeScope filters are not valid with date range
timeScopeValue?: number;
}

interface ExportModalStateProps {
isDetailsDateRangeToggleEnabled?: boolean;
isExportsToggleEnabled?: boolean;
}

Expand Down Expand Up @@ -89,16 +91,17 @@ export class ExportModalBase extends React.Component<ExportModalProps, ExportMod
protected defaultState: ExportModalState = {
error: undefined,
formatType: 'csv',
timeScope: 'current',
resolution: this.props.resolution || 'monthly',
timeScope: this.props.timeScopeValue === -2 ? 'previous' : 'current',
};
public state: ExportModalState = { ...this.defaultState };

constructor(stateProps, dispatchProps) {
super(stateProps, dispatchProps);
this.handleOnMonthChange = this.handleOnMonthChange.bind(this);
this.handleOnResolutionChange = this.handleOnResolutionChange.bind(this);
this.handleOnTypeChange = this.handleOnTypeChange.bind(this);
public componentDidUpdate(prevProps: ExportModalProps) {
const { timeScopeValue } = this.props;

if (timeScopeValue !== prevProps.timeScopeValue) {
this.setState({ timeScope: timeScopeValue === -2 ? 'previous' : 'current' });
}
}

// Reset default state upon close -- see https://issues.redhat.com/browse/COST-1134
Expand Down Expand Up @@ -145,6 +148,7 @@ export class ExportModalBase extends React.Component<ExportModalProps, ExportMod
groupBy,
intl,
isAllItems,
isDetailsDateRangeToggleEnabled,
isExportsToggleEnabled,
isTimeScoped,
items,
Expand All @@ -153,7 +157,7 @@ export class ExportModalBase extends React.Component<ExportModalProps, ExportMod
reportType,
showAggregateType = true,
showFormatType = true,
showTimeScope = true,
showTimeScope = isDetailsDateRangeToggleEnabled ? false : true,
} = this.props;
const { error, formatType, name, resolution, timeScope } = this.state;

Expand Down Expand Up @@ -207,7 +211,7 @@ export class ExportModalBase extends React.Component<ExportModalProps, ExportMod
isTimeScoped={isTimeScoped}
items={items}
key="confirm"
timeScope={showTimeScope ? timeScope : undefined}
timeScope={timeScope}
onClose={this.handleOnClose}
onError={this.handleOnError}
name={defaultName}
Expand Down Expand Up @@ -334,6 +338,7 @@ export class ExportModalBase extends React.Component<ExportModalProps, ExportMod

const mapStateToProps = createMapStateToProps<ExportModalOwnProps, unknown>(state => {
return {
isDetailsDateRangeToggleEnabled: FeatureToggleSelectors.selectIsDetailsDateRangeToggleEnabled(state),
isExportsToggleEnabled: FeatureToggleSelectors.selectIsExportsToggleEnabled(state),
};
});
Expand Down
4 changes: 3 additions & 1 deletion src/routes/components/groupBy/groupBy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { SelectWrapperOption } from 'routes/components/selectWrapper';
import { SelectWrapper } from 'routes/components/selectWrapper';
import type { PerspectiveType } from 'routes/explorer/explorerUtils';
import { getDateRangeFromQuery } from 'routes/utils/dateRange';
import { getTimeScopeValue } from 'routes/utils/timeScope';
import type { FetchStatus } from 'store/common';
import { createMapStateToProps } from 'store/common';
import { orgActions, orgSelectors } from 'store/orgs';
Expand Down Expand Up @@ -326,13 +327,14 @@ class GroupByBase extends React.Component<GroupByProps, GroupByState> {
const mapStateToProps = createMapStateToProps<GroupByOwnProps, GroupByStateProps>(
(state, { orgPathsType, router, resourcePathsType, tagPathsType }) => {
const queryFromRoute = parseQuery<Query>(router.location.search);
const timeScopeValue = getTimeScopeValue(queryFromRoute);

// Default to current month filter for details pages
let tagFilter: any = {
filter: {
resolution: 'monthly',
time_scope_units: 'month',
time_scope_value: -1,
time_scope_value: timeScopeValue !== undefined ? timeScopeValue : -1,
},
};

Expand Down
7 changes: 5 additions & 2 deletions src/routes/details/awsBreakdown/awsBreakdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { BreakdownBase } from 'routes/details/components/breakdown';
import { getGroupById, getGroupByOrgValue, getGroupByValue } from 'routes/utils/groupBy';
import { filterProviders } from 'routes/utils/providers';
import { getQueryState } from 'routes/utils/queryState';
import { getTimeScopeValue } from 'routes/utils/timeScope';
import { createMapStateToProps } from 'store/common';
import { FeatureToggleSelectors } from 'store/featureToggle';
import { providersQuery, providersSelectors } from 'store/providers';
Expand Down Expand Up @@ -56,6 +57,7 @@ const mapStateToProps = createMapStateToProps<AwsBreakdownOwnProps, BreakdownSta

const costType = getCostType();
const currency = getCurrency();
const timeScopeValue = getTimeScopeValue(queryState);

const query = { ...queryFromRoute };
const reportQuery = {
Expand All @@ -64,7 +66,7 @@ const mapStateToProps = createMapStateToProps<AwsBreakdownOwnProps, BreakdownSta
filter: {
resolution: 'monthly',
time_scope_units: 'month',
time_scope_value: -1,
time_scope_value: timeScopeValue !== undefined ? timeScopeValue : -1,
},
filter_by: {
// Add filters here to apply logical OR/AND
Expand Down Expand Up @@ -120,7 +122,7 @@ const mapStateToProps = createMapStateToProps<AwsBreakdownOwnProps, BreakdownSta
emptyStateTitle: intl.formatMessage(messages.awsDetailsTitle),
groupBy,
groupByValue,
historicalDataComponent: <HistoricalData costType={costType} currency={currency} />,
historicalDataComponent: <HistoricalData costType={costType} currency={currency} timeScopeValue={timeScopeValue} />,
instancesComponent:
groupBy === serviceKey && groupByValue === 'AmazonEC2' ? (
<Instances costType={costType} currency={currency} />
Expand All @@ -139,6 +141,7 @@ const mapStateToProps = createMapStateToProps<AwsBreakdownOwnProps, BreakdownSta
reportQueryString,
showCostType: true,
tagPathsType: TagPathsType.aws,
timeScopeValue,
title,
};
});
Expand Down
2 changes: 1 addition & 1 deletion src/routes/details/awsBreakdown/historicalData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { awsHistoricalDataSelectors } from 'store/breakdown/historicalData/awsHi
import { createMapStateToProps } from 'store/common';

interface AwsHistoricalDataOwnProps {
// TBD...
timeScopeValue?: number;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
4 changes: 3 additions & 1 deletion src/routes/details/awsBreakdown/instances/instances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type { ComputedReportItem } from 'routes/utils/computedReport/getComputed
import { getUnsortedComputedReportItems } from 'routes/utils/computedReport/getComputedReportItems';
import { getExcludeTagKey, getFilterByTagKey } from 'routes/utils/groupBy';
import * as queryUtils from 'routes/utils/query';
import { getTimeScopeValue } from 'routes/utils/timeScope';
import type { RootState } from 'store';
import { FetchStatus } from 'store/common';
import { reportActions, reportSelectors } from 'store/reports';
Expand Down Expand Up @@ -333,6 +334,7 @@ const useMapToProps = ({ costType, currency, query }): InstancesStateProps => {
const dispatch: ThunkDispatch<RootState, any, AnyAction> = useDispatch();
const queryFromRoute = useQueryFromRoute();
const queryState = useQueryState('details');
const timeScopeValue = getTimeScopeValue(queryState);

const reportQuery = {
cost_type: costType,
Expand All @@ -341,7 +343,7 @@ const useMapToProps = ({ costType, currency, query }): InstancesStateProps => {
...(query.filter || baseQuery.filter),
resolution: 'monthly',
time_scope_units: 'month',
time_scope_value: -1,
time_scope_value: timeScopeValue !== undefined ? timeScopeValue : -1,
},
filter_by: {
// Add filters here to apply logical OR/AND
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import { DataToolbar } from 'routes/components/dataToolbar';
import type { ComputedReportItem } from 'routes/utils/computedReport/getComputedReportItems';
import { isEqual } from 'routes/utils/equal';
import type { Filter } from 'routes/utils/filter';
import { getTimeScopeValue } from 'routes/utils/timeScope';
import type { FetchStatus } from 'store/common';
import { createMapStateToProps } from 'store/common';
import { tagActions, tagSelectors } from 'store/tags';
import { useQueryState } from 'utils/hooks';
import { accountKey, regionKey, tagKey } from 'utils/props';

interface InstancesToolbarOwnProps {
Expand Down Expand Up @@ -187,13 +189,16 @@ export class InstancesToolbarBase extends React.Component<InstancesToolbarProps,

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const mapStateToProps = createMapStateToProps<InstancesToolbarOwnProps, InstancesToolbarStateProps>((state, props) => {
const queryState = useQueryState('details');
const timeScopeValue = getTimeScopeValue(queryState);

// Note: Omitting key_only would help to share a single, cached request. Only the toolbar requires key values;
// however, for better server-side performance, we chose to use key_only here.
const baseQuery = {
filter: {
resolution: 'monthly',
time_scope_units: 'month',
time_scope_value: -1,
time_scope_value: timeScopeValue !== undefined ? timeScopeValue : -1,
},
key_only: true,
limit: 1000,
Expand Down
Loading

0 comments on commit e36dd8d

Please sign in to comment.