Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 11 additions & 4 deletions src/containers/ProjectMenu/projectMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ import clsx from 'clsx'
import useAyonNavigate from '@hooks/useAyonNavigate'
import { useProjectSelectDispatcher } from './hooks/useProjectSelectDispatcher'
import { updateUserPreferences as updateUserPreferencesAction } from '@state/user'
import { useProjectDefaultTab } from '@hooks/useProjectDefaultTab'
import { useLocation } from 'react-router-dom'

const ProjectMenu = ({ isOpen, onHide }) => {
const navigate = useAyonNavigate()
const dispatch = useDispatch()
const location = useLocation()
const menuRef = useRef(null)
const searchRef = useRef(null)
const [oldPinned, setOldPinned] = useLocalStorage('projectMenu-pinned', [])
Expand Down Expand Up @@ -58,6 +61,7 @@ const ProjectMenu = ({ isOpen, onHide }) => {

const [showContext] = useCreateContextMenu([])
const [handleProjectSelectionDispatches] = useProjectSelectDispatcher([])
const { getDefaultTab } = useProjectDefaultTab()

const [updateUserPreferences] = useSetFrontendPreferencesMutation()

Expand Down Expand Up @@ -212,10 +216,13 @@ const ProjectMenu = ({ isOpen, onHide }) => {

setSearchOpen(false)

// if projects/[project] is null, projects/[projectName]/overview, else projects/[projectName]/[module]
const link = window.location.pathname.includes('projects')
? `/projects/${projectName}/${window.location.pathname.split('/')[3] || 'overview'}`
: `/projects/${projectName}/overview`
// if projects/[project] is null, projects/[projectName]/defaultTab, else projects/[projectName]/[module]
const defaultTab = getDefaultTab()
const pathSegments = location.pathname.split('/')
const currentModule = pathSegments[3]
const link = location.pathname.includes('projects')
? `/projects/${projectName}/${currentModule || defaultTab}`
: `/projects/${projectName}/${defaultTab}`

dispatch((_, getState) => navigate(getState)(link))
}
Expand Down
5 changes: 4 additions & 1 deletion src/containers/ProjectsList/ProjectsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useQueryParam } from 'use-query-params'
import { useProjectSelectDispatcher } from '@containers/ProjectMenu/hooks/useProjectSelectDispatcher'
import useAyonNavigate from '@hooks/useAyonNavigate'
import { useCreateContextMenu } from '@shared/containers'
import { useProjectDefaultTab } from '@hooks/useProjectDefaultTab'

export const PROJECTS_LIST_WIDTH_KEY = 'projects-list-splitter'

Expand Down Expand Up @@ -133,12 +134,14 @@ const ProjectsList: FC<ProjectsListProps> = ({
}

const [handleProjectSelectionDispatches] = useProjectSelectDispatcher()
const { getDefaultTab } = useProjectDefaultTab()

const navigate = useAyonNavigate()
const onOpenProject = (project: string) => {
handleProjectSelectionDispatches(project)

const link = `/projects/${project}/overview`
const defaultTab = getDefaultTab()
const link = `/projects/${project}/${defaultTab}`
// I don't like the setTimeout, but it is legacy code and I do not want to break existing stuffs
setTimeout(() => dispatch((_, getState) => navigate(getState)(link)), 0)
}
Expand Down
48 changes: 48 additions & 0 deletions src/hooks/useProjectDefaultTab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const STORAGE_KEY = 'ayon-project-default-tab'

/**
* Hook to manage the default project tab preference
* Stores the last visited tab in localStorage and retrieves it for new project navigation
*/
export const useProjectDefaultTab = () => {
/**
* Get the stored default tab, fallback to 'overview'
*/
const getDefaultTab = (): string => {
try {
const stored = localStorage.getItem(STORAGE_KEY)
return stored || 'overview'
} catch {
return 'overview'
}
}

/**
* Store the current tab as the default for future project navigation
*/
const setDefaultTab = (tab: string): void => {
try {
localStorage.setItem(STORAGE_KEY, tab)
} catch {
// Silently fail if localStorage is not available
}
}

/**
* Track the current tab and store it as default when the tab changes
* This should be called from the ProjectPage component
*/
const trackCurrentTab = (currentTab: string, isAddon: boolean = false): void => {
if (currentTab) {
// For addon pages, prefix with 'addon/' to distinguish from built-in modules
const tabToStore = isAddon ? `addon/${currentTab}` : currentTab
setDefaultTab(tabToStore)
}
}

return {
getDefaultTab,
setDefaultTab,
trackCurrentTab,
}
}
26 changes: 15 additions & 11 deletions src/pages/ProjectPage/ProjectPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect, useMemo } from 'react'
import { useState, useEffect, useMemo} from 'react'
import { useParams, useNavigate, useLocation, useSearchParams } from 'react-router-dom'
import { useAppDispatch, useAppSelector } from '@state/store'
import { Button, Dialog } from '@ynput/ayon-react-components'
Expand All @@ -13,7 +13,6 @@ import TasksProgressPage from '../TasksProgressPage'
import ProjectListsPage from '../ProjectListsPage'
import SchedulerPage from '@pages/SchedulerPage/SchedulerPage'


import { selectProject } from '@state/project'
import { useGetProjectQuery } from '@queries/project/enhancedProject'
import { useGetProjectAddonsQuery } from '@shared/api'
Expand All @@ -31,9 +30,10 @@ import useGetBundleAddonVersions from '@hooks/useGetBundleAddonVersions'
import ProjectReviewsPage from '@pages/ProjectListsPage/ProjectReviewsPage'
import ExternalUserPageLocked from '@components/ExternalUserPageLocked'
import { Views, ViewsProvider, ViewType } from '@shared/containers'
import HelpButton from "@components/HelpButton/HelpButton.tsx"
import HelpButton from '@components/HelpButton/HelpButton.tsx'
import ReportsPage from '@pages/ReportsPage/ReportsPage'
import { useLoadRemotePages } from '@/remote/useLoadRemotePages'
import { useProjectDefaultTab } from '@hooks/useProjectDefaultTab'

type NavLink = {
name?: string
Expand Down Expand Up @@ -77,6 +77,7 @@ const ProjectPage = () => {
const navigate = useNavigate()
const { projectName, module = '', addonName } = useParams()
const dispatch = useAppDispatch()
const { trackCurrentTab } = useProjectDefaultTab()
const [showContextDialog, setShowContextDialog] = useState(false)
const { isLoading, isError, isUninitialized, refetch } = useGetProjectQuery(
{ projectName: projectName || '' },
Expand Down Expand Up @@ -177,12 +178,11 @@ const ProjectPage = () => {
module: 'workfiles',
uriSync: true,
},
...remotePages
.map((remote) => ({
name: remote.name,
module: remote.module,
path: `/projects/${projectName}/${remote.module}`,
})),
...remotePages.map((remote) => ({
name: remote.name,
module: remote.module,
path: `/projects/${projectName}/${remote.module}`,
})),
...addonsData
.filter((addon) => {
if (addon.settings.admin && !isAdmin) return false
Expand Down Expand Up @@ -219,6 +219,10 @@ const ProjectPage = () => {

const title = useTitle(module, links, projectName || 'AYON')

const tab = !!addonName ? addonsData?.find((item) => item.name === addonName)?.name : module
const isAddon = !!addonName // Check if we're on an addon page
trackCurrentTab(tab, isAddon)

//
// Render page
//
Expand Down Expand Up @@ -303,8 +307,8 @@ const ProjectPage = () => {
dispatch(productSelected({ products: [productId], versions: [versionId] }))
}

if (isExternal){
return <ExternalUserPageLocked/>
if (isExternal) {
return <ExternalUserPageLocked />
}

return (
Expand Down