chore: Feedback fixes

This commit is contained in:
iamsivin
2025-12-22 17:22:42 +05:30
parent 8191d65033
commit dcd41cdae0
30 changed files with 124 additions and 60 deletions
@@ -84,7 +84,7 @@ const CurrentAttributeComponent = computed(() => {
v-if="attribute.attributeDescription"
:message="attribute.attributeDescription"
/>
<span class="text-sm font-420 truncate text-n-slate-12">
<span class="text-body-main truncate text-n-slate-12">
{{ attribute.attributeDisplayName }}
</span>
</div>
@@ -82,7 +82,7 @@ onMounted(() => {
<p
ref="noteContentRef"
v-dompurify-html="formatMessage(note.content || '')"
class="mb-0 font-420 prose-sm prose-p:text-sm prose-p:leading-relaxed prose-p:mb-1 prose-p:mt-0 prose-ul:mb-1 prose-ul:mt-0 text-n-slate-12"
class="mb-0 text-body-main prose-sm prose-p:text-sm prose-p:leading-relaxed prose-p:mb-1 prose-p:mt-0 prose-ul:mb-1 prose-ul:mt-0 text-n-slate-12"
:class="{
'line-clamp-4': collapsible && !isExpanded && needsCollapse,
}"
@@ -10,12 +10,9 @@ defineProps({
</script>
<template>
<div
:title="inbox.name"
class="flex items-center gap-0.5 text-n-slate-11 min-w-0"
>
<ChannelIcon :inbox="inbox" class="size-4 flex-shrink-0" />
<span class="truncate text-label-small">
<div :title="inbox.name" class="flex items-center gap-0.5 min-w-0">
<ChannelIcon :inbox="inbox" class="size-4 flex-shrink-0 text-n-slate-11" />
<span class="truncate text-label-small text-n-slate-12">
{{ inbox.name }}
</span>
</div>
@@ -78,9 +78,9 @@ const handleInputUpdate = async () => {
<div class="flex items-center w-full min-w-0 gap-1.5 justify-end">
<span
v-if="!isEditingValue"
class="min-w-0 text-sm"
class="min-w-0 text-body-main"
:class="{
'cursor-pointer text-n-slate-11 hover:text-n-slate-12 py-2 select-none font-medium':
'cursor-pointer text-n-slate-11 hover:text-n-slate-12 py-2 select-none !font-medium':
!isEditingView,
'text-n-slate-12 truncate': isEditingView && attribute.value,
'text-n-slate-10 truncate': isEditingView && !attribute.value,
@@ -52,9 +52,9 @@ const handleAttributeAction = async action => {
content: attribute.value,
delay: { show: 1000, hide: 0 },
}"
class="min-w-0 text-sm truncate font-420"
class="min-w-0 text-body-main truncate"
:class="{
'text-n-slate-11 hover:text-n-slate-12 py-2 select-none font-medium':
'text-n-slate-11 hover:text-n-slate-12 py-2 select-none !font-medium':
!isEditingView,
'text-n-slate-12': isEditingView && attribute.value,
'text-n-slate-10': isEditingView && !attribute.value,
@@ -121,9 +121,9 @@ const handleInputUpdate = async () => {
content: !isAttributeTypeLink ? attribute.value : '',
delay: { show: 1000, hide: 0 },
}"
class="min-w-0 text-sm cursor-pointer font-420"
class="min-w-0 cursor-pointer text-body-main"
:class="{
'text-n-slate-11 hover:text-n-slate-12 py-2 select-none font-medium':
'text-n-slate-11 hover:text-n-slate-12 py-2 select-none !font-medium':
!isEditingView,
'text-n-slate-12 truncate':
isEditingView && !isAttributeTypeLink && attribute.value,
@@ -20,10 +20,10 @@ const handleButtonClick = button => {
<template>
<div
class="flex flex-col items-start gap-3 justify-between ltr:pl-4 ltr:pr-2 rtl:pl-2 rtl:pr-4 my-2 py-2"
class="flex flex-col items-start gap-3 justify-between ltr:pl-4 ltr:pr-2 rtl:pl-2 rtl:pr-4 my-2 pt-2"
>
<div class="flex items-center justify-between gap-2 flex-1 w-full">
<span class="font-medium text-base text-n-slate-12">{{ title }}</span>
<span class="text-heading-1 text-n-slate-12">{{ title }}</span>
<div class="flex items-center h-6">
<Button
v-for="button in buttons"
@@ -154,6 +154,13 @@ const STYLE_CONFIG = {
'text-n-teal-9 hover:enabled:bg-n-alpha-2 focus-visible:bg-n-alpha-2 outline-transparent',
},
},
iconColor: {
blue: 'text-n-blue-11',
ruby: 'text-n-ruby-11',
amber: 'text-n-amber-11',
slate: 'text-n-slate-11',
teal: 'text-n-teal-11',
},
sizes: {
regular: {
xs: 'h-6 px-2 rounded-lg',
@@ -249,7 +256,11 @@ const animationClasses = computed(() => {
}"
>
<slot v-if="(icon || $slots.icon) && !isLoading" name="icon">
<Icon :icon="icon" class="flex-shrink-0" />
<Icon
:icon="icon"
class="flex-shrink-0"
:class="STYLE_CONFIG.iconColor[computedColor]"
/>
</slot>
<Spinner v-if="isLoading" class="!w-5 !h-5 flex-shrink-0" />
@@ -24,7 +24,7 @@ defineProps({
/>
<span
class="text-n-slate-12 whitespace-nowrap"
:class="compact ? 'text-label-small' : 'text-label !font-440'"
:class="compact ? 'text-label-small' : 'text-label !font-420'"
>
{{ label.title }}
</span>
@@ -29,7 +29,7 @@ const onToggle = () => {
class="flex items-center select-none w-full m-0 cursor-grab justify-between drag-handle px-4 py-0 focus-visible:outline-none outline-none !transition-none"
@click.stop="onToggle"
>
<h5 class="text-n-slate-12 text-sm font-medium mb-0 py-0 pr-2 pl-0">
<h5 class="text-n-slate-12 text-heading-2 mb-0 py-0 pr-2 pl-0">
{{ title }}
</h5>
<div
@@ -184,7 +184,7 @@ useEmitter(CMD_RESOLVE_CONVERSATION, onCmdResolveConversation);
<div
v-if="showActionsDropdown"
v-on-clickaway="closeDropdown"
class="border rounded-xl shadow-lg border-n-strong dark:border-n-strong box-content p-2 w-fit z-10 bg-n-alpha-3 backdrop-blur-[100px] absolute block top-full mt-0.5 start-0 sm:start-auto sm:end-0 xl:start-0 max-w-[12.5rem] min-w-[9.75rem] [&_ul>li]:mb-0"
class="border rounded-xl shadow-lg border-n-strong dark:border-n-strong box-content p-2 w-fit z-10 bg-n-alpha-3 backdrop-blur-[100px] absolute block top-full mt-0.5 start-0 sm:start-auto sm:end-0 max-w-[12.5rem] min-w-[9.75rem] [&_ul>li]:mb-0"
>
<Button
v-if="!isPending"
@@ -58,7 +58,7 @@ watch(
<div v-else-if="error" class="text-center text-n-ruby-12">
{{ error }}
</div>
<div v-else-if="!orders.length" class="mt-2">
<div v-else-if="!orders.length">
<SidePanelEmptyState
:message="$t('CONVERSATION_SIDEBAR.SHOPIFY.NO_SHOPIFY_ORDERS')"
/>
@@ -87,7 +87,7 @@ onMounted(() => {
<template>
<div>
<div class="pt-3 px-3 pb-2">
<div v-if="hasIssues" class="pt-3 px-3 pb-2">
<NextButton
sm
slate
@@ -101,10 +101,18 @@ onMounted(() => {
<Spinner />
</div>
<div v-else-if="!hasIssues" class="mt-2">
<div v-else-if="!hasIssues" class="mt-2 px-3 w-full">
<SidePanelEmptyState
:message="$t('INTEGRATION_SETTINGS.LINEAR.NO_LINKED_ISSUES')"
/>
<NextButton
sm
slate
icon="i-lucide-plus"
:label="$t('INTEGRATION_SETTINGS.LINEAR.ADD_OR_LINK_BUTTON')"
class="w-full mt-2"
@click="openCreateModal"
/>
</div>
<div v-else class="max-h-[300px] overflow-y-auto px-2">
@@ -53,13 +53,13 @@ const unlinkIssue = () => {
@unlink-issue="unlinkIssue"
/>
<h3 class="mt-2 text-sm font-medium text-n-slate-12">
<h3 class="mt-2 text-heading-3 text-n-slate-12">
{{ issue.title }}
</h3>
<p
v-if="issue.description"
class="mt-1 text-sm text-n-slate-11 line-clamp-3"
class="mt-1 text-body-para text-n-slate-11 line-clamp-3"
>
{{ issue.description }}
</p>
@@ -14,6 +14,8 @@
"OS": "Operating System",
"INITIATED_FROM": "Initiated from",
"INITIATED_AT": "Initiated at",
"INITIATED_AT_DATE": "Date",
"INITIATED_AT_TIME": "Time",
"IP_ADDRESS": "IP Address",
"CREATED_AT_LABEL": "Created",
"CALL_INITIATED": "Calling the contact…",
@@ -587,7 +589,7 @@
"COLLAPSE": "Collapse",
"NO_NOTES": "No notes, you can add notes from the contact details page.",
"EMPTY_STATE": "There are no notes associated to this contact. You can add a note by typing in the box above.",
"CONVERSATION_EMPTY_STATE": "There are no notes yet. Use the Add note button to create one."
"CONVERSATION_EMPTY_STATE": "There are no notes yet."
}
},
"EMPTY_STATE": {
@@ -203,9 +203,14 @@ const handleAgentAction = ({ action, value }) => {
:size="16"
rounded-full
/>
<Icon
v-else
icon="i-woot-empty-assignee"
class="size-4 text-n-slate-11"
/>
</template>
<div class="grid grid-cols-[1fr_auto] items-center gap-1.5 min-w-0">
<span class="truncate min-w-0 font-420">
<span class="truncate min-w-0 text-body-main">
{{ assignedAgentName }}
</span>
<Icon
@@ -19,7 +19,7 @@ defineProps({
:icon="icon"
class="text-n-slate-11 size-4 flex-shrink-0 mt-0.5"
/>
<div v-if="value" class="break-words">
<div v-if="value" class="break-words text-body-main">
<slot>
{{ value }}
</slot>
@@ -155,7 +155,7 @@ onMounted(() => {
class="px-1.5 h-6 rounded-md bg-n-button-color outline outline-1 outline-n-container flex items-center gap-0.6"
>
<Icon icon="i-lucide-hash" class="size-3.5 text-n-slate-10" />
<span class="text-xs font-440">{{ conversationId }}</span>
<span class="text-label-small">{{ conversationId }}</span>
</div>
</div>
</SidebarActionsHeader>
@@ -1,5 +1,6 @@
<script setup>
import { computed } from 'vue';
import { format } from 'date-fns';
import { getLanguageName } from 'dashboard/components/widgets/conversation/advancedFilterItems/languages';
import ContactDetailsItem from './ContactDetailsItem.vue';
import CustomAttributes from './customAttributes/CustomAttributes.vue';
@@ -17,9 +18,18 @@ const props = defineProps({
});
const referer = computed(() => props.conversationAttributes.referer);
const initiatedAt = computed(
() => props.conversationAttributes.initiated_at?.timestamp
);
const initiatedAtDate = computed(() => {
const timestamp = props.conversationAttributes.initiated_at?.timestamp;
if (!timestamp) return '';
return format(new Date(timestamp), 'EEEE, MMM dd, yyyy');
});
const initiatedAtTime = computed(() => {
const timestamp = props.conversationAttributes.initiated_at?.timestamp;
if (!timestamp) return '';
return format(new Date(timestamp), "HH:mm '('O')'");
});
const browserInfo = computed(() => props.conversationAttributes.browser);
@@ -46,9 +56,16 @@ const createdAtIp = computed(() => props.contactAttributes.created_at_ip);
const staticElements = computed(() =>
[
{
content: initiatedAt,
title: 'CONTACT_PANEL.INITIATED_AT',
key: 'static-initiated-at',
content: initiatedAtDate,
title: 'CONTACT_PANEL.INITIATED_AT_DATE',
key: 'static-initiated-at-date',
type: 'static_attribute',
icon: 'i-lucide-calendar',
},
{
content: initiatedAtTime,
title: 'CONTACT_PANEL.INITIATED_AT_TIME',
key: 'static-initiated-at-time',
type: 'static_attribute',
icon: 'i-lucide-timer',
},
@@ -69,14 +69,14 @@ onMounted(() => {
<template>
<div>
<div v-if="!uiFlags.isFetching && !macros.length" class="p-3">
<SidePanelEmptyState :message="$t('MACROS.LIST.404')" class="mb-2" />
<SidePanelEmptyState :message="$t('MACROS.LIST.404')" />
<router-link :to="accountScopedUrl('settings/macros')">
<NextButton
link
sm
slate
icon="i-lucide-plus"
:label="$t('MACROS.HEADER_BTN_TXT')"
class="!text-n-slate-11 hover:!text-n-slate-12 hover:!no-underline !py-2"
class="w-full mt-2"
/>
</router-link>
</div>
@@ -76,7 +76,7 @@ const closeMacroPreview = () => {
class="[&>span]:size-3.5"
@click="toggleMacroPreview"
/>
<span class="font-420 text-ellipsis text-n-slate-12 truncate">
<span class="text-body-main text-n-slate-12 truncate">
{{ macro.name }}
</span>
</div>
@@ -61,7 +61,7 @@ const resolvedMacro = computed(() => {
<div
v-for="(action, i) in resolvedMacro"
:key="i"
class="relative ltr:pl-7 rtl:pr-7 py-3 after:content-[''] after:absolute ltr:after:left-1.5 rtl:after:right-1.5 after:w-px after:bg-n-weak"
class="relative ltr:pl-7 rtl:pr-7 py-3 after:content-[''] after:absolute ltr:after:left-1.5 rtl:after:right-1.5 after:w-px after:bg-n-strong"
:class="{
'after:top-1 after:h-3.5': resolvedMacro.length === 1,
'after:top-2 after:-bottom-5':
@@ -69,7 +69,7 @@ const resolvedMacro = computed(() => {
}"
>
<div
class="absolute ltr:left-[2.5px] rtl:right-[2.5px] top-[18px] w-2 h-2 rounded-full bg-n-surface-1 border-2 border-n-weak z-10"
class="absolute ltr:left-[2.5px] rtl:right-[2.5px] top-[18px] w-2 h-2 rounded-full bg-n-surface-1 border-2 border-n-strong z-10"
/>
<p class="mb-1 text-sm font-medium text-n-slate-11">
@@ -196,9 +196,18 @@ onMounted(() => {
:more-count-text="moreParticipantsText"
gap="tight"
/>
<div
v-else
class="size-4 flex items-center justify-center flex-shrink-0"
>
<Icon
icon="i-lucide-users-round"
class="size-3.5 text-n-slate-11"
/>
</div>
</template>
<div class="grid grid-cols-[1fr_auto] items-center gap-1.5 min-w-0">
<span class="truncate min-w-0 font-420">
<span class="truncate min-w-0 text-body-main">
{{ participantsLabel }}
</span>
<Icon
@@ -153,7 +153,7 @@ const handlePriorityAction = ({ value }) => {
<CardPriorityIcon :priority="assignedPriority.priority" show-empty />
</template>
<div class="grid grid-cols-[1fr_auto] items-center gap-1.5 min-w-0">
<span class="truncate min-w-0 font-420">
<span class="truncate min-w-0 text-body-main">
{{ assignedPriorityName }}
</span>
<Icon
@@ -9,6 +9,6 @@ defineProps({
<template>
<div class="custom-dashed-border p-4 rounded-xl">
<p class="text-center text-n-slate-10 font-420">{{ message }}</p>
<p class="text-center text-n-slate-10 text-body-main">{{ message }}</p>
</div>
</template>
@@ -141,9 +141,18 @@ const handleTeamAction = ({ action, value }) => {
:size="16"
rounded-full
/>
<div
v-else
class="size-4 flex items-center justify-center flex-shrink-0"
>
<Icon
icon="i-lucide-users-round"
class="size-3.5 text-n-slate-11"
/>
</div>
</template>
<div class="grid grid-cols-[1fr_auto] items-center gap-1.5 min-w-0">
<span class="truncate min-w-0 font-420">
<span class="truncate min-w-0 text-body-main">
{{ assignedTeamName }}
</span>
<Icon
@@ -162,12 +162,12 @@ const openMergeModal = () => {
/>
<div
v-if="showAvatar"
class="flex flex-col justify-center min-w-0 flex-1"
class="flex flex-col justify-center min-w-0 gap-1 flex-1"
>
<div class="flex items-center gap-1">
<h3
:title="contact.name"
class="flex-shrink font-medium max-w-full min-w-0 my-0 text-base capitalize break-words text-n-slate-12 line-clamp-2"
class="flex-shrink text-heading-3 max-w-full min-w-0 my-0 capitalize break-words text-n-slate-12 line-clamp-2"
>
{{ contact.name }}
</h3>
@@ -184,10 +184,7 @@ const openMergeModal = () => {
/>
</a>
</div>
<p
v-if="contact"
class="text-sm text-n-slate-11 font-420 m-0 truncate"
>
<p v-if="contact" class="text-n-slate-11 text-body-main m-0 truncate">
{{ contact.email || contact.phone_number || '---' }}
</p>
</div>
@@ -196,7 +193,7 @@ const openMergeModal = () => {
<div class="flex flex-col items-start gap-3 min-w-0 w-full">
<p
v-if="additionalAttributes.description"
class="break-words text-sm text-n-slate-11 font-420 mb-0"
class="break-words text-body-para text-n-slate-11 mb-0"
>
{{ additionalAttributes.description }}
</p>
@@ -34,7 +34,7 @@ const onCopy = async e => {
<template>
<div class="grid grid-cols-[30%_1fr] gap-4 w-full items-center h-9">
<span class="text-sm font-420 text-n-slate-11 truncate whitespace-nowrap">
<span class="text-body-main text-n-slate-11 truncate whitespace-nowrap">
{{ title }}
</span>
@@ -45,21 +45,21 @@ const onCopy = async e => {
class="hover:underline min-w-0 truncate"
:title="value"
>
<span v-if="value" class="text-sm font-420 text-n-slate-12">
<span v-if="value" class="text-body-main text-n-slate-12">
{{ value }}
</span>
<span v-else class="text-sm text-n-slate-10">
<span v-else class="text-body-main text-n-slate-10">
{{ '---' }}
</span>
</a>
<div v-else class="text-n-slate-12 min-w-0 truncate">
<div v-else class="text-body-main text-n-slate-12 min-w-0 truncate">
<span
v-if="value"
v-dompurify-html="value"
class="text-sm font-420 text-n-slate-12 [&>span]:ltr:ml-1.5 [&>span]:rtl:mr-1.5"
class="text-body-main text-n-slate-12 [&>span]:ltr:ml-1.5 [&>span]:rtl:mr-1.5"
/>
<span v-else class="text-sm text-n-slate-10">{{ '---' }}</span>
<span v-else class="text-body-main text-n-slate-10">{{ '---' }}</span>
</div>
<NextButton
@@ -99,7 +99,7 @@ watch(
<template>
<div>
<div class="px-3 pt-3 pb-2">
<div v-if="notes.length" class="px-3 pt-3 pb-2">
<NextButton
sm
slate
@@ -135,6 +135,15 @@ watch(
<SidePanelEmptyState
:message="t('CONTACTS_LAYOUT.SIDEBAR.NOTES.CONVERSATION_EMPTY_STATE')"
/>
<NextButton
sm
slate
icon="i-lucide-plus"
:label="$t('CONTACTS_LAYOUT.SIDEBAR.NOTES.ADD_NOTE')"
:disabled="!contactId || isFetchingNotes"
class="w-full mt-2"
@click="openCreateModal"
/>
</div>
<woot-modal
@@ -264,7 +264,7 @@ onMounted(() => {
v-if="element.attributeDescription"
:message="element.attributeDescription"
/>
<span class="text-sm font-420 truncate text-n-slate-12">
<span class="text-body-main truncate text-n-slate-12">
{{ element.attributeDisplayName }}
</span>
</div>