snapshot of https://github.com/makeplane/plane.git @ d868349a55de79979eb8b98701bf1702c67ad634 (2026-09-15)
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
This commit is contained in:
117
apps/web/core/components/navigation/tab-navigation-utils.ts
Normal file
117
apps/web/core/components/navigation/tab-navigation-utils.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
// Tab preferences type
|
||||
export type TTabPreferences = {
|
||||
defaultTab: string;
|
||||
hiddenTabs: string[];
|
||||
};
|
||||
|
||||
// Constants
|
||||
export const TAB_PREFS_KEY = "plane_tab_prefs";
|
||||
export const DEFAULT_TAB_KEY = "work_items";
|
||||
|
||||
/**
|
||||
* Get tab preferences for a specific project from localStorage
|
||||
* @param projectId - The project ID
|
||||
* @returns Tab preferences object with defaultTab and hiddenTabs
|
||||
*/
|
||||
export const getTabPreferences = (projectId: string): TTabPreferences => {
|
||||
try {
|
||||
const stored = localStorage.getItem(TAB_PREFS_KEY);
|
||||
if (stored) {
|
||||
const allPrefs = JSON.parse(stored);
|
||||
return (
|
||||
allPrefs[projectId] || {
|
||||
defaultTab: DEFAULT_TAB_KEY,
|
||||
hiddenTabs: [],
|
||||
}
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error reading tab preferences:", error);
|
||||
}
|
||||
return {
|
||||
defaultTab: DEFAULT_TAB_KEY,
|
||||
hiddenTabs: [],
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Save tab preferences for a specific project to localStorage
|
||||
* @param projectId - The project ID
|
||||
* @param preferences - Tab preferences to save
|
||||
*/
|
||||
export const saveTabPreferences = (projectId: string, preferences: TTabPreferences): void => {
|
||||
try {
|
||||
const stored = localStorage.getItem(TAB_PREFS_KEY);
|
||||
const allPrefs = stored ? JSON.parse(stored) : {};
|
||||
allPrefs[projectId] = preferences;
|
||||
localStorage.setItem(TAB_PREFS_KEY, JSON.stringify(allPrefs));
|
||||
} catch (error) {
|
||||
console.error("Error saving tab preferences:", error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Map tab keys to their corresponding URLs
|
||||
* @param workspaceSlug - The workspace slug
|
||||
* @param projectId - The project ID
|
||||
* @param tabKey - The tab key to map
|
||||
* @returns Full URL path for the tab
|
||||
*/
|
||||
export const getTabUrl = (workspaceSlug: string, projectId: string, tabKey: string): string => {
|
||||
const baseUrl = `/${workspaceSlug}/projects/${projectId}`;
|
||||
const tabUrlMap: Record<string, string> = {
|
||||
work_items: `${baseUrl}/issues`,
|
||||
cycles: `${baseUrl}/cycles`,
|
||||
modules: `${baseUrl}/modules`,
|
||||
views: `${baseUrl}/views`,
|
||||
pages: `${baseUrl}/pages`,
|
||||
intake: `${baseUrl}/intake`,
|
||||
overview: `${baseUrl}/overview`,
|
||||
epics: `${baseUrl}/epics`,
|
||||
};
|
||||
return tabUrlMap[tabKey] || `${baseUrl}/issues`; // fallback to issues
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the default tab URL for a project
|
||||
* @param workspaceSlug - The workspace slug
|
||||
* @param projectId - The project ID
|
||||
* @param availableTabKeys - Optional array of available tab keys for validation
|
||||
* @returns Full URL path for the default tab (validated if availableTabKeys provided)
|
||||
*/
|
||||
export const getDefaultTabUrl = (workspaceSlug: string, projectId: string, availableTabKeys?: string[]): string => {
|
||||
const preferences = getTabPreferences(projectId);
|
||||
let tabKey = preferences.defaultTab;
|
||||
|
||||
// Validate against available tabs if provided
|
||||
if (availableTabKeys && availableTabKeys.length > 0) {
|
||||
tabKey = getValidatedDefaultTab(projectId, availableTabKeys);
|
||||
}
|
||||
|
||||
return getTabUrl(workspaceSlug, projectId, tabKey);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the default tab key, with validation that it exists in available tabs
|
||||
* @param projectId - The project ID
|
||||
* @param availableTabKeys - Array of available tab keys
|
||||
* @returns The default tab key if valid, otherwise DEFAULT_TAB_KEY
|
||||
*/
|
||||
export const getValidatedDefaultTab = (projectId: string, availableTabKeys: string[]): string => {
|
||||
const preferences = getTabPreferences(projectId);
|
||||
const defaultTab = preferences.defaultTab;
|
||||
|
||||
// Check if the default tab is in the available tabs
|
||||
if (availableTabKeys.includes(defaultTab)) {
|
||||
return defaultTab;
|
||||
}
|
||||
|
||||
// Fall back to work_items
|
||||
return DEFAULT_TAB_KEY;
|
||||
};
|
||||
Reference in New Issue
Block a user