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

fix 'Download CSV' returns no data when panel has custom time range outside timerange of global time picker #163887

Merged
merged 10 commits into from
Aug 17, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -770,4 +770,8 @@ export class SavedSearchEmbeddable
this.subscription?.unsubscribe();
this.abortController?.abort();
}

public hasTimeRange() {
return this.getTimeRange() !== undefined;
}
}
1 change: 1 addition & 0 deletions src/plugins/discover/public/embeddable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface SearchOutput extends EmbeddableOutput {

export interface ISearchEmbeddable extends IEmbeddable<SearchInput, SearchOutput> {
getSavedSearch(): SavedSearch;
hasTimeRange(): boolean;
}

export interface SearchEmbeddable extends Embeddable<SearchInput, SearchOutput> {
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/discover/public/utils/get_sharing_data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('getSharingData', () => {
index.timeFieldName = 'cool-timefield';
const searchSourceMock = createSearchSourceMock({ index });
const { getSearchSource } = await getSharingData(searchSourceMock, {}, services);
expect(getSearchSource()).toMatchInlineSnapshot(`
expect(getSearchSource({})).toMatchInlineSnapshot(`
Object {
"fields": Array [
Object {
Expand Down Expand Up @@ -121,7 +121,7 @@ describe('getSharingData', () => {
},
services
);
expect(getSearchSource()).toMatchInlineSnapshot(`
expect(getSearchSource({})).toMatchInlineSnapshot(`
Object {
"index": "the-data-view-id",
"sort": Array [
Expand Down Expand Up @@ -151,7 +151,7 @@ describe('getSharingData', () => {
},
services
);
expect(getSearchSource().fields).toStrictEqual([
expect(getSearchSource({}).fields).toStrictEqual([
{ field: 'cool-timefield', include_unmapped: 'true' },
{ field: 'cool-field-1', include_unmapped: 'true' },
{ field: 'cool-field-2', include_unmapped: 'true' },
Expand Down
43 changes: 25 additions & 18 deletions src/plugins/discover/public/utils/get_sharing_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,28 +69,35 @@ export async function getSharingData(
const absoluteTimeFilter = data.query.timefilter.timefilter.createFilter(index);
const relativeTimeFilter = data.query.timefilter.timefilter.createRelativeFilter(index);
return {
getSearchSource: (absoluteTime?: boolean): SerializedSearchSourceFields => {
getSearchSource: ({
addGlobalTimeFilter,
absoluteTime,
}: {
addGlobalTimeFilter?: boolean;
absoluteTime?: boolean;
}): SerializedSearchSourceFields => {
const timeFilter = absoluteTime ? absoluteTimeFilter : relativeTimeFilter;
if (addGlobalTimeFilter && timeFilter) {
// remove timeFilter from existing filter
if (Array.isArray(existingFilter)) {
existingFilter = existingFilter.filter(
(current) => !isEqualFilters(current, absoluteTimeFilter)
);
} else if (isEqualFilters(existingFilter, absoluteTimeFilter)) {
existingFilter = undefined;
}

// remove timeFilter from existing filter
if (Array.isArray(existingFilter)) {
existingFilter = existingFilter.filter(
(current) => !isEqualFilters(current, absoluteTimeFilter)
);
} else if (isEqualFilters(existingFilter, absoluteTimeFilter)) {
existingFilter = undefined;
if (existingFilter) {
existingFilter = Array.isArray(existingFilter)
? [timeFilter, ...existingFilter]
: ([timeFilter, existingFilter] as Filter[]);
} else {
existingFilter = timeFilter;
}
}

if (existingFilter && timeFilter) {
searchSource.setField(
'filter',
Array.isArray(existingFilter)
? [timeFilter, ...existingFilter]
: ([timeFilter, existingFilter] as Filter[])
);
} else {
const filter = timeFilter || existingFilter;
searchSource.setField('filter', filter);
if (existingFilter) {
searchSource.setField('filter', existingFilter);
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ describe('GetCsvReportPanelAction', () => {
from: 'now-7d',
},
}),
hasTimeRange: () => true,
},
} as unknown as ActionContext;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class ReportingCsvPanelAction implements ActionDefinition<ActionContext>
});
}

public async getSearchSource(savedSearch: SavedSearch, _embeddable: ISearchEmbeddable) {
public async getSharingData(savedSearch: SavedSearch) {
const [{ uiSettings }, { data }] = await Rx.firstValueFrom(this.startServices$);
const { getSharingData } = await loadSharingDataHelpers();
return await getSharingData(savedSearch.searchSource, savedSearch, { uiSettings, data });
Expand Down Expand Up @@ -126,10 +126,13 @@ export class ReportingCsvPanelAction implements ActionDefinition<ActionContext>
}

const savedSearch = embeddable.getSavedSearch();
const { columns, getSearchSource } = await this.getSearchSource(savedSearch, embeddable);
const { columns, getSearchSource } = await this.getSharingData(savedSearch);

const immediateJobParams = this.apiClient.getDecoratedJobParams({
searchSource: getSearchSource(true),
searchSource: getSearchSource({
addGlobalTimeFilter: !embeddable.hasTimeRange(),
absoluteTime: true,
}),
columns,
title: savedSearch.title || '',
objectType: 'downloadCsv', // FIXME: added for typescript, but immediate download job does not need objectType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ export const reportingCsvShareProvider = ({
return [];
}

const getSearchSource = sharingData.getSearchSource as (
absoluteTime?: boolean
) => SearchSourceFields;
const getSearchSource = sharingData.getSearchSource as ({
addGlobalTimeFilter,
absoluteTime,
}: {
addGlobalTimeFilter?: boolean;
absoluteTime?: boolean;
}) => SearchSourceFields;

const jobParams = {
title: sharingData.title as string,
Expand All @@ -39,10 +43,12 @@ export const reportingCsvShareProvider = ({
};

const getJobParams = (forShareUrl?: boolean) => {
const absoluteTime = !forShareUrl;
return {
...jobParams,
searchSource: getSearchSource(absoluteTime),
searchSource: getSearchSource({
addGlobalTimeFilter: true,
absoluteTime: !forShareUrl,
}),
};
};

Expand Down
Loading
Loading