Merge pull request #6 from frappe/revert-5-use-global-properties
This commit is contained in:
commit
b03401e75c
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<router-view v-if="$route.name == 'Login'" />
|
<router-view v-if="$route.name == 'Login'" />
|
||||||
<CallUI v-else-if="$session.isLoggedIn">
|
<CallUI v-else-if="session().isLoggedIn">
|
||||||
<DesktopLayout>
|
<DesktopLayout>
|
||||||
<router-view />
|
<router-view />
|
||||||
</DesktopLayout>
|
</DesktopLayout>
|
||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import DesktopLayout from '@/components/DesktopLayout.vue'
|
import DesktopLayout from '@/components/DesktopLayout.vue'
|
||||||
|
import { sessionStore as session } from '@/stores/session'
|
||||||
import CallUI from './components/CallUI.vue'
|
import CallUI from './components/CallUI.vue'
|
||||||
import { Toasts } from 'frappe-ui'
|
import { Toasts } from 'frappe-ui'
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -52,7 +52,7 @@
|
|||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<UserAvatar :user="note.owner" size="xs" />
|
<UserAvatar :user="note.owner" size="xs" />
|
||||||
<div class="text-sm text-gray-800">
|
<div class="text-sm text-gray-800">
|
||||||
{{ $user(note.owner).full_name }}
|
{{ getUser(note.owner).full_name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Tooltip :text="dateFormat(note.modified, dateTooltipFormat)">
|
<Tooltip :text="dateFormat(note.modified, dateTooltipFormat)">
|
||||||
@ -382,6 +382,7 @@ import NoteIcon from '@/components/Icons/NoteIcon.vue'
|
|||||||
import DurationIcon from '@/components/Icons/DurationIcon.vue'
|
import DurationIcon from '@/components/Icons/DurationIcon.vue'
|
||||||
import PlayIcon from '@/components/Icons/PlayIcon.vue'
|
import PlayIcon from '@/components/Icons/PlayIcon.vue'
|
||||||
import { timeAgo, dateFormat, dateTooltipFormat } from '@/utils'
|
import { timeAgo, dateFormat, dateTooltipFormat } from '@/utils'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
FeatherIcon,
|
FeatherIcon,
|
||||||
@ -392,6 +393,8 @@ import {
|
|||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { computed, h } from 'vue'
|
import { computed, h } from 'vue'
|
||||||
|
|
||||||
|
const { getUser } = usersStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -425,7 +428,7 @@ const activities = computed(() => {
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
activity.owner_name = $user(activity.owner).full_name
|
activity.owner_name = getUser(activity.owner).full_name
|
||||||
activity.type = ''
|
activity.type = ''
|
||||||
activity.value = ''
|
activity.value = ''
|
||||||
activity.to = ''
|
activity.to = ''
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
@click="showCommunicationBox = true"
|
@click="showCommunicationBox = true"
|
||||||
v-show="!showCommunicationBox"
|
v-show="!showCommunicationBox"
|
||||||
>
|
>
|
||||||
<UserAvatar :user="$user().name" size="sm" />
|
<UserAvatar :user="getUser().name" size="sm" />
|
||||||
<div class="text-base text-gray-600">Add a reply...</div>
|
<div class="text-base text-gray-600">Add a reply...</div>
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
@ -16,9 +16,9 @@
|
|||||||
@keydown.meta.enter.capture.stop="submitComment"
|
@keydown.meta.enter.capture.stop="submitComment"
|
||||||
>
|
>
|
||||||
<div class="mb-4 flex items-center">
|
<div class="mb-4 flex items-center">
|
||||||
<UserAvatar :user="$user().name" size="sm" />
|
<UserAvatar :user="getUser().name" size="sm" />
|
||||||
<span class="ml-2 text-base font-medium text-gray-900">
|
<span class="ml-2 text-base font-medium text-gray-900">
|
||||||
{{ $user().full_name }}
|
{{ getUser().full_name }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<EmailEditor
|
<EmailEditor
|
||||||
@ -47,11 +47,15 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import UserAvatar from '@/components/UserAvatar.vue'
|
import UserAvatar from '@/components/UserAvatar.vue'
|
||||||
import EmailEditor from '@/components/EmailEditor.vue'
|
import EmailEditor from '@/components/EmailEditor.vue'
|
||||||
import { call, Button } from 'frappe-ui'
|
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
|
import { Tooltip, call, Button } from 'frappe-ui'
|
||||||
import { ref, watch, computed, defineModel } from 'vue'
|
import { ref, watch, computed, defineModel } from 'vue'
|
||||||
|
|
||||||
const modelValue = defineModel()
|
const modelValue = defineModel()
|
||||||
|
|
||||||
|
const { getUser } = usersStore()
|
||||||
|
|
||||||
const showCommunicationBox = ref(false)
|
const showCommunicationBox = ref(false)
|
||||||
const newEmail = ref('')
|
const newEmail = ref('')
|
||||||
const newEmailEditor = ref(null)
|
const newEmailEditor = ref(null)
|
||||||
@ -84,8 +88,8 @@ async function sendMail() {
|
|||||||
doctype: 'CRM Lead',
|
doctype: 'CRM Lead',
|
||||||
name: modelValue.value.data.name,
|
name: modelValue.value.data.name,
|
||||||
send_email: 1,
|
send_email: 1,
|
||||||
sender: $user().name,
|
sender: getUser().name,
|
||||||
sender_full_name: $user()?.full_name || undefined,
|
sender_full_name: getUser()?.full_name || undefined,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
<Autocomplete
|
<Autocomplete
|
||||||
v-else-if="field.type === 'link'"
|
v-else-if="field.type === 'link'"
|
||||||
:options="activeAgents"
|
:options="activeAgents"
|
||||||
:value="$user(newDeal[field.name]).full_name"
|
:value="getUser(newDeal[field.name]).full_name"
|
||||||
@change="(option) => (newDeal[field.name] = option.email)"
|
@change="(option) => (newDeal[field.name] = option.email)"
|
||||||
:placeholder="field.placeholder"
|
:placeholder="field.placeholder"
|
||||||
>
|
>
|
||||||
@ -66,6 +66,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||||
import UserAvatar from '@/components/UserAvatar.vue'
|
import UserAvatar from '@/components/UserAvatar.vue'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { dealStatuses, statusDropdownOptions } from '@/utils'
|
import { dealStatuses, statusDropdownOptions } from '@/utils'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -76,6 +77,7 @@ import {
|
|||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const { getUser, users } = usersStore()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
newDeal: {
|
newDeal: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -154,7 +156,7 @@ const allFields = [
|
|||||||
|
|
||||||
const activeAgents = computed(() => {
|
const activeAgents = computed(() => {
|
||||||
const nonAgents = ['Administrator', 'Guest']
|
const nonAgents = ['Administrator', 'Guest']
|
||||||
return $users.data
|
return users.data
|
||||||
.filter((user) => !nonAgents.includes(user.name))
|
.filter((user) => !nonAgents.includes(user.name))
|
||||||
.sort((a, b) => a.full_name - b.full_name)
|
.sort((a, b) => a.full_name - b.full_name)
|
||||||
.map((user) => {
|
.map((user) => {
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
<Autocomplete
|
<Autocomplete
|
||||||
v-else-if="field.type === 'link'"
|
v-else-if="field.type === 'link'"
|
||||||
:options="activeAgents"
|
:options="activeAgents"
|
||||||
:value="$user(newLead[field.name]).full_name"
|
:value="getUser(newLead[field.name]).full_name"
|
||||||
@change="(option) => (newLead[field.name] = option.email)"
|
@change="(option) => (newLead[field.name] = option.email)"
|
||||||
:placeholder="field.placeholder"
|
:placeholder="field.placeholder"
|
||||||
>
|
>
|
||||||
@ -66,6 +66,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||||
import UserAvatar from '@/components/UserAvatar.vue'
|
import UserAvatar from '@/components/UserAvatar.vue'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { leadStatuses, statusDropdownOptions } from '@/utils'
|
import { leadStatuses, statusDropdownOptions } from '@/utils'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -76,6 +77,7 @@ import {
|
|||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const { getUser, users } = usersStore()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
newLead: {
|
newLead: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -154,7 +156,7 @@ const allFields = [
|
|||||||
|
|
||||||
const activeAgents = computed(() => {
|
const activeAgents = computed(() => {
|
||||||
const nonAgents = ['Administrator', 'Guest']
|
const nonAgents = ['Administrator', 'Guest']
|
||||||
return $users.data
|
return users.data
|
||||||
.filter((user) => !nonAgents.includes(user.name))
|
.filter((user) => !nonAgents.includes(user.name))
|
||||||
.sort((a, b) => a.full_name - b.full_name)
|
.sort((a, b) => a.full_name - b.full_name)
|
||||||
.map((user) => {
|
.map((user) => {
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<Avatar
|
<Avatar
|
||||||
v-if="user"
|
v-if="user"
|
||||||
:label="$user(user).full_name"
|
:label="getUser(user).full_name"
|
||||||
:image="$user(user).user_image"
|
:image="getUser(user).user_image"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { Avatar } from 'frappe-ui'
|
import { Avatar } from 'frappe-ui'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -15,4 +16,6 @@ const props = defineProps({
|
|||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const { getUser } = usersStore()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { ref, watchEffect } from 'vue'
|
import { ref, watchEffect } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { toValue } from '@vueuse/core'
|
import { toValue } from '@vueuse/core'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
|
|
||||||
const operatorMap = {
|
const operatorMap = {
|
||||||
is: '=',
|
is: '=',
|
||||||
@ -20,6 +21,7 @@ const operatorMap = {
|
|||||||
export function useFilter(fields) {
|
export function useFilter(fields) {
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const { getUser } = usersStore()
|
||||||
const storage = ref(new Set())
|
const storage = ref(new Set())
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
@ -93,7 +95,7 @@ export function useFilter(fields) {
|
|||||||
*/
|
*/
|
||||||
function transformOut(f) {
|
function transformOut(f) {
|
||||||
if (f.value === '@me') {
|
if (f.value === '@me') {
|
||||||
f.value = $user()
|
f.value = getUser()
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,8 +19,6 @@ import {
|
|||||||
frappeRequest,
|
frappeRequest,
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import socket from './socket'
|
import socket from './socket'
|
||||||
import { sessionStore as session } from './stores/session'
|
|
||||||
import { usersStore } from './stores/users'
|
|
||||||
import { getCachedListResource } from 'frappe-ui/src/resources/listResource'
|
import { getCachedListResource } from 'frappe-ui/src/resources/listResource'
|
||||||
import { getCachedResource } from 'frappe-ui/src/resources/resources'
|
import { getCachedResource } from 'frappe-ui/src/resources/resources'
|
||||||
|
|
||||||
@ -48,12 +46,6 @@ for (let key in globalComponents) {
|
|||||||
app.component(key, globalComponents[key])
|
app.component(key, globalComponents[key])
|
||||||
}
|
}
|
||||||
|
|
||||||
let { getUser, users } = usersStore()
|
|
||||||
|
|
||||||
app.config.globalProperties.$user = getUser
|
|
||||||
app.config.globalProperties.$users = users
|
|
||||||
app.config.globalProperties.$session = session()
|
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
||||||
socket.on('refetch_resource', (data) => {
|
socket.on('refetch_resource', (data) => {
|
||||||
@ -65,9 +57,3 @@ socket.on('refetch_resource', (data) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (import.meta.env.DEV) {
|
|
||||||
window.$user = getUser
|
|
||||||
window.$users = users
|
|
||||||
window.$session = session()
|
|
||||||
}
|
|
||||||
|
|||||||
@ -154,12 +154,14 @@ import {
|
|||||||
Badge,
|
Badge,
|
||||||
createResource,
|
createResource,
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { contactsStore } from '@/stores/contacts'
|
import { contactsStore } from '@/stores/contacts'
|
||||||
import { secondsToDuration } from '@/utils'
|
import { secondsToDuration } from '@/utils'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const { getUser } = usersStore()
|
||||||
const { contacts, getContact } = contactsStore()
|
const { contacts, getContact } = contactsStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -186,13 +188,13 @@ const callLog = createResource({
|
|||||||
image: getContact(doc.from)?.image,
|
image: getContact(doc.from)?.image,
|
||||||
}
|
}
|
||||||
doc.receiver = {
|
doc.receiver = {
|
||||||
label: $user(doc.receiver).full_name,
|
label: getUser(doc.receiver).full_name,
|
||||||
image: $user(doc.receiver).user_image,
|
image: getUser(doc.receiver).user_image,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doc.caller = {
|
doc.caller = {
|
||||||
label: $user(doc.caller).full_name,
|
label: getUser(doc.caller).full_name,
|
||||||
image: $user(doc.caller).user_image,
|
image: getUser(doc.caller).user_image,
|
||||||
}
|
}
|
||||||
doc.receiver = {
|
doc.receiver = {
|
||||||
label: getContact(doc.to)?.full_name || 'Unknown',
|
label: getContact(doc.to)?.full_name || 'Unknown',
|
||||||
|
|||||||
@ -27,10 +27,12 @@ import Breadcrumbs from '@/components/Breadcrumbs.vue'
|
|||||||
import SortIcon from '@/components/Icons/SortIcon.vue'
|
import SortIcon from '@/components/Icons/SortIcon.vue'
|
||||||
import FilterIcon from '@/components/Icons/FilterIcon.vue'
|
import FilterIcon from '@/components/Icons/FilterIcon.vue'
|
||||||
import { secondsToDuration } from '@/utils'
|
import { secondsToDuration } from '@/utils'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { contactsStore } from '@/stores/contacts'
|
import { contactsStore } from '@/stores/contacts'
|
||||||
import { Button, createListResource } from 'frappe-ui'
|
import { Button, createListResource } from 'frappe-ui'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const { getUser } = usersStore()
|
||||||
const { getContact } = contactsStore()
|
const { getContact } = contactsStore()
|
||||||
|
|
||||||
const list = {
|
const list = {
|
||||||
@ -124,13 +126,13 @@ const rows = computed(() => {
|
|||||||
image: getContact(callLog.from)?.image,
|
image: getContact(callLog.from)?.image,
|
||||||
}
|
}
|
||||||
receiver = {
|
receiver = {
|
||||||
label: $user(receiver).full_name,
|
label: getUser(receiver).full_name,
|
||||||
image: $user(receiver).user_image,
|
image: getUser(receiver).user_image,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
caller = {
|
caller = {
|
||||||
label: $user(caller).full_name,
|
label: getUser(caller).full_name,
|
||||||
image: $user(caller).user_image,
|
image: getUser(caller).user_image,
|
||||||
}
|
}
|
||||||
receiver = {
|
receiver = {
|
||||||
label: getContact(callLog.to)?.full_name || 'Unknown',
|
label: getContact(callLog.to)?.full_name || 'Unknown',
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<template #right-header>
|
<template #right-header>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
:options="activeAgents"
|
:options="activeAgents"
|
||||||
:value="$user(deal.data.lead_owner).full_name"
|
:value="getUser(deal.data.lead_owner).full_name"
|
||||||
@change="(option) => updateAssignedAgent(option.email)"
|
@change="(option) => updateAssignedAgent(option.email)"
|
||||||
placeholder="Deal owner"
|
placeholder="Deal owner"
|
||||||
>
|
>
|
||||||
@ -220,7 +220,7 @@
|
|||||||
<Autocomplete
|
<Autocomplete
|
||||||
v-else-if="field.type === 'user'"
|
v-else-if="field.type === 'user'"
|
||||||
:options="activeAgents"
|
:options="activeAgents"
|
||||||
:value="$user(deal.data[field.name]).full_name"
|
:value="getUser(deal.data[field.name]).full_name"
|
||||||
@change="
|
@change="
|
||||||
(option) => updateAssignedAgent(option.email)
|
(option) => updateAssignedAgent(option.email)
|
||||||
"
|
"
|
||||||
@ -231,7 +231,7 @@
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@click="togglePopover()"
|
@click="togglePopover()"
|
||||||
:label="$user(deal.data[field.name]).full_name"
|
:label="getUser(deal.data[field.name]).full_name"
|
||||||
class="!justify-start w-full"
|
class="!justify-start w-full"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
@ -373,6 +373,7 @@ import {
|
|||||||
secondsToDuration,
|
secondsToDuration,
|
||||||
createToast,
|
createToast,
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { contactsStore } from '@/stores/contacts'
|
import { contactsStore } from '@/stores/contacts'
|
||||||
import {
|
import {
|
||||||
createResource,
|
createResource,
|
||||||
@ -390,7 +391,9 @@ import {
|
|||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { ref, computed, inject } from 'vue'
|
import { ref, computed, inject } from 'vue'
|
||||||
|
|
||||||
|
const { getUser, users } = usersStore()
|
||||||
const { getContact, contacts } = contactsStore()
|
const { getContact, contacts } = contactsStore()
|
||||||
|
|
||||||
const makeCall = inject('makeOutgoingCall')
|
const makeCall = inject('makeOutgoingCall')
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -618,7 +621,7 @@ const detailSections = computed(() => {
|
|||||||
|
|
||||||
const activeAgents = computed(() => {
|
const activeAgents = computed(() => {
|
||||||
const nonAgents = ['Administrator', 'Guest']
|
const nonAgents = ['Administrator', 'Guest']
|
||||||
return $users.data
|
return users.data
|
||||||
.filter((user) => !nonAgents.includes(user.name))
|
.filter((user) => !nonAgents.includes(user.name))
|
||||||
.sort((a, b) => a.full_name - b.full_name)
|
.sort((a, b) => a.full_name - b.full_name)
|
||||||
.map((user) => {
|
.map((user) => {
|
||||||
@ -722,13 +725,13 @@ const calls = createListResource({
|
|||||||
image: getContact(doc.from)?.image,
|
image: getContact(doc.from)?.image,
|
||||||
}
|
}
|
||||||
doc.receiver = {
|
doc.receiver = {
|
||||||
label: $user(doc.receiver).full_name,
|
label: getUser(doc.receiver).full_name,
|
||||||
image: $user(doc.receiver).user_image,
|
image: getUser(doc.receiver).user_image,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doc.caller = {
|
doc.caller = {
|
||||||
label: $user(doc.caller).full_name,
|
label: getUser(doc.caller).full_name,
|
||||||
image: $user(doc.caller).user_image,
|
image: getUser(doc.caller).user_image,
|
||||||
}
|
}
|
||||||
doc.receiver = {
|
doc.receiver = {
|
||||||
label: getContact(doc.to)?.full_name || 'Unknown',
|
label: getContact(doc.to)?.full_name || 'Unknown',
|
||||||
|
|||||||
@ -60,6 +60,7 @@ import Breadcrumbs from '@/components/Breadcrumbs.vue'
|
|||||||
import NewDeal from '@/components/NewDeal.vue'
|
import NewDeal from '@/components/NewDeal.vue'
|
||||||
import SortBy from '@/components/SortBy.vue'
|
import SortBy from '@/components/SortBy.vue'
|
||||||
import Filter from '@/components/Filter.vue'
|
import Filter from '@/components/Filter.vue'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { useOrderBy } from '@/composables/orderby'
|
import { useOrderBy } from '@/composables/orderby'
|
||||||
import { useFilter } from '@/composables/filter'
|
import { useFilter } from '@/composables/filter'
|
||||||
import { useDebounceFn } from '@vueuse/core'
|
import { useDebounceFn } from '@vueuse/core'
|
||||||
@ -80,6 +81,7 @@ const list = {
|
|||||||
plural_label: 'Deals',
|
plural_label: 'Deals',
|
||||||
singular_label: 'Deal',
|
singular_label: 'Deal',
|
||||||
}
|
}
|
||||||
|
const { getUser } = usersStore()
|
||||||
const { get: getOrderBy } = useOrderBy()
|
const { get: getOrderBy } = useOrderBy()
|
||||||
const { getArgs, storage } = useFilter()
|
const { getArgs, storage } = useFilter()
|
||||||
|
|
||||||
@ -195,7 +197,7 @@ const rows = computed(() => {
|
|||||||
},
|
},
|
||||||
email: lead.email,
|
email: lead.email,
|
||||||
mobile_no: lead.mobile_no,
|
mobile_no: lead.mobile_no,
|
||||||
lead_owner: lead.lead_owner && $user(lead.lead_owner),
|
lead_owner: lead.lead_owner && getUser(lead.lead_owner),
|
||||||
modified: lead.modified,
|
modified: lead.modified,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -255,7 +257,7 @@ let newDeal = reactive({
|
|||||||
deal_status: 'Qualification',
|
deal_status: 'Qualification',
|
||||||
email: '',
|
email: '',
|
||||||
mobile_no: '',
|
mobile_no: '',
|
||||||
lead_owner: $user().email,
|
lead_owner: getUser().email,
|
||||||
})
|
})
|
||||||
|
|
||||||
const createLead = createResource({
|
const createLead = createResource({
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<template #right-header>
|
<template #right-header>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
:options="activeAgents"
|
:options="activeAgents"
|
||||||
:value="$user(lead.data.lead_owner).full_name"
|
:value="getUser(lead.data.lead_owner).full_name"
|
||||||
@change="(option) => updateAssignedAgent(option.email)"
|
@change="(option) => updateAssignedAgent(option.email)"
|
||||||
placeholder="Lead owner"
|
placeholder="Lead owner"
|
||||||
>
|
>
|
||||||
@ -218,7 +218,7 @@
|
|||||||
<Autocomplete
|
<Autocomplete
|
||||||
v-else-if="field.type === 'user'"
|
v-else-if="field.type === 'user'"
|
||||||
:options="activeAgents"
|
:options="activeAgents"
|
||||||
:value="$user(lead.data[field.name]).full_name"
|
:value="getUser(lead.data[field.name]).full_name"
|
||||||
@change="
|
@change="
|
||||||
(option) => updateAssignedAgent(option.email)
|
(option) => updateAssignedAgent(option.email)
|
||||||
"
|
"
|
||||||
@ -229,7 +229,7 @@
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@click="togglePopover()"
|
@click="togglePopover()"
|
||||||
:label="$user(lead.data[field.name]).full_name"
|
:label="getUser(lead.data[field.name]).full_name"
|
||||||
class="!justify-start w-full"
|
class="!justify-start w-full"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
@ -341,9 +341,11 @@ import {
|
|||||||
secondsToDuration,
|
secondsToDuration,
|
||||||
createToast,
|
createToast,
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { contactsStore } from '@/stores/contacts'
|
import { contactsStore } from '@/stores/contacts'
|
||||||
import {
|
import {
|
||||||
createResource,
|
createResource,
|
||||||
|
createDocumentResource,
|
||||||
createListResource,
|
createListResource,
|
||||||
FileUploader,
|
FileUploader,
|
||||||
ErrorMessage,
|
ErrorMessage,
|
||||||
@ -358,6 +360,7 @@ import {
|
|||||||
import { ref, computed, inject } from 'vue'
|
import { ref, computed, inject } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const { getUser, users } = usersStore()
|
||||||
const { getContact, contacts } = contactsStore()
|
const { getContact, contacts } = contactsStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -593,7 +596,7 @@ const detailSections = computed(() => {
|
|||||||
|
|
||||||
const activeAgents = computed(() => {
|
const activeAgents = computed(() => {
|
||||||
const nonAgents = ['Administrator', 'admin@example.com', 'Guest']
|
const nonAgents = ['Administrator', 'admin@example.com', 'Guest']
|
||||||
return $users.data
|
return users.data
|
||||||
.filter((user) => !nonAgents.includes(user.name))
|
.filter((user) => !nonAgents.includes(user.name))
|
||||||
.sort((a, b) => a.full_name - b.full_name)
|
.sort((a, b) => a.full_name - b.full_name)
|
||||||
.map((user) => {
|
.map((user) => {
|
||||||
@ -704,13 +707,13 @@ const calls = createListResource({
|
|||||||
image: getContact(doc.from)?.image,
|
image: getContact(doc.from)?.image,
|
||||||
}
|
}
|
||||||
doc.receiver = {
|
doc.receiver = {
|
||||||
label: $user(doc.receiver).full_name,
|
label: getUser(doc.receiver).full_name,
|
||||||
image: $user(doc.receiver).user_image,
|
image: getUser(doc.receiver).user_image,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doc.caller = {
|
doc.caller = {
|
||||||
label: $user(doc.caller).full_name,
|
label: getUser(doc.caller).full_name,
|
||||||
image: $user(doc.caller).user_image,
|
image: getUser(doc.caller).user_image,
|
||||||
}
|
}
|
||||||
doc.receiver = {
|
doc.receiver = {
|
||||||
label: getContact(doc.to)?.full_name || 'Unknown',
|
label: getContact(doc.to)?.full_name || 'Unknown',
|
||||||
|
|||||||
@ -59,6 +59,7 @@ import Breadcrumbs from '@/components/Breadcrumbs.vue'
|
|||||||
import NewLead from '@/components/NewLead.vue'
|
import NewLead from '@/components/NewLead.vue'
|
||||||
import SortBy from '@/components/SortBy.vue'
|
import SortBy from '@/components/SortBy.vue'
|
||||||
import Filter from '@/components/Filter.vue'
|
import Filter from '@/components/Filter.vue'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
import { useOrderBy } from '@/composables/orderby'
|
import { useOrderBy } from '@/composables/orderby'
|
||||||
import { useFilter } from '@/composables/filter'
|
import { useFilter } from '@/composables/filter'
|
||||||
import { useDebounceFn } from '@vueuse/core'
|
import { useDebounceFn } from '@vueuse/core'
|
||||||
@ -79,6 +80,7 @@ const list = {
|
|||||||
plural_label: 'Leads',
|
plural_label: 'Leads',
|
||||||
singular_label: 'Lead',
|
singular_label: 'Lead',
|
||||||
}
|
}
|
||||||
|
const { getUser } = usersStore()
|
||||||
const { get: getOrderBy } = useOrderBy()
|
const { get: getOrderBy } = useOrderBy()
|
||||||
const { getArgs, storage } = useFilter()
|
const { getArgs, storage } = useFilter()
|
||||||
|
|
||||||
@ -204,7 +206,7 @@ const rows = computed(() => {
|
|||||||
},
|
},
|
||||||
email: lead.email,
|
email: lead.email,
|
||||||
mobile_no: lead.mobile_no,
|
mobile_no: lead.mobile_no,
|
||||||
lead_owner: lead.lead_owner && $user(lead.lead_owner),
|
lead_owner: lead.lead_owner && getUser(lead.lead_owner),
|
||||||
modified: lead.modified,
|
modified: lead.modified,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -264,7 +266,7 @@ let newLead = reactive({
|
|||||||
status: 'Open',
|
status: 'Open',
|
||||||
email: '',
|
email: '',
|
||||||
mobile_no: '',
|
mobile_no: '',
|
||||||
lead_owner: $user().email,
|
lead_owner: getUser().email,
|
||||||
})
|
})
|
||||||
|
|
||||||
const createLead = createResource({
|
const createLead = createResource({
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
label="Email"
|
label="Email"
|
||||||
v-model="email"
|
v-model="email"
|
||||||
placeholder="jane@example.com"
|
placeholder="jane@example.com"
|
||||||
:disabled="login.loading"
|
:disabled="session.login.loading"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
@ -34,15 +34,15 @@
|
|||||||
label="Password"
|
label="Password"
|
||||||
v-model="password"
|
v-model="password"
|
||||||
placeholder="••••••"
|
placeholder="••••••"
|
||||||
:disabled="login.loading"
|
:disabled="session.login.loading"
|
||||||
type="password"
|
type="password"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ErrorMessage class="mt-2" :message="login.error" />
|
<ErrorMessage class="mt-2" :message="session.login.error" />
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
class="mt-6 w-full"
|
class="mt-6 w-full"
|
||||||
:loading="login.loading"
|
:loading="session.login.loading"
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
@ -81,7 +81,7 @@ import { sessionStore } from '@/stores/session'
|
|||||||
import { FormControl, ErrorMessage, createResource } from 'frappe-ui'
|
import { FormControl, ErrorMessage, createResource } from 'frappe-ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const { login } = sessionStore()
|
const session = sessionStore()
|
||||||
let showEmailLogin = ref(false)
|
let showEmailLogin = ref(false)
|
||||||
let email = ref('')
|
let email = ref('')
|
||||||
let password = ref('')
|
let password = ref('')
|
||||||
@ -96,7 +96,7 @@ let authProviders = createResource({
|
|||||||
authProviders.fetch()
|
authProviders.fetch()
|
||||||
|
|
||||||
function submit() {
|
function submit() {
|
||||||
login.submit({
|
session.login.submit({
|
||||||
usr: email.value,
|
usr: email.value,
|
||||||
pwd: password.value,
|
pwd: password.value,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<UserAvatar :user="note.owner" size="xs" />
|
<UserAvatar :user="note.owner" size="xs" />
|
||||||
<div class="text-sm text-gray-800">
|
<div class="text-sm text-gray-800">
|
||||||
{{ $user(note.owner).full_name }}
|
{{ getUser(note.owner).full_name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Tooltip :text="dateFormat(note.modified, dateTooltipFormat)">
|
<Tooltip :text="dateFormat(note.modified, dateTooltipFormat)">
|
||||||
@ -93,6 +93,9 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
|
|
||||||
|
const { getUser } = usersStore()
|
||||||
|
|
||||||
const list = {
|
const list = {
|
||||||
title: 'Notes',
|
title: 'Notes',
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
|
import { sessionStore } from '@/stores/session'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@ -71,11 +73,14 @@ let router = createRouter({
|
|||||||
})
|
})
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
await $users.promise
|
const { users } = usersStore()
|
||||||
|
const { isLoggedIn } = sessionStore()
|
||||||
|
|
||||||
if (to.name === 'Login' && $session.isLoggedIn) {
|
await users.promise
|
||||||
|
|
||||||
|
if (to.name === 'Login' && isLoggedIn) {
|
||||||
next({ name: 'Leads' })
|
next({ name: 'Leads' })
|
||||||
} else if (to.name !== 'Login' && !$session.isLoggedIn) {
|
} else if (to.name !== 'Login' && !isLoggedIn) {
|
||||||
next({ name: 'Login' })
|
next({ name: 'Login' })
|
||||||
} else if (to.matched.length === 0) {
|
} else if (to.matched.length === 0) {
|
||||||
next({ name: 'Invalid Page' })
|
next({ name: 'Invalid Page' })
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { createResource } from 'frappe-ui'
|
import { createResource } from 'frappe-ui'
|
||||||
|
import { usersStore } from './users'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
export const sessionStore = defineStore('crm-session', () => {
|
export const sessionStore = defineStore('crm-session', () => {
|
||||||
|
const { users } = usersStore()
|
||||||
|
|
||||||
function sessionUser() {
|
function sessionUser() {
|
||||||
let cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
let cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
||||||
let _sessionUser = cookies.get('user_id')
|
let _sessionUser = cookies.get('user_id')
|
||||||
@ -22,7 +25,7 @@ export const sessionStore = defineStore('crm-session', () => {
|
|||||||
throw new Error('Invalid email or password')
|
throw new Error('Invalid email or password')
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
$users.reload()
|
users.reload()
|
||||||
user.value = sessionUser()
|
user.value = sessionUser()
|
||||||
login.reset()
|
login.reset()
|
||||||
router.replace({ path: '/' })
|
router.replace({ path: '/' })
|
||||||
@ -32,7 +35,7 @@ export const sessionStore = defineStore('crm-session', () => {
|
|||||||
const logout = createResource({
|
const logout = createResource({
|
||||||
url: 'logout',
|
url: 'logout',
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
$users.reset()
|
users.reset()
|
||||||
user.value = null
|
user.value = null
|
||||||
router.replace({ name: 'Login' })
|
router.replace({ name: 'Login' })
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user