diff --git a/crm/api/doc.py b/crm/api/doc.py
index b7b02511..b79de0c9 100644
--- a/crm/api/doc.py
+++ b/crm/api/doc.py
@@ -376,7 +376,7 @@ def get_type(field):
return "read_only"
return field.fieldtype.lower()
-def get_assigned_users(doctype, name):
+def get_assigned_users(doctype, name, default_assigned_to=None):
assigned_users = frappe.get_all(
"ToDo",
fields=["allocated_to"],
@@ -388,7 +388,12 @@ def get_assigned_users(doctype, name):
pluck="allocated_to",
)
- return list(set(assigned_users))
+ users = list(set(assigned_users))
+
+ # if users is empty, add default_assigned_to
+ if not users and default_assigned_to:
+ users = [default_assigned_to]
+ return users
@frappe.whitelist()
diff --git a/crm/fcrm/doctype/crm_deal/api.py b/crm/fcrm/doctype/crm_deal/api.py
index c05937bb..cb757b59 100644
--- a/crm/fcrm/doctype/crm_deal/api.py
+++ b/crm/fcrm/doctype/crm_deal/api.py
@@ -30,7 +30,7 @@ def get_deal(name):
deal["doctype_fields"], deal["all_fields"] = get_doctype_fields("CRM Deal", name)
deal["doctype"] = "CRM Deal"
deal["_form_script"] = get_form_script('CRM Deal')
- deal["_assign"] = get_assigned_users("CRM Deal", deal.name)
+ deal["_assign"] = get_assigned_users("CRM Deal", deal.name, deal.owner)
return deal
@frappe.whitelist()
diff --git a/crm/fcrm/doctype/crm_lead/api.py b/crm/fcrm/doctype/crm_lead/api.py
index 74b6b7d1..b4dca9f7 100644
--- a/crm/fcrm/doctype/crm_lead/api.py
+++ b/crm/fcrm/doctype/crm_lead/api.py
@@ -18,5 +18,5 @@ def get_lead(name):
lead["doctype_fields"], lead["all_fields"] = get_doctype_fields("CRM Lead", name)
lead["doctype"] = "CRM Lead"
lead["_form_script"] = get_form_script('CRM Lead')
- lead["_assign"] = get_assigned_users("CRM Lead", lead.name)
+ lead["_assign"] = get_assigned_users("CRM Lead", lead.name, lead.owner)
return lead
diff --git a/frontend/src/components/ListBulkActions.vue b/frontend/src/components/ListBulkActions.vue
new file mode 100644
index 00000000..6b54b15d
--- /dev/null
+++ b/frontend/src/components/ListBulkActions.vue
@@ -0,0 +1,205 @@
+
+
+
+
+
+
diff --git a/frontend/src/components/ListViews/CallLogsListView.vue b/frontend/src/components/ListViews/CallLogsListView.vue
index d4381818..e3aa425a 100644
--- a/frontend/src/components/ListViews/CallLogsListView.vue
+++ b/frontend/src/components/ListViews/CallLogsListView.vue
@@ -80,7 +80,9 @@
-
+
@@ -95,8 +97,18 @@
}"
@loadMore="emit('loadMore')"
/>
+
diff --git a/frontend/src/components/ListViews/ContactsListView.vue b/frontend/src/components/ListViews/ContactsListView.vue
index e4fdda12..4a192497 100644
--- a/frontend/src/components/ListViews/ContactsListView.vue
+++ b/frontend/src/components/ListViews/ContactsListView.vue
@@ -82,7 +82,9 @@
-
+
@@ -98,19 +100,18 @@
}"
@loadMore="emit('loadMore')"
/>
-
diff --git a/frontend/src/components/ListViews/DealsListView.vue b/frontend/src/components/ListViews/DealsListView.vue
index 40a0c934..8388c180 100644
--- a/frontend/src/components/ListViews/DealsListView.vue
+++ b/frontend/src/components/ListViews/DealsListView.vue
@@ -114,7 +114,9 @@
-
+
@@ -130,20 +132,14 @@
}"
@loadMore="emit('loadMore')"
/>
-
+
diff --git a/frontend/src/components/ListViews/EmailTemplatesListView.vue b/frontend/src/components/ListViews/EmailTemplatesListView.vue
index 1a35aa6d..52f3b4b0 100644
--- a/frontend/src/components/ListViews/EmailTemplatesListView.vue
+++ b/frontend/src/components/ListViews/EmailTemplatesListView.vue
@@ -69,7 +69,7 @@
-
+
@@ -84,18 +84,17 @@
}"
@loadMore="emit('loadMore')"
/>
-
diff --git a/frontend/src/components/ListViews/LeadsListView.vue b/frontend/src/components/ListViews/LeadsListView.vue
index a7a0a005..1855e85e 100644
--- a/frontend/src/components/ListViews/LeadsListView.vue
+++ b/frontend/src/components/ListViews/LeadsListView.vue
@@ -123,7 +123,7 @@
-
+
@@ -139,20 +139,14 @@
}"
@loadMore="emit('loadMore')"
/>
-
+
diff --git a/frontend/src/components/ListViews/OrganizationsListView.vue b/frontend/src/components/ListViews/OrganizationsListView.vue
index e3ed5b99..7a3509e0 100644
--- a/frontend/src/components/ListViews/OrganizationsListView.vue
+++ b/frontend/src/components/ListViews/OrganizationsListView.vue
@@ -69,7 +69,9 @@
-
+
@@ -84,18 +86,17 @@
}"
@loadMore="emit('loadMore')"
/>
-
diff --git a/frontend/src/components/ListViews/TasksListView.vue b/frontend/src/components/ListViews/TasksListView.vue
index 43a945aa..103a1a52 100644
--- a/frontend/src/components/ListViews/TasksListView.vue
+++ b/frontend/src/components/ListViews/TasksListView.vue
@@ -82,7 +82,7 @@
-
+
@@ -97,22 +97,21 @@
}"
@loadMore="emit('loadMore')"
/>
-
diff --git a/frontend/src/components/Modals/AssignmentModal.vue b/frontend/src/components/Modals/AssignmentModal.vue
index d9c3b9fa..0e1a9682 100644
--- a/frontend/src/components/Modals/AssignmentModal.vue
+++ b/frontend/src/components/Modals/AssignmentModal.vue
@@ -27,6 +27,7 @@
value=""
doctype="User"
@change="(option) => addValue(option) && ($refs.input.value = '')"
+ :placeholder="__('John Doe')"
:hideMe="true"
>
@@ -83,8 +84,18 @@ const props = defineProps({
type: Object,
default: null,
},
+ docs: {
+ type: Array,
+ default: () => [],
+ },
+ doctype: {
+ type: String,
+ default: '',
+ },
})
+const emit = defineEmits(['reload'])
+
const show = defineModel()
const assignees = defineModel('assignees')
const oldAssignees = ref([])
@@ -101,7 +112,7 @@ const removeValue = (value) => {
const owner = computed(() => {
if (!props.doc) return ''
- if (props.doc.doctype == 'CRM Lead') return props.doc.lead_owner
+ if (props.doctype == 'CRM Lead') return props.doc.lead_owner
return props.doc.deal_owner
})
@@ -137,7 +148,7 @@ function updateAssignees() {
if (removedAssignees.length) {
for (let a of removedAssignees) {
call('frappe.desk.form.assign_to.remove', {
- doctype: props.doc.doctype,
+ doctype: props.doctype,
name: props.doc.name,
assign_to: a,
})
@@ -145,11 +156,23 @@ function updateAssignees() {
}
if (addedAssignees.length) {
- call('frappe.desk.form.assign_to.add', {
- doctype: props.doc.doctype,
- name: props.doc.name,
- assign_to: addedAssignees,
- })
+ if (props.docs.size) {
+ call('frappe.desk.form.assign_to.add_multiple', {
+ doctype: props.doctype,
+ name: JSON.stringify(Array.from(props.docs)),
+ assign_to: addedAssignees,
+ bulk_assign: true,
+ re_assign: true,
+ }).then(() => {
+ emit('reload')
+ })
+ } else {
+ call('frappe.desk.form.assign_to.add', {
+ doctype: props.doctype,
+ name: props.doc.name,
+ assign_to: addedAssignees,
+ })
+ }
}
show.value = false
}
diff --git a/frontend/src/components/Modals/EditValueModal.vue b/frontend/src/components/Modals/EditValueModal.vue
index 3d918d96..9f60a6fa 100644
--- a/frontend/src/components/Modals/EditValueModal.vue
+++ b/frontend/src/components/Modals/EditValueModal.vue
@@ -59,7 +59,6 @@ const props = defineProps({
})
const show = defineModel()
-const unselectAll = defineModel('unselectAll')
const emit = defineEmits(['reload'])
@@ -114,7 +113,6 @@ function updateValues() {
newValue.value = ''
loading.value = false
show.value = false
- unselectAll.value()
emit('reload')
})
}
@@ -130,6 +128,10 @@ function updateValue(v) {
newValue.value = value
}
+function getSelectOptions(options) {
+ return options.split('\n')
+}
+
function getValueComponent(f) {
const { type, options } = f
if (typeSelect.includes(type) || typeCheck.includes(type)) {
@@ -140,6 +142,7 @@ function getValueComponent(f) {
label: o,
value: o,
})),
+ modelValue: newValue.value,
})
} else if (typeLink.includes(type)) {
if (type == 'Dynamic Link') {
diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue
index 3d849b09..a8b04997 100644
--- a/frontend/src/pages/Deal.vue
+++ b/frontend/src/pages/Deal.vue
@@ -280,6 +280,7 @@
diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue
index 5c983292..eeeda16e 100644
--- a/frontend/src/pages/Lead.vue
+++ b/frontend/src/pages/Lead.vue
@@ -186,6 +186,7 @@