Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(release): dev to main #2031

Merged
merged 18 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions desk/src/components/CommentBox.vue
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
<template>
<div class="flex-col text-base">
<div class="mb-0.5 flex items-center justify-between">
<div class="text-gray-600">
<span class="font-medium text-gray-800">
{{ commenter }}
</span>
<span> added a</span>
<span class="max-w-xs truncate font-medium text-gray-800">
comment
</span>
<span class="px-1">&middot;</span>
<div class="mb-1 ml-0.5 flex items-center justify-between">
<div class="text-gray-600 flex items-center gap-2">
<Avatar
size="sm"
:label="commenter"
:image="getUser(commentedBy).user_image"
/>
<p>
<span class="font-medium text-gray-800">
{{ commenter }}
</span>
<span> added a</span>
<span class="max-w-xs truncate font-medium text-gray-800">
comment
</span>
</p>
</div>
<div class="flex items-center">
<Tooltip :text="dateFormat(creation, dateTooltipFormat)">
<span class="pl-0.5 text-sm">
<span class="pl-0.5 text-sm text-gray-600">
{{ timeAgo(creation) }}
</span>
</Tooltip>
</div>
<div v-if="authStore.userId === commentedBy" class="px-4">
<Dropdown
:options="[{ label: 'Delete', onClick: () => (showDialog = true) }]"
>
<Button
icon="more-horizontal"
class="text-gray-600"
variant="ghost"
/>
</Dropdown>
<div v-if="authStore.userId === commentedBy">
<Dropdown
:options="[{ label: 'Delete', onClick: () => (showDialog = true) }]"
>
<Button
icon="more-horizontal"
class="text-gray-600"
variant="ghost"
/>
</Dropdown>
</div>
</div>
</div>
<div
Expand All @@ -52,9 +60,10 @@

<script setup lang="ts">
import { ref } from "vue";
import { Dropdown, createResource, Dialog } from "frappe-ui";
import { Dropdown, createResource, Dialog, Avatar } from "frappe-ui";
import { dateFormat, timeAgo, dateTooltipFormat, createToast } from "@/utils";
import { useAuthStore } from "@/stores/auth";
import { useUserStore } from "@/stores/user";

const authStore = useAuthStore();
const props = defineProps({
Expand All @@ -63,6 +72,7 @@ const props = defineProps({
required: true,
},
});
const { getUser } = useUserStore();

const { name, creation, content, commenter, commentedBy } = props.activity;

Expand Down
32 changes: 16 additions & 16 deletions desk/src/components/EmailArea.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
<template>
<div
class="grow cursor-pointer rounded-md border-transparent bg-gray-50 text-base leading-6 transition-all duration-300 ease-in-out"
class="grow cursor-pointer border-transparent bg-white rounded-md shadow text-base leading-6 transition-all duration-300 ease-in-out"
>
<div class="mb-1 flex items-center justify-between gap-2">
<!-- comment design for mobile -->
<!-- email design for mobile -->
<div v-if="isMobileView" class="flex items-center gap-2">
<UserAvatar :name="sender.name" size="lg" />
<div class="leading-tight">
<span>{{ sender.full_name }}</span>
<Tooltip :text="dateFormat(creation, dateTooltipFormat)">
<div class="text-xs text-gray-600">
{{ timeAgo(creation) }}
</div>
</Tooltip>
<span>{{ sender.full_name || "No name found" }}</span>
<span
class="sm:flex hidden text-sm text-gray-600"
v-if="sender.name"
>{{ "<" + sender.name + ">" }}</span
>
</div>
</div>
<!-- comment design for desktop -->
<!-- email design for desktop -->
<div v-else class="flex items-center gap-2">
<UserAvatar :name="sender.name" size="md" />
<span>{{ sender.full_name }}</span>
<span>&middot;</span>
<span>{{ sender.full_name || "No name found" }}</span>
<span class="sm:flex hidden text-sm text-gray-600" v-if="sender.name">{{
"<" + sender.name + ">"
}}</span>
</div>

<div class="flex gap-0.5 items-center">
<Tooltip :text="dateFormat(creation, dateTooltipFormat)">
<div class="text-sm text-gray-600">
{{ timeAgo(creation) }}
</div>
</Tooltip>
</div>

<div class="flex gap-0.5">
<Button
variant="ghost"
class="text-gray-700"
Expand Down
4 changes: 3 additions & 1 deletion desk/src/components/TextEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<div class="rounded p-3 shadow">
<FTextEditor
ref="e"
:extensions="[PreserveVideoControls]"
v-bind="$attrs"
editor-class="prose-f max-h-64 max-w-none overflow-auto my-4 min-h-[5rem]"
bubble-menu
Expand Down Expand Up @@ -57,6 +58,7 @@ import { computed, nextTick, ref } from "vue";
import { TextEditor as FTextEditor, TextEditorFixedMenu } from "frappe-ui";
import { useAuthStore } from "@/stores/auth";
import { UserAvatar } from "@/components";
import { PreserveVideoControls } from "@/tiptap-extensions";

interface P {
modelValue: string;
Expand All @@ -65,7 +67,7 @@ interface P {

interface E {
(event: "clear"): void;
(event: "update:modelValue"): string;
(event: "update:modelValue", any): string;
}

const props = withDefaults(defineProps<P>(), {
Expand Down
46 changes: 27 additions & 19 deletions desk/src/components/ticket/TicketAgentActivities.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,24 @@
:class="[i != activities.length - 1 ? 'after:h-full' : 'after:h-4']"
>
<div
class="z-10 flex h-7 w-7 items-center justify-center rounded-full bg-gray-100"
class="z-10 flex h-7 w-7 items-center justify-center rounded-full bg-white"
:class="[
activity.type === 'history' ? 'bg-white' : 'bg-gray-100',
activity.type === 'comment' ? 'mt-0.5' : '',
activity.type === 'email' ? 'mt-2' : '',
]"
>
<component
:is="getActivityIcon(activity.type)"
:class="[
activity.type == 'history'
? 'text-gray-600'
: 'text-gray-800',
]"
<Avatar
v-if="activity.type === 'email'"
size="md"
:label="activity.sender?.full_name"
:image="getUser(activity.sender?.name).user_image"
class="bg-white"
/>
<CommentIcon
v-else-if="activity.type === 'comment'"
class="text-gray-800"
/>
<DotIcon v-else class="text-gray-600" />
</div>
</div>
<div class="mb-4 w-full">
Expand Down Expand Up @@ -67,6 +70,7 @@
</template>

<script setup lang="ts">
import { Ref, inject, h, computed, onMounted, watch } from "vue";
import { useElementVisibility } from "@vueuse/core";
import {
DotIcon,
Expand All @@ -76,10 +80,8 @@ import {
ActivityIcon,
} from "@/components/icons";
import { EmailArea, CommentBox, HistoryBox } from "@/components";
import { Ref } from "vue";
import { inject } from "vue";
import { computed } from "vue";
import { h } from "vue";
import { useUserStore } from "@/stores/user";
import { Avatar } from "frappe-ui";

const props = defineProps({
activities: {
Expand All @@ -94,6 +96,7 @@ const props = defineProps({

const emit = defineEmits(["email:reply", "update"]);

const { getUser } = useUserStore();
const communicationAreaRef: Ref = inject("communicationArea");

const emptyText = computed(() => {
Expand All @@ -116,12 +119,6 @@ const emptyTextIcon = computed(() => {
return h(icon, { class: "text-gray-500" });
});

function getActivityIcon(type) {
if (type === "email") return EmailAtIcon;
else if (type === "comment") return CommentIcon;
else return DotIcon;
}

function scrollToLatestActivity() {
setTimeout(() => {
let el;
Expand All @@ -137,4 +134,15 @@ function scrollToLatestActivity() {
defineExpose({
scrollToLatestActivity,
});

onMounted(() => {
scrollToLatestActivity();
});

watch(
() => props.title,
() => {
scrollToLatestActivity();
}
);
</script>
2 changes: 1 addition & 1 deletion desk/src/components/ticket/TicketAgentContact.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="flex items-center justify-start gap-5 border-b p-5">
<Avatar size="3xl" :image="contact.image" :label="contact.name" />
<div class="flex items-center justify-between">
<div class="flex items-center justify-between flex-1">
<Tooltip :text="contact.name">
<div class="w-[242px] truncate text-2xl font-medium">
{{ contact.name }}
Expand Down
43 changes: 10 additions & 33 deletions desk/src/pages/KnowledgeBaseArticle.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<template>
<div class="flex h-full flex-col overflow-hidden">
<PageTitle>
<template #title>
<LayoutHeader>
<template #left-header>
<Breadcrumbs :items="breadcrumbs" />
</template>
<template #right v-if="!route.meta.public">
<template #right-header v-if="!isCustomerPortal">
<component
:is="actionsComponent"
:status="article.data?.status"
Expand All @@ -17,9 +17,9 @@
@toggle-status="toggleStatus"
/>
</template>
</PageTitle>
<div class="overflow-auto">
<div class="mx-5 my-12">
</LayoutHeader>
<div class="overflow-auto mx-auto w-full max-w-4xl px-5">
<div class="py-6">
<TextEditor
:content="textEditorContentWithIDs"
:editable="editMode"
Expand Down Expand Up @@ -56,12 +56,14 @@
<RouterLink
v-if="route.meta.public"
:to="{ name: CUSTOMER_PORTAL_NEW_TICKET }"
class=""
>
<Button
label="Still need help? Create a ticket"
size="md"
theme="gray"
variant="solid"
class="mt-5"
>
<template #suffix> &rightarrow; </template>
</Button>
Expand Down Expand Up @@ -92,15 +94,14 @@ import {
import { createToast } from "@/utils";
import { useAuthStore } from "@/stores/auth";
import { useError } from "@/composables/error";

import { PageTitle } from "@/components";
import { LayoutHeader } from "@/components";
import KnowledgeBaseArticleActionsEdit from "./knowledge-base/KnowledgeBaseArticleActionsEdit.vue";
import KnowledgeBaseArticleActionsNew from "./knowledge-base/KnowledgeBaseArticleActionsNew.vue";
import KnowledgeBaseArticleActionsView from "./knowledge-base/KnowledgeBaseArticleActionsView.vue";
import KnowledgeBaseArticleTopEdit from "./knowledge-base/KnowledgeBaseArticleTopEdit.vue";
import KnowledgeBaseArticleTopNew from "./knowledge-base/KnowledgeBaseArticleTopNew.vue";
import KnowledgeBaseArticleTopView from "./knowledge-base/KnowledgeBaseArticleTopView.vue";
import { Extension } from "@tiptap/core";
import { PreserveIds } from "@/tiptap-extensions";

const props = defineProps({
articleId: {
Expand Down Expand Up @@ -388,30 +389,6 @@ const textEditorMenuButtons = [
],
];

// extension to preserve ids in html of headings
const PreserveIds: Extension = Extension.create({
name: "preserveIds",
addGlobalAttributes() {
return [
{
types: ["heading"],
attributes: {
id: {
default: null,
parseHTML: (element) => element.getAttribute("id"),
renderHTML: (attributes) => {
if (!attributes.id) {
return {};
}
return { id: attributes.id };
},
},
},
},
];
},
});

const textEditorContentWithIDs = computed(() =>
article.data?.content ? addLinksToHeadings(article.data?.content) : null
);
Expand Down
5 changes: 2 additions & 3 deletions desk/src/pages/TicketCustomer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,9 @@ const showResolveButton = computed(() =>
["Open", "Replied"].includes(ticket.data.status)
);

const showEditor = computed(() =>
["Open", "Replied", "Resolved"].includes(ticket.data.status)
);
const showEditor = computed(() => ticket.data.status !== "Closed");

// this handles whether the ticket was raised and then was closed without any reply from the agent.
const showFeedback = computed(() => {
return ticket.data?.communications?.some((c) => {
if (c.sender !== ticket.data.raised_by) {
Expand Down
4 changes: 2 additions & 2 deletions desk/src/pages/TicketNew.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</LayoutHeader>
<!-- Container -->
<div
class="max-w-screen-lg flex flex-col gap-5 m-5 w-full h-full flex-1 self-center"
class="flex flex-col gap-5 py-6 h-full flex-1 self-center overflow-auto mx-auto w-full max-w-4xl px-5"
>
<!-- custom fields descriptions -->
<div v-if="Boolean(template.data?.about)" class="">
Expand All @@ -27,7 +27,7 @@
/>
</div>
<!-- existing fields -->
<div class="flex flex-col flex-1" :class="subject.length >= 2 && 'gap-5'">
<div class="flex flex-col" :class="subject.length >= 2 && 'gap-5'">
<FormControl
v-model="subject"
type="text"
Expand Down
7 changes: 6 additions & 1 deletion desk/src/pages/ticket/TicketCommunication.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ withDefaults(defineProps<P>(), {

function sanitize(html: string) {
return sanitizeHtml(html, {
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img", "video"]),
allowedAttributes: {
a: ["href"],
video: ["src", "controls"],
img: ["src"],
},
});
}
</script>
Loading
Loading