refactor: organization modal

This commit is contained in:
Shariq Ansari 2024-03-18 15:02:23 +05:30
parent d6f8106cfb
commit 7b8a15d224
6 changed files with 63 additions and 66 deletions

View File

@ -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
}

View File

@ -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>

View File

@ -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 [
{

View File

@ -260,7 +260,7 @@
</div>
<OrganizationModal
v-model="showOrganizationModal"
:organization="_organization"
v-model:organization="_organization"
:options="{
redirect: false,
afterInsert: (doc) =>

View File

@ -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"
>
&middot;
</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"
>
&middot;
</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"
>
&middot;
</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"
>
&middot;
</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() {

View File

@ -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'