diff --git a/frontend/src/composables/useActiveTabManager.js b/frontend/src/composables/useActiveTabManager.js new file mode 100644 index 000000000..5b9cd4848 --- /dev/null +++ b/frontend/src/composables/useActiveTabManager.js @@ -0,0 +1,80 @@ +import { ref, watch } from 'vue' +import { useRoute } from 'vue-router' +import { useDebounceFn, useStorage } from '@vueuse/core' + +export function useActiveTabManager(tabs, storageKey) { + const activieTab = useStorage(storageKey, 'activity') + const route = useRoute() + + const preserveLastVisitedTab = useDebounceFn((tabName) => { + activieTab.value = tabName.toLowerCase() + }, 300) + + function setActiveTabInUrl(tabName) { + window.location.hash = '#' + tabName.toLowerCase() + } + + function getActiveTabFromUrl() { + return route.hash.replace('#', '') + } + + function findTabIndex(tabName) { + return tabs.value.findIndex( + (tabOptions) => tabOptions.name.toLowerCase() === tabName, + ) + } + + function getTabIndex(tabName) { + let index = findTabIndex(tabName) + return index !== -1 ? index : 0 // Default to the first tab if not found + } + + function getActiveTabFromLocalStorage() { + return activieTab.value + } + + function getActiveTab() { + let activeTab = getActiveTabFromUrl() + if (activeTab) { + let index = findTabIndex(activeTab) + if (index !== -1) { + preserveLastVisitedTab(activeTab) + return index + } + return 0 + } + + let lastVisitedTab = getActiveTabFromLocalStorage() + if (lastVisitedTab) { + setActiveTabInUrl(lastVisitedTab) + return getTabIndex(lastVisitedTab) + } + + return 0 // Default to the first tab if nothing is found + } + + const tabIndex = ref(getActiveTab()) + + watch(tabIndex, (tabIndexValue) => { + let currentTab = tabs.value[tabIndexValue].name + setActiveTabInUrl(currentTab) + preserveLastVisitedTab(currentTab) + }) + + watch( + () => route.hash, + (tabValue) => { + if (!tabValue) return + + let tabName = tabValue.replace('#', '') + let index = findTabIndex(tabName) + if (index === -1) index = 0 + + let currentTab = tabs.value[index].name + preserveLastVisitedTab(currentTab) + tabIndex.value = index + }, + ) + + return { tabIndex } +} diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index a04922627..9429cd6cb 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -354,6 +354,8 @@ import { } from 'frappe-ui' import { ref, computed, h, onMounted, onBeforeUnmount } from 'vue' import { useRoute, useRouter } from 'vue-router' +import { useActiveTabManager } from '@/composables/useActiveTabManager' + const { $dialog, $socket, makeCall } = globalStore() const { statusOptions, getDealStatus } = statusesStore() @@ -516,7 +518,6 @@ usePageMeta(() => { } }) -const tabIndex = ref(0) const tabs = computed(() => { let tabOptions = [ { @@ -559,6 +560,7 @@ const tabs = computed(() => { ] return tabOptions.filter((tab) => (tab.condition ? tab.condition() : true)) }) +const { tabIndex } = useActiveTabManager(tabs, 'lastDealTab') const fieldsLayout = createResource({ url: 'crm.api.doc.get_sidebar_fields', diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index 25fedfd5c..03e106705 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -330,6 +330,7 @@ import { } from 'frappe-ui' import { ref, computed, onMounted, watch } from 'vue' import { useRouter, useRoute } from 'vue-router' +import { useActiveTabManager } from '@/composables/useActiveTabManager' const { $dialog, $socket, makeCall } = globalStore() const { getContactByName, contacts } = contactsStore() @@ -463,8 +464,6 @@ usePageMeta(() => { } }) -const tabIndex = ref(0) - const tabs = computed(() => { let tabOptions = [ { @@ -508,6 +507,8 @@ const tabs = computed(() => { return tabOptions.filter((tab) => (tab.condition ? tab.condition() : true)) }) +const { tabIndex } = useActiveTabManager(tabs, 'lastLeadTab') + watch(tabs, (value) => { if (value && route.params.tabName) { let index = value.findIndex(