Merge pull request #558 from frappe/develop
This commit is contained in:
commit
e2d28563af
@ -13,14 +13,14 @@ class CRMCallLog(Document):
|
|||||||
def default_list_data():
|
def default_list_data():
|
||||||
columns = [
|
columns = [
|
||||||
{
|
{
|
||||||
"label": "From",
|
"label": "Caller",
|
||||||
"type": "Link",
|
"type": "Link",
|
||||||
"key": "caller",
|
"key": "caller",
|
||||||
"options": "User",
|
"options": "User",
|
||||||
"width": "9rem",
|
"width": "9rem",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "To",
|
"label": "Receiver",
|
||||||
"type": "Link",
|
"type": "Link",
|
||||||
"key": "receiver",
|
"key": "receiver",
|
||||||
"options": "User",
|
"options": "User",
|
||||||
|
|||||||
@ -278,8 +278,6 @@ def update_call_log(call_payload, status="Ringing", call_log=None):
|
|||||||
|
|
||||||
if direction == "incoming" and call_payload.get("AgentEmail"):
|
if direction == "incoming" and call_payload.get("AgentEmail"):
|
||||||
call_log.receiver = call_payload.get("AgentEmail")
|
call_log.receiver = call_payload.get("AgentEmail")
|
||||||
else:
|
|
||||||
call_log.caller = frappe.session.user
|
|
||||||
|
|
||||||
call_log.save(ignore_permissions=True)
|
call_log.save(ignore_permissions=True)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
v-if="note.content"
|
v-if="note.content"
|
||||||
:content="note.content"
|
:content="note.content"
|
||||||
:editable="false"
|
:editable="false"
|
||||||
editor-class="!prose-sm max-w-none !text-sm text-ink-gray-5 focus:outline-none"
|
editor-class="prose-sm text-p-sm max-w-none text-ink-gray-5 focus:outline-none"
|
||||||
class="flex-1 overflow-hidden"
|
class="flex-1 overflow-hidden"
|
||||||
/>
|
/>
|
||||||
<div class="mt-1 flex items-center justify-between gap-2">
|
<div class="mt-1 flex items-center justify-between gap-2">
|
||||||
|
|||||||
@ -1,75 +1,97 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="profile" class="flex w-full items-center justify-between p-12 pt-14">
|
<div class="flex h-full flex-col gap-8 p-8 text-ink-gray-9">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex-1 flex flex-col gap-8 mt-2 overflow-y-auto">
|
||||||
<Avatar
|
<div v-if="profile" class="flex w-full items-center justify-between">
|
||||||
class="!size-16"
|
<div class="flex items-center gap-4">
|
||||||
:image="profile.user_image"
|
<Avatar
|
||||||
:label="profile.full_name"
|
class="!size-16"
|
||||||
/>
|
:image="profile.user_image"
|
||||||
<div class="flex flex-col gap-1">
|
:label="profile.full_name"
|
||||||
<span class="text-2xl font-semibold text-ink-gray-9">{{ profile.full_name }}</span>
|
/>
|
||||||
<span class="text-base text-ink-gray-7">{{ profile.email }}</span>
|
<div class="flex flex-col gap-1">
|
||||||
|
<span class="text-2xl font-semibold text-ink-gray-9">{{
|
||||||
|
profile.full_name
|
||||||
|
}}</span>
|
||||||
|
<span class="text-base text-ink-gray-7">{{ profile.email }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
:label="__('Edit profile photo')"
|
||||||
|
@click="showEditProfilePhotoModal = true"
|
||||||
|
/>
|
||||||
|
<Dialog
|
||||||
|
:options="{ title: __('Edit profile photo') }"
|
||||||
|
v-model="showEditProfilePhotoModal"
|
||||||
|
>
|
||||||
|
<template #body-content>
|
||||||
|
<ProfileImageEditor v-model="profile" />
|
||||||
|
</template>
|
||||||
|
<template #actions>
|
||||||
|
<Button
|
||||||
|
variant="solid"
|
||||||
|
class="w-full"
|
||||||
|
:loading="loading"
|
||||||
|
@click="updateUser"
|
||||||
|
:label="__('Save')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex justify-between gap-4">
|
||||||
|
<FormControl
|
||||||
|
class="w-full"
|
||||||
|
label="First name"
|
||||||
|
v-model="profile.first_name"
|
||||||
|
/>
|
||||||
|
<FormControl
|
||||||
|
class="w-full"
|
||||||
|
label="Last name"
|
||||||
|
v-model="profile.last_name"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-4">
|
||||||
|
<FormControl
|
||||||
|
class="w-full"
|
||||||
|
label="Email"
|
||||||
|
v-model="profile.email"
|
||||||
|
:disabled="true"
|
||||||
|
/>
|
||||||
|
<FormControl
|
||||||
|
class="w-full"
|
||||||
|
label="Set new password"
|
||||||
|
v-model="profile.new_password"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button :label="__('Edit profile')" @click="showProfileModal = true" />
|
<div class="flex justify-between flex-row-reverse">
|
||||||
<Dialog
|
<Button
|
||||||
:options="{ title: __('Edit Profile') }"
|
variant="solid"
|
||||||
v-model="showProfileModal"
|
:label="__('Update')"
|
||||||
@after-leave="editingProfilePhoto = false"
|
:loading="loading"
|
||||||
>
|
@click="updateUser"
|
||||||
<template #body-content>
|
/>
|
||||||
<div v-if="user" class="space-y-4">
|
<ErrorMessage :message="error" />
|
||||||
<ProfileImageEditor v-model="profile" v-if="editingProfilePhoto" />
|
</div>
|
||||||
<template v-else>
|
|
||||||
<div class="flex items-center gap-4">
|
|
||||||
<Avatar
|
|
||||||
size="lg"
|
|
||||||
:image="profile.user_image"
|
|
||||||
:label="profile.full_name"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
:label="__('Edit Profile Photo')"
|
|
||||||
@click="editingProfilePhoto = true"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<FormControl label="First Name" v-model="profile.first_name" />
|
|
||||||
<FormControl label="Last Name" v-model="profile.last_name" />
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #actions>
|
|
||||||
<Button
|
|
||||||
v-if="editingProfilePhoto"
|
|
||||||
class="mb-2 w-full"
|
|
||||||
@click="editingProfilePhoto = false"
|
|
||||||
:label="__('Back')"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="solid"
|
|
||||||
class="w-full"
|
|
||||||
:loading="loading"
|
|
||||||
@click="updateUser"
|
|
||||||
:label="__('Save')"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</Dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import ProfileImageEditor from '@/components/Settings/ProfileImageEditor.vue'
|
import ProfileImageEditor from '@/components/Settings/ProfileImageEditor.vue'
|
||||||
import { usersStore } from '@/stores/users'
|
import { usersStore } from '@/stores/users'
|
||||||
import { Dialog, Avatar, createResource } from 'frappe-ui'
|
import { createToast } from '@/utils'
|
||||||
|
import { Dialog, Avatar, createResource, ErrorMessage } from 'frappe-ui'
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
|
||||||
const { getUser, users } = usersStore()
|
const { getUser, users } = usersStore()
|
||||||
|
|
||||||
const user = computed(() => getUser() || {})
|
const user = computed(() => getUser() || {})
|
||||||
|
|
||||||
const showProfileModal = ref(false)
|
const showEditProfilePhotoModal = ref(false)
|
||||||
|
|
||||||
const editingProfilePhoto = ref(false)
|
|
||||||
const profile = ref({})
|
const profile = ref({})
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
const error = ref('')
|
||||||
|
|
||||||
function updateUser() {
|
function updateUser() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@ -77,6 +99,8 @@ function updateUser() {
|
|||||||
first_name: profile.value.first_name,
|
first_name: profile.value.first_name,
|
||||||
last_name: profile.value.last_name,
|
last_name: profile.value.last_name,
|
||||||
user_image: profile.value.user_image,
|
user_image: profile.value.user_image,
|
||||||
|
email: profile.value.email,
|
||||||
|
new_password: profile.value.new_password,
|
||||||
}
|
}
|
||||||
createResource({
|
createResource({
|
||||||
url: 'frappe.client.set_value',
|
url: 'frappe.client.set_value',
|
||||||
@ -88,9 +112,20 @@ function updateUser() {
|
|||||||
auto: true,
|
auto: true,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
showProfileModal.value = false
|
error.value = ''
|
||||||
|
profile.value.new_password = ''
|
||||||
|
showEditProfilePhotoModal.value = false
|
||||||
|
createToast({
|
||||||
|
title: __('Profile updated successfully'),
|
||||||
|
icon: 'check',
|
||||||
|
iconClasses: 'text-ink-green-3',
|
||||||
|
})
|
||||||
users.reload()
|
users.reload()
|
||||||
},
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
loading.value = false
|
||||||
|
error.value = err.message
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
class="absolute right-5 top-5"
|
class="absolute right-5 top-5"
|
||||||
|
variant="ghost"
|
||||||
icon="x"
|
icon="x"
|
||||||
@click="showSettings = false"
|
@click="showSettings = false"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
v-if="note.content"
|
v-if="note.content"
|
||||||
:content="note.content"
|
:content="note.content"
|
||||||
:editable="false"
|
:editable="false"
|
||||||
editor-class="prose-sm text-sm max-w-none text-ink-gray-5 focus:outline-none"
|
editor-class="prose-sm text-p-sm max-w-none text-ink-gray-5 focus:outline-none"
|
||||||
class="flex-1 overflow-hidden"
|
class="flex-1 overflow-hidden"
|
||||||
/>
|
/>
|
||||||
<div class="mt-2 flex items-center justify-between gap-2">
|
<div class="mt-2 flex items-center justify-between gap-2">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user