mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[8.18] [Lens][Embeddable] Restore show missing dataView error message in case of missing datasource (#208363) (#209556)
# Backport This will backport the following commits from `main` to `8.18`: - [[Lens][Embeddable] Restore show missing dataView error message in case of missing datasource (#208363)](https://github.com/elastic/kibana/pull/208363) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Marco Liberati","email":"dej611@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-02-04T14:34:13Z","message":"[Lens][Embeddable] Restore show missing dataView error message in case of missing datasource (#208363)\n\n## Summary\r\n\r\nFixes #207428 \r\n\r\nThis PR restores the `Could not find data view xxxx` message when a\r\ndataView referenced by the visualization is missing.\r\n<img width=\"764\" alt=\"Screenshot 2025-01-27 at 14 18 19\"\r\nsrc=\"https://github.com/user-attachments/assets/14ed86fc-f6db-4056-8517-2a14fe491541\"\r\n/>\r\n\r\n### Checklist\r\n\r\nCheck the PR satisfies following conditions. \r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"f3326446986c6a1cd4f472505d0c2968ef3605cd","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Visualizations","Feature:Lens","backport:prev-minor","Feature:Embeddables","v8.18.0","v9.1.0"],"title":"[Lens][Embeddable] Restore show missing dataView error message in case of missing datasource","number":208363,"url":"https://github.com/elastic/kibana/pull/208363","mergeCommit":{"message":"[Lens][Embeddable] Restore show missing dataView error message in case of missing datasource (#208363)\n\n## Summary\r\n\r\nFixes #207428 \r\n\r\nThis PR restores the `Could not find data view xxxx` message when a\r\ndataView referenced by the visualization is missing.\r\n<img width=\"764\" alt=\"Screenshot 2025-01-27 at 14 18 19\"\r\nsrc=\"https://github.com/user-attachments/assets/14ed86fc-f6db-4056-8517-2a14fe491541\"\r\n/>\r\n\r\n### Checklist\r\n\r\nCheck the PR satisfies following conditions. \r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"f3326446986c6a1cd4f472505d0c2968ef3605cd"}},"sourceBranch":"main","suggestedTargetBranches":["8.18"],"targetPullRequestStates":[{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/208363","number":208363,"mergeCommit":{"message":"[Lens][Embeddable] Restore show missing dataView error message in case of missing datasource (#208363)\n\n## Summary\r\n\r\nFixes #207428 \r\n\r\nThis PR restores the `Could not find data view xxxx` message when a\r\ndataView referenced by the visualization is missing.\r\n<img width=\"764\" alt=\"Screenshot 2025-01-27 at 14 18 19\"\r\nsrc=\"https://github.com/user-attachments/assets/14ed86fc-f6db-4056-8517-2a14fe491541\"\r\n/>\r\n\r\n### Checklist\r\n\r\nCheck the PR satisfies following conditions. \r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"f3326446986c6a1cd4f472505d0c2968ef3605cd"}}]}] BACKPORT--> Co-authored-by: Marco Liberati <dej611@users.noreply.github.com>
This commit is contained in:
parent
97cd9adc4a
commit
425b5bee28
3 changed files with 90 additions and 20 deletions
|
@ -141,7 +141,7 @@ function getMissingIndexPatternsErrors(
|
|||
// Check for access to both Management app && specific indexPattern section
|
||||
const { management: isManagementEnabled } = core.application.capabilities.navLinks;
|
||||
const isIndexPatternManagementEnabled =
|
||||
core.application.capabilities.management.kibana.indexPatterns;
|
||||
core.application.capabilities.management?.kibana?.indexPatterns;
|
||||
const canFix = isManagementEnabled && isIndexPatternManagementEnabled;
|
||||
return [
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ import {
|
|||
} from '@kbn/presentation-publishing';
|
||||
import { PublishesSearchSession } from '@kbn/presentation-publishing/interfaces/fetch/publishes_search_session';
|
||||
import { isObject } from 'lodash';
|
||||
import { defaultDoc } from '../mocks';
|
||||
import { createMockDatasource, defaultDoc } from '../mocks';
|
||||
|
||||
jest.mock('@kbn/interpreter', () => ({
|
||||
toExpression: jest.fn().mockReturnValue('expression'),
|
||||
|
@ -87,13 +87,21 @@ type ChangeFnType = ({
|
|||
async function expectRerenderOnDataLoder(
|
||||
changeFn: ChangeFnType,
|
||||
runtimeState: LensRuntimeState = { attributes: getLensAttributesMock() },
|
||||
parentApiOverrides?: Partial<
|
||||
{
|
||||
filters$: BehaviorSubject<Filter[] | undefined>;
|
||||
query$: BehaviorSubject<Query | AggregateQuery | undefined>;
|
||||
timeRange$: BehaviorSubject<TimeRange | undefined>;
|
||||
} & LensOverrides
|
||||
>
|
||||
{
|
||||
parentApiOverrides,
|
||||
servicesOverrides,
|
||||
internalApiOverrides,
|
||||
}: {
|
||||
parentApiOverrides?: Partial<
|
||||
{
|
||||
filters$: BehaviorSubject<Filter[] | undefined>;
|
||||
query$: BehaviorSubject<Query | AggregateQuery | undefined>;
|
||||
timeRange$: BehaviorSubject<TimeRange | undefined>;
|
||||
} & LensOverrides
|
||||
>;
|
||||
internalApiOverrides?: Partial<LensInternalApi>;
|
||||
servicesOverrides?: Partial<LensEmbeddableStartServices>;
|
||||
} = {}
|
||||
): Promise<void> {
|
||||
const parentApi = {
|
||||
...createUnifiedSearchApi(),
|
||||
|
@ -116,12 +124,15 @@ async function expectRerenderOnDataLoder(
|
|||
parentApi,
|
||||
};
|
||||
const getState = jest.fn(() => runtimeState);
|
||||
const internalApi = getLensInternalApiMock();
|
||||
const services = makeEmbeddableServices(new BehaviorSubject<string>(''), undefined, {
|
||||
visOverrides: { id: 'lnsXY' },
|
||||
dataOverrides: { id: 'form_based' },
|
||||
});
|
||||
services.documentToExpression = jest.fn().mockResolvedValue({ ast: 'expression_string' });
|
||||
const internalApi = getLensInternalApiMock(internalApiOverrides);
|
||||
const services = {
|
||||
...makeEmbeddableServices(new BehaviorSubject<string>(''), undefined, {
|
||||
visOverrides: { id: 'lnsXY' },
|
||||
dataOverrides: { id: 'form_based' },
|
||||
}),
|
||||
documentToExpression: jest.fn().mockResolvedValue({ ast: 'expression_string' }),
|
||||
...servicesOverrides,
|
||||
};
|
||||
const { cleanup } = loadEmbeddableData(
|
||||
faker.string.uuid(),
|
||||
getState,
|
||||
|
@ -242,7 +253,7 @@ describe('Data Loader', () => {
|
|||
return false;
|
||||
},
|
||||
undefined, // use default attributes
|
||||
createUnifiedSearchApi(query, filters) // customize parentApi
|
||||
{ parentApiOverrides: createUnifiedSearchApi(query, filters) } // customize parentApi
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -305,7 +316,13 @@ describe('Data Loader', () => {
|
|||
return false;
|
||||
},
|
||||
{ attributes },
|
||||
createUnifiedSearchApi(parentApiQuery, parentApiFilters, parentApiTimeRange)
|
||||
{
|
||||
parentApiOverrides: createUnifiedSearchApi(
|
||||
parentApiQuery,
|
||||
parentApiFilters,
|
||||
parentApiTimeRange
|
||||
),
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -411,4 +428,54 @@ describe('Data Loader', () => {
|
|||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should catch missing dataView errors correctly', async () => {
|
||||
await expectRerenderOnDataLoder(
|
||||
async ({ internalApi }) => {
|
||||
// wait for the error to appear
|
||||
await waitForValue(internalApi.blockingError$);
|
||||
|
||||
const error = internalApi.blockingError$.getValue()!;
|
||||
expect(error.message).toEqual(
|
||||
'Could not find the data view: 90943e30-9a47-11e8-b64d-95841ca0b247'
|
||||
);
|
||||
return false;
|
||||
},
|
||||
undefined,
|
||||
// Unfortuantely some mocks are required here to make the test work
|
||||
{
|
||||
// Mock the testing datasource to return an error when asked for checkIntegrity
|
||||
servicesOverrides: {
|
||||
datasourceMap: {
|
||||
form_based: {
|
||||
...createMockDatasource('form_based'),
|
||||
checkIntegrity: jest.fn().mockReturnValue(['90943e30-9a47-11e8-b64d-95841ca0b247']),
|
||||
},
|
||||
},
|
||||
},
|
||||
// Mock the visualization context to fully load the datasource state
|
||||
internalApiOverrides: {
|
||||
getVisualizationContext: jest.fn().mockReturnValue({
|
||||
activeAttributes: {
|
||||
...defaultDoc,
|
||||
visualizationType: 'lnsXY',
|
||||
state: { ...defaultDoc.state, datasourceStates: { form_based: {} } },
|
||||
},
|
||||
mergedSearchContext: {
|
||||
now: Date.now(),
|
||||
timeRange: { from: 'now-15m', to: 'now' },
|
||||
query: [defaultDoc.state.query],
|
||||
filters: [],
|
||||
disableWarningToasts: true,
|
||||
},
|
||||
indexPatterns: [],
|
||||
indexPatternRefs: {},
|
||||
activeVisualizationState: { activeId: 'lnsXY' },
|
||||
activeDatasourceState: {},
|
||||
activeData: {},
|
||||
}),
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -202,7 +202,7 @@ export function loadEmbeddableData(
|
|||
);
|
||||
|
||||
// Go concurrently: build the expression and fetch the dataViews
|
||||
const [{ params, abortController, ...rest }, dataViews] = await Promise.all([
|
||||
const [{ params, abortController, ...rest }, dataViewIds] = await Promise.all([
|
||||
getExpressionRendererParams(currentState, {
|
||||
searchContext,
|
||||
api,
|
||||
|
@ -241,9 +241,12 @@ export function loadEmbeddableData(
|
|||
});
|
||||
|
||||
// Publish the used dataViews on the Lens API
|
||||
internalApi.updateDataViews(dataViews);
|
||||
internalApi.updateDataViews(dataViewIds);
|
||||
|
||||
if (params?.expression != null && !dispatchBlockingErrorIfAny()) {
|
||||
// This will catch also failed loaded dataViews
|
||||
const hasBlockingErrors = dispatchBlockingErrorIfAny();
|
||||
|
||||
if (params?.expression != null && !hasBlockingErrors) {
|
||||
internalApi.updateExpressionParams(params);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue