mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Content management] Add "Last updated" metadata to TableListView (#132321)
This commit is contained in:
parent
8de3401dff
commit
a80bfb7283
13 changed files with 344 additions and 67 deletions
|
@ -98,12 +98,16 @@ export class SavedObjectLoader {
|
|||
mapHitSource(
|
||||
source: Record<string, unknown>,
|
||||
id: string,
|
||||
references: SavedObjectReference[] = []
|
||||
) {
|
||||
source.id = id;
|
||||
source.url = this.urlFor(id);
|
||||
source.references = references;
|
||||
return source;
|
||||
references: SavedObjectReference[] = [],
|
||||
updatedAt?: string
|
||||
): Record<string, unknown> {
|
||||
return {
|
||||
...source,
|
||||
id,
|
||||
url: this.urlFor(id),
|
||||
references,
|
||||
updatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,12 +120,14 @@ export class SavedObjectLoader {
|
|||
attributes,
|
||||
id,
|
||||
references = [],
|
||||
updatedAt,
|
||||
}: {
|
||||
attributes: Record<string, unknown>;
|
||||
id: string;
|
||||
references?: SavedObjectReference[];
|
||||
updatedAt?: string;
|
||||
}) {
|
||||
return this.mapHitSource(attributes, id, references);
|
||||
return this.mapHitSource(attributes, id, references, updatedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -129,6 +129,7 @@ exports[`TableListView render list view 1`] = `
|
|||
}
|
||||
/>
|
||||
}
|
||||
onChange={[Function]}
|
||||
pagination={
|
||||
Object {
|
||||
"initialPageIndex": 0,
|
||||
|
@ -155,7 +156,11 @@ exports[`TableListView render list view 1`] = `
|
|||
"toolsLeft": undefined,
|
||||
}
|
||||
}
|
||||
sorting={true}
|
||||
sorting={
|
||||
Object {
|
||||
"sort": undefined,
|
||||
}
|
||||
}
|
||||
tableCaption="test caption"
|
||||
tableLayout="fixed"
|
||||
/>
|
||||
|
|
|
@ -7,13 +7,24 @@
|
|||
*/
|
||||
|
||||
import { EuiEmptyPrompt } from '@elastic/eui';
|
||||
import { shallowWithIntl } from '@kbn/test-jest-helpers';
|
||||
import { shallowWithIntl, registerTestBed, TestBed } from '@kbn/test-jest-helpers';
|
||||
import { ToastsStart } from '@kbn/core/public';
|
||||
import React from 'react';
|
||||
import moment, { Moment } from 'moment';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { themeServiceMock, applicationServiceMock } from '@kbn/core/public/mocks';
|
||||
import { TableListView } from './table_list_view';
|
||||
import { TableListView, TableListViewProps } from './table_list_view';
|
||||
|
||||
const requiredProps = {
|
||||
jest.mock('lodash', () => {
|
||||
const original = jest.requireActual('lodash');
|
||||
|
||||
return {
|
||||
...original,
|
||||
debounce: (handler: () => void) => handler,
|
||||
};
|
||||
});
|
||||
|
||||
const requiredProps: TableListViewProps<Record<string, unknown>> = {
|
||||
entityName: 'test',
|
||||
entityNamePlural: 'tests',
|
||||
listingLimit: 5,
|
||||
|
@ -30,6 +41,14 @@ const requiredProps = {
|
|||
};
|
||||
|
||||
describe('TableListView', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
test('render default empty prompt', async () => {
|
||||
const component = shallowWithIntl(<TableListView {...requiredProps} />);
|
||||
|
||||
|
@ -81,4 +100,149 @@ describe('TableListView', () => {
|
|||
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('default columns', () => {
|
||||
let testBed: TestBed;
|
||||
|
||||
const tableColumns = [
|
||||
{
|
||||
field: 'title',
|
||||
name: 'Title',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
name: 'Description',
|
||||
sortable: true,
|
||||
},
|
||||
];
|
||||
|
||||
const twoDaysAgo = new Date(new Date().setDate(new Date().getDate() - 2));
|
||||
const yesterday = new Date(new Date().setDate(new Date().getDate() - 1));
|
||||
|
||||
const hits = [
|
||||
{
|
||||
title: 'Item 1',
|
||||
description: 'Item 1 description',
|
||||
updatedAt: twoDaysAgo,
|
||||
},
|
||||
{
|
||||
title: 'Item 2',
|
||||
description: 'Item 2 description',
|
||||
// This is the latest updated and should come first in the table
|
||||
updatedAt: yesterday,
|
||||
},
|
||||
];
|
||||
|
||||
const findItems = jest.fn(() => Promise.resolve({ total: hits.length, hits }));
|
||||
|
||||
const defaultProps: TableListViewProps<Record<string, unknown>> = {
|
||||
...requiredProps,
|
||||
tableColumns,
|
||||
findItems,
|
||||
createItem: () => undefined,
|
||||
};
|
||||
|
||||
const setup = registerTestBed(TableListView, { defaultProps });
|
||||
|
||||
test('should add a "Last updated" column if "updatedAt" is provided', async () => {
|
||||
await act(async () => {
|
||||
testBed = await setup();
|
||||
});
|
||||
|
||||
const { component, table } = testBed!;
|
||||
component.update();
|
||||
|
||||
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
|
||||
|
||||
expect(tableCellsValues).toEqual([
|
||||
['Item 2', 'Item 2 description', 'yesterday'], // Comes first as it is the latest updated
|
||||
['Item 1', 'Item 1 description', '2 days ago'],
|
||||
]);
|
||||
});
|
||||
|
||||
test('should not display relative time for items updated more than 7 days ago', async () => {
|
||||
const updatedAtValues: Moment[] = [];
|
||||
|
||||
const updatedHits = hits.map(({ title, description }, i) => {
|
||||
const updatedAt = new Date(new Date().setDate(new Date().getDate() - (7 + i)));
|
||||
updatedAtValues[i] = moment(updatedAt);
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
updatedAt,
|
||||
};
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
testBed = await setup({
|
||||
findItems: jest.fn(() =>
|
||||
Promise.resolve({
|
||||
total: updatedHits.length,
|
||||
hits: updatedHits,
|
||||
})
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
const { component, table } = testBed!;
|
||||
component.update();
|
||||
|
||||
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
|
||||
|
||||
expect(tableCellsValues).toEqual([
|
||||
// Renders the datetime with this format: "05/10/2022 @ 2:34 PM"
|
||||
['Item 1', 'Item 1 description', updatedAtValues[0].format('LL')],
|
||||
['Item 2', 'Item 2 description', updatedAtValues[1].format('LL')],
|
||||
]);
|
||||
});
|
||||
|
||||
test('should not add a "Last updated" column if no "updatedAt" is provided', async () => {
|
||||
await act(async () => {
|
||||
testBed = await setup({
|
||||
findItems: jest.fn(() =>
|
||||
Promise.resolve({
|
||||
total: hits.length,
|
||||
hits: hits.map(({ title, description }) => ({ title, description })),
|
||||
})
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
const { component, table } = testBed!;
|
||||
component.update();
|
||||
|
||||
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
|
||||
|
||||
expect(tableCellsValues).toEqual([
|
||||
['Item 1', 'Item 1 description'], // Sorted by title
|
||||
['Item 2', 'Item 2 description'],
|
||||
]);
|
||||
});
|
||||
|
||||
test('should not display anything if there is no updatedAt metadata for an item', async () => {
|
||||
await act(async () => {
|
||||
testBed = await setup({
|
||||
findItems: jest.fn(() =>
|
||||
Promise.resolve({
|
||||
total: hits.length + 1,
|
||||
hits: [...hits, { title: 'Item 3', description: 'Item 3 description' }],
|
||||
})
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
const { component, table } = testBed!;
|
||||
component.update();
|
||||
|
||||
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
|
||||
|
||||
expect(tableCellsValues).toEqual([
|
||||
['Item 2', 'Item 2 description', 'yesterday'],
|
||||
['Item 1', 'Item 1 description', '2 days ago'],
|
||||
['Item 3', 'Item 3 description', '-'], // Empty column as no updatedAt provided
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,16 +13,21 @@ import {
|
|||
EuiConfirmModal,
|
||||
EuiEmptyPrompt,
|
||||
EuiInMemoryTable,
|
||||
Criteria,
|
||||
PropertySort,
|
||||
Direction,
|
||||
EuiLink,
|
||||
EuiSpacer,
|
||||
EuiTableActionsColumnType,
|
||||
SearchFilterConfig,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { FormattedMessage, FormattedRelative } from '@kbn/i18n-react';
|
||||
import { ThemeServiceStart, HttpFetchError, ToastsStart, ApplicationStart } from '@kbn/core/public';
|
||||
import { debounce, keyBy, sortBy, uniq } from 'lodash';
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { KibanaPageTemplate } from '../page_template';
|
||||
import { toMountPoint } from '../util';
|
||||
|
||||
|
@ -64,6 +69,7 @@ export interface TableListViewProps<V> {
|
|||
export interface TableListViewState<V> {
|
||||
items: V[];
|
||||
hasInitialFetchReturned: boolean;
|
||||
hasUpdatedAtMetadata: boolean | null;
|
||||
isFetchingItems: boolean;
|
||||
isDeletingItems: boolean;
|
||||
showDeleteModal: boolean;
|
||||
|
@ -72,6 +78,10 @@ export interface TableListViewState<V> {
|
|||
filter: string;
|
||||
selectedIds: string[];
|
||||
totalItems: number;
|
||||
tableSort?: {
|
||||
field: keyof V;
|
||||
direction: Direction;
|
||||
};
|
||||
}
|
||||
|
||||
// saved object client does not support sorting by title because title is only mapped as analyzed
|
||||
|
@ -94,10 +104,12 @@ class TableListView<V extends {}> extends React.Component<
|
|||
initialPageSize: props.initialPageSize,
|
||||
pageSizeOptions: uniq([10, 20, 50, props.initialPageSize]).sort(),
|
||||
};
|
||||
|
||||
this.state = {
|
||||
items: [],
|
||||
totalItems: 0,
|
||||
hasInitialFetchReturned: false,
|
||||
hasUpdatedAtMetadata: null,
|
||||
isFetchingItems: false,
|
||||
isDeletingItems: false,
|
||||
showDeleteModal: false,
|
||||
|
@ -120,6 +132,28 @@ class TableListView<V extends {}> extends React.Component<
|
|||
this.fetchItems();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: TableListViewProps<V>, prevState: TableListViewState<V>) {
|
||||
if (this.state.hasUpdatedAtMetadata === null && prevState.items !== this.state.items) {
|
||||
// We check if the saved object have the "updatedAt" metadata
|
||||
// to render or not that column in the table
|
||||
const hasUpdatedAtMetadata = Boolean(
|
||||
this.state.items.find((item: { updatedAt?: string }) => Boolean(item.updatedAt))
|
||||
);
|
||||
|
||||
this.setState((prev) => {
|
||||
return {
|
||||
hasUpdatedAtMetadata,
|
||||
tableSort: hasUpdatedAtMetadata
|
||||
? {
|
||||
field: 'updatedAt' as keyof V,
|
||||
direction: 'desc' as const,
|
||||
}
|
||||
: prev.tableSort,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
debouncedFetch = debounce(async (filter: string) => {
|
||||
try {
|
||||
const response = await this.props.findItems(filter);
|
||||
|
@ -420,6 +454,12 @@ class TableListView<V extends {}> extends React.Component<
|
|||
);
|
||||
}
|
||||
|
||||
onTableChange(criteria: Criteria<V>) {
|
||||
if (criteria.sort) {
|
||||
this.setState({ tableSort: criteria.sort });
|
||||
}
|
||||
}
|
||||
|
||||
renderTable() {
|
||||
const { searchFilters } = this.props;
|
||||
|
||||
|
@ -435,24 +475,6 @@ class TableListView<V extends {}> extends React.Component<
|
|||
}
|
||||
: undefined;
|
||||
|
||||
const actions: EuiTableActionsColumnType<V>['actions'] = [
|
||||
{
|
||||
name: i18n.translate('kibana-react.tableListView.listing.table.editActionName', {
|
||||
defaultMessage: 'Edit',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'kibana-react.tableListView.listing.table.editActionDescription',
|
||||
{
|
||||
defaultMessage: 'Edit',
|
||||
}
|
||||
),
|
||||
icon: 'pencil',
|
||||
type: 'icon',
|
||||
enabled: (v) => !(v as unknown as { error: string })?.error,
|
||||
onClick: this.props.editItem,
|
||||
},
|
||||
];
|
||||
|
||||
const search = {
|
||||
onChange: this.setFilter.bind(this),
|
||||
toolsLeft: this.renderToolsLeft(),
|
||||
|
@ -464,8 +486,102 @@ class TableListView<V extends {}> extends React.Component<
|
|||
filters: searchFilters ?? [],
|
||||
};
|
||||
|
||||
const noItemsMessage = (
|
||||
<FormattedMessage
|
||||
id="kibana-react.tableListView.listing.noMatchedItemsMessage"
|
||||
defaultMessage="No {entityNamePlural} matched your search."
|
||||
values={{ entityNamePlural: this.props.entityNamePlural }}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiInMemoryTable
|
||||
itemId="id"
|
||||
items={this.state.items}
|
||||
columns={this.getTableColumns()}
|
||||
pagination={this.pagination}
|
||||
loading={this.state.isFetchingItems}
|
||||
message={noItemsMessage}
|
||||
selection={selection}
|
||||
search={search}
|
||||
sorting={{ sort: this.state.tableSort as PropertySort }}
|
||||
onChange={this.onTableChange.bind(this)}
|
||||
data-test-subj="itemsInMemTable"
|
||||
rowHeader={this.props.rowHeader}
|
||||
tableCaption={this.props.tableCaption}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
getTableColumns() {
|
||||
const columns = this.props.tableColumns.slice();
|
||||
|
||||
// Add "Last update" column
|
||||
if (this.state.hasUpdatedAtMetadata) {
|
||||
const renderUpdatedAt = (dateTime?: string) => {
|
||||
if (!dateTime) {
|
||||
return (
|
||||
<EuiToolTip
|
||||
content={i18n.translate('kibana-react.tableListView.updatedDateUnknownLabel', {
|
||||
defaultMessage: 'Last updated unknown',
|
||||
})}
|
||||
>
|
||||
<span>-</span>
|
||||
</EuiToolTip>
|
||||
);
|
||||
}
|
||||
const updatedAt = moment(dateTime);
|
||||
|
||||
if (updatedAt.diff(moment(), 'days') > -7) {
|
||||
return (
|
||||
<FormattedRelative value={new Date(dateTime).getTime()}>
|
||||
{(formattedDate: string) => (
|
||||
<EuiToolTip content={updatedAt.format('LL LT')}>
|
||||
<span>{formattedDate}</span>
|
||||
</EuiToolTip>
|
||||
)}
|
||||
</FormattedRelative>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<EuiToolTip content={updatedAt.format('LL LT')}>
|
||||
<span>{updatedAt.format('LL')}</span>
|
||||
</EuiToolTip>
|
||||
);
|
||||
};
|
||||
|
||||
columns.push({
|
||||
field: 'updatedAt',
|
||||
name: i18n.translate('kibana-react.tableListView.lastUpdatedColumnTitle', {
|
||||
defaultMessage: 'Last updated',
|
||||
}),
|
||||
render: (field: string, record: { updatedAt?: string }) =>
|
||||
renderUpdatedAt(record.updatedAt),
|
||||
sortable: true,
|
||||
width: '150px',
|
||||
});
|
||||
}
|
||||
|
||||
// Add "Actions" column
|
||||
if (this.props.editItem) {
|
||||
const actions: EuiTableActionsColumnType<V>['actions'] = [
|
||||
{
|
||||
name: i18n.translate('kibana-react.tableListView.listing.table.editActionName', {
|
||||
defaultMessage: 'Edit',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'kibana-react.tableListView.listing.table.editActionDescription',
|
||||
{
|
||||
defaultMessage: 'Edit',
|
||||
}
|
||||
),
|
||||
icon: 'pencil',
|
||||
type: 'icon',
|
||||
enabled: (v) => !(v as unknown as { error: string })?.error,
|
||||
onClick: this.props.editItem,
|
||||
},
|
||||
];
|
||||
|
||||
columns.push({
|
||||
name: i18n.translate('kibana-react.tableListView.listing.table.actionTitle', {
|
||||
defaultMessage: 'Actions',
|
||||
|
@ -475,29 +591,7 @@ class TableListView<V extends {}> extends React.Component<
|
|||
});
|
||||
}
|
||||
|
||||
const noItemsMessage = (
|
||||
<FormattedMessage
|
||||
id="kibana-react.tableListView.listing.noMatchedItemsMessage"
|
||||
defaultMessage="No {entityNamePlural} matched your search."
|
||||
values={{ entityNamePlural: this.props.entityNamePlural }}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<EuiInMemoryTable
|
||||
itemId="id"
|
||||
items={this.state.items}
|
||||
columns={columns}
|
||||
pagination={this.pagination}
|
||||
loading={this.state.isFetchingItems}
|
||||
message={noItemsMessage}
|
||||
selection={selection}
|
||||
search={search}
|
||||
sorting={true}
|
||||
data-test-subj="itemsInMemTable"
|
||||
rowHeader={this.props.rowHeader}
|
||||
tableCaption={this.props.tableCaption}
|
||||
/>
|
||||
);
|
||||
return columns;
|
||||
}
|
||||
|
||||
renderCreateButton() {
|
||||
|
|
|
@ -64,10 +64,12 @@ export function mapHitSource(
|
|||
attributes,
|
||||
id,
|
||||
references,
|
||||
updatedAt,
|
||||
}: {
|
||||
attributes: SavedObjectAttributes;
|
||||
id: string;
|
||||
references: SavedObjectReference[];
|
||||
updatedAt?: string;
|
||||
}
|
||||
) {
|
||||
const newAttributes: {
|
||||
|
@ -76,6 +78,7 @@ export function mapHitSource(
|
|||
url: string;
|
||||
savedObjectType?: string;
|
||||
editUrl?: string;
|
||||
updatedAt?: string;
|
||||
type?: BaseVisType;
|
||||
icon?: BaseVisType['icon'];
|
||||
image?: BaseVisType['image'];
|
||||
|
@ -85,6 +88,7 @@ export function mapHitSource(
|
|||
id,
|
||||
references,
|
||||
url: urlFor(id),
|
||||
updatedAt,
|
||||
...attributes,
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { SavedObject } from '@kbn/core/types/saved_objects';
|
||||
import type { SimpleSavedObject } from '@kbn/core/public';
|
||||
import { BaseVisType } from './base_vis_type';
|
||||
|
||||
export type VisualizationStage = 'experimental' | 'beta' | 'production';
|
||||
|
@ -30,7 +30,7 @@ export interface VisualizationListItem {
|
|||
export interface VisualizationsAppExtension {
|
||||
docTypes: string[];
|
||||
searchFields?: string[];
|
||||
toListItem: (savedObject: SavedObject) => VisualizationListItem;
|
||||
toListItem: (savedObject: SimpleSavedObject) => VisualizationListItem;
|
||||
}
|
||||
|
||||
export interface VisTypeAlias {
|
||||
|
|
|
@ -53,6 +53,7 @@ function mapHits(hit: any, url: string): GraphWorkspaceSavedObject {
|
|||
const source = hit.attributes;
|
||||
source.id = hit.id;
|
||||
source.url = url;
|
||||
source.updatedAt = hit.updatedAt;
|
||||
source.icon = 'fa-share-alt'; // looks like a graph
|
||||
return source;
|
||||
}
|
||||
|
|
|
@ -31,12 +31,13 @@ export const getLensAliasConfig = (): VisTypeAlias => ({
|
|||
docTypes: ['lens'],
|
||||
searchFields: ['title^3'],
|
||||
toListItem(savedObject) {
|
||||
const { id, type, attributes } = savedObject;
|
||||
const { id, type, updatedAt, attributes } = savedObject;
|
||||
const { title, description } = attributes as { title: string; description?: string };
|
||||
return {
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
updatedAt,
|
||||
editUrl: getEditPath(id),
|
||||
editApp: 'lens',
|
||||
icon: 'lensApp',
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
/* eslint-disable @typescript-eslint/consistent-type-definitions */
|
||||
|
||||
import { SavedObject } from '@kbn/core/types/saved_objects';
|
||||
|
||||
export type MapSavedObjectAttributes = {
|
||||
title: string;
|
||||
description?: string;
|
||||
|
@ -16,5 +14,3 @@ export type MapSavedObjectAttributes = {
|
|||
layerListJSON?: string;
|
||||
uiStateJSON?: string;
|
||||
};
|
||||
|
||||
export type MapSavedObject = SavedObject<MapSavedObjectAttributes>;
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { VisualizationsSetup, VisualizationStage } from '@kbn/visualizations-plugin/public';
|
||||
import type { SimpleSavedObject } from '@kbn/core/public';
|
||||
import type { SavedObject } from '@kbn/core/types/saved_objects';
|
||||
import type { MapSavedObject } from '../common/map_saved_object_type';
|
||||
import type { MapSavedObjectAttributes } from '../common/map_saved_object_type';
|
||||
import {
|
||||
APP_ID,
|
||||
APP_ICON,
|
||||
|
@ -38,12 +39,15 @@ export function getMapsVisTypeAlias(visualizations: VisualizationsSetup) {
|
|||
docTypes: [MAP_SAVED_OBJECT_TYPE],
|
||||
searchFields: ['title^3'],
|
||||
toListItem(savedObject: SavedObject) {
|
||||
const { id, type, attributes } = savedObject as MapSavedObject;
|
||||
const { id, type, updatedAt, attributes } =
|
||||
savedObject as SimpleSavedObject<MapSavedObjectAttributes>;
|
||||
const { title, description } = attributes;
|
||||
|
||||
return {
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
updatedAt,
|
||||
editUrl: getEditPath(id),
|
||||
editApp: APP_ID,
|
||||
icon: APP_ICON,
|
||||
|
|
|
@ -113,6 +113,7 @@ async function findMaps(searchQuery: string) {
|
|||
title: savedObject.attributes.title,
|
||||
description: savedObject.attributes.description,
|
||||
references: savedObject.references,
|
||||
updatedAt: savedObject.updatedAt,
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
*/
|
||||
|
||||
import { asyncForEach } from '@kbn/std';
|
||||
import { ISavedObjectsRepository } from '@kbn/core/server';
|
||||
import type { ISavedObjectsRepository, SavedObject } from '@kbn/core/server';
|
||||
import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants';
|
||||
import { MapSavedObject, MapSavedObjectAttributes } from '../../common/map_saved_object_type';
|
||||
import type { MapSavedObjectAttributes } from '../../common/map_saved_object_type';
|
||||
|
||||
export async function findMaps(
|
||||
savedObjectsClient: Pick<ISavedObjectsRepository, 'find'>,
|
||||
callback: (savedObject: MapSavedObject) => Promise<void>
|
||||
callback: (savedObject: SavedObject<MapSavedObjectAttributes>) => Promise<void>
|
||||
) {
|
||||
let nextPage = 1;
|
||||
let hasMorePages = false;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SavedObject } from '@kbn/core/server';
|
||||
import { asyncForEach } from '@kbn/std';
|
||||
import { KBN_FIELD_TYPES } from '@kbn/field-types';
|
||||
import { DataViewsService } from '@kbn/data-views-plugin/common';
|
||||
|
@ -15,7 +16,7 @@ import {
|
|||
ESSearchSourceDescriptor,
|
||||
LayerDescriptor,
|
||||
} from '../../../common/descriptor_types';
|
||||
import { MapSavedObject } from '../../../common/map_saved_object_type';
|
||||
import type { MapSavedObjectAttributes } from '../../../common/map_saved_object_type';
|
||||
import { IndexPatternStats } from './types';
|
||||
|
||||
/*
|
||||
|
@ -29,7 +30,7 @@ export class IndexPatternStatsCollector {
|
|||
this._indexPatternsService = indexPatternService;
|
||||
}
|
||||
|
||||
async push(savedObject: MapSavedObject) {
|
||||
async push(savedObject: SavedObject<MapSavedObjectAttributes>) {
|
||||
let layerList: LayerDescriptor[] = [];
|
||||
try {
|
||||
const { attributes } = injectReferences(savedObject);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue