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

feat: mobile support #1954

Merged
merged 22 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f6dbec5
feat: mobile support
RitvikSardana Aug 30, 2024
36d0352
fix: add mobile sidebar component
RitvikSardana Aug 30, 2024
175602d
fix: make all screens mobile compatable with layout header
RitvikSardana Aug 31, 2024
24a833b
fix: add notifications and command pallete back to desktop layout
RitvikSardana Aug 31, 2024
7ebb87a
fix: add styls for single ticket mobile view
RitvikSardana Sep 1, 2024
32031c8
fix: add mobile view support in single ticket
RitvikSardana Sep 1, 2024
356d783
fix(styles): multiple tickets view
RitvikSardana Sep 1, 2024
1631c81
fix(style): ticket sidebar
RitvikSardana Sep 1, 2024
17ab967
fix(style): header
RitvikSardana Sep 1, 2024
793a832
fix(styles): filter component
RitvikSardana Sep 1, 2024
4e1b6df
fix(mobile-sidebar): add logout option in dropdown
RitvikSardana Sep 1, 2024
0793a29
fix: hide label in sort and column settings
RitvikSardana Sep 1, 2024
68d9457
fix: replace notifications icon
RitvikSardana Sep 1, 2024
d55890e
fix: add notifications page for mobile view
RitvikSardana Sep 2, 2024
9e30d4c
fix(styles): mobile sidebar
RitvikSardana Sep 2, 2024
94e0447
fix(styles): comment in mobile style
RitvikSardana Sep 2, 2024
ee8011f
fix(styles): comment in mobile style
RitvikSardana Sep 2, 2024
a69dd18
fix(styles): mobile ticket agent component
RitvikSardana Sep 2, 2024
4d98166
fix(styles): canned response
RitvikSardana Sep 2, 2024
6f4b8a6
fix: user permissions
RitvikSardana Sep 2, 2024
cd1896f
fix: mobile sidebar close on navigate
RitvikSardana Sep 2, 2024
118f5c5
fix: close sidebar on notification page
RitvikSardana Sep 2, 2024
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
3 changes: 2 additions & 1 deletion desk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"copy-html-entry": "cp ../helpdesk/public/desk/index.html ../helpdesk/www/helpdesk/index.html"
},
"dependencies": {
"@headlessui/vue": "^1.7.22",
"@iconify-json/lucide": "^1.1.99",
"@iconify-json/ph": "^1.1.5",
"@iconify/tools": "^2.2.6",
Expand Down Expand Up @@ -37,7 +38,7 @@
"unplugin-vue-components": "^0.25.2",
"vee-validate": "^4.8.2",
"vite": "^4.4.9",
"vue": "^3.4.12",
"vue": "^3.4.12",
"vue-echarts": "^6.5.4",
"vue-router": "^4.2.2",
"vuedraggable": "^4.1.0",
Expand Down
14 changes: 3 additions & 11 deletions desk/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<template>
<span class="fixed inset-0">
<RouterView class="antialiased" />
<Toasts />
<KeymapDialog />
</span>
<RouterView class="antialiased" />
<Toasts />
<KeymapDialog />
</template>

<script setup lang="ts">
Expand All @@ -16,12 +14,6 @@ import { stopSession } from "@/telemetry";
import { init as initTelemetry } from "@/telemetry";
useConfigStore();

const viewportWidth = ref(
Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
);

provide("viewportWidth", viewportWidth);

onMounted(async () => {
window.addEventListener("online", () => {
createToast({
Expand Down
2 changes: 1 addition & 1 deletion desk/src/components/CannedResponseSelectorModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</TextInput>
<div
v-if="filteredTemplates.length"
class="mt-2 grid max-h-[560px] grid-cols-3 gap-2 overflow-y-auto"
class="mt-2 grid max-h-[560px] grid-cols-1 md:grid-cols-3 gap-2 overflow-y-auto"
>
<div
v-for="template in filteredTemplates"
Expand Down
9 changes: 8 additions & 1 deletion desk/src/components/ColumnSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
<NestedPopover>
<template #target>
<Button label="Columns">
<template #prefix>
<template v-if="hideLabel">
<ColumnsIcon class="h-4" />
</template>
<template v-if="!hideLabel" #prefix>
<ColumnsIcon class="h-4" />
</template>
</Button>
Expand Down Expand Up @@ -147,6 +150,10 @@ let props = defineProps({
type: Array,
required: true,
},
hideLabel: {
type: Boolean,
default: false,
},
});

function resetToDefault(close) {
Expand Down
150 changes: 80 additions & 70 deletions desk/src/components/CommunicationArea.vue
Original file line number Diff line number Diff line change
@@ -1,75 +1,77 @@
<template>
<div class="flex justify-between gap-3 border-t px-10 py-2.5">
<div class="flex gap-1.5">
<Button
ref="sendEmailRef"
variant="ghost"
label="Reply"
:class="[showEmailBox ? '!bg-gray-300 hover:!bg-gray-200' : '']"
@click="toggleEmailBox()"
>
<template #prefix>
<EmailIcon class="h-4" />
</template>
</Button>
<Button
variant="ghost"
label="Comment"
:class="[showCommentBox ? '!bg-gray-300 hover:!bg-gray-200' : '']"
@click="toggleCommentBox()"
>
<template #prefix>
<CommentIcon class="h-4" />
</template>
</Button>
<div class="flex flex-col comm-area">
<div class="flex justify-between gap-3 border-t px-10 py-2.5">
<div class="flex gap-1.5">
<Button
ref="sendEmailRef"
variant="ghost"
label="Reply"
:class="[showEmailBox ? '!bg-gray-300 hover:!bg-gray-200' : '']"
@click="toggleEmailBox()"
>
<template #prefix>
<EmailIcon class="h-4" />
</template>
</Button>
<Button
variant="ghost"
label="Comment"
:class="[showCommentBox ? '!bg-gray-300 hover:!bg-gray-200' : '']"
@click="toggleCommentBox()"
>
<template #prefix>
<CommentIcon class="h-4" />
</template>
</Button>
</div>
</div>
<div v-show="showCommentBox">
<CommentTextEditor
v-model="doc"
v-model:attachments="attachments"
:editable="showCommentBox"
:doctype="doctype"
placeholder="Add a comment..."
@submit="
() => {
showCommentBox = false;
emit('update');
}
"
@discard="
() => {
showCommentBox = false;
}
"
/>
</div>
<div
v-show="showEmailBox"
class="flex gap-1.5"
@keydown.ctrl.enter.capture.stop="submitEmail"
@keydown.meta.enter.capture.stop="submitEmail"
>
<EmailEditor
ref="emailEditorRef"
v-model="doc"
v-model:content="content"
v-model:attachments="attachments"
:to-emails="toEmails"
:cc-emails="ccEmails"
:bcc-emails="bccEmails"
@submit="
() => {
showEmailBox = false;
emit('update');
}
"
@discard="
() => {
showEmailBox = false;
}
"
/>
</div>
</div>
<div v-show="showCommentBox">
<CommentTextEditor
v-model="doc"
v-model:attachments="attachments"
:editable="showCommentBox"
:doctype="doctype"
placeholder="Add a comment..."
@submit="
() => {
showCommentBox = false;
emit('update');
}
"
@discard="
() => {
showCommentBox = false;
}
"
/>
</div>
<div
v-show="showEmailBox"
class="flex gap-1.5"
@keydown.ctrl.enter.capture.stop="submitEmail"
@keydown.meta.enter.capture.stop="submitEmail"
>
<EmailEditor
ref="emailEditorRef"
v-model="doc"
v-model:content="content"
v-model:attachments="attachments"
:to-emails="toEmails"
:cc-emails="ccEmails"
:bcc-emails="bccEmails"
@submit="
() => {
showEmailBox = false;
emit('update');
}
"
@discard="
() => {
showEmailBox = false;
}
"
/>
</div>
</template>

Expand Down Expand Up @@ -135,3 +137,11 @@ defineExpose({
toggleEmailBox,
});
</script>

<style>
@media screen and (max-width: 640px) {
.comm-area {
width: 100vw;
}
}
</style>
19 changes: 18 additions & 1 deletion desk/src/components/EmailBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,20 @@
class="grow cursor-pointer rounded-md border-transparent bg-gray-50 text-base leading-6 transition-all duration-300 ease-in-out"
>
<div class="mb-1 flex items-center justify-between gap-2">
<div class="flex items-center gap-2">
<!-- comment 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>
</div>
</div>
<!-- comment 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>
Expand All @@ -13,6 +26,7 @@
</div>
</Tooltip>
</div>

<div class="flex gap-0.5">
<Button
variant="ghost"
Expand Down Expand Up @@ -76,6 +90,7 @@
import { UserAvatar, AttachmentItem } from "@/components";
import { dateFormat, timeAgo, dateTooltipFormat } from "@/utils";
import { ReplyIcon, ReplyAllIcon } from "./icons/";
import { useScreenSize } from "@/composables/screen";

const props = defineProps({
sender: {
Expand All @@ -101,4 +116,6 @@ const props = defineProps({
});

const emit = defineEmits(["reply"]);

const { isMobileView } = useScreenSize();
</script>
8 changes: 7 additions & 1 deletion desk/src/components/EmailEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@
</div>
<div class="flex justify-between gap-2 overflow-hidden px-10 py-2.5">
<div class="flex items-center overflow-x-auto">
<TextEditorFixedMenu class="-ml-1" :buttons="textEditorMenuButtons" />
<TextEditorFixedMenu
class="-ml-1"
:buttons="textEditorMenuButtons"
v-if="!isMobileView"
/>
<div class="flex gap-1">
<FileUploader
:upload-args="{
Expand Down Expand Up @@ -163,10 +167,12 @@ import {
CannedResponseSelectorModal,
} from "@/components";
import { AttachmentIcon, EmailIcon } from "@/components/icons";
import { useScreenSize } from "@/composables/screen";

const editorRef = ref(null);
const showCannedResponseSelectorModal = ref(false);
const loading = ref(false);
const { isMobileView } = useScreenSize();

const props = defineProps({
placeholder: {
Expand Down
59 changes: 55 additions & 4 deletions desk/src/components/Filter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,63 @@
</template>
<template #body="{ close }">
<div class="my-2 rounded bg-white shadow">
<div class="min-w-[400px] p-2">
<div class="p-2" :class="!isMobileView && 'min-w-[420px]'">
<div v-if="filters.length">
<div
v-for="(filter, idx) in filters"
id="filter-list"
:key="idx"
class="mb-3 flex items-center justify-between gap-2"
class="mb-3 flex flex-1 justify-between gap-2"
>
<div class="flex items-center gap-2">
<div
v-if="isMobileView"
class="flex flex-1 gap-2 flex-col abcxyz"
>
<div
class="pl-2 text-end text-base text-gray-600 flex justify-between flex-1 items-center"
>
<p>{{ idx == 0 ? "Where" : "And" }}</p>
<Button variant="ghost" icon="x" @click="removeFilter(idx)" />
</div>
<div id="fieldname" class="!min-w-[140px]">
<Autocomplete
:value="filter.field.fieldname"
:options="filterableFields"
placeholder="Filter by..."
@change="(field) => updateFilter(idx, field)"
/>
</div>
<div id="operator">
<FormControl
v-model="filter.operator"
type="select"
:options="getOperators(filter.field.fieldtype)"
placeholder="Operator"
@change="
(e) => updateFilter(idx, null, null, e.target.value)
"
/>
</div>
<div id="value" class="!min-w-[140px]">
<SearchComplete
v-if="typeLink.includes(filter.field.fieldtype)"
:key="filter.field.fieldname"
:doctype="filter.field.options"
:value="filter.value.toString()"
@change="(v) => updateFilter(idx, null, v.value)"
/>
<component
:is="
getValSelect(filter.field.fieldtype, filter.field.options)
"
v-else
v-model="filter.value"
placeholder="Value"
@change="(e) => updateFilter(idx, null, e.target.value)"
/>
</div>
</div>
<div v-else class="flex items-center gap-2">
<div class="w-13 pl-2 text-end text-base text-gray-600">
{{ idx == 0 ? "Where" : "And" }}
</div>
Expand Down Expand Up @@ -72,8 +120,8 @@
@change="(e) => updateFilter(idx, null, e.target.value)"
/>
</div>
<Button variant="ghost" icon="x" @click="removeFilter(idx)" />
</div>
<Button variant="ghost" icon="x" @click="removeFilter(idx)" />
</div>
</div>
<div
Expand Down Expand Up @@ -121,6 +169,7 @@ import { h } from "vue";
import { FormControl } from "frappe-ui";
import { NestedPopover, SearchComplete, Autocomplete } from "@/components";
import FilterIcon from "@/components/icons/FilterIcon.vue";
import { useScreenSize } from "@/composables/screen";
import { DocField } from "@/types";

let emit = defineEmits(["event:filter"]);
Expand All @@ -136,6 +185,8 @@ const props = defineProps({
},
});

const { isMobileView } = useScreenSize();

function setfilter(data) {
let filterEvent = {
event: "add",
Expand Down
Loading
Loading