commit
7b58d0e10d
@ -5,6 +5,7 @@ from frappe import _
|
||||
from bs4 import BeautifulSoup
|
||||
from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
|
||||
|
||||
|
||||
def on_update(self, method):
|
||||
notify_mentions(self)
|
||||
|
||||
@ -24,25 +25,31 @@ def notify_mentions(doc):
|
||||
doctype = doc.reference_doctype
|
||||
if doctype.startswith("CRM "):
|
||||
doctype = doctype[4:].lower()
|
||||
name = reference_doc.lead_name or name if doctype == "lead" else reference_doc.organization or reference_doc.lead_name or name
|
||||
name = (
|
||||
reference_doc.lead_name
|
||||
if doctype == "lead"
|
||||
else reference_doc.organization or reference_doc.lead_name
|
||||
)
|
||||
notification_text = f"""
|
||||
<div class="mb-2 leading-5 text-gray-600">
|
||||
<span class="font-medium text-gray-900">{ owner }</span>
|
||||
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||
<span class="font-medium text-ink-gray-9">{ owner }</span>
|
||||
<span>{ _('mentioned you in {0}').format(doctype) }</span>
|
||||
<span class="font-medium text-gray-900">{ name }</span>
|
||||
<span class="font-medium text-ink-gray-9">{ name }</span>
|
||||
</div>
|
||||
"""
|
||||
notify_user({
|
||||
"owner": doc.owner,
|
||||
"assigned_to": mention.email,
|
||||
"notification_type": "Mention",
|
||||
"message": doc.content,
|
||||
"notification_text": notification_text,
|
||||
"reference_doctype": "Comment",
|
||||
"reference_docname": doc.name,
|
||||
"redirect_to_doctype": doc.reference_doctype,
|
||||
"redirect_to_docname": doc.reference_name,
|
||||
})
|
||||
notify_user(
|
||||
{
|
||||
"owner": doc.owner,
|
||||
"assigned_to": mention.email,
|
||||
"notification_type": "Mention",
|
||||
"message": doc.content,
|
||||
"notification_text": notification_text,
|
||||
"reference_doctype": "Comment",
|
||||
"reference_docname": doc.name,
|
||||
"redirect_to_doctype": doc.reference_doctype,
|
||||
"redirect_to_docname": doc.reference_name,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def extract_mentions(html):
|
||||
@ -56,39 +63,42 @@ def extract_mentions(html):
|
||||
)
|
||||
return mentions
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def add_attachments(name: str, attachments: Iterable[str | dict]) -> None:
|
||||
"""Add attachments to the given Comment
|
||||
"""Add attachments to the given Comment
|
||||
|
||||
:param name: Comment name
|
||||
:param attachments: File names or dicts with keys "fname" and "fcontent"
|
||||
"""
|
||||
# loop through attachments
|
||||
for a in attachments:
|
||||
if isinstance(a, str):
|
||||
attach = frappe.db.get_value("File", {"name": a}, ["file_url", "is_private"], as_dict=1)
|
||||
file_args = {
|
||||
"file_url": attach.file_url,
|
||||
"is_private": attach.is_private,
|
||||
}
|
||||
elif isinstance(a, dict) and "fcontent" in a and "fname" in a:
|
||||
# dict returned by frappe.attach_print()
|
||||
file_args = {
|
||||
"file_name": a["fname"],
|
||||
"content": a["fcontent"],
|
||||
"is_private": 1,
|
||||
}
|
||||
else:
|
||||
continue
|
||||
:param name: Comment name
|
||||
:param attachments: File names or dicts with keys "fname" and "fcontent"
|
||||
"""
|
||||
# loop through attachments
|
||||
for a in attachments:
|
||||
if isinstance(a, str):
|
||||
attach = frappe.db.get_value(
|
||||
"File", {"name": a}, ["file_url", "is_private"], as_dict=1
|
||||
)
|
||||
file_args = {
|
||||
"file_url": attach.file_url,
|
||||
"is_private": attach.is_private,
|
||||
}
|
||||
elif isinstance(a, dict) and "fcontent" in a and "fname" in a:
|
||||
# dict returned by frappe.attach_print()
|
||||
file_args = {
|
||||
"file_name": a["fname"],
|
||||
"content": a["fcontent"],
|
||||
"is_private": 1,
|
||||
}
|
||||
else:
|
||||
continue
|
||||
|
||||
file_args.update(
|
||||
{
|
||||
"attached_to_doctype": "Comment",
|
||||
"attached_to_name": name,
|
||||
"folder": "Home/Attachments",
|
||||
}
|
||||
)
|
||||
file_args.update(
|
||||
{
|
||||
"attached_to_doctype": "Comment",
|
||||
"attached_to_name": name,
|
||||
"folder": "Home/Attachments",
|
||||
}
|
||||
)
|
||||
|
||||
_file = frappe.new_doc("File")
|
||||
_file.update(file_args)
|
||||
_file.save(ignore_permissions=True)
|
||||
_file = frappe.new_doc("File")
|
||||
_file.update(file_args)
|
||||
_file.save(ignore_permissions=True)
|
||||
|
||||
191
crm/api/todo.py
191
crm/api/todo.py
@ -2,102 +2,131 @@ import frappe
|
||||
from frappe import _
|
||||
from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
|
||||
|
||||
def after_insert(doc, method):
|
||||
if doc.reference_type in ["CRM Lead", "CRM Deal"] and doc.reference_name and doc.allocated_to:
|
||||
fieldname = "lead_owner" if doc.reference_type == "CRM Lead" else "deal_owner"
|
||||
lead_owner = frappe.db.get_value(doc.reference_type, doc.reference_name, fieldname)
|
||||
if not lead_owner:
|
||||
frappe.db.set_value(doc.reference_type, doc.reference_name, fieldname, doc.allocated_to)
|
||||
|
||||
if doc.reference_type in ["CRM Lead", "CRM Deal", "CRM Task"] and doc.reference_name and doc.allocated_to:
|
||||
notify_assigned_user(doc)
|
||||
def after_insert(doc, method):
|
||||
if (
|
||||
doc.reference_type in ["CRM Lead", "CRM Deal"]
|
||||
and doc.reference_name
|
||||
and doc.allocated_to
|
||||
):
|
||||
fieldname = "lead_owner" if doc.reference_type == "CRM Lead" else "deal_owner"
|
||||
lead_owner = frappe.db.get_value(
|
||||
doc.reference_type, doc.reference_name, fieldname
|
||||
)
|
||||
if not lead_owner:
|
||||
frappe.db.set_value(
|
||||
doc.reference_type, doc.reference_name, fieldname, doc.allocated_to
|
||||
)
|
||||
|
||||
if (
|
||||
doc.reference_type in ["CRM Lead", "CRM Deal", "CRM Task"]
|
||||
and doc.reference_name
|
||||
and doc.allocated_to
|
||||
):
|
||||
notify_assigned_user(doc)
|
||||
|
||||
|
||||
def on_update(doc, method):
|
||||
if doc.has_value_changed("status") and doc.status == "Cancelled" and doc.reference_type in ["CRM Lead", "CRM Deal", "CRM Task"] and doc.reference_name and doc.allocated_to:
|
||||
notify_assigned_user(doc, is_cancelled=True)
|
||||
if (
|
||||
doc.has_value_changed("status")
|
||||
and doc.status == "Cancelled"
|
||||
and doc.reference_type in ["CRM Lead", "CRM Deal", "CRM Task"]
|
||||
and doc.reference_name
|
||||
and doc.allocated_to
|
||||
):
|
||||
notify_assigned_user(doc, is_cancelled=True)
|
||||
|
||||
|
||||
def notify_assigned_user(doc, is_cancelled=False):
|
||||
_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
|
||||
owner = frappe.get_cached_value("User", frappe.session.user, "full_name")
|
||||
notification_text = get_notification_text(owner, doc, _doc, is_cancelled)
|
||||
_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
|
||||
owner = frappe.get_cached_value("User", frappe.session.user, "full_name")
|
||||
notification_text = get_notification_text(owner, doc, _doc, is_cancelled)
|
||||
|
||||
message = _("Your assignment on {0} {1} has been removed by {2}").format(
|
||||
doc.reference_type,
|
||||
doc.reference_name,
|
||||
owner
|
||||
) if is_cancelled else _("{0} assigned a {1} {2} to you").format(
|
||||
owner,
|
||||
doc.reference_type,
|
||||
doc.reference_name
|
||||
)
|
||||
message = (
|
||||
_("Your assignment on {0} {1} has been removed by {2}").format(
|
||||
doc.reference_type, doc.reference_name, owner
|
||||
)
|
||||
if is_cancelled
|
||||
else _("{0} assigned a {1} {2} to you").format(
|
||||
owner, doc.reference_type, doc.reference_name
|
||||
)
|
||||
)
|
||||
|
||||
redirect_to_doctype, redirect_to_name = get_redirect_to_doc(doc)
|
||||
redirect_to_doctype, redirect_to_name = get_redirect_to_doc(doc)
|
||||
|
||||
notify_user(
|
||||
{
|
||||
"owner": frappe.session.user,
|
||||
"assigned_to": doc.allocated_to,
|
||||
"notification_type": "Assignment",
|
||||
"message": message,
|
||||
"notification_text": notification_text,
|
||||
"reference_doctype": doc.reference_type,
|
||||
"reference_docname": doc.reference_name,
|
||||
"redirect_to_doctype": redirect_to_doctype,
|
||||
"redirect_to_docname": redirect_to_name,
|
||||
}
|
||||
)
|
||||
|
||||
notify_user({
|
||||
"owner": frappe.session.user,
|
||||
"assigned_to": doc.allocated_to,
|
||||
"notification_type": "Assignment",
|
||||
"message": message,
|
||||
"notification_text": notification_text,
|
||||
"reference_doctype": doc.reference_type,
|
||||
"reference_docname": doc.reference_name,
|
||||
"redirect_to_doctype": redirect_to_doctype,
|
||||
"redirect_to_docname": redirect_to_name,
|
||||
})
|
||||
|
||||
def get_notification_text(owner, doc, reference_doc, is_cancelled=False):
|
||||
name = doc.reference_name
|
||||
doctype = doc.reference_type
|
||||
name = doc.reference_name
|
||||
doctype = doc.reference_type
|
||||
|
||||
if doctype.startswith("CRM "):
|
||||
doctype = doctype[4:].lower()
|
||||
if doctype.startswith("CRM "):
|
||||
doctype = doctype[4:].lower()
|
||||
|
||||
if doctype in ["lead", "deal"]:
|
||||
name = reference_doc.lead_name or name if doctype == "lead" else reference_doc.organization or reference_doc.lead_name or name
|
||||
if doctype in ["lead", "deal"]:
|
||||
name = (
|
||||
reference_doc.lead_name or name
|
||||
if doctype == "lead"
|
||||
else reference_doc.organization or reference_doc.lead_name or name
|
||||
)
|
||||
|
||||
if is_cancelled:
|
||||
return f"""
|
||||
<div class="mb-2 leading-5 text-gray-600">
|
||||
<span>{ _('Your assignment on {0} {1} has been removed by {2}').format(
|
||||
doctype,
|
||||
f'<span class="font-medium text-gray-900">{ name }</span>',
|
||||
f'<span class="font-medium text-gray-900">{ owner }</span>'
|
||||
) }</span>
|
||||
</div>
|
||||
"""
|
||||
if is_cancelled:
|
||||
return f"""
|
||||
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||
<span>{ _('Your assignment on {0} {1} has been removed by {2}').format(
|
||||
doctype,
|
||||
f'<span class="font-medium text-ink-gray-9">{ name }</span>',
|
||||
f'<span class="font-medium text-ink-gray-9">{ owner }</span>'
|
||||
) }</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
return f"""
|
||||
<div class="mb-2 leading-5 text-gray-600">
|
||||
<span class="font-medium text-gray-900">{ owner }</span>
|
||||
<span>{ _('assigned a {0} {1} to you').format(
|
||||
doctype,
|
||||
f'<span class="font-medium text-gray-900">{ name }</span>'
|
||||
) }</span>
|
||||
</div>
|
||||
"""
|
||||
return f"""
|
||||
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||
<span class="font-medium text-ink-gray-9">{ owner }</span>
|
||||
<span>{ _('assigned a {0} {1} to you').format(
|
||||
doctype,
|
||||
f'<span class="font-medium text-ink-gray-9">{ name }</span>'
|
||||
) }</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
if doctype == "task":
|
||||
if is_cancelled:
|
||||
return f"""
|
||||
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||
<span>{ _('Your assignment on task {0} has been removed by {1}').format(
|
||||
f'<span class="font-medium text-ink-gray-9">{ reference_doc.title }</span>',
|
||||
f'<span class="font-medium text-ink-gray-9">{ owner }</span>'
|
||||
) }</span>
|
||||
</div>
|
||||
"""
|
||||
return f"""
|
||||
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||
<span class="font-medium text-ink-gray-9">{ owner }</span>
|
||||
<span>{ _('assigned a new task {0} to you').format(
|
||||
f'<span class="font-medium text-ink-gray-9">{ reference_doc.title }</span>'
|
||||
) }</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
if doctype == "task":
|
||||
if is_cancelled:
|
||||
return f"""
|
||||
<div class="mb-2 leading-5 text-gray-600">
|
||||
<span>{ _('Your assignment on task {0} has been removed by {1}').format(
|
||||
f'<span class="font-medium text-gray-900">{ reference_doc.title }</span>',
|
||||
f'<span class="font-medium text-gray-900">{ owner }</span>'
|
||||
) }</span>
|
||||
</div>
|
||||
"""
|
||||
return f"""
|
||||
<div class="mb-2 leading-5 text-gray-600">
|
||||
<span class="font-medium text-gray-900">{ owner }</span>
|
||||
<span>{ _('assigned a new task {0} to you').format(
|
||||
f'<span class="font-medium text-gray-900">{ reference_doc.title }</span>'
|
||||
) }</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
def get_redirect_to_doc(doc):
|
||||
if doc.reference_type == "CRM Task":
|
||||
reference_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
|
||||
return reference_doc.reference_doctype, reference_doc.reference_docname
|
||||
if doc.reference_type == "CRM Task":
|
||||
reference_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
|
||||
return reference_doc.reference_doctype, reference_doc.reference_docname
|
||||
|
||||
return doc.reference_type, doc.reference_name
|
||||
return doc.reference_type, doc.reference_name
|
||||
|
||||
@ -30,25 +30,27 @@ def notify_agent(doc):
|
||||
if doctype.startswith("CRM "):
|
||||
doctype = doctype[4:].lower()
|
||||
notification_text = f"""
|
||||
<div class="mb-2 leading-5 text-gray-600">
|
||||
<span class="font-medium text-gray-900">{ _('You') }</span>
|
||||
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||
<span class="font-medium text-ink-gray-9">{ _('You') }</span>
|
||||
<span>{ _('received a whatsapp message in {0}').format(doctype) }</span>
|
||||
<span class="font-medium text-gray-900">{ doc.reference_name }</span>
|
||||
<span class="font-medium text-ink-gray-9">{ doc.reference_name }</span>
|
||||
</div>
|
||||
"""
|
||||
assigned_users = get_assigned_users(doc.reference_doctype, doc.reference_name)
|
||||
for user in assigned_users:
|
||||
notify_user({
|
||||
"owner": doc.owner,
|
||||
"assigned_to": user,
|
||||
"notification_type": "WhatsApp",
|
||||
"message": doc.message,
|
||||
"notification_text": notification_text,
|
||||
"reference_doctype": "WhatsApp Message",
|
||||
"reference_docname": doc.name,
|
||||
"redirect_to_doctype": doc.reference_doctype,
|
||||
"redirect_to_docname": doc.reference_name,
|
||||
})
|
||||
notify_user(
|
||||
{
|
||||
"owner": doc.owner,
|
||||
"assigned_to": user,
|
||||
"notification_type": "WhatsApp",
|
||||
"message": doc.message,
|
||||
"notification_text": notification_text,
|
||||
"reference_doctype": "WhatsApp Message",
|
||||
"reference_docname": doc.name,
|
||||
"redirect_to_doctype": doc.reference_doctype,
|
||||
"redirect_to_docname": doc.reference_name,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def get_lead_or_deal_from_number(number):
|
||||
@ -92,6 +94,7 @@ def is_whatsapp_enabled():
|
||||
return False
|
||||
return frappe.get_cached_value("WhatsApp Settings", "WhatsApp Settings", "enabled")
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def is_whatsapp_installed():
|
||||
if not frappe.db.exists("DocType", "WhatsApp Settings"):
|
||||
@ -105,8 +108,8 @@ def get_whatsapp_messages(reference_doctype, reference_name):
|
||||
return []
|
||||
messages = []
|
||||
|
||||
if reference_doctype == 'CRM Deal':
|
||||
lead = frappe.db.get_value(reference_doctype, reference_name, 'lead')
|
||||
if reference_doctype == "CRM Deal":
|
||||
lead = frappe.db.get_value(reference_doctype, reference_name, "lead")
|
||||
if lead:
|
||||
messages = frappe.get_all(
|
||||
"WhatsApp Message",
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 59415754663693989ae5144b43370f4b0426aa50
|
||||
Subproject commit 82150c9591a36abc5dc8667ae5873651d4b2cc0d
|
||||
@ -14,7 +14,7 @@
|
||||
"@vueuse/core": "^10.3.0",
|
||||
"@vueuse/integrations": "^10.3.0",
|
||||
"feather-icons": "^4.28.0",
|
||||
"frappe-ui": "^0.1.81",
|
||||
"frappe-ui": "^0.1.86",
|
||||
"gemoji": "^8.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"mime": "^4.0.1",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,152 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
font-display: swap;
|
||||
src: url("Inter-Thin.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-Thin.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 100;
|
||||
font-display: swap;
|
||||
src: url("Inter-ThinItalic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-ThinItalic.woff?v=3.12") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
font-display: swap;
|
||||
src: url("Inter-ExtraLight.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-ExtraLight.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 200;
|
||||
font-display: swap;
|
||||
src: url("Inter-ExtraLightItalic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-ExtraLightItalic.woff?v=3.12") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url("Inter-Light.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-Light.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url("Inter-LightItalic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-LightItalic.woff?v=3.12") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("Inter-Regular.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-Regular.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("Inter-Italic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-Italic.woff?v=3.12") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url("Inter-Medium.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-Medium.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url("Inter-MediumItalic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-MediumItalic.woff?v=3.12") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url("Inter-SemiBold.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-SemiBold.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url("Inter-SemiBoldItalic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-SemiBoldItalic.woff?v=3.12") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("Inter-Bold.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-Bold.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("Inter-BoldItalic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-BoldItalic.woff?v=3.12") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url("Inter-ExtraBold.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-ExtraBold.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url("Inter-ExtraBoldItalic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-ExtraBoldItalic.woff?v=3.12") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: url("Inter-Black.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-Black.woff?v=3.12") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: italic;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: url("Inter-BlackItalic.woff2?v=3.12") format("woff2"),
|
||||
url("Inter-BlackItalic.woff?v=3.12") format("woff");
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
>
|
||||
<div
|
||||
v-if="all_activities?.loading"
|
||||
class="flex flex-1 flex-col items-center justify-center gap-3 text-xl font-medium text-gray-500"
|
||||
class="flex flex-1 flex-col items-center justify-center gap-3 text-xl font-medium text-ink-gray-4"
|
||||
>
|
||||
<LoadingIndicator class="h-6 w-6" />
|
||||
<span>{{ __('Loading...') }}</span>
|
||||
@ -50,13 +50,13 @@
|
||||
class="activity grid grid-cols-[30px_minmax(auto,_1fr)] gap-2 px-3 sm:gap-4 sm:px-10"
|
||||
>
|
||||
<div
|
||||
class="relative flex justify-center after:absolute after:left-[50%] after:top-0 after:-z-10 after:border-l after:border-gray-200"
|
||||
class="relative flex justify-center after:absolute after:left-[50%] after:top-0 after:-z-10 after:border-l after:border-outline-gray-modals"
|
||||
:class="i != activities.length - 1 ? 'after:h-full' : 'after:h-4'"
|
||||
>
|
||||
<div
|
||||
class="z-10 flex h-8 w-7 items-center justify-center bg-white"
|
||||
class="z-10 flex h-8 w-7 items-center justify-center bg-surface-white"
|
||||
>
|
||||
<CommentIcon class="text-gray-800" />
|
||||
<CommentIcon class="text-ink-gray-8" />
|
||||
</div>
|
||||
</div>
|
||||
<CommentArea class="mb-4" :activity="comment" />
|
||||
@ -72,15 +72,15 @@
|
||||
class="activity grid grid-cols-[30px_minmax(auto,_1fr)] gap-4 px-3 sm:px-10"
|
||||
>
|
||||
<div
|
||||
class="relative flex justify-center after:absolute after:left-[50%] after:top-0 after:-z-10 after:border-l after:border-gray-200"
|
||||
class="relative flex justify-center after:absolute after:left-[50%] after:top-0 after:-z-10 after:border-l after:border-outline-gray-modals"
|
||||
:class="i != activities.length - 1 ? 'after:h-full' : 'after:h-4'"
|
||||
>
|
||||
<div
|
||||
class="z-10 flex h-8 w-7 items-center justify-center bg-white text-gray-800"
|
||||
class="z-10 flex h-8 w-7 items-center justify-center bg-surface-white text-ink-gray-8"
|
||||
>
|
||||
<MissedCallIcon
|
||||
v-if="call.status == 'No Answer'"
|
||||
class="text-red-600"
|
||||
class="text-ink-red-4"
|
||||
/>
|
||||
<DeclinedCallIcon v-else-if="call.status == 'Busy'" />
|
||||
<component
|
||||
@ -116,14 +116,14 @@
|
||||
>
|
||||
<div
|
||||
v-if="['Activity', 'Emails'].includes(title)"
|
||||
class="relative flex justify-center before:absolute before:left-[50%] before:top-0 before:-z-10 before:border-l before:border-gray-200"
|
||||
class="relative flex justify-center before:absolute before:left-[50%] before:top-0 before:-z-10 before:border-l before:border-outline-gray-modals"
|
||||
:class="[i != activities.length - 1 ? 'before:h-full' : 'before:h-4']"
|
||||
>
|
||||
<div
|
||||
class="z-10 flex h-7 w-7 items-center justify-center bg-white"
|
||||
class="z-10 flex h-7 w-7 items-center justify-center bg-surface-white"
|
||||
:class="{
|
||||
'mt-2.5': ['communication'].includes(activity.activity_type),
|
||||
'bg-white': ['added', 'removed', 'changed'].includes(
|
||||
'bg-surface-white': ['added', 'removed', 'changed'].includes(
|
||||
activity.activity_type,
|
||||
),
|
||||
'h-8': [
|
||||
@ -145,7 +145,7 @@
|
||||
activity.activity_type,
|
||||
) && activity.status == 'No Answer'
|
||||
"
|
||||
class="text-red-600"
|
||||
class="text-ink-red-4"
|
||||
/>
|
||||
<DeclinedCallIcon
|
||||
v-else-if="
|
||||
@ -159,8 +159,8 @@
|
||||
:is="activity.icon"
|
||||
:class="
|
||||
['added', 'removed', 'changed'].includes(activity.activity_type)
|
||||
? 'text-gray-500'
|
||||
: 'text-gray-800'
|
||||
? 'text-ink-gray-4'
|
||||
: 'text-ink-gray-8'
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -185,10 +185,10 @@
|
||||
>
|
||||
<div class="flex items-center justify-stretch gap-2 text-base">
|
||||
<div
|
||||
class="inline-flex items-center flex-wrap gap-1.5 text-gray-800 font-medium"
|
||||
class="inline-flex items-center flex-wrap gap-1.5 text-ink-gray-8 font-medium"
|
||||
>
|
||||
<span class="font-medium">{{ activity.owner_name }}</span>
|
||||
<span class="text-gray-600">{{ __(activity.data.type) }}</span>
|
||||
<span class="text-ink-gray-5">{{ __(activity.data.type) }}</span>
|
||||
<a
|
||||
v-if="activity.data.file_url"
|
||||
:href="activity.data.file_url"
|
||||
@ -205,7 +205,7 @@
|
||||
</div>
|
||||
<div class="ml-auto whitespace-nowrap">
|
||||
<Tooltip :text="dateFormat(activity.creation, dateTooltipFormat)">
|
||||
<div class="text-sm text-gray-600">
|
||||
<div class="text-sm text-ink-gray-5">
|
||||
{{ __(timeAgo(activity.creation)) }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
@ -225,7 +225,7 @@
|
||||
<div class="flex items-center justify-stretch gap-2 text-base">
|
||||
<div
|
||||
v-if="activity.other_versions"
|
||||
class="inline-flex flex-wrap gap-1.5 text-gray-800 font-medium"
|
||||
class="inline-flex flex-wrap gap-1.5 text-ink-gray-8 font-medium"
|
||||
>
|
||||
<span>{{ activity.show_others ? __('Hide') : __('Show') }}</span>
|
||||
<span> +{{ activity.other_versions.length + 1 }} </span>
|
||||
@ -243,22 +243,22 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="inline-flex items-center flex-wrap gap-1 text-gray-600"
|
||||
class="inline-flex items-center flex-wrap gap-1 text-ink-gray-5"
|
||||
>
|
||||
<span class="font-medium text-gray-800">
|
||||
<span class="font-medium text-ink-gray-8">
|
||||
{{ activity.owner_name }}
|
||||
</span>
|
||||
<span v-if="activity.type">{{ __(activity.type) }}</span>
|
||||
<span
|
||||
v-if="activity.data.field_label"
|
||||
class="max-w-xs truncate font-medium text-gray-800"
|
||||
class="max-w-xs truncate font-medium text-ink-gray-8"
|
||||
>
|
||||
{{ __(activity.data.field_label) }}
|
||||
</span>
|
||||
<span v-if="activity.value">{{ __(activity.value) }}</span>
|
||||
<span
|
||||
v-if="activity.data.old_value"
|
||||
class="max-w-xs font-medium text-gray-800"
|
||||
class="max-w-xs font-medium text-ink-gray-8"
|
||||
>
|
||||
<div
|
||||
class="flex items-center gap-1"
|
||||
@ -274,7 +274,7 @@
|
||||
<span v-if="activity.to">{{ __('to') }}</span>
|
||||
<span
|
||||
v-if="activity.data.value"
|
||||
class="max-w-xs font-medium text-gray-800"
|
||||
class="max-w-xs font-medium text-ink-gray-8"
|
||||
>
|
||||
<div
|
||||
class="flex items-center gap-1"
|
||||
@ -291,7 +291,7 @@
|
||||
|
||||
<div class="ml-auto whitespace-nowrap">
|
||||
<Tooltip :text="dateFormat(activity.creation, dateTooltipFormat)">
|
||||
<div class="text-sm text-gray-600">
|
||||
<div class="text-sm text-ink-gray-5">
|
||||
{{ __(timeAgo(activity.creation)) }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
@ -305,23 +305,23 @@
|
||||
v-for="activity in [activity, ...activity.other_versions]"
|
||||
class="flex items-start justify-stretch gap-2 py-1.5 text-base"
|
||||
>
|
||||
<div class="inline-flex flex-wrap gap-1 text-gray-600">
|
||||
<div class="inline-flex flex-wrap gap-1 text-ink-gray-5">
|
||||
<span
|
||||
v-if="activity.data.field_label"
|
||||
class="max-w-xs truncate text-gray-600"
|
||||
class="max-w-xs truncate text-ink-gray-5"
|
||||
>
|
||||
{{ __(activity.data.field_label) }}
|
||||
</span>
|
||||
<FeatherIcon
|
||||
name="arrow-right"
|
||||
class="mx-1 h-4 w-4 text-gray-600"
|
||||
class="mx-1 h-4 w-4 text-ink-gray-5"
|
||||
/>
|
||||
<span v-if="activity.type">
|
||||
{{ startCase(__(activity.type)) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="activity.data.old_value"
|
||||
class="max-w-xs font-medium text-gray-800"
|
||||
class="max-w-xs font-medium text-ink-gray-8"
|
||||
>
|
||||
<div
|
||||
class="flex items-center gap-1"
|
||||
@ -337,7 +337,7 @@
|
||||
<span v-if="activity.to">{{ __('to') }}</span>
|
||||
<span
|
||||
v-if="activity.data.value"
|
||||
class="max-w-xs font-medium text-gray-800"
|
||||
class="max-w-xs font-medium text-ink-gray-8"
|
||||
>
|
||||
<div
|
||||
class="flex items-center gap-1"
|
||||
@ -356,7 +356,7 @@
|
||||
<Tooltip
|
||||
:text="dateFormat(activity.creation, dateTooltipFormat)"
|
||||
>
|
||||
<div class="text-sm text-gray-600">
|
||||
<div class="text-sm text-ink-gray-5">
|
||||
{{ __(timeAgo(activity.creation)) }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
@ -368,7 +368,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="flex flex-1 flex-col items-center justify-center gap-3 text-xl font-medium text-gray-500"
|
||||
class="flex flex-1 flex-col items-center justify-center gap-3 text-xl font-medium text-ink-gray-4"
|
||||
>
|
||||
<component :is="emptyTextIcon" class="h-10 w-10" />
|
||||
<span>{{ __(emptyText) }}</span>
|
||||
@ -758,7 +758,7 @@ const emptyTextIcon = computed(() => {
|
||||
} else if (title.value == 'WhatsApp') {
|
||||
icon = WhatsAppIcon
|
||||
}
|
||||
return h(icon, { class: 'text-gray-500' })
|
||||
return h(icon, { class: 'text-ink-gray-4' })
|
||||
})
|
||||
|
||||
function timelineIcon(activity_type, is_lead) {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div
|
||||
class="mx-4 my-3 flex items-center justify-between text-lg font-medium sm:mx-10 sm:mb-4 sm:mt-8"
|
||||
>
|
||||
<div class="flex h-8 items-center text-xl font-semibold text-gray-800">
|
||||
<div class="flex h-8 items-center text-xl font-semibold text-ink-gray-8">
|
||||
{{ __(title) }}
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
<div v-if="attachments.length">
|
||||
<div v-for="(attachment, i) in attachments" :key="attachment.name">
|
||||
<div
|
||||
class="activity flex justify-between gap-2 hover:bg-gray-50 rounded text-base p-2.5 cursor-pointer"
|
||||
class="activity flex justify-between gap-2 hover:bg-surface-menu-bar rounded text-base p-2.5 cursor-pointer"
|
||||
@click="openFile(attachment)"
|
||||
>
|
||||
<div class="flex gap-2 truncate">
|
||||
<div
|
||||
class="size-11 bg-white rounded overflow-hidden flex-shrink-0 flex justify-center items-center"
|
||||
class="size-11 bg-surface-white rounded overflow-hidden flex-shrink-0 flex justify-center items-center"
|
||||
:class="{ border: !isImage(attachment.file_type) }"
|
||||
>
|
||||
<img
|
||||
@ -18,22 +18,22 @@
|
||||
/>
|
||||
<component
|
||||
v-else
|
||||
class="size-4"
|
||||
class="size-4 text-ink-gray-7"
|
||||
:is="fileIcon(attachment.file_type)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center gap-1 truncate">
|
||||
<div class="text-base text-gray-800 truncate">
|
||||
<div class="text-base text-ink-gray-8 truncate">
|
||||
{{ attachment.file_name }}
|
||||
</div>
|
||||
<div class="mb-1 text-sm text-gray-600">
|
||||
<div class="mb-1 text-sm text-ink-gray-5">
|
||||
{{ convertSize(attachment.file_size) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end gap-2 flex-shrink-0">
|
||||
<Tooltip :text="dateFormat(attachment.creation, dateTooltipFormat)">
|
||||
<div class="text-sm text-gray-600">
|
||||
<div class="text-sm text-ink-gray-5">
|
||||
{{ __(timeAgo(attachment.creation)) }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
@ -51,7 +51,7 @@
|
||||
>
|
||||
<FeatherIcon
|
||||
:name="attachment.is_private ? 'lock' : 'unlock'"
|
||||
class="size-3 text-gray-700"
|
||||
class="size-3 text-ink-gray-7"
|
||||
/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
@ -60,7 +60,7 @@
|
||||
class="!size-5"
|
||||
@click.stop="() => deleteAttachment(attachment.name)"
|
||||
>
|
||||
<FeatherIcon name="trash-2" class="size-3 text-gray-700" />
|
||||
<FeatherIcon name="trash-2" class="size-3 text-ink-gray-7" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@ -68,7 +68,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="i < attachments.length - 1"
|
||||
class="mx-2 h-px border-t border-gray-200"
|
||||
class="mx-2 h-px border-t border-outline-gray-modals"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="w-full text-sm text-gray-600">
|
||||
<div class="w-full text-sm text-ink-gray-5">
|
||||
<div class="flex items-center gap-2">
|
||||
<Button variant="ghost" @click="playPause">
|
||||
<template #icon>
|
||||
<PlayIcon v-if="isPaused" class="size-4 text-gray-600" />
|
||||
<PauseIcon v-else class="size-4 text-gray-600" />
|
||||
<PlayIcon v-if="isPaused" class="size-4 text-ink-gray-5" />
|
||||
<PauseIcon v-else class="size-4 text-ink-gray-5" />
|
||||
</template>
|
||||
</Button>
|
||||
<div class="flex gap-2 items-center justify-between flex-1">
|
||||
<input
|
||||
class="w-full slider !h-[0.5] bg-gray-200 [&::-webkit-slider-thumb]:shadow [&::-webkit-slider-thumb:hover]:outline [&::-webkit-slider-thumb:hover]:outline-[0.5px]"
|
||||
class="w-full slider !h-[0.5] bg-surface-gray-3 [&::-webkit-slider-thumb]:shadow [&::-webkit-slider-thumb:hover]:outline [&::-webkit-slider-thumb:hover]:outline-[0.5px]"
|
||||
:style="{
|
||||
background: `linear-gradient(to right, #171717 ${progress}%, #ededed ${progress}%)`,
|
||||
}"
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="mb-1 flex items-center justify-stretch gap-2 py-1 text-base">
|
||||
<div class="inline-flex items-center flex-wrap gap-1 text-gray-600">
|
||||
<div class="inline-flex items-center flex-wrap gap-1 text-ink-gray-5">
|
||||
<Avatar
|
||||
:image="activity.caller.image"
|
||||
:label="activity.caller.label"
|
||||
size="md"
|
||||
/>
|
||||
<span class="font-medium text-gray-800 ml-1">
|
||||
<span class="font-medium text-ink-gray-8 ml-1">
|
||||
{{ activity.caller.label }}
|
||||
</span>
|
||||
<span>{{
|
||||
@ -18,14 +18,14 @@
|
||||
</div>
|
||||
<div class="ml-auto whitespace-nowrap">
|
||||
<Tooltip :text="dateFormat(activity.creation, dateTooltipFormat)">
|
||||
<div class="text-sm text-gray-600">
|
||||
<div class="text-sm text-ink-gray-5">
|
||||
{{ __(timeAgo(activity.creation)) }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col gap-2 border border-gray-200 rounded-md bg-white px-3 py-2.5"
|
||||
class="flex flex-col gap-2 border border-outline-gray-modals rounded-md bg-surface-white px-3 py-2.5 text-ink-gray-9"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="inline-flex gap-2 items-center text-base font-medium">
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
<template>
|
||||
<div :id="activity.name">
|
||||
<div class="mb-1 flex items-center justify-stretch gap-2 py-1 text-base">
|
||||
<div class="inline-flex items-center flex-wrap gap-1 text-gray-600">
|
||||
<div class="inline-flex items-center flex-wrap gap-1 text-ink-gray-5">
|
||||
<UserAvatar class="mr-1" :user="activity.owner" size="md" />
|
||||
<span class="font-medium text-gray-800">
|
||||
<span class="font-medium text-ink-gray-8">
|
||||
{{ activity.owner_name }}
|
||||
</span>
|
||||
<span>{{ __('added a') }}</span>
|
||||
<span class="max-w-xs truncate font-medium text-gray-800">
|
||||
<span class="max-w-xs truncate font-medium text-ink-gray-8">
|
||||
{{ __('comment') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="ml-auto whitespace-nowrap">
|
||||
<Tooltip :text="dateFormat(activity.creation, dateTooltipFormat)">
|
||||
<div class="text-sm text-gray-600">
|
||||
<div class="text-sm text-ink-gray-5">
|
||||
{{ __(timeAgo(activity.creation)) }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="cursor-pointer rounded bg-gray-50 px-3 py-[7.5px] text-base leading-6 transition-all duration-300 ease-in-out"
|
||||
class="cursor-pointer rounded bg-surface-gray-1 px-3 py-[7.5px] text-base leading-6 transition-all duration-300 ease-in-out"
|
||||
>
|
||||
<div class="prose-f" v-html="activity.content" />
|
||||
<div v-if="activity.attachments.length" class="mt-2 flex flex-wrap gap-2">
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div
|
||||
class="cursor-pointer flex flex-col rounded-md shadow bg-white px-3 py-1.5 text-base transition-all duration-300 ease-in-out"
|
||||
class="cursor-pointer flex flex-col rounded-md shadow bg-surface-white px-3 py-1.5 text-base transition-all duration-300 ease-in-out"
|
||||
>
|
||||
<div class="-mb-0.5 flex items-center justify-between gap-2 truncate">
|
||||
<div class="-mb-0.5 flex items-center justify-between gap-2 truncate text-ink-gray-9">
|
||||
<div class="flex items-center gap-2 truncate">
|
||||
<span>{{ activity.data.sender_full_name }}</span>
|
||||
<span class="sm:flex hidden text-sm text-gray-600">
|
||||
<span class="sm:flex hidden text-sm text-ink-gray-5">
|
||||
{{ '<' + activity.data.sender + '>' }}
|
||||
</span>
|
||||
<Badge
|
||||
@ -23,7 +23,7 @@
|
||||
:theme="status.color"
|
||||
/>
|
||||
<Tooltip :text="dateFormat(activity.creation, dateTooltipFormat)">
|
||||
<div class="text-sm text-gray-600">
|
||||
<div class="text-sm text-ink-gray-5">
|
||||
{{ __(timeAgo(activity.creation)) }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
@ -32,7 +32,7 @@
|
||||
<div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-gray-700"
|
||||
class="text-ink-gray-7"
|
||||
@click="reply(activity.data)"
|
||||
>
|
||||
<template #icon>
|
||||
@ -45,7 +45,7 @@
|
||||
<div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="text-gray-700"
|
||||
class="text-ink-gray-7"
|
||||
@click="reply(activity.data, true)"
|
||||
>
|
||||
<template #icon>
|
||||
@ -57,24 +57,24 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1 text-base leading-5 text-gray-800">
|
||||
<div class="flex flex-col gap-1 text-base leading-5 text-ink-gray-8">
|
||||
<div>{{ activity.data.subject }}</div>
|
||||
<div>
|
||||
<span class="mr-1 text-gray-600"> {{ __('To') }}: </span>
|
||||
<span class="mr-1 text-ink-gray-5"> {{ __('To') }}: </span>
|
||||
<span>{{ activity.data.recipients }}</span>
|
||||
<span v-if="activity.data.cc">, </span>
|
||||
<span v-if="activity.data.cc" class="mr-1 text-gray-600">
|
||||
<span v-if="activity.data.cc" class="mr-1 text-ink-gray-5">
|
||||
{{ __('CC') }}:
|
||||
</span>
|
||||
<span v-if="activity.data.cc">{{ activity.data.cc }}</span>
|
||||
<span v-if="activity.data.bcc">, </span>
|
||||
<span v-if="activity.data.bcc" class="mr-1 text-gray-600">
|
||||
<span v-if="activity.data.bcc" class="mr-1 text-ink-gray-5">
|
||||
{{ __('BCC') }}:
|
||||
</span>
|
||||
<span v-if="activity.data.bcc">{{ activity.data.bcc }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-0 border-t mt-3 mb-1 border-gray-200" />
|
||||
<div class="border-0 border-t mt-3 mb-1 border-outline-gray-modals" />
|
||||
<EmailContent :content="activity.data.content" />
|
||||
<div v-if="activity.data?.attachments?.length" class="flex flex-wrap gap-2">
|
||||
<AttachmentItem
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="activity group flex h-48 cursor-pointer flex-col justify-between gap-2 rounded-md bg-gray-50 px-4 py-3 hover:bg-gray-100"
|
||||
class="activity group flex h-48 cursor-pointer flex-col justify-between gap-2 rounded-md bg-surface-menu-bar px-4 py-3 hover:bg-surface-gray-2"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="truncate text-lg font-medium">
|
||||
@ -20,7 +20,7 @@
|
||||
<Button
|
||||
icon="more-horizontal"
|
||||
variant="ghosted"
|
||||
class="!h-6 !w-6 hover:bg-gray-100"
|
||||
class="!h-6 !w-6 hover:bg-surface-gray-2"
|
||||
/>
|
||||
</Dropdown>
|
||||
</div>
|
||||
@ -28,21 +28,21 @@
|
||||
v-if="note.content"
|
||||
:content="note.content"
|
||||
:editable="false"
|
||||
editor-class="!prose-sm max-w-none !text-sm text-gray-600 focus:outline-none"
|
||||
editor-class="!prose-sm max-w-none !text-sm text-ink-gray-5 focus:outline-none"
|
||||
class="flex-1 overflow-hidden"
|
||||
/>
|
||||
<div class="mt-1 flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2 truncate">
|
||||
<UserAvatar :user="note.owner" size="xs" />
|
||||
<div
|
||||
class="truncate text-sm text-gray-800"
|
||||
class="truncate text-sm text-ink-gray-8"
|
||||
:title="getUser(note.owner).full_name"
|
||||
>
|
||||
{{ getUser(note.owner).full_name }}
|
||||
</div>
|
||||
</div>
|
||||
<Tooltip :text="dateFormat(note.modified, dateTooltipFormat)">
|
||||
<div class="truncate text-sm text-gray-700">
|
||||
<div class="truncate text-sm text-ink-gray-7">
|
||||
{{ __(timeAgo(note.modified)) }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
@ -2,20 +2,20 @@
|
||||
<div v-if="tasks.length">
|
||||
<div v-for="(task, i) in tasks" :key="task.name">
|
||||
<div
|
||||
class="activity flex cursor-pointer gap-6 rounded p-2.5 duration-300 ease-in-out hover:bg-gray-50"
|
||||
class="activity flex cursor-pointer gap-6 rounded p-2.5 duration-300 ease-in-out hover:bg-surface-gray-1"
|
||||
@click="modalRef.showTask(task)"
|
||||
>
|
||||
<div class="flex flex-1 flex-col gap-1.5 text-base truncate">
|
||||
<div class="font-medium text-gray-900 truncate">
|
||||
<div class="font-medium text-ink-gray-9 truncate">
|
||||
{{ task.title }}
|
||||
</div>
|
||||
<div class="flex gap-1.5 text-gray-800">
|
||||
<div class="flex gap-1.5 text-ink-gray-8">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<UserAvatar :user="task.assigned_to" size="xs" />
|
||||
{{ getUser(task.assigned_to).full_name }}
|
||||
</div>
|
||||
<div v-if="task.due_date" class="flex items-center justify-center">
|
||||
<DotIcon class="h-2.5 w-2.5 text-gray-600" :radius="2" />
|
||||
<DotIcon class="h-2.5 w-2.5 text-ink-gray-5" :radius="2" />
|
||||
</div>
|
||||
<div v-if="task.due_date">
|
||||
<Tooltip
|
||||
@ -28,7 +28,7 @@
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="flex items-center justify-center">
|
||||
<DotIcon class="h-2.5 w-2.5 text-gray-600" :radius="2" />
|
||||
<DotIcon class="h-2.5 w-2.5 text-ink-gray-5" :radius="2" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<TaskPriorityIcon class="!h-2 !w-2" :priority="task.priority" />
|
||||
@ -42,7 +42,7 @@
|
||||
@click.stop
|
||||
>
|
||||
<Tooltip :text="__('Change Status')">
|
||||
<Button variant="ghosted" class="hover:bg-gray-300">
|
||||
<Button variant="ghosted" class="hover:bg-surface-gray-4">
|
||||
<TaskStatusIcon :status="task.status" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
@ -76,14 +76,14 @@
|
||||
<Button
|
||||
icon="more-horizontal"
|
||||
variant="ghosted"
|
||||
class="hover:bg-gray-300"
|
||||
class="hover:bg-surface-gray-4 text-ink-gray-9"
|
||||
/>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="i < tasks.length - 1"
|
||||
class="mx-2 h-px border-t border-gray-200"
|
||||
class="mx-2 h-px border-t border-outline-gray-modals"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -11,12 +11,12 @@
|
||||
>
|
||||
<div
|
||||
:id="whatsapp.name"
|
||||
class="group/message relative max-w-[90%] rounded-md bg-gray-50 p-1.5 pl-2 text-base shadow-sm"
|
||||
class="group/message relative max-w-[90%] rounded-md bg-surface-gray-1 text-ink-gray-9 p-1.5 pl-2 text-base shadow-sm"
|
||||
>
|
||||
<div
|
||||
v-if="whatsapp.is_reply"
|
||||
@click="() => scrollToMessage(whatsapp.reply_to)"
|
||||
class="mb-1 cursor-pointer rounded border-0 border-l-4 bg-gray-200 p-2 text-gray-600"
|
||||
class="mb-1 cursor-pointer rounded border-0 border-l-4 bg-surface-gray-3 p-2 text-ink-gray-5"
|
||||
:class="
|
||||
whatsapp.reply_to_type == 'Incoming'
|
||||
? 'border-green-500'
|
||||
@ -27,8 +27,8 @@
|
||||
class="mb-1 text-sm font-bold"
|
||||
:class="
|
||||
whatsapp.reply_to_type == 'Incoming'
|
||||
? 'text-green-500'
|
||||
: 'text-blue-400'
|
||||
? 'text-ink-green-2'
|
||||
: 'text-ink-blue-link'
|
||||
"
|
||||
>
|
||||
{{ whatsapp.reply_to_from || __('You') }}
|
||||
@ -38,25 +38,25 @@
|
||||
{{ whatsapp.header }}
|
||||
</div>
|
||||
<div v-html="formatWhatsAppMessage(whatsapp.reply_message)" />
|
||||
<div v-if="whatsapp.footer" class="text-xs text-gray-600">
|
||||
<div v-if="whatsapp.footer" class="text-xs text-ink-gray-5">
|
||||
{{ whatsapp.footer }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2 justify-between">
|
||||
<div
|
||||
class="absolute -right-0.5 -top-0.5 flex cursor-pointer gap-1 rounded-full bg-white pb-2 pl-2 pr-1.5 pt-1.5 opacity-0 group-hover/message:opacity-100"
|
||||
class="absolute -right-0.5 -top-0.5 flex cursor-pointer gap-1 rounded-full bg-surface-white pb-2 pl-2 pr-1.5 pt-1.5 opacity-0 group-hover/message:opacity-100"
|
||||
:style="{
|
||||
background:
|
||||
'radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 35%, rgba(238, 130, 238, 0) 100%)',
|
||||
}"
|
||||
>
|
||||
<Dropdown :options="messageOptions(whatsapp)">
|
||||
<FeatherIcon name="chevron-down" class="size-4 text-gray-600" />
|
||||
<FeatherIcon name="chevron-down" class="size-4 text-ink-gray-5" />
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div
|
||||
class="absolute -bottom-5 flex gap-1 rounded-full border bg-white p-1 pb-[3px] shadow-sm"
|
||||
class="absolute -bottom-5 flex gap-1 rounded-full border bg-surface-white p-1 pb-[3px] shadow-sm"
|
||||
v-if="whatsapp.reaction"
|
||||
>
|
||||
<div class="flex size-4 items-center justify-center">
|
||||
@ -71,7 +71,7 @@
|
||||
{{ whatsapp.header }}
|
||||
</div>
|
||||
<div v-html="formatWhatsAppMessage(whatsapp.template)" />
|
||||
<div v-if="whatsapp.footer" class="text-xs text-gray-600">
|
||||
<div v-if="whatsapp.footer" class="text-xs text-ink-gray-5">
|
||||
{{ whatsapp.footer }}
|
||||
</div>
|
||||
</div>
|
||||
@ -100,10 +100,10 @@
|
||||
class="flex items-center gap-2"
|
||||
>
|
||||
<DocumentIcon
|
||||
class="size-10 cursor-pointer rounded-md text-gray-500"
|
||||
class="size-10 cursor-pointer rounded-md text-ink-gray-4"
|
||||
@click="() => openFileInAnotherTab(whatsapp.attach)"
|
||||
/>
|
||||
<div class="text-gray-600">Document</div>
|
||||
<div class="text-ink-gray-5">Document</div>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="whatsapp.content_type == 'audio'"
|
||||
@ -126,7 +126,7 @@
|
||||
v-html="formatWhatsAppMessage(whatsapp.message)"
|
||||
/>
|
||||
</div>
|
||||
<div class="-mb-1 flex shrink-0 items-end gap-1 text-gray-600">
|
||||
<div class="-mb-1 flex shrink-0 items-end gap-1 text-ink-gray-5">
|
||||
<Tooltip :text="dateFormat(whatsapp.creation, 'ddd, MMM D, YYYY')">
|
||||
<div class="text-2xs">
|
||||
{{ dateFormat(whatsapp.creation, 'hh:mm a') }}
|
||||
@ -140,7 +140,7 @@
|
||||
<DoubleCheckIcon
|
||||
v-else-if="['read', 'delivered'].includes(whatsapp.status)"
|
||||
class="size-4"
|
||||
:class="{ 'text-blue-500': whatsapp.status == 'read' }"
|
||||
:class="{ 'text-ink-blue-2': whatsapp.status == 'read' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -159,7 +159,7 @@
|
||||
@click="() => (reaction = true) && togglePopover()"
|
||||
class="rounded-full !size-6 mt-0.5"
|
||||
>
|
||||
<ReactIcon class="text-gray-400" />
|
||||
<ReactIcon class="text-ink-gray-3" />
|
||||
</Button>
|
||||
</IconPicker>
|
||||
</div>
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
class="flex items-center justify-around gap-2 px-3 pt-2 sm:px-10"
|
||||
>
|
||||
<div
|
||||
class="mb-1 ml-13 flex-1 cursor-pointer rounded border-0 border-l-4 border-green-500 bg-gray-100 p-2 text-base text-gray-600"
|
||||
class="mb-1 ml-13 flex-1 cursor-pointer rounded border-0 border-l-4 border-green-500 bg-surface-gray-2 p-2 text-base text-ink-gray-5"
|
||||
:class="reply.type == 'Incoming' ? 'border-green-500' : 'border-blue-400'"
|
||||
>
|
||||
<div
|
||||
class="mb-1 text-sm font-bold"
|
||||
:class="reply.type == 'Incoming' ? 'text-green-500' : 'text-blue-400'"
|
||||
:class="reply.type == 'Incoming' ? 'text-ink-green-2' : 'text-ink-blue-link'"
|
||||
>
|
||||
{{ reply.from_name || __('You') }}
|
||||
</div>
|
||||
@ -26,7 +26,7 @@
|
||||
<Dropdown :options="uploadOptions(openFileSelector)">
|
||||
<FeatherIcon
|
||||
name="plus"
|
||||
class="size-4.5 cursor-pointer text-gray-600"
|
||||
class="size-4.5 cursor-pointer text-ink-gray-5"
|
||||
/>
|
||||
</Dropdown>
|
||||
</div>
|
||||
@ -45,7 +45,7 @@
|
||||
>
|
||||
<SmileIcon
|
||||
@click="togglePopover"
|
||||
class="flex size-4.5 cursor-pointer rounded-sm text-xl leading-none text-gray-500"
|
||||
class="flex size-4.5 cursor-pointer rounded-sm text-xl leading-none text-ink-gray-4"
|
||||
/>
|
||||
</IconPicker>
|
||||
</div>
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
<template #target="{ togglePopover }">
|
||||
<button
|
||||
:class="[
|
||||
active ? 'bg-gray-100' : 'text-gray-800',
|
||||
'group w-full flex h-7 items-center justify-between rounded px-2 text-base hover:bg-gray-100',
|
||||
active ? 'bg-surface-gray-3' : 'text-ink-gray-6',
|
||||
'group w-full flex h-7 items-center justify-between rounded px-2 text-base hover:bg-surface-gray-2',
|
||||
]"
|
||||
@click.prevent="togglePopover()"
|
||||
>
|
||||
@ -14,20 +14,20 @@
|
||||
{{ __('Apps') }}
|
||||
</span>
|
||||
</div>
|
||||
<FeatherIcon name="chevron-right" class="size-4 text-gray-600" />
|
||||
<FeatherIcon name="chevron-right" class="size-4 text-ink-gray-5" />
|
||||
</button>
|
||||
</template>
|
||||
<template #body>
|
||||
<div
|
||||
class="grid grid-cols-3 justify-between mx-3 p-2 rounded-lg border border-gray-100 bg-white shadow-xl"
|
||||
class="grid grid-cols-3 justify-between mx-3 p-2 min-w-40 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
>
|
||||
<div v-for="app in apps.data" :key="app.name">
|
||||
<a
|
||||
:href="app.route"
|
||||
class="flex flex-col gap-1.5 rounded justify-center items-center py-2 px-1 hover:bg-gray-100"
|
||||
class="flex flex-col gap-1.5 rounded justify-center items-center py-2 px-1 hover:bg-surface-gray-2"
|
||||
>
|
||||
<img class="size-8" :src="app.logo" />
|
||||
<div class="text-sm text-gray-700" @click="app.onClick">
|
||||
<div class="text-sm text-ink-gray-7" @click="app.onClick">
|
||||
{{ app.title }}
|
||||
</div>
|
||||
</a>
|
||||
@ -39,8 +39,8 @@
|
||||
<script setup>
|
||||
import AppsIcon from '@/components/Icons/AppsIcon.vue'
|
||||
import { Popover, createResource } from 'frappe-ui'
|
||||
import { onUnmounted } from 'vue';
|
||||
import { stopRecording } from '@/telemetry';
|
||||
import { onUnmounted } from 'vue'
|
||||
import { stopRecording } from '@/telemetry'
|
||||
|
||||
const props = defineProps({
|
||||
active: Boolean,
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div v-show="showCallPopup" v-bind="$attrs">
|
||||
<div
|
||||
ref="callPopup"
|
||||
class="fixed z-20 flex w-60 cursor-move select-none flex-col rounded-lg bg-gray-900 p-4 text-gray-300 shadow-2xl"
|
||||
class="fixed z-20 flex w-60 cursor-move select-none flex-col rounded-lg bg-surface-gray-7 p-4 text-ink-gray-2 shadow-2xl"
|
||||
:style="style"
|
||||
>
|
||||
<div class="flex flex-row-reverse items-center gap-1">
|
||||
@ -22,7 +22,7 @@
|
||||
<div class="text-xl font-medium">
|
||||
{{ contact.full_name }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-600">{{ contact.mobile_no }}</div>
|
||||
<div class="text-sm text-ink-gray-5">{{ contact.mobile_no }}</div>
|
||||
</div>
|
||||
<CountUpTimer ref="counterUp">
|
||||
<div v-if="onCall" class="my-1 text-base">
|
||||
@ -54,15 +54,15 @@
|
||||
<Button class="rounded-full">
|
||||
<template #icon>
|
||||
<NoteIcon
|
||||
class="h-4 w-4 cursor-pointer rounded-full text-gray-900"
|
||||
class="h-4 w-4 cursor-pointer rounded-full text-ink-gray-9"
|
||||
@click="showNoteModal = true"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
<Button class="rounded-full bg-red-600 hover:bg-red-700">
|
||||
<Button class="rounded-full bg-surface-red-5 hover:bg-surface-red-6">
|
||||
<template #icon>
|
||||
<PhoneIcon
|
||||
class="h-4 w-4 rotate-[135deg] fill-white text-white"
|
||||
class="h-4 w-4 rotate-[135deg] fill-white text-ink-white"
|
||||
@click="hangUpCall"
|
||||
/>
|
||||
</template>
|
||||
@ -114,7 +114,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-show="showSmallCallWindow"
|
||||
class="ml-2 flex cursor-pointer select-none items-center justify-between gap-3 rounded-lg bg-gray-900 px-2 py-[7px] text-base text-gray-300"
|
||||
class="ml-2 flex cursor-pointer select-none items-center justify-between gap-3 rounded-lg bg-surface-gray-7 px-2 py-[7px] text-base text-ink-gray-2"
|
||||
@click="toggleCallWindow"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
</template>
|
||||
<template #body="{ close }">
|
||||
<div
|
||||
class="my-2 rounded-lg border border-gray-100 bg-white p-1.5 shadow-xl"
|
||||
class="my-2 p-1.5 min-w-40 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
>
|
||||
<div v-if="!edit">
|
||||
<Draggable
|
||||
@ -24,7 +24,7 @@
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div
|
||||
class="flex cursor-grab items-center justify-between gap-6 rounded px-2 py-1.5 text-base text-gray-800 hover:bg-gray-100"
|
||||
class="flex cursor-grab items-center justify-between gap-6 rounded px-2 py-1.5 text-base text-ink-gray-8 hover:bg-surface-gray-2"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<DragIcon class="h-3.5" />
|
||||
@ -49,7 +49,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
<div class="mt-1.5 flex flex-col gap-1 border-t pt-1.5">
|
||||
<div class="mt-1.5 flex flex-col gap-1 border-t border-outline-gray-modals pt-1.5">
|
||||
<Autocomplete
|
||||
value=""
|
||||
:options="fields"
|
||||
@ -57,7 +57,7 @@
|
||||
>
|
||||
<template #target="{ togglePopover }">
|
||||
<Button
|
||||
class="w-full !justify-start !text-gray-600"
|
||||
class="w-full !justify-start !text-ink-gray-5"
|
||||
variant="ghost"
|
||||
@click="togglePopover()"
|
||||
:label="__('Add Column')"
|
||||
@ -70,7 +70,7 @@
|
||||
</Autocomplete>
|
||||
<Button
|
||||
v-if="columnsUpdated"
|
||||
class="w-full !justify-start !text-gray-600"
|
||||
class="w-full !justify-start !text-ink-gray-5"
|
||||
variant="ghost"
|
||||
@click="reset(close)"
|
||||
:label="__('Reset Changes')"
|
||||
@ -81,7 +81,7 @@
|
||||
</Button>
|
||||
<Button
|
||||
v-if="!is_default"
|
||||
class="w-full !justify-start !text-gray-600"
|
||||
class="w-full !justify-start !text-ink-gray-5"
|
||||
variant="ghost"
|
||||
@click="resetToDefault(close)"
|
||||
:label="__('Reset to Default')"
|
||||
@ -94,7 +94,7 @@
|
||||
</div>
|
||||
<div v-else>
|
||||
<div
|
||||
class="flex flex-col items-center justify-between gap-2 rounded px-2 py-1.5 text-base text-gray-800"
|
||||
class="flex flex-col items-center justify-between gap-2 rounded px-2 py-1.5 text-base text-ink-gray-8"
|
||||
>
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
<FormControl
|
||||
@ -114,7 +114,7 @@
|
||||
placeholder="10rem"
|
||||
:description="
|
||||
__(
|
||||
'Width can be in number, pixel or rem (eg. 3, 30px, 10rem)'
|
||||
'Width can be in number, pixel or rem (eg. 3, 30px, 10rem)',
|
||||
)
|
||||
"
|
||||
:debounce="500"
|
||||
@ -295,6 +295,6 @@ watchOnce(
|
||||
oldValues.value.columns = JSON.parse(JSON.stringify(val.columns))
|
||||
oldValues.value.rows = JSON.parse(JSON.stringify(val.rows))
|
||||
oldValues.value.isDefault = val.is_default
|
||||
}
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<Button
|
||||
ref="sendEmailRef"
|
||||
variant="ghost"
|
||||
:class="[showEmailBox ? '!bg-gray-300 hover:!bg-gray-200' : '']"
|
||||
:class="[showEmailBox ? '!bg-surface-gray-4 hover:!bg-surface-gray-3' : '']"
|
||||
:label="__('Reply')"
|
||||
@click="toggleEmailBox()"
|
||||
>
|
||||
@ -15,7 +15,7 @@
|
||||
<Button
|
||||
variant="ghost"
|
||||
:label="__('Comment')"
|
||||
:class="[showCommentBox ? '!bg-gray-300 hover:!bg-gray-200' : '']"
|
||||
:class="[showCommentBox ? '!bg-surface-gray-4 hover:!bg-surface-gray-3' : '']"
|
||||
@click="toggleCommentBox()"
|
||||
>
|
||||
<template #prefix>
|
||||
|
||||
@ -174,7 +174,7 @@ const labelClasses = computed(() => {
|
||||
sm: 'text-xs',
|
||||
md: 'text-base',
|
||||
}[attrs.size || 'sm'],
|
||||
'text-gray-600',
|
||||
'text-ink-gray-5',
|
||||
]
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="flex flex-wrap gap-1 min-h-20 p-1.5 cursor-text rounded h-7 text-base border border-gray-300 bg-white hover:border-gray-400 focus:border-gray-500 focus:ring-0 focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-800 transition-colors w-full"
|
||||
class="group flex flex-wrap gap-1 min-h-20 p-1.5 cursor-text rounded h-7 text-base bg-surface-gray-2 hover:bg-surface-gray-3 focus:border-outline-gray-4 focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors w-full"
|
||||
@click="setFocus"
|
||||
>
|
||||
<Button
|
||||
@ -11,7 +11,7 @@
|
||||
:label="value"
|
||||
theme="gray"
|
||||
variant="subtle"
|
||||
class="rounded"
|
||||
class="rounded bg-surface-gray-3 group-hover:bg-surface-gray-4 focus-visible:ring-outline-gray-4"
|
||||
@keydown.delete.capture.stop="removeLastValue"
|
||||
>
|
||||
<template #suffix>
|
||||
@ -23,9 +23,9 @@
|
||||
</template>
|
||||
</Button>
|
||||
<div class="flex-1">
|
||||
<TextInput
|
||||
<input
|
||||
ref="search"
|
||||
class="w-full border-none bg-white hover:bg-white focus:border-none focus:!shadow-none focus-visible:!ring-0"
|
||||
class="w-full border-none h-7 text-base bg-surface-gray-2 group-hover:bg-surface-gray-3 focus:border-none focus:!shadow-none focus-visible:!ring-0 transition-colors"
|
||||
type="text"
|
||||
v-model="query"
|
||||
placeholder="example@email.com"
|
||||
@ -113,7 +113,7 @@ const removeLastValue = () => {
|
||||
}
|
||||
|
||||
function setFocus() {
|
||||
search.value.el.focus()
|
||||
search.value.focus()
|
||||
}
|
||||
|
||||
defineExpose({ setFocus })
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
<template #target="{ togglePopover }">
|
||||
<ComboboxInput
|
||||
ref="search"
|
||||
class="search-input form-input w-full border-none bg-white hover:bg-white focus:border-none focus:!shadow-none focus-visible:!ring-0"
|
||||
class="search-input form-input w-full border-none bg-surface-white hover:bg-surface-white focus:border-none focus:!shadow-none focus-visible:!ring-0"
|
||||
type="text"
|
||||
:value="query"
|
||||
@change="
|
||||
@ -41,9 +41,11 @@
|
||||
</template>
|
||||
<template #body="{ isOpen }">
|
||||
<div v-show="isOpen">
|
||||
<div class="mt-1 rounded-lg bg-white py-1 text-base shadow-2xl">
|
||||
<div
|
||||
class="mt-1 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
>
|
||||
<ComboboxOptions
|
||||
class="my-1 max-h-[12rem] overflow-y-auto px-1.5"
|
||||
class="p-1.5 max-h-[12rem] overflow-y-auto"
|
||||
static
|
||||
>
|
||||
<ComboboxOption
|
||||
@ -55,7 +57,7 @@
|
||||
<li
|
||||
:class="[
|
||||
'flex cursor-pointer items-center rounded px-2 py-1 text-base',
|
||||
{ 'bg-gray-100': active },
|
||||
{ 'bg-surface-gray-3': active },
|
||||
]"
|
||||
>
|
||||
<UserAvatar
|
||||
@ -63,11 +65,11 @@
|
||||
:user="option.value"
|
||||
size="lg"
|
||||
/>
|
||||
<div class="flex flex-col gap-1 p-1 text-gray-800">
|
||||
<div class="flex flex-col gap-1 p-1 text-ink-gray-8">
|
||||
<div class="text-base font-medium">
|
||||
{{ option.label }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-600">
|
||||
<div class="text-sm text-ink-gray-5">
|
||||
{{ option.value }}
|
||||
</div>
|
||||
</div>
|
||||
@ -146,16 +148,15 @@ const filterOptions = createResource({
|
||||
cache: [text.value, 'Contact'],
|
||||
params: { txt: text.value },
|
||||
transform: (data) => {
|
||||
let allData = data
|
||||
.map((option) => {
|
||||
let fullName = option[0]
|
||||
let email = option[1]
|
||||
let name = option[2]
|
||||
return {
|
||||
label: fullName || name || email,
|
||||
value: email,
|
||||
}
|
||||
})
|
||||
let allData = data.map((option) => {
|
||||
let fullName = option[0]
|
||||
let email = option[1]
|
||||
let name = option[2]
|
||||
return {
|
||||
label: fullName || name || email,
|
||||
value: email,
|
||||
}
|
||||
})
|
||||
return allData
|
||||
},
|
||||
})
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="group flex w-full items-center justify-between rounded bg-transparent p-1 pl-2 text-base text-gray-800 transition-colors hover:bg-gray-200 active:bg-gray-300"
|
||||
class="group flex w-full items-center justify-between rounded bg-transparent p-1 pl-2 text-base text-ink-gray-8 transition-colors hover:bg-surface-gray-3 active:bg-surface-gray-4"
|
||||
>
|
||||
<div class="flex flex-1 items-center justify-between gap-7">
|
||||
<div v-show="!editMode">{{ option.value }}</div>
|
||||
@ -20,7 +20,7 @@
|
||||
variant="ghost"
|
||||
:label="__('Save')"
|
||||
size="sm"
|
||||
class="opacity-0 hover:bg-gray-300 group-hover:opacity-100"
|
||||
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
|
||||
@click="saveOption"
|
||||
/>
|
||||
<Tooltip text="Set As Primary" v-if="!isNew && !option.selected">
|
||||
@ -28,7 +28,7 @@
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="opacity-0 hover:bg-gray-300 group-hover:opacity-100"
|
||||
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
|
||||
@click="option.onClick"
|
||||
>
|
||||
<SuccessIcon />
|
||||
@ -40,7 +40,7 @@
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="opacity-0 hover:bg-gray-300 group-hover:opacity-100"
|
||||
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
|
||||
@click="toggleEditMode"
|
||||
>
|
||||
<EditIcon />
|
||||
@ -53,7 +53,7 @@
|
||||
variant="ghost"
|
||||
icon="x"
|
||||
size="sm"
|
||||
class="opacity-0 hover:bg-gray-300 group-hover:opacity-100"
|
||||
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
|
||||
@click="() => option.onDelete(option, isNew)"
|
||||
/>
|
||||
</div>
|
||||
@ -61,7 +61,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="option.selected">
|
||||
<FeatherIcon name="check" class="text-primary-500 h-4 w-6" size="sm" />
|
||||
<FeatherIcon name="check" class="text-ink-gray-5 h-4 w-6" size="sm" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
<template #top>
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="sm:mx-10 mx-4 flex items-center gap-2 border-t pt-2.5">
|
||||
<span class="text-xs text-gray-500">{{ __('TO') }}:</span>
|
||||
<span class="text-xs text-ink-gray-4">{{ __('TO') }}:</span>
|
||||
<MultiselectInput
|
||||
class="flex-1"
|
||||
v-model="toEmails"
|
||||
@ -34,7 +34,9 @@
|
||||
variant="ghost"
|
||||
@click="toggleCC()"
|
||||
:class="[
|
||||
cc ? '!bg-gray-300 hover:bg-gray-200' : '!text-gray-500',
|
||||
cc
|
||||
? '!bg-surface-gray-4 hover:bg-surface-gray-3'
|
||||
: '!text-ink-gray-4',
|
||||
]"
|
||||
/>
|
||||
<Button
|
||||
@ -42,13 +44,15 @@
|
||||
variant="ghost"
|
||||
@click="toggleBCC()"
|
||||
:class="[
|
||||
bcc ? '!bg-gray-300 hover:bg-gray-200' : '!text-gray-500',
|
||||
bcc
|
||||
? '!bg-surface-gray-4 hover:bg-surface-gray-3'
|
||||
: '!text-ink-gray-4',
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="cc" class="sm:mx-10 mx-4 flex items-center gap-2">
|
||||
<span class="text-xs text-gray-500">{{ __('CC') }}:</span>
|
||||
<span class="text-xs text-ink-gray-4">{{ __('CC') }}:</span>
|
||||
<MultiselectInput
|
||||
ref="ccInput"
|
||||
class="flex-1"
|
||||
@ -60,7 +64,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div v-if="bcc" class="sm:mx-10 mx-4 flex items-center gap-2">
|
||||
<span class="text-xs text-gray-500">{{ __('BCC') }}:</span>
|
||||
<span class="text-xs text-ink-gray-4">{{ __('BCC') }}:</span>
|
||||
<MultiselectInput
|
||||
ref="bccInput"
|
||||
class="flex-1"
|
||||
@ -72,9 +76,9 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="sm:mx-10 mx-4 flex items-center gap-2 pb-2.5">
|
||||
<span class="text-xs text-gray-500">{{ __('SUBJECT') }}:</span>
|
||||
<TextInput
|
||||
class="flex-1 border-none bg-white hover:bg-white focus:border-none focus:!shadow-none focus-visible:!ring-0"
|
||||
<span class="text-xs text-ink-gray-4">{{ __('SUBJECT') }}:</span>
|
||||
<input
|
||||
class="flex-1 border-none text-ink-gray-9 text-base bg-surface-white hover:bg-surface-white focus:border-none focus:!shadow-none focus-visible:!ring-0"
|
||||
v-model="subject"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<div
|
||||
v-for="section in sections"
|
||||
:key="section.label"
|
||||
class="section first:border-t-0 first:pt-0"
|
||||
class="section first:border-t-0 border-outline-gray-modals first:pt-0"
|
||||
:class="section.hideBorder ? '' : 'border-t pt-4'"
|
||||
>
|
||||
<div
|
||||
@ -33,11 +33,11 @@
|
||||
>
|
||||
<div
|
||||
v-if="field.type != 'Check'"
|
||||
class="mb-2 text-sm text-gray-600"
|
||||
class="mb-2 text-sm text-ink-gray-5"
|
||||
>
|
||||
{{ __(field.label) }}
|
||||
<span
|
||||
class="text-red-500"
|
||||
class="text-ink-red-3"
|
||||
v-if="
|
||||
field.mandatory ||
|
||||
(field.mandatory_depends_on && field.mandatory_via_depends_on)
|
||||
@ -77,11 +77,11 @@
|
||||
:disabled="Boolean(field.read_only)"
|
||||
/>
|
||||
<label
|
||||
class="text-sm text-gray-600"
|
||||
class="text-sm text-ink-gray-5"
|
||||
@click="data[field.name] = !data[field.name]"
|
||||
>
|
||||
{{ __(field.label) }}
|
||||
<span class="text-red-500" v-if="field.mandatory">*</span>
|
||||
<span class="text-ink-red-3" v-if="field.mandatory">*</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex gap-1" v-else-if="field.type === 'Link'">
|
||||
|
||||
@ -169,7 +169,7 @@ function uploadViaWebLink() {
|
||||
title: __('Error'),
|
||||
title: __('Please enter a valid URL'),
|
||||
icon: 'x',
|
||||
iconClasses: 'text-red-600',
|
||||
iconClasses: 'text-ink-red-4',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@ -13,14 +13,14 @@
|
||||
</div>
|
||||
<div v-else>
|
||||
<div
|
||||
class="flex flex-col items-center justify-center gap-4 rounded-lg border border-dashed min-h-64 text-gray-600"
|
||||
class="flex flex-col items-center justify-center gap-4 rounded-lg border border-dashed min-h-64 text-ink-gray-5"
|
||||
@dragover.prevent="dragover"
|
||||
@dragleave.prevent="dragleave"
|
||||
@drop.prevent="dropfiles"
|
||||
v-show="files.length === 0"
|
||||
>
|
||||
<div v-if="!isDragging" class="flex flex-col gap-3">
|
||||
<div class="text-center text-gray-600">
|
||||
<div class="text-center text-ink-gray-5">
|
||||
{{ __('Drag and drop files here or upload from') }}
|
||||
</div>
|
||||
<div
|
||||
@ -75,8 +75,8 @@
|
||||
/>
|
||||
<component v-else class="size-4" :is="fileIcon(file.type)" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-1 text-sm text-gray-600 truncate">
|
||||
<div class="text-base text-gray-800 truncate">
|
||||
<div class="flex flex-col gap-1 text-sm text-ink-gray-5 truncate">
|
||||
<div class="text-base text-ink-gray-8 truncate">
|
||||
{{ file.name }}
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
@ -85,7 +85,7 @@
|
||||
<FormControl
|
||||
v-model="file.private"
|
||||
type="checkbox"
|
||||
class="[&>label]:text-sm [&>label]:text-gray-600"
|
||||
class="[&>label]:text-sm [&>label]:text-ink-gray-5"
|
||||
:label="__('Private')"
|
||||
/>
|
||||
<ErrorMessage
|
||||
@ -99,7 +99,7 @@
|
||||
<CircularProgressBar
|
||||
v-if="file.uploading || file.uploaded == file.total"
|
||||
:class="{
|
||||
'text-green-500': file.uploaded == file.total,
|
||||
'text-ink-green-2': file.uploaded == file.total,
|
||||
}"
|
||||
:theme="{
|
||||
primary: '#22C55E',
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<template #prefix><FilterIcon class="h-4" /></template>
|
||||
<template v-if="filters?.size" #suffix>
|
||||
<div
|
||||
class="flex h-5 w-5 items-center justify-center rounded bg-gray-900 pt-[1px] text-2xs font-medium text-white"
|
||||
class="flex h-5 w-5 items-center justify-center rounded-[5px] bg-surface-white pt-px text-xs font-medium text-ink-gray-8 shadow-sm"
|
||||
>
|
||||
{{ filters.size }}
|
||||
</div>
|
||||
@ -27,7 +27,9 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #body="{ close }">
|
||||
<div class="my-2 rounded-lg border border-gray-100 bg-white shadow-xl">
|
||||
<div
|
||||
class="my-2 min-w-40 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
>
|
||||
<div class="min-w-72 p-2 sm:min-w-[400px]">
|
||||
<div
|
||||
v-if="filters?.size"
|
||||
@ -38,7 +40,7 @@
|
||||
>
|
||||
<div v-if="isMobileView" class="flex flex-col gap-2">
|
||||
<div class="-mb-2 flex w-full items-center justify-between">
|
||||
<div class="text-base text-gray-600">
|
||||
<div class="text-base text-ink-gray-5">
|
||||
{{ i == 0 ? __('Where') : __('And') }}
|
||||
</div>
|
||||
<Button
|
||||
@ -76,7 +78,7 @@
|
||||
</div>
|
||||
<div v-else class="flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-13 pl-2 text-end text-base text-gray-600">
|
||||
<div class="w-13 pl-2 text-end text-base text-ink-gray-5">
|
||||
{{ i == 0 ? __('Where') : __('And') }}
|
||||
</div>
|
||||
<div id="fieldname" class="!min-w-[140px]">
|
||||
@ -117,7 +119,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="mb-3 flex h-7 items-center px-3 text-sm text-gray-600"
|
||||
class="mb-3 flex h-7 items-center px-3 text-sm text-ink-gray-5"
|
||||
>
|
||||
{{ __('Empty - Choose a field to filter by') }}
|
||||
</div>
|
||||
@ -130,7 +132,7 @@
|
||||
>
|
||||
<template #target="{ togglePopover }">
|
||||
<Button
|
||||
class="!text-gray-600"
|
||||
class="!text-ink-gray-5"
|
||||
variant="ghost"
|
||||
@click="togglePopover()"
|
||||
:label="__('Add Filter')"
|
||||
@ -143,7 +145,7 @@
|
||||
</Autocomplete>
|
||||
<Button
|
||||
v-if="filters?.size"
|
||||
class="!text-gray-600"
|
||||
class="!text-ink-gray-5"
|
||||
variant="ghost"
|
||||
:label="__('Clear all Filter')"
|
||||
@click="clearfilter(close)"
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
<template #body="{ togglePopover }">
|
||||
<div
|
||||
v-if="reaction"
|
||||
class="flex items-center justify-center gap-2 rounded-full bg-white px-2 py-1 shadow-sm"
|
||||
class="px-2 py-1 flex items-center justify-center gap-2 rounded-full bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
>
|
||||
<div
|
||||
class="size-5 cursor-pointer rounded-full bg-white text-xl"
|
||||
class="size-5 cursor-pointer rounded-full bg-surface-transparent text-xl"
|
||||
v-for="r in reactionEmojis"
|
||||
:key="r"
|
||||
@click="() => (emoji = r) && togglePopover()"
|
||||
@ -26,9 +26,12 @@
|
||||
@click.stop="() => (reaction = false)"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="my-3 max-w-max transform bg-white px-4 sm:px-0">
|
||||
<div
|
||||
v-else
|
||||
class="my-3 max-w-max transform bg-surface-white px-4 sm:px-0"
|
||||
>
|
||||
<div
|
||||
class="relative max-h-96 overflow-y-auto rounded-lg pb-3 shadow-2xl ring-1 ring-black ring-opacity-5"
|
||||
class="relative max-h-96 pb-3 overflow-y-auto min-w-40 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
>
|
||||
<div class="flex gap-2 px-3 pb-1 pt-3">
|
||||
<div class="flex-1">
|
||||
@ -43,12 +46,14 @@
|
||||
</div>
|
||||
<div class="w-96"></div>
|
||||
<div class="px-3" v-for="(emojis, group) in emojiGroups" :key="group">
|
||||
<div class="sticky top-0 bg-white pb-2 pt-3 text-sm text-gray-700">
|
||||
<div
|
||||
class="sticky top-0 bg-surface-modal pb-2 pt-3 text-sm text-ink-gray-7"
|
||||
>
|
||||
{{ group }}
|
||||
</div>
|
||||
<div class="grid w-96 grid-cols-12 place-items-center">
|
||||
<button
|
||||
class="h-8 w-8 rounded-md p-1 text-2xl hover:bg-gray-100 focus:outline-none focus:ring focus:ring-blue-200"
|
||||
class="h-8 w-8 rounded-md p-1 text-2xl hover:bg-surface-gray-2 focus:outline-none focus:ring focus:ring-blue-200"
|
||||
v-for="_emoji in emojis"
|
||||
:key="_emoji.description"
|
||||
@click="() => (emoji = _emoji.emoji) && togglePopover()"
|
||||
|
||||
@ -1,31 +1,16 @@
|
||||
<template>
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M2 4.5H14"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M4 8.5H12"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M6.5 12.5H9.5"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M2 4.16675C1.72386 4.16675 1.5 4.39061 1.5 4.66675C1.5 4.94289 1.72386 5.16675 2 5.16675H14C14.2761 5.16675 14.5 4.94289 14.5 4.66675C14.5 4.39061 14.2761 4.16675 14 4.16675H2ZM3.49996 7.99761C3.49996 7.72147 3.72382 7.49761 3.99996 7.49761H12C12.2761 7.49761 12.5 7.72147 12.5 7.99761C12.5 8.27375 12.2761 8.49761 12 8.49761H3.99996C3.72382 8.49761 3.49996 8.27375 3.49996 7.99761ZM5.9 11.3289C5.9 11.0527 6.12386 10.8289 6.4 10.8289H9.6C9.87614 10.8289 10.1 11.0527 10.1 11.3289C10.1 11.605 9.87614 11.8289 9.6 11.8289H6.4C6.12386 11.8289 5.9 11.605 5.9 11.3289Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
@ -1,45 +1,16 @@
|
||||
<template>
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1.75 3.75H10.75"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M1.75 7.75H7.75"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M1.75 11.75H5.75"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M14.25 8.25L12.25 6.25L10.25 8.25"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M12.25 12.25L12.25 6.25"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M5.5 3.5C5.5 3.22386 5.27614 3 5 3C4.72386 3 4.5 3.22386 4.5 3.5V11.2931L2.87846 9.67159C2.68319 9.47633 2.36661 9.47633 2.17135 9.67159C1.97609 9.86686 1.97609 10.1834 2.17135 10.3787L4.64622 12.8536C4.75097 12.9583 4.89063 13.0069 5.02774 12.9992C5.15903 12.9921 5.27684 12.9342 5.36195 12.845L7.8282 10.3787C8.02347 10.1834 8.02347 9.86686 7.8282 9.67159C7.63294 9.47633 7.31636 9.47633 7.1211 9.67159L5.5 11.2927V3.5ZM11.3698 3.16295C11.2784 3.06282 11.1468 3 11.0005 3C10.9947 3 10.989 3.0001 10.9832 3.00029C10.8608 3.00432 10.7396 3.05304 10.6462 3.14647L8.17135 5.62134C7.97609 5.8166 7.97609 6.13319 8.17135 6.32845C8.36661 6.52371 8.68319 6.52371 8.87846 6.32845L10.5005 4.70641V12.5C10.5005 12.7761 10.7243 13 11.0005 13C11.2766 13 11.5005 12.7761 11.5005 12.5V4.70784L13.1211 6.32845C13.3164 6.52371 13.6329 6.52371 13.8282 6.32845C14.0235 6.13319 14.0235 5.8166 13.8282 5.62134L11.3698 3.16295Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
:class="{
|
||||
'bg-red-500': priority === 'High',
|
||||
'bg-yellow-500': priority === 'Medium',
|
||||
'bg-gray-300': priority === 'Low',
|
||||
'bg-surface-gray-4': priority === 'Low',
|
||||
}, $attrs.class"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
class="text-gray-700"
|
||||
class="text-ink-gray-7"
|
||||
:aria-label="status"
|
||||
>
|
||||
<path
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
rx="1"
|
||||
transform="rotate(-45 0.792893 0)"
|
||||
fill="currentColor"
|
||||
stroke="white"
|
||||
class="stroke stroke-ink-white"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
@ -11,7 +11,9 @@
|
||||
<Dialog v-model="showDialog" :options="{ title: __('Kanban Settings') }">
|
||||
<template #body-content>
|
||||
<div>
|
||||
<div class="text-base text-gray-800 mb-2">{{ __('Column Field') }}</div>
|
||||
<div class="text-base text-ink-gray-8 mb-2">
|
||||
{{ __('Column Field') }}
|
||||
</div>
|
||||
<Autocomplete
|
||||
v-if="columnFields"
|
||||
value=""
|
||||
@ -21,13 +23,12 @@
|
||||
<template #target="{ togglePopover }">
|
||||
<Button
|
||||
class="w-full !justify-start"
|
||||
variant="subtle"
|
||||
@click="togglePopover()"
|
||||
:label="columnField.label"
|
||||
/>
|
||||
</template>
|
||||
</Autocomplete>
|
||||
<div class="text-base text-gray-800 mb-2 mt-4">
|
||||
<div class="text-base text-ink-gray-8 mb-2 mt-4">
|
||||
{{ __('Title Field') }}
|
||||
</div>
|
||||
<Autocomplete
|
||||
@ -39,7 +40,6 @@
|
||||
<template #target="{ togglePopover }">
|
||||
<Button
|
||||
class="w-full !justify-start"
|
||||
variant="subtle"
|
||||
@click="togglePopover()"
|
||||
:label="titleField.label"
|
||||
/>
|
||||
@ -47,7 +47,9 @@
|
||||
</Autocomplete>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<div class="text-base text-gray-800 mb-2">{{ __('Fields Order') }}</div>
|
||||
<div class="text-base text-ink-gray-8 mb-2">
|
||||
{{ __('Fields Order') }}
|
||||
</div>
|
||||
<Draggable
|
||||
:list="allFields"
|
||||
@end="reorder"
|
||||
@ -57,7 +59,7 @@
|
||||
>
|
||||
<template #item="{ element: field }">
|
||||
<div
|
||||
class="px-1 py-0.5 border rounded text-base text-gray-800 flex items-center justify-between gap-2"
|
||||
class="px-1 py-0.5 border border-outline-gray-modals rounded text-base text-ink-gray-8 flex items-center justify-between gap-2"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<DragVerticalIcon class="h-3.5 cursor-grab" />
|
||||
@ -78,7 +80,6 @@
|
||||
<template #target="{ togglePopover }">
|
||||
<Button
|
||||
class="w-full mt-2"
|
||||
variant="outline"
|
||||
@click="togglePopover()"
|
||||
:label="__('Add Field')"
|
||||
>
|
||||
@ -90,7 +91,7 @@
|
||||
<template #item-label="{ option }">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div>{{ option.label }}</div>
|
||||
<div class="text-gray-500 text-sm">
|
||||
<div class="text-ink-gray-4 text-sm">
|
||||
{{ `${option.fieldname} - ${option.fieldtype}` }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -11,13 +11,17 @@
|
||||
<template #item="{ element: column }">
|
||||
<div
|
||||
v-if="!column.column.delete"
|
||||
class="flex flex-col gap-2.5 min-w-72 w-72 hover:bg-gray-100 rounded-lg p-2.5"
|
||||
class="flex flex-col gap-2.5 min-w-72 w-72 hover:bg-surface-gray-2 rounded-lg p-2.5"
|
||||
>
|
||||
<div class="flex gap-2 items-center group justify-between">
|
||||
<div class="flex items-center text-base">
|
||||
<NestedPopover>
|
||||
<template #target>
|
||||
<Button variant="ghost" size="sm" class="hover:!bg-gray-100">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="hover:!bg-surface-gray-2"
|
||||
>
|
||||
<IndicatorIcon
|
||||
:class="colorClasses(column.column.color, true)"
|
||||
/>
|
||||
@ -25,7 +29,7 @@
|
||||
</template>
|
||||
<template #body="{ close }">
|
||||
<div
|
||||
class="flex flex-col gap-3 px-3 py-2.5 rounded-lg border border-gray-100 bg-white shadow-xl"
|
||||
class="flex flex-col gap-3 px-3 py-2.5 min-w-40 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
>
|
||||
<div class="flex gap-1">
|
||||
<Button
|
||||
@ -48,7 +52,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</NestedPopover>
|
||||
<div>{{ column.column.name }}</div>
|
||||
<div class="text-ink-gray-9">{{ column.column.name }}</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<Dropdown :options="actions(column)">
|
||||
@ -80,7 +84,7 @@
|
||||
<template #item="{ element: fields }">
|
||||
<component
|
||||
:is="options.getRoute ? 'router-link' : 'div'"
|
||||
class="pt-3 px-3.5 pb-2.5 rounded-lg border bg-white text-base flex flex-col"
|
||||
class="pt-3 px-3.5 pb-2.5 rounded-lg border bg-surface-white text-base flex flex-col text-ink-gray-9"
|
||||
:data-name="fields.name"
|
||||
v-bind="{
|
||||
to: options.getRoute ? options.getRoute(fields) : undefined,
|
||||
@ -97,7 +101,7 @@
|
||||
<div v-if="fields[titleField]">
|
||||
{{ fields[titleField] }}
|
||||
</div>
|
||||
<div class="text-gray-500" v-else>
|
||||
<div class="text-ink-gray-4" v-else>
|
||||
{{ __('No Title') }}
|
||||
</div>
|
||||
</div>
|
||||
@ -265,7 +269,7 @@ function updateColumn(d) {
|
||||
function colorClasses(color, onlyIcon = false) {
|
||||
let textColor = `!text-${color}-600`
|
||||
if (color == 'black') {
|
||||
textColor = '!text-gray-900'
|
||||
textColor = '!text-ink-gray-9'
|
||||
} else if (['gray', 'green'].includes(color)) {
|
||||
textColor = `!text-${color}-700`
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
/>
|
||||
<div
|
||||
v-else-if="unreadNotificationsCount"
|
||||
class="absolute -left-1.5 top-1 z-20 h-[5px] w-[5px] translate-x-6 translate-y-1 rounded-full bg-gray-800 ring-1 ring-white"
|
||||
class="absolute -left-1.5 top-1 z-20 h-[5px] w-[5px] translate-x-6 translate-y-1 rounded-full bg-surface-gray-6 ring-1 ring-white"
|
||||
/>
|
||||
</template>
|
||||
</SidebarLink>
|
||||
@ -42,7 +42,7 @@
|
||||
<template #header="{ opened, hide, toggle }">
|
||||
<div
|
||||
v-if="!hide"
|
||||
class="flex cursor-pointer gap-1.5 px-1 text-base font-medium text-gray-600 transition-all duration-300 ease-in-out"
|
||||
class="flex cursor-pointer gap-1.5 px-1 text-base font-medium text-ink-gray-5 transition-all duration-300 ease-in-out"
|
||||
:class="
|
||||
isSidebarCollapsed
|
||||
? 'ml-0 h-0 overflow-hidden opacity-0'
|
||||
@ -52,7 +52,7 @@
|
||||
>
|
||||
<FeatherIcon
|
||||
name="chevron-right"
|
||||
class="h-4 text-gray-900 transition-all duration-300 ease-in-out"
|
||||
class="h-4 text-ink-gray-9 transition-all duration-300 ease-in-out"
|
||||
:class="{ 'rotate-90': opened }"
|
||||
/>
|
||||
<span>{{ __(view.name) }}</span>
|
||||
@ -82,7 +82,7 @@
|
||||
<template #icon>
|
||||
<span class="grid h-4.5 w-4.5 flex-shrink-0 place-items-center">
|
||||
<CollapseSidebar
|
||||
class="h-4.5 w-4.5 text-gray-700 duration-300 ease-in-out"
|
||||
class="h-4.5 w-4.5 text-ink-gray-7 duration-300 ease-in-out"
|
||||
:class="{ '[transform:rotateY(180deg)]': isSidebarCollapsed }"
|
||||
/>
|
||||
</span>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="flex h-screen w-screen">
|
||||
<div class="h-full border-r bg-gray-50">
|
||||
<div class="h-full border-r bg-surface-menu-bar">
|
||||
<AppSidebar />
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col h-full overflow-auto">
|
||||
<div class="flex-1 flex flex-col h-full overflow-auto bg-surface-white">
|
||||
<AppHeader />
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex h-screen w-screen">
|
||||
<MobileSidebar />
|
||||
<div class="flex h-full flex-1 flex-col overflow-auto">
|
||||
<div class="flex h-full flex-1 flex-col overflow-auto bg-surface-white">
|
||||
<MobileAppHeader />
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@ -78,7 +78,7 @@ function convertToDeal(selections, unselectAll) {
|
||||
createToast({
|
||||
title: __('Converted successfully'),
|
||||
icon: 'check',
|
||||
iconClasses: 'text-green-600',
|
||||
iconClasses: 'text-ink-green-3',
|
||||
})
|
||||
list.value.reload()
|
||||
unselectAll()
|
||||
@ -113,7 +113,7 @@ function deleteValues(selections, unselectAll) {
|
||||
createToast({
|
||||
title: __('Deleted successfully'),
|
||||
icon: 'check',
|
||||
iconClasses: 'text-green-600',
|
||||
iconClasses: 'text-ink-green-3',
|
||||
})
|
||||
unselectAll()
|
||||
list.value.reload()
|
||||
@ -157,7 +157,7 @@ function clearAssignemnts(selections, unselectAll) {
|
||||
createToast({
|
||||
title: __('Assignment cleared successfully'),
|
||||
icon: 'check',
|
||||
iconClasses: 'text-green-600',
|
||||
iconClasses: 'text-ink-green-3',
|
||||
})
|
||||
reload(unselectAll)
|
||||
close()
|
||||
|
||||
@ -93,7 +93,7 @@
|
||||
type="checkbox"
|
||||
:modelValue="item"
|
||||
:disabled="true"
|
||||
class="text-gray-900"
|
||||
class="text-ink-gray-9"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="column.key === '_liked_by'">
|
||||
|
||||
@ -91,7 +91,7 @@
|
||||
type="checkbox"
|
||||
:modelValue="item"
|
||||
:disabled="true"
|
||||
class="text-gray-900"
|
||||
class="text-ink-gray-9"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="column.key === '_liked_by'">
|
||||
|
||||
@ -146,7 +146,7 @@
|
||||
type="checkbox"
|
||||
:modelValue="item"
|
||||
:disabled="true"
|
||||
class="text-gray-900"
|
||||
class="text-ink-gray-9"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
type="checkbox"
|
||||
:modelValue="item"
|
||||
:disabled="true"
|
||||
class="text-gray-900"
|
||||
class="text-ink-gray-9"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="column.key === '_liked_by'">
|
||||
|
||||
@ -159,7 +159,7 @@
|
||||
type="checkbox"
|
||||
:modelValue="item"
|
||||
:disabled="true"
|
||||
class="text-gray-900"
|
||||
class="text-ink-gray-9"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@ -3,12 +3,12 @@
|
||||
<div v-for="group in reactivieRows" :key="group.group">
|
||||
<ListGroupHeader :group="group">
|
||||
<div
|
||||
class="my-2 flex items-center gap-2 text-base font-medium text-gray-800"
|
||||
class="my-2 flex items-center gap-2 text-base font-medium text-ink-gray-8"
|
||||
>
|
||||
<div>{{ __(group.label) }} -</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<component v-if="group.icon" :is="group.icon" />
|
||||
<div v-if="group.group == ' '" class="text-gray-500">
|
||||
<div v-if="group.group == ' '" class="text-ink-gray-4">
|
||||
{{ __('Empty') }}
|
||||
</div>
|
||||
<div v-else>{{ group.group }}</div>
|
||||
|
||||
@ -75,7 +75,7 @@
|
||||
type="checkbox"
|
||||
:modelValue="item"
|
||||
:disabled="true"
|
||||
class="text-gray-900"
|
||||
class="text-ink-gray-9"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="column.key === '_liked_by'">
|
||||
|
||||
@ -97,7 +97,7 @@
|
||||
type="checkbox"
|
||||
:modelValue="item"
|
||||
:disabled="true"
|
||||
class="text-gray-900"
|
||||
class="text-ink-gray-9"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="column.key === '_liked_by'">
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
variant="ghosted"
|
||||
@click="sidebarOpened = !sidebarOpened"
|
||||
>
|
||||
<MenuIcon class="h-4" />
|
||||
<MenuIcon class="h-4 text-ink-gray-9" />
|
||||
</Button>
|
||||
</div>
|
||||
<div id="app-header" class="flex-1" />
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
leave-to="-translate-x-full"
|
||||
>
|
||||
<div
|
||||
class="relative z-10 flex h-full w-[260px] flex-col justify-between border-r bg-gray-50 transition-all duration-300 ease-in-out"
|
||||
class="relative z-10 flex h-full w-[260px] flex-col justify-between border-r bg-surface-menu-bar transition-all duration-300 ease-in-out"
|
||||
>
|
||||
<div><UserDropdown class="p-2" /></div>
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
@ -41,12 +41,12 @@
|
||||
<template #header="{ opened, hide, toggle }">
|
||||
<div
|
||||
v-if="!hide"
|
||||
class="ml-2 mt-4 flex h-7 w-auto cursor-pointer gap-1.5 px-1 text-base font-medium text-gray-600 opacity-100 transition-all duration-300 ease-in-out"
|
||||
class="ml-2 mt-4 flex h-7 w-auto cursor-pointer gap-1.5 px-1 text-base font-medium text-ink-gray-5 opacity-100 transition-all duration-300 ease-in-out"
|
||||
@click="toggle()"
|
||||
>
|
||||
<FeatherIcon
|
||||
name="chevron-right"
|
||||
class="h-4 text-gray-900 transition-all duration-300 ease-in-out"
|
||||
class="h-4 text-ink-gray-9 transition-all duration-300 ease-in-out"
|
||||
:class="{ 'rotate-90': opened }"
|
||||
/>
|
||||
<span>{{ __(view.name) }}</span>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<Dialog v-model="show" :options="dialogOptions">
|
||||
<template #body>
|
||||
<div class="bg-white px-4 pb-6 pt-5 sm:px-6">
|
||||
<div class="bg-surface-modal px-4 pb-6 pt-5 sm:px-6">
|
||||
<div class="mb-5 flex items-center justify-between">
|
||||
<div>
|
||||
<h3 class="text-2xl font-semibold leading-6 text-gray-900">
|
||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||
{{ __(dialogOptions.title) || __('Untitled') }}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
</template>
|
||||
<template #item-label="{ option }">
|
||||
<Tooltip :text="option.value">
|
||||
<div class="cursor-pointer">
|
||||
<div class="cursor-pointer text-ink-gray-9">
|
||||
{{ getUser(option.value).full_name }}
|
||||
</div>
|
||||
</Tooltip>
|
||||
@ -55,7 +55,6 @@
|
||||
<Button
|
||||
:label="getUser(assignee.name).full_name"
|
||||
theme="gray"
|
||||
variant="outline"
|
||||
>
|
||||
<template #prefix>
|
||||
<UserAvatar :user="assignee.name" size="sm" />
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<Dialog v-model="show">
|
||||
<template #body-title>
|
||||
<div class="flex items-center gap-3">
|
||||
<h3 class="text-2xl font-semibold leading-6 text-gray-900">
|
||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||
{{ __('Call Details') }}
|
||||
</h3>
|
||||
</div>
|
||||
@ -12,7 +12,7 @@
|
||||
<div
|
||||
v-for="field in detailFields"
|
||||
:key="field.name"
|
||||
class="flex gap-2 text-base text-gray-800"
|
||||
class="flex gap-2 text-base text-ink-gray-8"
|
||||
>
|
||||
<div class="grid size-7 place-content-center">
|
||||
<component :is="field.icon" />
|
||||
@ -32,7 +32,7 @@
|
||||
</div>
|
||||
<FeatherIcon
|
||||
name="arrow-right"
|
||||
class="mx-1 h-4 w-4 text-gray-600"
|
||||
class="mx-1 h-4 w-4 text-ink-gray-5"
|
||||
/>
|
||||
<Avatar
|
||||
:image="field.value.receiver.image"
|
||||
@ -54,7 +54,7 @@
|
||||
></audio>
|
||||
</div>
|
||||
<div
|
||||
class="w-full cursor-pointer rounded border px-2 pt-1.5 text-base text-gray-700"
|
||||
class="w-full cursor-pointer rounded border px-2 pt-1.5 text-base text-ink-gray-7"
|
||||
v-else-if="field.name == 'note'"
|
||||
@click="() => (showNoteModal = true)"
|
||||
>
|
||||
@ -75,7 +75,7 @@
|
||||
</div>
|
||||
<div v-if="field.link">
|
||||
<ArrowUpRightIcon
|
||||
class="h-4 w-4 shrink-0 cursor-pointer text-gray-600 hover:text-gray-800"
|
||||
class="h-4 w-4 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8"
|
||||
@click="() => field.link()"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<Dialog v-model="show" :options="dialogOptions">
|
||||
<template #body>
|
||||
<div class="bg-white px-4 pb-6 pt-5 sm:px-6">
|
||||
<div class="bg-surface-modal px-4 pb-6 pt-5 sm:px-6">
|
||||
<div class="mb-5 flex items-center justify-between">
|
||||
<div>
|
||||
<h3 class="text-2xl font-semibold leading-6 text-gray-900">
|
||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||
{{ __(dialogOptions.title) || __('Untitled') }}
|
||||
</h3>
|
||||
</div>
|
||||
@ -27,7 +27,7 @@
|
||||
<div
|
||||
v-for="field in detailFields"
|
||||
:key="field.name"
|
||||
class="flex h-7 items-center gap-2 text-base text-gray-800"
|
||||
class="flex h-7 items-center gap-2 text-base text-ink-gray-8"
|
||||
>
|
||||
<div class="grid w-7 place-content-center">
|
||||
<component :is="field.icon" />
|
||||
@ -41,13 +41,13 @@
|
||||
<Button
|
||||
variant="ghost"
|
||||
:label="contact.data[field.name]"
|
||||
class="dropdown-button w-full justify-between truncate hover:bg-white"
|
||||
class="dropdown-button w-full justify-between truncate hover:bg-surface-white"
|
||||
>
|
||||
<div class="truncate">{{ contact.data[field.name] }}</div>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-600"
|
||||
class="h-4 text-ink-gray-5"
|
||||
/>
|
||||
</template>
|
||||
</Button>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<Dialog v-model="show" :options="{ size: '3xl' }">
|
||||
<template #body>
|
||||
<div class="bg-white px-4 pb-6 pt-5 sm:px-6">
|
||||
<div class="bg-surface-modal px-4 pb-6 pt-5 sm:px-6">
|
||||
<div class="mb-5 flex items-center justify-between">
|
||||
<div>
|
||||
<h3 class="text-2xl font-semibold leading-6 text-gray-900">
|
||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||
{{ __('Create Deal') }}
|
||||
</h3>
|
||||
</div>
|
||||
@ -24,11 +24,11 @@
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-4 grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<div class="flex items-center gap-3 text-sm text-gray-600">
|
||||
<div class="flex items-center gap-3 text-sm text-ink-gray-5">
|
||||
<div>{{ __('Choose Existing Organization') }}</div>
|
||||
<Switch v-model="chooseExistingOrganization" />
|
||||
</div>
|
||||
<div class="flex items-center gap-3 text-sm text-gray-600">
|
||||
<div class="flex items-center gap-3 text-sm text-ink-gray-5">
|
||||
<div>{{ __('Choose Existing Contact') }}</div>
|
||||
<Switch v-model="chooseExistingContact" />
|
||||
</div>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<Dialog v-model="show" :options="{ title: __('Bulk Edit') }">
|
||||
<template #body-content>
|
||||
<div class="mb-4">
|
||||
<div class="mb-1.5 text-sm text-gray-600">{{ __('Field') }}</div>
|
||||
<div class="mb-1.5 text-sm text-ink-gray-5">{{ __('Field') }}</div>
|
||||
<Autocomplete
|
||||
:value="field.label"
|
||||
:options="fields.data"
|
||||
@ -11,7 +11,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-1.5 text-sm text-gray-600">{{ __('Value') }}</div>
|
||||
<div class="mb-1.5 text-sm text-ink-gray-5">{{ __('Value') }}</div>
|
||||
<component
|
||||
:is="getValueComponent(field)"
|
||||
:value="newValue"
|
||||
@ -161,7 +161,7 @@ function getValueComponent(f) {
|
||||
return h(TextEditor, {
|
||||
variant: 'outline',
|
||||
editorClass:
|
||||
'!prose-sm overflow-auto min-h-[80px] max-h-80 py-1.5 px-2 rounded border border-gray-300 bg-white hover:border-gray-400 hover:shadow-sm focus:bg-white focus:border-gray-500 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-800 transition-colors',
|
||||
'!prose-sm overflow-auto min-h-[80px] max-h-80 py-1.5 px-2 rounded border border-outline-gray-2 bg-surface-white hover:border-outline-gray-3 hover:shadow-sm 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',
|
||||
bubbleMenu: true,
|
||||
content: newValue.value,
|
||||
})
|
||||
|
||||
@ -17,60 +17,49 @@
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex sm:flex-row flex-col gap-4">
|
||||
<div class="flex-1">
|
||||
<div class="mb-1.5 text-sm text-gray-600">
|
||||
{{ __('Name') }}
|
||||
<span class="text-red-500">*</span>
|
||||
</div>
|
||||
<TextInput
|
||||
<FormControl
|
||||
ref="nameRef"
|
||||
variant="outline"
|
||||
v-model="_emailTemplate.name"
|
||||
:placeholder="__('Payment Reminder')"
|
||||
:label="__('Name')"
|
||||
:required="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="mb-1.5 text-sm text-gray-600">{{ __('Doctype') }}</div>
|
||||
<Select
|
||||
variant="outline"
|
||||
<FormControl
|
||||
type="select"
|
||||
v-model="_emailTemplate.reference_doctype"
|
||||
:label="__('Doctype')"
|
||||
:options="['CRM Deal', 'CRM Lead']"
|
||||
:placeholder="__('CRM Deal')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-1.5 text-sm text-gray-600">
|
||||
{{ __('Subject') }}
|
||||
<span class="text-red-500">*</span>
|
||||
</div>
|
||||
<TextInput
|
||||
<FormControl
|
||||
ref="subjectRef"
|
||||
variant="outline"
|
||||
v-model="_emailTemplate.subject"
|
||||
:label="__('Subject')"
|
||||
:placeholder="__('Payment Reminder from Frappé - (#{{ name }})')"
|
||||
:required="true"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-1.5 text-sm text-gray-600">
|
||||
{{ __('Content Type') }}
|
||||
</div>
|
||||
<Select
|
||||
variant="outline"
|
||||
<FormControl
|
||||
type="select"
|
||||
v-model="_emailTemplate.content_type"
|
||||
:label="__('Content Type')"
|
||||
default="Rich Text"
|
||||
:options="['Rich Text', 'HTML']"
|
||||
:placeholder="__('Rich Text')"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-1.5 text-sm text-gray-600">
|
||||
{{ __('Content') }}
|
||||
<span class="text-red-500">*</span>
|
||||
</div>
|
||||
<FormControl
|
||||
v-if="_emailTemplate.content_type === 'HTML'"
|
||||
type="textarea"
|
||||
variant="outline"
|
||||
:label="__('Content')"
|
||||
:required="true"
|
||||
ref="content"
|
||||
:rows="10"
|
||||
v-model="_emailTemplate.response_html"
|
||||
@ -80,20 +69,24 @@
|
||||
)
|
||||
"
|
||||
/>
|
||||
<TextEditor
|
||||
v-else
|
||||
variant="outline"
|
||||
ref="content"
|
||||
editor-class="!prose-sm overflow-auto min-h-[180px] max-h-80 py-1.5 px-2 rounded border border-gray-300 bg-white hover:border-gray-400 hover:shadow-sm focus:bg-white focus:border-gray-500 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-gray-400 text-gray-800 transition-colors"
|
||||
:bubbleMenu="true"
|
||||
:content="_emailTemplate.response"
|
||||
@change="(val) => (_emailTemplate.response = val)"
|
||||
:placeholder="
|
||||
__(
|
||||
'Dear {{ lead_name }}, \n\nThis is a reminder for the payment of {{ grand_total }}. \n\nThanks, \nFrappé',
|
||||
)
|
||||
"
|
||||
/>
|
||||
<div v-else>
|
||||
<div class="mb-1.5 text-xs text-ink-gray-5">
|
||||
{{ __('Content') }}
|
||||
<span class="text-ink-red-3">*</span>
|
||||
</div>
|
||||
<TextEditor
|
||||
ref="content"
|
||||
editor-class="!prose-sm overflow-auto min-h-[180px] max-h-80 py-1.5 px-2 rounded border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-gray-modals hover:bg-surface-gray-3 hover:shadow-sm 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"
|
||||
:bubbleMenu="true"
|
||||
:content="_emailTemplate.response"
|
||||
@change="(val) => (_emailTemplate.response = val)"
|
||||
:placeholder="
|
||||
__(
|
||||
'Dear {{ lead_name }}, \n\nThis is a reminder for the payment of {{ grand_total }}. \n\nThanks, \nFrappé',
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Checkbox v-model="_emailTemplate.enabled" :label="__('Enabled')" />
|
||||
@ -106,7 +99,7 @@
|
||||
|
||||
<script setup>
|
||||
import { capture } from '@/telemetry'
|
||||
import { Checkbox, Select, TextEditor, call } from 'frappe-ui'
|
||||
import { Checkbox, TextEditor, call } from 'frappe-ui'
|
||||
import { ref, nextTick, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
@ -229,9 +222,9 @@ watch(
|
||||
errorMessage.value = ''
|
||||
nextTick(() => {
|
||||
if (_emailTemplate.value.name) {
|
||||
subjectRef.value.el.focus()
|
||||
subjectRef.value?.el?.focus()
|
||||
} else {
|
||||
nameRef.value.el.focus()
|
||||
nameRef.value?.el?.focus()
|
||||
}
|
||||
_emailTemplate.value = { ...props.emailTemplate }
|
||||
_emailTemplate.value.content_type = _emailTemplate.value.use_html
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
:placeholder="__('Payment Reminder')"
|
||||
>
|
||||
<template #prefix>
|
||||
<FeatherIcon name="search" class="h-4 w-4 text-gray-500" />
|
||||
<FeatherIcon name="search" class="h-4 w-4 text-ink-gray-4" />
|
||||
</template>
|
||||
</TextInput>
|
||||
<div
|
||||
@ -21,34 +21,34 @@
|
||||
<div
|
||||
v-for="template in filteredTemplates"
|
||||
:key="template.name"
|
||||
class="flex h-56 cursor-pointer flex-col gap-2 rounded-lg border p-3 hover:bg-gray-100"
|
||||
class="flex h-56 cursor-pointer flex-col gap-2 rounded-lg border p-3 hover:bg-surface-gray-2"
|
||||
@click="emit('apply', template)"
|
||||
>
|
||||
<div class="border-b pb-2 text-base font-semibold">
|
||||
{{ template.name }}
|
||||
</div>
|
||||
<div v-if="template.subject" class="text-sm text-gray-600">
|
||||
<div v-if="template.subject" class="text-sm text-ink-gray-5">
|
||||
{{ __('Subject: {0}', [template.subject]) }}
|
||||
</div>
|
||||
<TextEditor
|
||||
v-if="template.use_html && template.response_html"
|
||||
:content="template.response_html"
|
||||
:editable="false"
|
||||
editor-class="!prose-sm max-w-none !text-sm text-gray-600 focus:outline-none"
|
||||
editor-class="!prose-sm max-w-none !text-sm text-ink-gray-5 focus:outline-none"
|
||||
class="flex-1 overflow-hidden"
|
||||
/>
|
||||
<TextEditor
|
||||
v-else-if="template.response"
|
||||
:content="template.response"
|
||||
:editable="false"
|
||||
editor-class="!prose-sm max-w-none !text-sm text-gray-600 focus:outline-none"
|
||||
editor-class="!prose-sm max-w-none !text-sm text-ink-gray-5 focus:outline-none"
|
||||
class="flex-1 overflow-hidden"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="mt-2">
|
||||
<div class="flex h-56 flex-col items-center justify-center">
|
||||
<div class="text-lg text-gray-500">
|
||||
<div class="text-lg text-ink-gray-4">
|
||||
{{ __('No templates found') }}
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<Dialog v-model="show" :options="{ size: '3xl' }">
|
||||
<template #body>
|
||||
<div class="bg-white px-4 pb-6 pt-5 sm:px-6">
|
||||
<div class="bg-surface-modal px-4 pb-6 pt-5 sm:px-6">
|
||||
<div class="mb-5 flex items-center justify-between">
|
||||
<div>
|
||||
<h3 class="text-2xl font-semibold leading-6 text-gray-900">
|
||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||
{{ __('Create Lead') }}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user