Skip to content

Commit a2c91f1

Browse files
[Maps] saved object tagging (#83197)
* add tag selector to save modal * save tag references onSave * populate tags when unwrapping attributes * tslint * update listing page to show tags * fix data-test-subj id in functional tests * i18n cleanup * tslint * remove unused import * use listingTable service for functional tests * tslint and fix mvt grid layer functional test * review feedback * add tags to all privileges and add test user to find, delete, get, get_all, and update tests * move functions to module scope Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
1 parent 6ea1940 commit a2c91f1

File tree

27 files changed

+603
-570
lines changed

27 files changed

+603
-570
lines changed

src/plugins/kibana_react/public/table_list_view/table_list_view.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export interface TableListViewProps {
5757
listingLimit: number;
5858
initialFilter: string;
5959
initialPageSize: number;
60-
noItemsFragment: JSX.Element;
60+
noItemsFragment?: JSX.Element;
6161
tableColumns: Array<EuiBasicTableColumn<any>>;
6262
tableListTitle: string;
6363
toastNotifications: ToastsStart;
@@ -73,7 +73,7 @@ export interface TableListViewProps {
7373
/**
7474
* Describes the content of the table. If not specified, the caption will be "This table contains {itemCount} rows."
7575
*/
76-
tableCaption: string;
76+
tableCaption?: string;
7777
searchFilters?: SearchFilterConfig[];
7878
}
7979

@@ -445,6 +445,7 @@ class TableListView extends React.Component<TableListViewProps, TableListViewSta
445445
defaultQuery: this.state.filter,
446446
box: {
447447
incremental: true,
448+
'data-test-subj': 'tableListSearchBox',
448449
},
449450
filters: searchFilters ?? [],
450451
};

test/functional/page_objects/dashboard_page.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,7 @@ export function DashboardPageProvider({ getService, getPageObjects }: FtrProvide
126126
*/
127127
public async onDashboardLandingPage() {
128128
log.debug(`onDashboardLandingPage`);
129-
return await testSubjects.exists('dashboardLandingPage', {
130-
timeout: 5000,
131-
});
129+
return await listingTable.onListingPage('dashboard');
132130
}
133131

134132
public async expectExistsDashboardLandingPage() {

test/functional/services/listing_table.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,19 @@
2020
import expect from '@kbn/expect';
2121
import { FtrProviderContext } from '../ftr_provider_context';
2222

23+
type AppName = 'visualize' | 'dashboard' | 'map';
24+
2325
export function ListingTableProvider({ getService, getPageObjects }: FtrProviderContext) {
2426
const testSubjects = getService('testSubjects');
2527
const find = getService('find');
2628
const log = getService('log');
2729
const retry = getService('retry');
2830
const { common, header } = getPageObjects(['common', 'header']);
29-
const prefixMap = { visualize: 'vis', dashboard: 'dashboard' };
31+
const prefixMap = { visualize: 'vis', dashboard: 'dashboard', map: 'map' };
3032

31-
/**
32-
* This class provides functions for dashboard and visualize landing pages
33-
*/
3433
class ListingTable {
3534
private async getSearchFilter() {
36-
const searchFilter = await find.allByCssSelector('main .euiFieldSearch');
37-
return searchFilter[0];
35+
return await testSubjects.find('tableListSearchBox');
3836
}
3937

4038
/**
@@ -86,9 +84,8 @@ export function ListingTableProvider({ getService, getPageObjects }: FtrProvider
8684

8785
/**
8886
* Returns items count on landing page
89-
* @param appName 'visualize' | 'dashboard'
9087
*/
91-
public async expectItemsCount(appName: 'visualize' | 'dashboard', count: number) {
88+
public async expectItemsCount(appName: AppName, count: number) {
9289
await retry.try(async () => {
9390
const elements = await find.allByCssSelector(
9491
`[data-test-subj^="${prefixMap[appName]}ListingTitleLink"]`
@@ -126,14 +123,8 @@ export function ListingTableProvider({ getService, getPageObjects }: FtrProvider
126123

127124
/**
128125
* Searches for item on Landing page and retruns items count that match `ListingTitleLink-${name}` pattern
129-
* @param appName 'visualize' | 'dashboard'
130-
* @param name item name
131126
*/
132-
public async searchAndExpectItemsCount(
133-
appName: 'visualize' | 'dashboard',
134-
name: string,
135-
count: number
136-
) {
127+
public async searchAndExpectItemsCount(appName: AppName, name: string, count: number) {
137128
await this.searchForItemWithName(name);
138129
await retry.try(async () => {
139130
const links = await testSubjects.findAll(
@@ -165,10 +156,8 @@ export function ListingTableProvider({ getService, getPageObjects }: FtrProvider
165156

166157
/**
167158
* Clicks item on Landing page by link name if it is present
168-
* @param appName 'dashboard' | 'visualize'
169-
* @param name item name
170159
*/
171-
public async clickItemLink(appName: 'dashboard' | 'visualize', name: string) {
160+
public async clickItemLink(appName: AppName, name: string) {
172161
await testSubjects.click(
173162
`${prefixMap[appName]}ListingTitleLink-${name.split(' ').join('-')}`
174163
);
@@ -204,6 +193,12 @@ export function ListingTableProvider({ getService, getPageObjects }: FtrProvider
204193
}
205194
});
206195
}
196+
197+
public async onListingPage(appName: AppName) {
198+
return await testSubjects.exists(`${appName}LandingPage`, {
199+
timeout: 5000,
200+
});
201+
}
207202
}
208203

209204
return new ListingTable();

x-pack/plugins/maps/kibana.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"savedObjects",
2020
"share"
2121
],
22-
"optionalPlugins": ["home"],
22+
"optionalPlugins": ["home", "savedObjectsTagging"],
2323
"ui": true,
2424
"server": true,
2525
"extraPublicDirs": ["common/constants"],

x-pack/plugins/maps/public/kibana_services.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export const getCoreI18n = () => coreStart.i18n;
4848
export const getSearchService = () => pluginsStart.data.search;
4949
export const getEmbeddableService = () => pluginsStart.embeddable;
5050
export const getNavigateToApp = () => coreStart.application.navigateToApp;
51+
export const getSavedObjectsTagging = () => pluginsStart.savedObjectsTagging;
5152

5253
// xpack.maps.* kibana.yml settings from this plugin
5354
let mapAppConfig: MapsConfigType;

x-pack/plugins/maps/public/map_attribute_service.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7+
import { SavedObjectReference } from 'src/core/types';
78
import { AttributeService } from '../../../../src/plugins/embeddable/public';
89
import { MapSavedObjectAttributes } from '../common/map_saved_object_type';
910
import { MAP_SAVED_OBJECT_TYPE } from '../common/constants';
@@ -14,11 +15,9 @@ import { getCoreOverlays, getEmbeddableService, getSavedObjectsClient } from './
1415
import { extractReferences, injectReferences } from '../common/migrations/references';
1516
import { MapByValueInput, MapByReferenceInput } from './embeddable/types';
1617

17-
export type MapAttributeService = AttributeService<
18-
MapSavedObjectAttributes,
19-
MapByValueInput,
20-
MapByReferenceInput
21-
>;
18+
type MapDoc = MapSavedObjectAttributes & { references?: SavedObjectReference[] };
19+
20+
export type MapAttributeService = AttributeService<MapDoc, MapByValueInput, MapByReferenceInput>;
2221

2322
let mapAttributeService: MapAttributeService | null = null;
2423

@@ -28,30 +27,37 @@ export function getMapAttributeService(): MapAttributeService {
2827
}
2928

3029
mapAttributeService = getEmbeddableService().getAttributeService<
31-
MapSavedObjectAttributes,
30+
MapDoc,
3231
MapByValueInput,
3332
MapByReferenceInput
3433
>(MAP_SAVED_OBJECT_TYPE, {
35-
saveMethod: async (attributes: MapSavedObjectAttributes, savedObjectId?: string) => {
36-
const { attributes: attributesWithExtractedReferences, references } = extractReferences({
37-
attributes,
34+
saveMethod: async (attributes: MapDoc, savedObjectId?: string) => {
35+
// AttributeService "attributes" contains "references" as a child.
36+
// SavedObjectClient "attributes" uses "references" as a sibling.
37+
// https://github.com/elastic/kibana/issues/83133
38+
const savedObjectClientReferences = attributes.references;
39+
const savedObjectClientAttributes = { ...attributes };
40+
delete savedObjectClientAttributes.references;
41+
const { attributes: updatedAttributes, references } = extractReferences({
42+
attributes: savedObjectClientAttributes,
43+
references: savedObjectClientReferences,
3844
});
3945

4046
const savedObject = await (savedObjectId
4147
? getSavedObjectsClient().update<MapSavedObjectAttributes>(
4248
MAP_SAVED_OBJECT_TYPE,
4349
savedObjectId,
44-
attributesWithExtractedReferences,
50+
updatedAttributes,
4551
{ references }
4652
)
4753
: getSavedObjectsClient().create<MapSavedObjectAttributes>(
4854
MAP_SAVED_OBJECT_TYPE,
49-
attributesWithExtractedReferences,
55+
updatedAttributes,
5056
{ references }
5157
));
5258
return { id: savedObject.id };
5359
},
54-
unwrapMethod: async (savedObjectId: string): Promise<MapSavedObjectAttributes> => {
60+
unwrapMethod: async (savedObjectId: string): Promise<MapDoc> => {
5561
const savedObject = await getSavedObjectsClient().get<MapSavedObjectAttributes>(
5662
MAP_SAVED_OBJECT_TYPE,
5763
savedObjectId
@@ -62,7 +68,7 @@ export function getMapAttributeService(): MapAttributeService {
6268
}
6369

6470
const { attributes } = injectReferences(savedObject);
65-
return attributes;
71+
return { ...attributes, references: savedObject.references };
6672
},
6773
checkForDuplicateTitle: (props: OnSaveProps) => {
6874
return checkForDuplicateTitle(

x-pack/plugins/maps/public/plugin.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import {
6363
setLicensingPluginStart,
6464
} from './licensed_features';
6565
import { EMSSettings } from '../common/ems_settings';
66+
import { SavedObjectTaggingPluginStart } from '../../saved_objects_tagging/public';
6667

6768
export interface MapsPluginSetupDependencies {
6869
inspector: InspectorSetupContract;
@@ -86,6 +87,7 @@ export interface MapsPluginStartDependencies {
8687
visualizations: VisualizationsStart;
8788
savedObjects: SavedObjectsStart;
8889
dashboard: DashboardStart;
90+
savedObjectsTagging?: SavedObjectTaggingPluginStart;
8991
}
9092

9193
/**

0 commit comments

Comments
 (0)