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] Replace dashboard listing with Kibana dashboard listing #155716

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
cbeb700
replace dashboard listing
angorayc Apr 25, 2023
ff32ec5
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Apr 25, 2023
576ec4a
styling
angorayc Apr 25, 2023
29f2a65
Merge branch 'dashboard-listing' of github.com:angorayc/kibana into d…
angorayc Apr 25, 2023
2fbf9b8
add fixed tag
angorayc May 16, 2023
7f33c9b
Merge remote-tracking branch 'upstream/main' into dashboard-listing
angorayc May 16, 2023
6fa35ce
disable actions
angorayc May 16, 2023
6b1d0b8
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine May 16, 2023
6a5a791
types
angorayc May 16, 2023
a9a63a5
Merge branch 'dashboard-listing' of github.com:angorayc/kibana into d…
angorayc May 16, 2023
6f04f3b
rm default value
angorayc May 16, 2023
0f04412
rm default value
angorayc May 16, 2023
205a5dc
Merge branch 'main' of github.com:elastic/kibana into dashboard-listing
angorayc May 17, 2023
498ae01
update tags selection behaviour
angorayc May 17, 2023
f92bca0
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine May 17, 2023
c961de4
Merge branch 'main' of github.com:elastic/kibana into dashboard-listing
angorayc May 17, 2023
55df917
Merge branch 'dashboard-listing' of github.com:angorayc/kibana into d…
angorayc May 17, 2023
fe9d202
unit tests
angorayc May 18, 2023
b743ea0
unit tests
angorayc May 18, 2023
eb0b111
fix selection
angorayc May 18, 2023
47ca980
fix types
angorayc May 18, 2023
770cfee
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine May 18, 2023
b797fc0
fix types
angorayc May 18, 2023
23728b5
Merge branch 'dashboard-listing' of github.com:angorayc/kibana into d…
angorayc May 18, 2023
de5584b
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine May 18, 2023
3bbac62
fix types
angorayc May 19, 2023
9581c92
Merge branch 'dashboard-listing' of github.com:angorayc/kibana into d…
angorayc May 19, 2023
3b84127
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine May 19, 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
50 changes: 30 additions & 20 deletions packages/content-management/table_list/src/components/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';

import type { Tag as TagReference } from '@kbn/saved-objects-tagging-plugin/common';
import { useServices } from '../services';
import type { Action } from '../actions';
import type {
Expand All @@ -29,6 +30,7 @@ import type {
UserContentCommonSchema,
} from '../table_list_view';
import type { TableItemsRowActions } from '../types';

import { TableSortSelect } from './table_sort_select';
import { TagFilterPanel } from './tag_filter_panel';
import { useTagFilterPanel } from './use_tag_filter_panel';
Expand All @@ -46,43 +48,47 @@ type TagManagementProps = Pick<
>;

interface Props<T extends UserContentCommonSchema> extends State<T>, TagManagementProps {
clearTagSelection: () => void;
deleteItems: TableListViewProps<T>['deleteItems'];
dispatch: Dispatch<Action<T>>;
entityName: string;
entityNamePlural: string;
isFetchingItems: boolean;
tableCaption: string;
tableColumns: Array<EuiBasicTableColumn<T>>;
fixedTag?: string;
hasUpdatedAtMetadata: boolean;
deleteItems: TableListViewProps<T>['deleteItems'];
tableItemsRowActions: TableItemsRowActions;
isFetchingItems: boolean;
onSortChange: (column: SortColumnField, direction: Direction) => void;
onTableChange: (criteria: CriteriaWithPagination<T>) => void;
onTableSearchChange: (arg: { query: Query | null; queryText: string }) => void;
clearTagSelection: () => void;
tableCaption: string;
tableColumns: Array<EuiBasicTableColumn<T>>;
tableItemsRowActions: TableItemsRowActions;
fixedTagReferences?: TagReference[] | null;
}

export function Table<T extends UserContentCommonSchema>({
addOrRemoveExcludeTagFilter,
addOrRemoveIncludeTagFilter,
clearTagSelection,
deleteItems,
dispatch,
items,
entityName,
entityNamePlural,
fixedTag,
hasUpdatedAtMetadata,
isFetchingItems,
items,
onSortChange,
onTableChange,
onTableSearchChange,
pagination,
searchQuery,
selectedIds,
pagination,
tableCaption,
tableColumns,
tableItemsRowActions,
tableSort,
hasUpdatedAtMetadata,
entityName,
entityNamePlural,
tagsToTableItemMap,
tableItemsRowActions,
deleteItems,
tableCaption,
onTableChange,
onTableSearchChange,
onSortChange,
addOrRemoveExcludeTagFilter,
addOrRemoveIncludeTagFilter,
clearTagSelection,
fixedTagReferences,
}: Props<T>) {
const { getTagList } = useServices();

Expand Down Expand Up @@ -151,6 +157,7 @@ export function Table<T extends UserContentCommonSchema>({
tagsToTableItemMap,
addOrRemoveExcludeTagFilter,
addOrRemoveIncludeTagFilter,
fixedTagReferences,
});

const tableSortSelectFilter = useMemo<SearchFilterConfig>(() => {
Expand All @@ -172,6 +179,7 @@ export function Table<T extends UserContentCommonSchema>({
return {
type: 'custom_component',
component: () => {
const disableActions = fixedTagReferences != null;
return (
<TagFilterPanel
isPopoverOpen={isPopoverOpen}
Expand All @@ -182,11 +190,13 @@ export function Table<T extends UserContentCommonSchema>({
onFilterButtonClick={onFilterButtonClick}
onSelectChange={onSelectChange}
clearTagSelection={clearTagSelection}
disableActions={disableActions}
/>
);
},
};
}, [
fixedTagReferences,
isPopoverOpen,
isInUse,
closePopover,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,25 @@ const saveBtnWrapperCSS = css`
interface Props {
clearTagSelection: () => void;
closePopover: () => void;
isPopoverOpen: boolean;
disableActions?: boolean;
isInUse: boolean;
options: TagOptionItem[];
totalActiveFilters: number;
isPopoverOpen: boolean;
onFilterButtonClick: () => void;
onSelectChange: (updatedOptions: TagOptionItem[]) => void;
options: TagOptionItem[];
totalActiveFilters: number;
}

export const TagFilterPanel: FC<Props> = ({
isPopoverOpen,
clearTagSelection,
closePopover,
disableActions,
isInUse,
options,
totalActiveFilters,
isPopoverOpen,
onFilterButtonClick,
onSelectChange,
closePopover,
clearTagSelection,
options,
totalActiveFilters,
}) => {
const { euiTheme } = useEuiTheme();
const { navigateToUrl, currentAppId$, getTagManagementUrl } = useServices();
Expand Down Expand Up @@ -122,18 +124,24 @@ 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}>
{i18n.translate(
'contentManagement.tableList.tagFilterPanel.clearSelectionButtonLabelLabel',
{
defaultMessage: 'Clear selection',
}
)}
</EuiButtonEmpty>
)}
</EuiFlexItem>
{!disableActions && (
<EuiFlexItem grow={false}>
{totalActiveFilters > 0 && (
<EuiButtonEmpty
flush="both"
onClick={clearTagSelection}
css={clearSelectionBtnCSS}
>
{i18n.translate(
'contentManagement.tableList.tagFilterPanel.clearSelectionButtonLabelLabel',
{
defaultMessage: 'Clear selection',
}
)}
</EuiButtonEmpty>
)}
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiPopoverTitle>
<EuiSelectable<any>
Expand All @@ -156,6 +164,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,11 +5,12 @@
* 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 as TagReference } from '@kbn/saved-objects-tagging-plugin/common';
import type { Tag } from '../types';

const isMac = navigator.platform.toLowerCase().indexOf('mac') >= 0;
Expand All @@ -36,14 +37,22 @@ export interface Params {
getTagList: () => Tag[];
addOrRemoveIncludeTagFilter: (tag: Tag) => void;
addOrRemoveExcludeTagFilter: (tag: Tag) => void;
fixedTagReferences?: TagReference[] | 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,
getTagList,
addOrRemoveExcludeTagFilter,
addOrRemoveIncludeTagFilter,
fixedTagReferences,
}: 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 @@ -53,21 +62,31 @@ export const useTagFilterPanel = ({
const [isInUse, setIsInUse] = useState(false);
const [options, setOptions] = useState<TagOptionItem[]>([]);
const [tagSelection, setTagSelection] = useState<TagSelection>({});
const totalActiveFilters = Object.keys(tagSelection).length;
const totalActiveFilters = useMemo(
() => getTotalActiveFilters(options, fixedTagReferences),
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we pass options and not tagSelection ? I would also pass an array if fixedTagReferences is undefined or null to make getTotalActiveFilters simpler

const getTotalActiveFilters = (
  tagSelection: TagSelection,
  fixedTagReferences: TagReference[]
) =>
  Math.max(
    fixedTagReferences.length,
    Object.keys(tagSelection).length
  );

const totalActiveFilters = useMemo(
  () => getTotalActiveFilters(tagSelection, fixedTagReferences ?? []),
  [fixedTagReferences, tagSelection]
);
...

Copy link
Contributor

Choose a reason for hiding this comment

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

It could really just be this

const totalActiveFilters = useMemo(() => (
    Math.max((fixedTagReferences ?? []).length, Object.keys(tagSelection).length)
  )),
  [fixedTagReferences, tagSelection]
);
...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As the tagSelection seemed to have problem displaying the actual count when a few tags sharing the same name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Screenshot 2023-05-23 at 15 30 45

[fixedTagReferences, options]
);

const onSelectChange = useCallback(
(updatedOptions: TagOptionItem[]) => {
// Note: see data flow comment in useEffect() below
const diff = updatedOptions.find((item, index) => item.checked !== options[index].checked);

if (fixedTagReferences?.find((ref) => ref.name === diff?.tag.name)) {
return;
}
if (diff) {
addOrRemoveIncludeTagFilter(diff.tag);
}
},
[options, addOrRemoveIncludeTagFilter]
[fixedTagReferences, options, addOrRemoveIncludeTagFilter]
);

const onOptionClick = useCallback(
(tag: Tag) => (e: MouseEvent) => {
if (fixedTagReferences?.find((ref) => ref.name === tag.name)) {
return;
}
const withModifierKey = (isMac && e.metaKey) || (!isMac && e.ctrlKey);

if (withModifierKey) {
Expand All @@ -76,7 +95,7 @@ export const useTagFilterPanel = ({
addOrRemoveIncludeTagFilter(tag);
}
},
[addOrRemoveIncludeTagFilter, addOrRemoveExcludeTagFilter]
[addOrRemoveExcludeTagFilter, addOrRemoveIncludeTagFilter, fixedTagReferences]
);

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

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

const onFilterButtonClick = useCallback(() => {
setIsPopoverOpen((prev) => !prev);
Expand Down
Loading