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

fix: customer portal filters #2024

Merged
merged 7 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
16 changes: 9 additions & 7 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 @@ -93,7 +95,7 @@ import { createToast } from "@/utils";
import { useAuthStore } from "@/stores/auth";
import { useError } from "@/composables/error";

import { PageTitle } from "@/components";
import { LayoutHeader, PageTitle } from "@/components";
import KnowledgeBaseArticleActionsEdit from "./knowledge-base/KnowledgeBaseArticleActionsEdit.vue";
import KnowledgeBaseArticleActionsNew from "./knowledge-base/KnowledgeBaseArticleActionsNew.vue";
import KnowledgeBaseArticleActionsView from "./knowledge-base/KnowledgeBaseArticleActionsView.vue";
Expand Down
2 changes: 1 addition & 1 deletion 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 Down
17 changes: 11 additions & 6 deletions helpdesk/api/doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,28 @@ def get_filterable_fields(doctype: str, show_customer_portal_fields=False):
)

# for customer portal show only fields present in customer_portal_fields

if show_customer_portal_fields:
from_doc_fields = from_doc_fields.where(
QBDocField.fieldname.isin(customer_portal_fields)
)
from_custom_fields = from_custom_fields.where(
QBCustomField.fieldname.isin(visible_custom_fields)
)
if len(visible_custom_fields) > 0:
from_custom_fields = from_custom_fields.where(
QBCustomField.fieldname.isin(visible_custom_fields)
)
from_custom_fields = from_custom_fields.run(as_dict=True)
else:
from_custom_fields = []

from_doc_fields = from_doc_fields.run(as_dict=True)
from_custom_fields = from_custom_fields.run(as_dict=True)
if not show_customer_portal_fields:
from_custom_fields = from_custom_fields.run(as_dict=True)

from_doc_fields = from_doc_fields.run(as_dict=True)
# from hd ticket template get children with fieldname and hidden_from_customer

res = []
res.extend(from_doc_fields)
# TODO: Ritvik => till a better way we have for custom fields, just show custom fields

res.extend(from_custom_fields)
if not show_customer_portal_fields:
res.append(
Expand Down
6 changes: 3 additions & 3 deletions helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,14 @@ def on_update(self):
self.publish_update()
self.update_search_index()

def notify_agent(self, agent, notiification_type="Assignment"):
def notify_agent(self, agent, notification_type="Assignment"):
frappe.get_doc(
frappe._dict(
doctype="HD Notification",
user_from=frappe.session.user,
reference_ticket=self.name,
user_to=agent,
notification_type=notiification_type,
notification_type=notification_type,
)
).insert(ignore_permissions=True)

Expand Down Expand Up @@ -343,7 +343,7 @@ def remove_assignment_if_not_in_team(self):
"""
if self.is_new():
return
if not self.agent_group or not self._assign:
if not self.agent_group or (hasattr(self, "_assign") and not self._assign):
return
if self.has_value_changed("agent_group") and self.status == "Open":
current_assigned_agent_doc = self.get_assigned_agent()
Expand Down
Loading