From b6ae8da13f5d5641798dd23a401539e12f19e701 Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Tue, 4 Mar 2025 15:24:47 +0100 Subject: [PATCH] [Discover] Move actions to utils --- .../tabbed_content/tabbed_content.tsx | 25 ++------ .../kbn-unified-tabs/src/utils/manage_tabs.ts | 58 +++++++++++++++++++ 2 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 src/platform/packages/shared/kbn-unified-tabs/src/utils/manage_tabs.ts diff --git a/src/platform/packages/shared/kbn-unified-tabs/src/components/tabbed_content/tabbed_content.tsx b/src/platform/packages/shared/kbn-unified-tabs/src/components/tabbed_content/tabbed_content.tsx index 5192681e45ba8..f4575c66695cd 100644 --- a/src/platform/packages/shared/kbn-unified-tabs/src/components/tabbed_content/tabbed_content.tsx +++ b/src/platform/packages/shared/kbn-unified-tabs/src/components/tabbed_content/tabbed_content.tsx @@ -12,6 +12,7 @@ import { htmlIdGenerator, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { TabsBar } from '../tabs_bar'; import { getTabAttributes } from '../../utils/get_tab_attributes'; import { getTabMenuActions } from '../../utils/get_tab_menu_actions'; +import { addTab, removeTab, selectTab } from '../../utils/manage_tabs'; import { TabItem } from '../../types'; export interface TabbedContentProps { @@ -59,39 +60,21 @@ export const TabbedContent: React.FC = ({ const onSelect = useCallback( (item: TabItem) => { - changeState((prevState) => ({ - ...prevState, - selectedItem: item, - })); + changeState((prevState) => selectTab(prevState, item)); }, [changeState] ); const onClose = useCallback( (item: TabItem) => { - changeState((prevState) => { - const nextItems = prevState.items.filter((prevItem) => prevItem.id !== item.id); - // TODO: better selection logic - const nextSelectedItem = nextItems.length ? nextItems[nextItems.length - 1] : null; - - return { - items: nextItems, - selectedItem: - prevState.selectedItem?.id !== item.id ? prevState.selectedItem : nextSelectedItem, - }; - }); + changeState((prevState) => removeTab(prevState, item)); }, [changeState] ); const onAdd = useCallback(() => { const newItem = createItem(); - changeState((prevState) => { - return { - items: [...prevState.items, newItem], - selectedItem: newItem, - }; - }); + changeState((prevState) => addTab(prevState, newItem)); }, [changeState, createItem]); const getTabMenuItems = useMemo(() => { diff --git a/src/platform/packages/shared/kbn-unified-tabs/src/utils/manage_tabs.ts b/src/platform/packages/shared/kbn-unified-tabs/src/utils/manage_tabs.ts new file mode 100644 index 0000000000000..d6144d754a2eb --- /dev/null +++ b/src/platform/packages/shared/kbn-unified-tabs/src/utils/manage_tabs.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { TabItem } from '../types'; + +interface TabsState { + items: TabItem[]; + selectedItem: TabItem | null; +} + +export const addTab = ({ items }: TabsState, item: TabItem): TabsState => { + return { + items: [...items, item], + selectedItem: item, + }; +}; + +export const removeTab = ({ items, selectedItem }: TabsState, item: TabItem): TabsState => { + const itemIndex = items.findIndex((i) => i.id === item.id); + + if (itemIndex === -1) { + return { + items, + selectedItem, + }; + } + + const nextItems = [...items]; + nextItems.splice(itemIndex, 1); + + if (selectedItem?.id !== item.id) { + return { + items: nextItems, + selectedItem, + }; + } + + const nextSelectedIndex = itemIndex === items.length - 1 ? itemIndex - 1 : itemIndex; + const nextSelectedItem = nextItems[nextSelectedIndex] || null; + + return { + items: nextItems, + selectedItem: nextSelectedItem, + }; +}; + +export const selectTab = ({ items, selectedItem }: TabsState, item: TabItem): TabsState => { + return { + items, + selectedItem: items.find((i) => i.id === item.id) || selectedItem, + }; +};