Skip to content

Commit

Permalink
Fix tooltips messages in the graphs at DR Policy dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
TimothyAsirJeyasing committed Oct 3, 2023
1 parent 4f5269c commit 6280876
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 137 deletions.
20 changes: 10 additions & 10 deletions locales/en/plugin__odf-console.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,10 @@
"Loading Empty Page": "Loading Empty Page",
"You are not authorized to complete this action. See your cluster administrator for role-based access control information.": "You are not authorized to complete this action. See your cluster administrator for role-based access control information.",
"Not Authorized": "Not Authorized",
"<0>Note:</0> Alerts are deployed for both <2>ApplicationSet</2> and <5>Subscription</5> type applications.": "<0>Note:</0> Alerts are deployed for both <2>ApplicationSet</2> and <5>Subscription</5> type applications.",
"{{ currentStatus }} to {{ preferredCluster }}": "{{ currentStatus }} to {{ preferredCluster }}",
"{{ currentStatus }} to {{ failoverCluster }}": "{{ currentStatus }} to {{ failoverCluster }}",
"Unknown": "Unknown",
"Protected PVCs": "Protected PVCs",
"{{ pvcsWithIssueCount }} with issues": "{{ pvcsWithIssueCount }} with issues",
"Snapshot": "Snapshot",
"Last replicated on: {{ lastSyncTime }}": "Last replicated on: {{ lastSyncTime }}",
"Operator health": "Operator health",
Expand All @@ -80,29 +79,30 @@
"Operators health": "Operators health",
"Peer connection": "Peer connection",
" {{ peerConnectedCount }} Connected": " {{ peerConnectedCount }} Connected",
"Total applications": "Total applications",
"Total applications (ApplicationSet)": "Total applications (ApplicationSet)",
" {{ protectedAppSetsCount }} protected apps": " {{ protectedAppSetsCount }} protected apps",
" {{ appsWithIssues }} of {{ protectedAppSetsCount }} apps with issues": " {{ appsWithIssues }} of {{ protectedAppSetsCount }} apps with issues",
"PVCs": "PVCs",
" {{ protectedPVCsCount }} protected": " {{ protectedPVCsCount }} protected",
"Current value: ": "Current value: ",
"Max value: ": "Max value: ",
"Min value: ": "Min value: ",
"Utilization": "Utilization",
"Snapshots synced": "Snapshots synced",
"The y-axis shows the number of snapshots taken. It represents the rate of difference in snapshot creation count during a failover.": "The y-axis shows the number of snapshots taken. It represents the rate of difference in snapshot creation count during a failover.",
"Replication throughput": "Replication throughput",
"The y-axis shows the average throughput for syncing snapshot bytes from the primary to the secondary cluster.": "The y-axis shows the average throughput for syncing snapshot bytes from the primary to the secondary cluster.",
"Volume replication health": "Volume replication health",
"Block volumes snapshots synced": "Block volumes snapshots synced",
"<0>This graph provides an overview of the total number of snapshots synced across your clusters.</0><1>Note: Only inbound values are displayed exclusively for block volumes (ceph rbd) and include snapshots from all applications excluding apps using file volumes (cephfs).</1>": "<0>This graph provides an overview of the total number of snapshots synced across your clusters.</0><1>Note: Only inbound values are displayed exclusively for block volumes (ceph rbd) and include snapshots from all applications excluding apps using file volumes (cephfs).</1>",
"Block volumes replication throughput": "Block volumes replication throughput",
"<0>This graph provides an overview of the replication throughput for the cluster i.e, rate at which data is replicated within the cluster.</0><1>Note: Only inbound values are displayed exclusively for block volumes (ceph rbd) and include snapshots from all applications excluding apps using file volumes (cephfs).</1>": "<0>This graph provides an overview of the replication throughput for the cluster i.e, rate at which data is replicated within the cluster.</0><1>Note: Only inbound values are displayed exclusively for block volumes (ceph rbd) and include snapshots from all applications excluding apps using file volumes (cephfs).</1>",
"Volume replication health (ApplicationSet)": "Volume replication health (ApplicationSet)",
"Volumes": "Volumes",
"Cluster: {{clusterName}}": "Cluster: {{clusterName}}",
"Select a cluster": "Select a cluster",
"Application:": "Application:",
"Namespace: ": "Namespace: ",
"Protected PVCs (ApplicationSet)": "Protected PVCs (ApplicationSet)",
"{{ pvcsWithIssueCount }} with issues": "{{ pvcsWithIssueCount }} with issues",
"Operator status": "Operator status",
"Cluster operator": "Cluster operator",
"{{ healthy }} healthy": "{{ healthy }} healthy",
"{{ issues }} with issues": "{{ issues }} with issues",
"<0>Note:</0> The applications count displayed herein pertain exclusively to <2>ApplicationsSet</2> type applications.": "<0>Note:</0> The applications count displayed herein pertain exclusively to <2>ApplicationsSet</2> type applications.",
"{{ protected }} DR protected": "{{ protected }} DR protected",
"Systems": "Systems",
"Storage System status": "Storage System status",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import * as React from 'react';
import { filterDRAlerts } from '@odf/mco/utils';
import AlertsPanel from '@odf/shared/alert/AlertsPanel';
import useAlerts from '@odf/shared/monitoring/useAlert';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { Trans } from 'react-i18next';
import { Card, CardBody } from '@patternfly/react-core';
import AlertItem from './alert-item';
import './alert-card.scss';

export const AlertsCard: React.FC = () => {
const [alerts, loaded, loadError] = useAlerts();
const { t } = useCustomTranslation();

return (
<Card data-test="alerts-card">
Expand All @@ -16,6 +19,12 @@ export const AlertsCard: React.FC = () => {
alerts={alerts}
AlertItemComponent={AlertItem}
alertsFilter={filterDRAlerts}
titleToolTip={
<Trans t={t}>
<b>Note:</b> Alerts are deployed for both <b>ApplicationSet</b>{' '}
and <b>Subscription</b> type applications.
</Trans>
}
loaded={loaded}
loadError={loadError}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,19 @@
*/

import * as React from 'react';
import { VOLUME_REPLICATION_HEALTH, DRPC_STATUS } from '@odf/mco/constants';
import {
PlacementInfo,
ProtectedAppSetsMap,
ProtectedPVCData,
} from '@odf/mco/types';
import { getVolumeReplicationHealth, getDRStatus } from '@odf/mco/utils';
import { DRPC_STATUS } from '@odf/mco/constants';
import { PlacementInfo, ProtectedAppSetsMap } from '@odf/mco/types';
import { getDRStatus } from '@odf/mco/utils';
import { utcDateTimeFormatter } from '@odf/shared/details-page/datetime';
import {
fromNow,
getTimeDifferenceInSeconds,
} from '@odf/shared/details-page/datetime';
import { fromNow } from '@odf/shared/details-page/datetime';
import { URL_POLL_DEFAULT_DELAY } from '@odf/shared/hooks/custom-prometheus-poll/use-url-poll';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import {
PrometheusResponse,
StatusIconAndText,
} from '@openshift-console/dynamic-plugin-sdk';
import { TFunction } from 'i18next';
import { TextVariants, Text } from '@patternfly/react-core';
import { Text } from '@patternfly/react-core';
import { StatusText } from './common';

const getCurrentActivity = (
Expand Down Expand Up @@ -54,54 +47,6 @@ const getCurrentActivity = (
}
};

export const ProtectedPVCsSection: React.FC<ProtectedPVCsSectionProps> = ({
protectedPVCData,
selectedAppSet,
}) => {
const { t } = useCustomTranslation();
const clearSetIntervalId = React.useRef<NodeJS.Timeout>();
const [protectedPVC, setProtectedPVC] = React.useState([0, 0]);
const [protectedPVCsCount, pvcsWithIssueCount] = protectedPVC;

const updateProtectedPVC = React.useCallback(() => {
const placementInfo = selectedAppSet?.placementInfo?.[0];
const issueCount =
protectedPVCData?.reduce((acc, protectedPVCItem) => {
if (
protectedPVCItem?.drpcName === placementInfo?.drpcName &&
protectedPVCItem?.drpcNamespace === placementInfo?.drpcNamespace &&
getVolumeReplicationHealth(
getTimeDifferenceInSeconds(protectedPVCItem?.lastSyncTime),
protectedPVCItem?.schedulingInterval
)[0] !== VOLUME_REPLICATION_HEALTH.HEALTHY
)
return acc + 1;
else return acc;
}, 0) || 0;

setProtectedPVC([protectedPVCData?.length || 0, issueCount]);
}, [selectedAppSet, protectedPVCData, setProtectedPVC]);

React.useEffect(() => {
updateProtectedPVC();
clearSetIntervalId.current = setInterval(
updateProtectedPVC,
URL_POLL_DEFAULT_DELAY
);
return () => clearInterval(clearSetIntervalId.current);
}, [updateProtectedPVC]);

return (
<div className="mco-dashboard__contentColumn">
<Text component={TextVariants.h1}>{protectedPVCsCount}</Text>
<StatusText>{t('Protected PVCs')}</StatusText>
<Text className="text-muted">
{t('{{ pvcsWithIssueCount }} with issues', { pvcsWithIssueCount })}
</Text>
</div>
);
};

export const ActivitySection: React.FC<CommonProps> = ({ selectedAppSet }) => {
const { t } = useCustomTranslation();

Expand Down Expand Up @@ -162,11 +107,6 @@ export const SnapshotSection: React.FC<CommonProps> = ({ selectedAppSet }) => {
);
};

type ProtectedPVCsSectionProps = {
protectedPVCData: ProtectedPVCData[];
selectedAppSet: ProtectedAppSetsMap;
};

type CommonProps = {
selectedAppSet: ProtectedAppSetsMap;
lastSyncTimeData?: PrometheusResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ import {
CSVStatusesContext,
DRResourcesContext,
} from '../dr-dashboard-context';
import {
ProtectedPVCsSection,
ActivitySection,
SnapshotSection,
} from './argo-application-set';
import { ActivitySection, SnapshotSection } from './argo-application-set';
import {
HealthSection,
PeerConnectionSection,
ApplicationsSection,
PVCsSection,
// PVCsSection,
UtilizationCard,
} from './cluster';
import { ClusterAppDropdown, VolumeSummarySection } from './common';
import {
ClusterAppDropdown,
ProtectedPVCsSection,
VolumeSummarySection,
} from './common';
import './cluster-app-card.scss';

export const ClusterWiseCard: React.FC<ClusterWiseCardProps> = ({
Expand Down Expand Up @@ -97,9 +97,9 @@ export const ClusterWiseCard: React.FC<ClusterWiseCardProps> = ({
/>
</GridItem>
<GridItem lg={9} rowSpan={10} sm={12}>
<PVCsSection
<ProtectedPVCsSection
protectedPVCData={protectedPVCData}
clusterName={clusterName}
selectedAppSet={null}
/>
</GridItem>
<GridItem lg={12} rowSpan={8} sm={12}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,17 @@ import * as React from 'react';
import {
DRDashboard,
getRBDSnapshotUtilizationQuery,
getTotalPVCCountPerClusterQuery,
} from '@odf/mco/components/mco-dashboard/queries';
import {
ODR_CLUSTER_OPERATOR,
VOL_SYNC,
HUB_CLUSTER_NAME,
ACM_ENDPOINT,
VOLUME_REPLICATION_HEALTH,
OBJECT_NAMESPACE,
OBJECT_NAME,
MANAGED_CLUSTER_CONDITION_AVAILABLE,
} from '@odf/mco/constants';
import {
DrClusterAppsMap,
PlacementInfo,
ProtectedPVCData,
} from '@odf/mco/types';
import { DrClusterAppsMap, PlacementInfo } from '@odf/mco/types';
import {
getVolumeReplicationHealth,
getManagedClusterCondition,
Expand All @@ -33,7 +27,6 @@ import { healthStateMapping } from '@odf/shared/dashboards/status-card/states';
import { PrometheusUtilizationItem } from '@odf/shared/dashboards/utilization-card/prometheus-utilization-item';
import { CustomUtilizationSummaryProps } from '@odf/shared/dashboards/utilization-card/utilization-item';
import { FieldLevelHelp } from '@odf/shared/generic';
import { useCustomPrometheusPoll } from '@odf/shared/hooks/custom-prometheus-poll';
import Status, { StatusPopupSection } from '@odf/shared/popup/status-popup';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { humanizeDecimalBytesPerSec, humanizeNumber } from '@odf/shared/utils';
Expand All @@ -45,6 +38,7 @@ import {
Humanize,
} from '@openshift-console/dynamic-plugin-sdk';
import { UtilizationDurationDropdown } from '@openshift-console/dynamic-plugin-sdk-internal';
import { Trans } from 'react-i18next';
import { Flex, Text, TextVariants } from '@patternfly/react-core';
import { ConnectedIcon } from '@patternfly/react-icons';
import { StatusText } from './common';
Expand Down Expand Up @@ -212,7 +206,7 @@ export const ApplicationsSection: React.FC<ApplicationsSectionProps> = ({
return (
<div className="mco-dashboard__contentColumn">
<Text component={TextVariants.h1}>{totalAppSetsCount || 0}</Text>
<StatusText>{t('Total applications')}</StatusText>
<StatusText>{t('Total applications (ApplicationSet)')}</StatusText>
<Text className="text-muted mco-dashboard__statusText--margin">
{t(' {{ protectedAppSetsCount }} protected apps', {
protectedAppSetsCount,
Expand All @@ -228,33 +222,6 @@ export const ApplicationsSection: React.FC<ApplicationsSectionProps> = ({
);
};

export const PVCsSection: React.FC<PVCsSectionProps> = ({
protectedPVCData,
clusterName,
}) => {
const { t } = useCustomTranslation();
const [pvcsCount] = useCustomPrometheusPoll({
endpoint: 'api/v1/query' as any,
query: !!clusterName ? getTotalPVCCountPerClusterQuery(clusterName) : null,
basePath: ACM_ENDPOINT,
cluster: HUB_CLUSTER_NAME,
});
let totalPVCsCount = pvcsCount?.data?.result?.[0]?.value?.[1] || '0';
let protectedPVCsCount = protectedPVCData?.length || 0;

return (
<div className="mco-dashboard__contentColumn">
<Text component={TextVariants.h1}>{totalPVCsCount}</Text>
<StatusText>{t('PVCs')}</StatusText>
<Text className="text-muted">
{t(' {{ protectedPVCsCount }} protected', {
protectedPVCsCount,
})}
</Text>
</div>
);
};

const getDescription = (result: PrometheusResult, _index: number) =>
// Returning cluster name as a description
result.metric?.['cluster'] || '';
Expand Down Expand Up @@ -354,23 +321,44 @@ export const UtilizationCard: React.FC<UtilizationCardProps> = ({
<div className="mco-cluster-app__graph--margin-bottom">
<SnapshotUtilizationCard
clusters={peerClusters}
title={t('Snapshots synced')}
title={t('Block volumes snapshots synced')}
queryType={DRDashboard.RBD_SNAPSHOT_SNAPSHOTS}
titleToolTip={t(
'The y-axis shows the number of snapshots taken. It represents the rate of difference in snapshot creation count during a failover.'
)}
titleToolTip={
<Trans t={t}>
<p>
This graph provides an overview of the total number of snapshots
synced across your clusters.
</p>
<p className="text-muted mco-cluster-app__text--margin-top">
Note: Only inbound values are displayed exclusively for block
volumes (ceph rbd) and include snapshots from all applications
excluding apps using file volumes (cephfs).
</p>
</Trans>
}
humanizeValue={humanizeNumber}
/>
</div>
<div className="mco-cluster-app__graph--margin-bottom">
<SnapshotUtilizationCard
clusters={[clusterName]}
title={t('Replication throughput')}
title={t('Block volumes replication throughput')}
queryType={DRDashboard.RBD_SNAPSHOTS_SYNC_BYTES}
humanizeValue={humanizeDecimalBytesPerSec}
titleToolTip={t(
'The y-axis shows the average throughput for syncing snapshot bytes from the primary to the secondary cluster.'
)}
titleToolTip={
<Trans t={t}>
<p>
This graph provides an overview of the replication throughput
for the cluster i.e, rate at which data is replicated within the
cluster.
</p>
<p className="text-muted mco-cluster-app__text--margin-top">
Note: Only inbound values are displayed exclusively for block
volumes (ceph rbd) and include snapshots from all applications
excluding apps using file volumes (cephfs).
</p>
</Trans>
}
CustomUtilizationSummary={CustomUtilizationSummary}
/>
</div>
Expand Down Expand Up @@ -403,18 +391,13 @@ type ApplicationsSectionProps = {
lastSyncTimeData: PrometheusResponse;
};

type PVCsSectionProps = {
protectedPVCData: ProtectedPVCData[];
clusterName: string;
};

type SnapshotUtilizationCardProps = {
title: string;
queryType: DRDashboard;
humanizeValue: Humanize;
chartLabel?: string;
clusters?: string[];
titleToolTip: string;
titleToolTip: JSX.Element;
CustomUtilizationSummary?: React.FC<CustomUtilizationSummaryProps>;
};

Expand Down
Loading

0 comments on commit 6280876

Please sign in to comment.