Skip to content

Commit

Permalink
feat: connect email fields to reply,reply all and other fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sumitbhanushali committed Apr 27, 2024
1 parent 90bb078 commit 80bb7a5
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 101 deletions.
57 changes: 18 additions & 39 deletions desk/src/components/CommunicationArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,9 @@
</template>
</Button>
</div>
<div v-show="showEmailBox" class="flex gap-1.5">
<Button
label="CC"
:class="[false ? 'bg-gray-300 hover:bg-gray-200' : '']"
@click="toggleCC()"
/>
<Button
label="BCC"
:class="[false ? 'bg-gray-300 hover:bg-gray-200' : '']"
@click="toggleBCC()"
/>
</div>
</div>
<div v-show="showCommentBox">
<CommentTextEditor
ref="newCommentEditor"
v-model="doc"
v-model:attachments="attachments"
:editable="showCommentBox"
Expand All @@ -64,7 +51,8 @@
@keydown.meta.enter.capture.stop="submitEmail"
>
<EmailEditor
ref="newEmailEditor"
ref="emailEditorRef"
v-model="doc"
v-model:content="content"
v-model:attachments="attachments"
:to-emails="toEmails"
Expand All @@ -86,21 +74,18 @@
</template>

<script setup lang="ts">
import { createResource } from "frappe-ui";
import EmailIcon from "@/components/icons/EmailIcon.vue";
import CommentIcon from "@/components/icons/CommentIcon.vue";
import { useAuthStore } from "@/stores/auth";
import { ref, defineModel } from "vue";
import { EmailEditor, CommentTextEditor } from "@/components";
import { ref, defineModel, nextTick } from "vue";
import { EmailIcon, CommentIcon } from "@/components/icons/";
const authStore = useAuthStore();
const content = defineModel("content");
const showEmailBox = ref(false);
const showCommentBox = ref(false);
const doc = defineModel();
const attachments = ref([]);
const newEmailEditor = ref(null);
const emit = defineEmits(["update"]);
const emailEditorRef = ref(null);
function toggleEmailBox() {
if (showCommentBox.value) {
Expand All @@ -116,20 +101,14 @@ function toggleCommentBox() {
showCommentBox.value = !showCommentBox.value;
}
function toggleCC() {
newEmailEditor.value.cc = !newEmailEditor.value.cc;
newEmailEditor.value.cc &&
nextTick(() => {
newEmailEditor.value.ccInput.setFocus();
});
}
function toggleBCC() {
newEmailEditor.value.bcc = !newEmailEditor.value.bcc;
newEmailEditor.value.bcc &&
nextTick(() => {
newEmailEditor.value.bccInput.setFocus();
});
function replyToEmail(data: object) {
showEmailBox.value = true;
emailEditorRef.value.addToReply(
data.content,
data.to?.split(","),
data.cc?.split(","),
data.bcc?.split(",")
);
}
const props = defineProps({
Expand All @@ -149,9 +128,9 @@ const props = defineProps({
type: Array,
default: () => [],
},
content: {
type: String,
default: "",
},
});
defineExpose({
replyToEmail,
});
</script>
49 changes: 29 additions & 20 deletions desk/src/components/EmailBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,32 @@
</Tooltip>
</div>
<div class="flex gap-0.5">
<Tooltip text="Reply">
<Button
variant="ghost"
class="text-gray-700"
@click="console.log('reply')"
>
<ReplyIcon class="h-4 w-4" />
</Button>
</Tooltip>
<Tooltip text="Reply All">
<Button
variant="ghost"
class="text-gray-700"
@click="console.log('reply all')"
>
<ReplyAllIcon class="h-4 w-4" />
</Button>
</Tooltip>
<Button
variant="ghost"
class="text-gray-700"
@click="
emit('reply', {
content: content,
to: sender.name,
})
"
>
<ReplyIcon class="h-4 w-4" />
</Button>
<Button
variant="ghost"
class="text-gray-700"
@click="
emit('reply', {
content: content,
to: to,
cc: cc,
bcc: bcc,
})
"
>
<ReplyAllIcon class="h-4 w-4" />
</Button>
</div>
</div>
<div class="text-sm leading-5 text-gray-600">
Expand Down Expand Up @@ -68,8 +76,7 @@
<script setup lang="ts">
import { UserAvatar, AttachmentItem } from "@/components";
import { dateFormat, timeAgo, dateTooltipFormat } from "@/utils";
import ReplyIcon from "./icons/ReplyIcon.vue";
import ReplyAllIcon from "./icons/ReplyAllIcon.vue";
import { ReplyIcon, ReplyAllIcon } from "./icons/";
const props = defineProps({
sender: {
Expand All @@ -93,4 +100,6 @@ const props = defineProps({
required: true,
},
});
const emit = defineEmits(["reply"]);
</script>
93 changes: 72 additions & 21 deletions desk/src/components/EmailEditor.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<template>
<TextEditor
ref="e"
ref="editorRef"
:editor-class="[
'prose-sm max-w-none mx-10 max-h-[50vh] overflow-y-auto border-t py-3',
true && 'min-h-[7rem]',
]"
:content="content"
:content="newEmail"
:starterkit-options="{ heading: { levels: [2, 3, 4, 5, 6] } }"
:placeholder="placeholder"
:editable="editable"
@change="editable ? (content = $event) : null"
@change="editable ? (newEmail = $event) : null"
>
<template #top>
<div
Expand All @@ -23,9 +23,19 @@
:validate="validateEmail"
:error-message="(value) => `${value} is an invalid email address`"
/>
<Button
:label="'CC'"
:class="[cc ? 'bg-gray-300 hover:bg-gray-200' : '']"
@click="toggleCC()"
/>
<Button
:label="'BCC'"
:class="[bcc ? 'bg-gray-300 hover:bg-gray-200' : '']"
@click="toggleBCC()"
/>
</div>
<div
v-if="cc"
v-if="showCC || cc"
class="mx-10 flex items-center gap-2 py-2.5"
:class="bcc ? 'border-b' : ''"
>
Expand All @@ -38,7 +48,7 @@
:error-message="(value) => `${value} is an invalid email address`"
/>
</div>
<div v-if="bcc" class="mx-10 flex items-center gap-2 py-2.5">
<div v-if="showBCC || bcc" class="mx-10 flex items-center gap-2 py-2.5">
<span class="text-xs text-gray-500">BCC:</span>
<MultiSelectInput
ref="bccInput"
Expand Down Expand Up @@ -99,7 +109,11 @@
variant="solid"
:disabled="emailEmpty"
label="Submit"
@click="() => {}"
@click="
() => {
submitMail();
}
"
/>
</div>
</div>
Expand All @@ -108,7 +122,7 @@
</template>

<script setup lang="ts">
import { defineModel, ref, computed } from "vue";
import { defineModel, ref, computed, nextTick } from "vue";
import { useStorage } from "@vueuse/core";
import {
FileUploader,
Expand All @@ -119,6 +133,7 @@ import {
import { validateEmail } from "@/utils";
import { MultiSelectInput } from "@/components";
import { AttachmentIcon } from "@/components/icons";
const editorRef = ref(null);
const props = defineProps({
placeholder: {
Expand All @@ -133,14 +148,6 @@ const props = defineProps({
type: String,
default: "HD Ticket",
},
submitButtonProps: {
type: Object,
default: () => ({}),
},
discardButtonProps: {
type: Object,
default: () => ({}),
},
toEmails: {
type: Array,
default: () => [],
Expand All @@ -164,13 +171,14 @@ const emailEmpty = computed(() => {
const emit = defineEmits(["submit", "discard"]);
const doc = defineModel();
const content = defineModel("content");
const attachments = defineModel("attachments");
const cc = ref(props.ccEmails.length ? true : false);
const bcc = ref(props.bccEmails.length ? true : false);
const toEmailsClone = ref([...props.toEmails]);
const ccEmailsClone = ref([...props.ccEmails]);
const bccEmailsClone = ref([...props.bccEmails]);
const showCC = ref(false);
const showBCC = ref(false);
const cc = computed(() => (ccEmailsClone.value.length ? true : false));
const bcc = computed(() => (bccEmailsClone.value.length ? true : false));
const ccInput = ref(null);
const bccInput = ref(null);
Expand All @@ -179,22 +187,61 @@ function submitMail() {
url: "run_doc_method",
makeParams: () => ({
dt: props.doctype,
dn: doc.value.data.name,
dn: doc.value.name,
method: "reply_via_agent",
args: {
attachments: attachments.value.map((x) => x.name),
cc: ccEmailsClone,
bcc: bccEmailsClone,
to: toEmailsClone.value.join(","),
cc: ccEmailsClone.value.join(","),
bcc: bccEmailsClone.value.join(","),
message: newEmail.value,
},
}),
onSuccess: () => {
emit("submit");
},
});
sendMail.submit();
}
function toggleCC() {
showCC.value = !showCC.value;
showCC.value &&
nextTick(() => {
ccInput.value.setFocus();
});
}
function toggleBCC() {
showBCC.value = !showBCC.value;
showBCC.value &&
nextTick(() => {
bccInput.value.setFocus();
});
}
function addToReply(
body: string,
toEmails: string[],
ccEmails: string[],
bccEmails: string[]
) {
toEmailsClone.value = toEmails;
ccEmailsClone.value = ccEmails;
bccEmailsClone.value = bccEmails;
editorRef.value.editor
.chain()
.clearContent()
.insertContent(body)
.focus("all")
.setBlockquote()
.insertContentAt(0, { type: "paragraph" })
.focus("start")
.run();
}
const textEditorMenuButtons = [
"Paragraph",
["Heading 2", "Heading 3", "Heading 4", "Heading 5", "Heading 6"],
Expand Down Expand Up @@ -232,4 +279,8 @@ const textEditorMenuButtons = [
"DeleteTable",
],
];
defineExpose({
addToReply,
});
</script>
2 changes: 2 additions & 0 deletions desk/src/components/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export { default as CommentIcon } from "./CommentIcon.vue";
export { default as IndicatorIcon } from "./IndicatorIcon.vue";
export { default as TicketIcon } from "./TicketIcon.vue";
export { default as AttachmentIcon } from "./AttachmentIcon.vue";
export { default as ReplyIcon } from "./ReplyIcon.vue";
export { default as ReplyAllIcon } from "./ReplyAllIcon.vue";
8 changes: 7 additions & 1 deletion desk/src/components/ticket/TicketAgentActivities.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
</div>
</div>
<div class="mt-4 w-full">
<EmailBox v-if="activity.type === 'email'" v-bind="activity" />
<EmailBox
v-if="activity.type === 'email'"
v-bind="activity"
@reply="(e) => emit('email:reply', e)"
/>
<CommentBox
v-else-if="activity.type === 'comment'"
v-bind="activity"
Expand All @@ -47,6 +51,8 @@ defineProps({
},
});
const emit = defineEmits(["email:reply"]);
function getActivityIcon(type) {
if (type === "email") return EmailAtIcon;
else if (type === "comment") return CommentIcon;
Expand Down
Loading

0 comments on commit 80bb7a5

Please sign in to comment.