-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
bulk assign
action to tag management (#84177)
* initial draft * move components to their own files * create services folder and move tags package * add assignment service * fix some types * prepare assign tag route * move server-side tag client under the `services` folder * add security check, move a lot of stuff. * design improvements * display tags in flyout * improve button and add notification on save * add action on tag rows * fix types * fix mock import paths * add lens to the list of assignable types * update generated doc * add base functional tests * move api to internal * add api/security test suites * add / use get_assignable_types API * fix feature control tests * fix assignable types propagation * rename actions folder to bulk_actions * extract actions to their own module * add common / server unit tests * add client-side assign tests * add some tests and tsdoc * typo * add getActions test * revert width change * fix typo in API * various minor improvements * typo * tsdoc on flyout page object * close flyout when leaving the page * fix bug when redirecting to SO management with a tag having whitespaces in its name * check for dupes in toAdd and toRemove * add lazy load to assign modal opener * add lazy load to edit/create modals * check if at least one assign or unassign tag id is specified * grammar * add explicit type existence check
- Loading branch information
1 parent
34be1e7
commit 446390d
Showing
137 changed files
with
4,100 additions
and
336 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
...ment/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.maxwidth.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [OverlayFlyoutOpenOptions](./kibana-plugin-core-public.overlayflyoutopenoptions.md) > [maxWidth](./kibana-plugin-core-public.overlayflyoutopenoptions.maxwidth.md) | ||
|
||
## OverlayFlyoutOpenOptions.maxWidth property | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
maxWidth?: boolean | number | string; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
...elopment/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.size.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [OverlayFlyoutOpenOptions](./kibana-plugin-core-public.overlayflyoutopenoptions.md) > [size](./kibana-plugin-core-public.overlayflyoutopenoptions.size.md) | ||
|
||
## OverlayFlyoutOpenOptions.size property | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
size?: EuiFlyoutSize; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
x-pack/plugins/saved_objects_tagging/common/assignments.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
/** | ||
* `type`+`id` tuple of a saved object | ||
*/ | ||
export interface ObjectReference { | ||
type: string; | ||
id: string; | ||
} | ||
|
||
/** | ||
* Represent an assignable saved object, as returned by the `_find_assignable_objects` API | ||
*/ | ||
export interface AssignableObject extends ObjectReference { | ||
icon?: string; | ||
title: string; | ||
tags: string[]; | ||
} | ||
|
||
export interface UpdateTagAssignmentsOptions { | ||
tags: string[]; | ||
assign: ObjectReference[]; | ||
unassign: ObjectReference[]; | ||
} | ||
|
||
export interface FindAssignableObjectsOptions { | ||
search?: string; | ||
maxResults?: number; | ||
types?: string[]; | ||
} | ||
|
||
/** | ||
* Return a string that can be used as an unique identifier for given saved object | ||
*/ | ||
export const getKey = ({ id, type }: ObjectReference) => `${type}|${id}`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
x-pack/plugins/saved_objects_tagging/common/http_api_types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { AssignableObject } from './assignments'; | ||
|
||
export interface FindAssignableObjectResponse { | ||
objects: AssignableObject[]; | ||
} | ||
|
||
export interface GetAssignableTypesResponse { | ||
types: string[]; | ||
} |
127 changes: 127 additions & 0 deletions
127
x-pack/plugins/saved_objects_tagging/common/references.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { SavedObjectReference } from 'src/core/types'; | ||
import { tagIdToReference, replaceTagReferences, updateTagReferences } from './references'; | ||
|
||
const ref = (type: string, id: string): SavedObjectReference => ({ | ||
id, | ||
type, | ||
name: `${type}-ref-${id}`, | ||
}); | ||
|
||
const tagRef = (id: string) => ref('tag', id); | ||
|
||
describe('tagIdToReference', () => { | ||
it('returns a reference for given tag id', () => { | ||
expect(tagIdToReference('some-tag-id')).toEqual({ | ||
id: 'some-tag-id', | ||
type: 'tag', | ||
name: 'tag-ref-some-tag-id', | ||
}); | ||
}); | ||
}); | ||
|
||
describe('replaceTagReferences', () => { | ||
it('updates the tag references', () => { | ||
expect( | ||
replaceTagReferences([tagRef('tag-1'), tagRef('tag-2'), tagRef('tag-3')], ['tag-2', 'tag-4']) | ||
).toEqual([tagRef('tag-2'), tagRef('tag-4')]); | ||
}); | ||
it('leaves the non-tag references unchanged', () => { | ||
expect( | ||
replaceTagReferences( | ||
[ref('dashboard', 'dash-1'), tagRef('tag-1'), ref('lens', 'lens-1'), tagRef('tag-2')], | ||
['tag-2', 'tag-4'] | ||
) | ||
).toEqual([ | ||
ref('dashboard', 'dash-1'), | ||
ref('lens', 'lens-1'), | ||
tagRef('tag-2'), | ||
tagRef('tag-4'), | ||
]); | ||
}); | ||
}); | ||
|
||
describe('updateTagReferences', () => { | ||
it('adds the `toAdd` tag references', () => { | ||
expect( | ||
updateTagReferences({ | ||
references: [tagRef('tag-1'), tagRef('tag-2')], | ||
toAdd: ['tag-3', 'tag-4'], | ||
}) | ||
).toEqual([tagRef('tag-1'), tagRef('tag-2'), tagRef('tag-3'), tagRef('tag-4')]); | ||
}); | ||
|
||
it('removes the `toRemove` tag references', () => { | ||
expect( | ||
updateTagReferences({ | ||
references: [tagRef('tag-1'), tagRef('tag-2'), tagRef('tag-3'), tagRef('tag-4')], | ||
toRemove: ['tag-1', 'tag-3'], | ||
}) | ||
).toEqual([tagRef('tag-2'), tagRef('tag-4')]); | ||
}); | ||
|
||
it('accepts both parameters at the same time', () => { | ||
expect( | ||
updateTagReferences({ | ||
references: [tagRef('tag-1'), tagRef('tag-2'), tagRef('tag-3'), tagRef('tag-4')], | ||
toRemove: ['tag-1', 'tag-3'], | ||
toAdd: ['tag-5', 'tag-6'], | ||
}) | ||
).toEqual([tagRef('tag-2'), tagRef('tag-4'), tagRef('tag-5'), tagRef('tag-6')]); | ||
}); | ||
|
||
it('does not create a duplicate reference when adding an already assigned tag', () => { | ||
expect( | ||
updateTagReferences({ | ||
references: [tagRef('tag-1'), tagRef('tag-2')], | ||
toAdd: ['tag-1', 'tag-3'], | ||
}) | ||
).toEqual([tagRef('tag-1'), tagRef('tag-2'), tagRef('tag-3')]); | ||
}); | ||
|
||
it('ignores non-existing `toRemove` ids', () => { | ||
expect( | ||
updateTagReferences({ | ||
references: [tagRef('tag-1'), tagRef('tag-2'), tagRef('tag-3')], | ||
toRemove: ['tag-2', 'unknown'], | ||
}) | ||
).toEqual([tagRef('tag-1'), tagRef('tag-3')]); | ||
}); | ||
|
||
it('throws if the same id is present in both `toAdd` and `toRemove`', () => { | ||
expect(() => | ||
updateTagReferences({ | ||
references: [tagRef('tag-1'), tagRef('tag-2'), tagRef('tag-3')], | ||
toAdd: ['tag-1', 'tag-2'], | ||
toRemove: ['tag-2', 'tag-3'], | ||
}) | ||
).toThrowErrorMatchingInlineSnapshot( | ||
`"Some ids from 'toAdd' also present in 'toRemove': [tag-2]"` | ||
); | ||
}); | ||
|
||
it('preserves the non-tag references', () => { | ||
expect( | ||
updateTagReferences({ | ||
references: [ | ||
ref('dashboard', 'dash-1'), | ||
tagRef('tag-1'), | ||
ref('lens', 'lens-1'), | ||
tagRef('tag-2'), | ||
], | ||
toAdd: ['tag-3'], | ||
toRemove: ['tag-1'], | ||
}) | ||
).toEqual([ | ||
ref('dashboard', 'dash-1'), | ||
ref('lens', 'lens-1'), | ||
tagRef('tag-2'), | ||
tagRef('tag-3'), | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { uniq, intersection } from 'lodash'; | ||
import { SavedObjectReference } from '../../../../src/core/types'; | ||
import { tagSavedObjectTypeName } from './constants'; | ||
|
||
/** | ||
* Create a {@link SavedObjectReference | reference} for given tag id. | ||
*/ | ||
export const tagIdToReference = (tagId: string): SavedObjectReference => ({ | ||
type: tagSavedObjectTypeName, | ||
id: tagId, | ||
name: `tag-ref-${tagId}`, | ||
}); | ||
|
||
/** | ||
* Update the given `references` array, replacing all the `tag` references with | ||
* references for the given `newTagIds`, while preserving all references to non-tag objects. | ||
*/ | ||
export const replaceTagReferences = ( | ||
references: SavedObjectReference[], | ||
newTagIds: string[] | ||
): SavedObjectReference[] => { | ||
return [ | ||
...references.filter(({ type }) => type !== tagSavedObjectTypeName), | ||
...newTagIds.map(tagIdToReference), | ||
]; | ||
}; | ||
|
||
/** | ||
* Update the given `references` array, adding references to `toAdd` tag ids and removing references | ||
* to `toRemove` tag ids. | ||
* All references to non-tag objects will be preserved. | ||
* | ||
* @remarks: Having the same id(s) in `toAdd` and `toRemove` will result in an error. | ||
*/ | ||
export const updateTagReferences = ({ | ||
references, | ||
toAdd = [], | ||
toRemove = [], | ||
}: { | ||
references: SavedObjectReference[]; | ||
toAdd?: string[]; | ||
toRemove?: string[]; | ||
}): SavedObjectReference[] => { | ||
const duplicates = intersection(toAdd, toRemove); | ||
if (duplicates.length > 0) { | ||
throw new Error(`Some ids from 'toAdd' also present in 'toRemove': [${duplicates.join(', ')}]`); | ||
} | ||
|
||
const nonTagReferences = references.filter(({ type }) => type !== tagSavedObjectTypeName); | ||
const newTagIds = uniq([ | ||
...references | ||
.filter(({ type }) => type === tagSavedObjectTypeName) | ||
.map(({ id }) => id) | ||
.filter((id) => !toRemove.includes(id)), | ||
...toAdd, | ||
]); | ||
|
||
return [...nonTagReferences, ...newTagIds.map(tagIdToReference)]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.