Skip to content

Commit 397f284

Browse files
committed
fix(mrc): add select all on visibility columns component
ref: #MANAGER-17733 Signed-off-by: Guillaume Hyenne <guillaume.hyenne@ovhcloud.com>
1 parent d4b05a2 commit 397f284

File tree

7 files changed

+124
-39
lines changed

7 files changed

+124
-39
lines changed

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ export interface FilterProps {
4343

4444
export interface DatagridTopbarProps {
4545
columnsVisibility?: ColumnsVisibility[];
46+
toggleAllColumnsVisible?: (a: boolean) => void;
47+
getIsAllColumnsVisible?: () => boolean;
48+
getIsSomeColumnsVisible?: () => boolean;
4649
filtersColumns?: ColumnFilter[];
4750
isSearchable?: boolean;
4851
filters?: FilterProps;
@@ -52,6 +55,9 @@ export interface DatagridTopbarProps {
5255

5356
export const DatagridTopbar = <T,>({
5457
columnsVisibility,
58+
toggleAllColumnsVisible,
59+
getIsAllColumnsVisible,
60+
getIsSomeColumnsVisible,
5561
filters,
5662
filtersColumns,
5763
isSearchable,
@@ -142,7 +148,12 @@ export const DatagridTopbar = <T,>({
142148
)}
143149
{hasVisibilityFeature && (
144150
<div className={filtersColumns?.length > 0 ? 'ml-[10px]' : ''}>
145-
<VisibilityManagement columnsVisibility={columnsVisibility} />
151+
<VisibilityManagement
152+
columnsVisibility={columnsVisibility}
153+
toggleAllColumnsVisible={toggleAllColumnsVisible}
154+
getIsAllColumnsVisible={getIsAllColumnsVisible}
155+
getIsSomeColumnsVisible={getIsSomeColumnsVisible}
156+
/>
146157
</div>
147158
)}
148159
</div>

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ describe('datagrid topbar', () => {
148148
onChange: () => null,
149149
},
150150
]}
151+
toggleAllColumnsVisible={() => null}
152+
getIsAllColumnsVisible={() => true}
153+
getIsSomeColumnsVisible={() => true}
151154
/>,
152155
);
153156

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ export const Datagrid = <T,>({
315315
<div>
316316
<DatagridTopbar
317317
columnsVisibility={columnsVisibility}
318+
toggleAllColumnsVisible={table.toggleAllColumnsVisible}
319+
getIsAllColumnsVisible={table.getIsAllColumnsVisible}
320+
getIsSomeColumnsVisible={table.getIsSomeColumnsVisible}
318321
filtersColumns={filtersColumns}
319322
isSearchable={!!searchColumns}
320323
filters={filters}

packages/manager-react-components/src/components/datagrid/translations/Messages_fr_FR.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
"common_pagination_load_more": "Charger plus",
88
"common_pagination_load_all": "Charger tout",
99
"common_empty_text_cell": "Aucun",
10-
"common_topbar_columns": "Colonnes"
10+
"common_topbar_columns": "Colonnes",
11+
"common_topbar_columns_select_all": "Sélectionner tout"
1112
}

packages/manager-react-components/src/components/datagrid/visibility/visibility-management.component.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,16 @@ export type ColumnsVisibility = {
2626

2727
export type ColumnsVisibilityProps = {
2828
columnsVisibility: ColumnsVisibility[];
29+
toggleAllColumnsVisible: (a: boolean) => void;
30+
getIsAllColumnsVisible: () => boolean;
31+
getIsSomeColumnsVisible: () => boolean;
2932
};
3033

3134
export function VisibilityManagement({
3235
columnsVisibility,
36+
toggleAllColumnsVisible,
37+
getIsAllColumnsVisible,
38+
getIsSomeColumnsVisible,
3339
}: Readonly<ColumnsVisibilityProps>) {
3440
const { t } = useTranslation('datagrid');
3541
const visibilityPopoverRef = useRef(null);
@@ -41,6 +47,9 @@ export function VisibilityManagement({
4147
column.isVisible(),
4248
).length;
4349

50+
const isAllColumnsVisible = getIsAllColumnsVisible();
51+
const isSomeColumnsVisible = getIsSomeColumnsVisible();
52+
4453
return (
4554
<>
4655
<OdsButton
@@ -63,9 +72,24 @@ export function VisibilityManagement({
6372
with-arrow
6473
>
6574
<div className="flex flex-col">
75+
<div className="pr-5 flex flex-row items-center gap-x-2">
76+
<OdsCheckbox
77+
name={'toggle-all-columns-visibility'}
78+
inputId={'toggle-all-columns-visibility'}
79+
isChecked={isAllColumnsVisible}
80+
onOdsChange={() => toggleAllColumnsVisible(!isAllColumnsVisible)}
81+
ariaLabel={t('common_topbar_columns_select_all')}
82+
isIndeterminate={!isAllColumnsVisible && isSomeColumnsVisible}
83+
/>
84+
<label slot="label" htmlFor={'toggle-all-columns-visibility'}>
85+
<OdsText preset={ODS_TEXT_PRESET.paragraph}>
86+
{t('common_topbar_columns_select_all')}
87+
</OdsText>
88+
</label>
89+
</div>
6690
{eligibleColumns.map((column) => (
6791
<OdsFormField key={column.id}>
68-
<div className="flex flex-row items-center gap-x-2">
92+
<div className="px-5 flex flex-row items-center gap-x-2">
6993
<OdsCheckbox
7094
name={column.id}
7195
inputId={column.id}

packages/manager-react-components/src/components/datagrid/visibility/visibility-management.spec.tsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ describe('visibility management button part', () => {
4545
onChange: () => null,
4646
},
4747
]}
48+
toggleAllColumnsVisible={() => null}
49+
getIsAllColumnsVisible={() => false}
50+
getIsSomeColumnsVisible={() => true}
4851
/>,
4952
);
5053

@@ -79,6 +82,9 @@ describe('visibility management button part', () => {
7982
onChange: () => null,
8083
},
8184
]}
85+
toggleAllColumnsVisible={() => null}
86+
getIsAllColumnsVisible={() => false}
87+
getIsSomeColumnsVisible={() => true}
8288
/>,
8389
);
8490

@@ -115,15 +121,18 @@ describe('visibility management dropdown part', () => {
115121
onChange: () => null,
116122
},
117123
]}
124+
toggleAllColumnsVisible={() => null}
125+
getIsAllColumnsVisible={() => true}
126+
getIsSomeColumnsVisible={() => true}
118127
/>,
119128
);
120129

121130
const checkboxElements = screen.queryAllByRole('checkbox');
122-
expect(checkboxElements[0]).toHaveProperty('checked', true);
123-
expect(checkboxElements[0]).toHaveProperty('disabled', false);
124-
125131
expect(checkboxElements[1]).toHaveProperty('checked', true);
126132
expect(checkboxElements[1]).toHaveProperty('disabled', false);
133+
134+
expect(checkboxElements[2]).toHaveProperty('checked', true);
135+
expect(checkboxElements[2]).toHaveProperty('disabled', false);
127136
});
128137

129138
it('should display visibility column disabled', async () => {
@@ -148,15 +157,18 @@ describe('visibility management dropdown part', () => {
148157
onChange,
149158
},
150159
]}
160+
toggleAllColumnsVisible={() => null}
161+
getIsAllColumnsVisible={() => false}
162+
getIsSomeColumnsVisible={() => true}
151163
/>,
152164
);
153165

154166
const checkboxElements = screen.queryAllByRole('checkbox');
155-
expect(checkboxElements[0]).toHaveProperty('checked', true);
156-
expect(checkboxElements[0]).toHaveProperty('disabled', true);
167+
expect(checkboxElements[1]).toHaveProperty('checked', true);
168+
expect(checkboxElements[1]).toHaveProperty('disabled', true);
157169

158-
expect(checkboxElements[1]).toHaveProperty('checked', false);
159-
expect(checkboxElements[1]).toHaveProperty('disabled', false);
170+
expect(checkboxElements[2]).toHaveProperty('checked', false);
171+
expect(checkboxElements[2]).toHaveProperty('disabled', false);
160172

161173
await act(() => fireEvent.click(checkboxElements[1]));
162174
expect(onChange).toHaveBeenCalled();

yarn.lock

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3320,7 +3320,7 @@
33203320
resolved "https://registry.yarnpkg.com/@cucumber/tag-expressions/-/tag-expressions-6.1.0.tgz#cb7af908bdb43669b7574c606f71fa707196e962"
33213321
integrity sha512-+3DwRumrCJG27AtzCIL37A/X+A/gSfxOPLg8pZaruh5SLumsTmpvilwroVWBT2fPzmno/tGXypeK5a7NHU4RzA==
33223322

3323-
"@datatr-ux/ods-tailwind-config@1.0.3":
3323+
"@datatr-ux/ods-tailwind-config@1.0.3", "@datatr-ux/ods-tailwind-config@^1.0.3":
33243324
version "1.0.3"
33253325
resolved "https://registry.yarnpkg.com/@datatr-ux/ods-tailwind-config/-/ods-tailwind-config-1.0.3.tgz#f4fe4cf803d9a1d5fbf2d5356b0cc58b0572f7a7"
33263326
integrity sha512-bQrlP+Qj1OC2oj/CmzqswG6D6j/RPvC21ZnRQrOuRLFo+CM+LhQi94EErf1abivJWeXMa2BZ/eID6s+iB4dPHw==
@@ -3332,6 +3332,11 @@
33323332
resolved "https://registry.yarnpkg.com/@datatr-ux/ovhcloud-types/-/ovhcloud-types-1.0.8.tgz#0e6a8359cc8a52389f65c1aebfae57261ec8215a"
33333333
integrity sha512-Fze56Qv4qkucB3/w5/bl1lNVCNKlOdSBKYDVLaHNCJhHs+JbHCtMR4Ki29dA+Lk8mti0r3g1fdMZ7Hb2YBZ8gA==
33343334

3335+
"@datatr-ux/ovhcloud-types@^1.0.11":
3336+
version "1.0.11"
3337+
resolved "https://registry.yarnpkg.com/@datatr-ux/ovhcloud-types/-/ovhcloud-types-1.0.11.tgz#bac1d9b460cc969a191967cd2b1d0858de713d78"
3338+
integrity sha512-NSqgUoIXKHxVRY5fnp5hV2kNQJxbX9/Om0naInG1tnztBvdkRuuhfzga9+ReYVqkktaSg/kb3CGZzyWi2tpvCg==
3339+
33353340
"@datatr-ux/uxlib@0.0.10":
33363341
version "0.0.10"
33373342
resolved "https://registry.yarnpkg.com/@datatr-ux/uxlib/-/uxlib-0.0.10.tgz#0a66c5d3ad49b0e1effa1cd02c36167e3ac6eef1"
@@ -3383,6 +3388,57 @@
33833388
tailwindcss-animate "^1.0.7"
33843389
vaul "^1.1.2"
33853390

3391+
"@datatr-ux/uxlib@^0.0.11-beta-8":
3392+
version "0.0.11-beta-8"
3393+
resolved "https://registry.yarnpkg.com/@datatr-ux/uxlib/-/uxlib-0.0.11-beta-8.tgz#e47edc3465d6ea8add18e81717193d3d543223c8"
3394+
integrity sha512-yAIPXaEVXtv0uxj7Z8A8GMIOUrtzuC06gG1Uw9proXtjCGSh6yBpnjaNIRhK0LWORtBQFxs9yVwy/M8CjkJkKw==
3395+
dependencies:
3396+
"@ovhcloud/ods-theme-blue-jeans" "^17.2.2"
3397+
"@ovhcloud/ods-themes" "^18.4.1"
3398+
"@radix-ui/react-accordion" "^1.2.2"
3399+
"@radix-ui/react-alert-dialog" "^1.1.4"
3400+
"@radix-ui/react-aspect-ratio" "^1.1.1"
3401+
"@radix-ui/react-avatar" "^1.1.2"
3402+
"@radix-ui/react-checkbox" "^1.1.3"
3403+
"@radix-ui/react-collapsible" "^1.1.2"
3404+
"@radix-ui/react-context-menu" "^2.2.4"
3405+
"@radix-ui/react-dialog" "^1.1.4"
3406+
"@radix-ui/react-dropdown-menu" "^2.1.4"
3407+
"@radix-ui/react-hover-card" "^1.1.4"
3408+
"@radix-ui/react-label" "^2.1.1"
3409+
"@radix-ui/react-menubar" "^1.1.4"
3410+
"@radix-ui/react-navigation-menu" "^1.2.3"
3411+
"@radix-ui/react-popover" "^1.1.4"
3412+
"@radix-ui/react-progress" "^1.1.1"
3413+
"@radix-ui/react-radio-group" "^1.2.2"
3414+
"@radix-ui/react-scroll-area" "^1.2.2"
3415+
"@radix-ui/react-select" "^2.1.4"
3416+
"@radix-ui/react-separator" "^1.1.1"
3417+
"@radix-ui/react-slider" "^1.2.2"
3418+
"@radix-ui/react-slot" "^1.1.1"
3419+
"@radix-ui/react-switch" "^1.1.2"
3420+
"@radix-ui/react-tabs" "^1.1.2"
3421+
"@radix-ui/react-toast" "^1.2.4"
3422+
"@radix-ui/react-toggle" "^1.1.1"
3423+
"@radix-ui/react-toggle-group" "^1.1.1"
3424+
"@radix-ui/react-tooltip" "^1.1.6"
3425+
class-variance-authority "^0.7.1"
3426+
clsx "^2.1.1"
3427+
cmdk "^1.0.0"
3428+
date-fns "^3.6.0"
3429+
embla-carousel-react "^8.5.1"
3430+
input-otp "^1.4.1"
3431+
lodash "^4.17.21"
3432+
lucide-react "^0.469.0"
3433+
next-themes "^0.4.4"
3434+
react-day-picker "^8.10.1"
3435+
react-resizable-panels "^2.1.7"
3436+
shiki "^3.2.1"
3437+
sonner "^1.7.1"
3438+
tailwind-merge "^2.6.0"
3439+
tailwindcss-animate "^1.0.7"
3440+
vaul "^1.1.2"
3441+
33863442
"@discoveryjs/json-ext@^0.5.0":
33873443
version "0.5.7"
33883444
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
@@ -27471,16 +27527,7 @@ string-length@^4.0.1:
2747127527
char-regex "^1.0.2"
2747227528
strip-ansi "^6.0.0"
2747327529

27474-
"string-width-cjs@npm:string-width@^4.2.0":
27475-
version "4.2.3"
27476-
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
27477-
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
27478-
dependencies:
27479-
emoji-regex "^8.0.0"
27480-
is-fullwidth-code-point "^3.0.0"
27481-
strip-ansi "^6.0.1"
27482-
27483-
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
27530+
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
2748427531
version "4.2.3"
2748527532
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
2748627533
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -27652,14 +27699,7 @@ stringify-entities@^4.0.0:
2765227699
character-entities-html4 "^2.0.0"
2765327700
character-entities-legacy "^3.0.0"
2765427701

27655-
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
27656-
version "6.0.1"
27657-
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
27658-
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
27659-
dependencies:
27660-
ansi-regex "^5.0.1"
27661-
27662-
strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1:
27702+
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1:
2766327703
version "6.0.1"
2766427704
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
2766527705
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -30525,7 +30565,7 @@ wordwrap@^1.0.0:
3052530565
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
3052630566
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
3052730567

30528-
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
30568+
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
3052930569
version "7.0.0"
3053030570
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
3053130571
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -30543,15 +30583,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0:
3054330583
string-width "^4.1.0"
3054430584
strip-ansi "^6.0.0"
3054530585

30546-
wrap-ansi@^7.0.0:
30547-
version "7.0.0"
30548-
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
30549-
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
30550-
dependencies:
30551-
ansi-styles "^4.0.0"
30552-
string-width "^4.1.0"
30553-
strip-ansi "^6.0.0"
30554-
3055530586
wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
3055630587
version "8.1.0"
3055730588
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"

0 commit comments

Comments
 (0)