From d621515e6eb5f62d1f69e34ce771ca8c7abaefcb Mon Sep 17 00:00:00 2001 From: Sergei Samokhvalov Date: Mon, 15 Jan 2024 10:46:57 +0100 Subject: [PATCH] Refactor helper getWorkbookBreadcrumbsItems (#381) * Refactor helper getWorkbookBreadcrumbsItems * Fix after review * Fix types * Add catch for getting breadcrumbs * Add condition for set breadcrumbs * Fix type * Fix type * Fix case, when have not collection id --- .../components/EntryPanel/EntryPanel.tsx | 12 ++-- .../EntryBreadcrumbs/EntryBreadcrumbs.tsx | 21 ++++--- src/ui/components/EntryBreadcrumbs/helpers.ts | 55 +++++++++++++------ .../types/components/EntryBreadcrumbs.ts | 3 +- src/ui/units/workbooks/store/actions/index.ts | 40 ++++++++++++-- .../workbooks/store/reducers/workbook-page.ts | 3 + .../units/workbooks/store/selectors/index.ts | 3 + 7 files changed, 101 insertions(+), 36 deletions(-) diff --git a/src/ui/components/ActionPanel/components/EntryPanel/EntryPanel.tsx b/src/ui/components/ActionPanel/components/EntryPanel/EntryPanel.tsx index 33abd3adc3..09e824b6f6 100644 --- a/src/ui/components/ActionPanel/components/EntryPanel/EntryPanel.tsx +++ b/src/ui/components/ActionPanel/components/EntryPanel/EntryPanel.tsx @@ -12,7 +12,7 @@ import {ActionPanelQA} from 'shared'; import {DatalensGlobalState, EntryDialogues, sdk} from 'ui'; import {registry} from 'ui/registry'; import {addWorkbookInfo, resetWorkbookPermissions} from 'units/workbooks/store/actions'; -import {selectWorkbookName} from 'units/workbooks/store/selectors'; +import {selectWorkbookBreadcrumbs, selectWorkbookName} from 'units/workbooks/store/selectors'; import type {GetEntryResponse} from '../../../../../shared/schema'; import {DL} from '../../../../constants/common'; @@ -104,7 +104,7 @@ class EntryPanel extends React.Component { const workbookId = this.state.entry?.workbookId; if (workbookId) { - this.props.actions.addWorkbookInfo(workbookId); + this.props.actions.addWorkbookInfo(workbookId, true); } } @@ -113,7 +113,7 @@ class EntryPanel extends React.Component { const prevWorkbookId = prevProps.entry?.workbookId; if (prevWorkbookId !== workbookId && workbookId) { - this.props.actions.addWorkbookInfo(workbookId); + this.props.actions.addWorkbookInfo(workbookId, true); } if (prevWorkbookId && !workbookId) { @@ -122,7 +122,7 @@ class EntryPanel extends React.Component { } render() { - const {children} = this.props; + const {children, workbookName, workbookBreadcrumbs} = this.props; const { entry: {isFavorite} = {isFavorite: undefined}, entry, @@ -141,7 +141,8 @@ class EntryPanel extends React.Component {
@@ -336,6 +337,7 @@ const mapStateToProps = (state: DatalensGlobalState, ownProps: OwnProps) => { return { workbookName: selectWorkbookName(state, workbookId), + workbookBreadcrumbs: selectWorkbookBreadcrumbs(state), }; }; diff --git a/src/ui/components/EntryBreadcrumbs/EntryBreadcrumbs.tsx b/src/ui/components/EntryBreadcrumbs/EntryBreadcrumbs.tsx index 4d3b8613f1..ae3233f5bc 100644 --- a/src/ui/components/EntryBreadcrumbs/EntryBreadcrumbs.tsx +++ b/src/ui/components/EntryBreadcrumbs/EntryBreadcrumbs.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Breadcrumbs, - BreadcrumbsProps, + BreadcrumbsItem, FirstDisplayedItemsCount, LastDisplayedItemsCount, } from '@gravity-ui/uikit'; @@ -17,17 +17,22 @@ import './EntryBreadcrumbs.scss'; const b = block('entry-panel-breadcrumbs'); export const EntryBreadcrumbs = (props: EntryBreadcrumbsProps) => { - const {renderRootContent, entry, workbookName} = props; + const {renderRootContent, entry, workbookName, workbookBreadcrumbs} = props; const history = useHistory(); const location = useLocation(); - const breadcrumbsItems: BreadcrumbsProps['items'] = getWorkbookBreadcrumbsItems({ - entry, - workbookName, - history, - location, - }); + let breadcrumbsItems: BreadcrumbsItem[] = []; + + if (entry?.workbookId) { + breadcrumbsItems = getWorkbookBreadcrumbsItems({ + workbookBreadcrumbs, + workbookName, + entry, + history, + location, + }); + } return ( { - if (!entry) { - return []; - } - - const rootName = workbookName || 'Workbook'; - let entryName = Utils.getEntryNameFromKey(entry.key || ''); - entryName = (entry as {fake?: boolean}).fake ? '' : entryName; - const fakeName = (entry as {fakeName?: string}).fakeName; + if (!entry) return []; - const items: BreadcrumbsItem[] = []; + const breadcrumbsItems: BreadcrumbsItem[] = [ + { + text: i18n('label_root-title'), + action: () => { + history.push('/collections'); + }, + }, + ]; - const workbookId = entry.workbookId; + if (workbookBreadcrumbs && workbookBreadcrumbs.length > 0) { + workbookBreadcrumbs.forEach((item: {title: string; collectionId: string}) => { + breadcrumbsItems.push({ + text: item.title, + action: () => { + history.push({ + ...location, + pathname: `/collections/${item.collectionId}`, + }); + }, + }); + }); + } - if (workbookId) { - items.push({ - text: rootName, + if (workbookName) { + breadcrumbsItems.push({ + text: workbookName, action: () => { history.push({ ...location, - pathname: `/workbooks/${workbookId}`, + pathname: `/workbooks/${entry.workbookId}`, }); }, }); } + let entryName = Utils.getEntryNameFromKey(entry?.key || ''); + entryName = (entry as {fake?: boolean}).fake ? '' : entryName; + const fakeName = (entry as {fakeName?: string}).fakeName; + if (entryName) { - items.push({ + breadcrumbsItems.push({ text: entryName, action: () => {}, }); } else if (fakeName) { - items.push({ + breadcrumbsItems.push({ text: fakeName, action: () => {}, }); } - return items; + return breadcrumbsItems; }; diff --git a/src/ui/registry/units/common/types/components/EntryBreadcrumbs.ts b/src/ui/registry/units/common/types/components/EntryBreadcrumbs.ts index f3584103c8..cfe83f737b 100644 --- a/src/ui/registry/units/common/types/components/EntryBreadcrumbs.ts +++ b/src/ui/registry/units/common/types/components/EntryBreadcrumbs.ts @@ -1,9 +1,10 @@ import {BreadcrumbsProps} from '@gravity-ui/uikit/build/esm/components/Breadcrumbs/Breadcrumbs'; -import {GetEntryResponse} from 'shared/schema'; +import {GetCollectionBreadcrumbsResponse, GetEntryResponse} from 'shared/schema'; export type EntryBreadcrumbsProps = { renderRootContent?: BreadcrumbsProps['renderRootContent']; entry?: GetEntryResponse; workbookName?: string; + workbookBreadcrumbs?: GetCollectionBreadcrumbsResponse | null; openNavigationAction?: (startFromNavigation: string) => void; }; diff --git a/src/ui/units/workbooks/store/actions/index.ts b/src/ui/units/workbooks/store/actions/index.ts index 51d25a70b6..069580f9f0 100644 --- a/src/ui/units/workbooks/store/actions/index.ts +++ b/src/ui/units/workbooks/store/actions/index.ts @@ -417,23 +417,53 @@ type AddWorkbookInfoAction = { workbookId: string; workbookName: string; workbookPermissions: WorkbookPermission; + workbookBreadcrumbs?: GetCollectionBreadcrumbsResponse | null; }; }; -export const addWorkbookInfo = (workbookId: string) => { - return (dispatch: WorkbooksDispatch) => { - getSdk() - .us.getWorkbook({workbookId, includePermissionsInfo: true}) - .then((workbook) => { +export const addWorkbookInfo = (workbookId: string, withBreadcrumbs = false) => { + return async (dispatch: WorkbooksDispatch) => { + const workbook = await getSdk().us.getWorkbook({workbookId, includePermissionsInfo: true}); + + let workbookBreadcrumbs = null; + let requestedWithBreadcrumbs = false; + + if (withBreadcrumbs && workbook.collectionId) { + try { + workbookBreadcrumbs = await getSdk().us.getCollectionBreadcrumbs( + { + collectionId: workbook.collectionId, + }, + {concurrentId: 'workbooks/getCollectionBreadcrumbs'}, + ); + dispatch({ type: ADD_WORKBOOK_INFO, data: { workbookId, workbookName: workbook.title, workbookPermissions: workbook.permissions, + workbookBreadcrumbs, }, }); + + // If we have permissions for getting breadcrumbs, set flag to exclude the next request + requestedWithBreadcrumbs = true; + } catch (e) { + logger.logError('workbooks/getCollectionBreadcrumbs failed', e); + } + } + + if (!requestedWithBreadcrumbs) { + dispatch({ + type: ADD_WORKBOOK_INFO, + data: { + workbookId, + workbookName: workbook.title, + workbookPermissions: workbook.permissions, + }, }); + } }; }; diff --git a/src/ui/units/workbooks/store/reducers/workbook-page.ts b/src/ui/units/workbooks/store/reducers/workbook-page.ts index 6111d06eff..a26e6ea0e3 100644 --- a/src/ui/units/workbooks/store/reducers/workbook-page.ts +++ b/src/ui/units/workbooks/store/reducers/workbook-page.ts @@ -72,6 +72,7 @@ export type WorkbooksState = { filters: WorkbookEntriesFilters; workbooksNames: Record; workbookPermissions: WorkbookPermission | null; + workbookBreadcrumbs: GetCollectionBreadcrumbsResponse | null; }; const initialState: WorkbooksState = { @@ -111,6 +112,7 @@ const initialState: WorkbooksState = { }, workbooksNames: {}, workbookPermissions: null, + workbookBreadcrumbs: null, }; // eslint-disable-next-line complexity @@ -362,6 +364,7 @@ export const workbooksReducer = (state: WorkbooksState = initialState, action: W [action.data.workbookId]: action.data.workbookName, }, workbookPermissions: action.data.workbookPermissions, + workbookBreadcrumbs: action.data.workbookBreadcrumbs, }; } diff --git a/src/ui/units/workbooks/store/selectors/index.ts b/src/ui/units/workbooks/store/selectors/index.ts index f7c59aadec..0543a47f26 100644 --- a/src/ui/units/workbooks/store/selectors/index.ts +++ b/src/ui/units/workbooks/store/selectors/index.ts @@ -20,6 +20,9 @@ const selectDeleteEntry = (state: DatalensGlobalState) => state.workbooks.delete export const selectWorkbookPermissions = (state: DatalensGlobalState) => state.workbooks.workbookPermissions; +export const selectWorkbookBreadcrumbs = (state: DatalensGlobalState) => + state.workbooks.workbookBreadcrumbs; + // Status of loading information about the workbook export const selectWorkbookInfoIsLoading = createSelector( [selectGetWorkbook, selectGetWorkbookBreadcrumbs],