From eb0b11168fe12627b86773264bcaf2f027f8918a Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Thu, 18 May 2023 15:56:46 +0100 Subject: [PATCH] fix selection --- .../src/components/use_tag_filter_panel.tsx | 13 ++++++-- .../table_list/src/table_list_view.test.tsx | 8 +++-- .../table_list/src/table_list_view.tsx | 32 ++++++++++++++----- .../table_list/src/types.ts | 9 ++++++ .../dashboard_listing.test.tsx | 4 ++- .../saved_objects_tagging_oss/common/types.ts | 5 +-- .../containers/use_fetch_security_tags.ts | 4 +-- .../dashboards/pages/landing_page/index.tsx | 9 +++--- 8 files changed, 63 insertions(+), 21 deletions(-) diff --git a/packages/content-management/table_list/src/components/use_tag_filter_panel.tsx b/packages/content-management/table_list/src/components/use_tag_filter_panel.tsx index 2e37705a6a115..b0ab95e675377 100644 --- a/packages/content-management/table_list/src/components/use_tag_filter_panel.tsx +++ b/packages/content-management/table_list/src/components/use_tag_filter_panel.tsx @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import React, { useEffect, useState, useCallback } from 'react'; +import React, { useEffect, useState, useCallback, useMemo } from 'react'; import type { MouseEvent } from 'react'; import { Query, EuiFlexGroup, EuiFlexItem, EuiText, EuiHealth, EuiBadge } from '@elastic/eui'; import type { FieldValueOptionType } from '@elastic/eui'; @@ -39,6 +39,12 @@ export interface Params { fixedTagReferences?: Tag[] | null; } +const getTotalActiveFilters = (options: TagOptionItem[], fixedTagReferences?: Tag[] | null) => + Math.max( + fixedTagReferences?.length ?? 0, + options.filter((option) => option.checked === 'on').length ?? 0 + ); + export const useTagFilterPanel = ({ query, tagsToTableItemMap, @@ -55,7 +61,10 @@ export const useTagFilterPanel = ({ const [isInUse, setIsInUse] = useState(false); const [options, setOptions] = useState([]); const [tagSelection, setTagSelection] = useState({}); - const totalActiveFilters = Object.keys(tagSelection).length; + const totalActiveFilters = useMemo( + () => getTotalActiveFilters(options, fixedTagReferences), + [fixedTagReferences, options] + ); const onSelectChange = useCallback( (updatedOptions: TagOptionItem[]) => { diff --git a/packages/content-management/table_list/src/table_list_view.test.tsx b/packages/content-management/table_list/src/table_list_view.test.tsx index bfae40f22e38f..a84b19d815ad0 100644 --- a/packages/content-management/table_list/src/table_list_view.test.tsx +++ b/packages/content-management/table_list/src/table_list_view.test.tsx @@ -736,7 +736,9 @@ describe('TableListView', () => { await act(async () => { testBed = await setupTagFiltering({ findItems, - fixedTagReferences: [{ id: 'id-tag-1', name: 'tag-1', description: '', color: '' }], + fixedTagReferences: [ + { id: 'id-tag-1', name: 'tag-1', description: '', color: '', type: 'tag' }, + ], }); }); @@ -758,7 +760,9 @@ describe('TableListView', () => { await act(async () => { testBed = await setupTagFiltering({ findItems, - fixedTagReferences: [{ id: 'id-tag-1', name: 'tag-1', description: '', color: '' }], + fixedTagReferences: [ + { id: 'id-tag-1', name: 'tag-1', description: '', color: '', type: 'tag' }, + ], }); }); diff --git a/packages/content-management/table_list/src/table_list_view.tsx b/packages/content-management/table_list/src/table_list_view.tsx index 2cc69690979fe..3bd7f2547569d 100644 --- a/packages/content-management/table_list/src/table_list_view.tsx +++ b/packages/content-management/table_list/src/table_list_view.tsx @@ -43,7 +43,7 @@ import { getReducer } from './reducer'; import type { SortColumnField } from './components'; import { useTags } from './use_tags'; import { useInRouterContext, useUrlState } from './use_url_state'; -import { RowActions, TableItemsRowActions, Tag } from './types'; +import { RowActions, TableItemsRowActions, TagReference } from './types'; interface ContentEditorConfig extends Pick { @@ -108,7 +108,7 @@ export interface Props { @@ -244,16 +244,32 @@ const appendQuery = (q: Query, tagName: string) => { return q.addOrFieldValue('tag', tagName, true, 'eq'); }; -const getDefaultQuery = (initialQuery: string, fixedTagReferences: Tag[] | null | undefined) => { +const getDefaultQuery = ( + initialQuery: string, + fixedTagReferences: TagReference[] | null | undefined +) => { const query = new Query(Ast.create([]), undefined, initialQuery); - + const uniqueQueryArray = fixedTagReferences?.reduce((acc, { name }) => { + if (name && acc.indexOf(name) === -1) { + acc.push(name); + } + return acc; + }, []); return ( - fixedTagReferences?.reduce((q, ref) => { - return appendQuery(q, ref.name); + uniqueQueryArray?.reduce((q, ref) => { + return appendQuery(q, ref); }, query) ?? query ); }; +const getFindItemReference = ( + references: SavedObjectsFindOptionsReference[] | undefined, + fixedTagReferences?: TagReference[] | null | undefined +): SavedObjectsFindOptionsReference[] | undefined => { + const fixedTagFindReferences = fixedTagReferences?.map(({ id, type }) => ({ id, type })) ?? []; + return [...(references ?? []), ...fixedTagFindReferences]; +}; + function TableListViewComp({ additionalRightSideActions = [], children, @@ -404,7 +420,7 @@ function TableListViewComp({ }; const response = await findItems(searchQueryParsed, { - references, + references: getFindItemReference(references, fixedTagReferences), referencesToExclude, }); @@ -426,7 +442,7 @@ function TableListViewComp({ data: err, }); } - }, [searchQueryParser, searchQuery.text, findItems]); + }, [searchQueryParser, searchQuery.text, findItems, fixedTagReferences]); const updateQuery = useCallback( (query: Query) => { diff --git a/packages/content-management/table_list/src/types.ts b/packages/content-management/table_list/src/types.ts index c8e734a289451..2ba812c966b4c 100644 --- a/packages/content-management/table_list/src/types.ts +++ b/packages/content-management/table_list/src/types.ts @@ -11,6 +11,15 @@ export interface Tag { name: string; description: string; color: string; + type: string; +} + +export interface TagReference { + id: string; + name: string; + description: string; + color: string; + type: string; } export type TableRowAction = 'delete'; diff --git a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx index 539bba8470157..419453d73ae7d 100644 --- a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx @@ -70,7 +70,9 @@ test('fixedTagReferences is passed through', async () => { pluginServices.getServices().dashboardCapabilities.showWriteControls = false; let component: ReactWrapper; - const fixedTagReferences = [{ id: 'mockTagId', name: 'mockTagName', description: '', color: '' }]; + const fixedTagReferences = [ + { id: 'mockTagId', name: 'mockTagName', description: '', color: '', type: 'tag' }, + ]; await act(async () => { ({ component } = mountWith({ props: { fixedTagReferences } })); diff --git a/src/plugins/saved_objects_tagging_oss/common/types.ts b/src/plugins/saved_objects_tagging_oss/common/types.ts index e62639659b5f4..06e2cc2b8cc6b 100644 --- a/src/plugins/saved_objects_tagging_oss/common/types.ts +++ b/src/plugins/saved_objects_tagging_oss/common/types.ts @@ -7,10 +7,11 @@ */ export interface Tag { + color: string; + description: string; id: string; name: string; - description: string; - color: string; + type: string; } export interface TagAttributes { diff --git a/x-pack/plugins/security_solution/public/dashboards/containers/use_fetch_security_tags.ts b/x-pack/plugins/security_solution/public/dashboards/containers/use_fetch_security_tags.ts index 601f1abf8060c..6e8cb3eef6a6b 100644 --- a/x-pack/plugins/security_solution/public/dashboards/containers/use_fetch_security_tags.ts +++ b/x-pack/plugins/security_solution/public/dashboards/containers/use_fetch_security_tags.ts @@ -42,9 +42,9 @@ export const useFetchSecurityTags = () => { const tagsResult = useMemo(() => { if (tags?.length) { - return tags.map((t) => ({ id: t.id, ...t.attributes })); + return tags.map((t) => ({ id: t.id, type: 'tag', ...t.attributes })); } - return tag ? [{ id: tag.id, ...tag.attributes }] : undefined; + return tag ? [{ id: tag.id, type: 'tag', ...tag.attributes }] : undefined; }, [tags, tag]); return { diff --git a/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.tsx b/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.tsx index 8a8d6724bba28..8bfa8af6c005f 100644 --- a/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.tsx +++ b/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.tsx @@ -28,14 +28,15 @@ const getInitialFilterString = (securityTags: Tag[] | null | undefined) => { if (!securityTags) { return; } - const queryArray = securityTags?.reduce((acc, { name }) => { - if (name) { - acc.push(`"${name}"`); + const uniqueQueryArray = securityTags?.reduce((acc, { name }) => { + const nameString = `"${name}"`; + if (name && acc.indexOf(nameString) === -1) { + acc.push(nameString); } return acc; }, []); - const query = [...new Set(queryArray)].join(' or'); + const query = [uniqueQueryArray].join(' or'); return `tag:(${query})`; };