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