Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Semantic Text UI] Add toast, modal and banner for deployment status #180246

Merged
merged 57 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
af43479
Resolve merge-conflicts
saikatsarkar056 Apr 22, 2024
f3d7fe5
Resolve merge-conflicts
saikatsarkar056 Apr 22, 2024
558c907
Call a single line function directly
saikatsarkar056 Apr 9, 2024
7883076
Add i18n messages
saikatsarkar056 Apr 9, 2024
c2df458
Refactor fetchInferenceModelsAndTrainedModelStats
saikatsarkar056 Apr 9, 2024
f4037fb
Resolve merge-conflicts
saikatsarkar056 Apr 22, 2024
05b80eb
Refactor fetchInferenceModelsAndTrainedModelStats
saikatsarkar056 Apr 9, 2024
2f59827
Format message
saikatsarkar056 Apr 9, 2024
cfebf8f
Resolve merge-conflicts
saikatsarkar056 Apr 22, 2024
d435da6
Resolve merge-conflicts
saikatsarkar056 Apr 22, 2024
598906e
Use array instead of set
saikatsarkar056 Apr 10, 2024
67f98e9
Use useMemo instead of useCallback
saikatsarkar056 Apr 10, 2024
291ba16
Declare the pure functions at top instead of useCallback
saikatsarkar056 Apr 10, 2024
57a1f84
Fix the test for trained_models_deployment_modal.test.tsx
saikatsarkar056 Apr 10, 2024
085b826
Make the code more idiomatic
saikatsarkar056 Apr 10, 2024
61dd977
Fix CI failures
saikatsarkar056 Apr 10, 2024
b635375
Fix CI failure
saikatsarkar056 Apr 10, 2024
8eecc4c
Fix CI failure
saikatsarkar056 Apr 10, 2024
b6a974b
Add tests for use_details_page_mappings_model_management hook
saikatsarkar056 Apr 11, 2024
01a0954
Add tests for use_details_page_mappings_model_management hook
saikatsarkar056 Apr 11, 2024
7714ad5
Add tests for use_details_page_mappings_model_management hook
saikatsarkar056 Apr 11, 2024
1e8899c
Add tests for use_details_page_mappings_model_management hook
saikatsarkar056 Apr 11, 2024
2ee77fd
Display warning based on prop
saikatsarkar056 Apr 11, 2024
331bf74
Display warning based on prop
saikatsarkar056 Apr 11, 2024
1b507f0
Fix the issue with fields
saikatsarkar056 Apr 11, 2024
c32227b
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 11, 2024
a49866b
Move plugin dependencies out of index-management package
sphilipse Apr 11, 2024
aba5651
Fix the issue with fields
saikatsarkar056 Apr 11, 2024
5955165
Handle errors in trained model
saikatsarkar056 Apr 11, 2024
dc50c0a
Add more tests for modals
saikatsarkar056 Apr 11, 2024
325ce60
Add more tests for modals
saikatsarkar056 Apr 11, 2024
778596b
Display warning instead of error if there is multipleMappingsDeclared
saikatsarkar056 Apr 11, 2024
4e3cbd1
Display warning instead of error if there is multipleMappingsDeclared
saikatsarkar056 Apr 11, 2024
9bc63f8
Show badge for inference_id
saikatsarkar056 Apr 12, 2024
bca4976
Add the deployables to the inferenceToModelIdMap
saikatsarkar056 Apr 12, 2024
0146093
Resolve merge-conflicts
saikatsarkar056 Apr 22, 2024
1ad414a
Resolve merge-conflicts
saikatsarkar056 Apr 22, 2024
772600b
Remove additional plugin
saikatsarkar056 Apr 22, 2024
74a11ee
Get the function used for api directly
saikatsarkar056 Apr 22, 2024
15f3c40
Modify the test
saikatsarkar056 Apr 22, 2024
875ddfd
Move toasts to create_field
saikatsarkar056 Apr 22, 2024
b904884
Resolve merge conflicts
saikatsarkar056 Apr 25, 2024
2d6b0f2
Utilize the existing inference api to create text_embedding
saikatsarkar056 Apr 22, 2024
62117a7
Remove unused prop
saikatsarkar056 Apr 22, 2024
ebf6acf
Remove unused prop
saikatsarkar056 Apr 22, 2024
dcec1cb
Add try-catch for error
saikatsarkar056 Apr 22, 2024
e318e9b
Add try-catch for error
saikatsarkar056 Apr 22, 2024
926b891
Move semantic logic to a seperate file
saikatsarkar056 Apr 22, 2024
917dbeb
Fix the tests
saikatsarkar056 Apr 23, 2024
2b73b1a
Move use_semantic_text hook to a seperate folder
saikatsarkar056 Apr 23, 2024
574902d
Add tests for use_semantic_text hook
saikatsarkar056 Apr 23, 2024
0bb1c37
Add tests for use_semantic_text hook
saikatsarkar056 Apr 23, 2024
2828c01
Add tests for use_semantic_text hook
saikatsarkar056 Apr 23, 2024
0f46e08
Add tests for use_semantic_text hook
saikatsarkar056 Apr 23, 2024
8cfe002
Clean up before component unmounts
saikatsarkar056 Apr 23, 2024
00cb2a1
Extract the common code-block to a seperate file
saikatsarkar056 Apr 23, 2024
83111b4
Resolve merge conflicts
saikatsarkar056 Apr 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion x-pack/packages/index-management/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
"include": [
"**/*.ts",
"**/*.tsx",
"**/*.tsx"
],
"exclude": [
"target/**/*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ export type InferenceServiceSettings =
model_id: string;
};
}
| {
service: 'elasticsearch';
service_settings: {
num_allocations: number;
num_threads: number;
model_id: string;
};
}
| {
service: 'openai';
service_settings: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export interface IndexDetailsPageTestBed extends TestBed {
getTreeViewContent: (fieldName: string) => string;
clickToggleViewButton: () => Promise<void>;
isSearchBarDisabled: () => boolean;
isSemanticTextBannerVisible: () => boolean;
};
settings: {
getCodeBlockContent: () => string;
Expand Down Expand Up @@ -218,6 +219,9 @@ export const setup = async ({
isSearchBarDisabled: () => {
return find('indexDetailsMappingsFieldSearch').prop('disabled');
},
isSemanticTextBannerVisible: () => {
return exists('indexDetailsMappingsSemanticTextBanner');
},
clickAddFieldButton: async () => {
expect(exists('indexDetailsMappingsAddField')).toBe(true);
await act(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,10 @@ describe('<IndexDetailsPage />', () => {
expect(testBed.actions.mappings.isSearchBarDisabled()).toBe(false);
});

it('semantic text banner is not visible', async () => {
expect(testBed.actions.mappings.isSemanticTextBannerVisible()).toBe(false);
});

it('sets the docs link href from the documentation service', async () => {
const docsLinkHref = testBed.actions.mappings.getDocsLinkHref();
// the url from the mocked docs mock
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { registerTestBed } from '@kbn/test-jest-helpers';
import { act } from 'react-dom/test-utils';
import { SemanticTextBanner } from '../../../public/application/sections/home/index_list/details_page/semantic_text_banner';

describe('When semantic_text is enabled', () => {
const setup = registerTestBed(SemanticTextBanner, {
defaultProps: { isSemanticTextEnabled: true },
memoryRouter: { wrapComponent: false },
});
const { exists, find } = setup();

it('should display the banner', () => {
expect(exists('indexDetailsMappingsSemanticTextBanner')).toBe(true);
});

it('should contain content related to semantic_text', () => {
expect(find('indexDetailsMappingsSemanticTextBanner').text()).toContain(
'semantic_text field type now available!'
);
});

it('should hide the banner if dismiss is clicked', async () => {
await act(async () => {
find('SemanticTextBannerDismissButton').simulate('click');
});
expect(exists('indexDetailsMappingsSemanticTextBanner')).toBe(true);
});
});

describe('When semantic_text is disabled', () => {
const setup = registerTestBed(SemanticTextBanner, {
defaultProps: { isSemanticTextEnabled: false },
memoryRouter: { wrapComponent: false },
});
const { exists } = setup();

it('should not display the banner', () => {
expect(exists('indexDetailsMappingsSemanticTextBanner')).toBe(false);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { registerTestBed } from '@kbn/test-jest-helpers';
import { TrainedModelsDeploymentModal } from '../../../public/application/sections/home/index_list/details_page/trained_models_deployment_modal';
import { act } from 'react-dom/test-utils';

const refreshModal = jest.fn();
const setIsModalVisible = jest.fn();
const tryAgainForErrorModal = jest.fn();
const setIsVisibleForErrorModal = jest.fn();

describe('When semantic_text is enabled', () => {
describe('When there is no error in the model deployment', () => {
const setup = registerTestBed(TrainedModelsDeploymentModal, {
defaultProps: {
isSemanticTextEnabled: true,
pendingDeployments: ['.elser-test-3'],
setIsModalVisible,
refreshModal,
},
memoryRouter: { wrapComponent: false },
});
const { exists, find } = setup();

it('should display the modal', () => {
expect(exists('trainedModelsDeploymentModal')).toBe(true);
});

it('should contain content related to semantic_text', () => {
expect(find('trainedModelsDeploymentModalText').text()).toContain(
'Some fields are referencing models'
);
});

it('should call refresh method if refresh button is pressed', async () => {
await act(async () => {
find('confirmModalConfirmButton').simulate('click');
});
expect(refreshModal.mock.calls).toHaveLength(1);
});

it('should call setIsModalVisible method if cancel button is pressed', async () => {
await act(async () => {
find('confirmModalCancelButton').simulate('click');
});
expect(setIsModalVisible.mock.calls).toHaveLength(1);
});
});

describe('When there is error in the model deployment', () => {
const setup = registerTestBed(TrainedModelsDeploymentModal, {
defaultProps: {
isSemanticTextEnabled: true,
pendingDeployments: ['.elser-test-3'],
setIsModalVisible: setIsVisibleForErrorModal,
refreshModal: tryAgainForErrorModal,
errorsInTrainedModelDeployment: ['.elser-test-3'],
},
memoryRouter: { wrapComponent: false },
});
const { exists, find } = setup();

it('should display the modal', () => {
expect(exists('trainedModelsErroredDeploymentModal')).toBe(true);
});

it('should contain content related to semantic_text', () => {
expect(find('trainedModelsErrorDeploymentModalText').text()).toContain(
'There was an error when trying to deploy'
);
});

it("should call refresh method if 'Try again' button is pressed", async () => {
await act(async () => {
find('confirmModalConfirmButton').simulate('click');
});
expect(tryAgainForErrorModal.mock.calls).toHaveLength(1);
});

it('should call setIsModalVisible method if cancel button is pressed', async () => {
await act(async () => {
find('confirmModalCancelButton').simulate('click');
});
expect(setIsVisibleForErrorModal.mock.calls).toHaveLength(1);
});
});
});

describe('When semantic_text is disabled', () => {
const setup = registerTestBed(TrainedModelsDeploymentModal, {
defaultProps: { isSemanticTextEnabled: false },
memoryRouter: { wrapComponent: false },
});
const { exists } = setup();
it('it should not display the modal', () => {
expect(exists('trainedModelsDeploymentModal')).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ import {
FatalErrorsStart,
ScopedHistory,
DocLinksStart,
IUiSettingsClient,
ExecutionContextStart,
HttpSetup,
IUiSettingsClient,
} from '@kbn/core/public';
import type { MlPluginStart } from '@kbn/ml-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';

import type { SettingsStart } from '@kbn/core-ui-settings-browser';
import { EuiBreadcrumb } from '@elastic/eui';
import type { CloudSetup } from '@kbn/cloud-plugin/public';
import type { ConsolePluginStart } from '@kbn/console-plugin/public';
import { EuiBreadcrumb } from '@elastic/eui';
import type { MlPluginStart } from '@kbn/ml-plugin/public';
import type { SettingsStart } from '@kbn/core-ui-settings-browser';
import { ExtensionsService } from '../services';
import { UiMetricService, NotificationService, HttpService } from './services';
import { HttpService, NotificationService, UiMetricService } from './services';
import { IndexManagementBreadcrumb } from './services/breadcrumbs';

export const AppContext = createContext<AppDependencies | undefined>(undefined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const { GlobalFlyoutProvider } = GlobalFlyout;
// We provide the minimum deps required to make the tests pass
const appDependencies = {
docLinks: {} as any,
plugins: { ml: {} as any },
} as any;

export const componentTemplatesDependencies = (httpSetup: HttpSetup, coreStart?: CoreStart) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ import { componentHelpers, MappingsEditorTestBed } from '../helpers';

const { setup, getMappingsEditorDataFactory } = componentHelpers.mappingsEditor;

jest.mock('../../../../component_templates/component_templates_context', () => ({
useComponentTemplatesContext: jest.fn().mockReturnValue({
toasts: {
addError: jest.fn(),
addSuccess: jest.fn(),
},
}),
}));

describe('Mappings editor: other datatype', () => {
/**
* Variable to store the mappings data forwarded to the consumer component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ import { componentHelpers, MappingsEditorTestBed } from './helpers';

const { setup, getMappingsEditorDataFactory } = componentHelpers.mappingsEditor;

jest.mock('../../../component_templates/component_templates_context', () => ({
useComponentTemplatesContext: jest.fn().mockReturnValue({
toasts: {
addError: jest.fn(),
addSuccess: jest.fn(),
},
}),
}));

describe('Mappings editor: core', () => {
/**
* Variable to store the mappings data forwarded to the consumer component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ import { componentHelpers, MappingsEditorTestBed } from './helpers';

const { setup, getMappingsEditorDataFactory } = componentHelpers.mappingsEditor;

jest.mock('../../../component_templates/component_templates_context', () => ({
useComponentTemplatesContext: jest.fn().mockReturnValue({
toasts: {
addError: jest.fn(),
addSuccess: jest.fn(),
},
}),
}));

describe('Mappings editor: runtime fields', () => {
/**
* Variable to store the mappings data forwarded to the consumer component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,36 @@
* 2.0.
*/

import React, { useMemo, useCallback, useEffect } from 'react';
import React, { useCallback, useEffect, useMemo } from 'react';

import { GlobalFlyout } from '../../shared_imports';
import { useMappingsState, useDispatch } from '../../mappings_state_context';
import { deNormalize } from '../../lib';
import { EditFieldContainer, EditFieldContainerProps, defaultFlyoutProps } from './fields';
import { useDispatch, useMappingsState } from '../../mappings_state_context';
import { GlobalFlyout } from '../../shared_imports';
import {
defaultFlyoutProps,
EditFieldContainer,
EditFieldContainerProps,
SemanticTextInfo,
} from './fields';
import { DocumentFieldsJsonEditor } from './fields_json_editor';
import { DocumentFieldsTreeEditor } from './fields_tree_editor';

const { useGlobalFlyout } = GlobalFlyout;

interface Props {
searchComponent?: React.ReactElement;
searchResultComponent?: React.ReactElement;
onCancelAddingNewFields?: () => void;
isAddingFields?: boolean;
isSemanticTextEnabled?: boolean;
indexName?: string;
semanticTextInfo?: SemanticTextInfo;
}
export const DocumentFields = React.memo(
({
searchComponent,
searchResultComponent,
onCancelAddingNewFields,
isAddingFields,
isSemanticTextEnabled,
indexName,
semanticTextInfo,
}: Props) => {
const { fields, documentFields } = useMappingsState();
const dispatch = useDispatch();
Expand All @@ -53,8 +57,7 @@ export const DocumentFields = React.memo(
<DocumentFieldsTreeEditor
onCancelAddingNewFields={onCancelAddingNewFields}
isAddingFields={isAddingFields}
isSemanticTextEnabled={isSemanticTextEnabled}
indexName={indexName}
semanticTextInfo={semanticTextInfo}
/>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ import { useLoadInferenceModels } from '../../../../../services/api';
interface Props {
onChange(value: string): void;
'data-test-subj'?: string;
setValue: (value: string) => void;
}
export const SelectInferenceId = ({ onChange, 'data-test-subj': dataTestSubj }: Props) => {
export const SelectInferenceId = ({
onChange,
'data-test-subj': dataTestSubj,
setValue,
}: Props) => {
const {
core: { application },
docLinks,
Expand Down Expand Up @@ -142,6 +147,9 @@ export const SelectInferenceId = ({ onChange, 'data-test-subj': dataTestSubj }:
return subscription.unsubscribe;
}, [subscribe, onChange]);
const selectedOptionLabel = options.find((option) => option.checked)?.label;
useEffect(() => {
setValue(selectedOptionLabel ?? 'elser_model_2');
}, [selectedOptionLabel, setValue]);
const [isInferencePopoverVisible, setIsInferencePopoverVisible] = useState<boolean>(false);
const [inferenceEndpointError, setInferenceEndpointError] = useState<string | undefined>(
undefined
Expand Down