Skip to content

Commit f4e4396

Browse files
committed
feat(backup-agent): fix feedbacks
ref: #BKP-498 Signed-off-by: Vincent Bonmarchand <[email protected]>
1 parent 46d8a8d commit f4e4396

File tree

16 files changed

+236
-159
lines changed

16 files changed

+236
-159
lines changed

packages/manager/modules/backup-agent/src/components/CommonTiles/GeneralInformationsTile/GeneralInformationTile.component.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import { NAMESPACES } from "@ovh-ux/manager-common-translations";
44
import { OdsSkeleton } from "@ovhcloud/ods-components/react";
55
import { useLocationDetails } from "@/data/hooks/location/getLocationDetails";
66
import { ResourceStatusBadge } from "@/components/ResourceStatusBadge/ResourceStatusBadge.components";
7-
import {WithRegion} from "@/types/Utils.type";
8-
import {Resource} from "@/types/Resource.type";
7+
import { WithRegion } from "@/types/Utils.type";
8+
import { Resource } from "@/types/Resource.type";
99

1010
export type GeneralInformationTileProps<T extends { name: string }> = {
1111
resourceDetails?: Pick<Resource<T>, 'resourceStatus'> & { currentState: WithRegion<T> };
1212
isLoading: boolean;
1313
};
1414

15-
export function GeneralInformationTile<T extends { name: string }>({ resourceDetails, isLoading }: Readonly<GeneralInformationTileProps<T>>) {
15+
const GeneralInformationTile = <T extends { name: string }>({ resourceDetails, isLoading }: GeneralInformationTileProps<T>) => {
1616
const { t } = useTranslation([NAMESPACES.DASHBOARD, NAMESPACES.STATUS, NAMESPACES.REGION, 'dashboard']);
1717
const { data: locationData, isLoading: isLocationLoading } = useLocationDetails(resourceDetails?.currentState.region)
1818

@@ -50,3 +50,5 @@ export function GeneralInformationTile<T extends { name: string }>({ resourceDet
5050
</ManagerTile>
5151
);
5252
}
53+
54+
export default GeneralInformationTile;

packages/manager/modules/backup-agent/src/components/CommonTiles/GeneralInformationsTile/__tests__/GeneralInformationTile.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { render, screen } from "@testing-library/react"
33
import { NAMESPACES } from "@ovh-ux/manager-common-translations";
44
import { mockVaults } from "@/mocks/vaults/vaults";
55

6-
import { GeneralInformationTile } from "../GeneralInformationTile.component"
6+
import GeneralInformationTile from "../GeneralInformationTile.component"
77
import { mockLocations } from "@/mocks/location/locations";
88

99
const TILE_TITLE = `${NAMESPACES.DASHBOARD}:general_information`

packages/manager/modules/backup-agent/src/data/hooks/tenants/useVspcTenants.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,34 @@ export const useVSPCTenantsMocks = (): TUseVSPCTenantsResult =>
3535

3636
export const useInstalledBackupAgents = ({
3737
vspcTenants,
38-
}: {
39-
vspcTenants: AssociatedTenantVSPC[];
40-
} & Partial<Omit<DefinedInitialDataOptions<Resource<VSPCTenant>, unknown>, "queryKey" | "queryFn">>) => {
41-
const vspcTenantIds = useMemo(() => {
42-
if (!vspcTenants) return [];
43-
return vspcTenants.map((vspc) => vspc.id);
44-
}, [vspcTenants]);
45-
const vspcTenantQueries = useQueries({
38+
}: Readonly<{
39+
vspcTenants: readonly AssociatedTenantVSPC[];
40+
}> & Readonly<
41+
Partial<
42+
Omit<
43+
DefinedInitialDataOptions<Resource<VSPCTenant>, unknown>,
44+
"queryKey" | "queryFn"
45+
>
46+
>
47+
>) => {
48+
49+
const vspcTenantIds = vspcTenants?.map((v) => v.id) ?? [];
50+
51+
return useQueries({
4652
queries: vspcTenantIds.map((vspcTenantId) => ({
47-
queryKey: ['vspcTenantDetails', vspcTenantId],
53+
queryKey: ["vspcTenantDetails", vspcTenantId],
4854
queryFn: () => getVSPCTenantDetails(vspcTenantId),
4955
enabled: !!vspcTenantId,
5056
})),
5157
combine: (results) => {
5258
const tenants = results
53-
.map((r) => r.data)
54-
.filter((tenant): tenant is VSPCTenant => !!tenant);
55-
59+
.map((r) => r.data)
60+
.filter((t): t is VSPCTenant => Boolean(t));
61+
5662
return {
5763
installedBackupAgents: countBackupAgents(tenants),
5864
isLoading: results.some((q) => q.isLoading),
59-
}
65+
};
6066
},
6167
});
62-
return vspcTenantQueries;
63-
};
68+
};
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import { VSPCBackupAgent } from "@/types/VspcTenant.type";
2+
3+
export const mockBackupVspcAgents: VSPCBackupAgent[] = [
4+
{
5+
id: "agent-001",
6+
ip: ["192.168.1.10", "10.0.0.1"],
7+
name: "Backup Agent Alpha",
8+
type: "VMware",
9+
vspcTenant: "tenant-001",
10+
},
11+
{
12+
id: "agent-002",
13+
ip: ["192.168.1.11"],
14+
name: "Backup Agent Bravo",
15+
type: "HyperV",
16+
vspcTenant: "tenant-001",
17+
},
18+
{
19+
id: "agent-003",
20+
ip: ["172.16.5.20"],
21+
name: "Backup Agent Charlie",
22+
type: "Linux",
23+
vspcTenant: "tenant-002",
24+
},
25+
{
26+
id: "agent-004",
27+
ip: ["10.10.0.50", "10.10.0.51"],
28+
name: "Backup Agent Delta",
29+
type: "Windows",
30+
vspcTenant: "tenant-003",
31+
},
32+
{
33+
id: "agent-005",
34+
ip: ["192.168.50.7"],
35+
name: "Backup Agent Echo",
36+
type: "VMware",
37+
vspcTenant: "tenant-002",
38+
},
39+
{
40+
id: "agent-006",
41+
ip: ["10.10.10.10"],
42+
name: "Backup Agent Foxtrot",
43+
type: "HyperV",
44+
vspcTenant: "tenant-003",
45+
},
46+
{
47+
id: "agent-007",
48+
ip: ["172.16.5.25"],
49+
name: "Backup Agent Golf",
50+
type: "Linux",
51+
vspcTenant: "tenant-004",
52+
},
53+
{
54+
id: "agent-008",
55+
ip: ["192.168.100.12"],
56+
name: "Backup Agent Hotel",
57+
type: "Windows",
58+
vspcTenant: "tenant-004",
59+
},
60+
{
61+
id: "agent-009",
62+
ip: ["10.0.0.55"],
63+
name: "Backup Agent India",
64+
type: "VMware",
65+
vspcTenant: "tenant-005",
66+
},
67+
{
68+
id: "agent-010",
69+
ip: ["192.168.0.35"],
70+
name: "Backup Agent Juliett",
71+
type: "HyperV",
72+
vspcTenant: "tenant-005",
73+
},
74+
{
75+
id: "agent-011",
76+
ip: ["10.20.30.40"],
77+
name: "Backup Agent Kilo",
78+
type: "Linux",
79+
vspcTenant: "tenant-006",
80+
},
81+
{
82+
id: "agent-012",
83+
ip: ["172.16.10.15"],
84+
name: "Backup Agent Lima",
85+
type: "Windows",
86+
vspcTenant: "tenant-006",
87+
},
88+
{
89+
id: "agent-013",
90+
ip: ["192.168.3.30", "10.5.5.10"],
91+
name: "Backup Agent Mike",
92+
type: "VMware",
93+
vspcTenant: "tenant-007",
94+
},
95+
{
96+
id: "agent-014",
97+
ip: ["10.10.10.80"],
98+
name: "Backup Agent November",
99+
type: "HyperV",
100+
vspcTenant: "tenant-007",
101+
},
102+
{
103+
id: "agent-015",
104+
ip: ["192.168.0.90"],
105+
name: "Backup Agent Oscar",
106+
type: "Linux",
107+
vspcTenant: "tenant-008",
108+
},
109+
{
110+
id: "agent-016",
111+
ip: ["10.5.6.45"],
112+
name: "Backup Agent Papa",
113+
type: "Windows",
114+
vspcTenant: "tenant-008",
115+
},
116+
{
117+
id: "agent-017",
118+
ip: ["172.16.20.10"],
119+
name: "Backup Agent Quebec",
120+
type: "VMware",
121+
vspcTenant: "tenant-009",
122+
},
123+
{
124+
id: "agent-018",
125+
ip: ["192.168.25.5"],
126+
name: "Backup Agent Romeo",
127+
type: "HyperV",
128+
vspcTenant: "tenant-009",
129+
},
130+
{
131+
id: "agent-019",
132+
ip: ["10.1.2.3"],
133+
name: "Backup Agent Sierra",
134+
type: "Linux",
135+
vspcTenant: "tenant-010",
136+
},
137+
{
138+
id: "agent-020",
139+
ip: ["172.16.8.30"],
140+
name: "Backup Agent Tango",
141+
type: "Windows",
142+
vspcTenant: "tenant-010",
143+
},
144+
];
145+

packages/manager/modules/backup-agent/src/pages/services/dashboard/general-information/GeneralInformation.page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { BillingInformationsTileStandard } from "@ovh-ux/manager-billing-informations"
22

3-
import { GeneralInformationTenantTile } from "./_components/general-information-tenant-tile/GeneralInformationTenantTile.component";
43
import { useParams } from "react-router-dom";
54
import { useBackupTenantDetails } from "@/data/hooks/tenants/useBackupTenantDetails";
6-
import { SubscriptionTile } from "./_components/subscription-tile/SubscriptionTile.component";
5+
import SubscriptionTile from "./_components/subscription-tile/SubscriptionTile.component";
6+
import GeneralInformationTenantTile from "./_components/general-information-tenant-tile/GeneralInformationTenantTile.component";
77

88

99
export default function GeneralInformationPage() {

packages/manager/modules/backup-agent/src/pages/services/dashboard/general-information/_components/__tests__/GeneralInformationTenantTile.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { vi } from "vitest"
22
import { render, screen } from "@testing-library/react"
33

4-
import { GeneralInformationTenantTile } from "../general-information-tenant-tile/GeneralInformationTenantTile.component";
4+
import GeneralInformationTenantTile from "../general-information-tenant-tile/GeneralInformationTenantTile.component";
55
import { GeneralInformationTileProps } from "@/components/CommonTiles/GeneralInformationsTile/GeneralInformationTile.component";
66
import { TENANTS_MOCKS } from "@/mocks/tenant/tenants.mock";
77

@@ -14,7 +14,7 @@ vi.mock('@/data/hooks/tenants/useBackupTenantDetails', () => ({
1414
}))
1515

1616
vi.mock('@/components/CommonTiles/GeneralInformationsTile/GeneralInformationTile.component', () => ({
17-
GeneralInformationTile: <T extends { name: string }>({ resourceDetails, isLoading }: GeneralInformationTileProps<T>) => isLoading ? (<>is loading</>) : (<>{resourceDetails?.currentState.name}</>)
17+
default: <T extends { name: string }>({ resourceDetails, isLoading }: GeneralInformationTileProps<T>) => isLoading ? (<>is loading</>) : (<>{resourceDetails?.currentState.name}</>)
1818
}))
1919

2020
describe('GeneralInformationTenantTile', () => {
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,17 @@
11
import { vi } from "vitest"
2-
import { render, screen } from "@testing-library/react"
3-
import { NAMESPACES } from "@ovh-ux/manager-common-translations";
4-
import { mockVaults } from "@/mocks/vaults/vaults";
5-
6-
import { SubscriptionTile } from "../subscription-tile/SubscriptionTile.component"
7-
import { TENANTS_MOCKS } from "@/mocks/tenant/tenants.mock";
8-
import { MemoryRouter } from "react-router-dom";
9-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
10-
11-
const LABELS_VISIBLES = [`${NAMESPACES.BILLING}:subscription`]
12-
13-
14-
const { useBackupVaultDetailsMock } = vi.hoisted(() => ({
15-
useBackupVaultDetailsMock: vi.fn()
16-
}))
17-
18-
vi.mock('@/data/hooks/vaults/getVaultDetails', () => ({
19-
useBackupVaultDetails: useBackupVaultDetailsMock
20-
}))
21-
22-
const { useBackupTenantDetailsMock } = vi.hoisted(() => ({
23-
useBackupTenantDetailsMock: vi.fn()
24-
}))
25-
26-
vi.mock('@/data/hooks/tenants/useBackupTenantDetails', () => ({
27-
useBackupTenantDetails: useBackupTenantDetailsMock
28-
}))
29-
30-
vi.mock("react-i18next", () => ({
31-
useTranslation: vi.fn().mockReturnValue({
32-
t: vi.fn().mockImplementation((key: string) => key),
33-
})
34-
}))
2+
import { screen, waitFor } from "@testing-library/react"
353

4+
import { renderTest } from "@/test-utils/Test.utils";
5+
import { urls } from "@/routes/Routes.constants";
6+
import { labels } from "@/test-utils/i18ntest.utils";
367

378
describe('SubscriptionTile', () => {
389
it("Should render SubscriptionTile component", async () => {
39-
const queryClient = new QueryClient();
40-
useBackupVaultDetailsMock.mockReturnValue({ data: mockVaults[0]!, isLoading: false })
41-
useBackupTenantDetailsMock.mockReturnValue({ data: TENANTS_MOCKS[0]!, isLoading: false })
42-
const { container } = render(<QueryClientProvider client={queryClient}><MemoryRouter><SubscriptionTile tenantId={mockVaults[0]!.id} /></MemoryRouter></QueryClientProvider>)
10+
await renderTest({initialRoute: urls.dashboardTenants});
4311

44-
await expect(container).toBeAccessible();
12+
await waitFor(() => expect(screen.getByText(labels.billing.subscription)).toBeVisible(), {
13+
timeout: 5_000,
14+
});
4515

46-
LABELS_VISIBLES.forEach(label => {
47-
expect(screen.getByText(label)).toBeVisible()
48-
})
4916
})
5017
});
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
import GeneralInformationTile from '@/components/CommonTiles/GeneralInformationsTile/GeneralInformationTile.component';
12
import { useBackupTenantDetails } from '@/data/hooks/tenants/useBackupTenantDetails';
2-
import { GeneralInformationTile } from '@/components/CommonTiles/GeneralInformationsTile/GeneralInformationTile.component';
33

44
type GeneralInformationTenantTileProps = {
55
tenantId: string
66
};
77

8-
export function GeneralInformationTenantTile({ tenantId }: Readonly<GeneralInformationTenantTileProps>) {
8+
const GeneralInformationTenantTile = ({ tenantId }: GeneralInformationTenantTileProps) => {
99
const { data, isLoading } = useBackupTenantDetails({ tenantId })
1010

1111
return <GeneralInformationTile resourceDetails={data} isLoading={isLoading} />
1212
}
13+
14+
export default GeneralInformationTenantTile;

packages/manager/modules/backup-agent/src/pages/services/dashboard/general-information/_components/subscription-tile/SubscriptionTile.component.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,35 @@ import { NAMESPACES } from "@ovh-ux/manager-common-translations";
44
import { OdsSkeleton } from "@ovhcloud/ods-components/react";
55
import { BACKUP_AGENT_NAMESPACES } from "@/BackupAgent.translations";
66
import { useBackupTenantDetails } from '@/data/hooks/tenants/useBackupTenantDetails';
7-
import { InstalledAgents } from './_components/InstalledAgents.component';
8-
import { ConnectedVaults } from './_components/ConnectedVaults.component';
97
import { useHref } from 'react-router-dom';
108
import { urls } from '@/routes/Routes.constants';
9+
import { useTenantBackupStats } from './_hooks/useTenantBackupStats';
1110

1211
type SubscriptionTileProps = {
1312
tenantId?: string;
1413
};
1514

16-
export function SubscriptionTile({ tenantId }: Readonly<SubscriptionTileProps>) {
15+
const SubscriptionTile = ({ tenantId }: SubscriptionTileProps) => {
1716
const { t } = useTranslation([NAMESPACES.DASHBOARD, NAMESPACES.BILLING, BACKUP_AGENT_NAMESPACES.SERVICE_DASHBOARD]);
1817
const { data, isLoading } = useBackupTenantDetails({ tenantId: tenantId! })
1918
const billingHref = useHref(urls.listingBilling)
19+
const { connectedVaultsText, installedAgentsText } = useTenantBackupStats({ tenantDetails: data, vspcTenants: data?.currentState.vspcTenants });
20+
2021
return (
2122
<ManagerTile>
2223
<ManagerTile.Title>{t(`${NAMESPACES.BILLING}:subscription`)}</ManagerTile.Title>
2324
<ManagerTile.Divider />
2425
<ManagerTile.Item>
2526
<ManagerTile.Item.Label>{t(`${BACKUP_AGENT_NAMESPACES.SERVICE_DASHBOARD}:installed_agents`)}</ManagerTile.Item.Label>
2627
<ManagerTile.Item.Description>
27-
{isLoading ? <OdsSkeleton /> : <InstalledAgents vspcTenants={data?.currentState.vspcTenants} />}
28+
{isLoading ? <OdsSkeleton /> : installedAgentsText}
2829
</ManagerTile.Item.Description>
2930
</ManagerTile.Item>
3031
<ManagerTile.Divider />
3132
<ManagerTile.Item>
3233
<ManagerTile.Item.Label>{t(`${BACKUP_AGENT_NAMESPACES.SERVICE_DASHBOARD}:connected_vaults`)}</ManagerTile.Item.Label>
3334
<ManagerTile.Item.Description>
34-
{isLoading ? <OdsSkeleton /> : <ConnectedVaults tenantDetails={data} />}
35+
{isLoading ? <OdsSkeleton /> : connectedVaultsText}
3536
</ManagerTile.Item.Description>
3637
</ManagerTile.Item>
3738
<ManagerTile.Divider />
@@ -41,3 +42,5 @@ export function SubscriptionTile({ tenantId }: Readonly<SubscriptionTileProps>)
4142
</ManagerTile>
4243
);
4344
}
45+
46+
export default SubscriptionTile;

0 commit comments

Comments
 (0)