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

This commit is contained in:
upstream-mirror
2026-09-15 15:14:58 +05:00
commit 23059a1de3
5252 changed files with 573834 additions and 0 deletions

View 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;
};