Skip to content

Commit 175a16b

Browse files
committed
Move repository combobox to its own component
1 parent 39e9e2e commit 175a16b

File tree

2 files changed

+93
-82
lines changed

2 files changed

+93
-82
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
import React, { useEffect, useRef } from 'react';
8+
import { EuiComboBoxOptionOption } from '@elastic/eui';
9+
10+
import { ComboBoxField, FieldHook } from '../../../../../../../shared_imports';
11+
import { useGlobalFields } from '../../../../form';
12+
13+
interface PropsRepositoryCombobox {
14+
field: FieldHook;
15+
isLoading: boolean;
16+
repos: string[];
17+
noSuggestions: boolean;
18+
globalRepository: string;
19+
}
20+
21+
export const RepositoryComboBoxField = ({
22+
field,
23+
isLoading,
24+
repos,
25+
noSuggestions,
26+
globalRepository,
27+
}: PropsRepositoryCombobox) => {
28+
const isMounted = useRef(false);
29+
const { setValue } = field;
30+
const {
31+
searchableSnapshotRepo: { setValue: setSearchableSnapshotRepository },
32+
} = useGlobalFields();
33+
34+
useEffect(() => {
35+
// We keep our phase searchable action field in sync
36+
// with the default repository field declared globally for the policy
37+
if (isMounted.current) {
38+
setValue(Boolean(globalRepository.trim()) ? [globalRepository] : []);
39+
}
40+
isMounted.current = true;
41+
}, [setValue, globalRepository]);
42+
43+
return (
44+
<ComboBoxField
45+
field={field}
46+
fullWidth={false}
47+
euiFieldProps={{
48+
'data-test-subj': 'searchableSnapshotCombobox',
49+
options: repos.map((repo) => ({ label: repo, value: repo })),
50+
singleSelection: { asPlainText: true },
51+
isLoading,
52+
noSuggestions,
53+
onCreateOption: (newOption: string) => {
54+
setSearchableSnapshotRepository(newOption);
55+
},
56+
onChange: (options: EuiComboBoxOptionOption[]) => {
57+
if (options.length > 0) {
58+
setSearchableSnapshotRepository(options[0].label);
59+
} else {
60+
setSearchableSnapshotRepository('');
61+
}
62+
},
63+
}}
64+
/>
65+
);
66+
};

x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx

Lines changed: 27 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,59 +5,40 @@
55
* 2.0.
66
*/
77

8+
import React, { FunctionComponent, useState, useEffect } from 'react';
89
import { i18n } from '@kbn/i18n';
910
import { get } from 'lodash';
10-
import React, { FunctionComponent, useState, useEffect } from 'react';
1111
import { FormattedMessage } from '@kbn/i18n/react';
12-
import {
13-
EuiComboBoxOptionOption,
14-
EuiTextColor,
15-
EuiSpacer,
16-
EuiCallOut,
17-
EuiLink,
18-
} from '@elastic/eui';
19-
20-
import {
21-
ComboBoxField,
22-
useKibana,
23-
fieldValidators,
24-
useFormData,
25-
} from '../../../../../../../shared_imports';
12+
import { EuiTextColor, EuiSpacer, EuiCallOut, EuiLink } from '@elastic/eui';
2613

14+
import { useKibana, useFormData } from '../../../../../../../shared_imports';
2715
import { useEditPolicyContext } from '../../../../edit_policy_context';
28-
import { useConfigurationIssues, UseField } from '../../../../form';
29-
30-
import { i18nTexts } from '../../../../i18n_texts';
31-
16+
import { useConfiguration, UseField } from '../../../../form';
3217
import { FieldLoadingError, DescribedFormRow, LearnMoreLink } from '../../../';
33-
3418
import { SearchableSnapshotDataProvider } from './searchable_snapshot_data_provider';
19+
import { RepositoryComboBoxField } from './repository_combobox_field';
3520

3621
import './_searchable_snapshot_field.scss';
3722

38-
const { emptyField } = fieldValidators;
39-
4023
export interface Props {
4124
phase: 'hot' | 'cold';
4225
}
4326

44-
/**
45-
* This repository is provisioned by Elastic Cloud and will always
46-
* exist as a "managed" repository.
47-
*/
48-
const CLOUD_DEFAULT_REPO = 'found-snapshots';
49-
5027
export const SearchableSnapshotField: FunctionComponent<Props> = ({ phase }) => {
5128
const {
5229
services: { cloud },
5330
} = useKibana();
5431
const { getUrlForApp, policy, license, isNewPolicy } = useEditPolicyContext();
55-
const { isUsingSearchableSnapshotInHotPhase } = useConfigurationIssues();
32+
const { isUsingSearchableSnapshotInHotPhase } = useConfiguration();
33+
34+
const searchableSnapshotRepoPath = `phases.${phase}.actions.searchable_snapshot.snapshot_repository`;
35+
const searchableSnapshotRepoGlobalPath = `_meta.searchableSnapshot.repository`;
5636

57-
const searchableSnapshotPath = `phases.${phase}.actions.searchable_snapshot.snapshot_repository`;
37+
const [formData] = useFormData({
38+
watch: [searchableSnapshotRepoGlobalPath],
39+
});
5840

59-
const [formData] = useFormData({ watch: searchableSnapshotPath });
60-
const searchableSnapshotRepo = get(formData, searchableSnapshotPath);
41+
const searchableSnapshotGlobalRepo = get(formData, searchableSnapshotRepoGlobalPath);
6142

6243
const isColdPhase = phase === 'cold';
6344
const isDisabledDueToLicense = !license.canUseSearchableSnapshot();
@@ -141,7 +122,10 @@ export const SearchableSnapshotField: FunctionComponent<Props> = ({ phase }) =>
141122
/>
142123
</EuiCallOut>
143124
);
144-
} else if (searchableSnapshotRepo && !repos.includes(searchableSnapshotRepo)) {
125+
} else if (
126+
searchableSnapshotGlobalRepo &&
127+
!repos.includes(searchableSnapshotGlobalRepo)
128+
) {
145129
calloutContent = (
146130
<EuiCallOut
147131
title={i18n.translate(
@@ -178,56 +162,17 @@ export const SearchableSnapshotField: FunctionComponent<Props> = ({ phase }) =>
178162

179163
return (
180164
<div className="ilmSearchableSnapshotField">
181-
<UseField<string>
182-
config={{
183-
label: i18nTexts.editPolicy.searchableSnapshotsFieldLabel,
184-
defaultValue: cloud?.isCloudEnabled ? CLOUD_DEFAULT_REPO : undefined,
185-
validations: [
186-
{
187-
validator: emptyField(
188-
i18nTexts.editPolicy.errors.searchableSnapshotRepoRequired
189-
),
190-
},
191-
],
165+
<UseField
166+
path={searchableSnapshotRepoPath}
167+
defaultValue={[searchableSnapshotGlobalRepo]}
168+
component={RepositoryComboBoxField}
169+
componentProps={{
170+
globalRepository: searchableSnapshotGlobalRepo,
171+
isLoading,
172+
repos,
173+
noSuggestions: !!(error || repos.length === 0),
192174
}}
193-
path={searchableSnapshotPath}
194-
>
195-
{(field) => {
196-
const singleSelectionArray: [selectedSnapshot?: string] = field.value
197-
? [field.value]
198-
: [];
199-
200-
return (
201-
<ComboBoxField
202-
field={
203-
{
204-
...field,
205-
value: singleSelectionArray,
206-
} as any
207-
}
208-
label={field.label}
209-
fullWidth={false}
210-
euiFieldProps={{
211-
'data-test-subj': 'searchableSnapshotCombobox',
212-
options: repos.map((repo) => ({ label: repo, value: repo })),
213-
singleSelection: { asPlainText: true },
214-
isLoading,
215-
noSuggestions: !!(error || repos.length === 0),
216-
onCreateOption: (newOption: string) => {
217-
field.setValue(newOption);
218-
},
219-
onChange: (options: EuiComboBoxOptionOption[]) => {
220-
if (options.length > 0) {
221-
field.setValue(options[0].label);
222-
} else {
223-
field.setValue('');
224-
}
225-
},
226-
}}
227-
/>
228-
);
229-
}}
230-
</UseField>
175+
/>
231176
{calloutContent && (
232177
<>
233178
<EuiSpacer size="s" />

0 commit comments

Comments
 (0)