Skip to content

Commit

Permalink
feat(vrack-services): overview page
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas Pierre-charles <[email protected]>
  • Loading branch information
chipp972 committed Dec 1, 2023
1 parent a9c5295 commit 8dc5508
Show file tree
Hide file tree
Showing 27 changed files with 280 additions and 174 deletions.
1 change: 0 additions & 1 deletion packages/manager/apps/vrack-services/e2e/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable import/prefer-default-export */
import { config } from '../../../../../playwright-helpers/config';

export const urls = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Feature: Listing page

Scenario: User has an error when associating a vRack Services
Given User has a vRack Services in DRAFT state
Given User has an eligible vRacks to be associated to his vRack Services
Given The service to associate a vRack Services is KO
When User click on the link to associate a vRack
Then User sees a modal to select an eligible vRack
Expand All @@ -35,7 +36,7 @@ Feature: Listing page

Scenario Outline: User associate a vRack Services with no eligible vRack
Given User has a vRack Services in DRAFT state
Given User has no eligible vRack for this vRack Services
Given User has no eligible vRacks to be associated to his vRack Services
Given User has a vRack order <orderStatus>
When User click on the link to associate a vRack
Then User sees a modal to create a new vRack
Expand Down
18 changes: 11 additions & 7 deletions packages/manager/apps/vrack-services/e2e/given.step.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { Given } from '@cucumber/cucumber';
import { ICustomWorld } from '../../../../../playwright-helpers/custom-world';
import { ICustomWorld } from '@playwright-helpers/custom-world';
import { urls } from './constants';
import { ConfigParams } from '../mock/handlers';
import { OrderStatus, ProductStatus } from '../src/api';
import { OrderStatus, ProductStatus } from '@/api';
import { creationServiceError } from '../src/public/translations/vrack-services/create/Messages_fr_FR.json';
import { updateError } from '../src/public/translations/vrack-services/listing/Messages_fr_FR.json';

Given(
'User wants to create a vRack Services with name {string} and zone {word}',
Expand Down Expand Up @@ -59,6 +60,7 @@ Given('The service to edit a vRack Services is KO', function(
this: ICustomWorld<ConfigParams>,
) {
this.handlersConfig.updateKo = true;
this.testContext.errorMessage = updateError;
});

Given('The service to associate a vRack Services is KO', function(
Expand All @@ -67,11 +69,13 @@ Given('The service to associate a vRack Services is KO', function(
this.handlersConfig.associationKo = true;
});

Given('User has no eligible vRack for this vRack Services', function(
this: ICustomWorld<ConfigParams>,
) {
this.handlersConfig.nbEligibleVrackServices = 0;
});
Given(
'User has {word} eligible vRacks to be associated to his vRack Services',
function(this: ICustomWorld<ConfigParams>, anyEligibleVrack: 'an' | 'no') {
this.handlersConfig.nbEligibleVrackServices =
anyEligibleVrack === 'an' ? 5 : 0;
},
);

Given('User has a vRack order {word}', function(
this: ICustomWorld<ConfigParams>,
Expand Down
9 changes: 3 additions & 6 deletions packages/manager/apps/vrack-services/e2e/then.step.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { Then } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { ICustomWorld } from '../../../../../playwright-helpers/custom-world';
import {
modalDescriptionLine1,
creationServiceError,
} from '../src/public/translations/vrack-services/create/Messages_fr_FR.json';
import { ICustomWorld } from '@playwright-helpers/custom-world';
import { modalDescriptionLine1 } from '../src/public/translations/vrack-services/create/Messages_fr_FR.json';
import {
deliveringVrackServicesMessage,
emptyDataGridMessage,
Expand Down Expand Up @@ -44,7 +41,7 @@ Then('User sees {word} error message', async function(
anyErrorMessage: 'an' | 'no',
) {
const error = await this.page.locator('osds-message', {
hasText: creationServiceError,
hasText: this.testContext.errorMessage,
});
if (anyErrorMessage === 'an') {
await expect(error).toBeVisible();
Expand Down
4 changes: 2 additions & 2 deletions packages/manager/apps/vrack-services/e2e/when.step.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { When } from '@cucumber/cucumber';
import { ICustomWorld } from '../../../../../playwright-helpers/custom-world';
import { ICustomWorld } from '@playwright-helpers/custom-world';
import { vrackList } from '../mock/vrack/vrack';
import { ConfigParams, setupPlaywrightHandlers } from '../mock/handlers';
import { associateVrackButtonLabel } from '../src/public/translations/vrack-services/listing/Messages_fr_FR.json';
Expand All @@ -18,7 +18,7 @@ When('User navigates to vRack Services Listing page', async function(
this.handlersConfig.nbVs = this.handlersConfig.nbVs ?? 5;
this.testContext.initialUrl = urls.listing;
await setupPlaywrightHandlers(this);
await this.page.waitForURL(urls.listing, { waitUntil: 'load' });
await this.page.goto(urls.listing, { waitUntil: 'load' });
});

When('User clicks on the vRack Services configuration button', async function(
Expand Down
13 changes: 5 additions & 8 deletions packages/manager/apps/vrack-services/mock/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { BrowserContext } from '@playwright/test';
import { toPlaywrightMockHandler } from '../../../../../playwright-helpers/mock';
import { ICustomWorld } from '@playwright-helpers/custom-world';
import {
toMswHandlers,
Handler,
} from '../../../../super-components/_common/msw-helpers';
import { toPlaywrightMockHandler } from '../../../../../playwright-helpers/mock';
import {
getVrackServicesMocks,
GetVrackServicesMocksParams,
Expand Down Expand Up @@ -40,12 +40,9 @@ export const getConfig = (params: ConfigParams): Handler[] =>
export const getMswHandlers = (params: ConfigParams = {}) =>
toMswHandlers(getConfig(params));

export const setupPlaywrightHandlers = async (
context: BrowserContext,
params: ConfigParams = {},
) =>
export const setupPlaywrightHandlers = async (world: ICustomWorld) =>
Promise.all(
getConfig(params)
getConfig(world.handlersConfig)
.reverse()
.map(toPlaywrightMockHandler(context)),
.map(toPlaywrightMockHandler(world.context)),
);
6 changes: 3 additions & 3 deletions packages/manager/apps/vrack-services/mock/order/cart.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Handler } from '../../../../../super-components/_common/msw-helpers';
import { Cart, Item } from '../../src/api/order/order.type';
import { ResponseData } from '../../src/api/api.type';
import { Handler } from '@super-components/_common/msw-helpers';
import { Cart, Item } from '@/api/order/order.type';
import { ResponseData } from '@/api/api.type';

const getCart = (): Cart => {
const expire = new Date();
Expand Down
36 changes: 20 additions & 16 deletions packages/manager/apps/vrack-services/mock/order/order-details.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OrderData, OrderDetail } from '../../src/api/order';
import { Handler } from '../../../../../super-components/_common/msw-helpers';
import { Handler } from '@super-components/_common/msw-helpers';
import { OrderData, OrderDetail } from '@/api/order';

const orderList = [1, 2, 3];

Expand Down Expand Up @@ -130,14 +130,16 @@ export const getOrderDetailsMocks = ({
deliveringVrackServicesOrders,
}: GetOrderDetailsMocksParams): Handler[] => [
{
url: '/me/order',
response: orderList,
api: 'v6',
},
{
url: '/me/order/:id',
response: ({ params }: { params?: { id: number } }) =>
orderDataById[params?.id] || orderDataById[1],
url: '/me/order/:id/details/:detailid',
response: (data: { url: () => string; params: { detailid: string } }) => {
const detailid =
data.params?.detailid ||
data
.url()
.split('/')
.pop();
return orderDetailsById[Number(detailid)] || orderDetailsById[930000003];
},
api: 'v6',
},
{
Expand Down Expand Up @@ -171,12 +173,14 @@ export const getOrderDetailsMocks = ({
api: 'v6',
},
{
url: `/me/order/:id/details/:detailid`,
response: ({
params: { detailid },
}: {
params: { id: string; detailid: number };
}) => orderDetailsById[detailid] || orderDetailsById[930000003],
url: '/me/order/:id',
response: ({ params }: { params?: { id: number } }) =>
orderDataById[params?.id] || orderDataById[1],
api: 'v6',
},
{
url: '/me/order',
response: orderList,
api: 'v6',
},
];
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Handler } from '@super-components/_common/msw-helpers';
import { ResponseData, Status } from '../../src/api/api.type';
import { Handler } from '../../../../../super-components/_common/msw-helpers';
import {
VrackServices,
ProductStatus,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Handler } from '../../../../../super-components/_common/msw-helpers';
import { Handler } from '@super-components/_common/msw-helpers';

const zoneList = [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Handler } from '../../../../../super-components/_common/msw-helpers';
import { Handler } from '@super-components/_common/msw-helpers';
import { AllowedServicesResponse, Status, Task } from '../../src/api/api.type';
import { vrackServicesList } from '../vrack-services/vrack-services';

Expand Down
2 changes: 1 addition & 1 deletion packages/manager/apps/vrack-services/mock/vrack/vrack.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Handler } from '../../../../../super-components/_common/msw-helpers';
import { Handler } from '@super-components/_common/msw-helpers';

export const vrackList = [
'pn-00001',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const Breadcrumb: React.FC = () => {
});
}, [matches]);

const rootName = `${window.location.origin}/#/vrack-services`;
const rootName = `${window.location.origin}/#`;
const crumbs = [...categoryCrumbs, ...matchCrumbs];
const data = crumbs.map((crumb) => ({
label: crumb.label,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '@ovhcloud/ods-components/tabs/react';
import { ODS_TEXT_LEVEL, ODS_TEXT_SIZE } from '@ovhcloud/ods-components/text';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { useTranslation } from 'react-i18next';
import { PageLayout } from './PageLayout';

export type DashboardTabItemProps = {
Expand All @@ -21,6 +22,7 @@ export type DashboardLayoutProps = {
};

export const DashboardLayout: React.FC<DashboardLayoutProps> = ({ tabs }) => {
const { t } = useTranslation('vrack-services/dashboard');
const [activePanel, setActivePanel] = useState('');
const location = useLocation();
const navigate = useNavigate();
Expand All @@ -39,11 +41,20 @@ export const DashboardLayout: React.FC<DashboardLayoutProps> = ({ tabs }) => {
<PageLayout>
<div className="py-4">
<OsdsText
className="block mb-5"
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
size={ODS_TEXT_SIZE._600}
>
{location.pathname.split('/')[2]}
{t('title')}
</OsdsText>
<OsdsText
className="block mb-8"
level={ODS_TEXT_LEVEL.body}
color={ODS_THEME_COLOR_INTENT.default}
size={ODS_TEXT_SIZE._400}
>
{t('description')}
</OsdsText>
</div>
<OsdsTabs panel={activePanel}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import i18next from 'i18next';

export function breadcrumb() {
return i18next.t('vrack-services/dashboard:endpointsTabLabel');
}
const Endpoints: React.FC = () => {
return <h1>Tabs to custom</h1>;
};

export default Endpoints;
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* eslint-disable import/prefer-default-export */
import React from 'react';
import { useParams } from 'react-router-dom';
import { useEnvironment } from '@ovh-ux/manager-react-core-application';
import { OsdsTile } from '@ovhcloud/ods-components/tile/react';
import { useTranslation } from 'react-i18next';
import { useQuery } from '@tanstack/react-query';
import { OsdsText } from '@ovhcloud/ods-components/text/react';
import { OsdsDivider } from '@ovhcloud/ods-components/divider/react';
import { OsdsLink } from '@ovhcloud/ods-components/link/react';
import { ODS_TEXT_LEVEL, ODS_TEXT_SIZE } from '@ovhcloud/ods-components/text';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { ApiError, ErrorPage } from '@/components/Error';
import {
getVrackServicesResourceList,
getVrackServicesResourceListQueryKey,
} from '@/api';
import { formatDateString } from '@/utils/date';
import { ProductStatusCell } from '@/pages/index/components/VrackServicesDataGridCells';

type TileBlockProps = {
label: string;
};

const TileBlock: React.FC<React.PropsWithChildren<TileBlockProps>> = ({
label,
children,
}) => (
<div className="flex flex-col mb-3">
<OsdsText
className="mb-2"
size={ODS_TEXT_SIZE._200}
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
>
{label}
</OsdsText>
<OsdsText
className="mb-2"
size={ODS_TEXT_SIZE._400}
level={ODS_TEXT_LEVEL.body}
color={ODS_THEME_COLOR_INTENT.default}
>
{children}
</OsdsText>
<OsdsDivider separator />
</div>
);

export const OverviewTab: React.FC = () => {
const { t, i18n } = useTranslation('vrack-services/dashboard');
const environment = useEnvironment();
const { id } = useParams();
const urls = environment.getApplicationURLs();

const { data, isLoading, error } = useQuery({
queryKey: getVrackServicesResourceListQueryKey,
queryFn: () => getVrackServicesResourceList(),
});

if (error) {
return <ErrorPage error={error as ApiError} />;
}

const vrackServices = data?.data?.find((vs) => vs.id === id);

return (
<div className="grid xs:grid-cols-1 sm:grid-cols-2 md:grid-cols-3 py-6">
<div className="p-3">
<OsdsTile
className="w-full h-full flex-col"
loading={isLoading || undefined}
inline
rounded
>
<div className="flex flex-col w-full">
<OsdsText
size={ODS_TEXT_SIZE._400}
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
>
{t('tileTitle')}
</OsdsText>
<OsdsDivider separator />
<TileBlock label={t('displayName')}>
{vrackServices?.displayName || vrackServices?.id}
</TileBlock>
<TileBlock label={t('productStatus')}>
<ProductStatusCell
cellData={vrackServices?.currentState.productStatus}
rowData={vrackServices}
t={t}
/>
</TileBlock>
<TileBlock label={t('zone')}>
{t(vrackServices?.currentState.zone)}
</TileBlock>
<TileBlock label={t('vrackId')}>
{vrackServices?.currentState.vrackId ? (
<OsdsLink
href={`${urls.dedicated}vrack/${vrackServices.currentState.vrackId}`}
>
{vrackServices?.currentState.vrackId}
</OsdsLink>
) : (
'-'
)}
</TileBlock>
<TileBlock label={t('createdAt')}>
{formatDateString(vrackServices?.createdAt, i18n.language)}
</TileBlock>
</div>
</OsdsTile>
</div>
</div>
);
};
Loading

0 comments on commit 8dc5508

Please sign in to comment.