@@ -42,6 +42,8 @@ def get_bootinfo(): | |||||
bootinfo.user_info = get_user_info() | bootinfo.user_info = get_user_info() | ||||
bootinfo.sid = frappe.session['sid'] | bootinfo.sid = frappe.session['sid'] | ||||
bootinfo.user_groups = frappe.get_all('User Group', pluck="name") | |||||
bootinfo.modules = {} | bootinfo.modules = {} | ||||
bootinfo.module_list = [] | bootinfo.module_list = [] | ||||
load_desktop_data(bootinfo) | load_desktop_data(bootinfo) | ||||
@@ -1018,8 +1018,13 @@ def extract_mentions(txt): | |||||
soup = BeautifulSoup(txt, 'html.parser') | soup = BeautifulSoup(txt, 'html.parser') | ||||
emails = [] | emails = [] | ||||
for mention in soup.find_all(class_='mention'): | for mention in soup.find_all(class_='mention'): | ||||
if mention.get('data-is-group'): | |||||
user_group = frappe.get_cached_doc('User Group', mention['data-id']) | |||||
emails += [d.user for d in user_group.user_group_members] | |||||
continue | |||||
email = mention['data-id'] | email = mention['data-id'] | ||||
emails.append(email) | emails.append(email) | ||||
return emails | return emails | ||||
def handle_password_test_fail(result): | def handle_password_test_fail(result): | ||||
@@ -0,0 +1,10 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# Copyright (c) 2021, Frappe Technologies and Contributors | |||||
# See license.txt | |||||
from __future__ import unicode_literals | |||||
# import frappe | |||||
import unittest | |||||
class TestUserGroup(unittest.TestCase): | |||||
pass |
@@ -0,0 +1,8 @@ | |||||
// Copyright (c) 2021, Frappe Technologies and contributors | |||||
// For license information, please see license.txt | |||||
frappe.ui.form.on('User Group', { | |||||
// refresh: function(frm) { | |||||
// } | |||||
}); |
@@ -0,0 +1,50 @@ | |||||
{ | |||||
"actions": [], | |||||
"autoname": "field:group_name", | |||||
"creation": "2021-04-12 15:17:24.751710", | |||||
"doctype": "DocType", | |||||
"editable_grid": 1, | |||||
"engine": "InnoDB", | |||||
"field_order": [ | |||||
"group_name", | |||||
"user_group_members" | |||||
], | |||||
"fields": [ | |||||
{ | |||||
"fieldname": "group_name", | |||||
"fieldtype": "Data", | |||||
"label": "Group Name", | |||||
"unique": 1 | |||||
}, | |||||
{ | |||||
"fieldname": "user_group_members", | |||||
"fieldtype": "Table MultiSelect", | |||||
"label": "User Group Members", | |||||
"options": "User Group Member" | |||||
} | |||||
], | |||||
"index_web_pages_for_search": 1, | |||||
"links": [], | |||||
"modified": "2021-04-12 15:17:24.751710", | |||||
"modified_by": "Administrator", | |||||
"module": "Core", | |||||
"name": "User Group", | |||||
"owner": "Administrator", | |||||
"permissions": [ | |||||
{ | |||||
"create": 1, | |||||
"delete": 1, | |||||
"email": 1, | |||||
"export": 1, | |||||
"print": 1, | |||||
"read": 1, | |||||
"report": 1, | |||||
"role": "System Manager", | |||||
"share": 1, | |||||
"write": 1 | |||||
} | |||||
], | |||||
"sort_field": "modified", | |||||
"sort_order": "DESC", | |||||
"track_changes": 1 | |||||
} |
@@ -0,0 +1,10 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# Copyright (c) 2021, Frappe Technologies and contributors | |||||
# For license information, please see license.txt | |||||
from __future__ import unicode_literals | |||||
# import frappe | |||||
from frappe.model.document import Document | |||||
class UserGroup(Document): | |||||
pass |
@@ -0,0 +1,10 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# Copyright (c) 2021, Frappe Technologies and Contributors | |||||
# See license.txt | |||||
from __future__ import unicode_literals | |||||
# import frappe | |||||
import unittest | |||||
class TestUserGroupMember(unittest.TestCase): | |||||
pass |
@@ -0,0 +1,8 @@ | |||||
// Copyright (c) 2021, Frappe Technologies and contributors | |||||
// For license information, please see license.txt | |||||
frappe.ui.form.on('User Group Member', { | |||||
// refresh: function(frm) { | |||||
// } | |||||
}); |
@@ -0,0 +1,32 @@ | |||||
{ | |||||
"actions": [], | |||||
"creation": "2021-04-12 15:16:29.279107", | |||||
"doctype": "DocType", | |||||
"editable_grid": 1, | |||||
"engine": "InnoDB", | |||||
"field_order": [ | |||||
"user" | |||||
], | |||||
"fields": [ | |||||
{ | |||||
"fieldname": "user", | |||||
"fieldtype": "Link", | |||||
"in_list_view": 1, | |||||
"label": "User", | |||||
"options": "User", | |||||
"reqd": 1 | |||||
} | |||||
], | |||||
"index_web_pages_for_search": 1, | |||||
"istable": 1, | |||||
"links": [], | |||||
"modified": "2021-04-12 15:17:18.773046", | |||||
"modified_by": "Administrator", | |||||
"module": "Core", | |||||
"name": "User Group Member", | |||||
"owner": "Administrator", | |||||
"permissions": [], | |||||
"sort_field": "modified", | |||||
"sort_order": "DESC", | |||||
"track_changes": 1 | |||||
} |
@@ -0,0 +1,10 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# Copyright (c) 2021, Frappe Technologies and contributors | |||||
# For license information, please see license.txt | |||||
from __future__ import unicode_literals | |||||
# import frappe | |||||
from frappe.model.document import Document | |||||
class UserGroupMember(Document): | |||||
pass |
@@ -15,6 +15,7 @@ class MentionBlot extends Embed { | |||||
node.dataset.id = data.id; | node.dataset.id = data.id; | ||||
node.dataset.value = data.value; | node.dataset.value = data.value; | ||||
node.dataset.denotationChar = data.denotationChar; | node.dataset.denotationChar = data.denotationChar; | ||||
node.dataset.isGroup = data.isGroup; | |||||
if (data.link) { | if (data.link) { | ||||
node.dataset.link = data.link; | node.dataset.link = data.link; | ||||
} | } | ||||
@@ -27,6 +28,7 @@ class MentionBlot extends Embed { | |||||
value: domNode.dataset.value, | value: domNode.dataset.value, | ||||
link: domNode.dataset.link || null, | link: domNode.dataset.link || null, | ||||
denotationChar: domNode.dataset.denotationChar, | denotationChar: domNode.dataset.denotationChar, | ||||
isGroup: domNode.dataset.isGroup, | |||||
}; | }; | ||||
} | } | ||||
} | } | ||||
@@ -149,6 +149,7 @@ class Mention { | |||||
this.mentionList.childNodes[this.itemIndex].dataset.value, | this.mentionList.childNodes[this.itemIndex].dataset.value, | ||||
link: itemLink || null, | link: itemLink || null, | ||||
denotationChar: this.mentionList.childNodes[this.itemIndex].dataset.denotationChar, | denotationChar: this.mentionList.childNodes[this.itemIndex].dataset.denotationChar, | ||||
isGroup: this.mentionList.childNodes[this.itemIndex].dataset.isGroup, | |||||
}; | }; | ||||
} | } | ||||
@@ -197,6 +198,7 @@ class Mention { | |||||
li.dataset.index = i; | li.dataset.index = i; | ||||
li.dataset.id = data[i].id; | li.dataset.id = data[i].id; | ||||
li.dataset.value = data[i].value; | li.dataset.value = data[i].value; | ||||
li.dataset.isGroup = Boolean(data[i].is_group); | |||||
li.dataset.denotationChar = mentionChar; | li.dataset.denotationChar = mentionChar; | ||||
if (data[i].link) { | if (data[i].link) { | ||||
li.dataset.link = data[i].link; | li.dataset.link = data[i].link; | ||||
@@ -1285,6 +1285,15 @@ Object.assign(frappe.utils, { | |||||
value: frappe.boot.user_info[user].fullname, | value: frappe.boot.user_info[user].fullname, | ||||
}; | }; | ||||
}); | }); | ||||
frappe.boot.user_groups && frappe.boot.user_groups.map(group => { | |||||
names_for_mentions.push({ | |||||
id: group, | |||||
value: group, | |||||
is_group: true | |||||
}); | |||||
}); | |||||
return names_for_mentions; | return names_for_mentions; | ||||
}, | }, | ||||
print(doctype, docname, print_format, letterhead, lang_code) { | print(doctype, docname, print_format, letterhead, lang_code) { | ||||
@@ -190,4 +190,8 @@ | |||||
.mention>span { | .mention>span { | ||||
margin: 0 3px; | margin: 0 3px; | ||||
} | |||||
} | |||||
.mention[data-is-group="true"] { | |||||
background-color: var(--purple-100) !important; | |||||
} |
@@ -77,6 +77,7 @@ $threshold: 34; | |||||
} | } | ||||
} | } | ||||
.document-email-link-container { | .document-email-link-container { | ||||
@extend .ellipsis; | |||||
position: relative; | position: relative; | ||||
padding: var(--padding-sm); | padding: var(--padding-sm); | ||||
font-size: var(--text-sm); | font-size: var(--text-sm); | ||||
@@ -141,4 +142,4 @@ $threshold: 34; | |||||
--icon-stroke: var(--text-color); | --icon-stroke: var(--text-color); | ||||
} | } | ||||
} | } | ||||
} | |||||
} |
@@ -177,7 +177,7 @@ acceptable_attributes = [ | |||||
'data-value', 'role', 'frameborder', 'allowfullscreen', 'spellcheck', | 'data-value', 'role', 'frameborder', 'allowfullscreen', 'spellcheck', | ||||
'data-mode', 'data-gramm', 'data-placeholder', 'data-comment', | 'data-mode', 'data-gramm', 'data-placeholder', 'data-comment', | ||||
'data-id', 'data-denotation-char', 'itemprop', 'itemscope', | 'data-id', 'data-denotation-char', 'itemprop', 'itemscope', | ||||
'itemtype', 'itemid', 'itemref', 'datetime' | |||||
'itemtype', 'itemid', 'itemref', 'datetime', 'data-is-group' | |||||
] | ] | ||||
mathml_attributes = [ | mathml_attributes = [ | ||||