fix: implemented view selector in breadcrumb for all pages
This commit is contained in:
parent
b519e2a44e
commit
6abf9d1870
@ -7,6 +7,7 @@
|
||||
getRowRoute: (row) => ({
|
||||
name: 'Contact',
|
||||
params: { contactId: row.name },
|
||||
query: { view: route.query.view, viewType: route.params.viewType },
|
||||
}),
|
||||
selectable: options.selectable,
|
||||
showTooltip: options.showTooltip,
|
||||
@ -174,6 +175,7 @@ import {
|
||||
} from 'frappe-ui'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const props = defineProps({
|
||||
rows: {
|
||||
@ -205,6 +207,8 @@ const emit = defineEmits([
|
||||
'likeDoc',
|
||||
])
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const pageLengthCount = defineModel()
|
||||
const list = defineModel('list')
|
||||
|
||||
@ -230,7 +234,7 @@ const listBulkActionsRef = ref(null)
|
||||
|
||||
defineExpose({
|
||||
customListActions: computed(
|
||||
() => listBulkActionsRef.value?.customListActions
|
||||
() => listBulkActionsRef.value?.customListActions,
|
||||
),
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -4,14 +4,21 @@
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:options="{
|
||||
getRowRoute: (row) => ({ name: 'Deal', params: { dealId: row.name } }),
|
||||
getRowRoute: (row) => ({
|
||||
name: 'Deal',
|
||||
params: { dealId: row.name },
|
||||
query: { view: route.query.view, viewType: route.params.viewType },
|
||||
}),
|
||||
selectable: options.selectable,
|
||||
showTooltip: options.showTooltip,
|
||||
resizeColumn: options.resizeColumn,
|
||||
}"
|
||||
row-key="name"
|
||||
>
|
||||
<ListHeader class="sm:mx-5 mx-3" @columnWidthUpdated="emit('columnWidthUpdated')">
|
||||
<ListHeader
|
||||
class="sm:mx-5 mx-3"
|
||||
@columnWidthUpdated="emit('columnWidthUpdated')"
|
||||
>
|
||||
<ListHeaderItem
|
||||
v-for="column in columns"
|
||||
:key="column.key"
|
||||
@ -204,6 +211,7 @@ import {
|
||||
} from 'frappe-ui'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const props = defineProps({
|
||||
rows: {
|
||||
@ -235,6 +243,8 @@ const emit = defineEmits([
|
||||
'likeDoc',
|
||||
])
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const pageLengthCount = defineModel()
|
||||
const list = defineModel('list')
|
||||
|
||||
@ -260,7 +270,7 @@ const listBulkActionsRef = ref(null)
|
||||
|
||||
defineExpose({
|
||||
customListActions: computed(
|
||||
() => listBulkActionsRef.value?.customListActions
|
||||
() => listBulkActionsRef.value?.customListActions,
|
||||
),
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
getRowRoute: (row) => ({
|
||||
name: 'Organization',
|
||||
params: { organizationId: row.name },
|
||||
query: { view: route.query.view, viewType: route.params.viewType },
|
||||
}),
|
||||
selectable: options.selectable,
|
||||
showTooltip: options.showTooltip,
|
||||
@ -156,6 +157,7 @@ import {
|
||||
} from 'frappe-ui'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const props = defineProps({
|
||||
rows: {
|
||||
@ -187,6 +189,8 @@ const emit = defineEmits([
|
||||
'likeDoc',
|
||||
])
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const pageLengthCount = defineModel()
|
||||
const list = defineModel('list')
|
||||
|
||||
|
||||
@ -1,7 +1,39 @@
|
||||
<template>
|
||||
<LayoutHeader>
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<div class="flex items-center">
|
||||
<router-link
|
||||
:to="{ name: 'Call Logs' }"
|
||||
class="px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-600 hover:text-gray-700"
|
||||
>
|
||||
{{ __('Call Logs') }}
|
||||
</router-link>
|
||||
<span class="mx-0.5 text-base text-gray-500" aria-hidden="true">
|
||||
/
|
||||
</span>
|
||||
<Dropdown
|
||||
v-if="viewControls"
|
||||
:options="viewControls.viewsDropdownOptions"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-lg font-medium"
|
||||
:label="__(viewControls.currentView.label)"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon :icon="viewControls.currentView.icon" class="h-4" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-800"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<template #right-header>
|
||||
<CustomActions
|
||||
@ -54,6 +86,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
@ -61,11 +94,9 @@ import ViewControls from '@/components/ViewControls.vue'
|
||||
import CallLogsListView from '@/components/ListViews/CallLogsListView.vue'
|
||||
import CallLogModal from '@/components/Modals/CallLogModal.vue'
|
||||
import { getCallLogDetail } from '@/utils/callLog'
|
||||
import { Breadcrumbs } from 'frappe-ui'
|
||||
import { Dropdown } from 'frappe-ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const breadcrumbs = [{ label: __('Call Logs'), route: { name: 'Call Logs' } }]
|
||||
|
||||
const callLogsListView = ref(null)
|
||||
|
||||
// callLogs data is loaded in the ViewControls component
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<LayoutHeader v-if="contact.data">
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<Breadcrumbs :items="breadcrumbs">
|
||||
<template #prefix="{ item }">
|
||||
<Icon v-if="item.icon" :icon="item.icon" class="mr-2 h-4" />
|
||||
</template>
|
||||
</Breadcrumbs>
|
||||
</template>
|
||||
</LayoutHeader>
|
||||
<div v-if="contact.data" class="flex h-full flex-col overflow-hidden">
|
||||
@ -216,16 +220,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
Breadcrumbs,
|
||||
Avatar,
|
||||
FileUploader,
|
||||
Tooltip,
|
||||
Tabs,
|
||||
call,
|
||||
createResource,
|
||||
usePageMeta,
|
||||
} from 'frappe-ui'
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import Dropdown from '@/components/frappe-ui/Dropdown.vue'
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
import Email2Icon from '@/components/Icons/Email2Icon.vue'
|
||||
@ -242,13 +237,24 @@ import {
|
||||
timeAgo,
|
||||
formatNumberIntoCurrency,
|
||||
} from '@/utils'
|
||||
import { getView } from '@/utils/view'
|
||||
import { globalStore } from '@/stores/global.js'
|
||||
import { usersStore } from '@/stores/users.js'
|
||||
import { organizationsStore } from '@/stores/organizations.js'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { callEnabled } from '@/composables/settings'
|
||||
import {
|
||||
Breadcrumbs,
|
||||
Avatar,
|
||||
FileUploader,
|
||||
Tooltip,
|
||||
Tabs,
|
||||
call,
|
||||
createResource,
|
||||
usePageMeta,
|
||||
} from 'frappe-ui'
|
||||
import { ref, computed, h } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const { $dialog, makeCall } = globalStore()
|
||||
|
||||
@ -263,6 +269,7 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const showContactModal = ref(false)
|
||||
@ -287,6 +294,22 @@ const contact = createResource({
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
let items = [{ label: __('Contacts'), route: { name: 'Contacts' } }]
|
||||
|
||||
if (route.query.view || route.query.viewType) {
|
||||
let view = getView(route.query.view, route.query.viewType, 'Contact')
|
||||
if (view) {
|
||||
items.push({
|
||||
label: __(view.label),
|
||||
icon: view.icon,
|
||||
route: {
|
||||
name: 'Contacts',
|
||||
params: { viewType: route.query.viewType },
|
||||
query: { view: route.query.view },
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
items.push({
|
||||
label: contact.data?.full_name,
|
||||
route: { name: 'Contact', params: { contactId: props.contactId } },
|
||||
@ -300,7 +323,6 @@ usePageMeta(() => {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
function validateFile(file) {
|
||||
let extn = file.name.split('.').pop().toLowerCase()
|
||||
if (!['png', 'jpg', 'jpeg'].includes(extn)) {
|
||||
|
||||
@ -1,7 +1,39 @@
|
||||
<template>
|
||||
<LayoutHeader>
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<div class="flex items-center">
|
||||
<router-link
|
||||
:to="{ name: 'Contacts' }"
|
||||
class="px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-600 hover:text-gray-700"
|
||||
>
|
||||
{{ __('Contacts') }}
|
||||
</router-link>
|
||||
<span class="mx-0.5 text-base text-gray-500" aria-hidden="true">
|
||||
/
|
||||
</span>
|
||||
<Dropdown
|
||||
v-if="viewControls"
|
||||
:options="viewControls.viewsDropdownOptions"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-lg font-medium"
|
||||
:label="__(viewControls.currentView.label)"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon :icon="viewControls.currentView.icon" class="h-4" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-800"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<template #right-header>
|
||||
<CustomActions
|
||||
@ -72,6 +104,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import ContactsIcon from '@/components/Icons/ContactsIcon.vue'
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
@ -79,37 +112,16 @@ import ContactModal from '@/components/Modals/ContactModal.vue'
|
||||
import QuickEntryModal from '@/components/Settings/QuickEntryModal.vue'
|
||||
import ContactsListView from '@/components/ListViews/ContactsListView.vue'
|
||||
import ViewControls from '@/components/ViewControls.vue'
|
||||
import { Breadcrumbs } from 'frappe-ui'
|
||||
import { organizationsStore } from '@/stores/organizations.js'
|
||||
import { dateFormat, dateTooltipFormat, timeAgo } from '@/utils'
|
||||
import { Dropdown } from 'frappe-ui'
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { getOrganization } = organizationsStore()
|
||||
const route = useRoute()
|
||||
|
||||
const showContactModal = ref(false)
|
||||
const showQuickEntryModal = ref(false)
|
||||
|
||||
const currentContact = computed(() => {
|
||||
return contacts.value?.data?.data?.find(
|
||||
(contact) => contact.name === route.params.contactId,
|
||||
)
|
||||
})
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
let items = [{ label: __('Contacts'), route: { name: 'Contacts' } }]
|
||||
if (!currentContact.value) return items
|
||||
items.push({
|
||||
label: __(currentContact.value.full_name),
|
||||
route: {
|
||||
name: 'Contact',
|
||||
params: { contactId: currentContact.value.name },
|
||||
},
|
||||
})
|
||||
return items
|
||||
})
|
||||
|
||||
const contactsListView = ref(null)
|
||||
|
||||
// contacts data is loaded in the ViewControls component
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<LayoutHeader v-if="deal.data">
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<Breadcrumbs :items="breadcrumbs">
|
||||
<template #prefix="{ item }">
|
||||
<Icon v-if="item.icon" :icon="item.icon" class="mr-2 h-4" />
|
||||
</template>
|
||||
</Breadcrumbs>
|
||||
</template>
|
||||
<template #right-header>
|
||||
<CustomActions
|
||||
@ -302,6 +306,7 @@
|
||||
/>
|
||||
</template>
|
||||
<script setup>
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import Resizer from '@/components/Resizer.vue'
|
||||
import LoadingIndicator from '@/components/Icons/LoadingIndicator.vue'
|
||||
import EditIcon from '@/components/Icons/EditIcon.vue'
|
||||
@ -337,6 +342,7 @@ import {
|
||||
errorMessage,
|
||||
copyToClipboard,
|
||||
} from '@/utils'
|
||||
import { getView } from '@/utils/view'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { organizationsStore } from '@/stores/organizations'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
@ -353,12 +359,13 @@ import {
|
||||
usePageMeta,
|
||||
} from 'frappe-ui'
|
||||
import { ref, computed, h, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const { $dialog, makeCall } = globalStore()
|
||||
const { organizations, getOrganization } = organizationsStore()
|
||||
const { statusOptions, getDealStatus } = statusesStore()
|
||||
const { isManager } = usersStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const props = defineProps({
|
||||
@ -452,6 +459,22 @@ function validateRequired(fieldname, value) {
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
let items = [{ label: __('Deals'), route: { name: 'Deals' } }]
|
||||
|
||||
if (route.query.view || route.query.viewType) {
|
||||
let view = getView(route.query.view, route.query.viewType, 'CRM Deal')
|
||||
if (view) {
|
||||
items.push({
|
||||
label: __(view.label),
|
||||
icon: view.icon,
|
||||
route: {
|
||||
name: 'Deals',
|
||||
params: { viewType: route.query.viewType },
|
||||
query: { view: route.query.view },
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
items.push({
|
||||
label: organization.value?.name || __('Untitled'),
|
||||
route: { name: 'Deal', params: { dealId: deal.data.name } },
|
||||
|
||||
@ -1,7 +1,39 @@
|
||||
<template>
|
||||
<LayoutHeader>
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<div class="flex items-center">
|
||||
<router-link
|
||||
:to="{ name: 'Deals' }"
|
||||
class="px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-600 hover:text-gray-700"
|
||||
>
|
||||
{{ __('Deals') }}
|
||||
</router-link>
|
||||
<span class="mx-0.5 text-base text-gray-500" aria-hidden="true">
|
||||
/
|
||||
</span>
|
||||
<Dropdown
|
||||
v-if="viewControls"
|
||||
:options="viewControls.viewsDropdownOptions"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-lg font-medium"
|
||||
:label="__(viewControls.currentView.label)"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon :icon="viewControls.currentView.icon" class="h-4" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-800"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<template #right-header>
|
||||
<CustomActions
|
||||
@ -32,7 +64,11 @@
|
||||
v-if="route.params.viewType == 'kanban'"
|
||||
v-model="deals"
|
||||
:options="{
|
||||
getRoute: (row) => ({ name: 'Deal', params: { dealId: row.name } }),
|
||||
getRoute: (row) => ({
|
||||
name: 'Deal',
|
||||
params: { dealId: row.name },
|
||||
query: { view: route.query.view, viewType: route.params.viewType },
|
||||
}),
|
||||
onNewClick: (column) => onNewClick(column),
|
||||
}"
|
||||
@update="(data) => viewControls.updateKanbanSettings(data)"
|
||||
@ -259,6 +295,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import MultipleAvatar from '@/components/MultipleAvatar.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import EmailAtIcon from '@/components/Icons/EmailAtIcon.vue'
|
||||
@ -288,12 +325,10 @@ import {
|
||||
formatNumberIntoCurrency,
|
||||
formatTime,
|
||||
} from '@/utils'
|
||||
import { Breadcrumbs, Tooltip, Avatar, Dropdown } from 'frappe-ui'
|
||||
import { Tooltip, Avatar, Dropdown } from 'frappe-ui'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref, reactive, computed, h } from 'vue'
|
||||
|
||||
const breadcrumbs = [{ label: __('Deals'), route: { name: 'Deals' } }]
|
||||
|
||||
const { makeCall } = globalStore()
|
||||
const { getUser } = usersStore()
|
||||
const { getOrganization } = organizationsStore()
|
||||
|
||||
@ -1,7 +1,39 @@
|
||||
<template>
|
||||
<LayoutHeader>
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<div class="flex items-center">
|
||||
<router-link
|
||||
:to="{ name: 'Email Templates' }"
|
||||
class="px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-600 hover:text-gray-700"
|
||||
>
|
||||
{{ __('Email Templates') }}
|
||||
</router-link>
|
||||
<span class="mx-0.5 text-base text-gray-500" aria-hidden="true">
|
||||
/
|
||||
</span>
|
||||
<Dropdown
|
||||
v-if="viewControls"
|
||||
:options="viewControls.viewsDropdownOptions"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-lg font-medium"
|
||||
:label="__(viewControls.currentView.label)"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon :icon="viewControls.currentView.icon" class="h-4" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-800"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<template #right-header>
|
||||
<CustomActions
|
||||
@ -68,6 +100,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import Email2Icon from '@/components/Icons/Email2Icon.vue'
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
@ -75,13 +108,9 @@ import ViewControls from '@/components/ViewControls.vue'
|
||||
import EmailTemplatesListView from '@/components/ListViews/EmailTemplatesListView.vue'
|
||||
import EmailTemplateModal from '@/components/Modals/EmailTemplateModal.vue'
|
||||
import { dateFormat, dateTooltipFormat, timeAgo } from '@/utils'
|
||||
import { Breadcrumbs } from 'frappe-ui'
|
||||
import { Dropdown } from 'frappe-ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const breadcrumbs = [
|
||||
{ label: __('Email Templates'), route: { name: 'Email Templates' } },
|
||||
]
|
||||
|
||||
const emailTemplatesListView = ref(null)
|
||||
|
||||
// emailTemplates data is loaded in the ViewControls component
|
||||
|
||||
@ -1,7 +1,39 @@
|
||||
<template>
|
||||
<LayoutHeader>
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<div class="flex items-center">
|
||||
<router-link
|
||||
:to="{ name: 'Notes' }"
|
||||
class="px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-600 hover:text-gray-700"
|
||||
>
|
||||
{{ __('Notes') }}
|
||||
</router-link>
|
||||
<span class="mx-0.5 text-base text-gray-500" aria-hidden="true">
|
||||
/
|
||||
</span>
|
||||
<Dropdown
|
||||
v-if="viewControls"
|
||||
:options="viewControls.viewsDropdownOptions"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-lg font-medium"
|
||||
:label="__(viewControls.currentView.label)"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon :icon="viewControls.currentView.icon" class="h-4" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-800"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<template #right-header>
|
||||
<Button variant="solid" :label="__('Create')" @click="createNote">
|
||||
@ -10,6 +42,7 @@
|
||||
</template>
|
||||
</LayoutHeader>
|
||||
<ViewControls
|
||||
ref="viewControls"
|
||||
v-model="notes"
|
||||
v-model:loadMore="loadMore"
|
||||
v-model:updatedPageCount="updatedPageCount"
|
||||
@ -102,6 +135,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import NoteIcon from '@/components/Icons/NoteIcon.vue'
|
||||
@ -109,33 +143,25 @@ import NoteModal from '@/components/Modals/NoteModal.vue'
|
||||
import ViewControls from '@/components/ViewControls.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { timeAgo, dateFormat, dateTooltipFormat } from '@/utils'
|
||||
import {
|
||||
TextEditor,
|
||||
call,
|
||||
Dropdown,
|
||||
Tooltip,
|
||||
Breadcrumbs,
|
||||
ListFooter,
|
||||
} from 'frappe-ui'
|
||||
import { TextEditor, call, Dropdown, Tooltip, ListFooter } from 'frappe-ui'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
const { getUser } = usersStore()
|
||||
|
||||
const breadcrumbs = [{ label: __('Notes'), route: { name: 'Notes' } }]
|
||||
|
||||
const showNoteModal = ref(false)
|
||||
const currentNote = ref(null)
|
||||
|
||||
const notes = ref({})
|
||||
const loadMore = ref(1)
|
||||
const updatedPageCount = ref(20)
|
||||
const viewControls = ref(null)
|
||||
|
||||
watch(
|
||||
() => notes.value?.data?.page_length_count,
|
||||
(val, old_value) => {
|
||||
if (!val || val === old_value) return
|
||||
updatedPageCount.value = val
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
function createNote() {
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<LayoutHeader v-if="organization.doc">
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<Breadcrumbs :items="breadcrumbs">
|
||||
<template #prefix="{ item }">
|
||||
<Icon v-if="item.icon" :icon="item.icon" class="mr-2 h-4" />
|
||||
</template>
|
||||
</Breadcrumbs>
|
||||
</template>
|
||||
</LayoutHeader>
|
||||
<div v-if="organization.doc" class="flex flex-1 flex-col overflow-hidden">
|
||||
@ -226,17 +230,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
Breadcrumbs,
|
||||
Avatar,
|
||||
FileUploader,
|
||||
Dropdown,
|
||||
Tabs,
|
||||
call,
|
||||
createListResource,
|
||||
createDocumentResource,
|
||||
usePageMeta,
|
||||
} from 'frappe-ui'
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
||||
import QuickEntryModal from '@/components/Settings/QuickEntryModal.vue'
|
||||
@ -252,14 +246,26 @@ import ContactsIcon from '@/components/Icons/ContactsIcon.vue'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { getView } from '@/utils/view'
|
||||
import {
|
||||
dateFormat,
|
||||
dateTooltipFormat,
|
||||
timeAgo,
|
||||
formatNumberIntoCurrency,
|
||||
} from '@/utils'
|
||||
import {
|
||||
Breadcrumbs,
|
||||
Avatar,
|
||||
FileUploader,
|
||||
Dropdown,
|
||||
Tabs,
|
||||
call,
|
||||
createListResource,
|
||||
createDocumentResource,
|
||||
usePageMeta,
|
||||
} from 'frappe-ui'
|
||||
import { h, computed, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const props = defineProps({
|
||||
organizationId: {
|
||||
@ -274,6 +280,7 @@ const showOrganizationModal = ref(false)
|
||||
const showQuickEntryModal = ref(false)
|
||||
const detailMode = ref(false)
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const organization = createDocumentResource({
|
||||
@ -286,6 +293,26 @@ const organization = createDocumentResource({
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
let items = [{ label: __('Organizations'), route: { name: 'Organizations' } }]
|
||||
|
||||
if (route.query.view || route.query.viewType) {
|
||||
let view = getView(
|
||||
route.query.view,
|
||||
route.query.viewType,
|
||||
'CRM Organization',
|
||||
)
|
||||
if (view) {
|
||||
items.push({
|
||||
label: __(view.label),
|
||||
icon: view.icon,
|
||||
route: {
|
||||
name: 'Organizations',
|
||||
params: { viewType: route.query.viewType },
|
||||
query: { view: route.query.view },
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
items.push({
|
||||
label: props.organizationId,
|
||||
route: {
|
||||
|
||||
@ -1,7 +1,39 @@
|
||||
<template>
|
||||
<LayoutHeader>
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<div class="flex items-center">
|
||||
<router-link
|
||||
:to="{ name: 'Organizations' }"
|
||||
class="px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-600 hover:text-gray-700"
|
||||
>
|
||||
{{ __('Organizations') }}
|
||||
</router-link>
|
||||
<span class="mx-0.5 text-base text-gray-500" aria-hidden="true">
|
||||
/
|
||||
</span>
|
||||
<Dropdown
|
||||
v-if="viewControls"
|
||||
:options="viewControls.viewsDropdownOptions"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-lg font-medium"
|
||||
:label="__(viewControls.currentView.label)"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon :icon="viewControls.currentView.icon" class="h-4" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-800"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<template #right-header>
|
||||
<CustomActions
|
||||
@ -70,6 +102,7 @@
|
||||
/>
|
||||
</template>
|
||||
<script setup>
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import OrganizationsIcon from '@/components/Icons/OrganizationsIcon.vue'
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
@ -77,7 +110,7 @@ import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
||||
import QuickEntryModal from '@/components/Settings/QuickEntryModal.vue'
|
||||
import OrganizationsListView from '@/components/ListViews/OrganizationsListView.vue'
|
||||
import ViewControls from '@/components/ViewControls.vue'
|
||||
import { Breadcrumbs } from 'frappe-ui'
|
||||
import { Dropdown } from 'frappe-ui'
|
||||
import {
|
||||
dateFormat,
|
||||
dateTooltipFormat,
|
||||
@ -85,33 +118,11 @@ import {
|
||||
formatNumberIntoCurrency,
|
||||
} from '@/utils'
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const organizationsListView = ref(null)
|
||||
const showOrganizationModal = ref(false)
|
||||
const showQuickEntryModal = ref(false)
|
||||
|
||||
const currentOrganization = computed(() => {
|
||||
return organizations.value?.data?.data?.find(
|
||||
(organization) => organization.name === route.params.organizationId,
|
||||
)
|
||||
})
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
let items = [{ label: __('Organizations'), route: { name: 'Organizations' } }]
|
||||
if (!currentOrganization.value) return items
|
||||
items.push({
|
||||
label: __(currentOrganization.value.name),
|
||||
route: {
|
||||
name: 'Organization',
|
||||
params: { organizationId: currentOrganization.value.name },
|
||||
},
|
||||
})
|
||||
return items
|
||||
})
|
||||
|
||||
// organizations data is loaded in the ViewControls component
|
||||
const organizations = ref({})
|
||||
const loadMore = ref(1)
|
||||
|
||||
@ -1,7 +1,39 @@
|
||||
<template>
|
||||
<LayoutHeader>
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
<div class="flex items-center">
|
||||
<router-link
|
||||
:to="{ name: 'Tasks' }"
|
||||
class="px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-600 hover:text-gray-700"
|
||||
>
|
||||
{{ __('Tasks') }}
|
||||
</router-link>
|
||||
<span class="mx-0.5 text-base text-gray-500" aria-hidden="true">
|
||||
/
|
||||
</span>
|
||||
<Dropdown
|
||||
v-if="viewControls"
|
||||
:options="viewControls.viewsDropdownOptions"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-lg font-medium"
|
||||
:label="__(viewControls.currentView.label)"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon :icon="viewControls.currentView.icon" class="h-4" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-800"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<template #right-header>
|
||||
<CustomActions
|
||||
@ -193,6 +225,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import ArrowUpRightIcon from '@/components/Icons/ArrowUpRightIcon.vue'
|
||||
import TaskStatusIcon from '@/components/Icons/TaskStatusIcon.vue'
|
||||
@ -205,19 +238,10 @@ import KanbanView from '@/components/Kanban/KanbanView.vue'
|
||||
import TaskModal from '@/components/Modals/TaskModal.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { dateFormat, dateTooltipFormat, timeAgo } from '@/utils'
|
||||
import {
|
||||
Breadcrumbs,
|
||||
Tooltip,
|
||||
Avatar,
|
||||
TextEditor,
|
||||
Dropdown,
|
||||
call,
|
||||
} from 'frappe-ui'
|
||||
import { Tooltip, Avatar, TextEditor, Dropdown, call } from 'frappe-ui'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const breadcrumbs = [{ label: __('Tasks'), route: { name: 'Tasks' } }]
|
||||
|
||||
const { getUser } = usersStore()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -40,7 +40,8 @@ const routes = [
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/notes',
|
||||
alias: '/notes',
|
||||
path: '/notes/view/:viewType?',
|
||||
name: 'Notes',
|
||||
component: () => import('@/pages/Notes.vue'),
|
||||
},
|
||||
@ -51,7 +52,8 @@ const routes = [
|
||||
component: () => import('@/pages/Tasks.vue'),
|
||||
},
|
||||
{
|
||||
path: '/contacts',
|
||||
alias: '/contacts',
|
||||
path: '/contacts/view/:viewType?',
|
||||
name: 'Contacts',
|
||||
component: () => import('@/pages/Contacts.vue'),
|
||||
meta: { scrollPos: { top: 0, left: 0 } },
|
||||
@ -63,7 +65,8 @@ const routes = [
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/organizations',
|
||||
alias: '/organizations',
|
||||
path: '/organizations/view/:viewType?',
|
||||
name: 'Organizations',
|
||||
component: () => import('@/pages/Organizations.vue'),
|
||||
meta: { scrollPos: { top: 0, left: 0 } },
|
||||
@ -75,13 +78,15 @@ const routes = [
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/call-logs',
|
||||
alias: '/call-logs',
|
||||
path: '/call-logs/view/:viewType?',
|
||||
name: 'Call Logs',
|
||||
component: () => import('@/pages/CallLogs.vue'),
|
||||
meta: { scrollPos: { top: 0, left: 0 } },
|
||||
},
|
||||
{
|
||||
path: '/email-templates',
|
||||
alias: '/email-templates',
|
||||
path: '/email-templates/view/:viewType?',
|
||||
name: 'Email Templates',
|
||||
component: () => import('@/pages/EmailTemplates.vue'),
|
||||
meta: { scrollPos: { top: 0, left: 0 } },
|
||||
@ -92,11 +97,6 @@ const routes = [
|
||||
component: () => import('@/pages/EmailTemplate.vue'),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/dashboard',
|
||||
name: 'Dashboard',
|
||||
component: () => import('@/pages/Dashboard.vue'),
|
||||
},
|
||||
{
|
||||
path: '/:invalidpath',
|
||||
name: 'Invalid Page',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user