783 lines
24 KiB
Vue
783 lines
24 KiB
Vue
<template>
|
|
<div
|
|
v-if="!getAssignmentRuleData.loading"
|
|
class="flex flex-col h-full gap-6 px-6 py-8 text-ink-gray-8"
|
|
>
|
|
<div class="flex items-center justify-between px-2 w-full">
|
|
<div class="flex items-center gap-2">
|
|
<Button
|
|
variant="ghost"
|
|
icon-left="chevron-left"
|
|
:label="
|
|
assignmentRuleData.assignmentRuleName || __('New Assignment Rule')
|
|
"
|
|
size="md"
|
|
@click="goBack()"
|
|
class="cursor-pointer -ml-4 hover:bg-transparent focus:bg-transparent focus:outline-none focus:ring-0 focus:ring-offset-0 focus-visible:none active:bg-transparent active:outline-none active:ring-0 active:ring-offset-0 active:text-ink-gray-5 font-semibold text-xl hover:opacity-70 !pr-0 !max-w-96 !justify-start"
|
|
/>
|
|
<Badge
|
|
:variant="'subtle'"
|
|
:theme="'orange'"
|
|
size="sm"
|
|
:label="__('Unsaved')"
|
|
v-if="isDirty"
|
|
/>
|
|
</div>
|
|
<div class="flex items-center gap-4">
|
|
<div
|
|
class="flex items-center justify-between gap-2"
|
|
@click="assignmentRuleData.disabled = !assignmentRuleData.disabled"
|
|
>
|
|
<Switch size="sm" :model-value="!assignmentRuleData.disabled" />
|
|
<span class="text-sm text-ink-gray-7">{{ __('Enabled') }}</span>
|
|
</div>
|
|
<Button
|
|
:disabled="Boolean(!isDirty && step.data)"
|
|
:label="__('Save')"
|
|
theme="gray"
|
|
variant="solid"
|
|
@click="saveAssignmentRule()"
|
|
:loading="isLoading || getAssignmentRuleData.loading"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="overflow-y-auto px-2">
|
|
<div class="grid grid-cols-2 gap-5">
|
|
<div>
|
|
<FormControl
|
|
:type="'text'"
|
|
size="sm"
|
|
variant="subtle"
|
|
:placeholder="__('Name')"
|
|
:label="__('Name')"
|
|
v-model="assignmentRuleData.assignmentRuleName"
|
|
required
|
|
maxlength="50"
|
|
@change="validateAssignmentRule('assignmentRuleName')"
|
|
/>
|
|
<ErrorMessage
|
|
:message="assignmentRuleErrors.assignmentRuleName"
|
|
class="mt-2"
|
|
/>
|
|
</div>
|
|
<div class="flex flex-col gap-1.5">
|
|
<FormLabel :label="__('Priority')" />
|
|
<Popover>
|
|
<template #target="{ togglePopover }">
|
|
<div
|
|
class="flex items-center justify-between text-base rounded h-7 py-1.5 pl-2 pr-2 border border-outline-gray-2 bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-gray-modals hover:bg-surface-gray-3 focus:bg-surface-white focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors w-full dark:[color-scheme:dark] cursor-default"
|
|
@click="togglePopover()"
|
|
>
|
|
<div>
|
|
{{
|
|
priorityOptions.find(
|
|
(option) => option.value == assignmentRuleData.priority,
|
|
)?.label
|
|
}}
|
|
</div>
|
|
<FeatherIcon name="chevron-down" class="size-4" />
|
|
</div>
|
|
</template>
|
|
<template #body="{ togglePopover }">
|
|
<div
|
|
class="p-1 text-ink-gray-6 top-1 absolute w-full bg-white shadow-2xl rounded"
|
|
>
|
|
<div
|
|
v-for="option in priorityOptions"
|
|
:key="option.value"
|
|
class="p-2 cursor-pointer hover:bg-gray-50 text-base flex items-center justify-between rounded"
|
|
@click="
|
|
() => {
|
|
assignmentRuleData.priority = option.value
|
|
togglePopover()
|
|
}
|
|
"
|
|
>
|
|
{{ option.label }}
|
|
<FeatherIcon
|
|
v-if="assignmentRuleData.priority == option.value"
|
|
name="check"
|
|
class="size-4"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</Popover>
|
|
</div>
|
|
<div>
|
|
<FormControl
|
|
:type="'textarea'"
|
|
size="sm"
|
|
variant="subtle"
|
|
:placeholder="__('Description')"
|
|
:label="__('Description')"
|
|
required
|
|
maxlength="250"
|
|
@change="validateAssignmentRule('description')"
|
|
v-model="assignmentRuleData.description"
|
|
/>
|
|
<ErrorMessage
|
|
:message="assignmentRuleErrors.description"
|
|
class="mt-2"
|
|
/>
|
|
</div>
|
|
<div class="flex flex-col gap-1.5">
|
|
<FormLabel :label="__('Apply on')" />
|
|
<Select
|
|
:options="[
|
|
{
|
|
label: 'Lead',
|
|
value: 'CRM Lead',
|
|
},
|
|
{
|
|
label: 'Deal',
|
|
value: 'CRM Deal',
|
|
},
|
|
]"
|
|
v-model="assignmentRuleData.documentType"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<hr class="my-8" />
|
|
<div>
|
|
<div class="flex flex-col gap-1">
|
|
<span class="text-lg font-semibold text-ink-gray-8">{{
|
|
__('Assignment condition')
|
|
}}</span>
|
|
<div class="flex items-center justify-between gap-6">
|
|
<span class="text-p-sm text-ink-gray-6">
|
|
{{
|
|
__('Choose which {0} are affected by this assignment rule.', [
|
|
documentType,
|
|
])
|
|
}}
|
|
<a
|
|
class="font-medium underline"
|
|
href="https://docs.frappe.io/crm/assignment-rule"
|
|
target="_blank"
|
|
>{{ __('Learn about conditions') }}</a
|
|
>
|
|
</span>
|
|
<div v-if="isOldSla && step.data">
|
|
<Popover trigger="hover" :hoverDelay="0.25" placement="top-end">
|
|
<template #target>
|
|
<div
|
|
class="text-sm text-ink-gray-6 flex gap-1 cursor-default text-nowrap items-center"
|
|
>
|
|
<span>{{ __('Old Condition') }}</span>
|
|
<FeatherIcon name="info" class="size-4" />
|
|
</div>
|
|
</template>
|
|
<template #body-main>
|
|
<div
|
|
class="text-sm text-ink-gray-6 p-2 bg-white rounded-md max-w-96 text-wrap whitespace-pre-wrap leading-5"
|
|
>
|
|
<code>{{ assignmentRuleData.assignCondition }}</code>
|
|
</div>
|
|
</template>
|
|
</Popover>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-5">
|
|
<div
|
|
class="flex flex-col gap-3 items-center text-center text-ink-gray-7 text-sm mb-2 border border-outline-gray-2 rounded-md p-3 py-4"
|
|
v-if="!useNewUI && assignmentRuleData.assignCondition"
|
|
>
|
|
<span class="text-p-sm">
|
|
{{ __('Conditions for this rule were created from') }}
|
|
<a :href="deskUrl" target="_blank" class="underline">{{
|
|
__('desk')
|
|
}}</a>
|
|
{{
|
|
__(
|
|
'which are not compatible with this UI, you will need to recreate the conditions here if you want to manage and add new conditions from this UI.',
|
|
)
|
|
}}
|
|
</span>
|
|
<Button
|
|
:label="__('I understand, add conditions')"
|
|
variant="subtle"
|
|
theme="gray"
|
|
@click="useNewUI = true"
|
|
/>
|
|
</div>
|
|
<AssignmentRulesSection
|
|
:conditions="assignmentRuleData.assignConditionJson"
|
|
name="assignCondition"
|
|
:errors="assignmentRuleErrors.assignConditionError"
|
|
:doctype="assignmentRuleData.documentType"
|
|
v-else
|
|
/>
|
|
<div class="flex justify-end">
|
|
<ErrorMessage
|
|
:message="assignmentRuleErrors.assignCondition"
|
|
class="mt-2"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr class="my-8" />
|
|
<div>
|
|
<div class="flex flex-col gap-1">
|
|
<span class="text-lg font-semibold text-ink-gray-8">{{
|
|
__('Unassignment condition')
|
|
}}</span>
|
|
<div class="flex items-center justify-between gap-6">
|
|
<span class="text-p-sm text-ink-gray-6">
|
|
{{
|
|
__(
|
|
'Choose which {0} are affected by this un-assignment rule.',
|
|
[documentType],
|
|
)
|
|
}}
|
|
<a
|
|
class="font-medium underline"
|
|
href="https://docs.frappe.io/crm/assignment-rule"
|
|
target="_blank"
|
|
>{{ __('Learn about conditions') }}</a
|
|
>
|
|
</span>
|
|
<div
|
|
v-if="
|
|
isOldSla && step.data && assignmentRuleData.unassignCondition
|
|
"
|
|
>
|
|
<Popover trigger="hover" :hoverDelay="0.25" placement="top-end">
|
|
<template #target>
|
|
<div
|
|
class="text-sm text-ink-gray-6 flex gap-1 cursor-default text-nowrap items-center"
|
|
>
|
|
<span> {{ __('Old Condition') }} </span>
|
|
<FeatherIcon name="info" class="size-4" />
|
|
</div>
|
|
</template>
|
|
<template #body-main>
|
|
<div
|
|
class="text-sm text-ink-gray-6 p-2 bg-white rounded-md max-w-96 text-wrap whitespace-pre-wrap leading-5"
|
|
>
|
|
<code>{{ assignmentRuleData.unassignCondition }}</code>
|
|
</div>
|
|
</template>
|
|
</Popover>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-5">
|
|
<div
|
|
v-if="!useNewUI && assignmentRuleData.unassignCondition"
|
|
class="flex flex-col gap-3 items-center text-center text-ink-gray-7 text-sm mb-2 border border-outline-gray-2 rounded-md p-3 py-4"
|
|
>
|
|
<span class="text-p-sm">
|
|
{{ __('Conditions for this rule were created from') }}
|
|
<a :href="deskUrl" target="_blank" class="underline">
|
|
{{ __('desk') }}
|
|
</a>
|
|
{{
|
|
__(
|
|
'which are not compatible with this UI, you will need to recreate the conditions here if you want to manage and add new conditions from this UI.',
|
|
)
|
|
}}
|
|
</span>
|
|
<Button
|
|
:label="__('I understand, add conditions')"
|
|
variant="subtle"
|
|
theme="gray"
|
|
@click="useNewUI = true"
|
|
/>
|
|
</div>
|
|
<AssignmentRulesSection
|
|
v-else
|
|
:conditions="assignmentRuleData.unassignConditionJson"
|
|
name="unassignCondition"
|
|
:errors="assignmentRuleErrors.unassignConditionError"
|
|
:doctype="assignmentRuleData.documentType"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<hr class="my-8" />
|
|
<div>
|
|
<div class="flex flex-col gap-1">
|
|
<span class="text-lg font-semibold text-ink-gray-8">{{
|
|
__('Assignment Schedule')
|
|
}}</span>
|
|
<span class="text-p-sm text-ink-gray-6">
|
|
{{
|
|
__('Choose the days of the week when this rule should be active.')
|
|
}}
|
|
</span>
|
|
</div>
|
|
<div class="mt-6">
|
|
<AssignmentSchedule />
|
|
</div>
|
|
</div>
|
|
<hr class="my-8" />
|
|
<AssigneeRules />
|
|
</div>
|
|
</div>
|
|
<div v-else class="flex items-center h-full justify-center">
|
|
<LoadingIndicator class="w-4" />
|
|
</div>
|
|
<ConfirmDialog
|
|
v-model="showConfirmDialog.show"
|
|
:title="showConfirmDialog.title"
|
|
:message="showConfirmDialog.message"
|
|
:onConfirm="showConfirmDialog.onConfirm"
|
|
:onCancel="() => (showConfirmDialog.show = false)"
|
|
/>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {
|
|
Badge,
|
|
Button,
|
|
call,
|
|
createResource,
|
|
ErrorMessage,
|
|
FormControl,
|
|
FormLabel,
|
|
LoadingIndicator,
|
|
Popover,
|
|
Select,
|
|
Switch,
|
|
toast,
|
|
} from 'frappe-ui'
|
|
import {
|
|
onMounted,
|
|
onUnmounted,
|
|
ref,
|
|
inject,
|
|
watch,
|
|
provide,
|
|
computed,
|
|
} from 'vue'
|
|
import AssignmentRulesSection from './AssignmentRulesSection.vue'
|
|
import AssignmentSchedule from './AssignmentSchedule.vue'
|
|
import AssigneeRules from './AssigneeRules.vue'
|
|
import ConfirmDialog from 'frappe-ui/src/components/ConfirmDialog.vue'
|
|
import { globalStore } from '@/stores/global'
|
|
import { disableSettingModalOutsideClick } from '@/composables/settings'
|
|
import { convertToConditions, validateConditions } from '@/utils'
|
|
|
|
const isDirty = ref(false)
|
|
const initialData = ref(null)
|
|
const isLoading = ref(false)
|
|
const updateStep = inject('updateStep')
|
|
const step = inject('step')
|
|
const { $dialog } = globalStore()
|
|
|
|
const showConfirmDialog = ref({
|
|
show: false,
|
|
title: '',
|
|
message: '',
|
|
onConfirm: () => {},
|
|
})
|
|
const useNewUI = ref(true)
|
|
const isOldSla = ref(false)
|
|
const documentType = computed(() =>
|
|
assignmentRuleData.value.documentType == 'CRM Lead'
|
|
? __('leads')
|
|
: __('deals'),
|
|
)
|
|
const deskUrl = `${window.location.origin}/app/assignment-rule/${step.value.data?.name}`
|
|
|
|
const defaultAssignmentDays = [
|
|
'Monday',
|
|
'Tuesday',
|
|
'Wednesday',
|
|
'Thursday',
|
|
'Friday',
|
|
'Saturday',
|
|
'Sunday',
|
|
]
|
|
|
|
const assignmentRuleData = ref({
|
|
assignCondition: '',
|
|
unassignCondition: '',
|
|
assignConditionJson: [],
|
|
unassignConditionJson: [],
|
|
rule: 'Round Robin',
|
|
priority: 1,
|
|
users: [],
|
|
disabled: false,
|
|
description: '',
|
|
name: '',
|
|
assignmentRuleName: '',
|
|
assignmentDays: defaultAssignmentDays,
|
|
documentType: 'CRM Lead',
|
|
})
|
|
|
|
const validateAssignmentRule = (key, skipConditionCheck = false) => {
|
|
const validateField = (field) => {
|
|
if (key && field !== key) return
|
|
|
|
switch (field) {
|
|
case 'assignmentRuleName':
|
|
if (assignmentRuleData.value.assignmentRuleName?.length == 0) {
|
|
assignmentRuleErrors.value.assignmentRuleName = __('Name is required')
|
|
} else {
|
|
assignmentRuleErrors.value.assignmentRuleName = ''
|
|
}
|
|
break
|
|
case 'description':
|
|
assignmentRuleErrors.value.description =
|
|
assignmentRuleData.value.description?.length > 0
|
|
? ''
|
|
: __('Description is required')
|
|
break
|
|
case 'assignCondition':
|
|
if (skipConditionCheck) {
|
|
break
|
|
}
|
|
assignmentRuleErrors.value.assignCondition =
|
|
assignmentRuleData.value.assignConditionJson?.length > 0
|
|
? ''
|
|
: __('Assign condition is required')
|
|
|
|
if (!validateConditions(assignmentRuleData.value.assignConditionJson)) {
|
|
assignmentRuleErrors.value.assignConditionError = __(
|
|
'Assign conditions are invalid',
|
|
)
|
|
} else {
|
|
assignmentRuleErrors.value.assignConditionError = ''
|
|
}
|
|
|
|
break
|
|
case 'unassignCondition':
|
|
if (skipConditionCheck) {
|
|
break
|
|
}
|
|
if (
|
|
assignmentRuleData.value.unassignConditionJson?.length > 0 &&
|
|
!validateConditions(assignmentRuleData.value.unassignConditionJson)
|
|
) {
|
|
assignmentRuleErrors.value.unassignConditionError = __(
|
|
'Unassign conditions are invalid',
|
|
)
|
|
} else {
|
|
assignmentRuleErrors.value.unassignConditionError = ''
|
|
}
|
|
break
|
|
case 'users':
|
|
assignmentRuleErrors.value.users =
|
|
assignmentRuleData.value.users?.length > 0
|
|
? ''
|
|
: __('Users are required')
|
|
break
|
|
case 'assignmentDays':
|
|
assignmentRuleErrors.value.assignmentDays =
|
|
assignmentRuleData.value.assignmentDays?.length > 0
|
|
? ''
|
|
: __('Assignment days are required')
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
if (key) {
|
|
validateField(key)
|
|
} else {
|
|
Object.keys(assignmentRuleErrors.value).forEach(validateField)
|
|
}
|
|
|
|
return assignmentRuleErrors.value
|
|
}
|
|
|
|
const resetAssignmentRuleData = () => {
|
|
assignmentRuleData.value = {
|
|
assignCondition: '',
|
|
unassignCondition: '',
|
|
assignConditionJson: [],
|
|
unassignConditionJson: [],
|
|
rule: 'Round Robin',
|
|
priority: 1,
|
|
users: [],
|
|
disabled: false,
|
|
description: '',
|
|
name: '',
|
|
assignmentRuleName: '',
|
|
assignmentDays: defaultAssignmentDays,
|
|
documentType: 'CRM Lead',
|
|
}
|
|
}
|
|
|
|
const assignmentRuleErrors = ref({
|
|
assignmentRuleName: '',
|
|
assignCondition: '',
|
|
assignConditionError: '',
|
|
unassignConditionError: '',
|
|
users: '',
|
|
description: '',
|
|
assignmentDays: '',
|
|
})
|
|
|
|
const resetAssignmentRuleErrors = () => {
|
|
Object.keys(assignmentRuleErrors.value).forEach((key) => {
|
|
assignmentRuleErrors.value[key] = ''
|
|
})
|
|
}
|
|
|
|
provide('assignmentRuleData', assignmentRuleData)
|
|
provide('assignmentRuleErrors', assignmentRuleErrors)
|
|
provide('validateAssignmentRule', validateAssignmentRule)
|
|
provide('resetAssignmentRuleData', resetAssignmentRuleData)
|
|
provide('resetAssignmentRuleErrors', resetAssignmentRuleErrors)
|
|
|
|
const getAssignmentRuleData = createResource({
|
|
url: 'frappe.client.get',
|
|
params: {
|
|
doctype: 'Assignment Rule',
|
|
name: step.value.data?.name,
|
|
},
|
|
auto: Boolean(step.value.data),
|
|
onSuccess(data) {
|
|
assignmentRuleData.value = {
|
|
assignCondition: data.assign_condition,
|
|
unassignCondition: data.unassign_condition,
|
|
assignConditionJson: JSON.parse(data.assign_condition_json || '[]'),
|
|
unassignConditionJson: JSON.parse(data.unassign_condition_json || '[]'),
|
|
rule: data.rule,
|
|
priority: data.priority,
|
|
users: data.users,
|
|
disabled: data.disabled,
|
|
description: data.description,
|
|
name: data.name,
|
|
assignmentRuleName: data.name,
|
|
assignmentDays: data.assignment_days.map((day) => day.day),
|
|
documentType: data.document_type,
|
|
}
|
|
|
|
initialData.value = JSON.stringify(assignmentRuleData.value)
|
|
|
|
const conditionsAvailable =
|
|
assignmentRuleData.value.assignCondition?.length > 0
|
|
const conditionsJsonAvailable =
|
|
assignmentRuleData.value.assignConditionJson?.length > 0
|
|
|
|
if (conditionsAvailable && !conditionsJsonAvailable) {
|
|
useNewUI.value = false
|
|
isOldSla.value = true
|
|
} else {
|
|
useNewUI.value = true
|
|
isOldSla.value = false
|
|
}
|
|
},
|
|
})
|
|
|
|
if (!step.value.data) {
|
|
initialData.value = JSON.stringify(assignmentRuleData.value)
|
|
}
|
|
|
|
const goBack = () => {
|
|
if (isDirty.value && !showConfirmDialog.value.show) {
|
|
$dialog({
|
|
title: __('Unsaved changes'),
|
|
message: __(
|
|
'Are you sure you want to go back? Unsaved changes will be lost.',
|
|
),
|
|
variant: 'solid',
|
|
actions: [
|
|
{
|
|
label: __('Go back'),
|
|
variant: 'solid',
|
|
onClick: (close) => {
|
|
updateStep('list', null)
|
|
close()
|
|
},
|
|
},
|
|
],
|
|
})
|
|
return
|
|
}
|
|
updateStep('list', null)
|
|
showConfirmDialog.value.show = false
|
|
}
|
|
|
|
const saveAssignmentRule = () => {
|
|
const validationErrors = validateAssignmentRule(undefined, !useNewUI.value)
|
|
if (Object.values(validationErrors).some((error) => error)) {
|
|
toast.error(
|
|
__('Invalid fields, check if all are filled in and values are correct.'),
|
|
)
|
|
return
|
|
}
|
|
if (step.value.data) {
|
|
if (isOldSla.value && useNewUI.value) {
|
|
showConfirmDialog.value = {
|
|
show: true,
|
|
title: __('Confirm overwrite'),
|
|
message: __(
|
|
'Your old condition will be overwritten. Are you sure you want to save?',
|
|
),
|
|
onConfirm: () => {
|
|
updateAssignmentRule()
|
|
showConfirmDialog.value.show = false
|
|
},
|
|
}
|
|
return
|
|
}
|
|
updateAssignmentRule()
|
|
} else {
|
|
createAssignmentRule()
|
|
}
|
|
}
|
|
|
|
const createAssignmentRule = () => {
|
|
isLoading.value = true
|
|
createResource({
|
|
url: 'frappe.client.insert',
|
|
params: {
|
|
doc: {
|
|
doctype: 'Assignment Rule',
|
|
document_type: assignmentRuleData.value.documentType,
|
|
rule: assignmentRuleData.value.rule,
|
|
priority: assignmentRuleData.value.priority,
|
|
users: assignmentRuleData.value.users,
|
|
disabled: assignmentRuleData.value.disabled,
|
|
description: assignmentRuleData.value.description,
|
|
assignment_days: assignmentRuleData.value.assignmentDays.map((day) => ({
|
|
day: day,
|
|
})),
|
|
name: assignmentRuleData.value.assignmentRuleName,
|
|
assignment_rule_name: assignmentRuleData.value.assignmentRuleName,
|
|
assign_condition: convertToConditions({
|
|
conditions: assignmentRuleData.value.assignConditionJson,
|
|
}),
|
|
unassign_condition: convertToConditions({
|
|
conditions: assignmentRuleData.value.unassignConditionJson,
|
|
}),
|
|
assign_condition_json: JSON.stringify(
|
|
assignmentRuleData.value.assignConditionJson,
|
|
),
|
|
unassign_condition_json: JSON.stringify(
|
|
assignmentRuleData.value.unassignConditionJson,
|
|
),
|
|
},
|
|
},
|
|
auto: true,
|
|
onSuccess(data) {
|
|
getAssignmentRuleData
|
|
.submit({
|
|
doctype: 'Assignment Rule',
|
|
name: data.name,
|
|
})
|
|
.then(() => {
|
|
isLoading.value = false
|
|
toast.success(__('Assignment rule created'))
|
|
})
|
|
updateStep('view', data)
|
|
},
|
|
onError: () => {
|
|
isLoading.value = false
|
|
},
|
|
})
|
|
}
|
|
|
|
const priorityOptions = [
|
|
{ label: 'Low', value: '0' },
|
|
{ label: 'Low-Medium', value: '1' },
|
|
{ label: 'Medium', value: '2' },
|
|
{ label: 'Medium-High', value: '3' },
|
|
{ label: 'High', value: '4' },
|
|
]
|
|
|
|
const updateAssignmentRule = async () => {
|
|
isLoading.value = true
|
|
await call('frappe.client.set_value', {
|
|
doctype: 'Assignment Rule',
|
|
name: assignmentRuleData.value.name,
|
|
fieldname: {
|
|
rule: assignmentRuleData.value.rule,
|
|
priority: assignmentRuleData.value.priority,
|
|
users: assignmentRuleData.value.users,
|
|
disabled: assignmentRuleData.value.disabled,
|
|
description: assignmentRuleData.value.description,
|
|
document_type: assignmentRuleData.value.documentType,
|
|
assignment_days: assignmentRuleData.value.assignmentDays.map((day) => ({
|
|
day: day,
|
|
})),
|
|
assign_condition: useNewUI.value
|
|
? convertToConditions({
|
|
conditions: assignmentRuleData.value.assignConditionJson,
|
|
})
|
|
: assignmentRuleData.value.assignCondition,
|
|
unassign_condition: useNewUI.value
|
|
? convertToConditions({
|
|
conditions: assignmentRuleData.value.unassignConditionJson,
|
|
})
|
|
: assignmentRuleData.value.unassignCondition,
|
|
assign_condition_json: useNewUI.value
|
|
? JSON.stringify(assignmentRuleData.value.assignConditionJson)
|
|
: null,
|
|
unassign_condition_json: useNewUI.value
|
|
? JSON.stringify(assignmentRuleData.value.unassignConditionJson)
|
|
: null,
|
|
},
|
|
}).catch((er) => {
|
|
const error =
|
|
er?.messages?.[0] ||
|
|
__('Some error occurred while updating assignment rule')
|
|
toast.error(error)
|
|
isLoading.value = false
|
|
})
|
|
if (
|
|
assignmentRuleData.value.name !==
|
|
assignmentRuleData.value.assignmentRuleName
|
|
) {
|
|
await call('frappe.client.rename_doc', {
|
|
doctype: 'Assignment Rule',
|
|
old_name: assignmentRuleData.value.name,
|
|
new_name: assignmentRuleData.value.assignmentRuleName,
|
|
}).catch(async (er) => {
|
|
const error =
|
|
er?.messages?.[0] ||
|
|
__('Some error occurred while renaming assignment rule')
|
|
toast.error(error)
|
|
// Reset assignment rule to previous state
|
|
await getAssignmentRuleData.reload()
|
|
isLoading.value = false
|
|
})
|
|
await getAssignmentRuleData.submit({
|
|
doctype: 'Assignment Rule',
|
|
name: assignmentRuleData.value.assignmentRuleName,
|
|
})
|
|
} else {
|
|
getAssignmentRuleData.reload()
|
|
}
|
|
isLoading.value = false
|
|
toast.success(__('Assignment rule updated'))
|
|
}
|
|
|
|
watch(
|
|
assignmentRuleData,
|
|
(newVal) => {
|
|
if (!initialData.value) return
|
|
isDirty.value = JSON.stringify(newVal) != initialData.value
|
|
if (isDirty.value) {
|
|
disableSettingModalOutsideClick.value = true
|
|
} else {
|
|
disableSettingModalOutsideClick.value = false
|
|
}
|
|
},
|
|
{ deep: true },
|
|
)
|
|
|
|
const beforeUnloadHandler = (event) => {
|
|
if (!isDirty.value) return
|
|
event.preventDefault()
|
|
event.returnValue = true
|
|
}
|
|
|
|
onMounted(() => {
|
|
addEventListener('beforeunload', beforeUnloadHandler)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
resetAssignmentRuleErrors()
|
|
resetAssignmentRuleData()
|
|
removeEventListener('beforeunload', beforeUnloadHandler)
|
|
disableSettingModalOutsideClick.value = false
|
|
})
|
|
</script>
|