diff --git a/.eslintrc.js b/.eslintrc.js index 8c91e1714..91bc2c92b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,20 +5,28 @@ module.exports = { node: true, }, extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:json/recommended", - "plugin:vue/vue3-recommended", - "plugin:tailwindcss/recommended", - "plugin:prettier/recommended", + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:json/recommended', + 'plugin:vue/vue3-recommended', + 'plugin:tailwindcss/recommended', + 'plugin:prettier/recommended', ], parserOptions: { - ecmaVersion: "latest", - sourceType: "module", - parser: "@typescript-eslint/parser", + ecmaVersion: 'latest', + sourceType: 'module', + parser: '@typescript-eslint/parser', }, rules: { - "tailwindcss/no-custom-classname": "off", - "vue/multi-word-component-names": "off", + 'tailwindcss/no-custom-classname': 'off', + 'vue/multi-word-component-names': 'off', + 'prettier/prettier': [ + 'warn', + { + singleQuote: true, + semi: true, + useTabs: false, + }, + ], }, }; diff --git a/.prettierrc.json b/.prettierrc.json index 3e6444c99..36110d011 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,3 +1,4 @@ { + "singleQuote": true, "useTabs": false } diff --git a/desk/index.html b/desk/index.html index 8b4a0eb2f..38b7735e1 100644 --- a/desk/index.html +++ b/desk/index.html @@ -1,21 +1,24 @@ - - - - - Helpdesk - - -
-
-
- - - + + + + + + Helpdesk + + + +
+
+
+ + + + diff --git a/desk/package.json b/desk/package.json index fe5c5cff4..b88eb114a 100644 --- a/desk/package.json +++ b/desk/package.json @@ -33,6 +33,7 @@ "vue": "^3.2.47", "vue-echarts": "^6.5.4", "vue-router": "^4.1.6", + "vue-sonner": "^1.0.2", "vuedraggable": "^4.1.0", "zod": "^3.21.4" }, diff --git a/desk/public/favicon.svg b/desk/public/favicon.svg index 3a95f8558..b85f2596f 100644 --- a/desk/public/favicon.svg +++ b/desk/public/favicon.svg @@ -1,4 +1,4 @@ - - - + + + diff --git a/desk/src/App.vue b/desk/src/App.vue index 0a535a370..a3deee0b9 100644 --- a/desk/src/App.vue +++ b/desk/src/App.vue @@ -2,16 +2,18 @@ + diff --git a/desk/src/components/AttachmentItem.vue b/desk/src/components/AttachmentItem.vue index 54c338a76..54c1ef100 100644 --- a/desk/src/components/AttachmentItem.vue +++ b/desk/src/components/AttachmentItem.vue @@ -4,7 +4,7 @@ - + diff --git a/desk/src/pages/desk/contact/ContactList.vue b/desk/src/pages/desk/contact/ContactList.vue index 4240933f3..7e6be3594 100644 --- a/desk/src/pages/desk/contact/ContactList.vue +++ b/desk/src/pages/desk/contact/ContactList.vue @@ -14,12 +14,7 @@ - + diff --git a/desk/src/pages/desk/team/TeamList.vue b/desk/src/pages/desk/team/TeamList.vue index f0e968946..7e6ab0086 100644 --- a/desk/src/pages/desk/team/TeamList.vue +++ b/desk/src/pages/desk/team/TeamList.vue @@ -14,12 +14,7 @@ - + -import { ref } from "vue"; -import { useRouter } from "vue-router"; -import { createResource, usePageMeta, Dialog, FormControl } from "frappe-ui"; -import { isEmpty } from "lodash"; -import { AGENT_PORTAL_TEAM_SINGLE } from "@/router"; -import { createListManager } from "@/composables/listManager"; -import { useError } from "@/composables/error"; -import PageTitle from "@/components/PageTitle.vue"; -import { ListView } from "@/components"; -import IconPlus from "~icons/lucide/plus"; +import { ref } from 'vue'; +import { useRouter } from 'vue-router'; +import { createResource, usePageMeta, Dialog, FormControl } from 'frappe-ui'; +import { isEmpty } from 'lodash'; +import { AGENT_PORTAL_TEAM_SINGLE } from '@/router'; +import { createListManager } from '@/composables/listManager'; +import { useError } from '@/composables/error'; +import PageTitle from '@/components/PageTitle.vue'; +import { ListView } from '@/components'; +import IconPlus from '~icons/lucide/plus'; const router = useRouter(); const showNewDialog = ref(false); const newTeamTitle = ref(null); -const emptyMessage = "No Teams Found"; -const columns = [ - { - label: "Name", - key: "name", - width: "w-80", - }, - { - label: "Assignment rule", - key: "assignment_rule", - width: "w-80", - }, -]; const teams = createListManager({ - doctype: "HD Team", - fields: ["name", "assignment_rule"], + doctype: 'HD Team', + fields: ['name', 'assignment_rule'], auto: true, transform: (data) => { for (const d of data) { @@ -93,17 +75,17 @@ const teams = createListManager({ }); const newTeam = createResource({ - url: "frappe.client.insert", + url: 'frappe.client.insert', makeParams() { return { doc: { - doctype: "HD Team", + doctype: 'HD Team', team_name: newTeamTitle.value, }, }; }, validate(params) { - if (isEmpty(params.doc.team_name)) return "Title is required"; + if (isEmpty(params.doc.team_name)) return 'Title is required'; }, auto: false, onSuccess() { @@ -114,12 +96,12 @@ const newTeam = createResource({ }, }); }, - onError: useError({ title: "Error creating team" }), + onError: useError({ title: 'Error creating team' }), }); usePageMeta(() => { return { - title: "Teams", + title: 'Teams', }; }); diff --git a/desk/src/pages/index.ts b/desk/src/pages/index.ts index 9134c4c47..81cb22df5 100644 --- a/desk/src/pages/index.ts +++ b/desk/src/pages/index.ts @@ -10,7 +10,7 @@ export { default as KBHome } from "./knowledge-base/KnowledgeBasePublicHome.vue" export { default as KBCategoryPublic } from "./knowledge-base/KnowledgeBasePublicCategory.vue"; export { default as KBArticlePublic } from "./knowledge-base/KnowledgeBaseArticle.vue"; -export { default as TicketAgent } from "./ticket/TicketAgent.vue"; +export { default as TicketAgent } from "./ticket/TicketView.vue"; export { default as TicketCustomer } from "./ticket/TicketCustomer.vue"; export { default as TicketNew } from "./ticket/TicketNew.vue"; export { default as TicketsAgent } from "./tickets/TicketsAgent.vue"; diff --git a/desk/src/pages/ticket/TicketActionsTags.vue b/desk/src/pages/ticket/TicketActionsTags.vue index cd8966782..76bddeb32 100644 --- a/desk/src/pages/ticket/TicketActionsTags.vue +++ b/desk/src/pages/ticket/TicketActionsTags.vue @@ -27,14 +27,14 @@
Tags
{ - ticket.reload().then(() => (showInput.value = false)); + tags.reload().then(() => (showInput.value = false)); }, }); const rmTag = createResource({ @@ -117,7 +127,7 @@ const rmTag = createResource({ dt: "HD Ticket", dn: ticket.data.name, }), - onSuccess: () => ticket.reload(), + onSuccess: () => tags.reload(), }); /** diff --git a/desk/src/pages/ticket/TicketAgent.vue b/desk/src/pages/ticket/TicketAgent.vue index 89cca059d..20a6f6a7c 100644 --- a/desk/src/pages/ticket/TicketAgent.vue +++ b/desk/src/pages/ticket/TicketAgent.vue @@ -155,8 +155,8 @@ " theme="gray" variant="solid" - :disabled="$refs.editor.editor.isEmpty || resource.loading" - @click="() => resource.submit()" + :disabled="$refs.editor.editor.isEmpty || send.loading" + @click="() => send.submit()" /> @@ -177,7 +177,7 @@ diff --git a/desk/src/pages/ticket/TicketAgentSidebar.vue b/desk/src/pages/ticket/TicketAgentSidebar.vue index 0b1337824..37baf3515 100644 --- a/desk/src/pages/ticket/TicketAgentSidebar.vue +++ b/desk/src/pages/ticket/TicketAgentSidebar.vue @@ -17,6 +17,7 @@ -import { ref } from "vue"; -import { Tooltip } from "frappe-ui"; -import { TabGroup, TabList, Tab, TabPanels, TabPanel } from "@headlessui/vue"; -import TicketActionsTags from "./TicketActionsTags.vue"; -import TicketContact from "./TicketContact.vue"; -import TicketDetails from "./TicketDetails.vue"; -import TicketHistory from "./TicketHistory.vue"; -import TicketViews from "./TicketViews.vue"; -import LucideContact2 from "~icons/lucide/contact-2"; -import LucideHistory from "~icons/lucide/history"; -import LucideInfo from "~icons/lucide/info"; -import LucidePointer from "~icons/lucide/pointer"; -import LucideView from "~icons/lucide/view"; +import { computed, ref } from 'vue'; +import { Tooltip } from 'frappe-ui'; +import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue'; +import { useAuthStore } from '@/stores/auth'; +import TicketActionsTags from './TicketActionsTags.vue'; +import TicketContact from './TicketContact.vue'; +import TicketDetails from './TicketDetails.vue'; +import TicketHistory from './TicketHistory.vue'; +import TicketViews from './TicketViews.vue'; +import LucideContact2 from '~icons/lucide/contact-2'; +import LucideHistory from '~icons/lucide/history'; +import LucideInfo from '~icons/lucide/info'; +import LucidePointer from '~icons/lucide/pointer'; +import LucideView from '~icons/lucide/view'; +const authStore = useAuthStore(); const isExpanded = ref(true); -const items = [ - { - name: "Details", - component: TicketDetails, - icon: LucideInfo, - }, - { - name: "Actions & Tags", - component: TicketActionsTags, - icon: LucidePointer, - }, - { - name: "Contact", - component: TicketContact, - icon: LucideContact2, - }, - { - name: "History", - component: TicketHistory, - icon: LucideHistory, - }, - { - name: "Views", - component: TicketViews, - icon: LucideView, - }, -]; +const items = computed(() => + [ + { + name: 'Details', + component: TicketDetails, + icon: LucideInfo, + }, + { + name: 'Actions & Tags', + component: TicketActionsTags, + icon: LucidePointer, + hidden: !authStore.isAgent, + }, + { + name: 'Contact', + component: TicketContact, + icon: LucideContact2, + }, + { + name: 'History', + component: TicketHistory, + icon: LucideHistory, + hidden: !authStore.isAgent, + }, + { + name: 'Views', + component: TicketViews, + icon: LucideView, + hidden: !authStore.isAgent, + }, + ].filter((i) => !i.hidden) +); diff --git a/desk/src/pages/ticket/TicketBreadcrumbs.vue b/desk/src/pages/ticket/TicketBreadcrumbs.vue index 56f23db20..115c829ac 100644 --- a/desk/src/pages/ticket/TicketBreadcrumbs.vue +++ b/desk/src/pages/ticket/TicketBreadcrumbs.vue @@ -10,7 +10,7 @@ }, }, { - label: ticket?.data?.subject || title, + label: title, }, ]" /> @@ -22,17 +22,10 @@ diff --git a/desk/src/pages/ticket/TicketComment.vue b/desk/src/pages/ticket/TicketComment.vue deleted file mode 100644 index 2349d4fd9..000000000 --- a/desk/src/pages/ticket/TicketComment.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - diff --git a/desk/src/pages/ticket/TicketCommentPrivate.vue b/desk/src/pages/ticket/TicketCommentPrivate.vue new file mode 100644 index 000000000..a47232c21 --- /dev/null +++ b/desk/src/pages/ticket/TicketCommentPrivate.vue @@ -0,0 +1,79 @@ + + + diff --git a/desk/src/pages/ticket/TicketCommunication.vue b/desk/src/pages/ticket/TicketCommentPublic.vue similarity index 53% rename from desk/src/pages/ticket/TicketCommunication.vue rename to desk/src/pages/ticket/TicketCommentPublic.vue index 43f4d3d12..21d9c39cf 100644 --- a/desk/src/pages/ticket/TicketCommunication.vue +++ b/desk/src/pages/ticket/TicketCommentPublic.vue @@ -1,9 +1,9 @@ diff --git a/desk/src/pages/ticket/TicketCustomer.vue b/desk/src/pages/ticket/TicketCustomer.vue index 9d48d7ffb..27f63826d 100644 --- a/desk/src/pages/ticket/TicketCustomer.vue +++ b/desk/src/pages/ticket/TicketCustomer.vue @@ -54,16 +54,16 @@ diff --git a/desk/src/pages/ticket/TicketCustomerActions.vue b/desk/src/pages/ticket/TicketCustomerActions.vue new file mode 100644 index 000000000..6f1b638d3 --- /dev/null +++ b/desk/src/pages/ticket/TicketCustomerActions.vue @@ -0,0 +1,38 @@ + + + diff --git a/desk/src/pages/ticket/TicketCustomerTemplateFields.vue b/desk/src/pages/ticket/TicketCustomerTemplateFields.vue index a2fc3d7f5..c3222a2cc 100644 --- a/desk/src/pages/ticket/TicketCustomerTemplateFields.vue +++ b/desk/src/pages/ticket/TicketCustomerTemplateFields.vue @@ -24,15 +24,15 @@ - - diff --git a/desk/src/pages/ticket/TicketHistory.vue b/desk/src/pages/ticket/TicketHistory.vue index 992b3e651..1ec5c2c08 100644 --- a/desk/src/pages/ticket/TicketHistory.vue +++ b/desk/src/pages/ticket/TicketHistory.vue @@ -1,29 +1,47 @@ diff --git a/desk/src/pages/ticket/TicketPinnedComments.vue b/desk/src/pages/ticket/TicketPinnedComments.vue index 35d368a76..e1dcf4db4 100644 --- a/desk/src/pages/ticket/TicketPinnedComments.vue +++ b/desk/src/pages/ticket/TicketPinnedComments.vue @@ -7,10 +7,11 @@
Pinned comments
- {{ "(" + pinnedComments.length + ")" }} + {{ '(' + pinnedComments.length + ')' }}
- + +
- +
diff --git a/desk/src/pages/ticket/TicketSidebarHeader.vue b/desk/src/pages/ticket/TicketSidebarHeader.vue index cf99a09a7..7e5210f83 100644 --- a/desk/src/pages/ticket/TicketSidebarHeader.vue +++ b/desk/src/pages/ticket/TicketSidebarHeader.vue @@ -1,13 +1,8 @@ diff --git a/desk/src/pages/ticket/TicketTextEditor.vue b/desk/src/pages/ticket/TicketTextEditor.vue index 826519410..405c401b0 100644 --- a/desk/src/pages/ticket/TicketTextEditor.vue +++ b/desk/src/pages/ticket/TicketTextEditor.vue @@ -1,6 +1,5 @@ -
- - - {{ placeholder }} - -
diff --git a/desk/src/pages/ticket/TicketViews.vue b/desk/src/pages/ticket/TicketViews.vue index bdc1a3895..f74d363a3 100644 --- a/desk/src/pages/ticket/TicketViews.vue +++ b/desk/src/pages/ticket/TicketViews.vue @@ -1,25 +1,27 @@ diff --git a/desk/src/pages/ticket/symbols.ts b/desk/src/pages/ticket/symbols.ts index d06805e20..560014969 100644 --- a/desk/src/pages/ticket/symbols.ts +++ b/desk/src/pages/ticket/symbols.ts @@ -1,4 +1,7 @@ import { InjectionKey } from "vue"; -import { Resource, Ticket } from "@/types"; +import { Resource, Ticket as T } from "@/types"; -export const ITicket: InjectionKey> = Symbol("Ticket"); +export const Comments: InjectionKey = Symbol("Comments"); +export const ITicket: InjectionKey> = Symbol("ITicket"); +export const Id: InjectionKey = Symbol("Id"); +export const Ticket: InjectionKey = Symbol("Ticket"); diff --git a/desk/src/pages/tickets/PresetFilters.vue b/desk/src/pages/tickets/PresetFilters.vue index 380f84816..c0dcc5f73 100644 --- a/desk/src/pages/tickets/PresetFilters.vue +++ b/desk/src/pages/tickets/PresetFilters.vue @@ -1,111 +1,67 @@ - diff --git a/desk/src/pages/tickets/TicketsAgent.vue b/desk/src/pages/tickets/TicketsAgent.vue index 214544372..809085024 100644 --- a/desk/src/pages/tickets/TicketsAgent.vue +++ b/desk/src/pages/tickets/TicketsAgent.vue @@ -12,9 +12,9 @@
- +
- + - +
- +
diff --git a/desk/src/pages/tickets/TicketsAgentList.vue b/desk/src/pages/tickets/TicketsAgentList.vue index 6ae262406..eeb3f180e 100644 --- a/desk/src/pages/tickets/TicketsAgentList.vue +++ b/desk/src/pages/tickets/TicketsAgentList.vue @@ -37,7 +37,7 @@ v-if="data.agreement_status" :label="data.agreement_status" :theme="slaStatusColorMap[data.agreement_status]" - variant="outline" + variant="subtle" /> - - -