Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
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 @@ -62,7 +62,7 @@ export const useDatasetSelector = ({
'datasetManagement.dataset.titleExistsLabel',
{
values: { title: query.dataset.title },
defaultMessage: "An index pattern with the title '{title}' already exists.",
defaultMessage: "An dataset with the title '{title}' already exists.",
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { ExploreFlavor } from '../../../../common';
import { useSetEditorText } from '../../hooks';
import { EditorMode } from '../state_management/types';
import { getVisualizationBuilder } from '../../../components/visualizations/visualization_builder';
import { getPreviousPageBreadcrumb } from '../../../utils/get_previous_page_breadcrumb';

export const useInitPage = () => {
const dispatch = useDispatch();
Expand All @@ -42,7 +43,35 @@ export const useInitPage = () => {

// Update browser title and breadcrumbs
chrome.docTitle.change(title);
chrome.setBreadcrumbs([{ text: 'Explore', href: '#/' }, { text: title }]);

// Get previous page info for smart breadcrumb navigation
const { breadcrumbConfig, previousPage } = getPreviousPageBreadcrumb({
chrome,
application: services.core.application,
currentPageId: savedExplore.id,
});

// Build breadcrumbs array
const breadcrumbs = [];

// If user came from a dashboard, show dashboard name as a breadcrumb
if (previousPage && previousPage.meta?.type === 'dashboard') {
breadcrumbs.push({
text: 'Dashboard',
onClick: () => {
services.core.application.navigateToApp('dashboards', { path: '#/' });
},
});
breadcrumbs.push({
text: `${previousPage.label}`,
...breadcrumbConfig,
});
}

// Always show the current explore title
breadcrumbs.push({ text: title });

chrome.setBreadcrumbs(breadcrumbs);

// Sync query from saved object to data plugin (explore doesn't use filters)
const searchSourceFields = savedExplore.kibanaSavedObjectMeta;
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/explore/public/helpers/save_explore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export async function saveSavedExplore({
} else {
// Update browser title and breadcrumbs
chrome.docTitle.change(newTitle);
chrome.setBreadcrumbs([...getRootBreadcrumbs(), { text: savedExplore.title }]);
chrome.setBreadcrumbs([{ text: savedExplore.title }]);
}

store.dispatch(setSavedSearch(id));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { ChromeStart, ChromeRecentlyAccessedHistoryItem, ApplicationStart } from 'src/core/public';

export interface BreadcrumbConfig {
href?: string;
onClick?: () => void;
}

export interface PreviousPageInfo {
breadcrumbConfig: BreadcrumbConfig;
previousPage?: ChromeRecentlyAccessedHistoryItem;
}

export interface GetBreadcrumbOptions {
chrome: ChromeStart;
application?: ApplicationStart;
currentPageId?: string;
}

/**
* Get breadcrumb configuration that navigates to the previous page
* Uses chrome.recentlyAccessed to determine where the user came from
*
* @param options - Configuration options
* @returns Previous page info with breadcrumb config
*/
export function getPreviousPageBreadcrumb(options: GetBreadcrumbOptions): PreviousPageInfo;
export function getPreviousPageBreadcrumb(
chrome: ChromeStart,
currentPageId?: string
): PreviousPageInfo;
export function getPreviousPageBreadcrumb(
optionsOrChrome: GetBreadcrumbOptions | ChromeStart,
currentPageId?: string
): PreviousPageInfo {
// Handle both function signatures for backward compatibility
const chrome =
'chrome' in optionsOrChrome
? (optionsOrChrome as GetBreadcrumbOptions).chrome
: optionsOrChrome;
const application =
'application' in optionsOrChrome
? (optionsOrChrome as GetBreadcrumbOptions).application
: undefined;
const pageId =
'currentPageId' in optionsOrChrome
? (optionsOrChrome as GetBreadcrumbOptions).currentPageId
: currentPageId;
const recentlyAccessed = chrome.recentlyAccessed.get();

// Get the most recently accessed page (first item, which is most recent)
// Skip if it's the current page
const previousPage =
recentlyAccessed.length > 0 && recentlyAccessed[0].id !== pageId
? recentlyAccessed[0]
: undefined;

if (previousPage && previousPage.link) {
// We found a previous page - construct the full URL with workspace ID
let href = previousPage.link;

// Check if the current URL has a workspace ID and the previous page link doesn't
const currentPathname = window.location.pathname;
const workspaceMatch = currentPathname.match(/\/w\/([^/]+)\//);
Copy link
Member

Choose a reason for hiding this comment

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

not sure how reliable this is in the future, does workspace have API to get id?

Copy link
Member

Choose a reason for hiding this comment

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

@joshuali925 yes, workspace has API to get the current workspace id


if (workspaceMatch && !href.includes('/w/')) {
// Add workspace ID to the href
const workspaceId = workspaceMatch[1];
href = `/w/${workspaceId}${href}`;
}

// If application service is available, use onClick with navigateToUrl for SPA navigation
if (application) {
return {
breadcrumbConfig: {
onClick: () => {
application.navigateToUrl(href);
},
},
previousPage,
};
}

// Fallback to href (may cause hard refresh)
return { breadcrumbConfig: { href }, previousPage };
} else {
// No previous page found, fallback to explore home
return { breadcrumbConfig: { href: '#/' } };
}
}
Loading