Skip to content

Commit 5075e69

Browse files
authored
change: [M3-8151] - Allow Linode Select options to be disabled on a per-option basis (#12585)
* Allow Linode Select options to be disabled on a per-option basis * Added changeset: Allow Linode Select options to be disabled on a per-option basis * Update LinodeSelect.tsx * PR feedback - @HanaXu
1 parent 62b4fe0 commit 5075e69

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/shared": Changed
3+
---
4+
5+
Allow Linode Select options to be disabled on a per-option basis ([#12585](https://github.com/linode/manager/pull/12585))

packages/shared/src/components/LinodeSelect/LinodeSelect.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,31 @@ describe('LinodeSelect', () => {
147147
).not.toBeInTheDocument();
148148
});
149149
});
150+
151+
test('should display disabled reason when a Linode is disabled', async () => {
152+
const linode = linodeFactory.build({ id: 123, label: 'My Linode' });
153+
const disabledReason = 'You do not have access to this Linode';
154+
155+
const screen = renderWithWrappers(
156+
<LinodeSelect
157+
disabledLinodes={{ 123: disabledReason }}
158+
multiple={false}
159+
onSelectionChange={vi.fn()}
160+
options={[linode]}
161+
value={null}
162+
/>,
163+
[QueryClientWrapper(), ThemeWrapper()],
164+
);
165+
166+
const input = screen.getByTestId(TEXTFIELD_ID);
167+
await userEvent.click(input);
168+
169+
await waitFor(() => {
170+
// Ensure the label is in the dropdown
171+
expect(screen.getByText('My Linode')).toBeInTheDocument();
172+
173+
// Ensure the disabled reason is displayed
174+
expect(screen.getByText(disabledReason)).toBeInTheDocument();
175+
});
176+
});
150177
});

packages/shared/src/components/LinodeSelect/LinodeSelect.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { useAllLinodesQuery } from '@linode/queries';
2-
import { Autocomplete, CloseIcon, CustomPopper } from '@linode/ui';
2+
import {
3+
Autocomplete,
4+
CloseIcon,
5+
CustomPopper,
6+
ListItemOption,
7+
Typography,
8+
} from '@linode/ui';
39
import { mapIdsToDevices } from '@linode/utilities';
410
import React from 'react';
511

@@ -16,6 +22,8 @@ interface LinodeSelectProps {
1622
clearable?: boolean;
1723
/** Disable editing the input value. */
1824
disabled?: boolean;
25+
/** Map of Linode IDs to be disabled with a reason. */
26+
disabledLinodes?: Record<number, string>;
1927
/** Hint displayed with error styling. */
2028
errorText?: string;
2129
/** Filter sent to the API when retrieving account Linodes. */
@@ -76,6 +84,7 @@ export const LinodeSelect = (
7684
checkIsOptionEqualToValue,
7785
clearable = true,
7886
disabled,
87+
disabledLinodes,
7988
errorText,
8089
filter,
8190
getOptionDisabled,
@@ -121,7 +130,9 @@ export const LinodeSelect = (
121130
disabled={disabled}
122131
disablePortal={true}
123132
errorText={error?.[0].reason ?? errorText}
124-
getOptionDisabled={getOptionDisabled}
133+
getOptionDisabled={(linode) =>
134+
!!disabledLinodes?.[linode.id] || getOptionDisabled?.(linode) || false
135+
}
125136
helperText={helperText}
126137
id={id}
127138
inputValue={inputValue}
@@ -153,6 +164,24 @@ export const LinodeSelect = (
153164
: 'Select a Linode'
154165
}
155166
PopperComponent={CustomPopper}
167+
renderOption={(props, linode, { selected }) => {
168+
const { key, ...restProps } = props; // Avoids passing `key` via props, which triggers React console warnings.
169+
return (
170+
<ListItemOption
171+
disabledOptions={
172+
disabledLinodes?.[linode.id]
173+
? { reason: disabledLinodes[linode.id] }
174+
: undefined
175+
}
176+
item={linode}
177+
key={key}
178+
props={restProps}
179+
selected={selected}
180+
>
181+
<Typography>{linode.label}</Typography>
182+
</ListItemOption>
183+
);
184+
}}
156185
slotProps={{ chip: { deleteIcon: <CloseIcon /> } }}
157186
sx={sx}
158187
value={

0 commit comments

Comments
 (0)