You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2021/08/24 11:20:42 UTC
[superset] branch master updated: chore: Changes the
AlertReportModal to use the new Select component (#16144)
This is an automated email from the ASF dual-hosted git repository.
michaelsmolina pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 1fc9318 chore: Changes the AlertReportModal to use the new Select component (#16144)
1fc9318 is described below
commit 1fc9318594d9677ed3dada50c65ce90c22361050
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Tue Aug 24 08:19:27 2021 -0300
chore: Changes the AlertReportModal to use the new Select component (#16144)
* chore: Changes the AlertReportModal to use the new Select component
* Gives time to close the select before changing the type
---
.../src/components/TimezoneSelector/index.tsx | 16 +-
.../src/views/CRUD/alert/AlertReportModal.test.jsx | 36 +-
.../src/views/CRUD/alert/AlertReportModal.tsx | 418 ++++++++++-----------
.../CRUD/alert/components/NotificationMethod.tsx | 20 +-
4 files changed, 226 insertions(+), 264 deletions(-)
diff --git a/superset-frontend/src/components/TimezoneSelector/index.tsx b/superset-frontend/src/components/TimezoneSelector/index.tsx
index 73c6f1f..48dd100 100644
--- a/superset-frontend/src/components/TimezoneSelector/index.tsx
+++ b/superset-frontend/src/components/TimezoneSelector/index.tsx
@@ -19,8 +19,8 @@
import React, { useEffect, useRef } from 'react';
import moment from 'moment-timezone';
-
-import { NativeGraySelect as Select } from 'src/components/Select';
+import { t } from '@superset-ui/core';
+import { Select } from 'src/components';
const DEFAULT_TIMEZONE = 'GMT Standard Time';
const MIN_SELECT_WIDTH = '400px';
@@ -92,12 +92,6 @@ const TIMEZONE_OPTIONS = TIMEZONES.sort(
offsets: getOffsetKey(zone.name),
}));
-const timezoneOptions = TIMEZONE_OPTIONS.map(option => (
- <Select.Option key={option.value} value={option.value}>
- {option.label}
- </Select.Option>
-));
-
const TimezoneSelector = ({ onTimezoneChange, timezone }: TimezoneProps) => {
const prevTimezone = useRef(timezone);
const matchTimezoneToOptions = (timezone: string) =>
@@ -120,12 +114,12 @@ const TimezoneSelector = ({ onTimezoneChange, timezone }: TimezoneProps) => {
return (
<Select
+ ariaLabel={t('Timezone')}
css={{ minWidth: MIN_SELECT_WIDTH }} // smallest size for current values
onChange={onTimezoneChange}
value={timezone || DEFAULT_TIMEZONE}
- >
- {timezoneOptions}
- </Select>
+ options={TIMEZONE_OPTIONS}
+ />
);
};
diff --git a/superset-frontend/src/views/CRUD/alert/AlertReportModal.test.jsx b/superset-frontend/src/views/CRUD/alert/AlertReportModal.test.jsx
index 8575a52..1509bff 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertReportModal.test.jsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertReportModal.test.jsx
@@ -24,7 +24,7 @@ import fetchMock from 'fetch-mock';
import { act } from 'react-dom/test-utils';
import AlertReportModal from 'src/views/CRUD/alert/AlertReportModal';
import Modal from 'src/components/Modal';
-import { AsyncSelect, NativeGraySelect as Select } from 'src/components/Select';
+import { Select } from 'src/components';
import { Switch } from 'src/components/Switch';
import { Radio } from 'src/components/Radio';
import TextAreaControl from 'src/explore/components/controls/TextAreaControl';
@@ -161,11 +161,15 @@ describe('AlertReportModal', () => {
};
const editWrapper = await mountAndWait(props);
- expect(editWrapper.find(AsyncSelect).at(1).props().value).toEqual({
+ expect(
+ editWrapper.find('[aria-label="Database"]').at(0).props().value,
+ ).toEqual({
value: 1,
label: 'test database',
});
- expect(editWrapper.find(AsyncSelect).at(2).props().value).toEqual({
+ expect(
+ editWrapper.find('[aria-label="Chart"]').at(0).props().value,
+ ).toEqual({
value: 1,
label: 'test chart',
});
@@ -176,21 +180,9 @@ describe('AlertReportModal', () => {
expect(wrapper.find('input[name="name"]')).toExist();
});
- it('renders three async select elements when in report mode', () => {
- expect(wrapper.find(AsyncSelect)).toExist();
- expect(wrapper.find(AsyncSelect)).toHaveLength(3);
- });
-
- it('renders four async select elements when in alert mode', async () => {
- const props = {
- ...mockedProps,
- isReport: false,
- };
-
- const addWrapper = await mountAndWait(props);
-
- expect(addWrapper.find(AsyncSelect)).toExist();
- expect(addWrapper.find(AsyncSelect)).toHaveLength(4);
+ it('renders five select elements when in report mode', () => {
+ expect(wrapper.find(Select)).toExist();
+ expect(wrapper.find(Select)).toHaveLength(5);
});
it('renders Switch element', () => {
@@ -226,12 +218,12 @@ describe('AlertReportModal', () => {
expect(input.props().value).toEqual('SELECT NaN');
});
- it('renders two select element when in report mode', () => {
+ it('renders five select element when in report mode', () => {
expect(wrapper.find(Select)).toExist();
- expect(wrapper.find(Select)).toHaveLength(2);
+ expect(wrapper.find(Select)).toHaveLength(5);
});
- it('renders three select elements when in alert mode', async () => {
+ it('renders seven select elements when in alert mode', async () => {
const props = {
...mockedProps,
isReport: false,
@@ -240,7 +232,7 @@ describe('AlertReportModal', () => {
const addWrapper = await mountAndWait(props);
expect(addWrapper.find(Select)).toExist();
- expect(addWrapper.find(Select)).toHaveLength(3);
+ expect(addWrapper.find(Select)).toHaveLength(7);
});
it('renders value input element when in alert mode', async () => {
diff --git a/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx b/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
index c39783e..a16662d 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
@@ -16,7 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React, { FunctionComponent, useState, useEffect } from 'react';
+import React, {
+ FunctionComponent,
+ useState,
+ useEffect,
+ useMemo,
+ useCallback,
+} from 'react';
import {
styled,
t,
@@ -32,7 +38,7 @@ import { Switch } from 'src/components/Switch';
import Modal from 'src/components/Modal';
import TimezoneSelector from 'src/components/TimezoneSelector';
import { Radio } from 'src/components/Radio';
-import { AsyncSelect, NativeGraySelect as Select } from 'src/components/Select';
+import { Select } from 'src/components';
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import Owner from 'src/types/Owner';
@@ -215,10 +221,6 @@ const StyledSectionContainer = styled.div`
}
}
}
-
- .hide-dropdown {
- display: none;
- }
`;
const StyledSectionTitle = styled.div`
@@ -248,7 +250,7 @@ const StyledSwitchContainer = styled.div`
`;
export const StyledInputContainer = styled.div`
- flex: 1 1 auto;
+ flex: 1;
margin: ${({ theme }) => theme.gridUnit * 2}px;
margin-top: 0;
@@ -284,9 +286,7 @@ export const StyledInputContainer = styled.div`
}
input,
- textarea,
- .Select,
- .ant-select {
+ textarea {
flex: 1 1 auto;
}
@@ -300,36 +300,24 @@ export const StyledInputContainer = styled.div`
}
input::placeholder,
- textarea::placeholder,
- .Select__placeholder {
+ textarea::placeholder {
color: ${({ theme }) => theme.colors.grayscale.light1};
}
textarea,
input[type='text'],
- input[type='number'],
- .Select__control,
- .ant-select-single .ant-select-selector {
- padding: ${({ theme }) => theme.gridUnit * 1.5}px
+ input[type='number'] {
+ padding: ${({ theme }) => theme.gridUnit}px
${({ theme }) => theme.gridUnit * 2}px;
border-style: none;
border: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
border-radius: ${({ theme }) => theme.gridUnit}px;
- .ant-select-selection-placeholder,
- .ant-select-selection-item {
- line-height: 24px;
- }
-
&[name='description'] {
flex: 1 1 auto;
}
}
- .Select__control {
- padding: 2px 0;
- }
-
.input-label {
margin-left: 10px;
}
@@ -581,94 +569,100 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
};
// Fetch data to populate form dropdowns
- const loadOwnerOptions = (input = '') => {
- const query = rison.encode({ filter: input, page_size: SELECT_PAGE_SIZE });
- return SupersetClient.get({
- endpoint: `/api/v1/report/related/owners?q=${query}`,
- }).then(
- response =>
- response.json.result.map((item: any) => ({
- value: item.value,
- label: item.text,
- })),
- badResponse => [],
- );
- };
-
- const loadSourceOptions = (input = '') => {
- const query = rison.encode({ filter: input, page_size: SELECT_PAGE_SIZE });
- return SupersetClient.get({
- endpoint: `/api/v1/report/related/database?q=${query}`,
- }).then(
- response => {
- const list = response.json.result.map((item: any) => ({
- value: item.value,
- label: item.text,
- }));
-
- setSourceOptions(list);
-
- // Find source if current alert has one set
- if (
- currentAlert &&
- currentAlert.database &&
- !currentAlert.database.label
- ) {
- updateAlertState('database', getSourceData());
- }
+ const loadOwnerOptions = useMemo(
+ () => (input = '', page: number, pageSize: number) => {
+ const query = rison.encode({ filter: input, page, page_size: pageSize });
+ return SupersetClient.get({
+ endpoint: `/api/v1/report/related/owners?q=${query}`,
+ }).then(response => ({
+ data: response.json.result.map(
+ (item: { value: number; text: string }) => ({
+ value: item.value,
+ label: item.text,
+ }),
+ ),
+ totalCount: response.json.count,
+ }));
+ },
+ [],
+ );
- return list;
- },
- badResponse => [],
- );
- };
+ const getSourceData = useCallback(
+ (db?: MetaObject) => {
+ const database = db || currentAlert?.database;
- const getSourceData = (db?: MetaObject) => {
- const database = db || currentAlert?.database;
+ if (!database || database.label) {
+ return null;
+ }
- if (!database || database.label) {
- return null;
- }
+ let result;
- let result;
+ // Cycle through source options to find the selected option
+ sourceOptions.forEach(source => {
+ if (source.value === database.value || source.value === database.id) {
+ result = source;
+ }
+ });
- // Cycle through source options to find the selected option
- sourceOptions.forEach(source => {
- if (source.value === database.value || source.value === database.id) {
- result = source;
- }
- });
+ return result;
+ },
+ [currentAlert?.database, sourceOptions],
+ );
- return result;
+ // Updating alert/report state
+ const updateAlertState = (name: string, value: any) => {
+ setCurrentAlert(currentAlertData => ({
+ ...currentAlertData,
+ [name]: value,
+ }));
};
- const loadDashboardOptions = (input = '') => {
- const query = rison.encode({ filter: input, page_size: SELECT_PAGE_SIZE });
- return SupersetClient.get({
- endpoint: `/api/v1/report/related/dashboard?q=${query}`,
- }).then(
- response => {
- const list = response.json.result.map((item: any) => ({
- value: item.value,
- label: item.text,
- }));
+ const loadSourceOptions = useMemo(
+ () => (input = '', page: number, pageSize: number) => {
+ const query = rison.encode({ filter: input, page, page_size: pageSize });
+ return SupersetClient.get({
+ endpoint: `/api/v1/report/related/database?q=${query}`,
+ }).then(response => {
+ const list = response.json.result.map(
+ (item: { value: number; text: string }) => ({
+ value: item.value,
+ label: item.text,
+ }),
+ );
+ setSourceOptions(list);
+ return { data: list, totalCount: response.json.count };
+ });
+ },
+ [],
+ );
+ const databaseLabel =
+ currentAlert && currentAlert.database && !currentAlert.database.label;
+ useEffect(() => {
+ // Find source if current alert has one set
+ if (databaseLabel) {
+ updateAlertState('database', getSourceData());
+ }
+ }, [databaseLabel, getSourceData]);
+
+ const loadDashboardOptions = useMemo(
+ () => (input = '', page: number, pageSize: number) => {
+ const query = rison.encode({ filter: input, page, page_size: pageSize });
+ return SupersetClient.get({
+ endpoint: `/api/v1/report/related/dashboard?q=${query}`,
+ }).then(response => {
+ const list = response.json.result.map(
+ (item: { value: number; text: string }) => ({
+ value: item.value,
+ label: item.text,
+ }),
+ );
setDashboardOptions(list);
-
- // Find source if current alert has one set
- if (
- currentAlert &&
- currentAlert.dashboard &&
- !currentAlert.dashboard.label
- ) {
- updateAlertState('dashboard', getDashboardData());
- }
-
- return list;
- },
- badResponse => [],
- );
- };
+ return { data: list, totalCount: response.json.count };
+ });
+ },
+ [],
+ );
const getDashboardData = (db?: MetaObject) => {
const dashboard = db || currentAlert?.dashboard;
@@ -689,62 +683,62 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
return result;
};
- const loadChartOptions = (input = '') => {
- const query = rison.encode({ filter: input, page_size: SELECT_PAGE_SIZE });
- return SupersetClient.get({
- endpoint: `/api/v1/report/related/chart?q=${query}`,
- }).then(
- response => {
- const list = response.json.result.map((item: any) => ({
- value: item.value,
- label: item.text,
- }));
+ const getChartData = useCallback(
+ (chartData?: MetaObject) => {
+ const chart = chartData || currentAlert?.chart;
- setChartOptions(list);
+ if (!chart || chart.label) {
+ return null;
+ }
- // Find source if current alert has one set
- if (currentAlert && currentAlert.chart && !currentAlert.chart.label) {
- updateAlertState('chart', getChartData());
- }
+ let result;
- return list;
- },
- badResponse => [],
- );
- };
+ // Cycle through chart options to find the selected option
+ chartOptions.forEach(slice => {
+ if (slice.value === chart.value || slice.value === chart.id) {
+ result = slice;
+ }
+ });
- const getChartData = (chartData?: MetaObject) => {
- const chart = chartData || currentAlert?.chart;
+ return result;
+ },
+ [chartOptions, currentAlert?.chart],
+ );
- if (!chart || chart.label) {
- return null;
+ const noChartLabel =
+ currentAlert && currentAlert.chart && !currentAlert.chart.label;
+ useEffect(() => {
+ // Find source if current alert has one set
+ if (noChartLabel) {
+ updateAlertState('chart', getChartData());
}
+ }, [getChartData, noChartLabel]);
+
+ const loadChartOptions = useMemo(
+ () => (input = '', page: number, pageSize: number) => {
+ const query = rison.encode({ filter: input, page, page_size: pageSize });
+ return SupersetClient.get({
+ endpoint: `/api/v1/report/related/chart?q=${query}`,
+ }).then(response => {
+ const list = response.json.result.map(
+ (item: { value: number; text: string }) => ({
+ value: item.value,
+ label: item.text,
+ }),
+ );
- let result;
-
- // Cycle through chart options to find the selected option
- chartOptions.forEach(slice => {
- if (slice.value === chart.value || slice.value === chart.id) {
- result = slice;
- }
- });
-
- return result;
- };
+ setChartOptions(list);
+ return { data: list, totalCount: response.json.count };
+ });
+ },
+ [],
+ );
const getChartVisualizationType = (chart: SelectValue) =>
SupersetClient.get({
endpoint: `/api/v1/chart/${chart.value}`,
}).then(response => setChartVizType(response.json.result.viz_type));
- // Updating alert/report state
- const updateAlertState = (name: string, value: any) => {
- setCurrentAlert(currentAlertData => ({
- ...currentAlertData,
- [name]: value,
- }));
- };
-
// Handle input/textarea updates
const onTextChange = (
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,
@@ -775,11 +769,11 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
updateAlertState('sql', value || '');
};
- const onOwnersChange = (value: Array<Owner>) => {
+ const onOwnersChange = (value: Array<SelectValue>) => {
updateAlertState('owners', value || []);
};
- const onSourceChange = (value: Array<Owner>) => {
+ const onSourceChange = (value: Array<SelectValue>) => {
updateAlertState('database', value || []);
};
@@ -832,8 +826,8 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
const onContentTypeChange = (event: any) => {
const { target } = event;
-
- setContentType(target.value);
+ // Gives time to close the select before changing the type
+ setTimeout(() => setContentType(target.value), 200);
};
const onFormatChange = (event: any) => {
@@ -1004,19 +998,6 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
setIsHidden(false);
}
- // Dropdown options
- const conditionOptions = CONDITIONS.map(condition => (
- <Select.Option key={condition.value} value={condition.value}>
- {condition.label}
- </Select.Option>
- ));
-
- const retentionOptions = RETENTION_OPTIONS.map(option => (
- <Select.Option key={option.value} value={option.value}>
- {option.label}
- </Select.Option>
- ));
-
return (
<StyledModal
className="no-content-padding"
@@ -1064,13 +1045,22 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
<span className="required">*</span>
</div>
<div data-test="owners-select" className="input-container">
- <AsyncSelect
+ <Select
+ ariaLabel={t('Owners')}
+ allowClear
+ // TODO Use default page size (100). To do that, the server
+ // needs to send the total number of results. Currently, the
+ // number of results is limited to SELECT_PAGE_SIZE
+ pageSize={SELECT_PAGE_SIZE}
name="owners"
- isMulti
- value={currentAlert ? currentAlert.owners : []}
- loadOptions={loadOwnerOptions}
- defaultOptions // load options on render
- cacheOptions
+ mode="multiple"
+ value={
+ (currentAlert?.owners as {
+ label: string;
+ value: number;
+ }[]) || []
+ }
+ options={loadOwnerOptions}
onChange={onOwnersChange}
/>
</div>
@@ -1107,19 +1097,23 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
<span className="required">*</span>
</div>
<div className="input-container">
- <AsyncSelect
+ <Select
+ ariaLabel={t('Database')}
+ // TODO Use default page size (100). To do that, the server
+ // needs to send the total number of results. Currently, the
+ // number of results is limited to SELECT_PAGE_SIZE
+ pageSize={SELECT_PAGE_SIZE}
name="source"
value={
- currentAlert?.database
+ currentAlert?.database?.label &&
+ currentAlert?.database?.value
? {
value: currentAlert.database.value,
label: currentAlert.database.label,
}
: undefined
}
- loadOptions={loadSourceOptions}
- defaultOptions // load options on render
- cacheOptions
+ options={loadSourceOptions}
onChange={onSourceChange}
/>
</div>
@@ -1148,21 +1142,14 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
</div>
<div className="input-container">
<Select
+ ariaLabel={t('Condition')}
onChange={onConditionChange}
placeholder="Condition"
- defaultValue={
- currentAlert
- ? currentAlert.validator_config_json?.op || undefined
- : undefined
- }
value={
- currentAlert
- ? currentAlert.validator_config_json?.op || undefined
- : undefined
+ currentAlert?.validator_config_json?.op || undefined
}
- >
- {conditionOptions}
- </Select>
+ options={CONDITIONS}
+ />
</div>
</StyledInputContainer>
<StyledInputContainer>
@@ -1224,21 +1211,12 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
</div>
<div className="input-container">
<Select
+ ariaLabel={t('Log retention')}
+ placeholder={t('Log retention')}
onChange={onLogRetentionChange}
- placeholder
- defaultValue={
- currentAlert
- ? currentAlert.log_retention || DEFAULT_RETENTION
- : DEFAULT_RETENTION
- }
- value={
- currentAlert
- ? currentAlert.log_retention || DEFAULT_RETENTION
- : DEFAULT_RETENTION
- }
- >
- {retentionOptions}
- </Select>
+ value={currentAlert?.log_retention || DEFAULT_RETENTION}
+ options={RETENTION_OPTIONS}
+ />
</div>
</StyledInputContainer>
<StyledInputContainer>
@@ -1284,44 +1262,46 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
<StyledRadio value="dashboard">{t('Dashboard')}</StyledRadio>
<StyledRadio value="chart">{t('Chart')}</StyledRadio>
</Radio.Group>
- <AsyncSelect
- className={
- contentType === 'chart'
- ? 'async-select'
- : 'hide-dropdown async-select'
- }
+ <Select
+ ariaLabel={t('Chart')}
+ css={{
+ display: contentType === 'chart' ? 'inline' : 'none',
+ }}
+ // TODO Use default page size (100). To do that, the server
+ // needs to send the total number of results. Currently, the
+ // number of results is limited to SELECT_PAGE_SIZE
+ pageSize={SELECT_PAGE_SIZE}
name="chart"
value={
- currentAlert && currentAlert.chart
+ currentAlert?.chart?.label && currentAlert?.chart?.value
? {
value: currentAlert.chart.value,
label: currentAlert.chart.label,
}
: undefined
}
- loadOptions={loadChartOptions}
- defaultOptions // load options on render
- cacheOptions
+ options={loadChartOptions}
onChange={onChartChange}
/>
- <AsyncSelect
- className={
- contentType === 'dashboard'
- ? 'async-select'
- : 'hide-dropdown async-select'
- }
+ <Select
+ ariaLabel={t('Dashboard')}
+ css={{
+ display: contentType === 'dashboard' ? 'inline' : 'none',
+ }}
+ // TODO Use default page size (100). To do that, the server
+ // needs to send the total number of results. Currently, the
+ // number of results is limited to SELECT_PAGE_SIZE
+ pageSize={SELECT_PAGE_SIZE}
name="dashboard"
value={
- currentAlert && currentAlert.dashboard
+ currentAlert?.dashboard?.label && currentAlert?.dashboard?.value
? {
value: currentAlert.dashboard.value,
label: currentAlert.dashboard.label,
}
: undefined
}
- loadOptions={loadDashboardOptions}
- defaultOptions // load options on render
- cacheOptions
+ options={loadDashboardOptions}
onChange={onDashboardChange}
/>
{formatOptionEnabled && (
diff --git a/superset-frontend/src/views/CRUD/alert/components/NotificationMethod.tsx b/superset-frontend/src/views/CRUD/alert/components/NotificationMethod.tsx
index 0e4b1b7..905e85e 100644
--- a/superset-frontend/src/views/CRUD/alert/components/NotificationMethod.tsx
+++ b/superset-frontend/src/views/CRUD/alert/components/NotificationMethod.tsx
@@ -18,7 +18,7 @@
*/
import React, { FunctionComponent, useState } from 'react';
import { styled, t, useTheme } from '@superset-ui/core';
-import { NativeGraySelect as Select } from 'src/components/Select';
+import { Select } from 'src/components';
import Icons from 'src/components/Icons';
import { StyledInputContainer } from '../AlertReportModal';
@@ -116,26 +116,22 @@ export const NotificationMethod: FunctionComponent<NotificationMethodProps> = ({
setRecipientValue(recipients);
}
- const methodOptions = (options || []).map((method: NotificationMethod) => (
- <Select.Option key={method} value={method}>
- {t(method)}
- </Select.Option>
- ));
-
return (
<StyledNotificationMethod>
<div className="inline-container">
<StyledInputContainer>
<div className="input-container">
<Select
+ ariaLabel={t('Delivery method')}
data-test="select-delivery-method"
onChange={onMethodChange}
- placeholder="Select Delivery Method"
- defaultValue={method}
+ placeholder={t('Select Delivery Method')}
+ options={(options || []).map((method: NotificationMethod) => ({
+ label: method,
+ value: method,
+ }))}
value={method}
- >
- {methodOptions}
- </Select>
+ />
</div>
</StyledInputContainer>
{method !== undefined && !!onRemove ? (