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

[Logs+] Restore Dataset selection from page URL #161144

Merged
merged 61 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
8b5af82
feat(discover-log-explorer): wip on mode state selection
Jun 29, 2023
3272648
feat(discover-log-explorer): wip on DatasetSelection data structures
Jun 29, 2023
d305f84
feat(discover-log-explorer): implement dataset selection strategies
Jun 30, 2023
1815c18
refactor(discover-log-explorer): update dataset selector to manage se…
Jun 30, 2023
68e70d8
tests(discover-log-explorer): add encoding/decoding tests
Jun 30, 2023
dc1b427
refactor(discover-log-explorer): remove empty line
Jun 30, 2023
24e5437
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 30, 2023
f483418
refactor(discover-log-explorer): improve state machine readability
Jun 30, 2023
de15dc6
Merge branch '160146-all-entry-dataset-selector' of github.com:tonygh…
Jun 30, 2023
6d24915
Merge branch 'main' into 160146-all-entry-dataset-selector
tonyghiani Jun 30, 2023
e9fa701
feat(discover-log-explorer): wip on restore selection
Jul 3, 2023
db5855f
feat(discover-log-explorer): update logic for initial work
Jul 3, 2023
b32adf5
feat(discover-log-explorer): add columns init
Jul 4, 2023
e93066f
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 4, 2023
4875476
refactor(discover-log-explorer): remove unused provider
Jul 4, 2023
70cac7e
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jul 4, 2023
7ab1ba9
refactor(discover-log-explorer): add restore error notification
Jul 4, 2023
16c437e
refactor(discover-log-explorer): add types to restore state machine
Jul 4, 2023
f9530ee
refactor(discover-log-explorer): remove imports
Jul 4, 2023
50ff8e0
refactor(discover-log-explorer): lazy load new machine
Jul 5, 2023
9046fe5
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Jul 5, 2023
b796bd8
refactor(discover-log-explorer): update useLogExplorer hook
Jul 5, 2023
814555e
Merge branch '160425-restore-dataset-selection' of github.com:tonyghi…
Jul 5, 2023
3cc34df
refactor(discover-log-explorer): move services around
Jul 5, 2023
dafc59e
refactor(discover-log-explorer): reapply waiting for customizations
Jul 5, 2023
4f20c37
feat(discover-log-explorer): initialize data view by state machine
Jul 6, 2023
7603b61
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 6, 2023
9705194
fix(discover-log-explorer): create time based data view
Jul 6, 2023
443cf5f
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Jul 6, 2023
8d44f3e
refactor(discover-log-explorer): extract state machine notifications
Jul 6, 2023
4423ee2
Merge branch '160425-restore-dataset-selection' of github.com:tonyghi…
Jul 6, 2023
006c0b1
refactor(discover-log-explorer): remove conflict marker
Jul 6, 2023
85157e1
refactor(discover-log-explorer): minor changes
Jul 7, 2023
f465566
test(discover-log-explorer): add suite for restore selection
Jul 7, 2023
6f5f6a0
refactor(discover): initialization flag for customizationService
Jul 7, 2023
4c252af
refactor(discover): update test
Jul 7, 2023
f1f8db8
refactor(discover): remove action
Jul 10, 2023
b34be9c
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 10, 2023
d09060b
refactor(discover): rename discover state action
Jul 12, 2023
58f7804
refactor(discover): update initialization flow for discover
Jul 12, 2023
9657834
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 12, 2023
ec9e636
refactor(discover): remove unused import
Jul 12, 2023
56dbe58
Merge branch '160425-restore-dataset-selection' of github.com:tonyghi…
Jul 12, 2023
1839921
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 12, 2023
7703b9f
refactor(discover): move back appState sync
Jul 12, 2023
da9afac
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 12, 2023
eb66346
refactor(discover): update comments
Jul 13, 2023
8f88c40
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 13, 2023
524137c
refactor(discover): update test
Jul 13, 2023
5e2624a
refactor(discover): remove import
Jul 13, 2023
600230f
refactor(discover-log-explorer): add serverless test
Jul 13, 2023
c5e98cd
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 17, 2023
3efdb4e
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 18, 2023
a7cae5e
refactor(discover): switch back to original approach
Jul 18, 2023
0da335d
refactor(discover): update test
Jul 18, 2023
4773ab7
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 19, 2023
65b44fa
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 19, 2023
42f029d
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 19, 2023
d97e26c
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 19, 2023
f736edf
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 19, 2023
8fe91cc
Merge branch 'main' into 160425-restore-dataset-selection
tonyghiani Jul 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export const DiscoverTopNav = ({
currentDataViewId: dataView?.id,
onAddField: addField,
onDataViewCreated: createNewDataView,
onCreateDefaultAdHocDataView: stateContainer.actions.onCreateDefaultAdHocDataView,
onCreateDefaultAdHocDataView: stateContainer.actions.createAndAppendAdHocDataView,
onChangeDataView: stateContainer.actions.onChangeDataView,
textBasedLanguages: supportedTextBasedLanguages as DataViewPickerProps['textBasedLanguages'],
adHocDataViews,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ jest.mock('../../customizations', () => {
const originalModule = jest.requireActual('../../customizations');
return {
...originalModule,
useDiscoverCustomizationService: () => mockCustomizationService,
useDiscoverCustomizationService: () => ({
customizationService: mockCustomizationService,
isInitialized: Boolean(mockCustomizationService),
}),
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ export function DiscoverMainRoute({ customizationCallbacks, isDev }: MainRoutePr
services,
})
);
const customizationService = useDiscoverCustomizationService({
customizationCallbacks,
stateContainer,
});
const { customizationService, isInitialized: isCustomizationServiceInitialized } =
useDiscoverCustomizationService({
customizationCallbacks,
stateContainer,
});
const [error, setError] = useState<Error>();
const [loading, setLoading] = useState(true);
const [hasESData, setHasESData] = useState(false);
Expand Down Expand Up @@ -219,25 +220,17 @@ export function DiscoverMainRoute({ customizationCallbacks, isDev }: MainRoutePr
[loadSavedSearch]
);

// primary fetch: on initial search + triggered when id changes
useEffect(() => {
if (!isCustomizationServiceInitialized) return;

setLoading(true);
setHasESData(false);
setHasUserDataView(false);
setShowNoDataPage(false);
setError(undefined);
// restore the previously selected data view for a new state
loadSavedSearch(!savedSearchId ? stateContainer.internalState.getState().dataView : undefined);
}, [
loadSavedSearch,
savedSearchId,
stateContainer,
setLoading,
setHasESData,
setHasUserDataView,
setShowNoDataPage,
setError,
]);
}, [isCustomizationServiceInitialized, loadSavedSearch, savedSearchId, stateContainer]);

// secondary fetch: in case URL is set to `/`, used to reset to 'new' state, keeping the current data view
useUrl({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ describe('Test discover state actions', () => {
const { state } = await getState('/', { savedSearch: savedSearchMock });
await state.actions.loadSavedSearch({ savedSearchId: savedSearchMock.id });
const unsubscribe = state.actions.initializeAndSync();
await state.actions.onCreateDefaultAdHocDataView({ title: 'ad-hoc-test' });
await state.actions.createAndAppendAdHocDataView({ title: 'ad-hoc-test' });
expect(state.appState.getState().index).toBe('ad-hoc-id');
expect(state.internalState.getState().adHocDataViews[0].id).toBe('ad-hoc-id');
unsubscribe();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export interface DiscoverStateContainer {
* Used by the Data View Picker
* @param pattern
*/
onCreateDefaultAdHocDataView: (dataViewSpec: DataViewSpec) => Promise<void>;
createAndAppendAdHocDataView: (dataViewSpec: DataViewSpec) => Promise<DataView>;
/**
* Triggered when a new data view is created
* @param dataView
Expand Down Expand Up @@ -389,14 +389,15 @@ export function getDiscoverStateContainer({
};
};

const onCreateDefaultAdHocDataView = async (dataViewSpec: DataViewSpec) => {
const createAndAppendAdHocDataView = async (dataViewSpec: DataViewSpec) => {
const newDataView = await services.dataViews.create(dataViewSpec);
if (newDataView.fields.getByName('@timestamp')?.type === 'date') {
newDataView.timeFieldName = '@timestamp';
}
internalStateContainer.transitions.appendAdHocDataViews(newDataView);

await onChangeDataView(newDataView);
return newDataView;
};
/**
* Triggered when a user submits a query in the search bar
Expand Down Expand Up @@ -457,7 +458,7 @@ export function getDiscoverStateContainer({
loadDataViewList,
loadSavedSearch,
onChangeDataView,
onCreateDefaultAdHocDataView,
createAndAppendAdHocDataView,
onDataViewCreated,
onDataViewEdited,
onOpenSavedSearch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,17 @@ describe('useDiscoverCustomizationService', () => {
customizationCallbacks: [callback],
})
);
expect(wrapper.result.current).toBeUndefined();
expect(wrapper.result.current.isInitialized).toBe(false);
expect(wrapper.result.current.customizationService).toBeUndefined();
expect(callback).toHaveBeenCalledTimes(1);
const cleanup = jest.fn();
await act(async () => {
resolveCallback(cleanup);
await promise;
});
expect(wrapper.result.current).toBeDefined();
expect(wrapper.result.current).toBe(service);
expect(wrapper.result.current.isInitialized).toBe(true);
expect(wrapper.result.current.customizationService).toBeDefined();
expect(wrapper.result.current.customizationService).toBe(service);
expect(callback).toHaveBeenCalledTimes(1);
expect(cleanup).not.toHaveBeenCalled();
wrapper.unmount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export const useDiscoverCustomizationService = ({
};
});

return customizationService;
const isInitialized = Boolean(customizationService);

return { customizationService, isInitialized };
};

export const useDiscoverCustomization$ = <TCustomizationId extends DiscoverCustomizationId>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ export class Integration {
}

public static create(integration: IntegrationType) {
return new Integration({
const integrationProps = {
...integration,
id: `integration-${integration.name}-${integration.version}` as IntegrationId,
datasets: integration.dataStreams.map((dataset) => Dataset.create(dataset, integration)),
title: integration.title ?? integration.name,
};
return new Integration({
...integrationProps,
datasets: integration.dataStreams.map((dataset) => Dataset.create(dataset, integrationProps)),
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const DatasetsPopover = ({
iconSide="right"
onClick={onClick}
fullWidth={isMobile}
data-test-subj={`${POPOVER_ID}-button`}
>
{iconType ? (
<EuiIcon type={iconType} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,23 @@
* 2.0.
*/

/* eslint-disable react-hooks/exhaustive-deps */

import React, { useState } from 'react';
import { DiscoverStateContainer } from '@kbn/discover-plugin/public';
import React from 'react';
import { DatasetSelector } from '../components/dataset_selector';
import { DatasetsProvider, useDatasetsContext } from '../hooks/use_datasets';
import { InternalStateProvider } from '../hooks/use_data_view';
import { IntegrationsProvider, useIntegrationsContext } from '../hooks/use_integrations';
import { IDatasetsClient } from '../services/datasets';
import {
AllDatasetSelection,
DatasetSelection,
DatasetSelectionChange,
} from '../utils/dataset_selection';
import { LogExplorerProfileStateService } from '../state_machines/log_explorer_profile';
import { useLogExplorerProfile } from '../hooks/use_log_explorer_profile';

interface CustomDatasetSelectorProps {
stateContainer: DiscoverStateContainer;
logExplorerProfileStateService: LogExplorerProfileStateService;
}

export const CustomDatasetSelector = withProviders(({ stateContainer }) => {
/**
* TOREMOVE: This is a temporary workaround to control the datasetSelection value
* until we handle the restore/initialization of the dataview with https://github.com/elastic/kibana/issues/160425,
* where this value will be used to control the DatasetSelector selection with a top level state machine.
*/
const [datasetSelection, setDatasetSelection] = useState<DatasetSelection>(() =>
AllDatasetSelection.create()
export const CustomDatasetSelector = withProviders(({ logExplorerProfileStateService }) => {
const { datasetSelection, handleDatasetSelectionChange } = useLogExplorerProfile(
logExplorerProfileStateService
);

// Restore All dataset selection on refresh until restore from url is not available
React.useEffect(() => handleStreamSelection(datasetSelection), []);

const {
error: integrationsError,
integrations,
Expand All @@ -59,17 +44,6 @@ export const CustomDatasetSelector = withProviders(({ stateContainer }) => {
sortDatasets,
} = useDatasetsContext();

/**
* TODO: this action will be abstracted into a method of a class adapter in a follow-up PR
* since we'll need to handle more actions from the stateContainer
*/
const handleStreamSelection: DatasetSelectionChange = (nextDatasetSelection) => {
setDatasetSelection(nextDatasetSelection);
return stateContainer.actions.onCreateDefaultAdHocDataView(
nextDatasetSelection.toDataviewSpec()
);
};

return (
<DatasetSelector
datasets={datasets}
Expand All @@ -85,7 +59,7 @@ export const CustomDatasetSelector = withProviders(({ stateContainer }) => {
onIntegrationsSort={sortIntegrations}
onIntegrationsStreamsSearch={searchIntegrationsStreams}
onIntegrationsStreamsSort={sortIntegrationsStreams}
onSelectionChange={handleStreamSelection}
onSelectionChange={handleDatasetSelectionChange}
onStreamsEntryClick={loadDatasets}
onUnmanagedStreamsReload={reloadDatasets}
onUnmanagedStreamsSearch={searchDatasets}
Expand All @@ -103,17 +77,15 @@ export type CustomDatasetSelectorBuilderProps = CustomDatasetSelectorProps & {

function withProviders(Component: React.FunctionComponent<CustomDatasetSelectorProps>) {
return function ComponentWithProviders({
stateContainer,
logExplorerProfileStateService,
datasetsClient,
}: CustomDatasetSelectorBuilderProps) {
return (
<InternalStateProvider value={stateContainer.internalState}>
<IntegrationsProvider datasetsClient={datasetsClient}>
<DatasetsProvider datasetsClient={datasetsClient}>
<Component stateContainer={stateContainer} />
</DatasetsProvider>
</IntegrationsProvider>
</InternalStateProvider>
<IntegrationsProvider datasetsClient={datasetsClient}>
<DatasetsProvider datasetsClient={datasetsClient}>
<Component logExplorerProfileStateService={logExplorerProfileStateService} />
</DatasetsProvider>
</IntegrationsProvider>
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { CoreStart } from '@kbn/core/public';
import type { CoreStart } from '@kbn/core/public';
import { CustomizationCallback } from '@kbn/discover-plugin/public';
import React from 'react';
import { dynamic } from '../utils/dynamic';
Expand All @@ -19,11 +19,29 @@ interface CreateLogExplorerProfileCustomizationsDeps {
export const createLogExplorerProfileCustomizations =
({ core }: CreateLogExplorerProfileCustomizationsDeps): CustomizationCallback =>
async ({ customizations, stateContainer }) => {
const { DatasetsService } = await import('../services/datasets');
// Lazy load dependencies
const datasetServiceModuleLoadable = import('../services/datasets');
const logExplorerMachineModuleLoadable = import('../state_machines/log_explorer_profile');

const [{ DatasetsService }, { initializeLogExplorerProfileStateService, waitForState }] =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: parallelize the lazy loading for the required deps to keep the bundle size the smallest possible.

await Promise.all([datasetServiceModuleLoadable, logExplorerMachineModuleLoadable]);

const datasetsService = new DatasetsService().start({
http: core.http,
});

const logExplorerProfileStateService = initializeLogExplorerProfileStateService({
stateContainer,
toasts: core.notifications.toasts,
});

//
/**
* Wait for the machine to be fully initialized to set the restored selection
* create the DataView and set it in the stateContainer from Discover
*/
await waitForState(logExplorerProfileStateService, 'initialized');

/**
* Replace the DataViewPicker with a custom `DatasetSelector` to pick integrations streams
*/
Expand All @@ -32,7 +50,7 @@ export const createLogExplorerProfileCustomizations =
CustomDataViewPicker: () => (
<LazyCustomDatasetSelector
datasetsClient={datasetsService.client}
stateContainer={stateContainer}
logExplorerProfileStateService={logExplorerProfileStateService}
/>
),
});
Expand Down
13 changes: 0 additions & 13 deletions x-pack/plugins/discover_log_explorer/public/hooks/use_data_view.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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 { useSelector } from '@xstate/react';
import { useCallback } from 'react';
import { LogExplorerProfileStateService } from '../state_machines/log_explorer_profile';
import { DatasetSelectionChange } from '../utils/dataset_selection';

export const useLogExplorerProfile = (
logExplorerProfileStateService: LogExplorerProfileStateService
) => {
const datasetSelection = useSelector(
logExplorerProfileStateService,
(state) => state.context.datasetSelection
);

const handleDatasetSelectionChange: DatasetSelectionChange = useCallback(
(data) => {
logExplorerProfileStateService.send({ type: 'UPDATE_DATASET_SELECTION', data });
},
[logExplorerProfileStateService]
);

return { datasetSelection, handleDatasetSelectionChange };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* 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.
*/

export * from './src';
Loading