refactor: organization modal
This commit is contained in:
parent
d6f8106cfb
commit
7b8a15d224
@ -115,9 +115,9 @@
|
||||
v-for="action in dialogOptions.actions"
|
||||
:key="action.label"
|
||||
v-bind="action"
|
||||
>
|
||||
{{ action.label }}
|
||||
</Button>
|
||||
:label="action.label"
|
||||
:loading="loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -130,16 +130,11 @@ import WebsiteIcon from '@/components/Icons/WebsiteIcon.vue'
|
||||
import OrganizationsIcon from '@/components/Icons/OrganizationsIcon.vue'
|
||||
import TerritoryIcon from '@/components/Icons/TerritoryIcon.vue'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import { organizationsStore } from '@/stores/organizations'
|
||||
import { call, FeatherIcon } from 'frappe-ui'
|
||||
import { ref, nextTick, watch, computed, h } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const props = defineProps({
|
||||
organization: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: {
|
||||
@ -152,8 +147,9 @@ const props = defineProps({
|
||||
|
||||
const router = useRouter()
|
||||
const show = defineModel()
|
||||
const { organizations } = organizationsStore()
|
||||
const organization = defineModel('organization')
|
||||
|
||||
const loading = ref(false)
|
||||
const title = ref(null)
|
||||
const detailMode = ref(false)
|
||||
const editMode = ref(false)
|
||||
@ -165,13 +161,15 @@ let _organization = ref({
|
||||
industry: '',
|
||||
})
|
||||
|
||||
let doc = ref({})
|
||||
|
||||
async function updateOrganization() {
|
||||
const old = { ...props.organization }
|
||||
const old = { ...doc.value }
|
||||
const newOrg = { ..._organization.value }
|
||||
|
||||
const nameChanged = old.name !== newOrg.name
|
||||
delete old.name
|
||||
delete newOrg.name
|
||||
const nameChanged = old.organization_name !== newOrg.organization_name
|
||||
delete old.organization_name
|
||||
delete newOrg.organization_name
|
||||
|
||||
const otherFieldChanged = JSON.stringify(old) !== JSON.stringify(newOrg)
|
||||
const values = newOrg
|
||||
@ -182,21 +180,23 @@ async function updateOrganization() {
|
||||
}
|
||||
|
||||
let name
|
||||
loading.value = true
|
||||
if (nameChanged) {
|
||||
name = await callRenameDoc()
|
||||
}
|
||||
if (otherFieldChanged) {
|
||||
name = await callSetValue(values)
|
||||
}
|
||||
handleOrganizationUpdate({ name })
|
||||
handleOrganizationUpdate({ name }, nameChanged)
|
||||
}
|
||||
|
||||
async function callRenameDoc() {
|
||||
const d = await call('frappe.client.rename_doc', {
|
||||
doctype: 'CRM Organization',
|
||||
old_name: props.organization.name,
|
||||
new_name: _organization.value.name,
|
||||
old_name: doc.value?.organization_name,
|
||||
new_name: _organization.value.organization_name,
|
||||
})
|
||||
loading.value = false
|
||||
return d
|
||||
}
|
||||
|
||||
@ -206,6 +206,7 @@ async function callSetValue(values) {
|
||||
name: _organization.value.name,
|
||||
fieldname: values,
|
||||
})
|
||||
loading.value = false
|
||||
return d.name
|
||||
}
|
||||
|
||||
@ -216,16 +217,18 @@ async function callInsertDoc() {
|
||||
..._organization.value,
|
||||
},
|
||||
})
|
||||
loading.value = false
|
||||
doc.name && handleOrganizationUpdate(doc)
|
||||
}
|
||||
|
||||
function handleOrganizationUpdate(doc) {
|
||||
organizations.reload()
|
||||
if (doc.name && props.options.redirect) {
|
||||
function handleOrganizationUpdate(doc, renamed = false) {
|
||||
if (doc.name && (props.options.redirect || renamed)) {
|
||||
router.push({
|
||||
name: 'Organization',
|
||||
params: { organizationId: doc.name },
|
||||
})
|
||||
} else {
|
||||
organization.value.reload?.()
|
||||
}
|
||||
show.value = false
|
||||
props.options.afterInsert && props.options.afterInsert(doc)
|
||||
@ -296,7 +299,8 @@ watch(
|
||||
nextTick(() => {
|
||||
// TODO: Issue with FormControl
|
||||
// title.value.el.focus()
|
||||
_organization.value = { ...props.organization }
|
||||
doc.value = organization.value?.doc || organization.value || {}
|
||||
_organization.value = { ...doc.value }
|
||||
if (_organization.value.name) {
|
||||
editMode.value = true
|
||||
}
|
||||
|
||||
@ -61,10 +61,10 @@
|
||||
</div>
|
||||
<OrganizationModal
|
||||
v-model="showOrganizationModal"
|
||||
:organization="_organization"
|
||||
v-model:organization="_organization"
|
||||
:options="{
|
||||
redirect: false,
|
||||
afterInsert: (doc) => (newLead.organization = doc.name),
|
||||
afterInsert: (doc) => (newDeal.organization = doc.name),
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@ -59,20 +59,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<OrganizationModal
|
||||
v-model="showOrganizationModal"
|
||||
:organization="_organization"
|
||||
:options="{
|
||||
redirect: false,
|
||||
afterInsert: (doc) => (newLead.organization = doc.name),
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
@ -89,9 +80,6 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const showOrganizationModal = ref(false)
|
||||
const _organization = ref({})
|
||||
|
||||
const allFields = computed(() => {
|
||||
return [
|
||||
{
|
||||
|
||||
@ -260,7 +260,7 @@
|
||||
</div>
|
||||
<OrganizationModal
|
||||
v-model="showOrganizationModal"
|
||||
:organization="_organization"
|
||||
v-model:organization="_organization"
|
||||
:options="{
|
||||
redirect: false,
|
||||
afterInsert: (doc) =>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<LayoutHeader v-if="organization">
|
||||
<LayoutHeader v-if="organization.doc">
|
||||
<template #left-header>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
</template>
|
||||
</LayoutHeader>
|
||||
<div v-if="organization" class="flex flex-1 flex-col overflow-hidden">
|
||||
<div v-if="organization.doc" class="flex flex-1 flex-col overflow-hidden">
|
||||
<FileUploader
|
||||
@success="changeOrganizationImage"
|
||||
:validateFile="validateFile"
|
||||
@ -14,19 +14,19 @@
|
||||
<div class="group relative h-24 w-24">
|
||||
<Avatar
|
||||
size="3xl"
|
||||
:image="organization.organization_logo"
|
||||
:label="organization.name"
|
||||
:image="organization.doc.organization_logo"
|
||||
:label="organization.doc.name"
|
||||
class="!h-24 !w-24"
|
||||
/>
|
||||
<component
|
||||
:is="organization.organization_logo ? Dropdown : 'div'"
|
||||
:is="organization.doc.organization_logo ? Dropdown : 'div'"
|
||||
v-bind="
|
||||
organization.organization_logo
|
||||
organization.doc.organization_logo
|
||||
? {
|
||||
options: [
|
||||
{
|
||||
icon: 'upload',
|
||||
label: organization.organization_logo
|
||||
label: organization.doc.organization_logo
|
||||
? 'Change image'
|
||||
: 'Upload image',
|
||||
onClick: openFileSelector,
|
||||
@ -55,67 +55,67 @@
|
||||
</div>
|
||||
<div class="flex flex-col justify-center gap-0.5">
|
||||
<div class="text-3xl font-semibold text-gray-900">
|
||||
{{ organization.name }}
|
||||
{{ organization.doc.name }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-base text-gray-700">
|
||||
<div
|
||||
v-if="organization.website"
|
||||
v-if="organization.doc.website"
|
||||
class="flex items-center gap-1.5"
|
||||
>
|
||||
<WebsiteIcon class="h-4 w-4" />
|
||||
<span class="">{{ website(organization.website) }}</span>
|
||||
<span class="">{{ website(organization.doc.website) }}</span>
|
||||
</div>
|
||||
<span
|
||||
v-if="organization.website"
|
||||
v-if="organization.doc.website"
|
||||
class="text-3xl leading-[0] text-gray-600"
|
||||
>
|
||||
·
|
||||
</span>
|
||||
<div
|
||||
v-if="organization.industry"
|
||||
v-if="organization.doc.industry"
|
||||
class="flex items-center gap-1.5"
|
||||
>
|
||||
<FeatherIcon name="briefcase" class="h-4 w-4" />
|
||||
<span class="">{{ organization.industry }}</span>
|
||||
<span class="">{{ organization.doc.industry }}</span>
|
||||
</div>
|
||||
<span
|
||||
v-if="organization.industry"
|
||||
v-if="organization.doc.industry"
|
||||
class="text-3xl leading-[0] text-gray-600"
|
||||
>
|
||||
·
|
||||
</span>
|
||||
<div
|
||||
v-if="organization.territory"
|
||||
v-if="organization.doc.territory"
|
||||
class="flex items-center gap-1.5"
|
||||
>
|
||||
<TerritoryIcon class="h-4 w-4" />
|
||||
<span class="">{{ organization.territory }}</span>
|
||||
<span class="">{{ organization.doc.territory }}</span>
|
||||
</div>
|
||||
<span
|
||||
v-if="organization.territory"
|
||||
v-if="organization.doc.territory"
|
||||
class="text-3xl leading-[0] text-gray-600"
|
||||
>
|
||||
·
|
||||
</span>
|
||||
<div
|
||||
v-if="organization.annual_revenue"
|
||||
v-if="organization.doc.annual_revenue"
|
||||
class="flex items-center gap-1.5"
|
||||
>
|
||||
<FeatherIcon name="dollar-sign" class="h-4 w-4" />
|
||||
<span class="">{{ organization.annual_revenue }}</span>
|
||||
<span class="">{{ organization.doc.annual_revenue }}</span>
|
||||
</div>
|
||||
<span
|
||||
v-if="organization.annual_revenue"
|
||||
v-if="organization.doc.annual_revenue"
|
||||
class="text-3xl leading-[0] text-gray-600"
|
||||
>
|
||||
·
|
||||
</span>
|
||||
<Button
|
||||
v-if="
|
||||
organization.website ||
|
||||
organization.industry ||
|
||||
organization.territory ||
|
||||
organization.annual_revenue
|
||||
organization.doc.website ||
|
||||
organization.doc.industry ||
|
||||
organization.doc.territory ||
|
||||
organization.doc.annual_revenue
|
||||
"
|
||||
variant="ghost"
|
||||
label="More"
|
||||
@ -191,7 +191,7 @@
|
||||
v-if="tab.label === 'Contacts' && rows.length"
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
:options="{ selectable: false, showTooltip: false, }"
|
||||
:options="{ selectable: false, showTooltip: false }"
|
||||
/>
|
||||
<div
|
||||
v-if="!rows.length"
|
||||
@ -207,7 +207,7 @@
|
||||
</div>
|
||||
<OrganizationModal
|
||||
v-model="showOrganizationModal"
|
||||
:organization="organization"
|
||||
v-model:organization="organization"
|
||||
:options="{ detailMode }"
|
||||
/>
|
||||
</template>
|
||||
@ -221,6 +221,7 @@ import {
|
||||
Tabs,
|
||||
call,
|
||||
createListResource,
|
||||
createDocumentResource,
|
||||
} from 'frappe-ui'
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
||||
@ -234,7 +235,6 @@ import DealsIcon from '@/components/Icons/DealsIcon.vue'
|
||||
import ContactsIcon from '@/components/Icons/ContactsIcon.vue'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { organizationsStore } from '@/stores/organizations.js'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import {
|
||||
dateFormat,
|
||||
@ -253,14 +253,19 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const { $dialog } = globalStore()
|
||||
const { organizations, getOrganization } = organizationsStore()
|
||||
const { getDealStatus } = statusesStore()
|
||||
const showOrganizationModal = ref(false)
|
||||
const detailMode = ref(false)
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const organization = computed(() => getOrganization(props.organizationId))
|
||||
const organization = createDocumentResource({
|
||||
doctype: 'CRM Organization',
|
||||
name: props.organizationId,
|
||||
cache: ['organization', props.organizationId],
|
||||
fields: ['*'],
|
||||
auto: true,
|
||||
})
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
let items = [{ label: 'Organizations', route: { name: 'Organizations' } }]
|
||||
@ -288,7 +293,7 @@ async function changeOrganizationImage(file) {
|
||||
fieldname: 'organization_logo',
|
||||
value: file?.file_url || '',
|
||||
})
|
||||
organizations.reload()
|
||||
organization.reload()
|
||||
}
|
||||
|
||||
async function deleteOrganization() {
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<OrganizationModal v-model="showOrganizationModal" :organization="{}" />
|
||||
<OrganizationModal v-model="showOrganizationModal" />
|
||||
</template>
|
||||
<script setup>
|
||||
import OrganizationsIcon from '@/components/Icons/OrganizationsIcon.vue'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user