Skip to content

Commit c394457

Browse files
chipp972Nicolas Pierre-charlesdarseneovh-cds
authored
feat(*): vrack-service ga (#11920)
Addition of new components on manager-components Vrack-services GA scope features Vrack-services refactoring to match defined folder structure ref: MANAGER-13968 Signed-off-by: Quentin Pavy <[email protected]> Co-authored-by: Nicolas Pierre-charles <[email protected]> Co-authored-by: David Arsène <[email protected]> Co-authored-by: CDS Translator Agent <[email protected]>
1 parent d44ad02 commit c394457

File tree

643 files changed

+8222
-4658
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

643 files changed

+8222
-4658
lines changed

packages/manager-components/jest.setup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import { TextEncoder, TextDecoder } from 'util';
33
import { Blob, File } from 'buffer';
4+
45
import 'element-internals-polyfill';
56

67
Object.assign(global, {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from 'react';
2+
import { ODS_TEXT_LEVEL, ODS_TEXT_SIZE } from '@ovhcloud/ods-components';
3+
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
4+
import {
5+
OsdsDivider,
6+
OsdsText,
7+
OsdsTile,
8+
} from '@ovhcloud/ods-components/react';
9+
import { TileBlock } from './tile-block.component';
10+
11+
export type DashboardTileBlockItem = {
12+
id: string;
13+
label: string;
14+
value: React.ReactNode;
15+
};
16+
17+
export type DashboardTileProps = {
18+
title?: string;
19+
items: DashboardTileBlockItem[];
20+
};
21+
22+
export const DashboardTile: React.FC<DashboardTileProps> = ({
23+
title,
24+
items,
25+
}) => (
26+
<OsdsTile className="w-full h-full flex-col" inline rounded>
27+
<div className="flex flex-col w-full">
28+
{title && (
29+
<>
30+
<OsdsText
31+
size={ODS_TEXT_SIZE._400}
32+
level={ODS_TEXT_LEVEL.heading}
33+
color={ODS_THEME_COLOR_INTENT.text}
34+
>
35+
{title}
36+
</OsdsText>
37+
<OsdsDivider separator />
38+
</>
39+
)}
40+
{items.map(({ id, label, value }) => (
41+
<TileBlock key={id} label={label}>
42+
{value}
43+
</TileBlock>
44+
))}
45+
</div>
46+
</OsdsTile>
47+
);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { waitFor, screen } from '@testing-library/react';
2+
import { render } from '../../../utils/test.provider';
3+
import { DashboardTile } from './dashboard-tile.component';
4+
import '@testing-library/jest-dom';
5+
6+
const testItem = {
7+
id: 'id',
8+
label: 'label',
9+
value: 'value',
10+
};
11+
12+
describe('Dashboard Tile component', () => {
13+
it('renders correctly', async () => {
14+
render(<DashboardTile title="Title" items={[testItem]} />);
15+
await waitFor(() => {
16+
expect(screen.getByText('Title')).toBeInTheDocument();
17+
expect(screen.getByText(testItem.value)).toBeInTheDocument();
18+
expect(screen.getByText(testItem.label)).toBeInTheDocument();
19+
expect(screen.queryByText(testItem.id)).not.toBeInTheDocument();
20+
});
21+
});
22+
23+
it('renders correctly without items', async () => {
24+
render(<DashboardTile title="Title" items={[]} />);
25+
await waitFor(() => {
26+
expect(screen.getByText('Title')).toBeInTheDocument();
27+
});
28+
});
29+
30+
it('renders correctly without title', async () => {
31+
render(<DashboardTile items={[testItem]} />);
32+
await waitFor(() => {
33+
expect(screen.getByText(testItem.value)).toBeInTheDocument();
34+
expect(screen.getByText(testItem.label)).toBeInTheDocument();
35+
expect(screen.queryByText(testItem.id)).not.toBeInTheDocument();
36+
});
37+
});
38+
});
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from 'react';
2+
import { Meta } from '@storybook/react';
3+
import { OsdsSkeleton } from '@ovhcloud/ods-components/react';
4+
import {
5+
DashboardTile,
6+
DashboardTileBlockItem,
7+
} from './dashboard-tile.component';
8+
import ActionMenu from '../../navigation/menus/action/action.component';
9+
10+
const actionItems = [
11+
{
12+
id: 1,
13+
href: 'https://ovhcloud.com',
14+
label: 'Action 1',
15+
},
16+
{
17+
id: 2,
18+
onClick: () => window.open('https://ovhcloud.com', '_blank', 'noopener'),
19+
label: 'Action 2',
20+
},
21+
];
22+
23+
const items: DashboardTileBlockItem[] = [
24+
{
25+
id: 'component-example',
26+
label: 'Component Example',
27+
value: <span>Test</span>,
28+
},
29+
{
30+
id: 'loading-component-example',
31+
label: 'Loading',
32+
value: <OsdsSkeleton />,
33+
},
34+
{
35+
id: 'text-directly',
36+
label: 'Text Directly',
37+
value: 'Text example',
38+
},
39+
{
40+
id: 'menu-example',
41+
label: 'Menu Example',
42+
value: (
43+
<div className="flex">
44+
<div className="mr-auto">Test value</div>
45+
<ActionMenu isCompact items={actionItems} />
46+
</div>
47+
),
48+
},
49+
];
50+
51+
export const WithTitle = () => <DashboardTile title="Title" items={items} />;
52+
53+
export const NoTitle = () => <DashboardTile items={items} />;
54+
55+
const meta: Meta = {
56+
title: 'Content/Dashboard Tile',
57+
component: DashboardTile,
58+
argTypes: {},
59+
args: {
60+
title: 'Titre',
61+
items,
62+
},
63+
};
64+
65+
export default meta;

packages/manager/apps/vrack-services/src/components/TileBlock.tsx renamed to packages/manager-components/src/components/content/dashboard-tile/tile-block.component.tsx

File renamed without changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
export * from './headers/headers.component';
22
export * from './price/price.component';
3+
export * from './dashboard-tile/dashboard-tile.component';
4+
export * from './dashboard-tile/tile-block.component';

packages/manager-components/src/components/datagrid/datagrid.component.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ export interface DatagridProps<T> {
7777
manualPagination?: boolean;
7878
/** If provided, this function will be called with an updaterFn when state.sorting changes. */
7979
/** setSorting?: OnChangeFn<SortingState>; */
80+
/** label displayed if there is no item in the datagrid */
81+
noResultLabel?: string;
8082
}
8183

8284
export const Datagrid = <T,>({
@@ -93,6 +95,7 @@ export const Datagrid = <T,>({
9395
onFetchNextPage,
9496
manualSorting = true,
9597
manualPagination = true,
98+
noResultLabel,
9699
}: DatagridProps<T>) => {
97100
const { t } = useTranslation('datagrid');
98101
const pageCount = pagination
@@ -233,7 +236,7 @@ export const Datagrid = <T,>({
233236
>
234237
<td className="text-center" colSpan={columns.length}>
235238
<DataGridTextCell>
236-
{t('common_pagination_no_results')}
239+
{noResultLabel ?? t('common_pagination_no_results')}
237240
</DataGridTextCell>
238241
</td>
239242
</tr>

packages/manager-components/src/components/datagrid/datagrid.spec.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
DatagridColumn,
77
PaginationState,
88
} from './datagrid.component';
9+
import DataGridTextCell from './text-cell.component';
910

1011
jest.mock('react-i18next', () => ({
1112
useTranslation: () => {
@@ -26,18 +27,25 @@ const sampleColumns = [
2627
},
2728
label: 'Name',
2829
},
30+
{
31+
id: 'another-column',
32+
label: 'test',
33+
cell: () => <DataGridTextCell />,
34+
},
2935
];
3036

3137
const DatagridTest = ({
3238
columns,
3339
items,
3440
pageIndex,
3541
className,
42+
noResultLabel,
3643
}: {
3744
columns: DatagridColumn<string>[];
3845
items: string[];
3946
pageIndex: number;
4047
className?: string;
48+
noResultLabel?: string;
4149
}) => {
4250
const [pagination, setPagination] = useState<PaginationState>({
4351
pageIndex,
@@ -55,6 +63,7 @@ const DatagridTest = ({
5563
onPaginationChange={setPagination}
5664
onSortChange={() => {}}
5765
className={className || ''}
66+
noResultLabel={noResultLabel}
5867
/>
5968
);
6069
};
@@ -171,6 +180,18 @@ describe('Paginated datagrid component', () => {
171180
expect(container.querySelectorAll('thead tr').length).toBe(1);
172181
expect(container.querySelectorAll('tbody tr').length).toBe(1);
173182
});
183+
184+
it('should display a custom message if there are no items and we pass a custom message', async () => {
185+
render(
186+
<DatagridTest
187+
columns={sampleColumns}
188+
items={[]}
189+
pageIndex={0}
190+
noResultLabel="Test no result"
191+
/>,
192+
);
193+
expect(screen.queryByText('Test no result')).not.toBeNull();
194+
});
174195
});
175196

176197
it('should disable overflow of table', async () => {

packages/manager-components/src/components/datagrid/text-cell.component.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
1-
import React, { ReactNode } from 'react';
1+
import React from 'react';
22
import { OsdsText } from '@ovhcloud/ods-components/react';
33
import {
44
ODS_THEME_COLOR_INTENT,
55
ODS_THEME_TYPOGRAPHY_LEVEL,
66
ODS_THEME_TYPOGRAPHY_SIZE,
77
} from '@ovhcloud/ods-common-theming';
8+
import { useTranslation } from 'react-i18next';
89

910
/** Simple datagrid cell text formatter applying ODS style */
10-
export function DataGridTextCell({ children }: { children: ReactNode }) {
11+
export function DataGridTextCell({
12+
children,
13+
}: React.PropsWithChildren<unknown>) {
14+
const { t } = useTranslation('datagrid');
1115
return (
1216
<OsdsText
1317
level={ODS_THEME_TYPOGRAPHY_LEVEL.body}
14-
size={ODS_THEME_TYPOGRAPHY_SIZE._400}
18+
size={
19+
children
20+
? ODS_THEME_TYPOGRAPHY_SIZE._600
21+
: ODS_THEME_TYPOGRAPHY_SIZE._300
22+
}
1523
color={ODS_THEME_COLOR_INTENT.text}
1624
>
17-
{children}
25+
{children ?? t('common_empty_text_cell')}
1826
</OsdsText>
1927
);
2028
}

packages/manager-components/src/components/datagrid/translations/Messages_de_DE.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
"common_pagination_no_results": "Keine Ergebnisse",
55
"common_clipboard_success_label": "Kopiert!",
66
"common_clipboard_error_label": "Fehler beim Kopieren.",
7-
"common_pagination_load_more": "Mehr laden"
7+
"common_pagination_load_more": "Mehr laden",
8+
"common_empty_text_cell": "Keine"
89
}

0 commit comments

Comments
 (0)