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

[SecuritySolution] Dashboard listing UI #160540

Merged
merged 41 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
716fd81
replace dashboard listing
angorayc Jun 26, 2023
071dfb7
styling
angorayc Apr 25, 2023
eb41945
add fixed tag
angorayc May 16, 2023
aac6c3c
disable actions
angorayc May 16, 2023
df89974
default selected tags
angorayc Jun 26, 2023
3fa5710
fix tag types
angorayc Jun 26, 2023
93237cd
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 26, 2023
a08e4ce
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 26, 2023
ce5e867
fix types
angorayc Jun 27, 2023
59a293d
unit tests
angorayc Jun 27, 2023
0413ea0
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 27, 2023
3429a79
consume TableListViewTable from dashboard listing
angorayc Jun 27, 2023
c51202c
revert tagReferences
angorayc Jun 27, 2023
94c0758
fix filter count
angorayc Jun 27, 2023
c86641c
rename
angorayc Jun 27, 2023
7e8ce70
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 28, 2023
8573325
styling
angorayc Jun 28, 2023
884643f
Merge branch 'dashboard-listing' of github.com:angorayc/kibana into d…
angorayc Jun 28, 2023
ffebde7
unit test
angorayc Jun 28, 2023
288e21e
unit tests
angorayc Jun 28, 2023
7b068b2
Merge branch 'main' of github.com:elastic/kibana into dashboard-listing
angorayc Jun 28, 2023
ab434ac
revert changes for fixing active tag count
angorayc Jun 28, 2023
875b3b9
add tests
angorayc Jun 28, 2023
a578b94
types
angorayc Jun 28, 2023
f1ffe31
Merge branch 'main' into dashboard-listing
angorayc Jun 28, 2023
521e978
revert change
angorayc Jun 30, 2023
d11ff02
Merge branch 'main' of github.com:elastic/kibana into dashboard-listing
angorayc Jun 30, 2023
0b5c270
export dashboardListingTable
angorayc Jun 30, 2023
060bca6
Merge branch 'main' of github.com:elastic/kibana into dashboard-listing
angorayc Jun 30, 2023
448ee22
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 30, 2023
20d1511
types
angorayc Jun 30, 2023
cbc4b7d
Merge branch 'dashboard-listing' of github.com:angorayc/kibana into d…
angorayc Jun 30, 2023
d6e2435
test
angorayc Jun 30, 2023
34ba502
Implement review sugestions
machadoum Jul 5, 2023
cad6053
Merge branch 'main' into dashboard-listing
angorayc Jul 18, 2023
59bd25a
review
angorayc Jul 18, 2023
2afacc4
review
angorayc Jul 18, 2023
93ee16a
Merge branch 'main' of github.com:elastic/kibana into dashboard-listing
angorayc Jul 24, 2023
df1000c
use savedObjectsTagging client
angorayc Jul 24, 2023
5b028b0
unit test
angorayc Jul 24, 2023
c0ffaea
review
angorayc Jul 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
type TableListViewTableProps,
type UserContentCommonSchema,
} from '@kbn/content-management-table-list-view-table';
import { EuiPaddingSize } from '@elastic/eui';
import { SavedObjectsReference } from '@kbn/content-management-content-editor/src/services';

export type TableListViewProps<T extends UserContentCommonSchema = UserContentCommonSchema> = Pick<
TableListViewTableProps<T>,
Expand Down Expand Up @@ -46,6 +48,10 @@ export type TableListViewProps<T extends UserContentCommonSchema = UserContentCo
*/
additionalRightSideActions?: ReactNode[];
children?: ReactNode | undefined;
tagReferences?: SavedObjectsReference[] | undefined;
withPageTemplateHeader?: boolean;
restrictPageSectionWidth?: boolean;
pageSectionPadding?: EuiPaddingSize;
};

export const TableListView = <T extends UserContentCommonSchema>({
Expand Down Expand Up @@ -73,6 +79,10 @@ export const TableListView = <T extends UserContentCommonSchema>({
titleColumnName,
additionalRightSideActions,
withoutPageTemplateWrapper,
tagReferences,
withPageTemplateHeader,
restrictPageSectionWidth,
pageSectionPadding,
}: TableListViewProps<T>) => {
const PageTemplate = withoutPageTemplateWrapper
? (React.Fragment as unknown as typeof KibanaPageTemplate)
Expand All @@ -83,13 +93,19 @@ export const TableListView = <T extends UserContentCommonSchema>({

return (
<PageTemplate panelled data-test-subj={pageDataTestSubject}>
<KibanaPageTemplate.Header
pageTitle={<span id={headingId}>{title}</span>}
description={description}
rightSideItems={additionalRightSideActions?.slice(0, 2)}
data-test-subj="top-nav"
/>
<KibanaPageTemplate.Section aria-labelledby={hasInitialFetchReturned ? headingId : undefined}>
{withPageTemplateHeader && (
<KibanaPageTemplate.Header
pageTitle={<span id={headingId}>{title}</span>}
description={description}
rightSideItems={additionalRightSideActions?.slice(0, 2)}
data-test-subj="top-nav"
/>
)}
<KibanaPageTemplate.Section
aria-labelledby={hasInitialFetchReturned ? headingId : undefined}
restrictWidth={restrictPageSectionWidth}
paddingSize={pageSectionPadding}
>
{/* Any children passed to the component */}
{children}

Expand Down Expand Up @@ -121,6 +137,7 @@ export const TableListView = <T extends UserContentCommonSchema>({
}
}}
setPageDataTestSubject={setPageDataTestSubject}
tagReferences={tagReferences}
/>
</KibanaPageTemplate.Section>
</PageTemplate>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';

import { useServices } from '../services';
import { SavedObjectsReference, useServices } from '../services';
import type { Action } from '../actions';
import type {
State as TableListViewState,
Expand Down Expand Up @@ -61,6 +61,7 @@ interface Props<T extends UserContentCommonSchema> extends State<T>, TagManageme
onTableChange: (criteria: CriteriaWithPagination<T>) => void;
onTableSearchChange: (arg: { query: Query | null; queryText: string }) => void;
clearTagSelection: () => void;
tagReferences?: SavedObjectsReference[] | undefined;
}

export function Table<T extends UserContentCommonSchema>({
Expand All @@ -86,6 +87,7 @@ export function Table<T extends UserContentCommonSchema>({
addOrRemoveExcludeTagFilter,
addOrRemoveIncludeTagFilter,
clearTagSelection,
tagReferences,
}: Props<T>) {
const { getTagList } = useServices();

Expand Down Expand Up @@ -150,7 +152,12 @@ export function Table<T extends UserContentCommonSchema>({
totalActiveFilters,
} = useTagFilterPanel({
query: searchQuery.query,
getTagList,
getTagList: useCallback(() => {
const tags = getTagList();

return tags;
}, [getTagList]),
tagReferences,
tagsToTableItemMap,
addOrRemoveExcludeTagFilter,
addOrRemoveIncludeTagFilter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export const TagFilterPanel: FC<Props> = ({
<EuiPopoverTitle paddingSize="m" css={popoverTitleCSS}>
<EuiFlexGroup>
<EuiFlexItem>Tags</EuiFlexItem>

<EuiFlexItem grow={false}>
{totalActiveFilters > 0 && (
<EuiButtonEmpty flush="both" onClick={clearTagSelection} css={clearSelectionBtnCSS}>
Expand Down Expand Up @@ -156,6 +157,7 @@ export const TagFilterPanel: FC<Props> = ({
);
}}
</EuiSelectable>

<EuiPopoverFooter paddingSize="m">
<EuiFlexGroup direction="column" alignItems="center" gutterSize="s">
<EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
* 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';

import type { Tag } from '../types';
import { SavedObjectsReference } from '../services';

const isMac = navigator.platform.toLowerCase().indexOf('mac') >= 0;

Expand All @@ -36,6 +37,7 @@ export interface Params {
getTagList: () => Tag[];
addOrRemoveIncludeTagFilter: (tag: Tag) => void;
addOrRemoveExcludeTagFilter: (tag: Tag) => void;
tagReferences?: SavedObjectsReference[] | undefined;
}

export const useTagFilterPanel = ({
Expand All @@ -44,6 +46,7 @@ export const useTagFilterPanel = ({
getTagList,
addOrRemoveExcludeTagFilter,
addOrRemoveIncludeTagFilter,
tagReferences,
}: Params) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
// When the panel is "in use" it means that it is opened and the user is interacting with it.
Expand All @@ -52,8 +55,26 @@ export const useTagFilterPanel = ({
// "isInUse" state which disable the transition.
const [isInUse, setIsInUse] = useState(false);
const [options, setOptions] = useState<TagOptionItem[]>([]);
const [tagSelection, setTagSelection] = useState<TagSelection>({});
const totalActiveFilters = Object.keys(tagSelection).length;
const [tagSelection, setTagSelection] = useState<TagSelection>(
tagReferences
? tagReferences.reduce((acc, obj) => {
acc[obj.name] = 'include';
return acc;
}, {} as TagSelection)
: {}
);
const totalActiveFilters = useMemo(
() =>
Object.keys(tagSelection).reduce((acc, currentOption) => {
const inTagReferences = tagReferences?.find((ref) => ref.name === currentOption);
acc +=
inTagReferences != null
? tagReferences?.filter((ref) => ref.name === currentOption).length ?? 0
: 1;
return acc;
}, 0),
[tagReferences, tagSelection]
);
Copy link
Contributor Author

@angorayc angorayc Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to fix this scenario: (When more than one tags with the same name exist, it show the count as 1, expected to be 2)
incorrect_tag_counts


const onSelectChange = useCallback(
(updatedOptions: TagOptionItem[]) => {
Expand All @@ -76,7 +97,7 @@ export const useTagFilterPanel = ({
addOrRemoveIncludeTagFilter(tag);
}
},
[addOrRemoveIncludeTagFilter, addOrRemoveExcludeTagFilter]
[addOrRemoveExcludeTagFilter, addOrRemoveIncludeTagFilter]
);

const updateTagList = useCallback(() => {
Expand Down Expand Up @@ -118,7 +139,7 @@ export const useTagFilterPanel = ({
});

setOptions(tagsToSelectOptions);
}, [getTagList, tagsToTableItemMap, tagSelection, onOptionClick]);
}, [getTagList, tagSelection, onOptionClick, tagsToTableItemMap]);

const onFilterButtonClick = useCallback(() => {
setIsPopoverOpen((prev) => !prev);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
CriteriaWithPagination,
Query,
Ast,
EuiPaddingSize,
} from '@elastic/eui';
import { keyBy, uniq, get } from 'lodash';
import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -91,7 +92,7 @@ export interface TableListViewTableProps<
*/
editItem?(item: T): void;
/**
* Handler to set edit action visiblity per item.
* Handler to set edit action visibility per item.
*/
showEditActionForItem?(item: T): boolean;
/**
Expand All @@ -105,12 +106,16 @@ export interface TableListViewTableProps<
* @deprecated
*/
withoutPageTemplateWrapper?: boolean;
withPageTemplateHeader?: boolean;
contentEditor?: ContentEditorConfig;

tableCaption: string;
refreshListBouncer?: boolean;
onFetchSuccess: () => void;
setPageDataTestSubject: (subject: string) => void;
restrictPageSectionWidth?: boolean;
pageSectionPadding?: EuiPaddingSize;
tagReferences?: SavedObjectsReference[] | undefined;
}

export interface State<T extends UserContentCommonSchema = UserContentCommonSchema> {
Expand Down Expand Up @@ -184,7 +189,7 @@ const urlStateDeserializer = (params: URLQueryParams): URLState => {
}
});

// For backward compability with the Dashboard app we will support both "s" and "title" passed
// For backward compatibility with the Dashboard app we will support both "s" and "title" passed
// in the query params. We might want to stop supporting both in a future release (v9.0?)
stateFromURL.s = sanitizedParams.s ?? sanitizedParams.title;

Expand Down Expand Up @@ -242,6 +247,35 @@ const tableColumnMetadata = {
},
} as const;

const appendQuery = (q: Query, tagName: string) => {
return q.addOrFieldValue('tag', tagName, true, 'eq');
};

const getDefaultQuery = (
initialQuery: string,
tagReferences: SavedObjectsReference[] | null | undefined
) => {
const query = new Query(Ast.create([]), undefined, initialQuery);
const uniqueQueryArray = tagReferences?.reduce<string[]>((acc, { name }) => {
if (name && acc.indexOf(name) === -1) {
acc.push(name);
}
return acc;
}, []);
return (
uniqueQueryArray?.reduce((q, ref) => {
return appendQuery(q, ref);
}, query) ?? query
);
};

const getFindItemReference = (
references: SavedObjectsFindOptionsReference[] | undefined,
tagReferences?: SavedObjectsReference[] | undefined
): SavedObjectsFindOptionsReference[] | undefined => {
return [...(references ?? []), ...(tagReferences?.map(({ id, type }) => ({ id, type })) ?? [])];
};

function TableListViewTableComp<T extends UserContentCommonSchema>({
tableCaption,
entityName,
Expand All @@ -268,6 +302,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
onFetchSuccess,
refreshListBouncer,
setPageDataTestSubject,
tagReferences,
}: TableListViewTableProps<T>) {
useEffect(() => {
setPageDataTestSubject(`${entityName}LandingPage`);
Expand Down Expand Up @@ -304,6 +339,12 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
getTagList,
} = useServices();

const getTagListing = useCallback(() => {
const tags = getTagList();

return tags;
}, [getTagList]);

const openContentEditor = useOpenContentEditor();

const isInRouterContext = useInRouterContext();
Expand Down Expand Up @@ -335,7 +376,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
selectedIds: [],
searchQuery:
initialQuery !== undefined
? { text: initialQuery, query: new Query(Ast.create([]), undefined, initialQuery) }
? { text: initialQuery, query: getDefaultQuery(initialQuery, tagReferences) }
: { text: '', query: new Query(Ast.create([]), undefined, '') },
pagination: {
pageIndex: 0,
Expand All @@ -348,7 +389,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
direction: 'asc',
},
}),
[initialPageSize, initialQuery]
[initialPageSize, initialQuery, tagReferences]
);

const [state, dispatch] = useReducer(reducer, initialState);
Expand Down Expand Up @@ -385,9 +426,16 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
referencesToExclude,
} = searchQueryParser
? await searchQueryParser(searchQuery.text)
: { searchQuery: searchQuery.text, references: undefined, referencesToExclude: undefined };

const response = await findItems(searchQueryParsed, { references, referencesToExclude });
: {
searchQuery: searchQuery.text,
references: tagReferences ?? undefined,
referencesToExclude: undefined,
};

const response = await findItems(searchQueryParsed, {
references: getFindItemReference(references, tagReferences),
referencesToExclude,
});

if (!isMounted.current) {
return;
Expand All @@ -409,7 +457,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
data: err,
});
}
}, [searchQueryParser, searchQuery.text, findItems, onFetchSuccess]);
}, [searchQueryParser, searchQuery.text, findItems, onFetchSuccess, tagReferences]);

useEffect(() => {
fetchItems();
Expand Down Expand Up @@ -444,7 +492,9 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
const inspectItem = useCallback(
(item: T) => {
const tags = getTagIdsFromReferences(item.references).map((_id) => {
return item.references.find(({ id: refId }) => refId === _id) as SavedObjectsReference;
return item.references.find(({ id: refId }) => {
return refId === _id;
}) as SavedObjectsReference;
});

const close = openContentEditor({
Expand Down Expand Up @@ -823,7 +873,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
termMatch = searchTerm;

if (references?.length || referencesToExclude?.length) {
const allTags = getTagList();
angorayc marked this conversation as resolved.
Show resolved Hide resolved
const allTags = getTagListing();

if (references?.length) {
references.forEach(({ id: refId }) => {
Expand Down Expand Up @@ -879,7 +929,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({

updateQueryFromURL(urlState.s);
updateSortFromURL(urlState.sort);
}, [urlState, searchQueryParser, getTagList, urlStateEnabled]);
}, [urlState, searchQueryParser, getTagListing, urlStateEnabled]);

useEffect(() => {
isMounted.current = true;
Expand Down Expand Up @@ -969,6 +1019,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
addOrRemoveIncludeTagFilter={addOrRemoveIncludeTagFilter}
addOrRemoveExcludeTagFilter={addOrRemoveExcludeTagFilter}
clearTagSelection={clearTagSelection}
tagReferences={tagReferences}
/>

{/* Delete modal */}
Expand Down
Loading