fix: update scemantic classes fro dark mode manually
This commit is contained in:
parent
e9afb11407
commit
7f62371837
@ -5,6 +5,7 @@ from frappe import _
|
|||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
|
from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
|
||||||
|
|
||||||
|
|
||||||
def on_update(self, method):
|
def on_update(self, method):
|
||||||
notify_mentions(self)
|
notify_mentions(self)
|
||||||
|
|
||||||
@ -24,25 +25,31 @@ def notify_mentions(doc):
|
|||||||
doctype = doc.reference_doctype
|
doctype = doc.reference_doctype
|
||||||
if doctype.startswith("CRM "):
|
if doctype.startswith("CRM "):
|
||||||
doctype = doctype[4:].lower()
|
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"""
|
notification_text = f"""
|
||||||
<div class="mb-2 leading-5 text-gray-600">
|
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||||
<span class="font-medium text-gray-900">{ owner }</span>
|
<span class="font-medium text-ink-gray-9">{ owner }</span>
|
||||||
<span>{ _('mentioned you in {0}').format(doctype) }</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>
|
</div>
|
||||||
"""
|
"""
|
||||||
notify_user({
|
notify_user(
|
||||||
"owner": doc.owner,
|
{
|
||||||
"assigned_to": mention.email,
|
"owner": doc.owner,
|
||||||
"notification_type": "Mention",
|
"assigned_to": mention.email,
|
||||||
"message": doc.content,
|
"notification_type": "Mention",
|
||||||
"notification_text": notification_text,
|
"message": doc.content,
|
||||||
"reference_doctype": "Comment",
|
"notification_text": notification_text,
|
||||||
"reference_docname": doc.name,
|
"reference_doctype": "Comment",
|
||||||
"redirect_to_doctype": doc.reference_doctype,
|
"reference_docname": doc.name,
|
||||||
"redirect_to_docname": doc.reference_name,
|
"redirect_to_doctype": doc.reference_doctype,
|
||||||
})
|
"redirect_to_docname": doc.reference_name,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def extract_mentions(html):
|
def extract_mentions(html):
|
||||||
@ -56,39 +63,42 @@ def extract_mentions(html):
|
|||||||
)
|
)
|
||||||
return mentions
|
return mentions
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def add_attachments(name: str, attachments: Iterable[str | dict]) -> None:
|
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 name: Comment name
|
||||||
:param attachments: File names or dicts with keys "fname" and "fcontent"
|
:param attachments: File names or dicts with keys "fname" and "fcontent"
|
||||||
"""
|
"""
|
||||||
# loop through attachments
|
# loop through attachments
|
||||||
for a in attachments:
|
for a in attachments:
|
||||||
if isinstance(a, str):
|
if isinstance(a, str):
|
||||||
attach = frappe.db.get_value("File", {"name": a}, ["file_url", "is_private"], as_dict=1)
|
attach = frappe.db.get_value(
|
||||||
file_args = {
|
"File", {"name": a}, ["file_url", "is_private"], as_dict=1
|
||||||
"file_url": attach.file_url,
|
)
|
||||||
"is_private": attach.is_private,
|
file_args = {
|
||||||
}
|
"file_url": attach.file_url,
|
||||||
elif isinstance(a, dict) and "fcontent" in a and "fname" in a:
|
"is_private": attach.is_private,
|
||||||
# dict returned by frappe.attach_print()
|
}
|
||||||
file_args = {
|
elif isinstance(a, dict) and "fcontent" in a and "fname" in a:
|
||||||
"file_name": a["fname"],
|
# dict returned by frappe.attach_print()
|
||||||
"content": a["fcontent"],
|
file_args = {
|
||||||
"is_private": 1,
|
"file_name": a["fname"],
|
||||||
}
|
"content": a["fcontent"],
|
||||||
else:
|
"is_private": 1,
|
||||||
continue
|
}
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
file_args.update(
|
file_args.update(
|
||||||
{
|
{
|
||||||
"attached_to_doctype": "Comment",
|
"attached_to_doctype": "Comment",
|
||||||
"attached_to_name": name,
|
"attached_to_name": name,
|
||||||
"folder": "Home/Attachments",
|
"folder": "Home/Attachments",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
_file = frappe.new_doc("File")
|
_file = frappe.new_doc("File")
|
||||||
_file.update(file_args)
|
_file.update(file_args)
|
||||||
_file.save(ignore_permissions=True)
|
_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 frappe import _
|
||||||
from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
|
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:
|
def after_insert(doc, method):
|
||||||
notify_assigned_user(doc)
|
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):
|
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:
|
if (
|
||||||
notify_assigned_user(doc, is_cancelled=True)
|
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):
|
def notify_assigned_user(doc, is_cancelled=False):
|
||||||
_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
|
_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
|
||||||
owner = frappe.get_cached_value("User", frappe.session.user, "full_name")
|
owner = frappe.get_cached_value("User", frappe.session.user, "full_name")
|
||||||
notification_text = get_notification_text(owner, doc, _doc, is_cancelled)
|
notification_text = get_notification_text(owner, doc, _doc, is_cancelled)
|
||||||
|
|
||||||
message = _("Your assignment on {0} {1} has been removed by {2}").format(
|
message = (
|
||||||
doc.reference_type,
|
_("Your assignment on {0} {1} has been removed by {2}").format(
|
||||||
doc.reference_name,
|
doc.reference_type, doc.reference_name, owner
|
||||||
owner
|
)
|
||||||
) if is_cancelled else _("{0} assigned a {1} {2} to you").format(
|
if is_cancelled
|
||||||
owner,
|
else _("{0} assigned a {1} {2} to you").format(
|
||||||
doc.reference_type,
|
owner, doc.reference_type, doc.reference_name
|
||||||
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):
|
def get_notification_text(owner, doc, reference_doc, is_cancelled=False):
|
||||||
name = doc.reference_name
|
name = doc.reference_name
|
||||||
doctype = doc.reference_type
|
doctype = doc.reference_type
|
||||||
|
|
||||||
if doctype.startswith("CRM "):
|
if doctype.startswith("CRM "):
|
||||||
doctype = doctype[4:].lower()
|
doctype = doctype[4:].lower()
|
||||||
|
|
||||||
if doctype in ["lead", "deal"]:
|
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
|
name = (
|
||||||
|
reference_doc.lead_name or name
|
||||||
|
if doctype == "lead"
|
||||||
|
else reference_doc.organization or reference_doc.lead_name or name
|
||||||
|
)
|
||||||
|
|
||||||
if is_cancelled:
|
if is_cancelled:
|
||||||
return f"""
|
return f"""
|
||||||
<div class="mb-2 leading-5 text-gray-600">
|
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||||
<span>{ _('Your assignment on {0} {1} has been removed by {2}').format(
|
<span>{ _('Your assignment on {0} {1} has been removed by {2}').format(
|
||||||
doctype,
|
doctype,
|
||||||
f'<span class="font-medium text-gray-900">{ name }</span>',
|
f'<span class="font-medium text-ink-gray-9">{ name }</span>',
|
||||||
f'<span class="font-medium text-gray-900">{ owner }</span>'
|
f'<span class="font-medium text-ink-gray-9">{ owner }</span>'
|
||||||
) }</span>
|
) }</span>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
<div class="mb-2 leading-5 text-gray-600">
|
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||||
<span class="font-medium text-gray-900">{ owner }</span>
|
<span class="font-medium text-ink-gray-9">{ owner }</span>
|
||||||
<span>{ _('assigned a {0} {1} to you').format(
|
<span>{ _('assigned a {0} {1} to you').format(
|
||||||
doctype,
|
doctype,
|
||||||
f'<span class="font-medium text-gray-900">{ name }</span>'
|
f'<span class="font-medium text-ink-gray-9">{ name }</span>'
|
||||||
) }</span>
|
) }</span>
|
||||||
</div>
|
</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):
|
def get_redirect_to_doc(doc):
|
||||||
if doc.reference_type == "CRM Task":
|
if doc.reference_type == "CRM Task":
|
||||||
reference_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
|
reference_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
|
||||||
return reference_doc.reference_doctype, reference_doc.reference_docname
|
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 "):
|
if doctype.startswith("CRM "):
|
||||||
doctype = doctype[4:].lower()
|
doctype = doctype[4:].lower()
|
||||||
notification_text = f"""
|
notification_text = f"""
|
||||||
<div class="mb-2 leading-5 text-gray-600">
|
<div class="mb-2 leading-5 text-ink-gray-5">
|
||||||
<span class="font-medium text-gray-900">{ _('You') }</span>
|
<span class="font-medium text-ink-gray-9">{ _('You') }</span>
|
||||||
<span>{ _('received a whatsapp message in {0}').format(doctype) }</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>
|
</div>
|
||||||
"""
|
"""
|
||||||
assigned_users = get_assigned_users(doc.reference_doctype, doc.reference_name)
|
assigned_users = get_assigned_users(doc.reference_doctype, doc.reference_name)
|
||||||
for user in assigned_users:
|
for user in assigned_users:
|
||||||
notify_user({
|
notify_user(
|
||||||
"owner": doc.owner,
|
{
|
||||||
"assigned_to": user,
|
"owner": doc.owner,
|
||||||
"notification_type": "WhatsApp",
|
"assigned_to": user,
|
||||||
"message": doc.message,
|
"notification_type": "WhatsApp",
|
||||||
"notification_text": notification_text,
|
"message": doc.message,
|
||||||
"reference_doctype": "WhatsApp Message",
|
"notification_text": notification_text,
|
||||||
"reference_docname": doc.name,
|
"reference_doctype": "WhatsApp Message",
|
||||||
"redirect_to_doctype": doc.reference_doctype,
|
"reference_docname": doc.name,
|
||||||
"redirect_to_docname": doc.reference_name,
|
"redirect_to_doctype": doc.reference_doctype,
|
||||||
})
|
"redirect_to_docname": doc.reference_name,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_lead_or_deal_from_number(number):
|
def get_lead_or_deal_from_number(number):
|
||||||
@ -92,6 +94,7 @@ def is_whatsapp_enabled():
|
|||||||
return False
|
return False
|
||||||
return frappe.get_cached_value("WhatsApp Settings", "WhatsApp Settings", "enabled")
|
return frappe.get_cached_value("WhatsApp Settings", "WhatsApp Settings", "enabled")
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def is_whatsapp_installed():
|
def is_whatsapp_installed():
|
||||||
if not frappe.db.exists("DocType", "WhatsApp Settings"):
|
if not frappe.db.exists("DocType", "WhatsApp Settings"):
|
||||||
@ -105,8 +108,8 @@ def get_whatsapp_messages(reference_doctype, reference_name):
|
|||||||
return []
|
return []
|
||||||
messages = []
|
messages = []
|
||||||
|
|
||||||
if reference_doctype == 'CRM Deal':
|
if reference_doctype == "CRM Deal":
|
||||||
lead = frappe.db.get_value(reference_doctype, reference_name, 'lead')
|
lead = frappe.db.get_value(reference_doctype, reference_name, "lead")
|
||||||
if lead:
|
if lead:
|
||||||
messages = frappe.get_all(
|
messages = frappe.get_all(
|
||||||
"WhatsApp Message",
|
"WhatsApp Message",
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 59415754663693989ae5144b43370f4b0426aa50
|
Subproject commit 82150c9591a36abc5dc8667ae5873651d4b2cc0d
|
||||||
@ -18,7 +18,7 @@
|
|||||||
/>
|
/>
|
||||||
<component
|
<component
|
||||||
v-else
|
v-else
|
||||||
class="size-4"
|
class="size-4 text-ink-gray-7"
|
||||||
:is="fileIcon(attachment.file_type)"
|
:is="fileIcon(attachment.file_type)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col gap-2 border border-outline-gray-modals rounded-md bg-surface-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="flex items-center justify-between">
|
||||||
<div class="inline-flex gap-2 items-center text-base font-medium">
|
<div class="inline-flex gap-2 items-center text-base font-medium">
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="cursor-pointer rounded bg-surface-menu-bar 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 class="prose-f" v-html="activity.content" />
|
||||||
<div v-if="activity.attachments.length" class="mt-2 flex flex-wrap gap-2">
|
<div v-if="activity.attachments.length" class="mt-2 flex flex-wrap gap-2">
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div
|
<div
|
||||||
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"
|
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">
|
<div class="flex items-center gap-2 truncate">
|
||||||
<span>{{ activity.data.sender_full_name }}</span>
|
<span>{{ activity.data.sender_full_name }}</span>
|
||||||
<span class="sm:flex hidden text-sm text-ink-gray-5">
|
<span class="sm:flex hidden text-sm text-ink-gray-5">
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div v-if="tasks.length">
|
<div v-if="tasks.length">
|
||||||
<div v-for="(task, i) in tasks" :key="task.name">
|
<div v-for="(task, i) in tasks" :key="task.name">
|
||||||
<div
|
<div
|
||||||
class="activity flex cursor-pointer gap-6 rounded p-2.5 duration-300 ease-in-out hover:bg-surface-menu-bar"
|
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)"
|
@click="modalRef.showTask(task)"
|
||||||
>
|
>
|
||||||
<div class="flex flex-1 flex-col gap-1.5 text-base truncate">
|
<div class="flex flex-1 flex-col gap-1.5 text-base truncate">
|
||||||
@ -76,7 +76,7 @@
|
|||||||
<Button
|
<Button
|
||||||
icon="more-horizontal"
|
icon="more-horizontal"
|
||||||
variant="ghosted"
|
variant="ghosted"
|
||||||
class="hover:bg-surface-gray-4"
|
class="hover:bg-surface-gray-4 text-ink-gray-9"
|
||||||
/>
|
/>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:id="whatsapp.name"
|
:id="whatsapp.name"
|
||||||
class="group/message relative max-w-[90%] rounded-md bg-surface-menu-bar 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
|
<div
|
||||||
v-if="whatsapp.is_reply"
|
v-if="whatsapp.is_reply"
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<template #target="{ togglePopover }">
|
<template #target="{ togglePopover }">
|
||||||
<button
|
<button
|
||||||
:class="[
|
:class="[
|
||||||
active ? 'bg-surface-gray-2' : 'text-ink-gray-8',
|
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',
|
'group w-full flex h-7 items-center justify-between rounded px-2 text-base hover:bg-surface-gray-2',
|
||||||
]"
|
]"
|
||||||
@click.prevent="togglePopover()"
|
@click.prevent="togglePopover()"
|
||||||
@ -19,7 +19,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-3 justify-between mx-3 p-2 rounded-lg border border-gray-100 bg-surface-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">
|
<div v-for="app in apps.data" :key="app.name">
|
||||||
<a
|
<a
|
||||||
@ -39,8 +39,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import AppsIcon from '@/components/Icons/AppsIcon.vue'
|
import AppsIcon from '@/components/Icons/AppsIcon.vue'
|
||||||
import { Popover, createResource } from 'frappe-ui'
|
import { Popover, createResource } from 'frappe-ui'
|
||||||
import { onUnmounted } from 'vue';
|
import { onUnmounted } from 'vue'
|
||||||
import { stopRecording } from '@/telemetry';
|
import { stopRecording } from '@/telemetry'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
active: Boolean,
|
active: Boolean,
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body="{ close }">
|
<template #body="{ close }">
|
||||||
<div
|
<div
|
||||||
class="my-2 rounded-lg border border-gray-100 bg-surface-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">
|
<div v-if="!edit">
|
||||||
<Draggable
|
<Draggable
|
||||||
@ -49,7 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Draggable>
|
</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
|
<Autocomplete
|
||||||
value=""
|
value=""
|
||||||
:options="fields"
|
:options="fields"
|
||||||
@ -114,7 +114,7 @@
|
|||||||
placeholder="10rem"
|
placeholder="10rem"
|
||||||
:description="
|
: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"
|
:debounce="500"
|
||||||
@ -295,6 +295,6 @@ watchOnce(
|
|||||||
oldValues.value.columns = JSON.parse(JSON.stringify(val.columns))
|
oldValues.value.columns = JSON.parse(JSON.stringify(val.columns))
|
||||||
oldValues.value.rows = JSON.parse(JSON.stringify(val.rows))
|
oldValues.value.rows = JSON.parse(JSON.stringify(val.rows))
|
||||||
oldValues.value.isDefault = val.is_default
|
oldValues.value.isDefault = val.is_default
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap gap-1 min-h-20 p-1.5 cursor-text rounded h-7 text-base border border-outline-gray-2 bg-surface-white hover:border-outline-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"
|
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"
|
@click="setFocus"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
@ -11,7 +11,7 @@
|
|||||||
:label="value"
|
:label="value"
|
||||||
theme="gray"
|
theme="gray"
|
||||||
variant="subtle"
|
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"
|
@keydown.delete.capture.stop="removeLastValue"
|
||||||
>
|
>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
@ -23,9 +23,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</Button>
|
</Button>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<TextInput
|
<input
|
||||||
ref="search"
|
ref="search"
|
||||||
class="w-full border-none bg-surface-white hover:bg-surface-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"
|
type="text"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
placeholder="example@email.com"
|
placeholder="example@email.com"
|
||||||
@ -113,7 +113,7 @@ const removeLastValue = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setFocus() {
|
function setFocus() {
|
||||||
search.value.el.focus()
|
search.value.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ setFocus })
|
defineExpose({ setFocus })
|
||||||
|
|||||||
@ -41,9 +41,11 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body="{ isOpen }">
|
<template #body="{ isOpen }">
|
||||||
<div v-show="isOpen">
|
<div v-show="isOpen">
|
||||||
<div class="mt-1 rounded-lg bg-surface-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
|
<ComboboxOptions
|
||||||
class="my-1 max-h-[12rem] overflow-y-auto px-1.5"
|
class="p-1.5 max-h-[12rem] overflow-y-auto"
|
||||||
static
|
static
|
||||||
>
|
>
|
||||||
<ComboboxOption
|
<ComboboxOption
|
||||||
@ -55,7 +57,7 @@
|
|||||||
<li
|
<li
|
||||||
:class="[
|
:class="[
|
||||||
'flex cursor-pointer items-center rounded px-2 py-1 text-base',
|
'flex cursor-pointer items-center rounded px-2 py-1 text-base',
|
||||||
{ 'bg-surface-gray-2': active },
|
{ 'bg-surface-gray-3': active },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
@ -146,16 +148,15 @@ const filterOptions = createResource({
|
|||||||
cache: [text.value, 'Contact'],
|
cache: [text.value, 'Contact'],
|
||||||
params: { txt: text.value },
|
params: { txt: text.value },
|
||||||
transform: (data) => {
|
transform: (data) => {
|
||||||
let allData = data
|
let allData = data.map((option) => {
|
||||||
.map((option) => {
|
let fullName = option[0]
|
||||||
let fullName = option[0]
|
let email = option[1]
|
||||||
let email = option[1]
|
let name = option[2]
|
||||||
let name = option[2]
|
return {
|
||||||
return {
|
label: fullName || name || email,
|
||||||
label: fullName || name || email,
|
value: email,
|
||||||
value: email,
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
return allData
|
return allData
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@ -61,7 +61,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="option.selected">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -34,7 +34,9 @@
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
@click="toggleCC()"
|
@click="toggleCC()"
|
||||||
:class="[
|
:class="[
|
||||||
cc ? '!bg-surface-gray-4 hover:bg-surface-gray-3' : '!text-ink-gray-4',
|
cc
|
||||||
|
? '!bg-surface-gray-4 hover:bg-surface-gray-3'
|
||||||
|
: '!text-ink-gray-4',
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
@ -42,7 +44,9 @@
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
@click="toggleBCC()"
|
@click="toggleBCC()"
|
||||||
:class="[
|
:class="[
|
||||||
bcc ? '!bg-surface-gray-4 hover:bg-surface-gray-3' : '!text-ink-gray-4',
|
bcc
|
||||||
|
? '!bg-surface-gray-4 hover:bg-surface-gray-3'
|
||||||
|
: '!text-ink-gray-4',
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -73,8 +77,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="sm:mx-10 mx-4 flex items-center gap-2 pb-2.5">
|
<div class="sm:mx-10 mx-4 flex items-center gap-2 pb-2.5">
|
||||||
<span class="text-xs text-ink-gray-4">{{ __('SUBJECT') }}:</span>
|
<span class="text-xs text-ink-gray-4">{{ __('SUBJECT') }}:</span>
|
||||||
<TextInput
|
<input
|
||||||
class="flex-1 border-none bg-surface-white hover:bg-surface-white focus:border-none focus:!shadow-none focus-visible:!ring-0"
|
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"
|
v-model="subject"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<div
|
<div
|
||||||
v-for="section in sections"
|
v-for="section in sections"
|
||||||
:key="section.label"
|
: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'"
|
:class="section.hideBorder ? '' : 'border-t pt-4'"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
<template #prefix><FilterIcon class="h-4" /></template>
|
<template #prefix><FilterIcon class="h-4" /></template>
|
||||||
<template v-if="filters?.size" #suffix>
|
<template v-if="filters?.size" #suffix>
|
||||||
<div
|
<div
|
||||||
class="flex h-5 w-5 items-center justify-center rounded bg-surface-gray-7 pt-[1px] text-2xs font-medium text-ink-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 }}
|
{{ filters.size }}
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +27,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ close }">
|
<template #body="{ close }">
|
||||||
<div class="my-2 rounded-lg border border-gray-100 bg-surface-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 class="min-w-72 p-2 sm:min-w-[400px]">
|
||||||
<div
|
<div
|
||||||
v-if="filters?.size"
|
v-if="filters?.size"
|
||||||
|
|||||||
@ -8,10 +8,10 @@
|
|||||||
<template #body="{ togglePopover }">
|
<template #body="{ togglePopover }">
|
||||||
<div
|
<div
|
||||||
v-if="reaction"
|
v-if="reaction"
|
||||||
class="flex items-center justify-center gap-2 rounded-full bg-surface-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
|
<div
|
||||||
class="size-5 cursor-pointer rounded-full bg-surface-white text-xl"
|
class="size-5 cursor-pointer rounded-full bg-surface-transparent text-xl"
|
||||||
v-for="r in reactionEmojis"
|
v-for="r in reactionEmojis"
|
||||||
:key="r"
|
:key="r"
|
||||||
@click="() => (emoji = r) && togglePopover()"
|
@click="() => (emoji = r) && togglePopover()"
|
||||||
@ -26,9 +26,12 @@
|
|||||||
@click.stop="() => (reaction = false)"
|
@click.stop="() => (reaction = false)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="my-3 max-w-max transform bg-surface-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
|
<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 gap-2 px-3 pb-1 pt-3">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
@ -43,7 +46,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="w-96"></div>
|
<div class="w-96"></div>
|
||||||
<div class="px-3" v-for="(emojis, group) in emojiGroups" :key="group">
|
<div class="px-3" v-for="(emojis, group) in emojiGroups" :key="group">
|
||||||
<div class="sticky top-0 bg-surface-white pb-2 pt-3 text-sm text-ink-gray-7">
|
<div
|
||||||
|
class="sticky top-0 bg-surface-modal pb-2 pt-3 text-sm text-ink-gray-7"
|
||||||
|
>
|
||||||
{{ group }}
|
{{ group }}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid w-96 grid-cols-12 place-items-center">
|
<div class="grid w-96 grid-cols-12 place-items-center">
|
||||||
|
|||||||
@ -1,31 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg
|
<svg
|
||||||
width="16"
|
width="16"
|
||||||
height="17"
|
height="16"
|
||||||
viewBox="0 0 16 17"
|
viewBox="0 0 16 16"
|
||||||
fill="none"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
d="M2 4.5H14"
|
fill-rule="evenodd"
|
||||||
stroke="currentColor"
|
clip-rule="evenodd"
|
||||||
stroke-miterlimit="10"
|
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"
|
||||||
stroke-linecap="round"
|
fill="currentColor"
|
||||||
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"
|
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,45 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg
|
<svg
|
||||||
width="16"
|
width="16"
|
||||||
height="17"
|
height="16"
|
||||||
viewBox="0 0 16 17"
|
viewBox="0 0 16 16"
|
||||||
fill="none"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
d="M1.75 3.75H10.75"
|
fill-rule="evenodd"
|
||||||
stroke="currentColor"
|
clip-rule="evenodd"
|
||||||
stroke-miterlimit="10"
|
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"
|
||||||
stroke-linecap="round"
|
fill="currentColor"
|
||||||
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"
|
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
rx="1"
|
rx="1"
|
||||||
transform="rotate(-45 0.792893 0)"
|
transform="rotate(-45 0.792893 0)"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
stroke="white"
|
class="stroke stroke-ink-white"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -11,7 +11,9 @@
|
|||||||
<Dialog v-model="showDialog" :options="{ title: __('Kanban Settings') }">
|
<Dialog v-model="showDialog" :options="{ title: __('Kanban Settings') }">
|
||||||
<template #body-content>
|
<template #body-content>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-base text-ink-gray-8 mb-2">{{ __('Column Field') }}</div>
|
<div class="text-base text-ink-gray-8 mb-2">
|
||||||
|
{{ __('Column Field') }}
|
||||||
|
</div>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
v-if="columnFields"
|
v-if="columnFields"
|
||||||
value=""
|
value=""
|
||||||
@ -21,7 +23,6 @@
|
|||||||
<template #target="{ togglePopover }">
|
<template #target="{ togglePopover }">
|
||||||
<Button
|
<Button
|
||||||
class="w-full !justify-start"
|
class="w-full !justify-start"
|
||||||
variant="subtle"
|
|
||||||
@click="togglePopover()"
|
@click="togglePopover()"
|
||||||
:label="columnField.label"
|
:label="columnField.label"
|
||||||
/>
|
/>
|
||||||
@ -39,7 +40,6 @@
|
|||||||
<template #target="{ togglePopover }">
|
<template #target="{ togglePopover }">
|
||||||
<Button
|
<Button
|
||||||
class="w-full !justify-start"
|
class="w-full !justify-start"
|
||||||
variant="subtle"
|
|
||||||
@click="togglePopover()"
|
@click="togglePopover()"
|
||||||
:label="titleField.label"
|
:label="titleField.label"
|
||||||
/>
|
/>
|
||||||
@ -47,7 +47,9 @@
|
|||||||
</Autocomplete>
|
</Autocomplete>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<div class="text-base text-ink-gray-8 mb-2">{{ __('Fields Order') }}</div>
|
<div class="text-base text-ink-gray-8 mb-2">
|
||||||
|
{{ __('Fields Order') }}
|
||||||
|
</div>
|
||||||
<Draggable
|
<Draggable
|
||||||
:list="allFields"
|
:list="allFields"
|
||||||
@end="reorder"
|
@end="reorder"
|
||||||
@ -57,7 +59,7 @@
|
|||||||
>
|
>
|
||||||
<template #item="{ element: field }">
|
<template #item="{ element: field }">
|
||||||
<div
|
<div
|
||||||
class="px-1 py-0.5 border rounded text-base text-ink-gray-8 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">
|
<div class="flex items-center gap-2">
|
||||||
<DragVerticalIcon class="h-3.5 cursor-grab" />
|
<DragVerticalIcon class="h-3.5 cursor-grab" />
|
||||||
@ -78,7 +80,6 @@
|
|||||||
<template #target="{ togglePopover }">
|
<template #target="{ togglePopover }">
|
||||||
<Button
|
<Button
|
||||||
class="w-full mt-2"
|
class="w-full mt-2"
|
||||||
variant="outline"
|
|
||||||
@click="togglePopover()"
|
@click="togglePopover()"
|
||||||
:label="__('Add Field')"
|
:label="__('Add Field')"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -17,7 +17,11 @@
|
|||||||
<div class="flex items-center text-base">
|
<div class="flex items-center text-base">
|
||||||
<NestedPopover>
|
<NestedPopover>
|
||||||
<template #target>
|
<template #target>
|
||||||
<Button variant="ghost" size="sm" class="hover:!bg-surface-gray-2">
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
class="hover:!bg-surface-gray-2"
|
||||||
|
>
|
||||||
<IndicatorIcon
|
<IndicatorIcon
|
||||||
:class="colorClasses(column.column.color, true)"
|
:class="colorClasses(column.column.color, true)"
|
||||||
/>
|
/>
|
||||||
@ -25,7 +29,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body="{ close }">
|
<template #body="{ close }">
|
||||||
<div
|
<div
|
||||||
class="flex flex-col gap-3 px-3 py-2.5 rounded-lg border border-gray-100 bg-surface-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">
|
<div class="flex gap-1">
|
||||||
<Button
|
<Button
|
||||||
@ -48,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</NestedPopover>
|
</NestedPopover>
|
||||||
<div>{{ column.column.name }}</div>
|
<div class="text-ink-gray-9">{{ column.column.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<Dropdown :options="actions(column)">
|
<Dropdown :options="actions(column)">
|
||||||
@ -80,7 +84,7 @@
|
|||||||
<template #item="{ element: fields }">
|
<template #item="{ element: fields }">
|
||||||
<component
|
<component
|
||||||
:is="options.getRoute ? 'router-link' : 'div'"
|
:is="options.getRoute ? 'router-link' : 'div'"
|
||||||
class="pt-3 px-3.5 pb-2.5 rounded-lg border bg-surface-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"
|
:data-name="fields.name"
|
||||||
v-bind="{
|
v-bind="{
|
||||||
to: options.getRoute ? options.getRoute(fields) : undefined,
|
to: options.getRoute ? options.getRoute(fields) : undefined,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex h-screen w-screen">
|
<div class="flex h-screen w-screen">
|
||||||
<MobileSidebar />
|
<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 />
|
<MobileAppHeader />
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
variant="ghosted"
|
variant="ghosted"
|
||||||
@click="sidebarOpened = !sidebarOpened"
|
@click="sidebarOpened = !sidebarOpened"
|
||||||
>
|
>
|
||||||
<MenuIcon class="h-4" />
|
<MenuIcon class="h-4 text-ink-gray-9" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div id="app-header" class="flex-1" />
|
<div id="app-header" class="flex-1" />
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog v-model="show" :options="dialogOptions">
|
<Dialog v-model="show" :options="dialogOptions">
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="bg-surface-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 class="mb-5 flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||||
|
|||||||
@ -40,7 +40,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #item-label="{ option }">
|
<template #item-label="{ option }">
|
||||||
<Tooltip :text="option.value">
|
<Tooltip :text="option.value">
|
||||||
<div class="cursor-pointer">
|
<div class="cursor-pointer text-ink-gray-9">
|
||||||
{{ getUser(option.value).full_name }}
|
{{ getUser(option.value).full_name }}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -55,7 +55,6 @@
|
|||||||
<Button
|
<Button
|
||||||
:label="getUser(assignee.name).full_name"
|
:label="getUser(assignee.name).full_name"
|
||||||
theme="gray"
|
theme="gray"
|
||||||
variant="outline"
|
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<UserAvatar :user="assignee.name" size="sm" />
|
<UserAvatar :user="assignee.name" size="sm" />
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog v-model="show" :options="dialogOptions">
|
<Dialog v-model="show" :options="dialogOptions">
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="bg-surface-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 class="mb-5 flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog v-model="show" :options="{ size: '3xl' }">
|
<Dialog v-model="show" :options="{ size: '3xl' }">
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="bg-surface-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 class="mb-5 flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||||
|
|||||||
@ -17,60 +17,49 @@
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex sm:flex-row flex-col gap-4">
|
<div class="flex sm:flex-row flex-col gap-4">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
<FormControl
|
||||||
{{ __('Name') }}
|
|
||||||
<span class="text-ink-red-3">*</span>
|
|
||||||
</div>
|
|
||||||
<TextInput
|
|
||||||
ref="nameRef"
|
ref="nameRef"
|
||||||
variant="outline"
|
|
||||||
v-model="_emailTemplate.name"
|
v-model="_emailTemplate.name"
|
||||||
:placeholder="__('Payment Reminder')"
|
:placeholder="__('Payment Reminder')"
|
||||||
|
:label="__('Name')"
|
||||||
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">{{ __('Doctype') }}</div>
|
<FormControl
|
||||||
<Select
|
type="select"
|
||||||
variant="outline"
|
|
||||||
v-model="_emailTemplate.reference_doctype"
|
v-model="_emailTemplate.reference_doctype"
|
||||||
|
:label="__('Doctype')"
|
||||||
:options="['CRM Deal', 'CRM Lead']"
|
:options="['CRM Deal', 'CRM Lead']"
|
||||||
:placeholder="__('CRM Deal')"
|
:placeholder="__('CRM Deal')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
<FormControl
|
||||||
{{ __('Subject') }}
|
|
||||||
<span class="text-ink-red-3">*</span>
|
|
||||||
</div>
|
|
||||||
<TextInput
|
|
||||||
ref="subjectRef"
|
ref="subjectRef"
|
||||||
variant="outline"
|
|
||||||
v-model="_emailTemplate.subject"
|
v-model="_emailTemplate.subject"
|
||||||
|
:label="__('Subject')"
|
||||||
:placeholder="__('Payment Reminder from Frappé - (#{{ name }})')"
|
:placeholder="__('Payment Reminder from Frappé - (#{{ name }})')"
|
||||||
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
<FormControl
|
||||||
{{ __('Content Type') }}
|
type="select"
|
||||||
</div>
|
|
||||||
<Select
|
|
||||||
variant="outline"
|
|
||||||
v-model="_emailTemplate.content_type"
|
v-model="_emailTemplate.content_type"
|
||||||
|
:label="__('Content Type')"
|
||||||
default="Rich Text"
|
default="Rich Text"
|
||||||
:options="['Rich Text', 'HTML']"
|
:options="['Rich Text', 'HTML']"
|
||||||
:placeholder="__('Rich Text')"
|
:placeholder="__('Rich Text')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
|
||||||
{{ __('Content') }}
|
|
||||||
<span class="text-ink-red-3">*</span>
|
|
||||||
</div>
|
|
||||||
<FormControl
|
<FormControl
|
||||||
v-if="_emailTemplate.content_type === 'HTML'"
|
v-if="_emailTemplate.content_type === 'HTML'"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
variant="outline"
|
:label="__('Content')"
|
||||||
|
:required="true"
|
||||||
ref="content"
|
ref="content"
|
||||||
:rows="10"
|
:rows="10"
|
||||||
v-model="_emailTemplate.response_html"
|
v-model="_emailTemplate.response_html"
|
||||||
@ -80,20 +69,24 @@
|
|||||||
)
|
)
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<TextEditor
|
<div v-else>
|
||||||
v-else
|
<div class="mb-1.5 text-xs text-ink-gray-5">
|
||||||
variant="outline"
|
{{ __('Content') }}
|
||||||
ref="content"
|
<span class="text-ink-red-3">*</span>
|
||||||
editor-class="!prose-sm overflow-auto min-h-[180px] 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"
|
</div>
|
||||||
:bubbleMenu="true"
|
<TextEditor
|
||||||
:content="_emailTemplate.response"
|
ref="content"
|
||||||
@change="(val) => (_emailTemplate.response = val)"
|
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"
|
||||||
:placeholder="
|
:bubbleMenu="true"
|
||||||
__(
|
:content="_emailTemplate.response"
|
||||||
'Dear {{ lead_name }}, \n\nThis is a reminder for the payment of {{ grand_total }}. \n\nThanks, \nFrappé',
|
@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>
|
||||||
<div>
|
<div>
|
||||||
<Checkbox v-model="_emailTemplate.enabled" :label="__('Enabled')" />
|
<Checkbox v-model="_emailTemplate.enabled" :label="__('Enabled')" />
|
||||||
@ -106,7 +99,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { capture } from '@/telemetry'
|
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'
|
import { ref, nextTick, watch } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -229,9 +222,9 @@ watch(
|
|||||||
errorMessage.value = ''
|
errorMessage.value = ''
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (_emailTemplate.value.name) {
|
if (_emailTemplate.value.name) {
|
||||||
subjectRef.value.el.focus()
|
subjectRef.value?.el?.focus()
|
||||||
} else {
|
} else {
|
||||||
nameRef.value.el.focus()
|
nameRef.value?.el?.focus()
|
||||||
}
|
}
|
||||||
_emailTemplate.value = { ...props.emailTemplate }
|
_emailTemplate.value = { ...props.emailTemplate }
|
||||||
_emailTemplate.value.content_type = _emailTemplate.value.use_html
|
_emailTemplate.value.content_type = _emailTemplate.value.use_html
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog v-model="show" :options="{ size: '3xl' }">
|
<Dialog v-model="show" :options="{ size: '3xl' }">
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="bg-surface-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 class="mb-5 flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||||
|
|||||||
@ -19,7 +19,6 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<Button
|
<Button
|
||||||
v-if="_note?.reference_docname"
|
v-if="_note?.reference_docname"
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
size="sm"
|
||||||
:label="
|
:label="
|
||||||
_note.reference_doctype == 'CRM Deal'
|
_note.reference_doctype == 'CRM Deal'
|
||||||
@ -37,20 +36,19 @@
|
|||||||
<template #body-content>
|
<template #body-content>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">{{ __('Title') }}</div>
|
<FormControl
|
||||||
<TextInput
|
|
||||||
ref="title"
|
ref="title"
|
||||||
variant="outline"
|
:label="__('Title')"
|
||||||
v-model="_note.title"
|
v-model="_note.title"
|
||||||
:placeholder="__('Call with John Doe')"
|
:placeholder="__('Call with John Doe')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">{{ __('Content') }}</div>
|
<div class="mb-1.5 text-xs text-ink-gray-5">{{ __('Content') }}</div>
|
||||||
<TextEditor
|
<TextEditor
|
||||||
variant="outline"
|
variant="outline"
|
||||||
ref="content"
|
ref="content"
|
||||||
editor-class="!prose-sm overflow-auto min-h-[180px] 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"
|
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"
|
:bubbleMenu="true"
|
||||||
:content="_note.content"
|
:content="_note.content"
|
||||||
@change="(val) => (_note.content = val)"
|
@change="(val) => (_note.content = val)"
|
||||||
@ -149,12 +147,12 @@ watch(
|
|||||||
if (!value) return
|
if (!value) return
|
||||||
editMode.value = false
|
editMode.value = false
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
title.value.el.focus()
|
title.value?.el?.focus()
|
||||||
_note.value = { ...props.note }
|
_note.value = { ...props.note }
|
||||||
if (_note.value.title || _note.value.content) {
|
if (_note.value.title || _note.value.content) {
|
||||||
editMode.value = true
|
editMode.value = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog v-model="show" :options="dialogOptions">
|
<Dialog v-model="show" :options="dialogOptions">
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="bg-surface-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 class="mb-5 flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
|
||||||
|
|||||||
@ -19,7 +19,6 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<Button
|
<Button
|
||||||
v-if="task?.reference_docname"
|
v-if="task?.reference_docname"
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
size="sm"
|
||||||
:label="
|
:label="
|
||||||
task.reference_doctype == 'CRM Deal'
|
task.reference_doctype == 'CRM Deal'
|
||||||
@ -37,22 +36,21 @@
|
|||||||
<template #body-content>
|
<template #body-content>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">{{ __('Title') }}</div>
|
<FormControl
|
||||||
<TextInput
|
|
||||||
ref="title"
|
ref="title"
|
||||||
variant="outline"
|
:label="__('Title')"
|
||||||
v-model="_task.title"
|
v-model="_task.title"
|
||||||
:placeholder="__('Call with John Doe')"
|
:placeholder="__('Call with John Doe')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
<div class="mb-1.5 text-xs text-ink-gray-5">
|
||||||
{{ __('Description') }}
|
{{ __('Description') }}
|
||||||
</div>
|
</div>
|
||||||
<TextEditor
|
<TextEditor
|
||||||
variant="outline"
|
variant="outline"
|
||||||
ref="description"
|
ref="description"
|
||||||
editor-class="!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"
|
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"
|
:bubbleMenu="true"
|
||||||
:content="_task.description"
|
:content="_task.description"
|
||||||
@change="(val) => (_task.description = val)"
|
@change="(val) => (_task.description = val)"
|
||||||
|
|||||||
@ -5,15 +5,15 @@
|
|||||||
title: editMode
|
title: editMode
|
||||||
? __('Edit View')
|
? __('Edit View')
|
||||||
: duplicateMode
|
: duplicateMode
|
||||||
? __('Duplicate View')
|
? __('Duplicate View')
|
||||||
: __('Create View'),
|
: __('Create View'),
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
label: editMode
|
label: editMode
|
||||||
? __('Save Changes')
|
? __('Save Changes')
|
||||||
: duplicateMode
|
: duplicateMode
|
||||||
? __('Duplicate')
|
? __('Duplicate')
|
||||||
: __('Create'),
|
: __('Create'),
|
||||||
variant: 'solid',
|
variant: 'solid',
|
||||||
onClick: () => (editMode ? update() : create()),
|
onClick: () => (editMode ? update() : create()),
|
||||||
},
|
},
|
||||||
@ -27,16 +27,14 @@
|
|||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<IconPicker v-model="view.icon" v-slot="{ togglePopover }">
|
<IconPicker v-model="view.icon" v-slot="{ togglePopover }">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
|
||||||
size="md"
|
size="md"
|
||||||
class="flex size-8 text-2xl leading-none"
|
class="flex size-8 text-2xl leading-none"
|
||||||
:label="view.icon"
|
:label="view.icon"
|
||||||
@click="togglePopover"
|
@click="togglePopover"
|
||||||
/>
|
/>
|
||||||
</IconPicker>
|
</IconPicker>
|
||||||
<TextInput
|
<FormControl
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
variant="outline"
|
|
||||||
size="md"
|
size="md"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="__('My Open Deals')"
|
:placeholder="__('My Open Deals')"
|
||||||
@ -49,7 +47,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import IconPicker from '@/components/IconPicker.vue'
|
import IconPicker from '@/components/IconPicker.vue'
|
||||||
import { call, TextInput } from 'frappe-ui'
|
import { call } from 'frappe-ui'
|
||||||
import { ref, watch, nextTick } from 'vue'
|
import { ref, watch, nextTick } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -87,7 +85,7 @@ async function create() {
|
|||||||
view.value.doctype = props.doctype
|
view.value.doctype = props.doctype
|
||||||
let v = await call(
|
let v = await call(
|
||||||
'crm.fcrm.doctype.crm_view_settings.crm_view_settings.create',
|
'crm.fcrm.doctype.crm_view_settings.crm_view_settings.create',
|
||||||
{ view: view.value }
|
{ view: view.value },
|
||||||
)
|
)
|
||||||
show.value = false
|
show.value = false
|
||||||
props.options.afterCreate?.(v)
|
props.options.afterCreate?.(v)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="avatars?.length"
|
v-if="avatars?.length"
|
||||||
class="mr-1.5 flex cursor-pointer items-center"
|
class="mr-1.5 flex cursor-pointer items-center "
|
||||||
:class="[
|
:class="[
|
||||||
avatars?.length > 1 ? 'flex-row-reverse' : 'truncate [&>div]:truncate',
|
avatars?.length > 1 ? 'flex-row-reverse' : 'truncate [&>div]:truncate',
|
||||||
]"
|
]"
|
||||||
@ -24,7 +24,7 @@
|
|||||||
:key="avatar.name"
|
:key="avatar.name"
|
||||||
>
|
>
|
||||||
<Avatar
|
<Avatar
|
||||||
class="user-avatar -mr-1.5 transform ring-2 ring-white transition hover:z-10 hover:scale-110"
|
class="user-avatar -mr-1.5 transform ring-2 ring-outline-white transition hover:z-10 hover:scale-110"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
:image="avatar.image"
|
:image="avatar.image"
|
||||||
:label="avatar.label"
|
:label="avatar.label"
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
left: 'calc(100% + 1px)',
|
left: 'calc(100% + 1px)',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex h-screen flex-col">
|
<div class="flex h-screen flex-col text-ink-gray-9">
|
||||||
<div
|
<div
|
||||||
class="z-20 flex items-center justify-between border-b bg-surface-white px-5 py-2.5"
|
class="z-20 flex items-center justify-between border-b bg-surface-white px-5 py-2.5"
|
||||||
>
|
>
|
||||||
@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="notifications.data?.length"
|
v-if="notifications.data?.length"
|
||||||
class="divide-y overflow-auto text-base"
|
class="divide-y divide-outline-gray-modals overflow-auto text-base"
|
||||||
>
|
>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
v-for="n in notifications.data"
|
v-for="n in notifications.data"
|
||||||
|
|||||||
@ -2,14 +2,14 @@
|
|||||||
<div>
|
<div>
|
||||||
<Draggable :list="sections" item-key="label" class="flex flex-col gap-5.5">
|
<Draggable :list="sections" item-key="label" class="flex flex-col gap-5.5">
|
||||||
<template #item="{ element: section }">
|
<template #item="{ element: section }">
|
||||||
<div class="flex flex-col gap-1.5 p-2.5 bg-surface-menu-bar rounded">
|
<div class="flex flex-col gap-1.5 p-2.5 bg-surface-gray-2 rounded">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div
|
<div
|
||||||
class="flex h-7 max-w-fit cursor-pointer items-center gap-2 text-base font-medium leading-4"
|
class="flex h-7 max-w-fit cursor-pointer items-center gap-2 text-base font-medium leading-4 text-ink-gray-9"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="!section.editingLabel"
|
v-if="!section.editingLabel"
|
||||||
:class="section.hideLabel ? 'text-ink-gray-3' : ''"
|
:class="{ 'text-ink-gray-3': section.hideLabel }"
|
||||||
>
|
>
|
||||||
{{ __(section.label) || __('Untitled') }}
|
{{ __(section.label) || __('Untitled') }}
|
||||||
</div>
|
</div>
|
||||||
@ -48,7 +48,7 @@
|
|||||||
>
|
>
|
||||||
<template #item="{ element: field }">
|
<template #item="{ element: field }">
|
||||||
<div
|
<div
|
||||||
class="px-2.5 py-2 border rounded text-base bg-surface-white text-ink-gray-8 flex items-center leading-4 justify-between gap-2"
|
class="px-2.5 py-2 border border-outline-gray-2 rounded text-base bg-surface-modal text-ink-gray-8 flex items-center leading-4 justify-between gap-2"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<DragVerticalIcon class="h-3.5 cursor-grab" />
|
<DragVerticalIcon class="h-3.5 cursor-grab" />
|
||||||
@ -74,7 +74,7 @@
|
|||||||
<template #target="{ togglePopover }">
|
<template #target="{ togglePopover }">
|
||||||
<div class="gap-2 w-full">
|
<div class="gap-2 w-full">
|
||||||
<Button
|
<Button
|
||||||
class="w-full !h-8 !border-outline-gray-modals hover:!border-outline-gray-2"
|
class="w-full !h-8 !bg-surface-modal"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@click="togglePopover()"
|
@click="togglePopover()"
|
||||||
:label="__('Add Field')"
|
:label="__('Add Field')"
|
||||||
@ -86,7 +86,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #item-label="{ option }">
|
<template #item-label="{ option }">
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1 text-ink-gray-9">
|
||||||
<div>{{ option.label }}</div>
|
<div>{{ option.label }}</div>
|
||||||
<div class="text-ink-gray-4 text-sm">
|
<div class="text-ink-gray-4 text-sm">
|
||||||
{{ `${option.fieldname} - ${option.fieldtype}` }}
|
{{ `${option.fieldname} - ${option.fieldtype}` }}
|
||||||
|
|||||||
@ -112,6 +112,6 @@ let slaSection = computed(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
:deep(.form-control button) {
|
:deep(.form-control button) {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
background: white;
|
background: transparent;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -2,12 +2,12 @@
|
|||||||
<slot name="header" v-bind="{ opened, hide, open, close, toggle }">
|
<slot name="header" v-bind="{ opened, hide, open, close, toggle }">
|
||||||
<div v-if="!hide" class="flex items-center justify-between">
|
<div v-if="!hide" class="flex items-center justify-between">
|
||||||
<div
|
<div
|
||||||
class="flex h-7 max-w-fit cursor-pointer items-center gap-2 pl-2 pr-3 text-base font-semibold leading-5"
|
class="flex h-7 text-ink-gray-9 max-w-fit cursor-pointer items-center gap-2 pl-2 pr-3 text-base font-semibold leading-5"
|
||||||
@click="toggle()"
|
@click="toggle()"
|
||||||
>
|
>
|
||||||
<FeatherIcon
|
<FeatherIcon
|
||||||
name="chevron-right"
|
name="chevron-right"
|
||||||
class="h-4 text-ink-gray-9 transition-all duration-300 ease-in-out"
|
class="h-4 transition-all duration-300 ease-in-out"
|
||||||
:class="{ 'rotate-90': opened }"
|
:class="{ 'rotate-90': opened }"
|
||||||
/>
|
/>
|
||||||
{{ __(label) || __('Untitled') }}
|
{{ __(label) || __('Untitled') }}
|
||||||
|
|||||||
@ -39,7 +39,10 @@
|
|||||||
<div v-if="data[field.name]" class="truncate">
|
<div v-if="data[field.name]" class="truncate">
|
||||||
{{ data[field.name] }}
|
{{ data[field.name] }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="text-base leading-5 text-ink-gray-4 truncate">
|
<div
|
||||||
|
v-else
|
||||||
|
class="text-base leading-5 text-ink-gray-4 truncate"
|
||||||
|
>
|
||||||
{{ field.placeholder }}
|
{{ field.placeholder }}
|
||||||
</div>
|
</div>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
@ -52,7 +55,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div
|
<div
|
||||||
class="my-2 space-y-1.5 divide-y rounded-lg border border-gray-100 bg-surface-white p-1.5 shadow-xl"
|
class="my-2 p-1.5 min-w-40 space-y-1.5 divide-y divide-outline-gray-1 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
@ -161,16 +164,18 @@
|
|||||||
@change.stop="emit('update', field.name, $event.target.value)"
|
@change.stop="emit('update', field.name, $event.target.value)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ArrowUpRightIcon
|
<div class="ml-1">
|
||||||
v-if="field.type === 'link' && field.link && data[field.name]"
|
<ArrowUpRightIcon
|
||||||
class="h-4 w-4 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8"
|
v-if="field.type === 'link' && field.link && data[field.name]"
|
||||||
@click="field.link(data[field.name])"
|
class="h-4 w-4 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8"
|
||||||
/>
|
@click.stop="field.link(data[field.name])"
|
||||||
<EditIcon
|
/>
|
||||||
v-if="field.type === 'link' && field.edit && data[field.name]"
|
<EditIcon
|
||||||
class="size-3.5 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8"
|
v-if="field.type === 'link' && field.edit && data[field.name]"
|
||||||
@click="field.edit(data[field.name])"
|
class="size-3.5 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8"
|
||||||
/>
|
@click.stop="field.edit(data[field.name])"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</FadedScrollableDiv>
|
</FadedScrollableDiv>
|
||||||
@ -257,7 +262,7 @@ function evaluate(code, context = {}) {
|
|||||||
:deep(.form-control button),
|
:deep(.form-control button),
|
||||||
.dropdown-button {
|
.dropdown-button {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
background: white;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.form-control button) {
|
:deep(.form-control button) {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex h-full flex-col gap-8 p-8">
|
<div class="flex h-full flex-col gap-8 p-8 text-ink-gray-9">
|
||||||
<h2 class="flex gap-2 text-xl font-semibold leading-none h-5">
|
<h2 class="flex gap-2 text-xl font-semibold leading-none h-5">
|
||||||
{{ __('Send Invites To') }}
|
{{ __('Send Invites To') }}
|
||||||
</h2>
|
</h2>
|
||||||
@ -18,7 +18,6 @@
|
|||||||
type="select"
|
type="select"
|
||||||
class="mt-4"
|
class="mt-4"
|
||||||
v-model="role"
|
v-model="role"
|
||||||
variant="outline"
|
|
||||||
:label="__('Invite as')"
|
:label="__('Invite as')"
|
||||||
:options="[
|
:options="[
|
||||||
{ label: __('Regular Access'), value: 'Sales User' },
|
{ label: __('Regular Access'), value: 'Sales User' },
|
||||||
@ -35,7 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<ul class="flex flex-col gap-1">
|
<ul class="flex flex-col gap-1">
|
||||||
<li
|
<li
|
||||||
class="flex items-center justify-between px-2 py-1 rounded-lg bg-surface-menu-bar"
|
class="flex items-center justify-between px-2 py-1 rounded-lg bg-surface-gray-2"
|
||||||
v-for="user in pendingInvitations.data"
|
v-for="user in pendingInvitations.data"
|
||||||
:key="user.name"
|
:key="user.name"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
:label="profile.full_name"
|
:label="profile.full_name"
|
||||||
/>
|
/>
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<span class="text-2xl font-semibold">{{ profile.full_name }}</span>
|
<span class="text-2xl font-semibold text-ink-gray-9">{{ profile.full_name }}</span>
|
||||||
<span class="text-base text-ink-gray-7">{{ profile.email }}</span>
|
<span class="text-base text-ink-gray-7">{{ profile.email }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
>
|
>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="flex h-[calc(100vh_-_8rem)]">
|
<div class="flex h-[calc(100vh_-_8rem)]">
|
||||||
<div class="flex w-52 shrink-0 flex-col bg-surface-menu-bar p-2">
|
<div class="flex w-52 shrink-0 flex-col bg-surface-gray-2 p-2">
|
||||||
<h1 class="mb-3 px-2 pt-2 text-lg font-semibold">
|
<h1 class="mb-3 px-2 pt-2 text-lg font-semibold text-ink-gray-9">
|
||||||
{{ __('Settings') }}
|
{{ __('Settings') }}
|
||||||
</h1>
|
</h1>
|
||||||
<div v-for="tab in tabs">
|
<div v-for="tab in tabs">
|
||||||
@ -25,15 +25,15 @@
|
|||||||
class="w-full"
|
class="w-full"
|
||||||
:class="
|
:class="
|
||||||
activeTab?.label == i.label
|
activeTab?.label == i.label
|
||||||
? 'bg-surface-white shadow-sm'
|
? 'bg-surface-selected shadow-sm hover:bg-surface-selected'
|
||||||
: 'hover:bg-surface-gray-2'
|
: 'hover:bg-surface-gray-3'
|
||||||
"
|
"
|
||||||
@click="activeTab = i"
|
@click="activeTab = i"
|
||||||
/>
|
/>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-1 flex-col overflow-y-auto">
|
<div class="flex flex-1 flex-col overflow-y-auto bg-surface-modal">
|
||||||
<component :is="activeTab.component" v-if="activeTab" />
|
<component :is="activeTab.component" v-if="activeTab" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +41,6 @@
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import ContactsIcon from '@/components/Icons/ContactsIcon.vue'
|
|
||||||
import WhatsAppIcon from '@/components/Icons/WhatsAppIcon.vue'
|
import WhatsAppIcon from '@/components/Icons/WhatsAppIcon.vue'
|
||||||
import ERPNextIcon from '@/components/Icons/ERPNextIcon.vue'
|
import ERPNextIcon from '@/components/Icons/ERPNextIcon.vue'
|
||||||
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||||
@ -57,10 +56,12 @@ import {
|
|||||||
showSettings,
|
showSettings,
|
||||||
activeSettingsPage,
|
activeSettingsPage,
|
||||||
} from '@/composables/settings'
|
} from '@/composables/settings'
|
||||||
import { Dialog } from 'frappe-ui'
|
import { Dialog, Avatar } from 'frappe-ui'
|
||||||
import { ref, markRaw, computed, watch } from 'vue'
|
import { ref, markRaw, computed, watch, h } from 'vue'
|
||||||
|
|
||||||
const { isManager } = usersStore()
|
const { isManager, getUser } = usersStore()
|
||||||
|
|
||||||
|
const user = computed(() => getUser() || {})
|
||||||
|
|
||||||
const tabs = computed(() => {
|
const tabs = computed(() => {
|
||||||
let _tabs = [
|
let _tabs = [
|
||||||
@ -70,7 +71,12 @@ const tabs = computed(() => {
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: __('Profile'),
|
label: __('Profile'),
|
||||||
icon: ContactsIcon,
|
icon: () =>
|
||||||
|
h(Avatar, {
|
||||||
|
size: 'xs',
|
||||||
|
label: user.value.full_name,
|
||||||
|
image: user.value.user_image,
|
||||||
|
}),
|
||||||
component: markRaw(ProfileSettings),
|
component: markRaw(ProfileSettings),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex h-full flex-col gap-8">
|
<div class="flex h-full flex-col gap-8">
|
||||||
<h2 class="flex gap-2 text-xl font-semibold leading-none h-5">
|
<h2 class="flex gap-2 text-xl font-semibold leading-none h-5 text-ink-gray-9">
|
||||||
<div>{{ title || __(doctype) }}</div>
|
<div>{{ title || __(doctype) }}</div>
|
||||||
<Badge
|
<Badge
|
||||||
v-if="data.isDirty"
|
v-if="data.isDirty"
|
||||||
|
|||||||
@ -4,15 +4,15 @@
|
|||||||
<template #item="{ element: section }">
|
<template #item="{ element: section }">
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<div
|
<div
|
||||||
class="flex items-center justify-between rounded px-2.5 py-2 bg-surface-menu-bar"
|
class="flex items-center justify-between rounded px-2.5 py-2 bg-surface-gray-2"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex max-w-fit cursor-pointer items-center gap-2 text-base leading-4"
|
class="flex max-w-fit cursor-pointer items-center gap-2 text-base leading-4 text-ink-gray-9"
|
||||||
@click="section.opened = !section.opened"
|
@click="section.opened = !section.opened"
|
||||||
>
|
>
|
||||||
<FeatherIcon
|
<FeatherIcon
|
||||||
name="chevron-right"
|
name="chevron-right"
|
||||||
class="h-4 text-ink-gray-9 transition-all duration-300 ease-in-out"
|
class="h-4 transition-all duration-300 ease-in-out"
|
||||||
:class="{ 'rotate-90': section.opened }"
|
:class="{ 'rotate-90': section.opened }"
|
||||||
/>
|
/>
|
||||||
<div v-if="!section.editingLabel">
|
<div v-if="!section.editingLabel">
|
||||||
@ -62,7 +62,7 @@
|
|||||||
>
|
>
|
||||||
<template #item="{ element: field }">
|
<template #item="{ element: field }">
|
||||||
<div
|
<div
|
||||||
class="px-2.5 py-2 border rounded text-base leading-4 text-ink-gray-8 flex items-center justify-between gap-2"
|
class="px-2.5 py-2 border border-outline-gray-modals rounded text-base leading-4 text-ink-gray-8 flex items-center justify-between gap-2"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<DragVerticalIcon class="h-3.5 cursor-grab" />
|
<DragVerticalIcon class="h-3.5 cursor-grab" />
|
||||||
@ -87,7 +87,7 @@
|
|||||||
>
|
>
|
||||||
<template #target="{ togglePopover }">
|
<template #target="{ togglePopover }">
|
||||||
<Button
|
<Button
|
||||||
class="w-full h-8 mt-1.5 !border-outline-gray-modals hover:!border-outline-gray-2"
|
class="w-full h-8 mt-1.5 !bg-surface-gray-1"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@click="togglePopover()"
|
@click="togglePopover()"
|
||||||
:label="__('Add Field')"
|
:label="__('Add Field')"
|
||||||
@ -98,7 +98,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
<template #item-label="{ option }">
|
<template #item-label="{ option }">
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1 text-ink-gray-9">
|
||||||
<div>{{ option.label }}</div>
|
<div>{{ option.label }}</div>
|
||||||
<div class="text-ink-gray-4 text-sm">
|
<div class="text-ink-gray-4 text-sm">
|
||||||
{{ `${option.fieldname} - ${option.fieldtype}` }}
|
{{ `${option.fieldname} - ${option.fieldtype}` }}
|
||||||
@ -108,7 +108,7 @@
|
|||||||
</Autocomplete>
|
</Autocomplete>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="flex justify-center items-center border rounded border-dashed p-3"
|
class="flex justify-center items-center border rounded border-dashed border-outline-gray-modals p-3"
|
||||||
>
|
>
|
||||||
<div class="text-sm text-ink-gray-4">
|
<div class="text-sm text-ink-gray-4">
|
||||||
{{ __('This section is not editable') }}
|
{{ __('This section is not editable') }}
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="flex flex-1 justify-center items-center text-ink-gray-5 bg-surface-menu-bar rounded border border-gray-50"
|
class="flex flex-1 justify-center items-center text-ink-gray-5 bg-surface-gray-2 rounded"
|
||||||
>
|
>
|
||||||
{{ __('Toggle on for preview') }}
|
{{ __('Toggle on for preview') }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<button
|
<button
|
||||||
class="flex h-7 cursor-pointer items-center rounded text-ink-gray-7 duration-300 ease-in-out focus:outline-none focus:transition-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-outline-gray-3"
|
class="flex h-7 cursor-pointer items-center rounded text-ink-gray-7 duration-300 ease-in-out focus:outline-none focus:transition-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-outline-gray-3"
|
||||||
:class="isActive ? 'bg-surface-white shadow-sm' : 'hover:bg-surface-gray-2'"
|
:class="isActive ? 'bg-surface-selected shadow-sm' : 'hover:bg-surface-gray-2'"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -55,7 +55,7 @@ const route = useRoute()
|
|||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
icon: {
|
icon: {
|
||||||
type: [Object, String],
|
type: [Object, String, Function],
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
<template v-if="!hideLabel" #prefix><SortIcon class="h-4" /></template>
|
<template v-if="!hideLabel" #prefix><SortIcon class="h-4" /></template>
|
||||||
<template v-if="sortValues?.size" #suffix>
|
<template v-if="sortValues?.size" #suffix>
|
||||||
<div
|
<div
|
||||||
class="flex h-5 w-5 items-center justify-center rounded bg-surface-gray-7 pt-[1px] text-2xs font-medium text-ink-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"
|
||||||
>
|
>
|
||||||
{{ sortValues.size }}
|
{{ sortValues.size }}
|
||||||
</div>
|
</div>
|
||||||
@ -52,6 +52,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
:label="getSortLabel()"
|
:label="getSortLabel()"
|
||||||
|
class="shrink-0"
|
||||||
:class="sortValues.size ? 'rounded-l-none' : ''"
|
:class="sortValues.size ? 'rounded-l-none' : ''"
|
||||||
>
|
>
|
||||||
<template v-if="!hideLabel && !sortValues?.size" #prefix>
|
<template v-if="!hideLabel && !sortValues?.size" #prefix>
|
||||||
@ -67,7 +68,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ close }">
|
<template #body="{ close }">
|
||||||
<div class="my-2 rounded-lg border border-gray-100 bg-surface-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-60 p-2">
|
<div class="min-w-60 p-2">
|
||||||
<div
|
<div
|
||||||
v-if="sortValues?.size"
|
v-if="sortValues?.size"
|
||||||
@ -82,7 +85,7 @@
|
|||||||
<div class="handle flex h-7 w-7 items-center justify-center">
|
<div class="handle flex h-7 w-7 items-center justify-center">
|
||||||
<DragIcon class="h-4 w-4 cursor-grab text-ink-gray-5" />
|
<DragIcon class="h-4 w-4 cursor-grab text-ink-gray-5" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex">
|
<div class="flex flex-1 [&>_div]:w-full">
|
||||||
<Button
|
<Button
|
||||||
size="md"
|
size="md"
|
||||||
class="rounded-r-none border-r"
|
class="rounded-r-none border-r"
|
||||||
@ -97,7 +100,6 @@
|
|||||||
<DesendingIcon v-else class="h-4" />
|
<DesendingIcon v-else class="h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
class="!w-32"
|
|
||||||
:value="sort.fieldname"
|
:value="sort.fieldname"
|
||||||
:options="sortOptions.data"
|
:options="sortOptions.data"
|
||||||
@change="(e) => updateSort(e, i)"
|
@change="(e) => updateSort(e, i)"
|
||||||
@ -240,7 +242,7 @@ function getSortLabel() {
|
|||||||
if (!sortValues.value.size) return __('Sort')
|
if (!sortValues.value.size) return __('Sort')
|
||||||
let values = Array.from(sortValues.value)
|
let values = Array.from(sortValues.value)
|
||||||
let label = sortOptions.data?.find(
|
let label = sortOptions.data?.find(
|
||||||
(option) => option.value === values[0].fieldname
|
(option) => option.value === values[0].fieldname,
|
||||||
)?.label
|
)?.label
|
||||||
|
|
||||||
return label || sort.fieldname
|
return label || sort.fieldname
|
||||||
|
|||||||
@ -27,10 +27,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #item="{ item, active }">
|
<template #item="{ item, active }">
|
||||||
<button
|
<button
|
||||||
:class="[
|
class="group flex text-ink-gray-6 gap-4 h-7 w-full justify-between items-center rounded px-2 text-base"
|
||||||
active ? 'bg-surface-gray-2' : 'text-ink-gray-8',
|
:class="{ 'bg-surface-gray-3': active }"
|
||||||
'group flex gap-4 h-7 w-full justify-between items-center rounded px-2 text-base',
|
|
||||||
]"
|
|
||||||
@click="item.onClick"
|
@click="item.onClick"
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
>
|
>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<button
|
<button
|
||||||
class="flex w-full items-center justify-between focus:outline-none"
|
class="flex h-7 w-full items-center justify-between gap-2 rounded bg-surface-gray-2 px-2 py-1 transition-colors hover:bg-surface-gray-3 border border-transparent focus:border-outline-gray-4 focus:outline-none focus:ring-2 focus:ring-outline-gray-3"
|
||||||
:class="inputClasses"
|
:class="inputClasses"
|
||||||
@click="() => togglePopover()"
|
@click="() => togglePopover()"
|
||||||
>
|
>
|
||||||
@ -41,11 +41,13 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body="{ isOpen }">
|
<template #body="{ isOpen }">
|
||||||
<div v-show="isOpen">
|
<div v-show="isOpen">
|
||||||
<div class="mt-1 rounded-lg bg-surface-white py-1 text-base shadow-2xl">
|
<div
|
||||||
<div class="relative px-1.5 pt-0.5">
|
class="relative mt-1 rounded-lg bg-surface-modal text-base shadow-2xl"
|
||||||
|
>
|
||||||
|
<div class="relative px-1.5 pt-1.5">
|
||||||
<ComboboxInput
|
<ComboboxInput
|
||||||
ref="search"
|
ref="search"
|
||||||
class="form-input w-full"
|
class="form-input w-full focus:bg-surface-gray-3 hover:bg-surface-gray-4 text-ink-gray-8"
|
||||||
type="text"
|
type="text"
|
||||||
@change="
|
@change="
|
||||||
(e) => {
|
(e) => {
|
||||||
@ -60,7 +62,7 @@
|
|||||||
class="absolute right-1.5 inline-flex h-7 w-7 items-center justify-center"
|
class="absolute right-1.5 inline-flex h-7 w-7 items-center justify-center"
|
||||||
@click="selectedValue = null"
|
@click="selectedValue = null"
|
||||||
>
|
>
|
||||||
<FeatherIcon name="x" class="w-4" />
|
<FeatherIcon name="x" class="w-4 text-ink-gray-8" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ComboboxOptions
|
<ComboboxOptions
|
||||||
@ -75,7 +77,7 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="group.group && !group.hideLabel"
|
v-if="group.group && !group.hideLabel"
|
||||||
class="px-2.5 py-1.5 text-sm font-medium text-ink-gray-4"
|
class="truncate bg-surface-modal px-2.5 py-1.5 text-sm font-medium text-ink-gray-5"
|
||||||
>
|
>
|
||||||
{{ group.group }}
|
{{ group.group }}
|
||||||
</div>
|
</div>
|
||||||
@ -88,8 +90,8 @@
|
|||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
:class="[
|
:class="[
|
||||||
'flex items-center rounded px-2.5 py-1.5 text-base',
|
'flex cursor-pointer items-center rounded px-2.5 py-1.5 text-base',
|
||||||
{ 'bg-surface-gray-2': active },
|
{ 'bg-surface-gray-3': active },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<slot
|
<slot
|
||||||
@ -100,19 +102,24 @@
|
|||||||
name="item-label"
|
name="item-label"
|
||||||
v-bind="{ active, selected, option }"
|
v-bind="{ active, selected, option }"
|
||||||
>
|
>
|
||||||
{{ option.label }}
|
<div class="flex-1 truncate text-ink-gray-7">
|
||||||
|
{{ option.label }}
|
||||||
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
</li>
|
</li>
|
||||||
</ComboboxOption>
|
</ComboboxOption>
|
||||||
</div>
|
</div>
|
||||||
<li
|
<li
|
||||||
v-if="groups.length == 0"
|
v-if="groups.length == 0"
|
||||||
class="mt-1.5 rounded-md px-2.5 py-1.5 text-base text-ink-gray-5"
|
class="my-1.5 rounded-md px-2.5 py-1.5 text-base text-ink-gray-5"
|
||||||
>
|
>
|
||||||
No results found
|
No results found
|
||||||
</li>
|
</li>
|
||||||
</ComboboxOptions>
|
</ComboboxOptions>
|
||||||
<div v-if="slots.footer" class="border-t p-1.5 pb-0.5">
|
<div
|
||||||
|
v-if="slots.footer"
|
||||||
|
class="border-t border-outline-gray-modals p-1.5"
|
||||||
|
>
|
||||||
<slot
|
<slot
|
||||||
name="footer"
|
name="footer"
|
||||||
v-bind="{ value: search?.el._value, close }"
|
v-bind="{ value: search?.el._value, close }"
|
||||||
@ -219,7 +226,7 @@ function filterOptions(options) {
|
|||||||
return options.filter((option) => {
|
return options.filter((option) => {
|
||||||
let searchTexts = [option.label, option.value]
|
let searchTexts = [option.label, option.value]
|
||||||
return searchTexts.some((text) =>
|
return searchTexts.some((text) =>
|
||||||
(text || '').toString().toLowerCase().includes(query.value.toLowerCase())
|
(text || '').toString().toLowerCase().includes(query.value.toLowerCase()),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -272,7 +279,9 @@ const inputClasses = computed(() => {
|
|||||||
'border border-outline-gray-2 bg-surface-white placeholder-ink-gray-4 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',
|
'border border-outline-gray-2 bg-surface-white placeholder-ink-gray-4 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',
|
||||||
disabled: [
|
disabled: [
|
||||||
'border bg-surface-menu-bar placeholder-ink-gray-3',
|
'border bg-surface-menu-bar placeholder-ink-gray-3',
|
||||||
props.variant === 'outline' ? 'border-outline-gray-2' : 'border-transparent',
|
props.variant === 'outline'
|
||||||
|
? 'border-outline-gray-2'
|
||||||
|
: 'border-transparent',
|
||||||
],
|
],
|
||||||
}[variant]
|
}[variant]
|
||||||
|
|
||||||
|
|||||||
@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
<template #body>
|
<template #body>
|
||||||
<div
|
<div
|
||||||
class="rounded-lg bg-surface-white shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
class="mt-2 min-w-40 divide-y divide-outline-gray-modals rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||||
:class="{
|
:class="{
|
||||||
'mt-2': ['bottom', 'left', 'right'].includes(placement),
|
'mt-2': ['bottom', 'left', 'right'].includes(placement),
|
||||||
'ml-2': placement == 'right-start',
|
'ml-2': placement == 'right-start',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<MenuItems
|
<MenuItems
|
||||||
class="min-w-40 divide-y divide-gray-100"
|
class="min-w-40 divide-y divide-outline-gray-modals"
|
||||||
:class="{
|
:class="{
|
||||||
'left-0 origin-top-left': placement == 'left',
|
'left-0 origin-top-left': placement == 'left',
|
||||||
'right-0 origin-top-right': placement == 'right',
|
'right-0 origin-top-right': placement == 'right',
|
||||||
@ -52,7 +52,7 @@
|
|||||||
<button
|
<button
|
||||||
v-else
|
v-else
|
||||||
:class="[
|
:class="[
|
||||||
active ? 'bg-surface-gray-2' : 'text-ink-gray-8',
|
active ? 'bg-surface-gray-3' : 'text-ink-gray-6',
|
||||||
'group flex h-7 w-full items-center rounded px-2 text-base',
|
'group flex h-7 w-full items-center rounded px-2 text-base',
|
||||||
]"
|
]"
|
||||||
@click="item.onClick"
|
@click="item.onClick"
|
||||||
@ -68,7 +68,7 @@
|
|||||||
v-else-if="item.icon"
|
v-else-if="item.icon"
|
||||||
:is="item.icon"
|
:is="item.icon"
|
||||||
/>
|
/>
|
||||||
<span class="whitespace-nowrap">
|
<span class="whitespace-nowrap text-ink-gray-7">
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -60,11 +60,13 @@
|
|||||||
clip-path: inset(22px 0 0 0);
|
clip-path: inset(22px 0 0 0);
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<CameraIcon class="h-6 w-6 cursor-pointer text-ink-white" />
|
<CameraIcon
|
||||||
|
class="h-6 w-6 cursor-pointer text-white"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2 truncate">
|
<div class="flex flex-col gap-2 truncate text-ink-gray-9">
|
||||||
<div class="truncate text-2xl font-medium">
|
<div class="truncate text-2xl font-medium">
|
||||||
<span v-if="contact.data.salutation">
|
<span v-if="contact.data.salutation">
|
||||||
{{ contact.data.salutation + '. ' }}
|
{{ contact.data.salutation + '. ' }}
|
||||||
@ -150,7 +152,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Resizer>
|
</Resizer>
|
||||||
<Tabs class="overflow-hidden" v-model="tabIndex" :tabs="tabs">
|
<Tabs class="!h-full" v-model="tabIndex" :tabs="tabs">
|
||||||
<template #tab="{ tab, selected }">
|
<template #tab="{ tab, selected }">
|
||||||
<button
|
<button
|
||||||
class="group flex items-center gap-2 border-b border-transparent py-2.5 text-base text-ink-gray-5 duration-300 ease-in-out hover:border-outline-gray-3 hover:text-ink-gray-9"
|
class="group flex items-center gap-2 border-b border-transparent py-2.5 text-base text-ink-gray-5 duration-300 ease-in-out hover:border-outline-gray-3 hover:text-ink-gray-9"
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
<Resizer side="right" class="flex flex-col justify-between border-l">
|
<Resizer side="right" class="flex flex-col justify-between border-l">
|
||||||
<div
|
<div
|
||||||
class="flex h-10.5 cursor-copy items-center border-b px-5 py-2.5 text-lg font-medium"
|
class="flex h-10.5 cursor-copy items-center border-b px-5 py-2.5 text-lg font-medium text-ink-gray-9"
|
||||||
@click="copyToClipboard(deal.data.name)"
|
@click="copyToClipboard(deal.data.name)"
|
||||||
>
|
>
|
||||||
{{ __(deal.data.name) }}
|
{{ __(deal.data.name) }}
|
||||||
@ -64,7 +64,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div class="flex flex-col gap-2.5 truncate">
|
<div class="flex flex-col gap-2.5 truncate text-ink-gray-9">
|
||||||
<Tooltip :text="organization.data?.name || __('Set an organization')">
|
<Tooltip :text="organization.data?.name || __('Set an organization')">
|
||||||
<div class="truncate text-2xl font-medium">
|
<div class="truncate text-2xl font-medium">
|
||||||
{{ organization.data?.name || __('Untitled') }}
|
{{ organization.data?.name || __('Untitled') }}
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
<Resizer class="flex flex-col justify-between border-l" side="right">
|
<Resizer class="flex flex-col justify-between border-l" side="right">
|
||||||
<div
|
<div
|
||||||
class="flex h-10.5 cursor-copy items-center border-b px-5 py-2.5 text-lg font-medium"
|
class="flex h-10.5 cursor-copy items-center border-b px-5 py-2.5 text-lg font-medium text-ink-gray-9"
|
||||||
@click="copyToClipboard(lead.data.name)"
|
@click="copyToClipboard(lead.data.name)"
|
||||||
>
|
>
|
||||||
{{ __(lead.data.name) }}
|
{{ __(lead.data.name) }}
|
||||||
@ -102,13 +102,13 @@
|
|||||||
clip-path: inset(12px 0 0 0);
|
clip-path: inset(12px 0 0 0);
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<CameraIcon class="size-4 cursor-pointer text-ink-white" />
|
<CameraIcon class="size-4 cursor-pointer text-white" />
|
||||||
</div>
|
</div>
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2.5 truncate">
|
<div class="flex flex-col gap-2.5 truncate">
|
||||||
<Tooltip :text="lead.data.lead_name || __('Set first name')">
|
<Tooltip :text="lead.data.lead_name || __('Set first name')">
|
||||||
<div class="truncate text-2xl font-medium">
|
<div class="truncate text-2xl font-medium text-ink-gray-9">
|
||||||
{{ lead.data.lead_name || __('Untitled') }}
|
{{ lead.data.lead_name || __('Untitled') }}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@ -53,12 +53,12 @@
|
|||||||
clip-path: inset(22px 0 0 0);
|
clip-path: inset(22px 0 0 0);
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<CameraIcon class="h-6 w-6 cursor-pointer text-ink-white" />
|
<CameraIcon class="h-6 w-6 cursor-pointer text-white" />
|
||||||
</div>
|
</div>
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2 truncate">
|
<div class="flex flex-col gap-2 truncate">
|
||||||
<div class="truncate text-lg font-medium">
|
<div class="truncate text-lg font-medium text-ink-gray-9">
|
||||||
<span v-if="contact.data.salutation">
|
<span v-if="contact.data.salutation">
|
||||||
{{ contact.data.salutation + '. ' }}
|
{{ contact.data.salutation + '. ' }}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -22,10 +22,10 @@
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</template>
|
</template>
|
||||||
</LayoutHeader>
|
</LayoutHeader>
|
||||||
<div class="flex flex-col overflow-hidden">
|
<div class="flex flex-col overflow-hidden text-ink-gray-9">
|
||||||
<div
|
<div
|
||||||
v-if="notifications.data?.length"
|
v-if="notifications.data?.length"
|
||||||
class="divide-y overflow-y-auto text-base"
|
class="divide-y divide-outline-gray-1 overflow-y-auto text-base"
|
||||||
>
|
>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
v-for="n in notifications.data"
|
v-for="n in notifications.data"
|
||||||
|
|||||||
@ -56,12 +56,12 @@
|
|||||||
clip-path: inset(22px 0 0 0);
|
clip-path: inset(22px 0 0 0);
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<CameraIcon class="h-6 w-6 cursor-pointer text-ink-white" />
|
<CameraIcon class="h-6 w-6 cursor-pointer text-white" />
|
||||||
</div>
|
</div>
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2 truncate">
|
<div class="flex flex-col gap-2 truncate">
|
||||||
<div class="truncate text-lg font-medium">
|
<div class="truncate text-lg font-medium text-ink-gray-9">
|
||||||
{{ organization.doc.name }}
|
{{ organization.doc.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-1.5">
|
<div class="flex items-center gap-1.5">
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
@click="editNote(note)"
|
@click="editNote(note)"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div class="truncate text-lg font-medium">
|
<div class="truncate text-lg font-medium text-ink-gray-9">
|
||||||
{{ note.title }}
|
{{ note.title }}
|
||||||
</div>
|
</div>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
|
|||||||
@ -60,12 +60,12 @@
|
|||||||
clip-path: inset(22px 0 0 0);
|
clip-path: inset(22px 0 0 0);
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<CameraIcon class="h-6 w-6 cursor-pointer text-ink-white" />
|
<CameraIcon class="h-6 w-6 cursor-pointer text-white" />
|
||||||
</div>
|
</div>
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2 truncate">
|
<div class="flex flex-col gap-2 truncate">
|
||||||
<div class="truncate text-2xl font-medium">
|
<div class="truncate text-2xl font-medium text-ink-gray-9">
|
||||||
<span>{{ organization.doc.name }}</span>
|
<span>{{ organization.doc.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -135,7 +135,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Resizer>
|
</Resizer>
|
||||||
<Tabs class="overflow-hidden" v-model="tabIndex" :tabs="tabs">
|
<Tabs class="!h-full" v-model="tabIndex" :tabs="tabs">
|
||||||
<template #tab="{ tab, selected }">
|
<template #tab="{ tab, selected }">
|
||||||
<button
|
<button
|
||||||
class="group flex items-center gap-2 border-b border-transparent py-2.5 text-base text-ink-gray-5 duration-300 ease-in-out hover:border-outline-gray-3 hover:text-ink-gray-9"
|
class="group flex items-center gap-2 border-b border-transparent py-2.5 text-base text-ink-gray-5 duration-300 ease-in-out hover:border-outline-gray-3 hover:text-ink-gray-9"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user