Merge pull request #5 from shariquerik/use-global-properties

This commit is contained in:
Shariq Ansari 2023-09-18 19:37:11 +05:30 committed by GitHub
commit 23ee69e7a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 70 additions and 98 deletions

View File

@ -1,6 +1,6 @@
<template>
<router-view v-if="$route.name == 'Login'" />
<CallUI v-else-if="session().isLoggedIn">
<CallUI v-else-if="$session.isLoggedIn">
<DesktopLayout>
<router-view />
</DesktopLayout>
@ -10,7 +10,6 @@
<script setup>
import DesktopLayout from '@/components/DesktopLayout.vue'
import { sessionStore as session } from '@/stores/session'
import CallUI from './components/CallUI.vue'
import { Toasts } from 'frappe-ui'
</script>

View File

@ -52,7 +52,7 @@
<div class="flex items-center gap-2">
<UserAvatar :user="note.owner" size="xs" />
<div class="text-sm text-gray-800">
{{ getUser(note.owner).full_name }}
{{ $user(note.owner).full_name }}
</div>
</div>
<Tooltip :text="dateFormat(note.modified, dateTooltipFormat)">
@ -382,7 +382,6 @@ import NoteIcon from '@/components/Icons/NoteIcon.vue'
import DurationIcon from '@/components/Icons/DurationIcon.vue'
import PlayIcon from '@/components/Icons/PlayIcon.vue'
import { timeAgo, dateFormat, dateTooltipFormat } from '@/utils'
import { usersStore } from '@/stores/users'
import {
Button,
FeatherIcon,
@ -393,8 +392,6 @@ import {
} from 'frappe-ui'
import { computed, h } from 'vue'
const { getUser } = usersStore()
const props = defineProps({
title: {
type: String,
@ -428,7 +425,7 @@ const activities = computed(() => {
)
return
activity.owner_name = getUser(activity.owner).full_name
activity.owner_name = $user(activity.owner).full_name
activity.type = ''
activity.value = ''
activity.to = ''

View File

@ -6,7 +6,7 @@
@click="showCommunicationBox = true"
v-show="!showCommunicationBox"
>
<UserAvatar :user="getUser().name" size="sm" />
<UserAvatar :user="$user().name" size="sm" />
<div class="text-base text-gray-600">Add a reply...</div>
</button>
<div
@ -16,9 +16,9 @@
@keydown.meta.enter.capture.stop="submitComment"
>
<div class="mb-4 flex items-center">
<UserAvatar :user="getUser().name" size="sm" />
<UserAvatar :user="$user().name" size="sm" />
<span class="ml-2 text-base font-medium text-gray-900">
{{ getUser().full_name }}
{{ $user().full_name }}
</span>
</div>
<EmailEditor
@ -47,15 +47,11 @@
<script setup>
import UserAvatar from '@/components/UserAvatar.vue'
import EmailEditor from '@/components/EmailEditor.vue'
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
import { usersStore } from '@/stores/users'
import { Tooltip, call, Button } from 'frappe-ui'
import { call, Button } from 'frappe-ui'
import { ref, watch, computed, defineModel } from 'vue'
const modelValue = defineModel()
const { getUser } = usersStore()
const showCommunicationBox = ref(false)
const newEmail = ref('')
const newEmailEditor = ref(null)
@ -88,8 +84,8 @@ async function sendMail() {
doctype: 'CRM Lead',
name: modelValue.value.data.name,
send_email: 1,
sender: getUser().name,
sender_full_name: getUser()?.full_name || undefined,
sender: $user().name,
sender_full_name: $user()?.full_name || undefined,
})
}

View File

@ -22,7 +22,7 @@
<Autocomplete
v-else-if="field.type === 'link'"
:options="activeAgents"
:value="getUser(newDeal[field.name]).full_name"
:value="$user(newDeal[field.name]).full_name"
@change="(option) => (newDeal[field.name] = option.email)"
:placeholder="field.placeholder"
>
@ -66,7 +66,6 @@
<script setup>
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import { usersStore } from '@/stores/users'
import { dealStatuses, statusDropdownOptions } from '@/utils'
import {
FormControl,
@ -77,7 +76,6 @@ import {
} from 'frappe-ui'
import { computed } from 'vue'
const { getUser, users } = usersStore()
const props = defineProps({
newDeal: {
type: Object,
@ -156,7 +154,7 @@ const allFields = [
const activeAgents = computed(() => {
const nonAgents = ['Administrator', 'Guest']
return users.data
return $users.data
.filter((user) => !nonAgents.includes(user.name))
.sort((a, b) => a.full_name - b.full_name)
.map((user) => {

View File

@ -22,7 +22,7 @@
<Autocomplete
v-else-if="field.type === 'link'"
:options="activeAgents"
:value="getUser(newLead[field.name]).full_name"
:value="$user(newLead[field.name]).full_name"
@change="(option) => (newLead[field.name] = option.email)"
:placeholder="field.placeholder"
>
@ -66,7 +66,6 @@
<script setup>
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import { usersStore } from '@/stores/users'
import { leadStatuses, statusDropdownOptions } from '@/utils'
import {
FormControl,
@ -77,7 +76,6 @@ import {
} from 'frappe-ui'
import { computed } from 'vue'
const { getUser, users } = usersStore()
const props = defineProps({
newLead: {
type: Object,
@ -156,7 +154,7 @@ const allFields = [
const activeAgents = computed(() => {
const nonAgents = ['Administrator', 'Guest']
return users.data
return $users.data
.filter((user) => !nonAgents.includes(user.name))
.sort((a, b) => a.full_name - b.full_name)
.map((user) => {

View File

@ -1,13 +1,12 @@
<template>
<Avatar
v-if="user"
:label="getUser(user).full_name"
:image="getUser(user).user_image"
:label="$user(user).full_name"
:image="$user(user).user_image"
v-bind="$attrs"
/>
</template>
<script setup>
import { usersStore } from '@/stores/users'
import { Avatar } from 'frappe-ui'
const props = defineProps({
@ -16,6 +15,4 @@ const props = defineProps({
default: null,
},
})
const { getUser } = usersStore()
</script>

View File

@ -1,7 +1,6 @@
import { ref, watchEffect } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { toValue } from '@vueuse/core'
import { usersStore } from '@/stores/users'
const operatorMap = {
is: '=',
@ -21,7 +20,6 @@ const operatorMap = {
export function useFilter(fields) {
const route = useRoute()
const router = useRouter()
const { getUser } = usersStore()
const storage = ref(new Set())
watchEffect(() => {
@ -95,7 +93,7 @@ export function useFilter(fields) {
*/
function transformOut(f) {
if (f.value === '@me') {
f.value = getUser()
f.value = $user()
}
return f
}

View File

@ -19,6 +19,8 @@ import {
frappeRequest,
} from 'frappe-ui'
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 { getCachedResource } from 'frappe-ui/src/resources/resources'
@ -46,6 +48,12 @@ for (let key in globalComponents) {
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')
socket.on('refetch_resource', (data) => {
@ -57,3 +65,9 @@ socket.on('refetch_resource', (data) => {
}
}
})
if (import.meta.env.DEV) {
window.$user = getUser
window.$users = users
window.$session = session()
}

View File

@ -154,14 +154,12 @@ import {
Badge,
createResource,
} from 'frappe-ui'
import { usersStore } from '@/stores/users'
import { contactsStore } from '@/stores/contacts'
import { secondsToDuration } from '@/utils'
import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const { getUser } = usersStore()
const { contacts, getContact } = contactsStore()
const props = defineProps({
@ -188,13 +186,13 @@ const callLog = createResource({
image: getContact(doc.from)?.image,
}
doc.receiver = {
label: getUser(doc.receiver).full_name,
image: getUser(doc.receiver).user_image,
label: $user(doc.receiver).full_name,
image: $user(doc.receiver).user_image,
}
} else {
doc.caller = {
label: getUser(doc.caller).full_name,
image: getUser(doc.caller).user_image,
label: $user(doc.caller).full_name,
image: $user(doc.caller).user_image,
}
doc.receiver = {
label: getContact(doc.to)?.full_name || 'Unknown',

View File

@ -27,12 +27,10 @@ import Breadcrumbs from '@/components/Breadcrumbs.vue'
import SortIcon from '@/components/Icons/SortIcon.vue'
import FilterIcon from '@/components/Icons/FilterIcon.vue'
import { secondsToDuration } from '@/utils'
import { usersStore } from '@/stores/users'
import { contactsStore } from '@/stores/contacts'
import { Button, createListResource } from 'frappe-ui'
import { computed } from 'vue'
const { getUser } = usersStore()
const { getContact } = contactsStore()
const list = {
@ -126,13 +124,13 @@ const rows = computed(() => {
image: getContact(callLog.from)?.image,
}
receiver = {
label: getUser(receiver).full_name,
image: getUser(receiver).user_image,
label: $user(receiver).full_name,
image: $user(receiver).user_image,
}
} else {
caller = {
label: getUser(caller).full_name,
image: getUser(caller).user_image,
label: $user(caller).full_name,
image: $user(caller).user_image,
}
receiver = {
label: getContact(callLog.to)?.full_name || 'Unknown',

View File

@ -6,7 +6,7 @@
<template #right-header>
<Autocomplete
:options="activeAgents"
:value="getUser(deal.data.lead_owner).full_name"
:value="$user(deal.data.lead_owner).full_name"
@change="(option) => updateAssignedAgent(option.email)"
placeholder="Deal owner"
>
@ -220,7 +220,7 @@
<Autocomplete
v-else-if="field.type === 'user'"
:options="activeAgents"
:value="getUser(deal.data[field.name]).full_name"
:value="$user(deal.data[field.name]).full_name"
@change="
(option) => updateAssignedAgent(option.email)
"
@ -231,7 +231,7 @@
<Button
variant="ghost"
@click="togglePopover()"
:label="getUser(deal.data[field.name]).full_name"
:label="$user(deal.data[field.name]).full_name"
class="!justify-start w-full"
>
<template #prefix>
@ -373,7 +373,6 @@ import {
secondsToDuration,
createToast,
} from '@/utils'
import { usersStore } from '@/stores/users'
import { contactsStore } from '@/stores/contacts'
import {
createResource,
@ -391,9 +390,7 @@ import {
} from 'frappe-ui'
import { ref, computed, inject } from 'vue'
const { getUser, users } = usersStore()
const { getContact, contacts } = contactsStore()
const makeCall = inject('makeOutgoingCall')
const props = defineProps({
@ -621,7 +618,7 @@ const detailSections = computed(() => {
const activeAgents = computed(() => {
const nonAgents = ['Administrator', 'Guest']
return users.data
return $users.data
.filter((user) => !nonAgents.includes(user.name))
.sort((a, b) => a.full_name - b.full_name)
.map((user) => {
@ -725,13 +722,13 @@ const calls = createListResource({
image: getContact(doc.from)?.image,
}
doc.receiver = {
label: getUser(doc.receiver).full_name,
image: getUser(doc.receiver).user_image,
label: $user(doc.receiver).full_name,
image: $user(doc.receiver).user_image,
}
} else {
doc.caller = {
label: getUser(doc.caller).full_name,
image: getUser(doc.caller).user_image,
label: $user(doc.caller).full_name,
image: $user(doc.caller).user_image,
}
doc.receiver = {
label: getContact(doc.to)?.full_name || 'Unknown',

View File

@ -60,7 +60,6 @@ import Breadcrumbs from '@/components/Breadcrumbs.vue'
import NewDeal from '@/components/NewDeal.vue'
import SortBy from '@/components/SortBy.vue'
import Filter from '@/components/Filter.vue'
import { usersStore } from '@/stores/users'
import { useOrderBy } from '@/composables/orderby'
import { useFilter } from '@/composables/filter'
import { useDebounceFn } from '@vueuse/core'
@ -81,7 +80,6 @@ const list = {
plural_label: 'Deals',
singular_label: 'Deal',
}
const { getUser } = usersStore()
const { get: getOrderBy } = useOrderBy()
const { getArgs, storage } = useFilter()
@ -197,7 +195,7 @@ const rows = computed(() => {
},
email: lead.email,
mobile_no: lead.mobile_no,
lead_owner: lead.lead_owner && getUser(lead.lead_owner),
lead_owner: lead.lead_owner && $user(lead.lead_owner),
modified: lead.modified,
}
})
@ -257,7 +255,7 @@ let newDeal = reactive({
deal_status: 'Qualification',
email: '',
mobile_no: '',
lead_owner: getUser().email,
lead_owner: $user().email,
})
const createLead = createResource({

View File

@ -6,7 +6,7 @@
<template #right-header>
<Autocomplete
:options="activeAgents"
:value="getUser(lead.data.lead_owner).full_name"
:value="$user(lead.data.lead_owner).full_name"
@change="(option) => updateAssignedAgent(option.email)"
placeholder="Lead owner"
>
@ -218,7 +218,7 @@
<Autocomplete
v-else-if="field.type === 'user'"
:options="activeAgents"
:value="getUser(lead.data[field.name]).full_name"
:value="$user(lead.data[field.name]).full_name"
@change="
(option) => updateAssignedAgent(option.email)
"
@ -229,7 +229,7 @@
<Button
variant="ghost"
@click="togglePopover()"
:label="getUser(lead.data[field.name]).full_name"
:label="$user(lead.data[field.name]).full_name"
class="!justify-start w-full"
>
<template #prefix>
@ -341,11 +341,9 @@ import {
secondsToDuration,
createToast,
} from '@/utils'
import { usersStore } from '@/stores/users'
import { contactsStore } from '@/stores/contacts'
import {
createResource,
createDocumentResource,
createListResource,
FileUploader,
ErrorMessage,
@ -360,7 +358,6 @@ import {
import { ref, computed, inject } from 'vue'
import { useRouter } from 'vue-router'
const { getUser, users } = usersStore()
const { getContact, contacts } = contactsStore()
const router = useRouter()
@ -596,7 +593,7 @@ const detailSections = computed(() => {
const activeAgents = computed(() => {
const nonAgents = ['Administrator', 'admin@example.com', 'Guest']
return users.data
return $users.data
.filter((user) => !nonAgents.includes(user.name))
.sort((a, b) => a.full_name - b.full_name)
.map((user) => {
@ -707,13 +704,13 @@ const calls = createListResource({
image: getContact(doc.from)?.image,
}
doc.receiver = {
label: getUser(doc.receiver).full_name,
image: getUser(doc.receiver).user_image,
label: $user(doc.receiver).full_name,
image: $user(doc.receiver).user_image,
}
} else {
doc.caller = {
label: getUser(doc.caller).full_name,
image: getUser(doc.caller).user_image,
label: $user(doc.caller).full_name,
image: $user(doc.caller).user_image,
}
doc.receiver = {
label: getContact(doc.to)?.full_name || 'Unknown',

View File

@ -59,7 +59,6 @@ import Breadcrumbs from '@/components/Breadcrumbs.vue'
import NewLead from '@/components/NewLead.vue'
import SortBy from '@/components/SortBy.vue'
import Filter from '@/components/Filter.vue'
import { usersStore } from '@/stores/users'
import { useOrderBy } from '@/composables/orderby'
import { useFilter } from '@/composables/filter'
import { useDebounceFn } from '@vueuse/core'
@ -80,7 +79,6 @@ const list = {
plural_label: 'Leads',
singular_label: 'Lead',
}
const { getUser } = usersStore()
const { get: getOrderBy } = useOrderBy()
const { getArgs, storage } = useFilter()
@ -206,7 +204,7 @@ const rows = computed(() => {
},
email: lead.email,
mobile_no: lead.mobile_no,
lead_owner: lead.lead_owner && getUser(lead.lead_owner),
lead_owner: lead.lead_owner && $user(lead.lead_owner),
modified: lead.modified,
}
})
@ -266,7 +264,7 @@ let newLead = reactive({
status: 'Open',
email: '',
mobile_no: '',
lead_owner: getUser().email,
lead_owner: $user().email,
})
const createLead = createResource({

View File

@ -24,7 +24,7 @@
label="Email"
v-model="email"
placeholder="jane@example.com"
:disabled="session.login.loading"
:disabled="login.loading"
/>
</div>
<div class="mt-4">
@ -34,15 +34,15 @@
label="Password"
v-model="password"
placeholder="••••••"
:disabled="session.login.loading"
:disabled="login.loading"
type="password"
/>
</div>
<ErrorMessage class="mt-2" :message="session.login.error" />
<ErrorMessage class="mt-2" :message="login.error" />
<Button
variant="solid"
class="mt-6 w-full"
:loading="session.login.loading"
:loading="login.loading"
>
Login
</Button>
@ -81,7 +81,7 @@ import { sessionStore } from '@/stores/session'
import { FormControl, ErrorMessage, createResource } from 'frappe-ui'
import { ref } from 'vue'
const session = sessionStore()
const { login } = sessionStore()
let showEmailLogin = ref(false)
let email = ref('')
let password = ref('')
@ -96,7 +96,7 @@ let authProviders = createResource({
authProviders.fetch()
function submit() {
session.login.submit({
login.submit({
usr: email.value,
pwd: password.value,
})

View File

@ -48,7 +48,7 @@
<div class="flex items-center gap-2">
<UserAvatar :user="note.owner" size="xs" />
<div class="text-sm text-gray-800">
{{ getUser(note.owner).full_name }}
{{ $user(note.owner).full_name }}
</div>
</div>
<Tooltip :text="dateFormat(note.modified, dateTooltipFormat)">
@ -93,9 +93,6 @@ import {
Tooltip,
} from 'frappe-ui'
import { ref } from 'vue'
import { usersStore } from '@/stores/users'
const { getUser } = usersStore()
const list = {
title: 'Notes',

View File

@ -1,6 +1,4 @@
import { createRouter, createWebHistory } from 'vue-router'
import { usersStore } from '@/stores/users'
import { sessionStore } from '@/stores/session'
const routes = [
{
@ -73,14 +71,11 @@ let router = createRouter({
})
router.beforeEach(async (to, from, next) => {
const { users } = usersStore()
const { isLoggedIn } = sessionStore()
await $users.promise
await users.promise
if (to.name === 'Login' && isLoggedIn) {
if (to.name === 'Login' && $session.isLoggedIn) {
next({ name: 'Leads' })
} else if (to.name !== 'Login' && !isLoggedIn) {
} else if (to.name !== 'Login' && !$session.isLoggedIn) {
next({ name: 'Login' })
} else if (to.matched.length === 0) {
next({ name: 'Invalid Page' })

View File

@ -1,12 +1,9 @@
import { defineStore } from 'pinia'
import { createResource } from 'frappe-ui'
import { usersStore } from './users'
import router from '@/router'
import { ref, computed } from 'vue'
export const sessionStore = defineStore('crm-session', () => {
const { users } = usersStore()
function sessionUser() {
let cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
let _sessionUser = cookies.get('user_id')
@ -25,7 +22,7 @@ export const sessionStore = defineStore('crm-session', () => {
throw new Error('Invalid email or password')
},
onSuccess() {
users.reload()
$users.reload()
user.value = sessionUser()
login.reset()
router.replace({ path: '/' })
@ -35,7 +32,7 @@ export const sessionStore = defineStore('crm-session', () => {
const logout = createResource({
url: 'logout',
onSuccess() {
users.reset()
$users.reset()
user.value = null
router.replace({ name: 'Login' })
},