Skip to content

Commit 1384915

Browse files
fix(web-hosting): test condition in datagrid
ref: #MANAGER-867787 Signed-off-by: Alex Boungnaseng <[email protected]>
1 parent 0d9a3cc commit 1384915

File tree

19 files changed

+651
-234
lines changed

19 files changed

+651
-234
lines changed

packages/manager-tools/manager-pm/src/playbook/catalog/pnpm-private-modules.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
[
2+
{
3+
"turbo": "--filter @ovh-ux/muk",
4+
"pnpm": "packages/manager-ui-kit"
5+
},
26
{
37
"turbo": "--filter @ovh-ux/manager-react-core-application",
48
"pnpm": "packages/manager/core/application"

packages/manager-ui-kit/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"name": "@ovh-ux/muk",
3-
"version": "0.9.1",
3+
"version": "0.10.0",
4+
"private": true,
45
"description": "MUK:Manager UI Kit",
56
"homepage": "https://github.com/ovh/manager/blob/master/packages/manager-ui-kit/README.md",
67
"bugs": {
@@ -57,6 +58,7 @@
5758
"devDependencies": {
5859
"@mdx-js/react": "^3.0.1",
5960
"@ovh-ux/manager-common-translations": "^0.24.1",
61+
"@ovh-ux/manager-config": "^8.8.0",
6062
"@ovh-ux/manager-core-api": "^0.19.4",
6163
"@ovh-ux/manager-core-utils": "^0.4.9",
6264
"@ovh-ux/manager-react-shell-client": "^0.11.2",
@@ -103,6 +105,7 @@
103105
},
104106
"peerDependencies": {
105107
"@ovh-ux/manager-common-translations": "*",
108+
"@ovh-ux/manager-config": "^8.8.0",
106109
"@ovh-ux/manager-core-api": "^0.10.0",
107110
"@ovh-ux/manager-core-utils": "*",
108111
"@ovh-ux/manager-react-shell-client": "^0.11.2",
@@ -120,4 +123,4 @@
120123
"react-use": "^17.5.0",
121124
"zustand": "^4.5.5"
122125
}
123-
}
126+
}

packages/manager-ui-kit/src/components/datagrid/Datagrid.component.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ export const Datagrid = <T extends Record<string, unknown>>({
8181
const shouldRenderTopbar =
8282
topbar || hasSearchFeature || hasFilterFeature || hasColumnVisibilityFeature;
8383

84+
console.info('****************************************')
85+
console.info('datagrid component !!!!')
86+
console.info('rows : ',rows);
87+
8488
return (
8589
<>
8690
{shouldRenderTopbar && (

packages/manager-ui-kit/src/components/datagrid/table/table-body/TableBody.component.tsx

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Fragment, useCallback, useEffect, useMemo } from 'react';
1+
import { Fragment, useCallback, useEffect, useLayoutEffect, useMemo } from 'react';
22

33
import { flexRender } from '@tanstack/react-table';
44
import { useVirtualizer } from '@tanstack/react-virtual';
@@ -26,35 +26,56 @@ export const TableBody = <T,>({
2626
}: TableBodyProps<T>) => {
2727
const { rows } = rowModel;
2828
const previousRowsLength = usePrevious(rows?.length);
29-
const browserName = useMemo(() => getBrowserName(), []);
29+
const browserName = () => getBrowserName();
30+
console.info('****************************************')
31+
console.info('TableBody rows : ', rows);
32+
console.info('TableBody maxRowHeight : ', maxRowHeight);
33+
console.info('TableBody subComponentHeight : ', subComponentHeight);
34+
console.info('TableBody tableContainerRef : ', tableContainerRef);
35+
console.info('TableBody contentAlignLeft : ', contentAlignLeft);
36+
console.info('TableBody autoScroll : ', autoScroll);
37+
console.info('TableBody isLoading : ', isLoading);
38+
console.info('TableBody hideHeader : ', hideHeader);
39+
console.info('TableBody expanded : ', expanded);
3040
const rowVirtualizer = useVirtualizer({
3141
count: rows.length,
32-
estimateSize: useCallback(() => maxRowHeight, [maxRowHeight]),
33-
getScrollElement: () => tableContainerRef.current,
42+
estimateSize: () => maxRowHeight,
43+
getScrollElement: () => tableContainerRef?.current ?? null,
3444
measureElement:
3545
typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1
3646
? (el) => el?.getBoundingClientRect().height
3747
: undefined,
3848
overscan: 15,
3949
});
4050

51+
// Ensure virtualizer updates when ref becomes available after navigation
52+
// This is important because when navigating between pages, the component remounts
53+
// and the ref might not be attached immediately when useVirtualizer initializes
54+
useLayoutEffect(() => {
55+
// Check if ref is available and force re-measure
56+
if (tableContainerRef?.current && rows.length > 0) {
57+
// Small delay to ensure DOM is fully ready
58+
const timeoutId = setTimeout(() => {
59+
rowVirtualizer.measure();
60+
}, 0);
61+
return () => clearTimeout(timeoutId);
62+
}
63+
}, [rows.length, rowVirtualizer]); // Re-run when rows change or virtualizer updates
64+
4165
useEffect(() => {
4266
if (autoScroll && previousRowsLength !== undefined && rows?.length > previousRowsLength) {
4367
rowVirtualizer.scrollToIndex(previousRowsLength, { align: 'start' });
4468
}
4569
}, [rows?.length]);
4670

47-
const getOffset = useCallback(
48-
(index: number) => {
49-
let count = 0;
50-
for (let i = 0; i < index; i += 1) {
51-
if (rows[i]?.getIsExpanded()) count += 1;
52-
}
53-
return count * subComponentHeight;
54-
},
55-
[subComponentHeight],
56-
);
57-
71+
const getOffset = (index: number) => {
72+
let count = 0;
73+
for (let i = 0; i < index; i += 1) {
74+
if (rows[i]?.getIsExpanded()) count += 1;
75+
}
76+
return count * subComponentHeight;
77+
}
78+
5879
const totalHeight = useMemo(() => {
5980
const total = rows.reduce((acc, row) => {
6081
return acc + maxRowHeight + (row.getIsExpanded() ? subComponentHeight : 0);
@@ -66,6 +87,9 @@ export const TableBody = <T,>({
6687
return <EmptyRow />;
6788
}
6889

90+
console.info('TableBody rowVirtualizer.getVirtualItems() ', rowVirtualizer.getVirtualItems());
91+
console.info('TableBody rows : ', rows);
92+
6993
return (
7094
<tbody
7195
key={`table-body-${rows.length}`}
@@ -76,13 +100,29 @@ export const TableBody = <T,>({
76100
>
77101
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
78102
const row = rows[virtualRow?.index];
103+
console.info('+++++++++++++++++++++++++++++');
104+
console.info('rowVirtualizer.getVirtualItems() !');
105+
console.info('TableBody row : ', row);
106+
console.info('TableBody virtualRow : ', virtualRow);
79107
if (!row) return null;
80108
const offset = renderSubComponent ? getOffset(virtualRow?.index) : 0;
109+
console.info('TableBody offset : ', offset);
81110
const translateY = hideHeader
82111
? virtualRow.start + offset - virtualRow?.index + 1
83112
: virtualRow.start + offset - virtualRow?.index - 1;
84113
const width = !hideHeader ? '100%' : 'calc(100% - 1px)';
85114
const leftPosition = !hideHeader ? -1 : 0;
115+
console.info('TableBody leftPosition : ', leftPosition);
116+
console.info('TableBody translateY : ', translateY);
117+
console.info('TableBody width : ', width);
118+
console.info('TableBody maxRowHeight : ', maxRowHeight);
119+
console.info('TableBody browserName : ', browserName());
120+
console.info('TableBody hideHeader : ', hideHeader);
121+
console.info('TableBody contentAlignLeft : ', contentAlignLeft);
122+
console.info('TableBody autoScroll : ', autoScroll);
123+
console.info('TableBody isLoading : ', isLoading);
124+
console.info('TableBody hideHeader : ', hideHeader);
125+
console.info('TableBody expanded : ', expanded);
86126
return (
87127
<Fragment key={`table-body-tr-${row.id}`}>
88128
<tr
@@ -94,7 +134,7 @@ export const TableBody = <T,>({
94134
left: leftPosition,
95135
height: `${maxRowHeight}px`,
96136
transform:
97-
browserName === 'Safari' && !hideHeader
137+
browserName() === 'Safari' && !hideHeader
98138
? `translateY(${translateY + maxRowHeight}px)`
99139
: `translateY(${translateY}px)`,
100140
width,

packages/manager-ui-kit/src/components/error/Error.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const Error = ({
4040

4141
useEffect(() => {
4242
const env = shell?.environment?.getEnvironment();
43-
env?.then((response) => {
43+
env?.then((response: { applicationName: string }) => {
4444
const { applicationName } = response;
4545
const safeError = error ?? { status: 0 };
4646
const name = `errors::${getTrackingTypology(safeError)}::${applicationName}`;

packages/manager-wiki/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
},
1414
"dependencies": {
1515
"@ovh-ux/manager-core-api": "^0.19.4",
16-
"@ovh-ux/muk": "^0.9.1",
16+
"@ovh-ux/muk": "*",
1717
"@ovhcloud/ods-react": "^19.2.0",
1818
"@ovhcloud/ods-themes": "^19.2.0",
1919
"clsx": "^2.1.1",
@@ -74,4 +74,4 @@
7474
".storybook/public"
7575
]
7676
}
77-
}
77+
}

packages/manager/apps/web-hosting/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"name": "@ovh-ux/manager-web-hosting-app",
33
"version": "0.10.4",
4-
"private": true,
54
"description": "Manage web hostings in the OVH Control Panel",
65
"repository": {
76
"type": "git",
@@ -29,9 +28,9 @@
2928
"@ovh-ux/manager-react-core-application": "^0.13.4",
3029
"@ovh-ux/manager-react-shell-client": "^0.11.2",
3130
"@ovh-ux/manager-tailwind-config": "^0.6.1",
31+
"@ovh-ux/muk": "*",
3232
"@ovh-ux/request-tagger": "^0.5.9",
33-
"@ovh-ux/shell": "^4.9.2",
34-
"@ovh-ux/muk": "^0.9.0",
33+
"@ovh-ux/shell": "^4.9.2",
3534
"@ovhcloud/ods-react": "^19.2.1",
3635
"@ovhcloud/ods-themes": "^19.2.1",
3736
"@tanstack/react-query": "^5.51.21",

packages/manager/apps/web-hosting/src/pages/dashboard/multisite/cdn/component/OptionCache.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@ import {
3030
CdnQueryParameters,
3131
} from '@/data/types/product/cdn';
3232
import { subRoutes, urls } from '@/routes/routes.constants';
33-
import { getPrewarmQuotaPercentage, getQuotaUsage, hasOption } from '@/utils/cdn';
33+
import {
34+
getPrewarmQuotaPercentage,
35+
getQuotaUsage,
36+
hasOption,
37+
} from '@/utils/cdn';
3438

3539
import { ToggleCard } from './CdnToogleCard';
3640

3741
interface OptionCacheProps {
3842
controlValues: CdnFormValues;
39-
control: Control<CdnFormValues, unknown, CdnFormValues>;
43+
control: Control<CdnFormValues>;
4044
optionsData: CdnOption[];
4145
advancedPurge: boolean;
4246
}
@@ -53,7 +57,9 @@ export const OptionCache: React.FC<OptionCacheProps> = ({
5357

5458
return (
5559
<>
56-
<Text preset={TEXT_PRESET.heading3}>{t('cdn_shared_option_category_cache')}</Text>
60+
<Text preset={TEXT_PRESET.heading3}>
61+
{t('cdn_shared_option_category_cache')}
62+
</Text>
5763
{hasOption(optionsData, CdnOptionType.DEVMODE) && (
5864
<Controller
5965
name="devmode"
@@ -70,7 +76,9 @@ export const OptionCache: React.FC<OptionCacheProps> = ({
7076
/>
7177
)}
7278
<div className=" flex flex-col space-y-5">
73-
<Text preset={TEXT_PRESET.heading4}>{t('cdn_shared_option_advanced_flush_title')}</Text>
79+
<Text preset={TEXT_PRESET.heading4}>
80+
{t('cdn_shared_option_advanced_flush_title')}
81+
</Text>
7482
<Text>
7583
{t(
7684
`cdn_shared_option_advanced_flush_info${
@@ -149,9 +157,14 @@ export const OptionCache: React.FC<OptionCacheProps> = ({
149157
)}
150158
{controlValues?.prewarm && (
151159
<>
152-
<Text preset={TEXT_PRESET.heading6}>{t('cdn_shared_option_prewarm_quota')}</Text>
160+
<Text preset={TEXT_PRESET.heading6}>
161+
{t('cdn_shared_option_prewarm_quota')}
162+
</Text>
153163
<Text>{getQuotaUsage(optionsData)}</Text>
154-
<ProgressBar className="w-80" value={getPrewarmQuotaPercentage(optionsData)} />
164+
<ProgressBar
165+
className="w-80"
166+
value={getPrewarmQuotaPercentage(optionsData)}
167+
/>
155168
<Button
156169
variant={BUTTON_VARIANT.default}
157170
color={BUTTON_COLOR.primary}

packages/manager/apps/web-hosting/src/pages/dashboard/multisite/cdn/component/OptionPerformance.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@ import { ShellContext } from '@ovh-ux/manager-react-shell-client';
1616
import { Link, LinkType } from '@ovh-ux/muk';
1717

1818
import { SHARED_CDN_OPTIONS } from '@/constants';
19-
import { CdnFormValues, CdnOption, CdnOptionType } from '@/data/types/product/cdn';
19+
import {
20+
CdnFormValues,
21+
CdnOption,
22+
CdnOptionType,
23+
} from '@/data/types/product/cdn';
2024
import { hasOption } from '@/utils/cdn';
2125

2226
import { ToggleCard } from './CdnToogleCard';
2327

2428
interface OptionPerformanceProps {
2529
controlValues: CdnFormValues;
26-
control: Control<CdnFormValues, unknown, CdnFormValues>;
30+
control: Control<CdnFormValues>;
2731
optionsData: CdnOption[];
2832
}
2933

@@ -44,7 +48,9 @@ export const OptionPerformance: React.FC<OptionPerformanceProps> = ({
4448

4549
return (
4650
<>
47-
<Text preset={TEXT_PRESET.heading3}>{t('cdn_shared_option_category_performance')}</Text>
51+
<Text preset={TEXT_PRESET.heading3}>
52+
{t('cdn_shared_option_category_performance')}
53+
</Text>
4854
<ToggleCard
4955
title={t('cdn_shared_option_always_online_title')}
5056
info={t('cdn_shared_option_always_online_info')}
@@ -99,7 +105,11 @@ export const OptionPerformance: React.FC<OptionPerformanceProps> = ({
99105
toggleValue={!!field.value}
100106
onToggle={(detail) => field.onChange(detail.checked)}
101107
>
102-
<Link href={sharedOptionUrl} target="_blank" type={LinkType.external}>
108+
<Link
109+
href={sharedOptionUrl}
110+
target="_blank"
111+
type={LinkType.external}
112+
>
103113
{t('cdn_shared_option_prefetch_info_link')}
104114
</Link>
105115
</ToggleCard>
@@ -134,7 +144,9 @@ export const OptionPerformance: React.FC<OptionPerformanceProps> = ({
134144
onValueChange={(detail) => field.onChange(detail.value[0])}
135145
items={[
136146
{
137-
label: t('cdn_shared_option_mobile_redirect_strategy_still'),
147+
label: t(
148+
'cdn_shared_option_mobile_redirect_strategy_still',
149+
),
138150
value: SHARED_CDN_OPTIONS.MOBILE_REDIRECT.STILL_URL,
139151
},
140152
{

packages/manager/apps/web-hosting/src/pages/dashboard/multisite/cdn/component/OptionSecurity.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { ToggleCard } from './CdnToogleCard';
3232

3333
interface OptionSecurityProps {
3434
controlValues: CdnFormValues;
35-
control: Control<CdnFormValues, unknown, CdnFormValues>;
35+
control: Control<CdnFormValues>;
3636
optionsData: CdnOption[];
3737
}
3838

@@ -48,7 +48,9 @@ export const OptionSecurity: React.FC<OptionSecurityProps> = ({
4848
if (!hasSecurityOption(optionsData)) return null;
4949
return (
5050
<div className="flex flex-col space-y-6">
51-
<Text preset={TEXT_PRESET.heading3}>{t('cdn_shared_option_category_security')}</Text>
51+
<Text preset={TEXT_PRESET.heading3}>
52+
{t('cdn_shared_option_category_security')}
53+
</Text>
5254

5355
<Controller
5456
name="cors"
@@ -90,7 +92,11 @@ export const OptionSecurity: React.FC<OptionSecurityProps> = ({
9092
onToggle={(detail) => field.onChange(detail.checked)}
9193
>
9294
{field.value && (
93-
<Message color={MESSAGE_COLOR.warning} dismissible={false} className="w-full">
95+
<Message
96+
color={MESSAGE_COLOR.warning}
97+
dismissible={false}
98+
className="w-full"
99+
>
94100
{t('cdn_ssl_required_warning')}
95101
</Message>
96102
)}
@@ -138,7 +144,11 @@ export const OptionSecurity: React.FC<OptionSecurityProps> = ({
138144
onToggle={(detail) => field.onChange(detail.checked)}
139145
>
140146
{field.value && (
141-
<Message color={MESSAGE_COLOR.warning} dismissible={false} className="w-full">
147+
<Message
148+
color={MESSAGE_COLOR.warning}
149+
dismissible={false}
150+
className="w-full"
151+
>
142152
{t('cdn_ssl_required_warning')}
143153
</Message>
144154
)}

0 commit comments

Comments
 (0)