frappe/helpdesk/main 218k tokens More Tools
```
├── .eslintrc.js (100 tokens)
├── .flake8 (100 tokens)
├── .git-blame-ignore-revs (100 tokens)
├── .github/
   ├── AgentListView.png
   ├── Hero2.png
   ├── ISSUE_TEMPLATE/
      ├── bug_report.yaml (400 tokens)
      ├── feature_request.yaml (500 tokens)
   ├── KB.png
   ├── Search2.png
   ├── hd-logo.svg (100 tokens)
   ├── helpers/
      ├── .flake8_strict (200 tokens)
      ├── install.sh (400 tokens)
      ├── site_config_mariadb.json (100 tokens)
   ├── release.yml (100 tokens)
   ├── try-on-f-cloud-button.svg (900 tokens)
   ├── workflows/
      ├── build.yml (300 tokens)
      ├── lint.yml (300 tokens)
      ├── server-tests.yml (700 tokens)
├── .gitignore (100 tokens)
├── .gitmodules
├── .lintstagedrc
├── .pre-commit-config.yaml (200 tokens)
├── .prettierrc.json
├── LICENSE (omitted)
├── MANIFEST.in (100 tokens)
├── README.md (1400 tokens)
├── commitlint.config.js (100 tokens)
├── desk/
   ├── .gitignore
   ├── index.html (2000 tokens)
   ├── lucide.ts (200 tokens)
   ├── package.json (300 tokens)
   ├── postcss.config.js
   ├── public/
      ├── article-2.png
      ├── article.png
      ├── desk.png
      ├── favicon.svg (100 tokens)
      ├── manifest/
         ├── apple-icon-180.png
         ├── apple-splash-1125-2436.jpg
         ├── apple-splash-1136-640.jpg
         ├── apple-splash-1170-2532.jpg
         ├── apple-splash-1179-2556.jpg
         ├── apple-splash-1242-2208.jpg
         ├── apple-splash-1242-2688.jpg
         ├── apple-splash-1284-2778.jpg
         ├── apple-splash-1290-2796.jpg
         ├── apple-splash-1334-750.jpg
         ├── apple-splash-1488-2266.jpg
         ├── apple-splash-1536-2048.jpg
         ├── apple-splash-1620-2160.jpg
         ├── apple-splash-1640-2360.jpg
         ├── apple-splash-1668-2224.jpg
         ├── apple-splash-1668-2388.jpg
         ├── apple-splash-1792-828.jpg
         ├── apple-splash-2048-1536.jpg
         ├── apple-splash-2048-2732.jpg
         ├── apple-splash-2160-1620.jpg
         ├── apple-splash-2208-1242.jpg
         ├── apple-splash-2224-1668.jpg
         ├── apple-splash-2266-1488.jpg
         ├── apple-splash-2360-1640.jpg
         ├── apple-splash-2388-1668.jpg
         ├── apple-splash-2436-1125.jpg
         ├── apple-splash-2532-1170.jpg
         ├── apple-splash-2556-1179.jpg
         ├── apple-splash-2688-1242.jpg
         ├── apple-splash-2732-2048.jpg
         ├── apple-splash-2778-1284.jpg
         ├── apple-splash-2796-1290.jpg
         ├── apple-splash-640-1136.jpg
         ├── apple-splash-750-1334.jpg
         ├── apple-splash-828-1792.jpg
         ├── manifest-icon-192.maskable.png
         ├── manifest-icon-512.maskable.png
   ├── src/
      ├── App.vue (200 tokens)
      ├── assets/
         ├── custom_icons/
            ├── bullet.svg (100 tokens)
            ├── check.svg (200 tokens)
            ├── chevron-down.svg (100 tokens)
            ├── chevron-up.svg (100 tokens)
            ├── circle_check.svg (100 tokens)
            ├── comment.svg (200 tokens)
            ├── corner_up_left.svg (200 tokens)
            ├── customers.svg (400 tokens)
            ├── dislike.svg (200 tokens)
            ├── document.svg (100 tokens)
            ├── external_link.svg (100 tokens)
            ├── f-desk.svg (800 tokens)
            ├── filter.svg (100 tokens)
            ├── folder.svg (100 tokens)
            ├── knowledge-based.svg (200 tokens)
            ├── like.svg (200 tokens)
            ├── lock.svg (300 tokens)
            ├── log_out.svg (100 tokens)
            ├── priority_high.svg (100 tokens)
            ├── priority_low.svg (100 tokens)
            ├── priority_medium.svg (100 tokens)
            ├── priority_urgent.svg (100 tokens)
            ├── reports.svg (200 tokens)
            ├── select.svg (100 tokens)
            ├── settings.svg (900 tokens)
            ├── sla-fail.svg (200 tokens)
            ├── sort-ascending.svg (100 tokens)
            ├── text_editor_icons/
               ├── Bold.svg (300 tokens)
               ├── Bullet list.svg (100 tokens)
               ├── Clear Formatting.svg (100 tokens)
               ├── Code.svg (100 tokens)
               ├── Decrease Indent.svg (100 tokens)
               ├── Image-add.svg (200 tokens)
               ├── Increase Indent.svg (100 tokens)
               ├── Italic.svg (100 tokens)
               ├── Left Align.svg (100 tokens)
               ├── Link-url.svg (200 tokens)
               ├── Numbered List.svg (500 tokens)
               ├── Quote.svg (200 tokens)
               ├── Text Color.svg (100 tokens)
               ├── Underline.svg (200 tokens)
            ├── ticket.svg (200 tokens)
            ├── time.svg (200 tokens)
            ├── user-plus.svg (100 tokens)
         ├── icons/
            ├── activity.svg (400 tokens)
            ├── add.svg (100 tokens)
            ├── alert-circle.svg (100 tokens)
            ├── at-sign.svg (400 tokens)
            ├── attachment.svg (300 tokens)
            ├── call.svg (300 tokens)
            ├── chat.svg (200 tokens)
            ├── comment.svg (500 tokens)
            ├── contact-solid.svg (300 tokens)
            ├── contact.svg (400 tokens)
            ├── customer-solid.svg (200 tokens)
            ├── customer.svg (200 tokens)
            ├── dashboard-solid.svg (200 tokens)
            ├── dashboard.svg (300 tokens)
            ├── delete.svg (400 tokens)
            ├── details.svg (300 tokens)
            ├── dot-horizontal.svg (100 tokens)
            ├── email.svg (100 tokens)
            ├── file.svg (1500 tokens)
            ├── filter.svg (100 tokens)
            ├── hash.svg (300 tokens)
            ├── home.svg (300 tokens)
            ├── knowledge-base-solid.svg (300 tokens)
            ├── knowledge-base.svg (600 tokens)
            ├── location.svg (400 tokens)
            ├── mail.svg (200 tokens)
            ├── pdf.svg (1700 tokens)
            ├── right-chevron.svg (100 tokens)
            ├── settings-solid.svg (300 tokens)
            ├── settings.svg (400 tokens)
            ├── sort-arrow.svg (300 tokens)
            ├── teams.svg (300 tokens)
            ├── ticket-solid.svg (300 tokens)
            ├── ticket.svg (300 tokens)
            ├── web-link.svg (200 tokens)
            ├── web.svg (600 tokens)
         ├── images/
            ├── frappe-mail.svg (200 tokens)
            ├── gmail.png
            ├── outlook.png
            ├── sendgrid.png
            ├── sparkpost.webp
            ├── yahoo.png
            ├── yandex.png
         ├── logos/
            ├── HDLogo.vue (100 tokens)
      ├── components/
         ├── Apps.vue (400 tokens)
         ├── AssignmentModal.vue (600 tokens)
         ├── AttachmentItem.vue (400 tokens)
         ├── Autocomplete.vue (1600 tokens)
         ├── BrandLogo.vue (100 tokens)
         ├── CannedResponseSelectorModal.vue (500 tokens)
         ├── CommentBox.vue (1100 tokens)
         ├── CommentTextEditor.vue (1000 tokens)
         ├── CommunicationArea.vue (700 tokens)
         ├── CustomActions.vue (400 tokens)
         ├── DiscardButton.vue (200 tokens)
         ├── EmailArea.vue (1100 tokens)
         ├── EmailContent.vue (1300 tokens)
         ├── EmailEditor.vue (1700 tokens)
         ├── EmptyState.vue (200 tokens)
         ├── FadedScrollableDiv.vue (400 tokens)
         ├── HistoryBox.vue (400 tokens)
         ├── Icon.vue (100 tokens)
         ├── IconPicker.vue (700 tokens)
         ├── LayoutHeader.vue (100 tokens)
         ├── ListRows.vue (600 tokens)
         ├── ListViewBuilder.vue (3.3k tokens)
         ├── MultiSelect.vue (300 tokens)
         ├── MultiSelectInput.vue (1300 tokens)
         ├── MultipleAvatar.vue (400 tokens)
         ├── NestedPopover.vue (300 tokens)
         ├── PageTitle.vue (100 tokens)
         ├── Pill.vue (100 tokens)
         ├── SearchArticles.vue (700 tokens)
         ├── SearchComplete.vue (400 tokens)
         ├── SearchPopover.vue (300 tokens)
         ├── Section.vue (500 tokens)
         ├── Settings/
            ├── Branding.vue (700 tokens)
            ├── EmailAccountCard.vue (300 tokens)
            ├── EmailAccountList.vue (400 tokens)
            ├── EmailAdd.vue (1000 tokens)
            ├── EmailConfig.vue (200 tokens)
            ├── EmailEdit.vue (1300 tokens)
            ├── EmailProviderIcon.vue (100 tokens)
            ├── SettingsModal.vue (300 tokens)
            ├── emailConfig.ts (1000 tokens)
         ├── SidebarLink.vue (500 tokens)
         ├── StarRating.vue (300 tokens)
         ├── TextEditor.vue (500 tokens)
         ├── UniInput.vue (500 tokens)
         ├── UniInput2.vue (700 tokens)
         ├── UserAvatar.vue (200 tokens)
         ├── UserMenu.vue (400 tokens)
         ├── ViewBreadcrumbs.vue (700 tokens)
         ├── ViewModal.vue (400 tokens)
         ├── canned-response/
            ├── CannedResponseModal.vue (500 tokens)
            ├── index.js
         ├── command-palette/
            ├── CP.vue (1400 tokens)
            ├── CPGroup.vue (100 tokens)
            ├── CPGroupResult.vue (200 tokens)
         ├── desk/
            ├── global/
               ├── AddNewAgentsDialog.vue (1000 tokens)
               ├── CustomIcons.vue (13.5k tokens)
               ├── NewContactDialog.vue (1300 tokens)
               ├── NewCustomerDialog.vue (400 tokens)
         ├── dialogs.jsx (200 tokens)
         ├── frappe-ui/
            ├── Autocomplete.vue (1600 tokens)
            ├── Dropdown.vue (1000 tokens)
            ├── Link.vue (1000 tokens)
         ├── icons/
            ├── ActivityIcon.vue (200 tokens)
            ├── AppsIcon.vue (400 tokens)
            ├── AscendingIcon.vue (100 tokens)
            ├── AttachmentIcon.vue (300 tokens)
            ├── ColumnsIcon.vue (200 tokens)
            ├── CommentIcon.vue (300 tokens)
            ├── DescendingIcon.vue (100 tokens)
            ├── DetailsIcon.vue (100 tokens)
            ├── DotIcon.vue (100 tokens)
            ├── DragIcon.vue (200 tokens)
            ├── EditIcon.vue (200 tokens)
            ├── EmailAtIcon.vue (400 tokens)
            ├── EmailIcon.vue (100 tokens)
            ├── FilterIcon.vue (100 tokens)
            ├── FrappeCloudIcon.vue (300 tokens)
            ├── IndicatorIcon.vue (100 tokens)
            ├── LinkIcon.vue (300 tokens)
            ├── OrganizationsIcon.vue (600 tokens)
            ├── PhoneIcon.vue (100 tokens)
            ├── PinIcon.vue (200 tokens)
            ├── RefreshIcon.vue (200 tokens)
            ├── ReloadIcon.vue (200 tokens)
            ├── ReplyAllIcon.vue (200 tokens)
            ├── ReplyIcon.vue (100 tokens)
            ├── SortIcon.vue (200 tokens)
            ├── ThumbsDownFilledIcon.vue (200 tokens)
            ├── ThumbsDownIcon.vue (200 tokens)
            ├── ThumbsUpFilledIcon.vue (200 tokens)
            ├── ThumbsUpIcon.vue (200 tokens)
            ├── TicketIcon.vue (300 tokens)
            ├── UnpinIcon.vue (200 tokens)
            ├── index.ts (400 tokens)
         ├── index.ts (400 tokens)
         ├── knowledge-base/
            ├── ArticleCard.vue (300 tokens)
            ├── ArticleFeedback.vue (400 tokens)
            ├── CategoryFolder.vue (200 tokens)
            ├── CategoryFolderContainer.vue (100 tokens)
            ├── CategoryModal.vue (400 tokens)
            ├── MergeCategoryModal.vue (200 tokens)
            ├── MoveToCategoryModal.vue (200 tokens)
         ├── layouts/
            ├── AppHeader.vue
            ├── DesktopLayout.vue (100 tokens)
            ├── MobileAppHeader.vue (100 tokens)
            ├── MobileLayout.vue (100 tokens)
            ├── MobileSidebar.vue (1300 tokens)
            ├── Sidebar.vue (1600 tokens)
            ├── layoutSettings.ts (300 tokens)
         ├── notifications/
            ├── Notifications.vue (700 tokens)
         ├── ticket/
            ├── ActivityHeader.vue (400 tokens)
            ├── ExportModal.vue (300 tokens)
            ├── TicketAgentActivities.vue (900 tokens)
            ├── TicketAgentContact.vue (300 tokens)
            ├── TicketAgentDetails.vue (700 tokens)
            ├── TicketAgentFields.vue (300 tokens)
            ├── TicketAgentSidebar.vue (500 tokens)
            ├── TicketCustomerSidebar.vue (1200 tokens)
            ├── TicketFeedback.vue (200 tokens)
            ├── TicketMergeModal.vue (900 tokens)
            ├── TicketSplitModal.vue (500 tokens)
            ├── index.ts
         ├── view-controls/
            ├── ColumnSettings.vue (1600 tokens)
            ├── Filter.vue (3.5k tokens)
            ├── QuickFilterField.vue (300 tokens)
            ├── QuickFilters.vue (300 tokens)
            ├── Reload.vue (100 tokens)
            ├── SortBy.vue (1700 tokens)
            ├── index.ts (100 tokens)
      ├── composables/
         ├── device.ts (100 tokens)
         ├── error.ts (100 tokens)
         ├── fc.ts (200 tokens)
         ├── formCustomisation.ts (700 tokens)
         ├── index.ts
         ├── mobile.ts
         ├── screen.ts (100 tokens)
         ├── useView.ts (900 tokens)
      ├── dayjs.ts (200 tokens)
      ├── index.css (100 tokens)
      ├── main.js (300 tokens)
      ├── pages/
         ├── CannedResponses.vue (1000 tokens)
         ├── CustomerPortalRoot.vue (100 tokens)
         ├── HRoot.vue (100 tokens)
         ├── InvalidPage.vue (100 tokens)
         ├── KeymapDialog.vue (200 tokens)
         ├── MobileNotifications.vue (700 tokens)
         ├── desk/
            ├── AgentRoot.vue (200 tokens)
            ├── agent/
               ├── Agents.vue (300 tokens)
            ├── contact/
               ├── ContactDialog.vue (1600 tokens)
               ├── Contacts.vue (500 tokens)
            ├── customer/
               ├── CustomerDialog.vue (500 tokens)
               ├── Customers.vue (500 tokens)
            ├── team/
               ├── TeamSingle.vue (1600 tokens)
               ├── Teams.vue (500 tokens)
         ├── knowledge-base/
            ├── Article.vue (2.5k tokens)
            ├── Articles.vue (400 tokens)
            ├── KnowledgeBaseAgent.vue (2.1k tokens)
            ├── KnowledgeBaseCustomer.vue (300 tokens)
            ├── NewArticle.vue (1000 tokens)
         ├── ticket/
            ├── MobileTicketAgent.vue (2.3k tokens)
            ├── TicketAgent.vue (2.4k tokens)
            ├── TicketBreadcrumbs.vue (200 tokens)
            ├── TicketCommunication.vue (300 tokens)
            ├── TicketConversation.vue (500 tokens)
            ├── TicketCustomer.vue (1400 tokens)
            ├── TicketCustomerTemplateFields.vue (700 tokens)
            ├── TicketFeedback.vue (600 tokens)
            ├── TicketNew.vue (1600 tokens)
            ├── TicketTextEditor.vue (600 tokens)
            ├── Tickets.vue (3k tokens)
            ├── data.ts (200 tokens)
            ├── symbols.ts
      ├── router/
         ├── index.ts (1200 tokens)
      ├── socket.ts (200 tokens)
      ├── stores/
         ├── agent.ts (100 tokens)
         ├── auth.ts (500 tokens)
         ├── config.ts (200 tokens)
         ├── contact.ts (100 tokens)
         ├── globalStore.ts
         ├── keymap.ts (400 tokens)
         ├── knowledgeBase.ts (500 tokens)
         ├── notification.ts (300 tokens)
         ├── sidebar.ts (100 tokens)
         ├── ticketStatus.ts (200 tokens)
         ├── user.ts (200 tokens)
      ├── telemetry.ts (500 tokens)
      ├── tiptap-extensions.ts (200 tokens)
      ├── types.ts (1300 tokens)
      ├── utils.ts (1100 tokens)
   ├── tailwind.config.js (100 tokens)
   ├── tsconfig.json (100 tokens)
   ├── vite.config.js (600 tokens)
   ├── yarn.lock (omitted)
├── docker/
   ├── docker-compose.yml (100 tokens)
   ├── init.sh (200 tokens)
├── helpdesk/
   ├── __init__.py
   ├── api/
      ├── account.py (500 tokens)
      ├── agent.py (100 tokens)
      ├── article.py (300 tokens)
      ├── auth.py (500 tokens)
      ├── config.py (100 tokens)
      ├── doc.py (3.4k tokens)
      ├── general.py (300 tokens)
      ├── knowledge_base.py (900 tokens)
      ├── permission.py (100 tokens)
      ├── session.py (100 tokens)
      ├── settings.py (600 tokens)
      ├── telemetry.py (200 tokens)
      ├── ticket.py (200 tokens)
   ├── config/
      ├── __init__.py
      ├── desktop.py (100 tokens)
      ├── docs.py (100 tokens)
   ├── consts.py
   ├── extends/
      ├── assignment_rule.py (100 tokens)
      ├── data_import.py (200 tokens)
   ├── helpdesk/
      ├── __init__.py
      ├── doctype/
         ├── __init__.py
         ├── hd_action/
            ├── __init__.py
            ├── hd_action.js
            ├── hd_action.json (400 tokens)
            ├── hd_action.py
            ├── test_hd_action.py
         ├── hd_agent/
            ├── __init__.py
            ├── hd_agent.js
            ├── hd_agent.json (300 tokens)
            ├── hd_agent.py (300 tokens)
            ├── test_hd_agent.py
         ├── hd_article/
            ├── __init__.py
            ├── hd_article.js
            ├── hd_article.json (500 tokens)
            ├── hd_article.py (700 tokens)
            ├── test_hd_article.py
         ├── hd_article_category/
            ├── __init__.py
            ├── hd_article_category.js
            ├── hd_article_category.json (300 tokens)
            ├── hd_article_category.py (300 tokens)
            ├── test_hd_article_category.py
         ├── hd_article_feedback/
            ├── __init__.py
            ├── hd_article_feedback.js
            ├── hd_article_feedback.json (300 tokens)
            ├── hd_article_feedback.py
            ├── test_hd_article_feedback.py (200 tokens)
         ├── hd_canned_response/
            ├── __init__.py
            ├── hd_canned_response.js
            ├── hd_canned_response.json (200 tokens)
            ├── hd_canned_response.py (200 tokens)
            ├── test_hd_canned_response.py
         ├── hd_customer/
            ├── __init__.py
            ├── hd_customer.js
            ├── hd_customer.json (300 tokens)
            ├── hd_customer.py (200 tokens)
            ├── test_hd_customer.py
         ├── hd_desk_account_request/
            ├── __init__.py
            ├── hd_desk_account_request.js
            ├── hd_desk_account_request.json (200 tokens)
            ├── hd_desk_account_request.py (200 tokens)
            ├── test_hd_desk_account_request.py
         ├── hd_escalation_rule/
            ├── __init__.py
            ├── hd_escalation_rule.js
            ├── hd_escalation_rule.json (500 tokens)
            ├── hd_escalation_rule.py (300 tokens)
            ├── test_hd_escalation_rule.py
         ├── hd_form_script/
            ├── __init__.py
            ├── hd_form_script.js
            ├── hd_form_script.json (400 tokens)
            ├── hd_form_script.py (200 tokens)
            ├── test_hd_form_script.py
         ├── hd_holiday/
            ├── README.md
            ├── __init__.py
            ├── hd_holiday.json (200 tokens)
            ├── hd_holiday.py
         ├── hd_notification/
            ├── __init__.py
            ├── hd_notification.js
            ├── hd_notification.json (400 tokens)
            ├── hd_notification.py (400 tokens)
            ├── test_hd_notification.py
            ├── utils.py (100 tokens)
         ├── hd_organization/
            ├── __init__.py
            ├── hd_organization.js
            ├── hd_organization.json (200 tokens)
            ├── hd_organization.py
            ├── test_hd_organization.py
         ├── hd_organization_contact_item/
            ├── __init__.py
            ├── hd_organization_contact_item.json (100 tokens)
            ├── hd_organization_contact_item.py
         ├── hd_pause_service_level_agreement_on_status/
            ├── __init__.py
            ├── hd_pause_service_level_agreement_on_status.json (100 tokens)
            ├── hd_pause_service_level_agreement_on_status.py (100 tokens)
         ├── hd_portal_signup_request/
            ├── __init__.py
            ├── hd_portal_signup_request.js
            ├── hd_portal_signup_request.json (200 tokens)
            ├── hd_portal_signup_request.py
            ├── test_hd_portal_signup_request.py
         ├── hd_preset_filter/
            ├── __init__.py
            ├── hd_preset_filter.js
            ├── hd_preset_filter.json (400 tokens)
            ├── hd_preset_filter.py (100 tokens)
            ├── test_hd_preset_filter.py
         ├── hd_preset_filter_item/
            ├── __init__.py
            ├── hd_preset_filter_item.json (200 tokens)
            ├── hd_preset_filter_item.py
         ├── hd_service_day/
            ├── __init__.py
            ├── hd_service_day.json (200 tokens)
            ├── hd_service_day.py (100 tokens)
         ├── hd_service_holiday_list/
            ├── README.md
            ├── __init__.py
            ├── hd_service_holiday_list.js (400 tokens)
            ├── hd_service_holiday_list.json (600 tokens)
            ├── hd_service_holiday_list.py (800 tokens)
            ├── hd_service_holiday_list_calendar.js (100 tokens)
            ├── hd_service_holiday_list_dashboard.py (100 tokens)
            ├── test_hd_service_holiday_list.py (300 tokens)
            ├── test_records.json (100 tokens)
         ├── hd_service_level_agreement/
            ├── __init__.py
            ├── hd_service_level_agreement.js (700 tokens)
            ├── hd_service_level_agreement.json (900 tokens)
            ├── hd_service_level_agreement.py (2.8k tokens)
            ├── hd_service_level_agreement_dashboard.py
            ├── patches/
               ├── missing_sla_creation.py (100 tokens)
            ├── test_hd_service_level_agreement.py
            ├── utils.py (300 tokens)
         ├── hd_service_level_agreement_fulfilled_on_status/
            ├── __init__.py
            ├── hd_service_level_agreement_fulfilled_on_status.json (100 tokens)
            ├── hd_service_level_agreement_fulfilled_on_status.py
         ├── hd_service_level_priority/
            ├── __init__.py
            ├── hd_service_level_priority.json (300 tokens)
            ├── hd_service_level_priority.py (100 tokens)
         ├── hd_settings/
            ├── __init__.py
            ├── hd_settings.js (100 tokens)
            ├── hd_settings.json (1500 tokens)
            ├── hd_settings.py (600 tokens)
            ├── test_hd_settings.py
         ├── hd_stopword/
            ├── __init__.py
            ├── hd_stopword.js
            ├── hd_stopword.json (200 tokens)
            ├── hd_stopword.py
            ├── test_hd_stopword.py
         ├── hd_support_search_source/
            ├── __init__.py
            ├── hd_support_search_source.json (600 tokens)
            ├── hd_support_search_source.py (100 tokens)
         ├── hd_synonym/
            ├── __init__.py
            ├── hd_synonym.json (100 tokens)
            ├── hd_synonym.py
         ├── hd_synonyms/
            ├── __init__.py
            ├── hd_synonyms.js
            ├── hd_synonyms.json (200 tokens)
            ├── hd_synonyms.py
            ├── test_hd_synonyms.py
         ├── hd_team/
            ├── __init__.py
            ├── hd_team.js
            ├── hd_team.json (400 tokens)
            ├── hd_team.py (1300 tokens)
            ├── test_hd_team.py
         ├── hd_team_member/
            ├── __init__.py
            ├── hd_team_member.json (100 tokens)
            ├── hd_team_member.py
         ├── hd_ticket/
            ├── __init__.py
            ├── api.py (2.8k tokens)
            ├── hd_ticket.js
            ├── hd_ticket.json (2k tokens)
            ├── hd_ticket.py (6.4k tokens)
            ├── patches/
               ├── fallback_ticket_type.py (100 tokens)
               ├── feedback_in_master.py (100 tokens)
               ├── first_responded_on.py (200 tokens)
               ├── replace_overdue_failed.py
            ├── test_hd_ticket.py (700 tokens)
         ├── hd_ticket_activity/
            ├── __init__.py
            ├── hd_ticket_activity.js
            ├── hd_ticket_activity.json (200 tokens)
            ├── hd_ticket_activity.py (100 tokens)
            ├── test_hd_ticket_activity.py
         ├── hd_ticket_comment/
            ├── __init__.py
            ├── hd_ticket_comment.js
            ├── hd_ticket_comment.json (300 tokens)
            ├── hd_ticket_comment.py (200 tokens)
            ├── test_hd_ticket_comment.py
         ├── hd_ticket_feedback_option/
            ├── __init__.py
            ├── hd_ticket_feedback_option.js
            ├── hd_ticket_feedback_option.json (300 tokens)
            ├── hd_ticket_feedback_option.py (100 tokens)
            ├── patches/
               ├── label_as_name.py (100 tokens)
               ├── ootb.py
            ├── test_hd_ticket_feedback_option.py
         ├── hd_ticket_priority/
            ├── __init__.py
            ├── hd_ticket_priority.js
            ├── hd_ticket_priority.json (300 tokens)
            ├── hd_ticket_priority.py (100 tokens)
            ├── test_hd_ticket_priority.py
         ├── hd_ticket_template/
            ├── __init__.py
            ├── api.py (500 tokens)
            ├── hd_ticket_template.js
            ├── hd_ticket_template.json (300 tokens)
            ├── hd_ticket_template.py (300 tokens)
            ├── test_hd_ticket_template.py
         ├── hd_ticket_template_field/
            ├── __init__.py
            ├── hd_ticket_template_field.js
            ├── hd_ticket_template_field.json (200 tokens)
            ├── hd_ticket_template_field.py
            ├── test_hd_ticket_template_field.py
         ├── hd_ticket_type/
            ├── __init__.py
            ├── hd_ticket_type.js
            ├── hd_ticket_type.json (300 tokens)
            ├── hd_ticket_type.py (100 tokens)
            ├── test_hd_ticket_type.py
         ├── hd_view/
            ├── __init__.py
            ├── hd_view.js
            ├── hd_view.json (800 tokens)
            ├── hd_view.py (200 tokens)
            ├── test_hd_view.py (200 tokens)
      ├── hooks/
         ├── contact.py (200 tokens)
      ├── report/
         ├── __init__.py
         ├── first_response_time_for_tickets/
            ├── __init__.py
            ├── first_response_time_for_tickets.js (200 tokens)
            ├── first_response_time_for_tickets.json (200 tokens)
            ├── first_response_time_for_tickets.py (200 tokens)
         ├── support_hour_distribution/
            ├── __init__.py
            ├── support_hour_distribution.js (100 tokens)
            ├── support_hour_distribution.json (100 tokens)
            ├── support_hour_distribution.py (600 tokens)
         ├── ticket_analytics/
            ├── __init__.py
            ├── test_ticket_analytics.py
            ├── ticket_analytics.js (700 tokens)
            ├── ticket_analytics.json (100 tokens)
            ├── ticket_analytics.py (1600 tokens)
         ├── ticket_search_analysis/
            ├── __init__.py
            ├── ticket_search_analysis.js (100 tokens)
            ├── ticket_search_analysis.json (100 tokens)
            ├── ticket_search_analysis.py (400 tokens)
         ├── ticket_summary/
            ├── __init__.py
            ├── ticket_summary.js (300 tokens)
            ├── ticket_summary.json (100 tokens)
            ├── ticket_summary.py (2.9k tokens)
      ├── utils/
         ├── email.py (200 tokens)
      ├── web_form/
         ├── __init__.py
         ├── tickets/
            ├── __init__.py
            ├── tickets.js
            ├── tickets.json (500 tokens)
            ├── tickets.py
      ├── workspace/
         ├── helpdesk/
            ├── helpdesk.json (800 tokens)
   ├── hooks.py (400 tokens)
   ├── mixins/
      ├── mentions.py (200 tokens)
   ├── modules.txt
   ├── overrides/
      ├── contact.py (200 tokens)
   ├── patches.txt (200 tokens)
   ├── patches/
      ├── add_priority_integer.py (100 tokens)
      ├── agent_manager_perms.py
      ├── change_app_name_to_helpdesk.py (100 tokens)
      ├── communication_read_perm_agent.py
      ├── create_helpdesk_folder.py
      ├── default_article_category.py (200 tokens)
      ├── naming_autoincrement.py (200 tokens)
      ├── rename_doctypes_prefix_with_hd.py (400 tokens)
      ├── rename_frappedesk_module_references.py (100 tokens)
      ├── template_remove_default_fields.py (100 tokens)
      ├── update_hd_team_users.py (200 tokens)
   ├── search.py (2.5k tokens)
   ├── setup/
      ├── default_template.py (100 tokens)
      ├── file.py
      ├── install.py (1700 tokens)
      ├── setup_wizard.py (100 tokens)
      ├── ticket_feedback.py (100 tokens)
      ├── ticket_type.py (100 tokens)
      ├── welcome_ticket.py (300 tokens)
   ├── templates/
      ├── components/
         ├── contact_with_us.html (100 tokens)
         ├── knowledge_base_title_with_search_bar.html (100 tokens)
         ├── search/
            ├── search.html (600 tokens)
            ├── search.py (100 tokens)
      ├── emails/
         ├── email_verification.html (100 tokens)
         ├── macros.html (200 tokens)
         ├── new_reply_on_customer_portal_notification.html (100 tokens)
         ├── new_reply_to_agent.html (100 tokens)
         ├── notification.html
      ├── kb_base_template.html (600 tokens)
   ├── utils.py (900 tokens)
   ├── www/
      ├── __init__.py
      ├── helpdesk/
         ├── __init__.py
         ├── index.py (300 tokens)
├── package.json
├── pyproject.toml (100 tokens)
├── screenshot.webp
├── yarn.lock (omitted)
```


## /.eslintrc.js

```js path="/.eslintrc.js" 
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: [
    "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",
  },
  rules: {
    "tailwindcss/no-custom-classname": "off",
    "vue/multi-word-component-names": "off",
  },
};

```

## /.flake8

```flake8 path="/.flake8" 
[flake8]
ignore =
    E121,
    E126,
    E127,
    E128,
    E203,
    E225,
    E226,
    E231,
    E241,
    E251,
    E261,
    E265,
    E302,
    E303,
    E305,
    E402,
    E501,
    E741,
    W291,
    W292,
    W293,
    W391,
    W503,
    W504,
    F403,
    B007,
    B950,
    W191,
    E124, # closing bracket, irritating while writing QB code
    E131, # continuation line unaligned for hanging indent
    E123, # closing bracket does not match indentation of opening bracket's line
    E101, # ensured by use of black

max-line-length = 200
exclude=.github/helper/semgrep_rules
```

## /.git-blame-ignore-revs

```git-blame-ignore-revs path="/.git-blame-ignore-revs" 
# Since version 2.23 (released in August 2019), git-blame has a feature
# to ignore or bypass certain commits.
#
# This file contains a list of commits that are not likely what you
# are looking for in a blame, such as mass reformatting or renaming.
# You can set this file as a default ignore file for blame by running
# the following command.
#
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs

# bulk formatting
b7fb25fe7c784c4dcf639cf954445ac8452a85d9
353aaae07a5f56c5686caa79ce5d1e2e1544494a

```

## /.github/AgentListView.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/.github/AgentListView.png

## /.github/Hero2.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/.github/Hero2.png

## /.github/ISSUE_TEMPLATE/bug_report.yaml

```yaml path="/.github/ISSUE_TEMPLATE/bug_report.yaml" 
---
name: Bug Report
description: Report a bug encountered while using Frappe Helpdesk
labels: ["bug"]

body:
  - type: markdown
    attributes:
      value: |
        Welcome to Frappe Helpdesk issue tracker! Before creating an issue, please consider the following:

        1. This tracker should only be used to report bugs and request features / enhancements to Frappe Helpdesk
            - For questions and general support, checkout the [documentation](https://docs.frappe.io/helpdesk) or use the [forum](https://discuss.frappe.io) to get inputs from the open source community.
            - For documentation issues, propose edit on the [documentation site](https://docs.frappe.io/helpdesk) directly.
        2. When making a bug report, make sure you provide all required information. The easier it is for
           maintainers to reproduce, the faster it'll be fixed.
        3. If you think you know what the reason for the bug is, share it with us. Maybe put in a PR 😉

  - type: textarea
    id: bug-info
    attributes:
      label: Information about bug
      description: Also tell us, what did you expect to happen? If applicable, add screenshots to help explain your problem.
      placeholder: Please provide as much information as possible.
    validations:
      required: true

  - type: textarea
    id: exact-version
    attributes:
      label: Version
      description: Share exact version number of Frappe, and Frappe Helpdesk you are using.
      placeholder: |
        Frappe version -
        Frappe Helpdesk version -
    validations:
      required: true

  - type: dropdown
    id: install-method
    attributes:
      label: Installation method
      options:
        - docker
        - easy-install
        - manual install
        - FrappeCloud
    validations:
      required: false

  - type: textarea
    id: logs
    attributes:
      label: Relevant log output / Stack trace / Full Error Message.
      description: Please copy and paste any relevant log output. This will be automatically formatted.
      render: shell

...

```

## /.github/ISSUE_TEMPLATE/feature_request.yaml

```yaml path="/.github/ISSUE_TEMPLATE/feature_request.yaml" 
---
name: Feature Request
description: Suggest an idea to improve Frappe Helpdesk
labels: ["feature-request"]

body:
  - type: markdown
    attributes:
      value: |
        Welcome to Frappe Helpdesk issue tracker! Before submitting a request, please consider the following:

        1. This tracker should only be used to report bugs and request features / enhancements to Frappe Helpdesk
            - For questions and general support, checkout the [documentation](https://docs.frappe.io/helpdesk) or use the [forum](https://discuss.frappe.io) to get inputs from the open source community.
        2. Use the search function before creating a new issue. Duplicates will be closed and directed to
          the original discussion.
        3. When making a feature request, make sure to be as verbose as possible. The better you convey your message, the greater the drive to make it happen.


        Please keep in mind that we get many many requests and we can't possibly work on all of them, we prioritize development based on the goals of the product and organization. Feature requests are still welcome as it helps us in research when we do decide to work on the requested feature.

        If you're in urgent need to a feature, please try the following channels to get paid developments done quickly:
        1. Certified Frappe partners: https://frappe.io/partners
        2. Developer community on Frappe forums: https://discuss.frappe.io/c/developers/5
        3. Telegram group for Frappe Helpdesk development work: https://t.me/+eBnEZm7urwEwYTc1

  - type: textarea
    id: problem-info
    attributes:
      label: Is your feature request related to a problem? Please describe.
      description: A clear and concise description of what the problem is. Eg. I'm always frustrated when [...]
      placeholder: Please provide as much information as possible.

  - type: textarea
    id: solution-info
    attributes:
      label: Describe the solution you'd like
      description: A clear and concise description of what you want to happen.

  - type: textarea
    id: alternatives-info
    attributes:
      label: Describe the alternatives you've considered
      description: A clear and concise description of any alternative solutions or features you've considered.

  - type: textarea
    id: additional-info
    attributes:
      label: Additional context
      description: Add any other context or screenshots about the feature request here.
...
```

## /.github/KB.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/.github/KB.png

## /.github/Search2.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/.github/Search2.png

## /.github/hd-logo.svg

```svg path="/.github/hd-logo.svg" 
<svg width="118" height="118" viewBox="0 0 118 118" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M93.9278 0H23.1013C10.3428 0 0 10.3428 0 23.1013V93.9278C0 106.686 10.3428 117.029 23.1013 117.029H93.9278C106.686 117.029 117.029 106.686 117.029 93.9278V23.1013C117.029 10.3428 106.686 0 93.9278 0Z" fill="#7D42FB"/>
<path d="M95.9759 50.8753V27.8265L21 27.8265V38.3271H85.5278V48.3027C81.3275 49.5103 78.2824 53.3955 78.2824 57.9632C78.2824 62.531 81.3275 66.3637 85.5278 67.5713V77.5468H31.5006V50.1403H21V88.0474H96.0284V64.9986L89.7805 60.5359V55.3906L96.0284 50.9278L95.9759 50.8753Z" fill="#EDF7FF"/>
</svg>

```

## /.github/helpers/.flake8_strict

```flake8_strict path="/.github/helpers/.flake8_strict" 
[flake8]
ignore =
    B007,
    B009,
    B010,
    B950,
    E101,
    E111,
    E114,
    E116,
    E117,
    E121,
    E122,
    E123,
    E124,
    E125,
    E126,
    E127,
    E128,
    E131,
    E201,
    E202,
    E203,
    E211,
    E221,
    E222,
    E223,
    E224,
    E225,
    E226,
    E228,
    E231,
    E241,
    E242,
    E251,
    E261,
    E262,
    E265,
    E266,
    E271,
    E272,
    E273,
    E274,
    E301,
    E302,
    E303,
    E305,
    E306,
    E402,
    E501,
    E502,
    E701,
    E702,
    E703,
    E741,
    F403,
    W191,
    W291,
    W292,
    W293,
    W391,
    W503,
    W504,
    E711,
    E129,
    F841,
    E713,
    E712,
    B023


max-line-length = 200
exclude=.github/helper/semgrep_rules,test_*.py
```

## /.github/helpers/install.sh

```sh path="/.github/helpers/install.sh" 
#!/bin/bash

set -e

cd ~ || ex

sudo apt update
sudo apt remove mysql-server mysql-client
sudo apt install libcups2-dev redis-server mariadb-client libmariadb-dev

pip install frappe-bench

git clone "https://github.com/frappe/frappe" --branch "develop" --depth 1 
bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench

mkdir ~/frappe-bench/sites/test_site

cp -r "${GITHUB_WORKSPACE}/.github/helpers/site_config_mariadb.json" ~/frappe-bench/sites/test_site/site_config.json

mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'"
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"

mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE DATABASE test_frappe"
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"

mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "FLUSH PRIVILEGES"

install_whktml() {
    wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
    tar -xf /tmp/wkhtmltox.tar.xz -C /tmp
    sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
    sudo chmod o+x /usr/local/bin/wkhtmltopdf
}
install_whktml &

cd ~/frappe-bench || exit

sed -i 's/watch:/# watch:/g' Procfile
sed -i 's/schedule:/# schedule:/g' Procfile
sed -i 's/socketio:/# socketio:/g' Procfile
sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile

bench get-app helpdesk "${GITHUB_WORKSPACE}"
bench setup requirements --dev


bench start &>> ~/frappe-bench/bench_start.log &
CI=Yes bench build --app frappe &
bench --site test_site reinstall --yes

```

## /.github/helpers/site_config_mariadb.json

```json path="/.github/helpers/site_config_mariadb.json" 
{
	"db_host": "127.0.0.1",
	"db_port": 3306,
	"db_name": "test_frappe",
	"db_password": "test_frappe",
	"auto_email_id": "test@example.com",
	"mail_server": "smtp.example.com",
	"mail_login": "test@example.com",
	"mail_password": "test",
	"admin_password": "admin",
	"root_login": "root",
	"root_password": "root",
	"host_name": "http://test_site:8000",
	"install_apps": ["helpdesk"],
	"throttle_user_limit": 100
}

```

## /.github/release.yml

```yml path="/.github/release.yml" 
changelog:
  exclude:
    authors:
      - octocat
  categories:
    - title: Breaking Changes 🛠
      labels:
        - breaking-change
    - title: Bug Fixes 🐛
      labels:
        - bug-fix
    - title: Exciting New Features 🎉
      labels:
        - enhancement
        - feature

```

## /.github/try-on-f-cloud-button.svg

```svg path="/.github/try-on-f-cloud-button.svg" 
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="4 2 193 52">
<g filter="url(#filter0_dd)">
<rect x="4" y="2" width="193" height="52" rx="6" fill="#2490EF"/>
<path d="M28 22.2891H32.8786V35.5H36.2088V22.2891H41.0874V19.5H28V22.2891Z" fill="white"/>
<path d="M41.6982 35.5H45.0129V28.7109C45.0129 27.2344 46.0866 26.2188 47.5494 26.2188C48.0085 26.2188 48.6388 26.2969 48.95 26.3984V23.4453C48.6543 23.375 48.2419 23.3281 47.9074 23.3281C46.5691 23.3281 45.472 24.1094 45.0362 25.5938H44.9117V23.5H41.6982V35.5Z" fill="white"/>
<path d="M52.8331 40C55.2996 40 56.6068 38.7344 57.2837 36.7969L61.9289 23.5156L58.4197 23.5L55.9221 32.3125H55.7976L53.3233 23.5H49.8374L54.1247 35.8437L53.9302 36.3516C53.4944 37.4766 52.6619 37.5312 51.4947 37.1719L50.7478 39.6562C51.2224 39.8594 51.9927 40 52.8331 40Z" fill="white"/>
<path d="M73.6142 35.7344C77.2401 35.7344 79.4966 33.2422 79.4966 29.5469C79.4966 25.8281 77.2401 23.3438 73.6142 23.3438C69.9883 23.3438 67.7319 25.8281 67.7319 29.5469C67.7319 33.2422 69.9883 35.7344 73.6142 35.7344ZM73.6298 33.1562C71.9569 33.1562 71.101 31.6171 71.101 29.5233C71.101 27.4296 71.9569 25.8827 73.6298 25.8827C75.2715 25.8827 76.1274 27.4296 76.1274 29.5233C76.1274 31.6171 75.2715 33.1562 73.6298 33.1562Z" fill="white"/>
<path d="M84.7253 28.5625C84.7331 27.0156 85.6512 26.1094 86.9895 26.1094C88.3201 26.1094 89.1215 26.9844 89.1137 28.4531V35.5H92.4284V27.8594C92.4284 25.0625 90.7945 23.3438 88.3046 23.3438C86.5306 23.3438 85.2466 24.2187 84.7097 25.6172H84.5697V23.5H81.4106V35.5H84.7253V28.5625Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M102.429 19.5H113.429V22.3141H102.429V19.5ZM102.429 35.5V26.6794H112.699V29.4982H105.94V35.5H102.429Z" fill="white"/>
<path d="M131.584 24.9625C131.09 21.5057 128.345 19.5 124.785 19.5C120.589 19.5 117.429 22.463 117.429 27.4924C117.429 32.5142 120.55 35.4848 124.785 35.4848C128.604 35.4848 131.137 33.0916 131.584 30.1211L128.651 30.1059C128.282 31.9293 126.745 32.9549 124.824 32.9549C122.22 32.9549 120.354 31.0632 120.354 27.4924C120.354 23.9824 122.204 22.0299 124.832 22.0299C126.784 22.0299 128.314 23.1011 128.651 24.9625H131.584Z" fill="white"/>
<path d="M136.409 19.7124H133.571V35.2718H136.409V19.7124Z" fill="white"/>
<path d="M144.031 35.5001C147.56 35.5001 149.803 33.0917 149.803 29.483C149.803 25.8667 147.56 23.4507 144.031 23.4507C140.502 23.4507 138.259 25.8667 138.259 29.483C138.259 33.0917 140.502 35.5001 144.031 35.5001ZM144.047 33.2969C142.094 33.2969 141.137 31.6103 141.137 29.4754C141.137 27.3406 142.094 25.6312 144.047 25.6312C145.968 25.6312 146.925 27.3406 146.925 29.4754C146.925 31.6103 145.968 33.2969 144.047 33.2969Z" fill="white"/>
<path d="M159.338 30.3641C159.338 32.1419 158.028 33.0232 156.773 33.0232C155.409 33.0232 154.499 32.0887 154.499 30.6072V23.6025H151.66V31.0327C151.66 33.8361 153.307 35.4239 155.675 35.4239C157.479 35.4239 158.749 34.5046 159.298 33.1979H159.424V35.272H162.176V23.6025H159.338V30.3641Z" fill="white"/>
<path d="M169.014 35.4769C171.084 35.4769 172.017 34.2841 172.464 33.4332H172.637V35.2718H175.429V19.7124H172.582V25.532H172.464C172.033 24.6887 171.147 23.4503 169.022 23.4503C166.238 23.4503 164.05 25.5624 164.05 29.4522C164.05 33.2965 166.175 35.4769 169.014 35.4769ZM169.806 33.2205C167.931 33.2205 166.943 31.6251 166.943 29.437C166.943 27.2642 167.916 25.7067 169.806 25.7067C171.633 25.7067 172.637 27.173 172.637 29.437C172.637 31.701 171.617 33.2205 169.806 33.2205Z" fill="white"/>
</g>
<defs>
<filter id="filter0_dd" x="0" y="0" width="201" height="60" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="0.25"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.13 0"/>
<feBlend mode="normal" in2="effect1_dropShadow" result="effect2_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow" result="shape"/>
</filter>
</defs>
</svg>
```

## /.github/workflows/build.yml

```yml path="/.github/workflows/build.yml" 
name: Build Container Image
on:
  workflow_dispatch:
  push:
    branches:
      - main
    tags:
      - "*"

jobs:
  build:
    name: Build

    runs-on: ubuntu-latest

    strategy:
      matrix:
        arch: [amd64, arm64]

    steps:
      - name: Checkout Entire Repository
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          platforms: linux/${{ matrix.arch }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Set Branch
        run: |
          export APPS_JSON='[{"url": "https://github.com/frappe/helpdesk","branch": "main"}]'
          echo "APPS_JSON_BASE64=$(echo $APPS_JSON | base64 -w 0)" >> $GITHUB_ENV
          echo "FRAPPE_BRANCH=version-15" >> $GITHUB_ENV

      - name: Set Image Tag
        run: |
          echo "IMAGE_TAG=stable" >> $GITHUB_ENV

      - uses: actions/checkout@v4
        with:
          repository: frappe/frappe_docker
          path: builds

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          push: true
          context: builds
          file: builds/images/layered/Containerfile
          tags: >
            ghcr.io/${{ github.repository }}:${{ github.ref_name }},
            ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}
          build-args: |
            "FRAPPE_BRANCH=${{ env.FRAPPE_BRANCH }}"
            "APPS_JSON_BASE64=${{ env.APPS_JSON_BASE64 }}"
```

## /.github/workflows/lint.yml

```yml path="/.github/workflows/lint.yml" 
name: Lint

on:
  pull_request:
    branches:
      - main
      - develop

jobs:
  commit-lint:
    name: Semantic Commits
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 200
      - uses: actions/setup-node@v3
        with:
          node-version: 18
          check-latest: true
      - name: Check commit titles
        run: |
          npm install @commitlint/cli @commitlint/config-conventional
          npx commitlint --verbose --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }}

  linter:
    name: 'Frappe Linter'
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'

    steps:
      - uses: actions/checkout@v2

      - name: Set up Python 3.10
        uses: actions/setup-python@v2
        with:
          python-version: '3.10'

      - name: Install and Run Pre-commit
        uses: pre-commit/action@v3.0.1

      - name: Download Semgrep rules
        run: git clone --depth 1 https://github.com/frappe/semgrep-rules.git frappe-semgrep-rules

      - name: Download semgrep
        run: pip install semgrep

      - name: Run Semgrep rules
        run: semgrep ci --config ./frappe-semgrep-rules/rules --config r/python.lang.correctness

```

## /.github/workflows/server-tests.yml

```yml path="/.github/workflows/server-tests.yml" 
name: Server

on:
  pull_request:
    branches:
      - main
      - develop

    paths-ignore:
      - '**.js'
      - '**.css'
      - '**.md'
      - '**.html'
      - '**.csv'
  workflow_dispatch:
    inputs:
      user:
        description: 'Frappe Framework repository user (add your username for forks)'
        required: true
        default: 'frappe'
        type: string
      branch:
        description: 'Frappe Framework branch'
        default: 'develop'
        required: false
        type: string

concurrency:
  group: develop-${{ github.event.number }}
  cancel-in-progress: true

jobs:
  test:
    name: Python Unit Tests
    runs-on: ubuntu-latest
    timeout-minutes: 60

    strategy:
      fail-fast: false

    services:
        mysql:
          image: mariadb:10.6
          env:
            MARIADB_ROOT_PASSWORD: 'root'
          ports:
            - 3306:3306
          options: --health-cmd="mariadb-admin ping" --health-interval=5s --health-timeout=2s --health-retries=3

    steps:
      - name: Clone
        uses: actions/checkout@v2

      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.10'

      - name: Check for valid Python & Merge Conflicts
        run: |
          python -m compileall -f "${GITHUB_WORKSPACE}"
          if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
              then echo "Found merge conflicts"
              exit 1
          fi

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: 18
          check-latest: true

      - name: Install Yarn
        run: npm install -g yarn

      - name: Add to Hosts
        run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts

      - name: Cache pip
        uses: actions/cache@v4
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/pyproject.toml') }}
          restore-keys: |
            ${{ runner.os }}-pip-
            ${{ runner.os }}-

      - name: Cache node modules
        uses: actions/cache@v4
        env:
          cache-name: cache-node-modules
        with:
          path: ~/.npm
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
            ${{ runner.os }}-build-
            ${{ runner.os }}-

      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn cache dir)"

      - uses: actions/cache@v4
        id: yarn-cache
        with:
          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-

      - name: Install
        run: bash ${GITHUB_WORKSPACE}/.github/helpers/install.sh
        env:
          TYPE: server
          FRAPPE_USER: ${{ github.event.inputs.user }}
          FRAPPE_BRANCH: ${{ github.event.inputs.branch }}

      # - name: Run Tests
      #   run: 'cd ~/frappe-bench/ && bench --site test_site run-tests --app helpdesk'
      #   env:
      #     TYPE: server
      #     CI_BUILD_ID: ${{ github.run_id }}
      #     ORCHESTRATOR_URL: http://test-orchestrator.frappe.io


```

## /.gitignore

```gitignore path="/.gitignore" 
# Byte-compiled / optimized / DLL files
__pycache__/

.DS_Store
*.pyc
*.egg-info
*.swp
*.log
tags
node_modules
.vscode

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg

helpdesk/docs/current
helpdesk/public/desk
helpdesk/public/frontend
helpdesk/public/node_modules
helpdesk/www/helpdesk/index.html
desk/components.d.ts

```

## /.gitmodules

```gitmodules path="/.gitmodules" 
[submodule "frappe-ui"]
	path = frappe-ui
	url = https://github.com/frappe/frappe-ui.git

```

## /.lintstagedrc

```lintstagedrc path="/.lintstagedrc" 
{
	"**/*.{vue,js,ts,json}": "eslint --fix"
}

```

## /.pre-commit-config.yaml

```yaml path="/.pre-commit-config.yaml" 
exclude: "node_modules|.git"
default_stages: [commit]
fail_fast: false

repos:
  - repo: https://github.com/psf/black
    rev: 22.6.0
    hooks:
      - id: black
        types_or: [python, pyi]

  - repo: https://github.com/PyCQA/flake8
    rev: 5.0.4
    hooks:
      - id: flake8
        additional_dependencies:
          - flake8-bugbear
          - flake8-comprehensions
          - flake8-simplify
        args: ['--config', '.github/helpers/.flake8_strict']

  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v2.6.2
    hooks:
      - id: prettier
        additional_dependencies:
          - prettier@2.6.2
        types: [file]
        types_or: [javascript, vue, html]

  - repo: https://github.com/timothycrosley/isort
    rev: 5.12.0
    hooks:
      - id: isort
        args: [--profile, black]

ci:
  autoupdate_schedule: weekly
  skip: []
  submodules: false

```

## /.prettierrc.json

```json path="/.prettierrc.json" 
{
	"semi": true,
	"tabWidth": 2,
	"useTabs": false
}

```

## /MANIFEST.in

```in path="/MANIFEST.in" 
include MANIFEST.in
include requirements.txt
include *.json
include *.md
include *.py
include *.txt
recursive-include helpdesk *.css
recursive-include helpdesk *.csv
recursive-include helpdesk *.html
recursive-include helpdesk *.ico
recursive-include helpdesk *.js
recursive-include helpdesk *.json
recursive-include helpdesk *.md
recursive-include helpdesk *.png
recursive-include helpdesk *.py
recursive-include helpdesk *.svg
recursive-include helpdesk *.txt
recursive-exclude helpdesk *.pyc

```

## /README.md

<div align="center" markdown="1">

<img src=".github/hd-logo.svg" alt="Frappe Helpdesk logo" width="80"/>
<h1>Frappe Helpdesk</h1>

**Customer Service, Made Simple and Effective**

![GitHub release (latest by date)](https://img.shields.io/github/v/release/frappe/helpdesk)
[![codecov](https://codecov.io/github/frappe/helpdesk/branch/develop/graph/badge.svg?token=8ZXHCY4G9U)](https://codecov.io/github/frappe/helpdesk)

<a href="https://trendshift.io/repositories/12764" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12764" alt="teableio%2Fteable | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</div>

</div>


<div align="center">
	<img src="./.github/Hero2.png" alt="Hero Image" width="100%" />
</div>
<br />
<div align="center">
	<a href="https://frappe.io/helpdesk">Website</a>
	-
	<a href="https://docs.frappe.io/helpdesk">Documentation</a>
</div>

## Frappe Helpdesk
Frappe Helpdesk is an 100% open-source Ticket Management tool which helps you  streamline your company's support, offers an easy setup, clean user interface, and automation tools to resolve customer queries efficiently.



### Motivation
Managing issues from our customers was a big challenge for us. We were using the ERPNext support module which was not very good in UI and the UX was also not good. We wanted to have a tool that can be easily integrated with our existing system and can be customized as per our needs. So we decided to build Frappe Helpdesk.

### Key Features

- **Agent and Customer Portal Views**: Dual portals for agents and customers to simplify issue submission and management.

- **Customizable SLAs**: Discover how you can set and track SLAs for better response times.

- **Assignment Rules**: Custom auto-assignment of tickets based on priority, issue type, or workload.

- **Knowledge Base**: Learn how to create and manage help articles to empower users and reduce tickets.

- **Canned Responses**: Pre-written replies for common queries to ensure quick and consistent communication.

<details open>
<summary >View Screenshots</summary>
<h3></h3>

<div align="center">
	<sub>
		Agent List View
	</sub>
</div>

![Agent List View](.github/AgentListView.png)


<div align="center">
	<sub>
		Upload articles and let your customer solve their queries through the Knowledge Base.
	</sub>
</div>

![Knowledge Base](.github/KB.png)

<div align="center">
	<sub>
		With advanced search, your customers will be recommended relevant articles regarding their issue.
	</sub>
</div>


![Article Search](.github/Search2.png)



</details>
<br>


### Under the Hood

- [**Frappe Framework**](https://github.com/frappe/frappe): A full-stack web application framework written in Python and Javascript.

- [**Frappe UI**](https://github.com/frappe/frappe-ui): A Vue-based UI library, to provide a modern user interface. 


## Production Setup

### Managed Hosting

You can try [Frappe Cloud](https://frappecloud.com), a simple, user-friendly and sophisticated [open-source](https://github.com/frappe/press) platform to host Frappe applications with peace of mind.

It takes care of installation, setup, upgrades, monitoring, maintenance and support of your Frappe deployments. It is a fully featured developer platform with an ability to manage and control multiple Frappe deployments.

<div>
	<a href="https://frappecloud.com/helpdesk/signup" target="_blank">
		<picture>
			<source media="(prefers-color-scheme: dark)" srcset="https://frappe.io/files/try-on-fc-white.png">
			<img src="https://frappe.io/files/try-on-fc-black.png" alt="Try on Frappe Cloud" height="28" />
		</picture>
	</a>
</div>

### Self Hosting

Follow these steps to set up Frappe Helpdesk in production:

**Step 1**: Download the easy install script

```bash
wget https://frappe.io/easy-install.py
```

**Step 2**: Run the deployment command

```bash
python3 ./easy-install.py deploy \
    --project=helpdesk_prod_setup \
    --email=your_email.example.com \
    --image=ghcr.io/frappe/helpdesk \
    --version=stable \
    --app=helpdesk \
    --sitename subdomain.domain.tld
```

Replace the following parameters with your values:
- `your_email.example.com`: Your email address
- `subdomain.domain.tld`: Your domain name where Helpdesk will be hosted

The script will set up a production-ready instance of Frappe Helpdesk with all the necessary configurations in about 5 minutes.

## Development Setup

### Docker

You need Docker, docker-compose and git setup on your machine. Refer [Docker documentation](https://docs.docker.com/). After that, follow below steps:

**Step 1**: Setup folder and download the required files

    mkdir frappe-helpdesk
    cd frappe-helpdesk

    # Download the docker-compose file
    wget -O docker-compose.yml https://raw.githubusercontent.com/frappe/helpdesk/develop/docker/docker-compose.yml

    # Download the setup script
    wget -O init.sh https://raw.githubusercontent.com/frappe/helpdesk/develop/docker/init.sh

**Step 2**: Run the container and daemonize it

    docker compose up -d

**Step 3**: The site [http://helpdesk.localhost:8000/helpdesk](http://helpdesk.localhost:8000/helpdesk) should now be available. The default credentials are:
- Username: Administrator
- Password: admin

### Local

To setup the repository locally follow the steps mentioned below:

1. Install bench and setup a `frappe-bench` directory by following the [Installation Steps](https://frappeframework.com/docs/user/en/installation)
1. Start the server by running `bench start`
1. In a separate terminal window, create a new site by running `bench new-site helpdesk.test`
1. Map your site to localhost with the command `bench --site helpdesk.test add-to-hosts`
1. Get the Helpdesk app. Run `bench get-app https://github.com/frappe/helpdesk`
1. Run `bench --site helpdesk.test install-app helpdesk`.
1. Now open the URL `http://helpdesk.test:8000/helpdesk` in your browser, you should see the app running


**For Frontend Development**
1. Open a new terminal session and cd into `frappe-bench/apps/helpdesk/desk`, and run the following commands:
    ```
    yarn install
    yarn dev or yarn dev --host helpdesk.test
    ```
1. Now, you can access the site on vite dev server at `http://helpdesk.test:8080`

**Note:** You'll find all the code related to Helpdesk's frontend inside `frappe-bench/apps/helpdesk/desk`

## Learn and connect

- [Telegram Public Group](https://t.me/frappedesk)
- [Discuss Forum](https://discuss.frappe.io/c/frappehelpdesk/69)
- [Documentation](https://docs.frappe.io/helpdesk)

<br>
<br>
<div align="center">
	<a href="https://frappe.io" target="_blank">
		<picture>
			<source media="(prefers-color-scheme: dark)" srcset="https://frappe.io/files/Frappe-white.png">
			<img src="https://frappe.io/files/Frappe-black.png" alt="Frappe Technologies" height="28"/>
		</picture>
	</a>
</div>


## /commitlint.config.js

```js path="/commitlint.config.js" 
module.exports = {
  parserPreset: "conventional-changelog-conventionalcommits",
  rules: {
    "subject-empty": [2, "never"],
    "type-case": [2, "always", "lower-case"],
    "type-empty": [2, "never"],
    "type-enum": [
      2,
      "always",
      [
        "build",
        "chore",
        "ci",
        "docs",
        "feat",
        "fix",
        "perf",
        "refactor",
        "revert",
        "style",
        "test",
      ],
    ],
  },
};

```

## /desk/.gitignore

```gitignore path="/desk/.gitignore" 
node_modules
.DS_Store
dist
dist-ssr
*.local
dev-dist

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
```

## /desk/index.html

```html path="/desk/index.html" 
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Helpdesk</title>
    <meta name="mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-title" content="Frappe Helpdesk" />
    <meta name="apple-mobile-web-app-status-bar-style" content="white" />

    <!-- PWA -->
    <link
      rel="icon"
      type="image/png"
      sizes="196x196"
      href="/assets/helpdesk/desk/manifest/apple-icon-180.png"
    />

    <link
      rel="mask-icon"
      href="/assets/helpdesk/desk/manifest/manifest-icon-192.maskable.png"
      color="#FFFFFF"
    />

    <link
      rel="apple-touch-icon"
      href="/assets/helpdesk/desk/manifest/apple-icon-180.png"
    />

    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2048-2732.jpg"
      media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2732-2048.jpg"
      media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1668-2388.jpg"
      media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2388-1668.jpg"
      media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1536-2048.jpg"
      media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2048-1536.jpg"
      media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1488-2266.jpg"
      media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2266-1488.jpg"
      media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1640-2360.jpg"
      media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2360-1640.jpg"
      media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1668-2224.jpg"
      media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2224-1668.jpg"
      media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1620-2160.jpg"
      media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2160-1620.jpg"
      media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1290-2796.jpg"
      media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2796-1290.jpg"
      media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1179-2556.jpg"
      media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2556-1179.jpg"
      media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1284-2778.jpg"
      media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2778-1284.jpg"
      media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1170-2532.jpg"
      media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2532-1170.jpg"
      media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1125-2436.jpg"
      media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2436-1125.jpg"
      media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1242-2688.jpg"
      media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2688-1242.jpg"
      media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-828-1792.jpg"
      media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1792-828.jpg"
      media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1242-2208.jpg"
      media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-2208-1242.jpg"
      media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-750-1334.jpg"
      media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1334-750.jpg"
      media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-640-1136.jpg"
      media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
    />
    <link
      rel="apple-touch-startup-image"
      href="/assets/helpdesk/desk/manifest/apple-splash-1136-640.jpg"
      media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
    />
  </head>
  <body>
    <div id="app"></div>
    <div id="modals"></div>
    <div id="popovers"></div>
    <script type="module" src="/src/main.js"></script>
    <script>
      window.favicon = "{{ favicon }}";

      document.querySelectorAll("link[rel='icon']").forEach((link) => {
        link.href = window.favicon;
      });
    </script>
  </body>
</html>

```

## /desk/lucide.ts

```ts path="/desk/lucide.ts" 
import * as LucideIcons from "lucide-static";

const icons = {};
for (const icon in LucideIcons) {
  let iconSvg = LucideIcons[icon];
  if (icon == "default") {
    continue;
  }

  // set stroke-width to 1.5
  if (iconSvg && iconSvg.includes("stroke-width")) {
    iconSvg = iconSvg.replace(/stroke-width="2"/g, 'stroke-width="1.5"');
  }
  icons[icon] = iconSvg;

  const dashKeys = camelToDash(icon);
  for (const dashKey of dashKeys) {
    if (dashKey !== icon) {
      icons[dashKey] = iconSvg;
    }
  }
}

export default icons;

function camelToDash(key) {
  // barChart2 -> bar-chart-2
  const withNumber = key.replace(/[A-Z0-9]/g, (m) => "-" + m.toLowerCase());
  // barChart2 -> bar-chart2
  const withoutNumber = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());

  if (withNumber !== withoutNumber) {
    // both are required because unplugin icon resolver doesn't put a dash before numbers
    return [withNumber, withoutNumber];
  }
  return [withNumber];
}

```

## /desk/package.json

```json path="/desk/package.json" 
{
  "name": "helpdesk-ui",
  "private": true,
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview"
  },
  "dependencies": {
    "@headlessui/vue": "^1.7.22",
    "@iconify-json/lucide": "^1.1.99",
    "@iconify-json/ph": "^1.1.5",
    "@iconify/tools": "^2.2.6",
    "@iconify/vue": "^4.1.1",
    "@tailwindcss/line-clamp": "^0.4.4",
    "@tailwindcss/typography": "^0.5.9",
    "@tiptap/core": "^2.2.4",
    "@vee-validate/zod": "^4.8.2",
    "@vueuse/core": "^10.0.2",
    "@vueuse/integrations": "^12.0.0",
    "autoprefixer": "^10.4.13",
    "dayjs": "^1.11.7",
    "echarts": "^5.4.1",
    "frappe-ui": "0.1.122",
    "lodash": "^4.17.21",
    "lucide-static": "^0.276.0",
    "mime": "^3.0.0",
    "pinia": "^2.0.33",
    "pluralize": "^8.0.0",
    "sanitize-html": "^2.10.0",
    "socket.io-client": "^4.7.2",
    "tailwindcss": "^3.2.7",
    "unplugin-icons": "^0.16.1",
    "unplugin-vue-components": "^0.25.2",
    "vee-validate": "^4.8.2",
    "vue": "^3.4.12",
    "vue-echarts": "^6.5.4",
    "vue-router": "^4.2.2",
    "vuedraggable": "^4.1.0",
    "gemoji": "^8.1.0",
    "zod": "^3.21.4",
    "@vitejs/plugin-vue": "^4.2.3"
  },
  "resolutions": {
    "cheerio": "1.0.0-rc.12"
  },
  "devDependencies": {
    "vite": "^4.4.9",
    "@vitejs/plugin-vue-jsx": "^3.0.1",
    "vite-plugin-pwa": "^0.20.5",
    "typescript": "^5.0.2",
    "prettier": "2.8.4"
  }
}

```

## /desk/postcss.config.js

```js path="/desk/postcss.config.js" 
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};

```

## /desk/public/article-2.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/article-2.png

## /desk/public/article.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/article.png

## /desk/public/desk.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/desk.png

## /desk/public/favicon.svg

```svg path="/desk/public/favicon.svg" 
<svg width="118" height="118" viewBox="0 0 118 118" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M93.9278 0H23.1013C10.3428 0 0 10.3428 0 23.1013V93.9278C0 106.686 10.3428 117.029 23.1013 117.029H93.9278C106.686 117.029 117.029 106.686 117.029 93.9278V23.1013C117.029 10.3428 106.686 0 93.9278 0Z" fill="#7D42FB"/>
<path d="M95.9759 50.8753V27.8265L21 27.8265V38.3271H85.5278V48.3027C81.3275 49.5103 78.2824 53.3955 78.2824 57.9632C78.2824 62.531 81.3275 66.3637 85.5278 67.5713V77.5468H31.5006V50.1403H21V88.0474H96.0284V64.9986L89.7805 60.5359V55.3906L96.0284 50.9278L95.9759 50.8753Z" fill="#EDF7FF"/>
</svg>

```

## /desk/public/manifest/apple-icon-180.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-icon-180.png

## /desk/public/manifest/apple-splash-1125-2436.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1125-2436.jpg

## /desk/public/manifest/apple-splash-1136-640.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1136-640.jpg

## /desk/public/manifest/apple-splash-1170-2532.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1170-2532.jpg

## /desk/public/manifest/apple-splash-1179-2556.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1179-2556.jpg

## /desk/public/manifest/apple-splash-1242-2208.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1242-2208.jpg

## /desk/public/manifest/apple-splash-1242-2688.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1242-2688.jpg

## /desk/public/manifest/apple-splash-1284-2778.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1284-2778.jpg

## /desk/public/manifest/apple-splash-1290-2796.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1290-2796.jpg

## /desk/public/manifest/apple-splash-1334-750.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1334-750.jpg

## /desk/public/manifest/apple-splash-1488-2266.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1488-2266.jpg

## /desk/public/manifest/apple-splash-1536-2048.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1536-2048.jpg

## /desk/public/manifest/apple-splash-1620-2160.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1620-2160.jpg

## /desk/public/manifest/apple-splash-1640-2360.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1640-2360.jpg

## /desk/public/manifest/apple-splash-1668-2224.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1668-2224.jpg

## /desk/public/manifest/apple-splash-1668-2388.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1668-2388.jpg

## /desk/public/manifest/apple-splash-1792-828.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-1792-828.jpg

## /desk/public/manifest/apple-splash-2048-1536.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2048-1536.jpg

## /desk/public/manifest/apple-splash-2048-2732.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2048-2732.jpg

## /desk/public/manifest/apple-splash-2160-1620.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2160-1620.jpg

## /desk/public/manifest/apple-splash-2208-1242.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2208-1242.jpg

## /desk/public/manifest/apple-splash-2224-1668.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2224-1668.jpg

## /desk/public/manifest/apple-splash-2266-1488.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2266-1488.jpg

## /desk/public/manifest/apple-splash-2360-1640.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2360-1640.jpg

## /desk/public/manifest/apple-splash-2388-1668.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2388-1668.jpg

## /desk/public/manifest/apple-splash-2436-1125.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2436-1125.jpg

## /desk/public/manifest/apple-splash-2532-1170.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2532-1170.jpg

## /desk/public/manifest/apple-splash-2556-1179.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2556-1179.jpg

## /desk/public/manifest/apple-splash-2688-1242.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2688-1242.jpg

## /desk/public/manifest/apple-splash-2732-2048.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2732-2048.jpg

## /desk/public/manifest/apple-splash-2778-1284.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2778-1284.jpg

## /desk/public/manifest/apple-splash-2796-1290.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-2796-1290.jpg

## /desk/public/manifest/apple-splash-640-1136.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-640-1136.jpg

## /desk/public/manifest/apple-splash-750-1334.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-750-1334.jpg

## /desk/public/manifest/apple-splash-828-1792.jpg

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/apple-splash-828-1792.jpg

## /desk/public/manifest/manifest-icon-192.maskable.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/manifest-icon-192.maskable.png

## /desk/public/manifest/manifest-icon-512.maskable.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/public/manifest/manifest-icon-512.maskable.png

## /desk/src/App.vue

```vue path="/desk/src/App.vue" 
<template>
  <RouterView class="antialiased" />
  <Toasts />
  <KeymapDialog />
  <Dialogs />
</template>

<script setup lang="ts">
import { onMounted, onUnmounted } from "vue";
import { Toasts } from "frappe-ui";
import { createToast } from "@/utils";
import { useConfigStore } from "@/stores/config";
import KeymapDialog from "@/pages/KeymapDialog.vue";
import { stopSession } from "@/telemetry";
import { Dialogs } from "@/components/dialogs";

useConfigStore();

onMounted(() => {
  window.addEventListener("online", () => {
    createToast({
      title: "You are now online",
      icon: "wifi",
      iconClasses: "stroke-green-600",
    });
  });

  window.addEventListener("offline", () => {
    createToast({
      title: "You are now offline",
      icon: "wifi-off",
      iconClasses: "stroke-red-600",
    });
  });
});

onUnmounted(() => {
  stopSession();
});
</script>

```

## /desk/src/assets/custom_icons/bullet.svg

```svg path="/desk/src/assets/custom_icons/bullet.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="16" height="16" rx="8" fill="#F9FAFA"/>
<rect x="1.27734" y="1.27759" width="13.4444" height="13.4444" rx="6.72222" fill="white" stroke="#DCE0E3"/>
<circle cx="8" cy="8" r="1.5" fill="#74808B" stroke="#74808B"/>
</svg>

```

## /desk/src/assets/custom_icons/check.svg

```svg path="/desk/src/assets/custom_icons/check.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.6668 8.00001C14.6668 11.6819 11.6821 14.6667 8.00016 14.6667C4.31826 14.6667 1.3335 11.6819 1.3335 8.00001C1.3335 4.31811 4.31826 1.33334 8.00016 1.33334C11.6821 1.33334 14.6668 4.31811 14.6668 8.00001ZM11.4848 5.58164C11.0943 5.19112 10.4611 5.19112 10.0706 5.58164L9.51506 6.1372L8.40395 7.24831L6.88883 8.76342L6.48483 8.35942L5.92928 7.80386C5.53875 7.41334 4.90559 7.41334 4.51506 7.80386C4.12454 8.19439 4.12454 8.82755 4.51506 9.21808L5.07062 9.77363L6.18173 10.8847C6.36926 11.0723 6.62362 11.1776 6.88883 11.1776C7.15405 11.1776 7.4084 11.0723 7.59594 10.8847L9.81816 8.66252L10.9293 7.55141L11.4848 6.99585C11.8754 6.60533 11.8754 5.97217 11.4848 5.58164Z" fill="#2490EF"/>
</svg>

```

## /desk/src/assets/custom_icons/chevron-down.svg

```svg path="/desk/src/assets/custom_icons/chevron-down.svg" 
<svg width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.73049 0H0.684451C0.175406 0 -0.0822696 0.618739 0.280066 0.978509L4.3189 5.83016C4.54471 6.05598 4.90064 6.05725 5.12646 5.83016L9.13481 0.978509C9.49588 0.617446 9.2394 0 8.73043 0H8.73049Z" fill="#C8CFD5"/>
</svg>

```

## /desk/src/assets/custom_icons/chevron-up.svg

```svg path="/desk/src/assets/custom_icons/chevron-up.svg" 
<svg width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.61989 6H0.573855C0.0648106 6 -0.192865 5.38126 0.169471 5.02149L4.20831 0.169836C4.43412 -0.0559751 4.79005 -0.0572481 5.01586 0.169836L9.02422 5.02149C9.38528 5.38255 9.1288 6 8.61983 6H8.61989Z" fill="#C8CFD5"/>
</svg>

```

## /desk/src/assets/custom_icons/circle_check.svg

```svg path="/desk/src/assets/custom_icons/circle_check.svg" 
<svg width="18" height="17" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 16.5C13.4183 16.5 17 12.9183 17 8.5C17 4.08172 13.4183 0.5 9 0.5C4.58172 0.5 1 4.08172 1 8.5C1 12.9183 4.58172 16.5 9 16.5Z" fill="#48BB74"/>
<path d="M5.6665 9.11357L7.6665 11.1136L12.3332 6.4469M17 8.5C17 12.9183 13.4183 16.5 9 16.5C4.58172 16.5 1 12.9183 1 8.5C1 4.08172 4.58172 0.5 9 0.5C13.4183 0.5 17 4.08172 17 8.5Z" stroke="white" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/comment.svg

```svg path="/desk/src/assets/custom_icons/comment.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.24127 2.66663H9.65506L11.701 2.66663C12.8056 2.66663 13.701 3.56206 13.701 4.66663V7.66075V8.94657C13.701 10.0511 12.8056 10.9466 11.701 10.9466H11.6263C11.3502 10.9466 11.1263 11.1704 11.1263 11.4466V12.2839C11.1263 12.7048 10.6382 12.9374 10.3114 12.6723L8.45917 11.1699C8.28102 11.0254 8.05861 10.9466 7.82923 10.9466H4.66654C3.56195 10.9466 2.66652 10.0511 2.66654 8.94654L2.66656 7.66075V4.66664C2.66656 3.56207 3.56199 2.66664 4.66656 2.66664L5.24127 2.66663Z" stroke="#38A160" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M5.24121 5.24133H10.3906" stroke="#38A160" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M5.24121 7.08044H8.18374" stroke="#38A160" stroke-miterlimit="10" stroke-linecap="round"/>
</svg>

```

## /desk/src/assets/custom_icons/corner_up_left.svg

```svg path="/desk/src/assets/custom_icons/corner_up_left.svg" 
<svg width="11" height="8" viewBox="0 0 11 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.9999 7.51503C10.9999 7.68835 10.9052 7.84845 10.7511 7.93505C10.5971 8.02165 10.4075 8.02165 10.2534 7.93505C10.0994 7.84845 10.0045 7.68834 10.0045 7.51503C10.003 6.35143 9.52785 5.23588 8.68346 4.41315C7.83907 3.59041 6.69417 3.12753 5.49998 3.12614H1.86175L3.44892 4.42778C3.55079 4.51038 3.61477 4.62913 3.62655 4.75773C3.63822 4.88644 3.59689 5.01429 3.51146 5.11312C3.42614 5.21184 3.30394 5.27344 3.17187 5.28405C3.03978 5.29477 2.90881 5.25363 2.80793 5.16984L0.177079 3.01171C0.0647672 2.91948 0 2.78373 0 2.64072C0 2.49761 0.0647644 2.36188 0.177079 2.26962L2.80782 0.111938L2.80793 0.112046C2.94402 0.00173586 3.13009 -0.0297653 3.29651 0.0293403C3.46282 0.088446 3.58446 0.229174 3.6158 0.399028C3.64724 0.568768 3.5837 0.742084 3.44894 0.854015L1.86235 2.15618H5.5C6.95808 2.1578 8.35587 2.72299 9.38707 3.72758C10.4181 4.73216 10.9982 6.0943 11 7.51507L10.9999 7.51503Z" fill="#74808B"/>
</svg>

```

## /desk/src/assets/custom_icons/customers.svg

```svg path="/desk/src/assets/custom_icons/customers.svg" 
<svg width="26" height="22" viewBox="0 0 26 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.9996 21H24.4438C24.9961 21 25.4438 20.5523 25.4438 20V16.1969C25.4436 15.9749 25.377 15.758 25.2524 15.5742C25.1279 15.3905 24.9511 15.2482 24.7449 15.1658L20.5874 13.4993C20.3815 13.417 20.205 13.2751 20.0805 13.0918C19.956 12.9085 19.8891 12.6921 19.8885 12.4704V11.4949C20.5624 11.1082 21.1225 10.5509 21.5126 9.87896C21.9027 9.20705 22.1089 8.44426 22.1106 7.66733V5.44522C22.1108 4.66501 21.9056 3.89851 21.5156 3.22276C21.1256 2.54701 20.5646 1.98584 19.8889 1.59566C19.2133 1.20548 18.4469 1.00004 17.6667 1C16.8864 0.999956 16.12 1.20531 15.4443 1.59541" stroke="#192734" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15.8559 16.2768L11.6984 14.6103C11.4925 14.528 11.316 14.3861 11.1915 14.2028C11.0669 14.0195 11.0001 13.8031 10.9995 13.5814V12.6059C11.6734 12.2192 12.2335 11.6619 12.6236 10.99C13.0137 10.318 13.2199 9.55526 13.2216 8.77833V6.55622C13.2216 5.37754 12.7534 4.24714 11.9199 3.41368C11.0865 2.58023 9.95607 2.112 8.77739 2.112C7.59871 2.112 6.4683 2.58023 5.63485 3.41368C4.8014 4.24714 4.33317 5.37754 4.33317 6.55622V8.77833C4.33486 9.55526 4.54113 10.318 4.9312 10.99C5.32128 11.6619 5.88142 12.2192 6.55528 12.6059V13.5814C6.55514 13.8034 6.48849 14.0203 6.36392 14.2041C6.23936 14.3879 6.06259 14.5301 5.85642 14.6125L1.69885 16.2791C1.49304 16.3613 1.31651 16.5032 1.19198 16.6865C1.06744 16.8699 1.00058 17.0863 1 17.3079V19.9999C1 20.5522 1.44772 20.9999 2 20.9999H15.5548C16.1071 20.9999 16.5548 20.5522 16.5548 19.9999V17.3079C16.5546 17.0859 16.488 16.869 16.3634 16.6852C16.2389 16.5015 16.0621 16.3592 15.8559 16.2768Z" stroke="#192734" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/dislike.svg

```svg path="/desk/src/assets/custom_icons/dislike.svg" 
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 24C5.37273 24 0 18.6273 0 12C0 5.37273 5.37273 0 12 0C18.6273 0 24 5.37273 24 12C24 18.6273 18.6273 24 12 24ZM12 1.09091C5.97273 1.09091 1.09091 5.97273 1.09091 12C1.09091 18.0273 5.97273 22.9091 12 22.9091C18.0273 22.9091 22.9091 18.0273 22.9091 12C22.9091 5.97273 18.0273 1.09091 12 1.09091ZM8.18191 8.18182C7.58191 8.18182 7.0911 8.67263 7.0911 9.27263C7.0911 9.87263 7.58191 10.3634 8.18191 10.3634C8.78191 10.3634 9.27273 9.87263 9.27273 9.27263C9.27273 8.67263 8.78191 8.18182 8.18191 8.18182ZM15.8183 8.18182C15.2183 8.18182 14.7275 8.67263 14.7275 9.27263C14.7275 9.87263 15.2183 10.3634 15.8183 10.3634C16.4183 10.3634 16.9091 9.87263 16.9091 9.27263C16.9093 8.67263 16.4183 8.18182 15.8183 8.18182ZM12.0002 13.6364C9.05474 13.6364 6.62747 15.7636 6.10929 18.5455H7.22752C7.71833 16.3636 9.68196 14.7274 12.0002 14.7274C14.3185 14.7274 16.2822 16.3638 16.773 18.5455H17.8912C17.373 15.7636 14.9457 13.6364 12.0003 13.6364H12.0002Z" fill="#A6B1B9"/>
</svg>

```

## /desk/src/assets/custom_icons/document.svg

```svg path="/desk/src/assets/custom_icons/document.svg" 
<svg width="15" height="17" viewBox="0 0 15 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.5 1H2.5C1.67157 1 1 1.67157 1 2.5V14.5C1 15.3284 1.67157 16 2.5 16H12.5C13.3284 16 14 15.3284 14 14.5V5.5L9.5 1Z" stroke="#A6B1B9" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 12.5H11" stroke="#A6B1B9" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 9.5H11" stroke="#A6B1B9" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 6.5H6" stroke="#A6B1B9" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/external_link.svg

```svg path="/desk/src/assets/custom_icons/external_link.svg" 
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.2504 13.0556V14.5001C16.2504 16.1569 14.9072 17.5001 13.2504 17.5001H5.917C4.26014 17.5001 2.91699 16.1569 2.91699 14.5001V7.16674C2.91699 5.50991 4.25988 4.16677 5.91671 4.16675C6.39175 4.16675 6.88395 4.16675 7.36149 4.16675" stroke="#505A62" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.25 2.5H17.0833V7.5" stroke="#505A62" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.25 8.33325L16.25 3.33325" stroke="#505A62" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/f-desk.svg

```svg path="/desk/src/assets/custom_icons/f-desk.svg" 
<svg width="70" height="17" viewBox="0 0 70 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 0H11.4921V2.9196H0V0ZM0 16.6V7.44866H10.73V10.3732H3.66813V16.6H0Z" fill="#2490EF"/>
<path d="M23.9024 16.3604H18.4921V0H24.0116C25.5966 0 26.9584 0.327521 28.0965 0.982575C29.24 1.63231 30.1183 2.56695 30.7315 3.78653C31.3447 5.0061 31.6514 6.46532 31.6514 8.1642C31.6514 9.8684 31.3422 11.3329 30.7237 12.5579C30.1104 13.7827 29.2243 14.7228 28.0653 15.3778C26.9116 16.0328 25.5239 16.3604 23.9024 16.3604ZM21.3843 13.796H23.7621C24.8743 13.796 25.802 13.5884 26.5452 13.1729C27.2884 12.7522 27.8471 12.1264 28.2213 11.2956C28.5955 10.4595 28.7825 9.41572 28.7825 8.1642C28.7825 6.91268 28.5955 5.87417 28.2213 5.04871C27.8471 4.2179 27.2935 3.59747 26.5608 3.1874C25.8331 2.77199 24.9288 2.56429 23.8479 2.56429H21.3843V13.796Z" fill="black"/>
<path d="M39.3561 16.6001C38.1555 16.6001 37.1187 16.3445 36.2456 15.8332C35.3777 15.3166 34.7099 14.587 34.242 13.6443C33.7743 12.6964 33.5405 11.5807 33.5405 10.2972C33.5405 9.03499 33.7743 7.92727 34.242 6.97398C34.715 6.01536 35.375 5.26977 36.2222 4.73721C37.0693 4.19932 38.0646 3.93037 39.2079 3.93037C39.946 3.93037 40.6424 4.05287 41.2973 4.29785C41.9572 4.5375 42.5394 4.9103 43.0435 5.41623C43.5528 5.92216 43.953 6.56657 44.2441 7.34943C44.5351 8.12697 44.6805 9.05363 44.6805 10.1294V11.0161H34.8657V9.06695H41.9755C41.9703 8.51308 41.8534 8.02047 41.6247 7.58909C41.396 7.15238 41.0764 6.80888 40.6658 6.55858C40.2605 6.30827 39.7875 6.18313 39.2469 6.18313C38.67 6.18313 38.1633 6.32691 37.7267 6.6145C37.2902 6.89675 36.9498 7.26956 36.7055 7.73288C36.4664 8.19088 36.3443 8.69415 36.3392 9.2427V10.9442C36.3392 11.6579 36.4664 12.2704 36.7211 12.7815C36.9758 13.2876 37.3317 13.6764 37.7892 13.9479C38.2464 14.2141 38.7817 14.3473 39.395 14.3473C39.8057 14.3473 40.1772 14.2887 40.5098 14.1716C40.8425 14.0491 41.1309 13.8707 41.3752 13.6363C41.6194 13.4021 41.804 13.1118 41.9288 12.7656L44.5637 13.0691C44.3974 13.7828 44.0803 14.406 43.6126 14.9385C43.15 15.4657 42.5576 15.8757 41.8351 16.1687C41.1127 16.4563 40.2864 16.6001 39.3561 16.6001Z" fill="black"/>
<path d="M56.3127 7.33345L53.7401 7.62104C53.6674 7.35476 53.5401 7.10445 53.3581 6.87013C53.1815 6.63581 52.9424 6.44674 52.6409 6.30295C52.3395 6.15916 51.9705 6.08725 51.534 6.08725C50.9467 6.08725 50.4529 6.21774 50.0528 6.4787C49.6578 6.73965 49.4628 7.07783 49.4681 7.49322C49.4628 7.85004 49.5902 8.14029 49.85 8.36397C50.1151 8.58765 50.5517 8.77138 51.1597 8.91517L53.2023 9.36253C54.3352 9.61283 55.1772 10.0096 55.7281 10.5528C56.2842 11.096 56.5648 11.807 56.57 12.6858C56.5648 13.4579 56.3439 14.1396 55.9073 14.7307C55.476 15.3166 54.8757 15.7745 54.1066 16.1048C53.3373 16.435 52.4538 16.6001 51.456 16.6001C49.9903 16.6001 48.8107 16.2858 47.9166 15.6574C47.0227 15.0237 46.4901 14.1423 46.3186 13.0133L49.0705 12.7416C49.1952 13.2955 49.4603 13.7135 49.8657 13.9958C50.2711 14.278 50.7986 14.4193 51.4482 14.4193C52.1187 14.4193 52.6565 14.278 53.0618 13.9958C53.4725 13.7135 53.6778 13.3648 53.6778 12.9494C53.6778 12.5979 53.5452 12.3076 53.2801 12.0785C53.0203 11.8496 52.615 11.6738 52.064 11.5514L50.0215 11.112C48.873 10.867 48.0232 10.4543 47.4724 9.87378C46.9214 9.28797 46.6486 8.5477 46.6539 7.653C46.6486 6.89675 46.8487 6.2417 47.2541 5.68784C47.6646 5.12864 48.2338 4.69727 48.9614 4.39371C49.6942 4.08482 50.5386 3.93037 51.495 3.93037C52.8982 3.93037 54.0026 4.2366 54.8081 4.84905C55.6189 5.4615 56.1205 6.28963 56.3127 7.33345Z" fill="black"/>
<path d="M61.25 12.5099L61.2423 9.01896H61.6944L65.9976 4.09008H69.2953L64.002 10.1294H63.4173L61.25 12.5099ZM58.6774 16.3604V0H61.4994V16.3604H58.6774ZM66.1925 16.3604L62.2947 10.7764L64.1968 8.73936L69.5681 16.3604H66.1925Z" fill="black"/>
</svg>

```

## /desk/src/assets/custom_icons/filter.svg

```svg path="/desk/src/assets/custom_icons/filter.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 4H14" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 8H12" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.5 12H9.5" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/folder.svg

```svg path="/desk/src/assets/custom_icons/folder.svg" 
<svg width="17" height="15" viewBox="0 0 17 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 2V12C1 13.1046 1.89543 14 3 14H14C15.1046 14 16 13.1046 16 12V4.5C16 3.94772 15.5523 3.5 15 3.5H8.71689C8.54915 3.5 8.39259 3.41589 8.29999 3.27602L6.94139 1.22398C6.84879 1.08411 6.69223 1 6.52448 1H2C1.44772 1 1 1.44772 1 2Z" stroke="#A6B1B9" stroke-miterlimit="10" stroke-linecap="square"/>
</svg>

```

## /desk/src/assets/custom_icons/knowledge-based.svg

```svg path="/desk/src/assets/custom_icons/knowledge-based.svg" 
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.2127 7.78706L18.0709 3.92887" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14.2127 14.2127L18.0709 18.0708" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.78726 14.2127L3.92908 18.0708" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.78726 7.78706L3.92908 3.92887" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 21C16.5228 21 21 16.5228 21 11C21 5.47715 16.5228 1 11 1C5.47715 1 1 5.47715 1 11C1 16.5228 5.47715 21 11 21Z" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 15.5454C13.5103 15.5454 15.5454 13.5103 15.5454 10.9999C15.5454 8.48952 13.5103 6.45445 11 6.45445C8.48958 6.45445 6.45451 8.48952 6.45451 10.9999C6.45451 13.5103 8.48958 15.5454 11 15.5454Z" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/like.svg

```svg path="/desk/src/assets/custom_icons/like.svg" 
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 24C5.37273 24 0 18.6273 0 12C0 5.37273 5.37273 0 12 0C18.6273 0 24 5.37273 24 12C24 18.6273 18.6273 24 12 24ZM12 1.09091C5.97273 1.09091 1.09091 5.97273 1.09091 12C1.09091 18.0273 5.97273 22.9091 12 22.9091C18.0273 22.9091 22.9091 18.0273 22.9091 12C22.9091 5.97273 18.0273 1.09091 12 1.09091ZM8.18191 8.18182C7.58191 8.18182 7.0911 8.67263 7.0911 9.27263C7.0911 9.87263 7.58191 10.3634 8.18191 10.3634C8.78191 10.3634 9.27273 9.87263 9.27273 9.27263C9.27273 8.67263 8.78191 8.18182 8.18191 8.18182ZM15.8183 8.18182C15.2183 8.18182 14.7275 8.67263 14.7275 9.27263C14.7275 9.87263 15.2183 10.3634 15.8183 10.3634C16.4183 10.3634 16.9091 9.87263 16.9091 9.27263C16.9093 8.67263 16.4183 8.18182 15.8183 8.18182ZM12.0002 18.5455C9.05474 18.5455 6.62747 16.4182 6.10929 13.6364H7.22752C7.71833 15.8182 9.68196 17.4544 12.0002 17.4544C14.3185 17.4544 16.2822 15.818 16.773 13.6364H17.8912C17.373 16.4182 14.9456 18.5455 12.0002 18.5455Z" fill="#A6B1B9"/>
</svg>

```

## /desk/src/assets/custom_icons/lock.svg

```svg path="/desk/src/assets/custom_icons/lock.svg" 
<svg width="13" height="14" viewBox="0 0 13 14" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path fill-rule="evenodd" clip-rule="evenodd" d="M6.8075 0.833507H6.75569C5.91253 0.825803 5.10072 1.15293 4.49845 1.74315C3.89557 2.33398 3.55202 3.14006 3.54337 3.98414L3.54334 3.98414V3.98927V4.2827H2.83325C1.72868 4.2827 0.833252 5.17813 0.833252 6.2827V11.1664C0.833252 12.271 1.72868 13.1664 2.83325 13.1664H10.6734C11.7779 13.1664 12.6734 12.271 12.6734 11.1664V6.2827C12.6734 5.17813 11.7779 4.2827 10.6734 4.2827H9.96327V4.04584C9.97097 3.20269 9.64384 2.39088 9.05362 1.78861C8.4628 1.18573 7.65671 0.842187 6.81263 0.833533V0.833507H6.8075ZM8.96327 4.2827V4.04347V4.03849L8.96329 4.03849C8.96905 3.45956 8.74464 2.90204 8.33941 2.48854C7.93475 2.07562 7.38285 1.84007 6.80481 1.83351H6.7533H6.74833V1.83348C6.1694 1.82772 5.61188 2.05213 5.19838 2.45736C4.78546 2.86203 4.54991 3.41392 4.54334 3.99196V4.2827H8.96327ZM2.83325 5.2827C2.28097 5.2827 1.83325 5.73042 1.83325 6.2827V11.1664C1.83325 11.7187 2.28097 12.1664 2.83325 12.1664H10.6734C11.2256 12.1664 11.6734 11.7187 11.6734 11.1664V6.2827C11.6734 5.73042 11.2256 5.2827 10.6734 5.2827H2.83325ZM6.75345 9.20273C7.01755 9.20273 7.23164 8.98864 7.23164 8.72454C7.23164 8.46044 7.01755 8.24634 6.75345 8.24634C6.48935 8.24634 6.27525 8.46044 6.27525 8.72454C6.27525 8.98864 6.48935 9.20273 6.75345 9.20273ZM8.23164 8.72454C8.23164 9.54092 7.56983 10.2027 6.75345 10.2027C5.93706 10.2027 5.27525 9.54092 5.27525 8.72454C5.27525 7.90815 5.93706 7.24634 6.75345 7.24634C7.56983 7.24634 8.23164 7.90815 8.23164 8.72454Z" fill="#74808B"/>
</svg>

```

## /desk/src/assets/custom_icons/log_out.svg

```svg path="/desk/src/assets/custom_icons/log_out.svg" 
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 10L4.89662 10.0054L7.79323 10.0107L9.24154 10.0134L10.9657 10.0147" stroke="#E24C4C" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.5 7L11.5 10L8.5 13" stroke="#E24C4C" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.12402 13C4.28136 15.6489 6.92448 17.5 9.99996 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 9.99996 2.5C6.92448 2.5 4.28136 4.35114 3.12402 7" stroke="#E24C4C" stroke-linecap="round"/>
</svg>

```

## /desk/src/assets/custom_icons/priority_high.svg

```svg path="/desk/src/assets/custom_icons/priority_high.svg" 
<svg width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="2" height="3" rx="1" transform="matrix(-1 0 0 1 2.5 6)" fill="#A6B1B9"/>
<rect width="2" height="6" rx="1" transform="matrix(-1 0 0 1 5.5 3)" fill="#A6B1B9"/>
<rect width="2" height="9" rx="1" transform="matrix(-1 0 0 1 8.5 0)" fill="#A6B1B9"/>
</svg>

```

## /desk/src/assets/custom_icons/priority_low.svg

```svg path="/desk/src/assets/custom_icons/priority_low.svg" 
<svg width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="2" height="3" rx="1" transform="matrix(-1 0 0 1 2.5 6)" fill="#A6B1B9"/>
<rect width="2" height="6" rx="1" transform="matrix(-1 0 0 1 5.5 3)" fill="#EBEEF0"/>
<rect width="2" height="9" rx="1" transform="matrix(-1 0 0 1 8.5 0)" fill="#EBEEF0"/>
</svg>

```

## /desk/src/assets/custom_icons/priority_medium.svg

```svg path="/desk/src/assets/custom_icons/priority_medium.svg" 
<svg width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="2" height="3" rx="1" transform="matrix(-1 0 0 1 2.5 6)" fill="#A6B1B9"/>
<rect width="2" height="6" rx="1" transform="matrix(-1 0 0 1 5.5 3)" fill="#A6B1B9"/>
<rect width="2" height="9" rx="1" transform="matrix(-1 0 0 1 8.5 0)" fill="#EBEEF0"/>
</svg>

```

## /desk/src/assets/custom_icons/priority_urgent.svg

```svg path="/desk/src/assets/custom_icons/priority_urgent.svg" 
<svg width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="2" height="6" rx="1" transform="matrix(-1 0 0 1 5.5 0)" fill="#E24C4C"/>
<rect width="2" height="2" rx="1" transform="matrix(-1 0 0 1 5.5 7)" fill="#E24C4C"/>
</svg>

```

## /desk/src/assets/custom_icons/reports.svg

```svg path="/desk/src/assets/custom_icons/reports.svg" 
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.0001 1H15.3334C14.7811 1 14.3334 1.44772 14.3334 2V20.9998H20.0001C20.5523 20.9998 21.0001 20.552 21.0001 19.9998V2C21.0001 1.44772 20.5523 1 20.0001 1Z" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M13.3333 6.71417H8.66661C8.11432 6.71417 7.66661 7.16189 7.66661 7.71417V20.9997H14.3333V7.71417C14.3333 7.16189 13.8856 6.71417 13.3333 6.71417Z" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M6.66667 12.6667H2C1.44772 12.6667 1 13.1144 1 13.6667V19.9999C1 20.5522 1.44771 20.9999 2 20.9999H7.66667V13.6667C7.66667 13.1144 7.21895 12.6667 6.66667 12.6667Z" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="square"/>
</svg>

```

## /desk/src/assets/custom_icons/select.svg

```svg path="/desk/src/assets/custom_icons/select.svg" 
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.5 3.63636L6.13636 2L7.77273 3.63636M4.5 8.36364L6.13636 10L7.77273 8.36364" stroke="#404040" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/settings.svg

```svg path="/desk/src/assets/custom_icons/settings.svg" 
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.9996 16.2729C14.8071 16.2729 16.2724 14.8076 16.2724 13.0001C16.2724 11.1927 14.8071 9.72742 12.9996 9.72742C11.1922 9.72742 9.7269 11.1927 9.7269 13.0001C9.7269 14.8076 11.1922 16.2729 12.9996 16.2729Z" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M21.0727 16.2727C20.9275 16.6018 20.8842 16.9668 20.9484 17.3206C21.0125 17.6745 21.1812 18.0011 21.4327 18.2582L21.4982 18.3236C21.701 18.5263 21.862 18.7669 21.9718 19.0318C22.0816 19.2966 22.1381 19.5805 22.1381 19.8673C22.1381 20.154 22.0816 20.4379 21.9718 20.7028C21.862 20.9676 21.701 21.2083 21.4982 21.4109C21.2956 21.6138 21.0549 21.7747 20.7901 21.8845C20.5252 21.9943 20.2413 22.0508 19.9545 22.0508C19.6678 22.0508 19.3839 21.9943 19.119 21.8845C18.8542 21.7747 18.6135 21.6138 18.4109 21.4109L18.3455 21.3455C18.0884 21.094 17.7618 20.9253 17.4079 20.8611C17.054 20.7969 16.689 20.8402 16.36 20.9855C16.0373 21.1237 15.7622 21.3534 15.5683 21.646C15.3745 21.9387 15.2705 22.2817 15.2691 22.6327V22.8182C15.2691 23.3968 15.0392 23.9518 14.6301 24.361C14.2209 24.7701 13.6659 25 13.0873 25C12.5086 25 11.9537 24.7701 11.5445 24.361C11.1353 23.9518 10.9055 23.3968 10.9055 22.8182V22.72C10.897 22.3589 10.7801 22.0087 10.57 21.7149C10.3599 21.4212 10.0663 21.1974 9.72727 21.0727C9.39824 20.9275 9.03324 20.8842 8.67936 20.9484C8.32547 21.0125 7.99892 21.1812 7.74182 21.4327L7.67636 21.4982C7.47373 21.701 7.2331 21.862 6.96823 21.9718C6.70336 22.0816 6.41945 22.1381 6.13273 22.1381C5.846 22.1381 5.56209 22.0816 5.29722 21.9718C5.03235 21.862 4.79172 21.701 4.58909 21.4982C4.38623 21.2956 4.2253 21.0549 4.11551 20.7901C4.00571 20.5252 3.94919 20.2413 3.94919 19.9545C3.94919 19.6678 4.00571 19.3839 4.11551 19.119C4.2253 18.8542 4.38623 18.6135 4.58909 18.4109L4.65455 18.3455C4.90604 18.0884 5.07475 17.7618 5.13891 17.4079C5.20308 17.054 5.15976 16.689 5.01455 16.36C4.87626 16.0373 4.64664 15.7622 4.35396 15.5683C4.06128 15.3745 3.71831 15.2705 3.36727 15.2691H3.18182C2.60316 15.2691 2.04821 15.0392 1.63904 14.6301C1.22987 14.2209 1 13.6659 1 13.0873C1 12.5086 1.22987 11.9537 1.63904 11.5445C2.04821 11.1353 2.60316 10.9055 3.18182 10.9055H3.28C3.64108 10.897 3.99128 10.7801 4.28505 10.57C4.57883 10.3599 4.8026 10.0663 4.92727 9.72727C5.07249 9.39824 5.11581 9.03324 5.05164 8.67936C4.98748 8.32547 4.81877 7.99892 4.56727 7.74182L4.50182 7.67636C4.29896 7.47373 4.13803 7.2331 4.02823 6.96823C3.91843 6.70336 3.86192 6.41945 3.86192 6.13273C3.86192 5.846 3.91843 5.56209 4.02823 5.29722C4.13803 5.03235 4.29896 4.79172 4.50182 4.58909C4.70445 4.38623 4.94508 4.2253 5.20995 4.11551C5.47482 4.00571 5.75873 3.94919 6.04545 3.94919C6.33218 3.94919 6.61609 4.00571 6.88096 4.11551C7.14583 4.2253 7.38646 4.38623 7.58909 4.58909L7.65455 4.65455C7.91165 4.90604 8.2382 5.07475 8.59209 5.13891C8.94597 5.20308 9.31096 5.15976 9.64 5.01455H9.72727C10.0499 4.87626 10.3251 4.64664 10.5189 4.35396C10.7128 4.06128 10.8168 3.71831 10.8182 3.36727V3.18182C10.8182 2.60316 11.0481 2.04821 11.4572 1.63904C11.8664 1.22987 12.4213 1 13 1C13.5787 1 14.1336 1.22987 14.5428 1.63904C14.9519 2.04821 15.1818 2.60316 15.1818 3.18182V3.28C15.1832 3.63104 15.2872 3.97401 15.4811 4.26669C15.6749 4.55937 15.9501 4.78899 16.2727 4.92727C16.6018 5.07249 16.9668 5.11581 17.3206 5.05164C17.6745 4.98748 18.0011 4.81877 18.2582 4.56727L18.3236 4.50182C18.5263 4.29896 18.7669 4.13803 19.0318 4.02823C19.2966 3.91843 19.5805 3.86192 19.8673 3.86192C20.154 3.86192 20.4379 3.91843 20.7028 4.02823C20.9676 4.13803 21.2083 4.29896 21.4109 4.50182C21.6138 4.70445 21.7747 4.94508 21.8845 5.20995C21.9943 5.47482 22.0508 5.75873 22.0508 6.04545C22.0508 6.33218 21.9943 6.61609 21.8845 6.88096C21.7747 7.14583 21.6138 7.38646 21.4109 7.58909L21.3455 7.65455C21.094 7.91165 20.9253 8.2382 20.8611 8.59209C20.7969 8.94597 20.8402 9.31096 20.9855 9.64V9.72727C21.1237 10.0499 21.3534 10.3251 21.646 10.5189C21.9387 10.7128 22.2817 10.8168 22.6327 10.8182H22.8182C23.3968 10.8182 23.9518 11.0481 24.361 11.4572C24.7701 11.8664 25 12.4213 25 13C25 13.5787 24.7701 14.1336 24.361 14.5428C23.9518 14.9519 23.3968 15.1818 22.8182 15.1818H22.72C22.369 15.1832 22.026 15.2872 21.7333 15.4811C21.4406 15.6749 21.211 15.9501 21.0727 16.2727V16.2727Z" stroke="#192734" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/sla-fail.svg

```svg path="/desk/src/assets/custom_icons/sla-fail.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.00016 14.6666C11.6821 14.6666 14.6668 11.6819 14.6668 7.99998C14.6668 4.31808 11.6821 1.33331 8.00016 1.33331C4.31826 1.33331 1.3335 4.31808 1.3335 7.99998C1.3335 11.6819 4.31826 14.6666 8.00016 14.6666ZM5.30317 5.30298C5.59606 5.01009 6.07094 5.01009 6.36383 5.30298L8.00092 6.94008L9.63799 5.30302C9.93088 5.01012 10.4058 5.01012 10.6986 5.30302C10.9915 5.59591 10.9915 6.07078 10.6986 6.36368L9.06159 8.00074L10.6986 9.6378C10.9915 9.93069 10.9915 10.4056 10.6986 10.6985C10.4058 10.9914 9.93088 10.9914 9.63799 10.6985L8.00093 9.0614L6.36383 10.6985C6.07094 10.9914 5.59606 10.9914 5.30317 10.6985C5.01028 10.4056 5.01027 9.93073 5.30317 9.63784L6.94026 8.00074L5.30317 6.36364C5.01028 6.07075 5.01028 5.59588 5.30317 5.30298Z" fill="#F56B6B"/>
</svg>

```

## /desk/src/assets/custom_icons/sort-ascending.svg

```svg path="/desk/src/assets/custom_icons/sort-ascending.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.75 3.25H10.75" stroke="#505A62" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.75 7.25H7.75" stroke="#505A62" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.75 11.25H5.75" stroke="#505A62" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14.25 7.75L12.25 5.75L10.25 7.75" stroke="#505A62" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.25 11.75L12.25 5.75" stroke="#505A62" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Bold.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Bold.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.11552 8.48467V11.1533H8.63755C9.89361 11.1533 10.5216 10.7085 10.5216 9.81896C10.5216 8.92944 9.89361 8.48467 8.63755 8.48467H7.11552ZM7.11552 4.6092V6.87548H8.24195C8.85881 6.87548 9.2991 6.7682 9.56283 6.55364C9.82656 6.33461 9.95843 6.06865 9.95843 5.75575C9.95843 5.43838 9.82433 5.16794 9.55613 4.94444C9.2924 4.72094 8.85434 4.6092 8.24195 4.6092H7.11552ZM5.31858 3H8.24195C8.65766 3 9.03761 3.03129 9.3818 3.09387C9.72599 3.15645 10.0165 3.23914 10.2534 3.34195C10.4904 3.44029 10.7004 3.56322 10.8837 3.71073C11.067 3.85377 11.2123 4.00128 11.3195 4.15326C11.4268 4.30077 11.514 4.46392 11.581 4.64272C11.6481 4.81705 11.6928 4.9802 11.7151 5.13218C11.742 5.27969 11.7554 5.43167 11.7554 5.58812C11.7554 6.07535 11.6257 6.47094 11.3665 6.7749C11.1117 7.07439 10.7742 7.28895 10.354 7.41858C10.7831 7.52139 11.1519 7.72031 11.4603 8.01533C11.7732 8.31034 11.9945 8.6143 12.1241 8.9272C12.2538 9.2401 12.3186 9.53736 12.3186 9.81896C12.3186 10.0559 12.294 10.2928 12.2448 10.5297C12.2001 10.7621 12.1018 11.0192 11.9498 11.3008C11.7978 11.5779 11.6011 11.8215 11.3598 12.0316C11.1184 12.2372 10.7787 12.4116 10.3406 12.5546C9.90702 12.6932 9.40638 12.7625 8.8387 12.7625H5.31858V3Z" fill="#1F272E"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Bullet list.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Bullet list.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.1514 3H14.8186" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.1514 7.80005H14.8186" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.1514 12.6001H14.8186" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2.81857 3H2.82457" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2.81857 7.80005H2.82457" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2.81857 12.6001H2.82457" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Clear Formatting.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Clear Formatting.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.48459 4.6665H13.8179" stroke="#1F272E" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.98459 12.1665L10.7763 4.6665" stroke="#1F272E" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.81857 3L13.8186 13" stroke="#FBFBFB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.65256 4.6665L12.9859 12.9998" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Code.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Code.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.8176 3L6.8176 13.4" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5.21857 5.3999L2.81857 7.7999L5.21857 10.1999" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.4184 5.3999L14.8184 7.7999L12.4184 10.1999" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Decrease Indent.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Decrease Indent.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.01877 7.8999H14.1388" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.01877 3H14.0188" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.01877 12.7998H14.0188" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.31857 6.25392L6.31857 9.54589C6.31857 9.88502 5.92303 10.0703 5.6625 9.85317L3.68732 8.20719C3.49542 8.04727 3.49542 7.75253 3.68732 7.59261L5.6625 5.94663C5.92303 5.72952 6.31857 5.91478 6.31857 6.25392Z" fill="#1F272E"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Image-add.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Image-add.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.14357 14.1333C7.67325 14.1333 5.74817 14.1333 4.31751 14.1333C3.21294 14.1333 2.31857 13.2379 2.31857 12.1333V4C2.31857 2.89543 3.214 2 4.31857 2H13.3186C14.4231 2 15.3186 2.89543 15.3186 4V8.37" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M7.27946 6.07369C7.27946 6.37193 7.0377 6.61369 6.73946 6.61369C6.44123 6.61369 6.19946 6.37193 6.19946 6.07369C6.19946 5.77546 6.44123 5.53369 6.73946 5.53369C7.0377 5.53369 7.27946 5.77546 7.27946 6.07369Z" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M5.43875 11.2735L7.51875 8.67353L9.59875 10.2335L12.1988 7.11353" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Increase Indent.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Increase Indent.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.01877 7.8999H14.1386" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.01877 3H14.0188" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.01877 12.7998H14.0188" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.31857 9.54589L3.31857 6.25392C3.31857 5.91478 3.71412 5.72952 3.97465 5.94663L5.94983 7.59261C6.14173 7.75253 6.14173 8.04727 5.94983 8.20719L3.97465 9.85317C3.71412 10.0703 3.31857 9.88502 3.31857 9.54589Z" fill="#1F272E"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Italic.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Italic.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3327_18536)">
<path d="M6.31858 12.2963L6.49099 11.4465H7.63631L9.00331 4.54995H7.85799L8.0304 3.7002H11.3186L11.1462 4.54995H10.0008L8.63385 11.4465H9.77917L9.60676 12.2963H6.31858Z" fill="#1F272E"/>
</g>
<defs>
<clipPath id="clip0_3327_18536">
<rect width="16" height="16" fill="white" transform="translate(0.818581)"/>
</clipPath>
</defs>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Left Align.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Left Align.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.81857 3.2002H13.8186" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.81857 8.00024H13.8186" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.81857 12.8003H9.81857" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Link-url.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Link-url.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.09201 10.7268L11.5463 5.27246" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.72766 4.72735L9.55158 2.90344C10.1303 2.32496 10.915 2 11.7333 2C12.5515 2 13.3363 2.32496 13.915 2.90344V2.90344C14.4935 3.48215 14.8185 4.2669 14.8185 5.08516C14.8185 5.90341 14.4935 6.68817 13.915 7.26687L12.0911 9.09079" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5.54593 6.90918L3.72201 8.7331C3.14354 9.31181 2.81857 10.0966 2.81857 10.9148C2.81857 11.7331 3.14354 12.5178 3.72201 13.0965V13.0965C4.30072 13.675 5.08548 14 5.90373 14C6.72198 14 7.50674 13.675 8.08545 13.0965L9.90937 11.2726" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Numbered List.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Numbered List.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.73553 3.41895H14.8186" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.7355 7.89551H14.8186" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.7355 12.3721H14.8186" stroke="#1F272E" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.69943 4.7998V2.61035H3.68576L2.98068 3.08691V2.46973L3.69748 1.98145H4.41232V4.7998H3.69943Z" fill="#1F272E"/>
<path d="M2.83419 7.34863C2.83419 7.06999 2.9351 6.84408 3.13692 6.6709C3.33874 6.49772 3.60372 6.41113 3.93184 6.41113C4.24955 6.41113 4.50476 6.48861 4.69747 6.64355C4.89148 6.7985 4.98848 7.00033 4.98848 7.24902C4.98848 7.31934 4.97742 7.3903 4.95528 7.46191C4.93315 7.53223 4.9071 7.59473 4.87716 7.64941C4.84721 7.7028 4.80619 7.76139 4.75411 7.8252C4.70333 7.8877 4.65971 7.93783 4.62325 7.97559C4.58679 8.01204 4.53926 8.05827 4.48067 8.11426L3.80684 8.73535V8.74902H5.02364V9.2998H2.8752V8.82129L3.97481 7.80957C4.0933 7.69629 4.17598 7.60059 4.22286 7.52246C4.27104 7.44303 4.29512 7.3597 4.29512 7.27246C4.29512 7.18132 4.25932 7.10514 4.1877 7.04395C4.11609 6.98145 4.02299 6.9502 3.90841 6.9502C3.78731 6.9502 3.68705 6.98796 3.60762 7.06348C3.5295 7.1377 3.49044 7.23275 3.49044 7.34863V7.3623H2.83419V7.34863Z" fill="#1F272E"/>
<path d="M3.56661 12.6064V12.1123H3.90841C4.0295 12.1123 4.1265 12.0817 4.19942 12.0205C4.27234 11.958 4.3088 11.876 4.3088 11.7744C4.3088 11.6715 4.27299 11.5908 4.20137 11.5322C4.12976 11.4736 4.03015 11.4443 3.90255 11.4443C3.78015 11.4443 3.68054 11.4782 3.60372 11.5459C3.5269 11.6136 3.48653 11.7021 3.48262 11.8115H2.83419C2.8394 11.5394 2.94226 11.3213 3.14278 11.1572C3.3433 10.9932 3.60697 10.9111 3.9338 10.9111C4.2476 10.9111 4.4989 10.9808 4.6877 11.1201C4.87781 11.2594 4.97286 11.445 4.97286 11.6768C4.97286 11.8447 4.91882 11.9873 4.81075 12.1045C4.70268 12.2217 4.5614 12.2959 4.38692 12.3271V12.3428C4.59786 12.3623 4.76518 12.432 4.88887 12.5518C5.01387 12.6715 5.07637 12.8271 5.07637 13.0186C5.07637 13.2764 4.96895 13.4827 4.75411 13.6377C4.54057 13.7926 4.25801 13.8701 3.90645 13.8701C3.57703 13.8701 3.3101 13.7874 3.10567 13.6221C2.90255 13.4567 2.79382 13.2367 2.7795 12.9619H3.46309C3.4696 13.0687 3.51322 13.1533 3.59395 13.2158C3.67468 13.277 3.78275 13.3076 3.91817 13.3076C4.04578 13.3076 4.14929 13.2757 4.22872 13.2119C4.30945 13.1468 4.34981 13.0622 4.34981 12.958C4.34981 12.8486 4.31075 12.7627 4.23262 12.7002C4.1545 12.6377 4.04708 12.6064 3.91036 12.6064H3.56661Z" fill="#1F272E"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Quote.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Quote.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.25573 3.3121L4.33894 3.3121C4.0513 3.3121 3.81809 3.54507 3.81809 3.83296L3.81809 7.79145C3.81809 8.07909 4.0513 8.31231 4.33894 8.31231L6.71987 8.31231C6.60797 10.2065 5.86305 11.4145 4.45232 11.9977C4.18655 12.1078 4.06015 12.4123 4.17002 12.6783C4.28039 12.944 4.58558 13.0699 4.85059 12.9606C6.79209 12.1577 7.77658 10.4186 7.77658 7.79145L7.77658 3.83296C7.77658 3.54507 7.54337 3.3121 7.25573 3.3121ZM13.2977 3.31211L10.3809 3.3121C10.0933 3.3121 9.86008 3.54507 9.86008 3.83296L9.86008 7.79145C9.86008 8.0791 10.0933 8.31231 10.3809 8.31231L12.7619 8.31231C12.65 10.2065 11.905 11.4145 10.4943 11.9977C10.2285 12.1078 10.1021 12.4123 10.212 12.6783C10.3224 12.944 10.6268 13.0699 10.8926 12.9606C12.8341 12.1577 13.8186 10.4186 13.8186 7.79145L13.8186 3.83296C13.8186 3.54507 13.5854 3.31211 13.2977 3.31211Z" fill="#1F272E"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Text Color.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Text Color.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.97781 4.15745L7.95202 7.12282H9.99771L8.97781 4.15745ZM9.8857 2.2002L12.969 10.7838H11.1355L10.3337 8.53181C10.3337 8.53181 9.4239 8.53181 7.6042 8.53181L6.80243 10.7838H4.96897L8.05224 2.2002H9.8857Z" fill="#1F272E"/>
<path d="M2.81858 13.5C2.81858 13.2239 3.04244 13 3.31858 13H14.3186C14.5947 13 14.8186 13.2239 14.8186 13.5V13.5C14.8186 13.7761 14.5947 14 14.3186 14H3.31858C3.04244 14 2.81858 13.7761 2.81858 13.5V13.5Z" fill="#73C42F"/>
</svg>

```

## /desk/src/assets/custom_icons/text_editor_icons/Underline.svg

```svg path="/desk/src/assets/custom_icons/text_editor_icons/Underline.svg" 
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3327_18531)">
<path d="M6.84135 2.2998V7.6767C6.84135 8.26692 7.01448 8.74106 7.36074 9.09913C7.71094 9.45326 8.19688 9.63033 8.81858 9.63033C9.44028 9.63033 9.92623 9.45326 10.2764 9.09913C10.6266 8.74106 10.8017 8.26692 10.8017 7.6767V2.2998H12.3186V7.81245C12.3186 8.75287 12.0018 9.51228 11.3683 10.0907C10.7388 10.6691 9.88884 10.9583 8.81858 10.9583C7.75225 10.9583 6.90234 10.6691 6.26883 10.0907C5.63533 9.51228 5.31858 8.75287 5.31858 7.81245V2.2998H6.84135Z" fill="#1F272E"/>
<path d="M2.81858 13.5C2.81858 13.2239 3.04244 13 3.31858 13H14.3186C14.5947 13 14.8186 13.2239 14.8186 13.5C14.8186 13.7761 14.5947 14 14.3186 14H3.31858C3.04244 14 2.81858 13.7761 2.81858 13.5Z" fill="#1F272E"/>
</g>
<defs>
<clipPath id="clip0_3327_18531">
<rect width="16" height="16" fill="white" transform="translate(0.818581)"/>
</clipPath>
</defs>
</svg>

```

## /desk/src/assets/custom_icons/ticket.svg

```svg path="/desk/src/assets/custom_icons/ticket.svg" 
<svg width="24" height="23" viewBox="0 0 24 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.18726 14.4773L3.42761 16.7176L3.60012 16.5451C4.55459 15.5907 6.09432 15.59 7.048 16.5437C8.00181 17.4975 8.00118 19.037 7.04658 19.9916L6.87407 20.1641L9.11442 22.4045L23.2566 8.26232L21.0162 6.02197L20.8437 6.19449C19.8891 7.14908 18.3496 7.14971 17.3958 6.19591C16.4421 5.24222 16.4428 3.7025 17.3972 2.74803L17.5697 2.57551L15.3294 0.33516L1.18726 14.4773ZM1.87677 14.477L11.0174 5.33636L18.255 12.5739L9.11433 21.7146L7.52573 20.126C8.48919 18.9774 8.47138 17.2773 7.39267 16.1986C6.31374 15.1196 4.60856 15.0958 3.45999 16.0602L1.87677 14.477ZM11.3623 4.99143L15.329 1.02474L16.9122 2.60792C15.9479 3.75638 15.9716 5.46168 17.0506 6.5406C18.1293 7.61931 19.8294 7.63714 20.978 6.67367L22.5666 8.26227L18.5999 12.229L11.3623 4.99143Z" fill="#1F272E" stroke="#1F272E" stroke-width="0.4"/>
</svg>

```

## /desk/src/assets/custom_icons/time.svg

```svg path="/desk/src/assets/custom_icons/time.svg" 
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.00034 5.0118C9.00034 4.73566 8.77648 4.5118 8.50034 4.5118C8.2242 4.5118 8.00034 4.73566 8.00034 5.0118H9.00034ZM8.50034 8.50017H8.00034C8.00034 8.63277 8.05301 8.75995 8.14678 8.85371L8.50034 8.50017ZM10.6464 11.3535C10.8417 11.5488 11.1583 11.5488 11.3535 11.3535C11.5488 11.1583 11.5488 10.8417 11.3536 10.6464L10.6464 11.3535ZM15.5 8.5C15.5 12.366 12.366 15.5 8.5 15.5V16.5C12.9183 16.5 16.5 12.9183 16.5 8.5H15.5ZM8.5 15.5C4.63401 15.5 1.5 12.366 1.5 8.5H0.5C0.5 12.9183 4.08172 16.5 8.5 16.5V15.5ZM1.5 8.5C1.5 4.63401 4.63401 1.5 8.5 1.5V0.5C4.08172 0.5 0.5 4.08172 0.5 8.5H1.5ZM8.5 1.5C12.366 1.5 15.5 4.63401 15.5 8.5H16.5C16.5 4.08172 12.9183 0.5 8.5 0.5V1.5ZM8.00034 5.0118V8.50017H9.00034V5.0118H8.00034ZM8.14678 8.85371L10.6464 11.3535L11.3536 10.6464L8.8539 8.14663L8.14678 8.85371Z" fill="#A6B1B9"/>
</svg>

```

## /desk/src/assets/custom_icons/user-plus.svg

```svg path="/desk/src/assets/custom_icons/user-plus.svg" 
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.25 8.375H5C4.00544 8.375 3.05161 8.77009 2.34835 9.47335C1.64509 10.1766 1.25 11.1304 1.25 12.125H8" stroke="#74808B" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.125 6.125C7.57475 6.125 8.75 4.94975 8.75 3.5C8.75 2.05025 7.57475 0.875 6.125 0.875C4.67525 0.875 3.5 2.05025 3.5 3.5C3.5 4.94975 4.67525 6.125 6.125 6.125Z" stroke="#74808B" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.25 8.375V11.375" stroke="#74808B" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.75 9.875H11.75" stroke="#74808B" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

```

## /desk/src/assets/icons/activity.svg

```svg path="/desk/src/assets/icons/activity.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_630_47683)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 0.75C4.27614 0.75 4.5 0.973858 4.5 1.25V2.25H5.5C5.77614 2.25 6 2.47386 6 2.75C6 3.02614 5.77614 3.25 5.5 3.25H4.5V4.25C4.5 4.52614 4.27614 4.75 4 4.75C3.72386 4.75 3.5 4.52614 3.5 4.25V3.25H2.5C2.22386 3.25 2 3.02614 2 2.75C2 2.47386 2.22386 2.25 2.5 2.25H3.5V1.25C3.5 0.973858 3.72386 0.75 4 0.75ZM8.74972 2.33683C9.00744 1.64034 9.99255 1.64034 10.2503 2.33683L11.1107 4.66221C11.364 5.34651 11.9035 5.88604 12.5878 6.13925L14.9132 6.99972C15.6097 7.25744 15.6097 8.24255 14.9132 8.50028L12.5878 9.36075C11.9035 9.61396 11.364 10.1535 11.1107 10.8378L10.2503 13.1632C9.99256 13.8597 9.00745 13.8597 8.74972 13.1632L7.88925 10.8378C7.63604 10.1535 7.09651 9.61396 6.41221 9.36075L4.08683 8.50028C3.39034 8.24256 3.39034 7.25745 4.08683 6.99972L6.41221 6.13925C7.09651 5.88604 7.63604 5.34651 7.88925 4.66221L8.74972 2.33683ZM9.5 3.19077L8.8271 5.00925C8.4726 5.96727 7.71727 6.7226 6.75925 7.0771L4.94077 7.75L6.75925 8.4229C7.71727 8.7774 8.4726 9.53273 8.8271 10.4908L9.5 12.3092L10.1729 10.4908C10.5274 9.53273 11.2827 8.7774 12.2408 8.4229L14.0592 7.75L12.2408 7.0771C11.2827 6.7226 10.5274 5.96727 10.1729 5.00925L9.5 3.19077ZM3.5 10.75C3.5 10.4739 3.27614 10.25 3 10.25C2.72386 10.25 2.5 10.4739 2.5 10.75V12.25H1C0.723858 12.25 0.5 12.4739 0.5 12.75C0.5 13.0261 0.723858 13.25 1 13.25H2.5V14.75C2.5 15.0261 2.72386 15.25 3 15.25C3.27614 15.25 3.5 15.0261 3.5 14.75V13.25H5C5.27614 13.25 5.5 13.0261 5.5 12.75C5.5 12.4739 5.27614 12.25 5 12.25H3.5V10.75Z" fill="#171717"/>
</g>
<defs>
<clipPath id="clip0_630_47683">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

```

## /desk/src/assets/icons/add.svg

```svg path="/desk/src/assets/icons/add.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.5 2.5C8.5 2.22386 8.27614 2 8 2C7.72386 2 7.5 2.22386 7.5 2.5V7.5H2.5C2.22386 7.5 2 7.72386 2 8C2 8.27614 2.22386 8.5 2.5 8.5H7.5V13.5C7.5 13.7761 7.72386 14 8 14C8.27614 14 8.5 13.7761 8.5 13.5V8.5H13.5C13.7761 8.5 14 8.27614 14 8C14 7.72386 13.7761 7.5 13.5 7.5H8.5V2.5Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/alert-circle.svg

```svg path="/desk/src/assets/icons/alert-circle.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14ZM8 15C11.866 15 15 11.866 15 8C15 4.13401 11.866 1 8 1C4.13401 1 1 4.13401 1 8C1 11.866 4.13401 15 8 15ZM8 5.75C8.48325 5.75 8.875 5.35825 8.875 4.875C8.875 4.39175 8.48325 4 8 4C7.51675 4 7.125 4.39175 7.125 4.875C7.125 5.35825 7.51675 5.75 8 5.75ZM8.5 7.43555C8.5 7.1594 8.27614 6.93555 8 6.93555C7.72386 6.93555 7.5 7.1594 7.5 7.43555V11.143C7.5 11.4191 7.72386 11.643 8 11.643C8.27614 11.643 8.5 11.4191 8.5 11.143V7.43555Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/at-sign.svg

```svg path="/desk/src/assets/icons/at-sign.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.00915 1.67113C6.43756 0.996093 8.0523 0.824124 9.59083 1.18318L9.47719 1.67009L9.59083 1.18318C11.1294 1.54222 12.5012 2.41118 13.4833 3.64873L13.4833 3.64875C14.4653 4.8863 14.9999 6.41969 15 7.99959V7.99961V8.64961C15 9.29937 14.7419 9.92256 14.2824 10.382C13.8229 10.8415 13.1998 11.0996 12.55 11.0996C11.9002 11.0996 11.2771 10.8415 10.8176 10.382C10.6732 10.2376 10.5487 10.077 10.4458 9.90455C9.87852 10.6319 8.99387 11.0996 8.00001 11.0996C6.28792 11.0996 4.90001 9.71167 4.90001 7.99961C4.90001 6.28752 6.28792 4.8996 8.00001 4.8996C8.81015 4.8996 9.54773 5.21039 10.1 5.71924V5.3996C10.1 5.12346 10.3239 4.8996 10.6 4.8996C10.8761 4.8996 11.1 5.12346 11.1 5.3996V7.99961V8.64961C11.1 9.03414 11.2528 9.40298 11.5247 9.67491C11.7966 9.94684 12.1654 10.0996 12.55 10.0996C12.9345 10.0996 13.3034 9.94684 13.5753 9.67491C13.8472 9.40298 14 9.03414 14 8.64961V7.99964C14 7.99963 14 7.99962 14 7.99961C13.9999 6.64545 13.5417 5.33113 12.7 4.27036C11.8582 3.20959 10.6823 2.46476 9.36356 2.15701L9.477 1.67093L9.36356 2.15701C8.04482 1.84925 6.66077 1.99665 5.43641 2.57525L5.24134 2.16246L5.43641 2.57525C4.21207 3.15384 3.21944 4.12961 2.61996 5.34387C2.02048 6.55813 1.84939 7.93946 2.13451 9.26331C2.41962 10.5871 3.14418 11.7756 4.19038 12.6354C5.23657 13.4952 6.54286 13.9758 7.89687 13.9991C9.25083 14.0224 10.5729 13.587 11.648 12.7636C11.8673 12.5958 12.1811 12.6374 12.349 12.8566C12.5169 13.0759 12.4752 13.3897 12.256 13.5576C11.0017 14.5181 9.45929 15.0261 7.87968 14.999C6.30002 14.9718 4.77601 14.4111 3.55545 13.408L3.55543 13.408C2.33489 12.4048 1.48956 11.0183 1.15692 9.47385C0.824284 7.92937 1.02389 6.31782 1.72329 4.90118L2.16883 5.12114L1.72329 4.90117C2.42268 3.48454 3.58074 2.34615 5.00915 1.67113ZM10.1 7.99961C10.1 6.83981 9.15978 5.8996 8.00001 5.8996C6.84021 5.8996 5.90001 6.8398 5.90001 7.99961C5.90001 9.15939 6.84021 10.0996 8.00001 10.0996C9.15978 10.0996 10.1 9.15939 10.1 7.99961Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/attachment.svg

```svg path="/desk/src/assets/icons/attachment.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5684 2.50774C11.5403 1.49742 9.95026 1.49742 8.92215 2.50774L3.62404 7.71417C2.12532 9.18695 2.12532 11.669 3.62404 13.1418C5.12762 14.6194 7.66861 14.6194 9.17219 13.1418L12.1609 10.2049C12.3578 10.0113 12.6744 10.0141 12.8679 10.211C13.0615 10.408 13.0587 10.7246 12.8618 10.9181L9.8731 13.8551C7.98045 15.715 4.81578 15.715 2.92313 13.8551C1.02562 11.9904 1.02562 8.86558 2.92313 7.00091L8.22124 1.79449C9.63842 0.401838 11.8521 0.401838 13.2693 1.79449C14.6914 3.19191 14.6914 5.38225 13.2693 6.77968L13.2668 6.78213L13.2668 6.78212L8.37876 11.5189C8.37834 11.5193 8.37793 11.5197 8.37752 11.5201C7.51767 12.3638 6.11144 12.3939 5.29119 11.5097C4.43611 10.6596 4.40778 9.26893 5.30922 8.46081L7.33823 6.46692C7.53518 6.27337 7.85175 6.27613 8.04531 6.47309C8.23886 6.67005 8.23609 6.98662 8.03913 7.18017L6.0014 9.18264L5.99203 9.19185L5.98219 9.20055C5.5391 9.59243 5.5104 10.3231 6.0014 10.8056L6.01078 10.8148L6.01967 10.8245C6.42299 11.2649 7.18224 11.2926 7.67785 10.8056L7.68034 10.8032L7.68035 10.8032L12.5684 6.06643C12.5688 6.06604 12.5692 6.06565 12.5696 6.06526C13.5917 5.05969 13.5913 3.51289 12.5684 2.50774Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/call.svg

```svg path="/desk/src/assets/icons/call.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.95285 2.54013C3.92327 2.49299 3.85726 2.48621 3.81872 2.52636L2.78495 3.60321C2.49506 3.90517 2.42141 4.33187 2.58844 4.68366C2.84601 5.22612 3.21996 5.95835 3.69649 6.74891L5.43393 5.02622C5.46235 4.99804 5.46743 4.95393 5.44616 4.92004L3.95285 2.54013ZM4.24582 7.61247L6.13802 5.73633C6.49871 5.37871 6.56318 4.81878 6.29322 4.38854L4.79991 2.00863C4.42446 1.41026 3.58655 1.32423 3.09734 1.83383L2.06356 2.91068C1.5064 3.49105 1.32751 4.35947 1.68509 5.11258C2.28411 6.37416 3.52561 8.7043 5.26657 10.4746C7.06249 12.3007 9.57172 13.7019 10.8504 14.3515C11.543 14.7033 12.3555 14.5979 12.952 14.1386L14.0769 13.2726C14.655 12.8276 14.6383 11.9504 14.0437 11.5278L11.6815 9.8484C11.2788 9.56215 10.7337 9.58388 10.3551 9.90126L8.26207 11.6559C7.46625 11.1043 6.66377 10.4691 5.97956 9.77337C5.32734 9.11017 4.74593 8.35658 4.24582 7.61247ZM9.13302 12.2307C9.9712 12.7581 10.7475 13.1776 11.3033 13.4599C11.6309 13.6264 12.0318 13.5851 12.342 13.3463L13.4669 12.4802C13.5124 12.4452 13.5111 12.3761 13.4643 12.3428L11.102 10.6634C11.0703 10.6409 11.0274 10.6426 10.9975 10.6676L9.13302 12.2307Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/chat.svg

```svg path="/desk/src/assets/icons/chat.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.95666 10.9519L3.43743 11.0892C3.47703 10.9506 3.45487 10.8016 3.37664 10.6805L2.95666 10.9519ZM2 14.3002L1.51924 14.1628C1.46737 14.3444 1.52219 14.5397 1.66095 14.6677C1.79972 14.7957 1.99878 14.8347 2.17556 14.7684L2 14.3002ZM5.30327 13.0615L5.5283 12.615C5.40365 12.5521 5.25841 12.5443 5.12771 12.5933L5.30327 13.0615ZM13.5 7.7002C13.5 10.7378 11.0376 13.2002 8 13.2002V14.2002C11.5899 14.2002 14.5 11.29 14.5 7.7002H13.5ZM8 2.2002C11.0376 2.2002 13.5 4.66263 13.5 7.7002H14.5C14.5 4.11034 11.5899 1.2002 8 1.2002V2.2002ZM2.5 7.7002C2.5 4.66263 4.96243 2.2002 8 2.2002V1.2002C4.41015 1.2002 1.5 4.11034 1.5 7.7002H2.5ZM3.37664 10.6805C2.82199 9.82205 2.5 8.79949 2.5 7.7002H1.5C1.5 8.99774 1.88071 10.2079 2.53669 11.2232L3.37664 10.6805ZM2.48076 14.4376L3.43743 11.0892L2.4759 10.8145L1.51924 14.1628L2.48076 14.4376ZM5.12771 12.5933L1.82444 13.832L2.17556 14.7684L5.47883 13.5296L5.12771 12.5933ZM8 13.2002C7.11006 13.2002 6.27085 12.9892 5.5283 12.615L5.07824 13.508C5.9572 13.951 6.95021 14.2002 8 14.2002V13.2002Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/comment.svg

```svg path="/desk/src/assets/icons/comment.svg" 
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.48339 10.5033L3.725 10.0655L3.725 10.0655L3.48339 10.5033ZM3.70226 10.8602L3.20373 10.8219L3.70226 10.8602ZM3.5 11.8125L3.02825 11.6468H3.02825L3.5 11.8125ZM3.14499 12.5597L3.57196 12.8199H3.57196L3.14499 12.5597ZM3.21409 12.7015L3.19921 13.2012H3.19921L3.21409 12.7015ZM4.8125 12.25L5.04604 12.6921H5.04604L4.8125 12.25ZM5.98677 11.4115L5.71069 10.9947L5.71069 10.9947L5.98677 11.4115ZM6.28665 11.3427L6.33203 10.8448H6.33203L6.28665 11.3427ZM7 11.875C10.5398 11.875 13.625 9.60213 13.625 6.5625H12.625C12.625 8.83861 10.2256 10.875 7 10.875V11.875ZM13.625 6.5625C13.625 3.52287 10.5398 1.25 7 1.25V2.25C10.2256 2.25 12.625 4.28639 12.625 6.5625H13.625ZM7 1.25C3.46016 1.25 0.375 3.52287 0.375 6.5625H1.375C1.375 4.28639 3.77435 2.25 7 2.25V1.25ZM0.375 6.5625C0.375 8.41929 1.5487 10.0066 3.24179 10.941L3.725 10.0655C2.26322 9.25874 1.375 7.96506 1.375 6.5625H0.375ZM3.24179 10.941C3.24812 10.9445 3.23994 10.9422 3.2281 10.9239C3.21398 10.9021 3.20041 10.865 3.20373 10.8219L4.20079 10.8985C4.23213 10.4906 3.97247 10.2021 3.725 10.0655L3.24179 10.941ZM3.20373 10.8219C3.18688 11.0411 3.12193 11.3801 3.02825 11.6468L3.97175 11.9782C4.09585 11.6248 4.17763 11.1999 4.20079 10.8985L3.20373 10.8219ZM3.02825 11.6468C2.92756 11.9335 2.79729 12.1694 2.71802 12.2995L3.57196 12.8199C3.67422 12.652 3.84069 12.3513 3.97175 11.9782L3.02825 11.6468ZM2.71802 12.2995C2.6129 12.472 2.60075 12.6846 2.68624 12.866C2.7754 13.0552 2.96583 13.1943 3.19921 13.2012L3.22896 12.2017C3.3904 12.2065 3.52755 12.3055 3.59079 12.4396C3.65035 12.566 3.63962 12.7088 3.57196 12.8199L2.71802 12.2995ZM3.19921 13.2012C3.53773 13.2113 4.18431 13.1473 5.04604 12.6921L4.57896 11.8079C3.87271 12.181 3.39768 12.2067 3.22896 12.2017L3.19921 13.2012ZM5.04604 12.6921C5.31374 12.5507 5.54397 12.3793 5.74029 12.2259C5.9483 12.0632 6.10116 11.9355 6.26285 11.8284L5.71069 10.9947C5.5055 11.1306 5.29829 11.3021 5.12442 11.438C4.93886 11.5831 4.7654 11.7094 4.57896 11.8079L5.04604 12.6921ZM6.26285 11.8284C6.25092 11.8363 6.24122 11.8392 6.23713 11.8401C6.2335 11.8409 6.23483 11.8401 6.24127 11.8406L6.33203 10.8448C6.13692 10.827 5.91139 10.8617 5.71069 10.9947L6.26285 11.8284ZM6.24127 11.8406C6.49038 11.8633 6.74356 11.875 7 11.875V10.875C6.77385 10.875 6.55095 10.8647 6.33203 10.8448L6.24127 11.8406Z" fill="#7C7C7C"/>
</svg>

```

## /desk/src/assets/icons/contact-solid.svg

```svg path="/desk/src/assets/icons/contact-solid.svg" 
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8373 5.9446C11.9769 5.9446 12.9007 5.0208 12.9007 3.88123C12.9007 2.74167 11.9769 1.81787 10.8373 1.81787C9.69773 1.81787 8.77393 2.74167 8.77393 3.88123C8.77393 5.0208 9.69773 5.9446 10.8373 5.9446ZM8.16495 7.22954C8.56659 7.07566 9.00077 6.99219 9.45043 6.99219H11.7067C13.3917 6.99219 14.8506 8.16249 15.2161 9.80736L15.2907 10.1431C15.5749 11.4218 14.6019 12.6348 13.292 12.6348H11.095C10.8243 12.6348 10.6027 12.4193 10.5952 12.1487C10.5838 11.7419 10.4269 10.6986 9.92263 9.90624C9.69003 9.54073 9.30361 9.19906 8.88236 8.91632C8.46472 8.636 8.05122 8.4391 7.80609 8.34962C7.62303 8.28279 7.49547 8.11569 7.47927 7.92148C7.46308 7.72727 7.5612 7.54135 7.73068 7.44513L7.76298 7.42674L7.76299 7.42673C7.88009 7.35998 7.99407 7.29501 8.16495 7.22954ZM4.29281 8.53955C2.60781 8.53955 1.1489 9.70985 0.78337 11.3547L0.708768 11.6904C0.424612 12.9691 1.39764 14.1821 2.70753 14.1821H8.13434C9.44424 14.1821 10.4173 12.9691 10.1331 11.6904L10.0585 11.3547C9.69298 9.70985 8.23406 8.53955 6.54906 8.53955H4.29281ZM5.42089 7.49218C6.7029 7.49218 7.74218 6.4529 7.74218 5.17089C7.74218 3.88888 6.7029 2.84961 5.42089 2.84961C4.13888 2.84961 3.09961 3.88888 3.09961 5.17089C3.09961 6.4529 4.13888 7.49218 5.42089 7.49218Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/contact.svg

```svg path="/desk/src/assets/icons/contact.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9013 3.88123C11.9013 4.46851 11.4252 4.9446 10.8379 4.9446C10.2507 4.9446 9.77457 4.46851 9.77457 3.88123C9.77457 3.29396 10.2507 2.81787 10.8379 2.81787C11.4252 2.81787 11.9013 3.29396 11.9013 3.88123ZM12.9013 3.88123C12.9013 5.0208 11.9775 5.9446 10.8379 5.9446C9.69837 5.9446 8.77457 5.0208 8.77457 3.88123C8.77457 2.74167 9.69837 1.81787 10.8379 1.81787C11.9775 1.81787 12.9013 2.74167 12.9013 3.88123ZM9.45131 6.99212C9.00165 6.99212 8.56746 7.0756 8.16583 7.22947C7.99675 7.29425 7.83353 7.37147 7.67737 7.46013L8.17111 8.32974C8.28387 8.26572 8.40167 8.21 8.52359 8.16328C8.81294 8.05243 9.12597 7.99212 9.45131 7.99212H11.7076C12.9239 7.99212 13.977 8.83689 14.2408 10.0242L14.3154 10.3599C14.4608 11.0141 13.963 11.6347 13.2928 11.6347H11.9361H11.0959V12.6347H11.9361H13.2928C14.6027 12.6347 15.5758 11.4217 15.2916 10.143L15.217 9.80729C14.8515 8.16242 13.3926 6.99212 11.7076 6.99212H9.45131ZM4.29329 9.53964C3.077 9.53964 2.0239 10.3844 1.76004 11.5717L1.68544 11.9075C1.54007 12.5616 2.03787 13.1822 2.70802 13.1822H8.13483C8.80498 13.1822 9.30278 12.5616 9.1574 11.9075L9.0828 11.5717C8.81895 10.3844 7.76585 9.53964 6.54955 9.53964H4.29329ZM0.783858 11.3548C1.14938 9.70995 2.6083 8.53964 4.29329 8.53964H6.54955C8.23455 8.53964 9.69346 9.70995 10.059 11.3548L10.1336 11.6905C10.4177 12.9692 9.44472 14.1822 8.13483 14.1822H2.70802C1.39812 14.1822 0.4251 12.9692 0.709257 11.6905L0.783858 11.3548ZM6.74289 5.17084C6.74289 5.90056 6.15133 6.49212 5.4216 6.49212C4.69188 6.49212 4.10032 5.90056 4.10032 5.17084C4.10032 4.44111 4.69188 3.84955 5.4216 3.84955C6.15133 3.84955 6.74289 4.44111 6.74289 5.17084ZM7.74289 5.17084C7.74289 6.45285 6.70361 7.49212 5.4216 7.49212C4.13959 7.49212 3.10032 6.45285 3.10032 5.17084C3.10032 3.88883 4.13959 2.84955 5.4216 2.84955C6.70361 2.84955 7.74289 3.88883 7.74289 5.17084Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/customer-solid.svg

```svg path="/desk/src/assets/icons/customer-solid.svg" 
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 8C1 4.13401 4.13401 1 8 1C11.866 1 15 4.13401 15 8C15 9.87217 14.265 11.5727 13.0679 12.8287L13.0726 12.838L12.8336 13.0633C11.6514 14.1921 10.0745 14.9112 8.33096 14.9923C8.2212 14.9974 8.11078 15 7.99976 15C7.61309 15 7.23371 14.9686 6.86403 14.9083C5.45701 14.6786 4.19059 14.0294 3.19839 13.0938L2.92627 12.8373L2.93112 12.8277C1.73456 11.5717 1 9.87165 1 8ZM12.5508 11.9104C11.5617 10.4562 9.89278 9.50002 7.99995 9.5L7.9958 9.50003C5.63018 9.51967 4.18081 10.8515 3.4501 11.9115C2.54631 10.8611 2 9.49437 2 8C2 4.68629 4.68629 2 8 2C11.3137 2 14 4.68629 14 8C14 9.49386 13.4541 10.8602 12.5508 11.9104ZM8 4C6.61929 4 5.5 5.11929 5.5 6.5C5.5 7.88071 6.61929 9 8 9C9.38071 9 10.5 7.88071 10.5 6.5C10.5 5.11929 9.38071 4 8 4Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/customer.svg

```svg path="/desk/src/assets/icons/customer.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 8C1 4.13401 4.13401 1 8 1C11.866 1 15 4.13401 15 8C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8ZM8 2C4.68629 2 2 4.68629 2 8C2 9.49445 2.54637 10.8613 3.45026 11.9117C4.18198 10.85 5.63088 9.51962 7.99595 9.49999L8.0001 9.49996C9.89288 9.49997 11.5617 10.4561 12.5509 11.9103C13.4541 10.8601 14 9.49381 14 8C14 4.68629 11.3137 2 8 2ZM11.823 12.6246C11.0285 11.3488 9.61399 10.5007 8.00216 10.5C5.9479 10.5178 4.73721 11.7367 4.17659 12.6242C5.21474 13.4836 6.54706 14 8 14C9.45275 14 10.7849 13.4837 11.823 12.6246ZM8 5C7.17157 5 6.5 5.67157 6.5 6.5C6.5 7.32843 7.17157 8 8 8C8.82843 8 9.5 7.32843 9.5 6.5C9.5 5.67157 8.82843 5 8 5ZM5.5 6.5C5.5 5.11929 6.61929 4 8 4C9.38071 4 10.5 5.11929 10.5 6.5C10.5 7.88071 9.38071 9 8 9C6.61929 9 5.5 7.88071 5.5 6.5Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/dashboard-solid.svg

```svg path="/desk/src/assets/icons/dashboard-solid.svg" 
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 3.25C2.5 2.42157 3.17157 1.75 4 1.75H6C6.82843 1.75 7.5 2.42157 7.5 3.25V5.25C7.5 6.07843 6.82843 6.75 6 6.75H4C3.17157 6.75 2.5 6.07843 2.5 5.25V3.25ZM8.5 11.25C8.5 10.4216 9.17157 9.75 10 9.75H12C12.8284 9.75 13.5 10.4216 13.5 11.25V13.25C13.5 14.0784 12.8284 14.75 12 14.75H10C9.17157 14.75 8.5 14.0784 8.5 13.25V11.25ZM10 1.75C9.17157 1.75 8.5 2.42157 8.5 3.25V7.25C8.5 8.07843 9.17157 8.75 10 8.75H12C12.8284 8.75 13.5 8.07843 13.5 7.25V3.25C13.5 2.42157 12.8284 1.75 12 1.75H10ZM2.5 9.25C2.5 8.42157 3.17157 7.75 4 7.75H6C6.82843 7.75 7.5 8.42157 7.5 9.25V13.25C7.5 14.0784 6.82843 14.75 6 14.75H4C3.17157 14.75 2.5 14.0784 2.5 13.25V9.25Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/dashboard.svg

```svg path="/desk/src/assets/icons/dashboard.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 1C2.17157 1 1.5 1.67157 1.5 2.5V4.5C1.5 5.32843 2.17157 6 3 6H6C6.82843 6 7.5 5.32843 7.5 4.5V2.5C7.5 1.67157 6.82843 1 6 1H3ZM2.5 2.5C2.5 2.22386 2.72386 2 3 2H6C6.27614 2 6.5 2.22386 6.5 2.5V4.5C6.5 4.77614 6.27614 5 6 5H3C2.72386 5 2.5 4.77614 2.5 4.5V2.5ZM10 10C9.17157 10 8.5 10.6716 8.5 11.5V13.5C8.5 14.3284 9.17157 15 10 15H13C13.8284 15 14.5 14.3284 14.5 13.5V11.5C14.5 10.6716 13.8284 10 13 10H10ZM9.5 11.5C9.5 11.2239 9.72386 11 10 11H13C13.2761 11 13.5 11.2239 13.5 11.5V13.5C13.5 13.7761 13.2761 14 13 14H10C9.72386 14 9.5 13.7761 9.5 13.5V11.5ZM8.5 2.5C8.5 1.67157 9.17157 1 10 1H13C13.8284 1 14.5 1.67157 14.5 2.5V7.5C14.5 8.32843 13.8284 9 13 9H10C9.17157 9 8.5 8.32843 8.5 7.5V2.5ZM10 2C9.72386 2 9.5 2.22386 9.5 2.5V7.5C9.5 7.77614 9.72386 8 10 8H13C13.2761 8 13.5 7.77614 13.5 7.5V2.5C13.5 2.22386 13.2761 2 13 2H10ZM3 7C2.17157 7 1.5 7.67157 1.5 8.5V13.5C1.5 14.3284 2.17157 15 3 15H6C6.82843 15 7.5 14.3284 7.5 13.5V8.5C7.5 7.67157 6.82843 7 6 7H3ZM2.5 8.5C2.5 8.22386 2.72386 8 3 8H6C6.27614 8 6.5 8.22386 6.5 8.5V13.5C6.5 13.7761 6.27614 14 6 14H3C2.72386 14 2.5 13.7761 2.5 13.5V8.5Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/delete.svg

```svg path="/desk/src/assets/icons/delete.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_b_5_8105)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.67578 2.31152H5.76953V2.08204C5.76953 1.25362 6.4411 0.582044 7.26953 0.582044H8.72849C9.55692 0.582044 10.2285 1.25362 10.2285 2.08204V2.31152H12.3232H12.8232V2.31974H14.0536C14.3298 2.31974 14.5536 2.5436 14.5536 2.81974C14.5536 3.09589 14.3298 3.31974 14.0536 3.31974H12.8232V12.9179C12.8232 14.2986 11.7039 15.4179 10.3232 15.4179H5.67578C4.29507 15.4179 3.17578 14.2986 3.17578 12.9179V3.31974H1.94727C1.67112 3.31974 1.44727 3.09589 1.44727 2.81974C1.44727 2.5436 1.67112 2.31974 1.94727 2.31974H3.17578V2.31152H3.67578ZM4.17578 3.31974V12.9179C4.17578 13.7463 4.84735 14.4179 5.67578 14.4179H10.3232C11.1516 14.4179 11.8232 13.7463 11.8232 12.9179V3.31974H4.17578ZM9.22849 2.31152H6.76953V2.08204C6.76953 1.8059 6.99339 1.58204 7.26953 1.58204H8.72849C9.00463 1.58204 9.22849 1.8059 9.22849 2.08204V2.31152ZM6.48633 5.77051C6.76247 5.77051 6.98633 5.99437 6.98633 6.27051V11.4589C6.98633 11.7351 6.76247 11.9589 6.48633 11.9589C6.21019 11.9589 5.98633 11.7351 5.98633 11.4589V6.27051C5.98633 5.99437 6.21019 5.77051 6.48633 5.77051ZM10.0137 6.27047C10.0137 5.99433 9.78988 5.77047 9.51374 5.77047C9.23759 5.77047 9.01374 5.99433 9.01374 6.27047V11.4589C9.01374 11.735 9.23759 11.9589 9.51374 11.9589C9.78988 11.9589 10.0137 11.735 10.0137 11.4589V6.27047Z" fill="#171717"/>
</g>
<defs>
<filter id="filter0_b_5_8105" x="-4" y="-4" width="24" height="24" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feGaussianBlur in="BackgroundImageFix" stdDeviation="2"/>
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_5_8105"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_5_8105" result="shape"/>
</filter>
</defs>
</svg>

```

## /desk/src/assets/icons/details.svg

```svg path="/desk/src/assets/icons/details.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5 2.5H3.5C2.94772 2.5 2.5 2.94772 2.5 3.5V12.5C2.5 13.0523 2.94772 13.5 3.5 13.5H12.5C13.0523 13.5 13.5 13.0523 13.5 12.5V3.5C13.5 2.94772 13.0523 2.5 12.5 2.5ZM3.5 1.5C2.39543 1.5 1.5 2.39543 1.5 3.5V12.5C1.5 13.6046 2.39543 14.5 3.5 14.5H12.5C13.6046 14.5 14.5 13.6046 14.5 12.5V3.5C14.5 2.39543 13.6046 1.5 12.5 1.5H3.5ZM5.5 8C5.5 8.34518 5.22018 8.625 4.875 8.625C4.52982 8.625 4.25 8.34518 4.25 8C4.25 7.65482 4.52982 7.375 4.875 7.375C5.22018 7.375 5.5 7.65482 5.5 8ZM4.875 5.625C5.22018 5.625 5.5 5.34518 5.5 5C5.5 4.65482 5.22018 4.375 4.875 4.375C4.52982 4.375 4.25 4.65482 4.25 5C4.25 5.34518 4.52982 5.625 4.875 5.625ZM5.5 11C5.5 11.3452 5.22018 11.625 4.875 11.625C4.52982 11.625 4.25 11.3452 4.25 11C4.25 10.6548 4.52982 10.375 4.875 10.375C5.22018 10.375 5.5 10.6548 5.5 11ZM6.75 4.5C6.47386 4.5 6.25 4.72386 6.25 5C6.25 5.27614 6.47386 5.5 6.75 5.5H11.75C12.0261 5.5 12.25 5.27614 12.25 5C12.25 4.72386 12.0261 4.5 11.75 4.5H6.75ZM6.25 8C6.25 7.72386 6.47386 7.5 6.75 7.5H11.75C12.0261 7.5 12.25 7.72386 12.25 8C12.25 8.27614 12.0261 8.5 11.75 8.5H6.75C6.47386 8.5 6.25 8.27614 6.25 8ZM6.75 10.5C6.47386 10.5 6.25 10.7239 6.25 11C6.25 11.2761 6.47386 11.5 6.75 11.5H11.75C12.0261 11.5 12.25 11.2761 12.25 11C12.25 10.7239 12.0261 10.5 11.75 10.5H6.75Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/dot-horizontal.svg

```svg path="/desk/src/assets/icons/dot-horizontal.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 8C4.5 8.82843 3.82843 9.5 3 9.5C2.17157 9.5 1.5 8.82843 1.5 8C1.5 7.17157 2.17157 6.5 3 6.5C3.82843 6.5 4.5 7.17157 4.5 8ZM8 9.5C8.82843 9.5 9.5 8.82843 9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5ZM13 9.5C13.8284 9.5 14.5 8.82843 14.5 8C14.5 7.17157 13.8284 6.5 13 6.5C12.1716 6.5 11.5 7.17157 11.5 8C11.5 8.82843 12.1716 9.5 13 9.5Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/email.svg

```svg path="/desk/src/assets/icons/email.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 2C2.11929 2 1 3.11929 1 4.5V5.48845C0.999827 5.49602 0.999828 5.50357 1 5.51111V11.5C1 12.8807 2.11929 14 3.5 14H12.5C13.8807 14 15 12.8807 15 11.5V5.51111C15.0002 5.50357 15.0002 5.49602 15 5.48845V4.5C15 3.11929 13.8807 2 12.5 2H3.5ZM14 5.16863V4.5C14 3.67157 13.3284 3 12.5 3H3.5C2.67157 3 2 3.67157 2 4.5V5.16863L7.80518 7.62467C7.92972 7.67736 8.07028 7.67736 8.19482 7.62467L14 5.16863ZM2 6.25445V11.5C2 12.3284 2.67157 13 3.5 13H12.5C13.3284 13 14 12.3284 14 11.5V6.25445L8.58446 8.54564C8.21085 8.7037 7.78915 8.7037 7.41554 8.54564L2 6.25445Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/file.svg

```svg path="/desk/src/assets/icons/file.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.92578 1.81129C3.3735 1.81129 2.92578 2.259 2.92578 2.81129V13.1885C2.92578 13.7408 3.3735 14.1885 3.92578 14.1885H12.0734C12.6258 14.1885 13.0734 13.7408 13.0734 13.1886V13.1697V13.1508V13.132V13.1131V13.0942V13.0753V13.0564V13.0375V13.0185V12.9996V12.9807V12.9618V12.9429V12.924V12.9051V12.8862V12.8673V12.8483V12.8294V12.8105V12.7916V12.7727V12.7538V12.7348V12.7159V12.697V12.6781V12.6592V12.6402V12.6213V12.6024V12.5835V12.5646V12.5457V12.5268V12.5079V12.4889V12.47V12.4511V12.4322V12.4133V12.3944V12.3755V12.3566V12.3377V12.3188V12.2999V12.281V12.2621V12.2433V12.2244V12.2055V12.1866V12.1677V12.1489V12.13V12.1111V12.0923V12.0734V12.0546V12.0357V12.0169V11.998V11.9792V11.9603V11.9415V11.9227V11.9038V11.885V11.8662V11.8474V11.8286V11.8098V11.791V11.7722V11.7534V11.7346V11.7158V11.6971V11.6783V11.6595V11.6408V11.622V11.6033V11.5845V11.5658V11.5471V11.5284V11.5097V11.4909V11.4722V11.4536V11.4349V11.4162V11.3975V11.3788V11.3602V11.3415V11.3229V11.3042V11.2856V11.267V11.2484V11.2298V11.2112V11.1926V11.174V11.1554V11.1368V11.1183V11.0997V11.0812V11.0627V11.0441V11.0256V11.0071V10.9886V10.9701V10.9516V10.9332V10.9147V10.8963V10.8778V10.8594V10.841V10.8225V10.8041V10.7857V10.7674V10.749V10.7306V10.7123V10.6939V10.6756V10.6573V10.639V10.6207V10.6024V10.5841V10.5659V10.5476V10.5294V10.5111V10.4929V10.4747V10.4565V10.4383V10.4202V10.402V10.3839V10.3657V10.3476V10.3295V10.3114V10.2933V10.2753V10.2572V10.2392V10.2211V10.2031V10.1851V10.1671V10.1491V10.1312V10.1132V10.0953V10.0774V10.0595V10.0416V10.0237V10.0058V9.98796V9.97013V9.95231V9.9345V9.91671V9.89893V9.88117V9.86342V9.84569V9.82797V9.81027V9.79259V9.77492V9.75726V9.73962V9.722V9.7044V9.6868V9.66923V9.65167V9.63413V9.61661V9.5991V9.58161V9.56413V9.54667V9.52923V9.51181V9.4944V9.47701V9.45964V9.44228V9.42495V9.40763V9.39033V9.37304V9.35578V9.33853V9.3213V9.30409V9.2869V9.26972V9.25257V9.23543V9.21831V9.20121V9.18413V9.16707V9.15002V9.133V9.116V9.09901V9.08205V9.0651V9.04818V9.03127V9.01439V8.99752V8.98067V8.96385V8.94704V8.93026V8.91349V8.89675V8.88003V8.86333V8.84664V8.82998V8.81335V8.79673V8.78013V8.76356V8.747V8.73047V8.71396V8.69747V8.68101V8.66456V8.64814V8.63174V8.61536V8.599V8.58267V8.56636V8.55007V8.53381V8.51757V8.50135V8.48515V8.46898V8.45283V8.4367V8.4206V8.40452V8.38846V8.37243V8.35642V8.34044V8.32448V8.30854V8.29263V8.27675V8.26088V8.24504V8.22923V8.21344V8.19768V8.18194V8.16623V8.15054V8.13487V8.11923V8.10362V8.08803V8.07247V8.05694V8.04143V8.02594V8.01048V7.99505V7.97965V7.96427V7.94891V7.93359V7.91829V7.90301V7.88777V7.87255V7.85736V7.84219V7.82705V7.81194V7.79686V7.7818V7.76677V7.75177V7.7368V7.72185V7.70694V7.69205V7.67719V7.66235V7.64755V7.63278V7.61803V7.60331V7.58862V7.57396V7.55933V7.54472V7.53015V7.51561V7.50109V7.48661V7.47215V7.45772V7.44333V7.42896V7.41462V7.40032V7.38604V7.3718V7.35758V7.34339V7.32924V7.31511V7.30102V7.28696V7.27293V7.25893V7.24496V7.23102V7.21711V7.20324V7.18939V7.17558V7.1618V7.14805V7.13433V7.12065V7.10699V7.09337V7.07979V7.06623V7.05271V7.03922V7.02576V7.01233V6.99894V6.98558V6.97225V6.95896V6.9457V6.93248V6.91928V6.90612V6.893V6.87991V6.86685V6.85382V6.84083V6.82788V6.81496V6.80207V6.78922V6.7764V6.76362V6.75087V6.73815V6.72547V6.71283V6.70022V6.68765V6.67511V6.66261V6.65014V6.63771V6.62531V6.61296V6.60063V6.58834V6.57609V6.56388V6.5517V6.53956V6.52745V6.51538V6.50335V6.49135V6.47939V6.46747V6.45559V6.44374V6.43193V6.42016V6.40842V6.39672V6.38506V6.37344V6.36186V6.35031V6.3388V6.32733V6.3159V6.30451V6.29315V6.28184V6.27056V6.25932V6.24812V6.23696V6.22584V6.21476V6.20371V6.19271V6.18175V6.17082V6.15994V6.14909V6.13829V6.12752V6.1168V6.10611V6.09547V6.08486V6.0743V6.06377V6.05329V6.04285V6.03245V6.02209V6.01177V6.00149V5.99125V5.98106V5.97091V5.96079V5.95072V5.94069V5.93071V5.92076V5.91086V5.901V5.89118V5.8814V5.87167V5.86198V5.85233V5.84272V5.83316V5.82364V5.81416V5.80473V5.79533V5.78599V5.77668V5.76742V5.7582V5.74903V5.7399V5.73082V5.72177V5.71278V5.70382V5.69491V5.68605V5.67723V5.66845V5.65972V5.65104V5.64239V5.6338V5.62525V5.61674V5.60828V5.59986V5.59149V5.58317V5.57489V5.56666V5.55847V5.55033V5.54223V5.53419V5.52618V5.51823V5.51032V5.50245V5.49464V5.48687V5.47915V5.47147V5.46384V5.45626V5.44872V5.44124V5.4338V5.4264V5.41906V5.41176V5.40604H10.7089C10.1566 5.40604 9.70893 4.95832 9.70893 4.40604V2.31129C9.70893 2.03515 9.48507 1.81129 9.20893 1.81129H6.09456H3.92578ZM6.09456 0.811289H3.92578C2.82121 0.811289 1.92578 1.70672 1.92578 2.81129V13.1885C1.92578 14.293 2.82121 15.1885 3.92578 15.1885H12.0734C13.1779 15.1885 14.0734 14.2933 14.0734 13.1886V13.1697V13.1508V13.132V13.1131V13.0942V13.0753V13.0564V13.0375V13.0185V12.9996V12.9807V12.9618V12.9429V12.924V12.9051V12.8862V12.8673V12.8483V12.8294V12.8105V12.7916V12.7727V12.7538V12.7348V12.7159V12.697V12.6781V12.6592V12.6402V12.6213V12.6024V12.5835V12.5646V12.5457V12.5268V12.5079V12.4889V12.47V12.4511V12.4322V12.4133V12.3944V12.3755V12.3566V12.3377V12.3188V12.2999V12.281V12.2621V12.2433V12.2244V12.2055V12.1866V12.1677V12.1489V12.13V12.1111V12.0923V12.0734V12.0546V12.0357V12.0169V11.998V11.9792V11.9603V11.9415V11.9227V11.9038V11.885V11.8662V11.8474V11.8286V11.8098V11.791V11.7722V11.7534V11.7346V11.7158V11.6971V11.6783V11.6595V11.6408V11.622V11.6033V11.5845V11.5658V11.5471V11.5284V11.5097V11.4909V11.4722V11.4536V11.4349V11.4162V11.3975V11.3788V11.3602V11.3415V11.3229V11.3042V11.2856V11.267V11.2484V11.2298V11.2112V11.1926V11.174V11.1554V11.1368V11.1183V11.0997V11.0812V11.0627V11.0441V11.0256V11.0071V10.9886V10.9701V10.9516V10.9332V10.9147V10.8963V10.8778V10.8594V10.841V10.8225V10.8041V10.7857V10.7674V10.749V10.7306V10.7123V10.6939V10.6756V10.6573V10.639V10.6207V10.6024V10.5841V10.5659V10.5476V10.5294V10.5111V10.4929V10.4747V10.4565V10.4383V10.4202V10.402V10.3839V10.3657V10.3476V10.3295V10.3114V10.2933V10.2753V10.2572V10.2392V10.2211V10.2031V10.1851V10.1671V10.1491V10.1312V10.1132V10.0953V10.0774V10.0595V10.0416V10.0237V10.0058V9.98796V9.97013V9.95231V9.9345V9.91671V9.89893V9.88117V9.86342V9.84569V9.82797V9.81027V9.79259V9.77492V9.75726V9.73962V9.722V9.7044V9.6868V9.66923V9.65167V9.63413V9.61661V9.5991V9.58161V9.56413V9.54667V9.52923V9.51181V9.4944V9.47701V9.45964V9.44228V9.42495V9.40763V9.39033V9.37304V9.35578V9.33853V9.3213V9.30409V9.2869V9.26972V9.25257V9.23543V9.21831V9.20121V9.18413V9.16707V9.15002V9.133V9.116V9.09901V9.08205V9.0651V9.04818V9.03127V9.01439V8.99752V8.98067V8.96385V8.94704V8.93026V8.91349V8.89675V8.88003V8.86333V8.84664V8.82998V8.81335V8.79673V8.78013V8.76356V8.747V8.73594H14.0735V5.29198C14.0735 4.91108 13.9286 4.54445 13.6682 4.26647L10.8759 1.28578C10.5923 0.983061 10.196 0.811289 9.78119 0.811289H9.20893H6.09456ZM10.7089 2.57026L12.4287 4.40604H10.7089V2.57026ZM4.99951 10.5786C4.72337 10.5786 4.49951 10.8025 4.49951 11.0786C4.49951 11.3548 4.72337 11.5786 4.99951 11.5786H10.9995C11.2757 11.5786 11.4995 11.3548 11.4995 11.0786C11.4995 10.8025 11.2757 10.5786 10.9995 10.5786H4.99951ZM4.99944 8.07861C4.7233 8.07861 4.49944 8.30247 4.49944 8.57861C4.49944 8.85476 4.7233 9.07861 4.99944 9.07861H7.99944C8.27558 9.07861 8.49944 8.85476 8.49944 8.57861C8.49944 8.30247 8.27558 8.07861 7.99944 8.07861H4.99944Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/filter.svg

```svg path="/desk/src/assets/icons/filter.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 4.66675C1.5 4.39061 1.72386 4.16675 2 4.16675H14C14.2761 4.16675 14.5 4.39061 14.5 4.66675C14.5 4.94289 14.2761 5.16675 14 5.16675H2C1.72386 5.16675 1.5 4.94289 1.5 4.66675ZM3.49996 7.99761C3.49996 7.72147 3.72382 7.49761 3.99996 7.49761H12C12.2761 7.49761 12.5 7.72147 12.5 7.99761C12.5 8.27375 12.2761 8.49761 12 8.49761H3.99996C3.72382 8.49761 3.49996 8.27375 3.49996 7.99761ZM5.9 11.3289C5.9 11.0527 6.12386 10.8289 6.4 10.8289H9.6C9.87614 10.8289 10.1 11.0527 10.1 11.3289C10.1 11.605 9.87614 11.8289 9.6 11.8289H6.4C6.12386 11.8289 5.9 11.605 5.9 11.3289Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/hash.svg

```svg path="/desk/src/assets/icons/hash.svg" 
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.74818 1.80526C5.77868 1.53081 5.58091 1.2836 5.30646 1.2531C5.032 1.22261 4.78479 1.42037 4.7543 1.69483L4.47959 4.16717H1.75C1.47386 4.16717 1.25 4.39103 1.25 4.66717C1.25 4.94331 1.47386 5.16717 1.75 5.16717H4.36848L3.96091 8.83532H1.75C1.47386 8.83532 1.25 9.05918 1.25 9.33532C1.25 9.61147 1.47386 9.83532 1.75 9.83532H3.8498L3.58735 12.1974C3.55685 12.4718 3.75462 12.719 4.02907 12.7495C4.30353 12.78 4.55074 12.5823 4.58123 12.3078L4.85595 9.83532H8.51798L8.25555 12.1972C8.22505 12.4716 8.42282 12.7189 8.69727 12.7493C8.97173 12.7798 9.21894 12.5821 9.24943 12.3076L9.52413 9.83532H12.2525C12.5287 9.83532 12.7525 9.61147 12.7525 9.33532C12.7525 9.05918 12.5287 8.83532 12.2525 8.83532H9.63524L9.83291 7.05635C9.8634 6.78189 9.66563 6.53468 9.39118 6.50419C9.11673 6.47369 8.86952 6.67146 8.83902 6.94592L8.62909 8.83532H4.96706L5.37464 5.16717H9.62947C9.64077 5.16755 9.65201 5.16754 9.66317 5.16717H12.2525C12.5287 5.16717 12.7525 4.94331 12.7525 4.66717C12.7525 4.39103 12.5287 4.16717 12.2525 4.16717H10.1946L10.4161 1.79655C10.4418 1.5216 10.2397 1.27789 9.96475 1.25221C9.68981 1.22653 9.4461 1.4286 9.42042 1.70354L9.1903 4.16717H5.48575L5.74818 1.80526Z" fill="#7C7C7C"/>
</svg>

```

## /desk/src/assets/icons/home.svg

```svg path="/desk/src/assets/icons/home.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_b_5_8236)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.32172 2.80646C7.70478 2.45286 8.29522 2.45286 8.67828 2.80646L13.5174 7.27336C13.825 7.55732 14 7.95691 14 8.37556V12.4999C14 13.3284 13.3284 13.9999 12.5 13.9999H11V11.2499C11 9.59307 9.65685 8.24993 8 8.24993C6.34315 8.24993 5 9.59307 5 11.2499V13.9999H3.5C2.67157 13.9999 2 13.3284 2 12.4999V8.37556C2 7.95691 2.17496 7.55732 2.48258 7.27336L7.32172 2.80646ZM6 13.9999H8H10V11.2499C10 10.1454 9.10457 9.24993 8 9.24993C6.89543 9.24993 6 10.1454 6 11.2499V13.9999ZM9.35656 2.07165C8.59044 1.36446 7.40956 1.36446 6.64344 2.07165L1.8043 6.53855C1.29159 7.01182 1 7.67782 1 8.37556V12.4999C1 13.8806 2.11929 14.9999 3.5 14.9999H8H12.5C13.8807 14.9999 15 13.8806 15 12.4999V8.37556C15 7.67781 14.7084 7.01182 14.1957 6.53855L9.35656 2.07165Z" fill="#171717"/>
</g>
<defs>
<filter id="filter0_b_5_8236" x="-4" y="-4" width="24" height="24" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feGaussianBlur in="BackgroundImageFix" stdDeviation="2"/>
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_5_8236"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_5_8236" result="shape"/>
</filter>
</defs>
</svg>

```

## /desk/src/assets/icons/knowledge-base-solid.svg

```svg path="/desk/src/assets/icons/knowledge-base-solid.svg" 
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.50098 3.31131C6.95054 3.02596 6.38172 2.85973 5.90892 2.76148C5.54599 2.68606 5.22809 2.64836 4.99977 2.62943C4.88537 2.61995 4.7928 2.61512 4.72753 2.61266C4.69487 2.61143 4.669 2.6108 4.65058 2.61046L4.62862 2.61016L4.62198 2.61012L4.61977 2.61011H4.61831H2.23633C1.4079 2.61011 0.736328 3.28168 0.736328 4.11011V13.2561C0.736328 13.5322 0.960186 13.7561 1.23633 13.7561H4.61831L4.61981 13.7561L4.63259 13.7563C4.64475 13.7565 4.66408 13.7569 4.6899 13.7579C4.74159 13.7599 4.81909 13.7638 4.91714 13.772C5.11374 13.7883 5.39028 13.821 5.70547 13.8865C6.28164 14.0063 6.95042 14.2279 7.50103 14.6274L7.50098 3.31131ZM8.50103 14.6263C9.05136 14.2275 9.71948 14.0061 10.2951 13.8865C10.6103 13.821 10.8869 13.7883 11.0835 13.772C11.1815 13.7638 11.259 13.7599 11.3107 13.7579C11.3365 13.7569 11.3558 13.7565 11.368 13.7563L11.3808 13.7561L11.383 13.7561H14.7643C15.0404 13.7561 15.2643 13.5322 15.2643 13.2561V4.11011C15.2643 3.28168 14.5927 2.61011 13.7643 2.61011H11.3823H11.3808L11.3786 2.61012L11.372 2.61016L11.35 2.61046C11.3316 2.6108 11.3057 2.61143 11.2731 2.61266C11.2078 2.61512 11.1152 2.61995 11.0008 2.62943C10.7725 2.64836 10.4546 2.68606 10.0917 2.76148C9.61927 2.85965 9.05099 3.02569 8.50098 3.31061L8.50103 14.6263Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/knowledge-base.svg

```svg path="/desk/src/assets/icons/knowledge-base.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.73633 3.86328C1.73633 3.58714 1.96019 3.36328 2.23633 3.36328H4.61769L4.61787 3.36328L4.61807 3.36328L4.61981 3.3633L4.63259 3.36348C4.64475 3.36369 4.66408 3.36416 4.6899 3.36513C4.74159 3.36708 4.81909 3.37106 4.91714 3.37919C5.11374 3.39549 5.39028 3.42824 5.70547 3.49374C6.28138 3.61342 6.94983 3.83496 7.5003 4.2341V13.2101C6.95008 12.925 6.38153 12.7588 5.90892 12.6606C5.54599 12.5852 5.22809 12.5475 4.99977 12.5286C4.88537 12.5191 4.7928 12.5143 4.72753 12.5118C4.69487 12.5106 4.669 12.5099 4.65058 12.5096L4.62862 12.5093L4.62198 12.5092L4.61977 12.5092L4.61895 12.5092H4.61861C4.61846 12.5092 4.61831 12.5092 4.61831 13.0092V12.5092H1.73633V3.86328ZM8.32464 14.5171C8.90383 14.0305 9.6564 13.7724 10.2951 13.6397C10.6103 13.5742 10.8869 13.5414 11.0835 13.5251C11.1815 13.517 11.259 13.513 11.3107 13.5111C11.3365 13.5101 11.3558 13.5097 11.368 13.5094L11.3808 13.5093L11.3823 13.5092H11.3825H11.3827H11.383H14.7643C15.0404 13.5092 15.2643 13.2854 15.2643 13.0092V3.86328C15.2643 3.03485 14.5927 2.36328 13.7643 2.36328H11.3823V2.86328C11.3823 2.36328 11.3821 2.36328 11.382 2.36328H11.3817H11.3808L11.3786 2.36329L11.372 2.36334L11.35 2.36364C11.3316 2.36397 11.3057 2.36461 11.2731 2.36584C11.2078 2.36829 11.1152 2.37312 11.0008 2.38261C10.7725 2.40154 10.4546 2.43924 10.0917 2.51466C9.47347 2.64312 8.69109 2.88781 8.0003 3.36306C7.30951 2.88781 6.52714 2.64312 5.90892 2.51466C5.54599 2.43924 5.22809 2.40154 4.99977 2.38261C4.88537 2.37312 4.7928 2.36829 4.72753 2.36584C4.69487 2.36461 4.669 2.36397 4.65058 2.36364L4.62862 2.36334L4.62198 2.36329L4.61977 2.36328H4.61895H4.61861C4.61846 2.36328 4.61831 2.36328 4.61831 2.86328V2.36328H2.23633C1.4079 2.36328 0.736328 3.03485 0.736328 3.86328V13.0092C0.736328 13.2854 0.960186 13.5092 1.23633 13.5092L4.61753 13.5092H4.6176L4.61762 13.5092H4.61787H4.61807H4.61831L4.61981 13.5093L4.63259 13.5094C4.64475 13.5097 4.66408 13.5101 4.6899 13.5111C4.74159 13.513 4.81909 13.517 4.91714 13.5251C5.11374 13.5414 5.39028 13.5742 5.70547 13.6397C6.34421 13.7724 7.09677 14.0305 7.67596 14.5171C7.76328 14.5916 7.87654 14.6366 8.0003 14.6366C8.12406 14.6366 8.23733 14.5916 8.32464 14.5171ZM8.5003 13.2101V4.2341C9.05077 3.83496 9.71922 3.61342 10.2951 3.49374C10.6103 3.42824 10.8869 3.39549 11.0835 3.37919C11.1815 3.37106 11.259 3.36708 11.3107 3.36513C11.3365 3.36416 11.3558 3.36369 11.368 3.36348L11.3808 3.3633L11.3823 3.36328L11.3825 3.36328L11.3827 3.36328L11.3829 3.36328H13.7643C14.0404 3.36328 14.2643 3.58714 14.2643 3.86328V12.5092H11.3823V13.0092C11.3823 12.5092 11.3821 12.5092 11.382 12.5092H11.3817L11.3808 12.5092L11.3786 12.5092L11.372 12.5093L11.35 12.5096C11.3316 12.5099 11.3057 12.5106 11.2731 12.5118C11.2078 12.5143 11.1152 12.5191 11.0008 12.5286C10.7725 12.5475 10.4546 12.5852 10.0917 12.6606C9.61907 12.7588 9.05053 12.925 8.5003 13.2101Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/location.svg

```svg path="/desk/src/assets/icons/location.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.15969 11.0123L4.17279 11.0253C4.17276 11.0253 4.17484 11.0272 4.17897 11.031C4.21695 11.0655 4.42864 11.2579 4.77688 11.5727C5.14213 11.9029 5.62149 12.3355 6.10132 12.7685C6.16929 12.8299 6.23758 12.8915 6.30581 12.9531C7.02952 13.6061 7.74656 14.2532 8.00622 14.4912C8.15155 14.3604 8.43754 14.1068 8.78577 13.7981C9.13708 13.4865 9.55174 13.1189 9.94918 12.7645C10.4342 12.3321 10.9128 11.9027 11.2691 11.5768C11.3745 11.4803 11.4673 11.3947 11.5452 11.3218V11.2964L11.8648 10.9997C12.95 9.99193 13.5109 8.58334 13.5109 7.05226V7.03944L13.5112 7.02663C13.5901 3.95314 11.1555 1.5 8.05226 1.5C4.954 1.5 2.5 3.954 2.5 7.05226C2.5 8.58334 3.06088 9.99193 4.14613 10.9997L4.15969 11.0123ZM7.90678 14.5823C7.91104 14.578 7.91527 14.574 7.91946 14.5701C7.91386 14.5754 7.90961 14.5795 7.90678 14.5823ZM7.39704 15.2894C7.35023 15.2426 6.39086 14.3768 5.43146 13.511C4.47199 12.6451 3.51248 11.7793 3.46568 11.7324C2.15523 10.5156 1.5 8.83073 1.5 7.05226C1.5 3.40172 4.40172 0.5 8.05226 0.5C11.7028 0.5 14.6045 3.40172 14.5109 7.05226C14.5109 8.83073 13.8557 10.5156 12.5452 11.7324C12.5452 11.8024 10.399 13.7046 9.27744 14.6986C8.89921 15.0338 8.63749 15.2658 8.61388 15.2894C8.33307 15.5702 7.77145 15.5702 7.39704 15.2894ZM8.05226 9.92434C6.47034 9.92434 5.18019 8.63419 5.18019 7.05226C5.18019 5.47034 6.47034 4.18019 8.05226 4.18019C9.63419 4.18019 10.9243 5.47034 10.9243 7.05226C10.9243 8.63419 9.63419 9.92434 8.05226 9.92434ZM6.18019 7.05226C6.18019 8.0819 7.02262 8.92434 8.05226 8.92434C9.0819 8.92434 9.92434 8.0819 9.92434 7.05226C9.92434 6.02262 9.0819 5.18019 8.05226 5.18019C7.02262 5.18019 6.18019 6.02262 6.18019 7.05226Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/mail.svg

```svg path="/desk/src/assets/icons/mail.svg" 
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.31263 1.6875C1.93192 1.6875 0.812629 2.80679 0.812629 4.1875V4.80095C0.812457 4.80852 0.812457 4.81607 0.812629 4.82361V9.8125C0.812629 11.1932 1.93192 12.3125 3.31263 12.3125H10.6876C12.0683 12.3125 13.1876 11.1932 13.1876 9.8125V4.82361C13.1878 4.81607 13.1878 4.80852 13.1876 4.80095V4.1875C13.1876 2.80679 12.0683 1.6875 10.6876 1.6875H3.31263ZM12.1876 4.48113V4.1875C12.1876 3.35907 11.5161 2.6875 10.6876 2.6875H3.31263C2.4842 2.6875 1.81263 3.35907 1.81263 4.1875V4.48113L6.80531 6.59342C6.92985 6.64611 7.07041 6.64611 7.19495 6.59342L12.1876 4.48113ZM1.81263 5.56695V9.8125C1.81263 10.6409 2.4842 11.3125 3.31263 11.3125H10.6876C11.5161 11.3125 12.1876 10.6409 12.1876 9.8125V5.56695L7.58459 7.51439C7.21098 7.67245 6.78928 7.67245 6.41567 7.51439L1.81263 5.56695Z" fill="#7C7C7C"/>
</svg>

```

## /desk/src/assets/icons/pdf.svg

```svg path="/desk/src/assets/icons/pdf.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.92578 1.81129C3.3735 1.81129 2.92578 2.259 2.92578 2.81129V13.1885C2.92578 13.7408 3.3735 14.1885 3.92578 14.1885H12.0734C12.6258 14.1885 13.0734 13.7408 13.0734 13.1886V13.1697V13.1508V13.132V13.1131V13.0942V13.0753V13.0564V13.0375V13.0185V12.9996V12.9807V12.9618V12.9429V12.924V12.9051V12.8862V12.8673V12.8483V12.8294V12.8105V12.7916V12.7727V12.7538V12.7348V12.7159V12.697V12.6781V12.6592V12.6402V12.6213V12.6024V12.5835V12.5646V12.5457V12.5268V12.5079V12.4889V12.47V12.4511V12.4322V12.4133V12.3944V12.3755V12.3566V12.3377V12.3188V12.2999V12.281V12.2621V12.2433V12.2244V12.2055V12.1866V12.1677V12.1489V12.13V12.1111V12.0923V12.0734V12.0546V12.0357V12.0169V11.998V11.9792V11.9603V11.9415V11.9227V11.9038V11.885V11.8662V11.8474V11.8286V11.8098V11.791V11.7722V11.7534V11.7346V11.7158V11.6971V11.6783V11.6595V11.6408V11.622V11.6033V11.5845V11.5658V11.5471V11.5284V11.5097V11.4909V11.4722V11.4536V11.4349V11.4162V11.3975V11.3788V11.3602V11.3415V11.3229V11.3042V11.2856V11.267V11.2484V11.2298V11.2112V11.1926V11.174V11.1554V11.1368V11.1183V11.0997V11.0812V11.0627V11.0441V11.0256V11.0071V10.9886V10.9701V10.9516V10.9332V10.9147V10.8963V10.8778V10.8594V10.841V10.8225V10.8041V10.7857V10.7674V10.749V10.7306V10.7123V10.6939V10.6756V10.6573V10.639V10.6207V10.6024V10.5841V10.5659V10.5476V10.5294V10.5111V10.4929V10.4747V10.4565V10.4383V10.4202V10.402V10.3839V10.3657V10.3476V10.3295V10.3114V10.2933V10.2753V10.2572V10.2392V10.2211V10.2031V10.1851V10.1671V10.1491V10.1312V10.1132V10.0953V10.0774V10.0595V10.0416V10.0237V10.0058V9.98796V9.97013V9.95231V9.9345V9.91671V9.89893V9.88117V9.86342V9.84569V9.82797V9.81027V9.79259V9.77492V9.75726V9.73962V9.722V9.7044V9.6868V9.66923V9.65167V9.63413V9.61661V9.5991V9.58161V9.56413V9.54667V9.52923V9.51181V9.4944V9.47701V9.45964V9.44228V9.42495V9.40763V9.39033V9.37304V9.35578V9.33853V9.3213V9.30409V9.2869V9.26972V9.25257V9.23543V9.21831V9.20121V9.18413V9.16707V9.15002V9.133V9.116V9.09901V9.08205V9.0651V9.04818V9.03127V9.01439V8.99752V8.98067V8.96385V8.94704V8.93026V8.91349V8.89675V8.88003V8.86333V8.84664V8.82998V8.81335V8.79673V8.78013V8.76356V8.747V8.73047V8.71396V8.69747V8.68101V8.66456V8.64814V8.63174V8.61536V8.599V8.58267V8.56636V8.55007V8.53381V8.51757V8.50135V8.48515V8.46898V8.45283V8.4367V8.4206V8.40452V8.38846V8.37243V8.35642V8.34044V8.32448V8.30854V8.29263V8.27675V8.26088V8.24504V8.22923V8.21344V8.19768V8.18194V8.16623V8.15054V8.13487V8.11923V8.10362V8.08803V8.07247V8.05694V8.04143V8.02594V8.01048V7.99505V7.97965V7.96427V7.94891V7.93359V7.91829V7.90301V7.88777V7.87255V7.85736V7.84219V7.82705V7.81194V7.79686V7.7818V7.76677V7.75177V7.7368V7.72185V7.70694V7.69205V7.67719V7.66235V7.64755V7.63278V7.61803V7.60331V7.58862V7.57396V7.55933V7.54472V7.53015V7.51561V7.50109V7.48661V7.47215V7.45772V7.44333V7.42896V7.41462V7.40032V7.38604V7.3718V7.35758V7.34339V7.32924V7.31511V7.30102V7.28696V7.27293V7.25893V7.24496V7.23102V7.21711V7.20324V7.18939V7.17558V7.1618V7.14805V7.13433V7.12065V7.10699V7.09337V7.07979V7.06623V7.05271V7.03922V7.02576V7.01233V6.99894V6.98558V6.97225V6.95896V6.9457V6.93248V6.91928V6.90612V6.893V6.87991V6.86685V6.85382V6.84083V6.82788V6.81496V6.80207V6.78922V6.7764V6.76362V6.75087V6.73815V6.72547V6.71283V6.70022V6.68765V6.67511V6.66261V6.65014V6.63771V6.62531V6.61296V6.60063V6.58834V6.57609V6.56388V6.5517V6.53956V6.52745V6.51538V6.50335V6.49135V6.47939V6.46747V6.45559V6.44374V6.43193V6.42016V6.40842V6.39672V6.38506V6.37344V6.36186V6.35031V6.3388V6.32733V6.3159V6.30451V6.29315V6.28184V6.27056V6.25932V6.24812V6.23696V6.22584V6.21476V6.20371V6.19271V6.18175V6.17082V6.15994V6.14909V6.13829V6.12752V6.1168V6.10611V6.09547V6.08486V6.0743V6.06377V6.05329V6.04285V6.03245V6.02209V6.01177V6.00149V5.99125V5.98106V5.97091V5.96079V5.95072V5.94069V5.93071V5.92076V5.91086V5.901V5.89118V5.8814V5.87167V5.86198V5.85233V5.84272V5.83316V5.82364V5.81416V5.80473V5.79533V5.78599V5.77668V5.76742V5.7582V5.74903V5.7399V5.73082V5.72177V5.71278V5.70382V5.69491V5.68605V5.67723V5.66845V5.65972V5.65104V5.64239V5.6338V5.62525V5.61674V5.60828V5.59986V5.59149V5.58317V5.57489V5.56666V5.55847V5.55033V5.54223V5.53419V5.52618V5.51823V5.51032V5.50245V5.49464V5.48687V5.47915V5.47147V5.46384V5.45626V5.44872V5.44124V5.4338V5.4264V5.41906V5.41176V5.40604H10.7089C10.1566 5.40604 9.70893 4.95832 9.70893 4.40604V2.31129C9.70893 2.03515 9.48507 1.81129 9.20893 1.81129H6.09456H3.92578ZM6.09456 0.811289H9.20893H9.78119C10.196 0.811289 10.5923 0.983061 10.8759 1.28578L13.6682 4.26647C13.9286 4.54445 14.0735 4.91108 14.0735 5.29198V8.73594H14.0734V8.747V8.76356V8.78013V8.79673V8.81335V8.82998V8.84664V8.86333V8.88003V8.89675V8.91349V8.93026V8.94704V8.96385V8.98067V8.99752V9.01439V9.03127V9.04818V9.0651V9.08205V9.09901V9.116V9.133V9.15002V9.16707V9.18413V9.20121V9.21831V9.23543V9.25257V9.26972V9.2869V9.30409V9.3213V9.33853V9.35578V9.37304V9.39033V9.40763V9.42495V9.44228V9.45964V9.47701V9.4944V9.51181V9.52923V9.54667V9.56413V9.58161V9.5991V9.61661V9.63413V9.65167V9.66923V9.6868V9.7044V9.722V9.73962V9.75726V9.77492V9.79259V9.81027V9.82797V9.84569V9.86342V9.88117V9.89893V9.91671V9.9345V9.95231V9.97013V9.98796V10.0058V10.0237V10.0416V10.0595V10.0774V10.0953V10.1132V10.1312V10.1491V10.1671V10.1851V10.2031V10.2211V10.2392V10.2572V10.2753V10.2933V10.3114V10.3295V10.3476V10.3657V10.3839V10.402V10.4202V10.4383V10.4565V10.4747V10.4929V10.5111V10.5294V10.5476V10.5659V10.5841V10.6024V10.6207V10.639V10.6573V10.6756V10.6939V10.7123V10.7306V10.749V10.7674V10.7857V10.8041V10.8225V10.841V10.8594V10.8778V10.8963V10.9147V10.9332V10.9516V10.9701V10.9886V11.0071V11.0256V11.0441V11.0627V11.0812V11.0997V11.1183V11.1368V11.1554V11.174V11.1926V11.2112V11.2298V11.2484V11.267V11.2856V11.3042V11.3229V11.3415V11.3602V11.3788V11.3975V11.4162V11.4349V11.4536V11.4722V11.4909V11.5097V11.5284V11.5471V11.5658V11.5845V11.6033V11.622V11.6408V11.6595V11.6783V11.6971V11.7158V11.7346V11.7534V11.7722V11.791V11.8098V11.8286V11.8474V11.8662V11.885V11.9038V11.9227V11.9415V11.9603V11.9792V11.998V12.0169V12.0357V12.0546V12.0734V12.0923V12.1111V12.13V12.1489V12.1677V12.1866V12.2055V12.2244V12.2433V12.2621V12.281V12.2999V12.3188V12.3377V12.3566V12.3755V12.3944V12.4133V12.4322V12.4511V12.47V12.4889V12.5079V12.5268V12.5457V12.5646V12.5835V12.6024V12.6213V12.6402V12.6592V12.6781V12.697V12.7159V12.7348V12.7538V12.7727V12.7916V12.8105V12.8294V12.8483V12.8673V12.8862V12.9051V12.924V12.9429V12.9618V12.9807V12.9996V13.0185V13.0375V13.0564V13.0753V13.0942V13.1131V13.132V13.1508V13.1697V13.1886C14.0734 14.2933 13.1779 15.1885 12.0734 15.1885H3.92578C2.82121 15.1885 1.92578 14.293 1.92578 13.1885V2.81129C1.92578 1.70672 2.82121 0.811289 3.92578 0.811289H6.09456ZM10.7089 2.57026L12.4287 4.40604H10.7089V2.57026ZM3.71289 11.9877V8.69727H5.02024C5.29555 8.69727 5.52669 8.74217 5.71366 8.83198C5.90063 8.92178 6.04197 9.0506 6.13766 9.21844C6.23483 9.38627 6.28342 9.58797 6.28342 9.82353C6.28342 10.0532 6.2341 10.2505 6.13546 10.4154C6.03829 10.5788 5.89401 10.7047 5.70262 10.793C5.51123 10.8799 5.27567 10.9233 4.99594 10.9233H4.54102V11.9877H3.71289ZM4.54102 9.37965V10.2696H4.94736C5.06514 10.2696 5.16157 10.2527 5.23666 10.2188C5.31321 10.1835 5.36989 10.1327 5.4067 10.0664C5.4435 10.0002 5.46191 9.91922 5.46191 9.82353C5.46191 9.72636 5.4435 9.64539 5.4067 9.58061C5.36989 9.51436 5.31321 9.4643 5.23666 9.43044C5.16157 9.39658 5.06514 9.37965 4.94736 9.37965H4.54102ZM7.91972 11.9877H7.51338H7.03638H6.67862V8.69727H7.02092H7.51338H7.9153C8.25097 8.69727 8.54247 8.76499 8.78981 8.90043C9.03715 9.03441 9.22854 9.22433 9.36398 9.47019C9.49943 9.71605 9.56715 10.0068 9.56715 10.3425C9.56715 10.6782 9.50016 10.9689 9.36619 11.2148C9.23222 11.4607 9.04156 11.6513 8.79423 11.7868C8.54836 11.9207 8.25686 11.9877 7.91972 11.9877ZM7.51338 9.3929V11.2921H7.87997C8.07136 11.2921 8.22962 11.2575 8.35476 11.1883C8.4799 11.1191 8.57266 11.0146 8.63302 10.8747C8.69485 10.7334 8.72577 10.556 8.72577 10.3425C8.72577 10.129 8.69412 9.95235 8.63081 9.81248C8.56897 9.67115 8.47402 9.56589 8.34593 9.49669C8.21932 9.4275 8.05811 9.3929 7.8623 9.3929H7.51338ZM12.2878 8.69727H9.98003V11.9877H10.8148V10.7996H12.0846V10.1327H10.8148V9.39069H12.2878V8.69727Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/right-chevron.svg

```svg path="/desk/src/assets/icons/right-chevron.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.64645 13.3536C5.45118 13.1583 5.45118 12.8417 5.64645 12.6464L10.2929 8L5.64645 3.35355C5.45118 3.15829 5.45118 2.84171 5.64645 2.64645C5.84171 2.45118 6.15829 2.45118 6.35355 2.64645L11.3536 7.64645C11.5488 7.84171 11.5488 8.15829 11.3536 8.35355L6.35355 13.3536C6.15829 13.5488 5.84171 13.5488 5.64645 13.3536Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/settings-solid.svg

```svg path="/desk/src/assets/icons/settings-solid.svg" 
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.58883 1.59557C6.69725 1.38347 6.91537 1.25 7.15358 1.25H8.84642C9.08463 1.25 9.30275 1.38347 9.41117 1.59556C9.83939 2.43327 10.8124 2.83628 11.7075 2.54671C11.9341 2.47339 12.1827 2.53325 12.3512 2.70169L13.5482 3.89871C13.7166 4.06715 13.7765 4.31575 13.7032 4.54239C13.4137 5.43759 13.8167 6.4106 14.6544 6.83883C14.8665 6.94725 15 7.16538 15 7.40358V9.09642C15 9.33463 14.8665 9.55275 14.6544 9.66117C13.8167 10.0894 13.4137 11.0624 13.7032 11.9576C13.7766 12.1842 13.7167 12.4328 13.5483 12.6012L12.9497 13.1997L12.9406 13.2087L12.3076 13.81C12.1391 13.9701 11.8962 14.0247 11.6754 13.9522C10.7992 13.6645 9.844 14.0577 9.42424 14.8789L9.41101 14.9047C9.30268 15.1167 9.08476 15.25 8.84677 15.25H7.15358C6.91537 15.25 6.69725 15.1165 6.58883 14.9044C6.16059 14.0667 5.18759 13.6637 4.29238 13.9532C4.06575 14.0265 3.81715 13.9666 3.64871 13.7982L2.45169 12.6012C2.28325 12.4327 2.22339 12.1841 2.29671 11.9575C2.58628 11.0624 2.18327 10.0894 1.34556 9.66117C1.13347 9.55275 1 9.33463 1 9.09642V7.40282C1 7.16335 1.13512 6.94641 1.34525 6.83899C2.17618 6.41424 2.57671 5.44267 2.28272 4.56262C2.20679 4.33532 2.26588 4.08462 2.43534 3.91516L3.64876 2.70174C3.8172 2.53331 4.06581 2.47345 4.29245 2.54676C5.18762 2.83632 6.1606 2.43329 6.58883 1.59557ZM8 10.5C9.24264 10.5 10.25 9.49264 10.25 8.25C10.25 7.00736 9.24264 6 8 6C6.75736 6 5.75 7.00736 5.75 8.25C5.75 9.49264 6.75736 10.5 8 10.5Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/settings.svg

```svg path="/desk/src/assets/icons/settings.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.20465 3.31006C5.42974 3.60357 6.70871 3.0738 7.36743 2H8H8.63257C9.29128 3.07377 10.5702 3.60355 11.7953 3.31002L12.2426 3.75736L12.6899 4.20461C12.3964 5.4297 12.9262 6.7087 14 7.36743V8V8.63257C12.9262 9.29129 12.3964 10.5703 12.6899 11.7953L12.2472 12.2381L11.7712 12.6903C10.5529 12.3926 9.27724 12.9233 8.63025 14H8H7.36743C6.7087 12.9262 5.4297 12.3964 4.20461 12.6899L3.75736 12.2426L3.31002 11.7953C3.60355 10.5702 3.07378 9.29128 2 8.63257L2 8L2 7.36727C3.0651 6.71234 3.596 5.43568 3.29587 4.21885L3.75736 3.75736L4.20465 3.31006ZM7.15358 1C6.91537 1 6.69725 1.13347 6.58883 1.34557C6.1606 2.18329 5.18762 2.58632 4.29245 2.29676C4.06581 2.22345 3.8172 2.28331 3.64876 2.45174L3.05025 3.05025L2.43534 3.66516C2.26588 3.83462 2.20679 4.08532 2.28272 4.31262C2.57671 5.19267 2.17618 6.16424 1.34525 6.58899C1.13512 6.69641 1 6.91335 1 7.15282V8V8.84642C1 9.08463 1.13347 9.30275 1.34556 9.41117C2.18327 9.83939 2.58628 10.8124 2.29671 11.7075C2.22339 11.9341 2.28325 12.1827 2.45169 12.3512L3.05025 12.9497L3.64871 13.5482C3.81715 13.7166 4.06575 13.7765 4.29238 13.7032C5.18759 13.4137 6.16059 13.8167 6.58883 14.6544C6.69725 14.8665 6.91537 15 7.15358 15H8H8.84677C9.08476 15 9.30268 14.8667 9.41101 14.6547L9.42424 14.6289C9.844 13.8077 10.7992 13.4145 11.6754 13.7022C11.8962 13.7747 12.1391 13.7201 12.3076 13.56L12.9406 12.9587L12.9407 12.9588L12.9497 12.9497L13.5483 12.3512C13.7167 12.1828 13.7766 11.9342 13.7032 11.7076C13.4137 10.8124 13.8167 9.8394 14.6544 9.41117C14.8665 9.30275 15 9.08463 15 8.84642V8V7.15358C15 6.91538 14.8665 6.69725 14.6544 6.58883C13.8167 6.1606 13.4137 5.18759 13.7032 4.29239C13.7765 4.06575 13.7166 3.81715 13.5482 3.64871L12.9497 3.05025L12.3512 2.45169C12.1827 2.28325 11.9341 2.22339 11.7075 2.29671C10.8124 2.58628 9.83939 2.18327 9.41117 1.34556C9.30275 1.13347 9.08463 1 8.84642 1H8H7.15358ZM6 8C6 6.89543 6.89543 6 8 6C9.10457 6 10 6.89543 10 8C10 9.10457 9.10457 10 8 10C6.89543 10 6 9.10457 6 8ZM8 5C6.34315 5 5 6.34315 5 8C5 9.65685 6.34315 11 8 11C9.65685 11 11 9.65685 11 8C11 6.34315 9.65685 5 8 5Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/sort-arrow.svg

```svg path="/desk/src/assets/icons/sort-arrow.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.50026 3.5C5.50026 3.22386 5.27641 3 5.00026 3C4.72412 3 4.50026 3.22386 4.50026 3.5V11.2929L2.87894 9.67157C2.68368 9.47631 2.3671 9.47631 2.17184 9.67157C1.97658 9.86684 1.97658 10.1834 2.17184 10.3787L4.64671 12.8536C4.69465 12.9015 4.7499 12.9377 4.80887 12.9621C4.86696 12.9861 4.93056 12.9996 4.99727 13C4.99826 13 4.99926 13 5.00026 13C5.00126 13 5.00226 13 5.00326 13C5.13022 12.9992 5.25695 12.9504 5.35382 12.8536L7.82869 10.3787C8.02395 10.1834 8.02395 9.86684 7.82869 9.67157C7.63343 9.47631 7.31685 9.47631 7.12158 9.67157L5.50026 11.2929V3.5ZM10.5003 12.5V4.70711L8.87894 6.32843C8.68368 6.52369 8.3671 6.52369 8.17184 6.32843C7.97657 6.13316 7.97657 5.81658 8.17184 5.62132L10.6467 3.14645C10.6946 3.09851 10.7499 3.06234 10.8089 3.03794C10.8678 3.01349 10.9325 3 11.0003 3C11.0681 3 11.1327 3.01349 11.1917 3.03794C11.2506 3.06234 11.3059 3.09851 11.3538 3.14645L13.8287 5.62132C14.024 5.81658 14.024 6.13316 13.8287 6.32843C13.6334 6.52369 13.3168 6.52369 13.1216 6.32843L11.5003 4.70711V12.5C11.5003 12.7761 11.2764 13 11.0003 13C10.7241 13 10.5003 12.7761 10.5003 12.5Z" fill="#383838"/>
</svg>

```

## /desk/src/assets/icons/teams.svg

```svg path="/desk/src/assets/icons/teams.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_b_84_50838)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.34738 2.1225C8.13218 1.99953 7.86799 1.99953 7.65279 2.1225L4.25202 4.0658L1.0559 5.89215C0.585631 6.16088 0.585631 6.83897 1.0559 7.10769L4.25202 8.93404L7.65279 10.8773C7.86799 11.0003 8.13218 11.0003 8.34738 10.8773L11.7482 8.93404L14.9443 7.10769C15.4145 6.83897 15.4145 6.16088 14.9443 5.89215L8.34738 2.1225ZM4.74816 4.93404L8.00009 3.0758L13.9923 6.49992L11.252 8.0658L8.00009 9.92405L4.74816 8.0658L2.00787 6.49992L4.74816 4.93404ZM1.24816 9.0658C1.0084 8.9288 0.702969 9.01209 0.565964 9.25185C0.428959 9.49161 0.512257 9.79704 0.752016 9.93404L4.25202 11.934L7.65279 13.8773C7.86799 14.0003 8.13218 14.0003 8.34738 13.8773L11.7482 11.934L15.2482 9.93404C15.4879 9.79704 15.5712 9.49161 15.4342 9.25185C15.2972 9.01209 14.9918 8.9288 14.752 9.0658L11.252 11.0658L8.00009 12.924L4.74816 11.0658L1.24816 9.0658Z" fill="#171717"/>
</g>
<defs>
<filter id="filter0_b_84_50838" x="-4" y="-4" width="24" height="24" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feGaussianBlur in="BackgroundImageFix" stdDeviation="2"/>
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_84_50838"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_84_50838" result="shape"/>
</filter>
</defs>
</svg>

```

## /desk/src/assets/icons/ticket-solid.svg

```svg path="/desk/src/assets/icons/ticket-solid.svg" 
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.997559 4.37305C0.997559 3.54462 1.66913 2.87305 2.49756 2.87305H13.5023C14.3307 2.87305 15.0023 3.54462 15.0023 4.37305V6.15978C15.0023 6.39752 14.8349 6.60238 14.6019 6.64975C13.8409 6.80449 13.2683 7.47826 13.2683 8.28388C13.2683 9.08951 13.8409 9.76328 14.6019 9.91802C14.8349 9.96539 15.0023 10.1703 15.0023 10.408V12.1266C15.0023 12.955 14.3307 13.6266 13.5023 13.6266H2.49756C1.66913 13.6266 0.997559 12.955 0.997559 12.1266V10.408C0.997559 10.1703 1.16496 9.96539 1.39793 9.91802C2.15894 9.76328 2.73152 9.08951 2.73152 8.28388C2.73152 7.47751 2.15906 6.80451 1.39793 6.64975C1.16496 6.60238 0.997559 6.39752 0.997559 6.15978V4.37305ZM5.40967 6.85645C5.40967 6.5803 5.63353 6.35645 5.90967 6.35645H10.0898C10.3659 6.35645 10.5898 6.5803 10.5898 6.85645C10.5898 7.13259 10.3659 7.35645 10.0898 7.35645H5.90967C5.63353 7.35645 5.40967 7.13259 5.40967 6.85645ZM5.40967 9.64331C5.40967 9.36717 5.63353 9.14331 5.90967 9.14331H10.0898C10.3659 9.14331 10.5898 9.36717 10.5898 9.64331C10.5898 9.91945 10.3659 10.1433 10.0898 10.1433H5.90967C5.63353 10.1433 5.40967 9.91945 5.40967 9.64331Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/ticket.svg

```svg path="/desk/src/assets/icons/ticket.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.99756 4.12305C1.99756 3.8469 2.22142 3.62305 2.49756 3.62305H13.5023C13.7784 3.62305 14.0023 3.84691 14.0023 4.12305V5.53459C12.9897 5.91326 12.2683 6.88902 12.2683 8.03388C12.2683 9.17875 12.9897 10.1545 14.0023 10.5332V11.8766C14.0023 12.1527 13.7784 12.3766 13.5023 12.3766H2.49756C2.22142 12.3766 1.99756 12.1527 1.99756 11.8766V10.5332C3.01017 10.1545 3.73152 9.17875 3.73152 8.03388C3.73152 6.88816 3.01009 5.91306 1.99756 5.53456V4.12305ZM2.49756 2.62305C1.66913 2.62305 0.997559 3.29462 0.997559 4.12305V5.90978C0.997559 6.14752 1.16496 6.35238 1.39793 6.39975C2.15906 6.55451 2.73152 7.22751 2.73152 8.03388C2.73152 8.83951 2.15894 9.51328 1.39793 9.66802C1.16496 9.71539 0.997559 9.92025 0.997559 10.158V11.8766C0.997559 12.705 1.66913 13.3766 2.49756 13.3766H13.5023C14.3307 13.3766 15.0023 12.705 15.0023 11.8766V10.158C15.0023 9.92025 14.8349 9.71539 14.6019 9.66802C13.8409 9.51328 13.2683 8.83951 13.2683 8.03388C13.2683 7.22826 13.8409 6.55449 14.6019 6.39975C14.8349 6.35238 15.0023 6.14752 15.0023 5.90978V4.12305C15.0023 3.29462 14.3307 2.62305 13.5023 2.62305H2.49756ZM5.40965 6.60646C5.40965 6.33032 5.63351 6.10646 5.90965 6.10646H10.0897C10.3659 6.10646 10.5897 6.33032 10.5897 6.60646C10.5897 6.8826 10.3659 7.10646 10.0897 7.10646H5.90965C5.63351 7.10646 5.40965 6.8826 5.40965 6.60646ZM5.40965 9.39324C5.40965 9.1171 5.63351 8.89324 5.90965 8.89324H10.0897C10.3659 8.89324 10.5897 9.1171 10.5897 9.39324C10.5897 9.66938 10.3659 9.89324 10.0897 9.89324H5.90965C5.63351 9.89324 5.40965 9.66938 5.40965 9.39324Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/web-link.svg

```svg path="/desk/src/assets/icons/web-link.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.86813 10.1317C5.67286 9.93647 5.67286 9.61988 5.86813 9.42462L12.7926 2.5001L9 2.5001C8.72386 2.5001 8.5 2.27624 8.5 2.0001C8.5 1.72396 8.72386 1.5001 9 1.5001L13.9899 1.5001C14.1076 1.49777 14.2261 1.53678 14.3215 1.61714C14.4306 1.70886 14.5 1.84638 14.5 2.0001V7.0001C14.5 7.27624 14.2761 7.5001 14 7.5001C13.7239 7.5001 13.5 7.27624 13.5 7.0001V3.20696L6.57523 10.1317C6.37997 10.327 6.06339 10.327 5.86813 10.1317ZM2.5 4.0001C2.5 3.17167 3.17157 2.5001 4 2.5001H5.8C6.07614 2.5001 6.3 2.27624 6.3 2.0001C6.3 1.72396 6.07614 1.5001 5.8 1.5001H4C2.61929 1.5001 1.5 2.61939 1.5 4.0001V12.0001C1.5 13.3808 2.61929 14.5001 4 14.5001H12C13.3807 14.5001 14.5 13.3808 14.5 12.0001V10.2001C14.5 9.92396 14.2761 9.7001 14 9.7001C13.7239 9.7001 13.5 9.92396 13.5 10.2001V12.0001C13.5 12.8285 12.8284 13.5001 12 13.5001H4C3.17157 13.5001 2.5 12.8285 2.5 12.0001V4.0001Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/icons/web.svg

```svg path="/desk/src/assets/icons/web.svg" 
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1204 8C2.69277 8.70548 3.52219 9.20408 4.49652 9.53968C4.67003 9.59944 4.84725 9.65371 5.02729 9.70283C4.95061 9.12994 4.91153 8.55864 4.90011 8.01041C4.89997 8.00347 4.89997 7.99653 4.90011 7.98959C4.91153 7.44136 4.95061 6.87006 5.02729 6.29717C4.84724 6.34629 4.67003 6.40056 4.49652 6.46032C3.52219 6.79592 2.69277 7.29452 2.1204 8ZM6.07178 6.07178C5.96646 6.71227 5.91373 7.36658 5.90011 8C5.91373 8.63343 5.96646 9.28773 6.07178 9.92822C6.71228 10.0335 7.36658 10.0863 8 10.0999C8.63343 10.0863 9.28773 10.0335 9.92822 9.92822C10.0335 9.28773 10.0863 8.63342 10.0999 8C10.0863 7.36657 10.0335 6.71227 9.92822 6.07178C9.28773 5.96645 8.63343 5.91373 8 5.90011C7.36658 5.91373 6.71228 5.96645 6.07178 6.07178ZM9.70283 5.02729C9.12994 4.95061 8.55864 4.91153 8.01042 4.90011C8.00347 4.89996 7.99653 4.89996 7.98959 4.90011C7.44136 4.91153 6.87006 4.95061 6.29717 5.02729C6.34629 4.84724 6.40056 4.67003 6.46032 4.49652C6.79592 3.52219 7.29452 2.69277 8 2.1204C8.70548 2.69277 9.20408 3.52219 9.53968 4.49651C9.59945 4.67003 9.65372 4.84724 9.70283 5.02729ZM10.9727 6.29717C11.0494 6.87006 11.0885 7.44136 11.0999 7.98958C11.1 7.99653 11.1 8.00347 11.0999 8.01041C11.0885 8.55864 11.0494 9.12994 10.9727 9.70283C11.1528 9.65371 11.33 9.59944 11.5035 9.53968C12.4778 9.20408 13.3072 8.70547 13.8796 8C13.3072 7.29452 12.4778 6.79592 11.5035 6.46032C11.33 6.40056 11.1528 6.34629 10.9727 6.29717ZM13.8266 9.43774C13.2344 9.8977 12.5479 10.2376 11.8292 10.4852C11.488 10.6027 11.1367 10.7004 10.7808 10.7808C10.7004 11.1367 10.6027 11.488 10.4852 11.8291C10.2376 12.5479 9.89771 13.2344 9.43774 13.8266C11.5965 13.2958 13.2958 11.5965 13.8266 9.43774ZM8.00001 13.8796C8.70548 13.3072 9.20409 12.4778 9.53968 11.5035C9.59945 11.33 9.65371 11.1528 9.70283 10.9727C9.12994 11.0494 8.55864 11.0885 8.01042 11.0999C8.00347 11.1 7.99653 11.1 7.98959 11.0999C7.44136 11.0885 6.87006 11.0494 6.29718 10.9727C6.34629 11.1528 6.40056 11.33 6.46032 11.5035C6.79592 12.4778 7.29453 13.3072 8.00001 13.8796ZM5.21919 10.7808C4.86326 10.7004 4.51204 10.6027 4.17085 10.4852C3.45208 10.2376 2.76557 9.8977 2.17336 9.43774C2.70424 11.5965 4.40351 13.2958 6.56227 13.8266C6.1023 13.2344 5.76241 12.5479 5.51484 11.8291C5.39732 11.488 5.2996 11.1367 5.21919 10.7808ZM2.17336 6.56226C2.76557 6.1023 3.45208 5.76241 4.17085 5.51484C4.51204 5.39732 4.86326 5.29959 5.21919 5.21919C5.29959 4.86326 5.39732 4.51203 5.51484 4.17085C5.76241 3.45208 6.1023 2.76557 6.56226 2.17336C4.40351 2.70424 2.70424 4.40351 2.17336 6.56226ZM9.43774 2.17336C9.89771 2.76557 10.2376 3.45208 10.4852 4.17085C10.6027 4.51203 10.7004 4.86326 10.7808 5.21919C11.1367 5.29959 11.488 5.39732 11.8292 5.51484C12.5479 5.76241 13.2344 6.1023 13.8266 6.56227C13.2958 4.40351 11.5965 2.70424 9.43774 2.17336ZM1 8C1 4.13401 4.13401 1 8 1C11.866 1 15 4.13401 15 8C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8Z" fill="#171717"/>
</svg>

```

## /desk/src/assets/images/frappe-mail.svg

```svg path="/desk/src/assets/images/frappe-mail.svg" 
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.5714 44L31.4286 44C38.3716 44 44 38.3716 44 31.4286L44 12.5714C44 5.62842 38.3716 0 31.4286 0L12.5714 0C5.62842 0 0 5.62842 0 12.5714L0 31.4286C0 38.3716 5.62842 44 12.5714 44Z" fill="#0466DC"/>
<path d="M9.42859 12.5715V14.8972L12.5714 17.4587L18.5743 22.3458C19.5329 23.1315 20.7586 23.5715 22 23.5715C23.2414 23.5715 24.4672 23.1315 25.4257 22.3458L31.4286 17.443V28.2701H12.5714V21.5287L9.42859 18.9672V27.4844C9.42859 29.653 11.1886 31.413 13.3572 31.413H30.6429C32.8115 31.413 34.5715 29.653 34.5715 27.4844V12.5715H9.42859ZM23.4457 19.9101C22.6286 20.5701 21.3714 20.5701 20.57 19.9101L15.4157 15.7144H28.6L23.4457 19.9101Z" fill="white"/>
</svg>

```

## /desk/src/assets/images/gmail.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/src/assets/images/gmail.png

## /desk/src/assets/images/outlook.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/src/assets/images/outlook.png

## /desk/src/assets/images/sendgrid.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/src/assets/images/sendgrid.png

## /desk/src/assets/images/sparkpost.webp

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/src/assets/images/sparkpost.webp

## /desk/src/assets/images/yahoo.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/src/assets/images/yahoo.png

## /desk/src/assets/images/yandex.png

Binary file available at https://raw.githubusercontent.com/frappe/helpdesk/refs/heads/main/desk/src/assets/images/yandex.png

## /desk/src/assets/logos/HDLogo.vue

```vue path="/desk/src/assets/logos/HDLogo.vue" 
<template>
  <svg
    width="118"
    height="118"
    viewBox="0 0 118 118"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      d="M93.9278 0H23.1013C10.3428 0 0 10.3428 0 23.1013V93.9278C0 106.686 10.3428 117.029 23.1013 117.029H93.9278C106.686 117.029 117.029 106.686 117.029 93.9278V23.1013C117.029 10.3428 106.686 0 93.9278 0Z"
      fill="#7D42FB"
    />
    <path
      d="M95.9759 50.8753V27.8265L21 27.8265V38.3271H85.5278V48.3027C81.3275 49.5103 78.2824 53.3955 78.2824 57.9632C78.2824 62.531 81.3275 66.3637 85.5278 67.5713V77.5468H31.5006V50.1403H21V88.0474H96.0284V64.9986L89.7805 60.5359V55.3906L96.0284 50.9278L95.9759 50.8753Z"
      fill="#EDF7FF"
    />
  </svg>
</template>

```

## /desk/src/components/Apps.vue

```vue path="/desk/src/components/Apps.vue" 
<template>
  <Popover placement="right-start" class="flex w-full">
    <template #target="{ togglePopover }">
      <button
        :class="[
          'group w-full flex h-7 items-center justify-between rounded px-2 text-base text-gray-800 hover:bg-gray-100',
        ]"
        @click.prevent="togglePopover()"
      >
        <div class="flex gap-2">
          <AppsIcon />
          <span class="whitespace-nowrap">Apps</span>
        </div>
        <ChevronRight class="h-4 w-4 stroke-1.5" />
      </button>
    </template>
    <template #body>
      <div
        class="grid grid-cols-3 justify-between mx-3 p-2 rounded-lg border border-gray-100 bg-white shadow-xl"
      >
        <div v-for="app in apps.data" key="name">
          <a
            :href="app.route"
            class="flex flex-col gap-1.5 rounded justify-center items-center py-2 px-3 hover:bg-gray-100"
          >
            <img class="size-8" :src="app.logo" />
            <div class="text-sm" @click="app.onClick">
              {{ app.title }}
            </div>
          </a>
        </div>
      </div>
    </template>
  </Popover>
</template>
<script setup>
import { Popover, createResource } from "frappe-ui";
import AppsIcon from "./icons/AppsIcon.vue";
import ChevronRight from "~icons/lucide/chevron-right";

const apps = createResource({
  url: "frappe.apps.get_apps",
  cache: "apps",
  auto: true,
  transform: (data) => {
    let _apps = [
      {
        name: "frappe",
        logo: "/assets/helpdesk/desk/desk.png",
        title: "Desk",
        route: "/app",
      },
    ];
    data.map((app) => {
      if (app.name === "helpdesk") return;
      _apps.push({
        name: app.name,
        logo: app.logo,
        title: app.title,
        route: app.route,
      });
    });
    return _apps;
  },
});
</script>

```

## /desk/src/components/AssignmentModal.vue

```vue path="/desk/src/components/AssignmentModal.vue" 
<template>
  <Dialog
    v-model="show"
    :options="{
      title: 'Assign To',
      size: 'xl',
    }"
  >
    <template #body-content>
      <SearchComplete
        class="form-control"
        doctype="HD Agent"
        :custom-filters="customFilters"
        :reset-input="true"
        @change="
          (option) => {
            addAssignee(option.value);
          }
        "
      >
        <template #item-prefix="{ option }">
          <UserAvatar class="mr-2" :name="option.value" size="sm" />
        </template>
        <template #item-label="{ option }">
          <Tooltip :text="option.value">
            {{ getUser(option.value).full_name }}
          </Tooltip>
        </template>
      </SearchComplete>
      <div class="mt-3 flex flex-wrap items-center gap-2">
        <Tooltip
          v-for="currentAssignee in assignees"
          :key="currentAssignee.name"
          :text="currentAssignee.name"
        >
          <Button
            :label="getUser(currentAssignee.name).full_name"
            theme="gray"
            variant="outline"
          >
            <template #prefix>
              <UserAvatar :name="currentAssignee.name" size="sm" />
            </template>
            <template #suffix>
              <FeatherIcon
                class="h-3.5"
                name="x"
                @click.stop="removeCurrentAssignee(currentAssignee.name)"
              />
            </template>
          </Button>
        </Tooltip>
      </div>
      <ErrorMessage v-if="error" class="mt-2" :message="error" />
    </template>
  </Dialog>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import { createResource } from "frappe-ui";
import { UserAvatar, SearchComplete } from "@/components";
import { useUserStore } from "@/stores/user";

const props = defineProps({
  assignees: {
    type: Array,
    required: true,
  },
  doctype: {
    type: String,
    required: true,
  },
  docname: {
    type: String,
    required: true,
  },
});

const show = defineModel();

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

const { getUser } = useUserStore();

const error = ref("");

const addAssignee = (value) => {
  error.value = "";
  createResource({
    url: "frappe.desk.form.assign_to.add",
    auto: true,
    params: {
      doctype: props.doctype,
      name: props.docname,
      assign_to: [value],
    },
    onSuccess: () => {
      emit("update");
    },
  });
  emit("update");
};

const removeCurrentAssignee = (value) => {
  createResource({
    url: "frappe.desk.form.assign_to.remove",
    auto: true,
    params: {
      doctype: props.doctype,
      name: props.docname,
      assign_to: value,
    },
    onSuccess: () => {
      emit("update");
    },
  });
};

const customFilters = computed(() => {
  const filters = {};
  filters["is_active"] = ["=", 1];
  if (Boolean(props.assignees?.length)) {
    filters["name"] = ["not in", [...props.assignees.map((a) => a.name)]];
  }
  return filters;
});
</script>

```

## /desk/src/components/AttachmentItem.vue

```vue path="/desk/src/components/AttachmentItem.vue" 
<template>
  <span>
    <a :href="isShowable ? null : url" target="_blank">
      <Button
        :label="label"
        theme="gray"
        variant="outline"
        @click="toggleDialog()"
      >
        <template #prefix>
          <component :is="getIcon()" class="h-4 w-4" />
        </template>
        <template #suffix>
          <slot name="suffix" />
        </template>
      </Button>
    </a>
    <Dialog
      v-model="showDialog"
      :options="{
        title: label,
        size: '4xl',
      }"
    >
      <template #body-content>
        <div
          v-if="isText"
          class="prose prose-sm max-w-none whitespace-pre-wrap"
        >
          {{ content }}
        </div>
        <img v-if="isImage" :src="url" class="m-auto rounded border" />
      </template>
    </Dialog>
  </span>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { Button, Dialog } from "frappe-ui";
import { getType as getMime } from "mime";
import LucideFileType from "~icons/lucide/file-type";
import LucideFileImage from "~icons/lucide/file-image";
import LucideFileText from "~icons/lucide/file-text";
import LucideFileSpreadsheet from "~icons/lucide/file-spreadsheet";
import LucideFile from "~icons/lucide/file";

interface P {
  label: string;
  url?: string;
}

const props = withDefaults(defineProps<P>(), {
  url: null,
});

const showDialog = ref(false);
const mimeType = getMime(props.label) || "";
const isImage = mimeType.startsWith("image/");
const isPdf = mimeType === "application/pdf";
const isSpreadsheet = mimeType.includes("spreadsheet");
const isText = mimeType === "text/plain";
const isShowable = props.url && (isText || isImage);
const content = ref("");

function getIcon() {
  if (isText) return LucideFileType;
  else if (isImage) return LucideFileImage;
  else if (isPdf) return LucideFileText;
  else if (isSpreadsheet) return LucideFileSpreadsheet;
  else return LucideFile;
}

function toggleDialog() {
  if (!isShowable) return;
  if (isText) {
    fetch(props.url).then((res) => res.text().then((t) => (content.value = t)));
  }
  showDialog.value = !showDialog.value;
}
</script>

```

## /desk/src/components/Autocomplete.vue

```vue path="/desk/src/components/Autocomplete.vue" 
<template>
  <Combobox v-slot="{ open: isComboboxOpen }" v-model="selectedValue" nullable>
    <Popover v-model:show="showOptions" class="w-full">
      <template #target="{ open: openPopover, togglePopover }">
        <slot name="target" v-bind="{ open: openPopover, togglePopover }">
          <div class="w-full -ml-0.5">
            <button
              class="flex w-full items-center justify-between focus:outline-none"
              :class="inputClasses"
              @click="() => togglePopover()"
            >
              <div class="flex items-center">
                <slot name="prefix" />
                <span
                  v-if="selectedValue"
                  class="overflow-hidden text-ellipsis whitespace-nowrap text-base leading-5"
                >
                  {{ displayValue(selectedValue) }}
                </span>
                <span v-else class="text-base leading-5 text-gray-500">
                  {{ placeholder || "" }}
                </span>
              </div>
              <FeatherIcon
                name="chevron-down"
                class="h-4 w-4 text-gray-600"
                aria-hidden="true"
              />
            </button>
          </div>
        </slot>
      </template>
      <template #body="{ isOpen }">
        <div v-show="isOpen">
          <div class="mt-1 rounded-lg bg-white py-1 text-base shadow-2xl">
            <div class="relative px-1.5 pt-0.5">
              <ComboboxInput
                ref="search"
                class="form-input w-full"
                type="text"
                :value="query"
                autocomplete="off"
                placeholder="Search"
                @change="
                  (e) => {
                    query = e.target.value;
                  }
                "
              />
              <button
                class="absolute right-1.5 inline-flex h-7 w-7 items-center justify-center"
                @click="selectedValue = null"
              >
                <FeatherIcon name="x" class="w-4" />
              </button>
            </div>
            <ComboboxOptions
              class="my-1 max-h-[12rem] overflow-y-auto px-1.5"
              static
            >
              <div
                v-for="group in groups"
                v-show="group.items.length > 0"
                :key="group.key"
                class="mt-1.5"
              >
                <div
                  v-if="group.group && !group.hideLabel"
                  class="px-2.5 py-1.5 text-sm font-medium text-gray-500"
                >
                  {{ group.group }}
                </div>
                <ComboboxOption
                  v-for="option in group.items"
                  :key="option.value"
                  v-slot="{ active, selected }"
                  as="template"
                  :value="option"
                >
                  <li
                    :class="[
                      'flex items-center rounded px-2.5 py-1.5 text-base',
                      { 'bg-gray-100': active },
                    ]"
                  >
                    <slot
                      name="item-prefix"
                      v-bind="{ active, selected, option }"
                    />
                    <slot
                      name="item-label"
                      v-bind="{ active, selected, option }"
                    >
                      {{ option.label }}
                    </slot>
                  </li>
                </ComboboxOption>
              </div>
              <li
                v-if="groups.length == 0"
                class="mt-1.5 rounded-md px-2.5 py-1.5 text-base text-gray-600"
              >
                No results found
              </li>
            </ComboboxOptions>
            <div v-if="slots.footer" class="border-t p-1.5 pb-0.5">
              <slot
                name="footer"
                v-bind="{ value: search?.el._value, close }"
              ></slot>
            </div>
          </div>
        </div>
      </template>
    </Popover>
  </Combobox>
</template>

<script setup>
import {
  Combobox,
  ComboboxInput,
  ComboboxOptions,
  ComboboxOption,
} from "@headlessui/vue";
import { Popover, Button, FeatherIcon } from "frappe-ui";
import { ref, computed, useAttrs, useSlots, watch, nextTick } from "vue";

const props = defineProps({
  modelValue: {
    type: String,
    default: "",
  },
  options: {
    type: Array,
    default: () => [],
  },
  size: {
    type: String,
    default: "md",
  },
  variant: {
    type: String,
    default: "subtle",
  },
  placeholder: {
    type: String,
    default: "",
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  filterable: {
    type: Boolean,
    default: true,
  },
});
const emit = defineEmits(["update:modelValue", "update:query", "change"]);

const query = ref("");
const showOptions = ref(false);
const search = ref(null);

const attrs = useAttrs();
const slots = useSlots();

const valuePropPassed = computed(() => "value" in attrs);

const selectedValue = computed({
  get() {
    return valuePropPassed.value ? attrs.value : props.modelValue;
  },
  set(val) {
    query.value = "";
    if (val) {
      showOptions.value = false;
    }
    emit(valuePropPassed.value ? "change" : "update:modelValue", val);
  },
});

function close() {
  showOptions.value = false;
}

const groups = computed(() => {
  if (!props.options || props.options.length == 0) return [];

  let groups = props.options[0]?.group
    ? props.options
    : [{ group: "", items: props.options }];

  return groups
    .map((group, i) => {
      return {
        key: i,
        group: group.group,
        hideLabel: group.hideLabel || false,
        items: props.filterable ? filterOptions(group.items) : group.items,
      };
    })
    .filter((group) => group.items.length > 0);
});

function filterOptions(options) {
  if (!query.value) {
    return options;
  }
  return options.filter((option) => {
    let searchTexts = [option.label, option.value];
    return searchTexts.some((text) =>
      (text || "").toString().toLowerCase().includes(query.value.toLowerCase())
    );
  });
}

function displayValue(option) {
  if (typeof option === "string") {
    let allOptions = groups.value.flatMap((group) => group.items);
    let selectedOption = allOptions.find((o) => o.value === option);
    return selectedOption?.label || option;
  }
  return option?.label;
}

watch(query, (q) => {
  emit("update:query", q);
});

watch(showOptions, (val) => {
  if (val) {
    nextTick(() => {
      search.value.el.focus();
    });
  }
});

const textColor = computed(() => {
  return props.disabled ? "text-gray-600" : "text-gray-800";
});

const inputClasses = computed(() => {
  let sizeClasses = {
    sm: "text-base rounded h-7",
    md: "text-base rounded h-8",
    lg: "text-lg rounded-md h-10",
    xl: "text-xl rounded-md h-10",
  }[props.size];

  let paddingClasses = {
    sm: "py-1.5 px-2",
    md: "py-1.5 px-2.5",
    lg: "py-1.5 px-3",
    xl: "py-1.5 px-3",
  }[props.size];

  let variant = props.disabled ? "disabled" : props.variant;
  let variantClasses = {
    subtle:
      "border border-gray-100 bg-gray-100 placeholder-gray-500 hover:border-gray-200 hover:bg-gray-200 focus:bg-white focus:border-gray-500 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-gray-400",
    outline:
      "border border-gray-300 bg-white placeholder-gray-500 hover:border-gray-400 hover:shadow-sm focus:bg-white focus:border-gray-500 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-gray-400",
    disabled: [
      "border bg-gray-50 placeholder-gray-400",
      props.variant === "outline" ? "border-gray-300" : "border-transparent",
    ],
  }[variant];

  return [
    sizeClasses,
    paddingClasses,
    variantClasses,
    textColor.value,
    "transition-colors w-full",
  ];
});

defineExpose({ query });
</script>

```

## /desk/src/components/BrandLogo.vue

```vue path="/desk/src/components/BrandLogo.vue" 
<template>
  <img
    v-if="config.brandLogo"
    :src="config.brandLogo"
    alt="Brand Logo"
    class="h-8 w-8 shrink-0 object-cover"
  />
  <HDLogo v-else class="h-8 w-8 shrink-0 rounded" />
</template>

<script setup lang="ts">
import { Avatar } from "frappe-ui";
import HDLogo from "@/assets/logos/HDLogo.vue";

import { useConfigStore } from "@/stores/config";
const config = useConfigStore();
</script>

<style scoped></style>

```

## /desk/src/components/CannedResponseSelectorModal.vue

```vue path="/desk/src/components/CannedResponseSelectorModal.vue" 
<template>
  <Dialog
    v-model="show"
    :options="{
      title: 'Canned Responses',
      size: '4xl',
    }"
  >
    <template #body-content>
      <TextInput
        ref="searchInput"
        v-model="search"
        type="text"
        :placeholder="'Site Down'"
      >
        <template #prefix>
          <FeatherIcon name="search" class="h-4 w-4 text-gray-500" />
        </template>
      </TextInput>
      <div
        v-if="filteredTemplates.length"
        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"
          :key="template.name"
          class="flex h-56 cursor-pointer flex-col gap-2 rounded-lg border p-3 hover:bg-gray-100"
          @click="emit('apply', template)"
        >
          <div class="border-b pb-2 text-base font-semibold">
            {{ template.title }}
          </div>
          <TextEditor
            v-if="template.message"
            :content="template.message"
            :editable="false"
            editor-class="!prose-sm max-w-none !text-sm text-gray-600 focus:outline-none"
            class="flex-1 overflow-hidden"
          />
        </div>
      </div>
      <div v-else class="mt-2">
        <div class="flex h-56 flex-col items-center justify-center">
          <div class="text-lg text-gray-500">
            {{ "No templates found" }}
          </div>
        </div>
      </div>
      <div class="flex justify-end mt-4">
        <Button
          label="New Canned Response"
          @click="
            () => {
              $router.push('/canned-responses#new');
              templates.data = null;
            }
          "
        />
      </div>
    </template>
  </Dialog>
</template>

<script setup>
import { TextEditor, createListResource } from "frappe-ui";
import { ref, computed, nextTick, watch, onMounted } from "vue";

const props = defineProps({
  doctype: {
    type: String,
    default: "",
  },
});

const show = defineModel();
const searchInput = ref("");

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

const search = ref("");

const templates = createListResource({
  type: "list",
  doctype: "HD Canned Response",
  cache: ["cannedResponses", props.doctype],
  fields: ["title", "message", "modified"],
  orderBy: "modified desc",
  pageLength: 99999,
});

onMounted(() => {
  if (templates.data == null) {
    templates.fetch();
  }
});

const filteredTemplates = computed(() => {
  return (
    templates.data?.filter((template) => {
      return template.title.toLowerCase().includes(search.value.toLowerCase());
    }) ?? []
  );
});

watch(show, (value) => value && nextTick(() => searchInput.value?.el?.focus()));
</script>

```

## /desk/src/components/CommentBox.vue

```vue path="/desk/src/components/CommentBox.vue" 
<template>
  <div class="flex-col text-base flex-1" ref="commentBoxRef">
    <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 gap-1">
        <Tooltip :text="dateFormat(creation, dateTooltipFormat)">
          <span class="pl-0.5 text-sm text-gray-600">
            {{ timeAgo(creation) }}
          </span>
        </Tooltip>
        <div v-if="authStore.userId === commentedBy && !editable">
          <Dropdown
            :options="[
              {
                label: 'Edit',
                onClick: () => handleEditMode(),
                icon: 'edit-2',
                condition: () => !isTicketMergedComment,
              },
              {
                label: 'Delete',
                onClick: () => (showDialog = true),
                icon: 'trash-2',
              },
            ]"
          >
            <Button
              icon="more-horizontal"
              class="text-gray-600"
              variant="ghost"
            />
          </Dropdown>
        </div>
      </div>
    </div>
    <div class="rounded bg-gray-50 px-4 py-3">
      <TextEditor
        ref="editorRef"
        :editor-class="[
          'prose-f shrink  text-p-sm transition-all duration-300 ease-in-out block w-full content',
          getFontFamily(_content),
        ]"
        :content="_content"
        :editable="editable"
        :bubble-menu="textEditorMenuButtons"
        @change="(event:string) => {_content = event}"
      >
        <template #bottom v-if="editable">
          <div class="flex flex-row-reverse gap-2">
            <Button label="Save" @click="handleSaveComment" variant="solid" />
            <Button label="Discard" @click="handleDiscard" />
          </div>
        </template>
      </TextEditor>
      <div class="flex flex-wrap gap-2" v-if="!editable">
        <AttachmentItem
          v-for="a in attachments"
          :key="a.file_url"
          :label="a.file_name"
          :url="a.file_url"
        />
      </div>
    </div>
  </div>
  <Dialog
    v-model="showDialog"
    :options="{
      title: 'Delete Comment',
      message: 'Are you sure you want to confirm this action?',
      actions: [
        { label: 'Cancel', onClick: () => (showDialog = false) },
        {
          label: 'Delete',
          onClick: () => deleteComment.submit(),
          variant: 'solid',
        },
      ],
    }"
  />
</template>

<script setup lang="ts">
import { ref, PropType, onMounted, computed } from "vue";
import {
  Dropdown,
  createResource,
  Dialog,
  Avatar,
  TextEditor,
} from "frappe-ui";
import {
  dateFormat,
  timeAgo,
  dateTooltipFormat,
  createToast,
  textEditorMenuButtons,
  isContentEmpty,
  getFontFamily,
} from "@/utils";
import { AttachmentItem } from "@/components";
import { useAuthStore } from "@/stores/auth";
import { useUserStore } from "@/stores/user";
import { CommentActivity } from "@/types";
import { updateRes as updateComment } from "@/stores/knowledgeBase";
const authStore = useAuthStore();
const props = defineProps({
  activity: {
    type: Object as PropType<CommentActivity>,
    required: true,
  },
});
const { getUser } = useUserStore();

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

const isTicketMergedComment = computed(() => {
  const regex = /has been merged with ticket #\d+/;
  return regex.test(content);
});

const emit = defineEmits(["update"]);
const showDialog = ref(false);
const editable = ref(false);
const _content = ref(content);

// HTML refs
const commentBoxRef = ref(null);
const editorRef = ref(null);

function handleEditMode() {
  editable.value = true;
  editorRef.value.editor.chain().focus("start");
}

function handleDiscard() {
  _content.value = content;
  editable.value = false;
}

const deleteComment = createResource({
  url: "frappe.client.delete",
  makeParams: () => ({
    doctype: "HD Ticket Comment",
    name: name,
  }),
  onSuccess() {
    emit("update");
    createToast({
      title: "Comment deleted",
      icon: "check",
      iconClasses: "text-green-500",
    });
  },
});

function handleSaveComment() {
  if (content === _content.value) {
    editable.value = false;
    return;
  }
  if (isContentEmpty(_content.value)) {
    createToast({
      title: "Comment cannot be empty",
      icon: "x",
      iconClasses: "text-red-600",
    });
    return;
  }

  updateComment.submit(
    {
      doctype: "HD Ticket Comment",
      name: name,
      fieldname: "content",
      value: _content.value,
    },
    {
      onSuccess: () => {
        editable.value = false;
        emit("update");
        createToast({
          title: "Comment updated",
          icon: "check",
          iconClasses: "text-green-500",
        });
      },
    }
  );
}

onMounted(() => {
  commentBoxRef.value.style.width = "0px";
});
</script>

```

## /desk/src/components/CommentTextEditor.vue

```vue path="/desk/src/components/CommentTextEditor.vue" 
<template>
  <TextEditor
    v-if="agentsList.data"
    ref="textEditor"
    :editor-class="[
      'prose-sm max-w-none',
      editable &&
        'min-h-[7rem] mx-10 max-h-[50vh] overflow-y-auto border-t py-3',
      getFontFamily(newComment),
    ]"
    :content="newComment"
    :starterkit-options="{ heading: { levels: [2, 3, 4, 5, 6] } }"
    :placeholder="placeholder"
    :editable="editable"
    :mentions="agents"
    @change="editable ? (newComment = $event) : null"
    :extensions="[PreserveVideoControls]"
  >
    <template #bottom>
      <div v-if="editable" class="flex flex-col gap-2">
        <div class="flex flex-wrap gap-2 px-10">
          <AttachmentItem
            v-for="a in attachments"
            :key="a.file_url"
            :label="a.file_name"
          >
            <template #suffix>
              <FeatherIcon
                class="h-3.5"
                name="x"
                @click.stop="removeAttachment(a)"
              />
            </template>
          </AttachmentItem>
        </div>
        <div
          class="flex justify-between gap-2 overflow-hidden border-t px-10 py-2.5"
        >
          <div class="flex items-center overflow-x-auto">
            <TextEditorFixedMenu
              class="-ml-1"
              :buttons="textEditorMenuButtons"
            />
            <FileUploader
              :upload-args="{
                doctype: doctype,
                docname: modelValue.name,
                private: true,
              }"
              @success="(f) => attachments.push(f)"
            >
              <template #default="{ openFileSelector }">
                <Button
                  theme="gray"
                  variant="ghost"
                  @click="openFileSelector()"
                >
                  <template #icon>
                    <AttachmentIcon
                      class="h-4"
                      style="color: #000000; stroke-width: 1.5 !important"
                    />
                  </template>
                </Button>
              </template>
            </FileUploader>
          </div>
          <div class="mt-2 flex items-center justify-end space-x-2 sm:mt-0">
            <Button
              label="Discard"
              @click="
                () => {
                  newComment = '';
                  attachments = [];
                  emit('discard');
                }
              "
            />
            <Button
              variant="solid"
              label="Comment"
              :disabled="commentEmpty"
              :loading="loading"
              @click="
                () => {
                  loading = true;
                  submitComment();
                  newComment = '';
                }
              "
            />
          </div>
        </div>
      </div>
    </template>
  </TextEditor>
</template>
<script setup lang="ts">
import { computed, ref, onMounted } from "vue";
import {
  TextEditorFixedMenu,
  TextEditor,
  FileUploader,
  createResource,
} from "frappe-ui";

import { AttachmentIcon } from "@/components/icons/";
import { AttachmentItem } from "@/components/";
import { useAgentStore } from "@/stores/agent";
import { useStorage } from "@vueuse/core";
import { PreserveVideoControls } from "@/tiptap-extensions";
import { isContentEmpty, textEditorMenuButtons, getFontFamily } from "@/utils";

const { agents: agentsList } = useAgentStore();
onMounted(() => {
  agentsList.fetch();
});
const props = defineProps({
  placeholder: {
    type: String,
    default: null,
  },
  editable: {
    type: Boolean,
    default: true,
  },
  doctype: {
    type: String,
    default: "HD Ticket",
  },
});

const emit = defineEmits(["submit", "discard"]);
const doc = defineModel();
const newComment = useStorage("commentBoxContent" + doc.value.name, "");
const attachments = ref([]);
const commentEmpty = computed(() => {
  return isContentEmpty(newComment.value);
});
const loading = ref(false);

const agents = computed(() => {
  return (
    agentsList.data?.map((agent) => ({
      label: agent.agent_name.trimEnd(),
      value: agent.name,
    })) || []
  );
});

function removeAttachment(attachment) {
  attachments.value = attachments.value.filter((a) => a !== attachment);
}

async function submitComment() {
  if (isContentEmpty(newComment.value)) {
    return;
  }
  const comment = createResource({
    url: "run_doc_method",
    makeParams: () => ({
      dt: props.doctype,
      dn: doc.value.name,
      method: "new_comment",
      args: {
        content: newComment.value,
        attachments: attachments.value,
      },
    }),
    onSuccess: () => {
      emit("submit");
      loading.value = false;
      attachments.value = [];
      newComment.value = null;
    },
    onError: () => {
      loading.value = false;
    },
  });

  comment.submit();
}
defineExpose({
  submitComment,
});
</script>

```

## /desk/src/components/CommunicationArea.vue

```vue path="/desk/src/components/CommunicationArea.vue" 
<template>
  <div class="flex flex-col comm-area">
    <div
      class="flex justify-between gap-3 border-t px-4 lg:px-10 py-4 md: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"
      @keydown.ctrl.enter.capture.stop="submitComment"
      @keydown.meta.enter.capture.stop="submitComment"
    >
      <CommentTextEditor
        ref="commentTextEditorRef"
        v-model="doc"
        :editable="showCommentBox"
        :doctype="doctype"
        placeholder="@John could you please look into this?"
        @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"
        placeholder="Hi John, we are looking into this issue."
        :to-emails="toEmails"
        :cc-emails="ccEmails"
        :bcc-emails="bccEmails"
        @submit="
          () => {
            showEmailBox = false;
            emit('update');
          }
        "
        @discard="
          () => {
            showEmailBox = false;
          }
        "
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";

import { EmailEditor, CommentTextEditor } from "@/components";
import { EmailIcon, CommentIcon } from "@/components/icons/";

const emit = defineEmits(["update"]);
const content = defineModel("content");
const doc = defineModel();

const showEmailBox = ref(false);
const showCommentBox = ref(false);

const emailEditorRef = ref(null);
const commentTextEditorRef = ref(null);

function toggleEmailBox() {
  if (showCommentBox.value) {
    showCommentBox.value = false;
  }
  showEmailBox.value = !showEmailBox.value;
}

function toggleCommentBox() {
  if (showEmailBox.value) {
    showEmailBox.value = false;
  }
  showCommentBox.value = !showCommentBox.value;
}

function submitEmail() {
  emailEditorRef.value.submitMail();
  emit("update");
}

function submitComment() {
  commentTextEditorRef.value.submitComment();
  emit("update");
}

function replyToEmail(data: object) {
  showEmailBox.value = true;
  emailEditorRef.value.addToReply(
    data.content,
    data.to?.split(","),
    data.cc?.split(","),
    data.bcc?.split(",")
  );
}

const props = defineProps({
  doctype: {
    type: String,
    default: "HD Ticket",
  },
  toEmails: {
    type: Array,
    default: () => [],
  },
  ccEmails: {
    type: Array,
    default: () => [],
  },
  bccEmails: {
    type: Array,
    default: () => [],
  },
});

defineExpose({
  replyToEmail,
  toggleEmailBox,
  toggleCommentBox,
  editor: emailEditorRef,
});
</script>

<style>
@media screen and (max-width: 640px) {
  .comm-area {
    width: 100vw;
  }
}
</style>

```

## /desk/src/components/CustomActions.vue

```vue path="/desk/src/components/CustomActions.vue" 
<template>
  <div v-if="normalActions.length" class="flex gap-2">
    <Button
      v-for="action in normalActions"
      :key="action.label"
      :label="action.label"
      @click="action.onClick()"
    >
      <template v-if="action.icon" #prefix>
        <FeatherIcon :name="action.icon" class="h-4 w-4" />
      </template>
    </Button>
  </div>
  <Dropdown v-if="groupedActions.length" :options="groupedActions">
    <Button icon="more-horizontal" />
  </Dropdown>
  <div v-if="groupedWithLabelActions.length">
    <div v-for="g in groupedWithLabelActions" :key="g.label">
      <Dropdown v-slot="{ open }" :options="g.action">
        <Button :label="g.label">
          <template #suffix>
            <FeatherIcon
              :name="open ? 'chevron-up' : 'chevron-down'"
              class="h-4"
            />
          </template>
        </Button>
      </Dropdown>
    </div>
  </div>
</template>

<script setup>
import { computed, h } from "vue";
import { Dropdown } from "frappe-ui";

const props = defineProps({
  actions: {
    type: Object,
    required: true,
  },
});

const normalActions = computed(() => {
  return props.actions.filter((action) => !action.group);
});

const groupedWithLabelActions = computed(() => {
  let _actions = [];

  props.actions
    .filter((action) => action.buttonLabel && action.group)
    .forEach((action) => {
      let groupIndex = _actions.findIndex(
        (a) => a.label === action.buttonLabel
      );
      if (groupIndex > -1) {
        _actions[groupIndex].action.push(action);
      } else {
        _actions.push({
          label: action.buttonLabel,
          action: [action],
        });
      }
    });
  return _actions;
});

const groupedActions = computed(() => {
  let _actions = [];
  _actions = _actions.concat(
    props.actions.filter((action) => action.group && !action.buttonLabel)
  );
  return _actions;
});
</script>

```

## /desk/src/components/DiscardButton.vue

```vue path="/desk/src/components/DiscardButton.vue" 
<template>
  <Button :label="label" @click="handleDiscard" />
</template>

<script setup lang="ts">
import { globalStore } from "@/stores/globalStore";
const { $dialog } = globalStore();
const emit = defineEmits<{
  (event: "discard"): void;
}>();

const {
  label = "Discard",
  hideDialog = false,
  title = "Discard?",
  message = "Are you sure you want to discard this?",
} = defineProps<{
  label?: string;
  hideDialog?: boolean;
  title?: string;
  message?: string;
}>();

function handleDiscard() {
  if (hideDialog) {
    emit("discard");
    return;
  }
  $dialog({
    title: title,
    message: message,
    onConfirm: ({ hideDialog }: { hideDialog: Function }) => {
      hideDialog();
    },
    actions: [
      {
        label: "Confirm",
        variant: "solid",
        onClick(close: Function) {
          emit("discard");
          close();
        },
      },
    ],
  });
}
</script>

```

## /desk/src/components/EmailArea.vue

```vue path="/desk/src/components/EmailArea.vue" 
<template>
  <div
    v-bind="$attrs"
    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">
      <!-- email design for mobile -->
      <div v-if="isMobileView" class="flex items-center gap-2 text-sm">
        <div class="leading-tight">
          <p>{{ sender.full_name || "No name found" }}</p>
          <Tooltip :text="dateFormat(creation, dateTooltipFormat)">
            <p class="text-xs md:text-sm text-gray-600">
              {{ timeAgo(creation) }}
            </p>
          </Tooltip>
          <p class="sm:flex hidden text-sm text-gray-600" v-if="sender.name">
            {{ "<" + sender.name + ">" }}
          </p>
        </div>
      </div>
      <!-- email design for desktop -->
      <div v-else class="flex items-center gap-2">
        <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)"
          v-if="!isMobileView"
        >
          <p class="text-xs md:text-sm text-gray-600">
            {{ timeAgo(creation) }}
          </p>
        </Tooltip>
        <Button
          variant="ghost"
          class="text-gray-700"
          @click="
            emit('reply', {
              content: content,
              to: sender?.name ?? to,
            })
          "
        >
          <ReplyIcon class="h-4 w-4" />
        </Button>
        <Button
          variant="ghost"
          class="text-gray-700"
          @click="
            emit('reply', {
              content: content,
              to: sender?.name ?? to,
              cc: cc,
              bcc: bcc,
            })
          "
        >
          <ReplyAllIcon class="h-4 w-4" />
        </Button>
        <Dropdown
          v-if="showSplitOption"
          :options="[
            {
              label: 'Split Ticket',
              icon: LucideSplit,
              onClick: () => (showSplitModal = true),
            },
          ]"
        >
          <Button
            icon="more-horizontal"
            class="text-gray-600"
            variant="ghost"
          />
        </Dropdown>
      </div>
    </div>
    <!-- <div class="text-sm leading-5 text-gray-600">
      {{ subject }}
    </div> -->
    <div class="mb-3 text-sm leading-5 text-gray-600">
      <span v-if="to" class="text-2xs mr-1 font-bold text-gray-500">TO:</span>
      <span v-if="to"> {{ to }} </span>
      <span v-if="cc">, </span>
      <span v-if="cc" class="text-2xs mr-1 font-bold text-gray-500"> CC: </span>
      <span v-if="cc">{{ cc }}</span>
      <span v-if="bcc">, </span>
      <span v-if="bcc" class="text-2xs mr-1 font-bold text-gray-500">
        BCC:
      </span>
      <span v-if="bcc">{{ bcc }}</span>
    </div>
    <EmailContent :content="content" />
    <div class="flex flex-wrap gap-2">
      <AttachmentItem
        v-for="a in attachments"
        :key="a.file_url"
        :label="a.file_name"
        :url="a.file_url"
      />
    </div>
  </div>
  <TicketSplitModal
    v-model="showSplitModal"
    :ticket_id="name"
    :communication_id="name"
  />
</template>

<script setup lang="ts">
import { ref } from "vue";
import { AttachmentItem } from "@/components";
import { dateFormat, timeAgo, dateTooltipFormat } from "@/utils";
import { ReplyIcon, ReplyAllIcon } from "./icons";
import LucideSplit from "~icons/lucide/split";
import { useScreenSize } from "@/composables/screen";
import TicketSplitModal from "./ticket/TicketSplitModal.vue";

const props = defineProps({
  activity: {
    type: Object,
    required: true,
  },
  showSplitOption: {
    type: Boolean,
    default: false,
  },
});

const { sender, to, cc, bcc, creation, subject, attachments, content, name } =
  props.activity;

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

const { isMobileView } = useScreenSize();

const showSplitModal = ref(false);

// TODO: Implement reply functionality using this way instead of emit drillup
// function reply(email, reply_all = false) {
//   emailBox.toggleEmailBox();
//   let editor = emailBox.editor;
//   let message = email.content;
//   let recipients = sender.name;
//   editor.toEmails = [email.sender];
//   editor.cc = editor.bcc = false;
//   editor.ccEmails = [];
//   editor.bccEmails = [];
//   console.log(recipients);

//   if (!email.subject.startsWith("Re:")) {
//     editor.subject = `Re: ${email.subject}`;
//   } else {
//     editor.subject = email.subject;
//   }

//   if (reply_all) {
//     let cc = email.cc?.split(",").map((r) => r.trim());
//     let bcc = email.bcc?.split(",").map((r) => r.trim());

//     if (cc?.length) {
//       recipients = recipients.filter((r) => !cc?.includes(r));
//       cc.push(...recipients);
//     } else {
//       cc = recipients;
//     }

//     editor.cc = cc ? true : false;
//     editor.bcc = bcc ? true : false;

//     editor.ccEmails = cc;
//     editor.bccEmails = bcc;
//   }

//   let repliedMessage = `<blockquote>${message}</blockquote>`;

//   editor.editor
//     .chain()
//     .clearContent()
//     .insertContent("<p>.</p>")
//     .updateAttributes("paragraph", { class: "reply-to-content" })
//     .insertContent(repliedMessage)
//     .focus("all")
//     .insertContentAt(0, { type: "paragraph" })
//     .focus("start")
//     .run();
// }
</script>

<style>
.email-content {
  max-width: 100%;
}
.email-content > * {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
}
</style>

```

## /desk/src/components/EmailContent.vue

```vue path="/desk/src/components/EmailContent.vue" 
<template>
  <iframe
    ref="iframeRef"
    :srcdoc="htmlContent"
    class="prose-f block h-10 max-h-[500px] w-full"
  />
</template>

<script setup>
import { ref, watch } from "vue";
import { getFontFamily } from "@/utils";

const props = defineProps({
  content: {
    type: String,
    required: true,
  },
});

const files = import.meta.globEager("/src/index.css", { query: "?inline" });
const css = files["/src/index.css"].default;

const iframeRef = ref(null);
const _content = ref(props.content);

const parser = new DOMParser();
const doc = parser.parseFromString(_content.value, "text/html");

const gmailReplyToContent = doc.querySelectorAll("div.gmail_quote");
const outlookReplyToContent = doc.querySelectorAll("div#appendonsend");
const replyToContent = doc.querySelectorAll("p.reply-to-content");

if (gmailReplyToContent.length) {
  _content.value = parseReplyToContent(doc, "div.gmail_quote", true);
} else if (outlookReplyToContent.length) {
  _content.value = parseReplyToContent(doc, "div#appendonsend");
} else if (replyToContent.length) {
  _content.value = parseReplyToContent(doc, "p.reply-to-content");
}

function parseReplyToContent(doc, selector, forGmail = false) {
  function handleAllInstances(doc) {
    const replyToContentElements = doc.querySelectorAll(selector);
    if (replyToContentElements.length === 0) return;
    const replyToContentElement = replyToContentElements[0];
    replaceReplyToContent(replyToContentElement, forGmail);
    handleAllInstances(doc);
  }

  handleAllInstances(doc);

  return doc.body.innerHTML;
}

function replaceReplyToContent(replyToContentElement, forGmail) {
  if (!replyToContentElement) return;
  let randomId = Math.random().toString(36).substring(2, 7);
  const wrapper = doc.createElement("div");
  wrapper.classList.add("replied-content");

  const collapseLabel = doc.createElement("label");
  collapseLabel.classList.add("collapse");
  collapseLabel.setAttribute("for", randomId);
  collapseLabel.innerHTML = "...";
  wrapper.appendChild(collapseLabel);

  const collapseInput = doc.createElement("input");
  collapseInput.setAttribute("id", randomId);
  collapseInput.setAttribute("class", "replyCollapser");
  collapseInput.setAttribute("type", "checkbox");
  wrapper.appendChild(collapseInput);

  if (forGmail) {
    const prevSibling = replyToContentElement.previousElementSibling;
    if (prevSibling && prevSibling.tagName === "BR") {
      prevSibling.remove();
    }
    let cloned = replyToContentElement.cloneNode(true);
    cloned.classList.remove("gmail_quote");
    wrapper.appendChild(cloned);
  } else {
    const allSiblings = Array.from(
      replyToContentElement.parentElement.children
    );
    const replyToContentIndex = allSiblings.indexOf(replyToContentElement);
    const followingSiblings = allSiblings.slice(replyToContentIndex + 1);

    if (followingSiblings.length === 0) return;

    let clonedFollowingSiblings = followingSiblings.map((sibling) =>
      sibling.cloneNode(true)
    );

    const div = doc.createElement("div");
    div.append(...clonedFollowingSiblings);

    wrapper.append(div);

    // Remove all siblings after the reply-to-content element
    for (let i = replyToContentIndex + 1; i < allSiblings.length; i++) {
      replyToContentElement.parentElement.removeChild(allSiblings[i]);
    }
  }

  replyToContentElement.parentElement.replaceChild(
    wrapper,
    replyToContentElement
  );
}

const htmlContent = `
  <!DOCTYPE html>
  <html>
  <head>
	<style>
	  ${css}
  
	  .replied-content .collapse {
		margin: 10px 0 10px 0;
		visibility: visible;
		cursor: pointer;
		display: flex;
		font-size: larger;
		font-weight: 700;
		height: 12px;
		line-height: 0.1;
		background: #e8eaed;
		width: 23px;
		justify-content: center;
		border-radius: 5px;
	  }
  
	  .replied-content .collapse:hover {
		background: #dadce0;
	  }
  
	  .replied-content .collapse + input {
		display: none;
	  }
	  .replied-content .collapse + input + div {
		display: none;
	  }
	  .replied-content .collapse + input:checked + div {
		display: block;
	  }
  
	  .email-content {
		  word-break: break-word;
	  }
	  .email-content
		  :is(:where(table):not(:where([class~='not-prose'], [class~='not-prose']
			  *))) {
	  table-layout: auto;
	  }
  
	  .email-content
		  :where(table):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
	  width: unset;
	  table-layout: auto;
	  text-align: unset;
	  margin-top: unset;
	  margin-bottom: unset;
	  font-size: unset;
	  line-height: unset;
	  }
  
	  /* tr */
  
	  .email-content
		  :where(tbody tr):not(:where([class~='not-prose'], [class~='not-prose']
			  *)) {
	  border-bottom-width: 0;
	  border-bottom-color: transparent;
	  }
  
	  /* td */
  
	  .email-content
		  :is(:where(td):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
	  position: unset;
	  border-width: 0;
	  border-color: transparent;
	  padding: 0;
	  }
  
	  .email-content
		  :where(tbody td):not(:where([class~='not-prose'], [class~='not-prose']
			  *)) {
	  vertical-align: revert;
	  }
  
	  /* image */
	  .email-content
		  :is(:where(img):not(:where([class~='not-prose'], [class~='not-prose']
			  *))) {
	  border-width: 0;
	  }
  
	  .email-content
		  :where(img):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
	  margin: 0;
	  }
  
	  /* before & after */
  
	  .email-content
		  :where(blockquote
		  p:first-of-type):not(:where([class~='not-prose'], [class~='not-prose']
			  *))::before {
	  content: none;
	  }
  
	  .email-content
		  :where(blockquote
		  p:last-of-type):not(:where([class~='not-prose'], [class~='not-prose']
			  *))::after {
	  content: none;
	  }
	</style>
  </head>
  <body>
	  <div ref="emailContentRef" class="email-content prose-f">${_content.value}</div>
  </body>
  <base target="_blank" />
  </html>
  `;

watch(iframeRef, (iframe) => {
  if (iframe) {
    iframe.onload = () => {
      const emailContent =
        iframe.contentWindow.document.querySelector(".email-content");
      let parent = emailContent.closest("html");
      emailContent.classList.add(getFontFamily(_content.value));
      iframe.style.height = parent.offsetHeight + 1 + "px";

      let replyCollapsers = emailContent.querySelectorAll(".replyCollapser");
      if (replyCollapsers.length) {
        replyCollapsers.forEach((replyCollapser) => {
          replyCollapser.addEventListener("change", () => {
            iframe.style.height = parent.offsetHeight + 1 + "px";
          });
        });
      }
    };
  }
});
</script>

```

## /desk/src/components/EmailEditor.vue

```vue path="/desk/src/components/EmailEditor.vue" 
<template>
  <TextEditor
    ref="editorRef"
    :editor-class="[
      'prose-sm max-w-none mx-10 max-h-[50vh] overflow-y-auto py-3',
      'min-h-[7rem]',
      getFontFamily(newEmail),
    ]"
    :content="newEmail"
    :starterkit-options="{ heading: { levels: [2, 3, 4, 5, 6] } }"
    :placeholder="placeholder"
    :editable="editable"
    @change="editable ? (newEmail = $event) : null"
    :extensions="[PreserveVideoControls]"
  >
    <template #top>
      <div class="mx-10 flex items-center gap-2 border-y py-2.5">
        <span class="text-xs text-gray-500">TO:</span>
        <MultiSelectInput
          v-model="toEmailsClone"
          class="flex-1"
          :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="showCC || cc"
        class="mx-10 flex items-center gap-2 py-2.5"
        :class="cc || showCC ? 'border-b' : ''"
      >
        <span class="text-xs text-gray-500">CC:</span>
        <MultiSelectInput
          ref="ccInput"
          v-model="ccEmailsClone"
          class="flex-1"
          :validate="validateEmail"
          :error-message="(value) => `${value} is an invalid email address`"
        />
      </div>
      <div
        v-if="showBCC || bcc"
        class="mx-10 flex items-center gap-2 py-2.5"
        :class="bcc || showBCC ? 'border-b' : ''"
      >
        <span class="text-xs text-gray-500">BCC:</span>
        <MultiSelectInput
          ref="bccInput"
          v-model="bccEmailsClone"
          class="flex-1"
          :validate="validateEmail"
          :error-message="(value) => `${value} is an invalid email address`"
        />
      </div>
    </template>
    <template #bottom>
      <div class="flex flex-wrap gap-2 px-10">
        <AttachmentItem
          v-for="a in attachments"
          :key="a.file_url"
          :label="a.file_name"
        >
          <template #suffix>
            <FeatherIcon
              class="h-3.5"
              name="x"
              @click.stop="removeAttachment(a)"
            />
          </template>
        </AttachmentItem>
      </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" />
          <div class="flex gap-1">
            <FileUploader
              :upload-args="{
                doctype: doctype,
                docname: modelValue?.name,
                private: true,
              }"
              @success="
                (f) => {
                  attachments.push(f);
                }
              "
            >
              <template #default="{ openFileSelector }">
                <Button variant="ghost" @click="openFileSelector()">
                  <template #icon>
                    <AttachmentIcon
                      class="h-4"
                      style="color: #000000; stroke-width: 1.5 !important"
                    />
                  </template>
                </Button>
              </template>
            </FileUploader>
            <Button
              variant="ghost"
              @click="showCannedResponseSelectorModal = true"
            >
              <template #icon>
                <EmailIcon
                  class="h-4"
                  style="color: #000000; stroke-width: 1.2"
                />
              </template>
            </Button>
          </div>
        </div>
        <div class="mt-2 flex items-center justify-end space-x-2 sm:mt-0">
          <Button label="Discard" @click="handleDiscard" />
          <Button
            variant="solid"
            :disabled="emailEmpty"
            :loading="sendMail.loading"
            label="Send"
            @click="
              () => {
                submitMail();
              }
            "
          />
        </div>
      </div>
    </template>
  </TextEditor>
  <CannedResponseSelectorModal
    v-model="showCannedResponseSelectorModal"
    :doctype="doctype"
    @apply="applyCannedResponse"
  />
</template>

<script setup lang="ts">
import { ref, computed, nextTick } from "vue";
import { useStorage } from "@vueuse/core";
import {
  FileUploader,
  TextEditor,
  TextEditorFixedMenu,
  createResource,
} from "frappe-ui";
import {
  createToast,
  validateEmail,
  textEditorMenuButtons,
  isContentEmpty,
  getFontFamily,
} from "@/utils";
import {
  MultiSelectInput,
  AttachmentItem,
  CannedResponseSelectorModal,
} from "@/components";
import { AttachmentIcon, EmailIcon } from "@/components/icons";
import { PreserveVideoControls } from "@/tiptap-extensions";

const editorRef = ref(null);
const showCannedResponseSelectorModal = ref(false);

const props = defineProps({
  placeholder: {
    type: String,
    default: null,
  },
  editable: {
    type: Boolean,
    default: true,
  },
  doctype: {
    type: String,
    default: "HD Ticket",
  },
  toEmails: {
    type: Array,
    default: () => [],
  },
  ccEmails: {
    type: Array,
    default: () => [],
  },
  bccEmails: {
    type: Array,
    default: () => [],
  },
});
const emit = defineEmits(["submit", "discard"]);
const doc = defineModel();

const newEmail = useStorage("emailBoxContent" + doc.value.name, "");
const attachments = ref([]);
const emailEmpty = computed(() => {
  return isContentEmpty(newEmail.value);
});

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);

function applyCannedResponse(template) {
  newEmail.value = template.message;
  showCannedResponseSelectorModal.value = false;
}

const sendMail = createResource({
  url: "run_doc_method",
  makeParams: () => ({
    dt: props.doctype,
    dn: doc.value.name,
    method: "reply_via_agent",
    args: {
      attachments: attachments.value.map((x) => x.name),
      to: toEmailsClone.value.join(","),
      cc: ccEmailsClone.value?.join(","),
      bcc: bccEmailsClone.value?.join(","),
      message: newEmail.value,
    },
  }),
  onSuccess: () => {
    resetState();
    emit("submit");
  },
  debounce: 300,
});

function submitMail() {
  if (isContentEmpty(newEmail.value)) {
    return;
  }
  if (!toEmailsClone.value.length) {
    createToast({
      text: "Please enter a recipient email address",
      icon: "x",
      iconClasses: "text-red-600",
    });
    return;
  }

  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 removeAttachment(attachment) {
  attachments.value = attachments.value.filter((a) => a !== attachment);
}

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();
}

function resetState() {
  newEmail.value = null;
  attachments.value = [];
}

function handleDiscard() {
  attachments.value = [];
  newEmail.value = null;

  ccEmailsClone.value = [];
  bccEmailsClone.value = [];
  ccEmailsClone.value = [];
  showCC.value = false;
  showBCC.value = false;

  emit("discard");
}

const editor = computed(() => {
  return editorRef.value.editor;
});

defineExpose({
  addToReply,
  editor,
  submitMail,
});
</script>

```

## /desk/src/components/EmptyState.vue

```vue path="/desk/src/components/EmptyState.vue" 
<template>
  <div class="flex h-full items-center justify-center">
    <div
      class="flex flex-col items-center gap-3 text-xl font-medium text-ink-gray-4"
    >
      <!-- Icon -->
      <component v-if="icon" :is="icon" class="h-10 w-10" />
      <!-- title -->
      <span>{{ title }}</span>
      <!-- Button which emits Empty State Action -->
      <Button label="Create" @click="emit('emptyStateAction')" variant="subtle">
        <template #prefix><FeatherIcon name="plus" class="h-4" /></template>
      </Button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { VNode } from "vue";
interface Props {
  title: string;
  icon?: VNode | string;
}

withDefaults(defineProps<Props>(), {
  title: "No Data Found",
  icon: "",
});

const emit = defineEmits(["emptyStateAction"]);
</script>

<style lang="scss" scoped></style>

```

## /desk/src/components/FadedScrollableDiv.vue

```vue path="/desk/src/components/FadedScrollableDiv.vue" 
<template>
  <div
    ref="scrollableDiv"
    :style="`maskImage: ${maskStyle}`"
    @scroll="updateMaskStyle"
  >
    <slot></slot>
  </div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from "vue";

const props = defineProps({
  maskLength: {
    type: Number,
    default: 30,
  },
  orientation: {
    type: String,
    default: "vertical",
  },
});

const scrollableDiv = ref(null);
const maskStyle = ref("none");
const side = computed(() =>
  props.orientation == "horizontal" ? "right" : "bottom"
);

function updateMaskStyle() {
  if (!scrollableDiv.value) return;

  let scrollWidth = scrollableDiv.value.scrollWidth;
  let clientWidth = scrollableDiv.value.clientWidth;
  let scrollHeight = scrollableDiv.value.scrollHeight;
  let clientHeight = scrollableDiv.value.clientHeight;
  let scrollTop = scrollableDiv.value.scrollTop;
  let scrollLeft = scrollableDiv.value.scrollLeft;

  maskStyle.value = "none";

  // faded on both sides
  if (
    (side.value == "right" && scrollWidth > clientWidth) ||
    (side.value == "bottom" && scrollHeight > clientHeight)
  ) {
    maskStyle.value = `linear-gradient(to ${side.value}, transparent, black ${props.maskLength}px, black calc(100% - ${props.maskLength}px), transparent);`;
  }

  // faded on left or top
  if (
    (side.value == "right" && scrollLeft - 20 > clientWidth) ||
    (side.value == "bottom" && scrollTop + clientHeight >= scrollHeight)
  ) {
    maskStyle.value = `linear-gradient(to ${side.value}, transparent, black ${props.maskLength}px, black 100%, transparent);`;
  }

  // faded on right or bottom
  if (
    (side.value == "right" && scrollLeft == 0) ||
    (side.value == "bottom" && scrollTop == 0)
  ) {
    maskStyle.value = `linear-gradient(to ${side.value}, black calc(100% - ${props.maskLength}px), transparent 100%);`;
  }

  if (
    (side.value == "right" && clientWidth == scrollWidth) ||
    (side.value == "bottom" && clientHeight == scrollHeight)
  ) {
    maskStyle.value = "none";
  }
}

onMounted(() => setTimeout(() => updateMaskStyle(), 300));
</script>

```

## /desk/src/components/HistoryBox.vue

```vue path="/desk/src/components/HistoryBox.vue" 
<template>
  <div class="flex-1">
    <div class="mt-1.5 flex justify-between text-base items-center">
      <div class="text-gray-600">
        <span class="font-medium text-gray-800">
          {{ user }}
        </span>
        <span> {{ content }}</span>
      </div>
      <Tooltip :text="dateFormat(creation, dateTooltipFormat)">
        <div class="text-gray-600 text-sm">
          {{ timeAgo(creation) }}
        </div>
      </Tooltip>
    </div>
    <div v-if="show_others && content !== 'created this ticket'">
      <div
        v-for="relatedActivity in relatedActivities"
        :key="relatedActivity.creation"
        class="mt-2 flex justify-between text-base"
      >
        <div class="text-gray-600">
          <span class="font-medium text-gray-800">
            {{ relatedActivity.user }}
          </span>
          <span> {{ relatedActivity.content }}</span>
        </div>
        <Tooltip
          :text="dateFormat(relatedActivity.creation, dateTooltipFormat)"
        >
          <div class="text-gray-600 text-sm">
            {{ timeAgo(relatedActivity.creation) }}
          </div>
        </Tooltip>
      </div>
    </div>
    <Button
      v-if="relatedActivities.length && content !== 'created this ticket'"
      :label="
        show_others ? 'Hide' : `${relatedActivities.length} other activities`
      "
      variant="outline"
      class="mt-2"
      @click="show_others = !show_others"
    >
      <template #suffix>
        <FeatherIcon
          :name="show_others ? 'chevron-up' : 'chevron-down'"
          class="h-4 text-gray-600"
        />
      </template>
    </Button>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { dateFormat, timeAgo, dateTooltipFormat } from "@/utils";

const props = defineProps({
  activity: {
    type: Object,
    required: true,
  },
});

const { user, content, creation, relatedActivities } = props.activity;

let show_others = ref(false);
</script>

```

## /desk/src/components/Icon.vue

```vue path="/desk/src/components/Icon.vue" 
<template>
  <div v-if="isEmoji(icon)" v-bind="$attrs">
    {{ icon }}
  </div>
  <FeatherIcon
    v-else-if="typeof icon == 'string'"
    :name="icon"
    v-bind="$attrs"
  />
  <component v-else :is="icon" v-bind="$attrs" />
</template>
<script setup>
import { isEmoji } from "@/utils";

const props = defineProps({
  icon: {
    type: [String, Object],
    required: true,
  },
});
</script>

```

## /desk/src/components/IconPicker.vue

```vue path="/desk/src/components/IconPicker.vue" 
<template>
  <Popover transition="default">
    <template #target="{ togglePopover, isOpen }">
      <slot v-bind="{ isOpen, togglePopover }">
        <span class="text-base"> {{ modelValue || "" }} </span>
      </slot>
    </template>
    <template #body="{ togglePopover }">
      <div
        v-if="reaction"
        class="px-2 py-1 flex items-center justify-center gap-2 rounded-full bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
      >
        <div
          class="size-5 cursor-pointer rounded-full bg-surface-transparent text-xl"
          v-for="r in reactionEmojis"
          :key="r"
          @click="() => (emoji = r) && togglePopover()"
        >
          <button>
            {{ r }}
          </button>
        </div>
        <Button
          class="rounded-full"
          icon="plus"
          @click.stop="() => (reaction = false)"
        />
      </div>
      <div
        v-else
        class="my-3 max-w-max transform bg-surface-white px-4 sm:px-0"
      >
        <div
          class="relative max-h-96 pb-3 overflow-y-auto min-w-40 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
        >
          <div class="flex gap-2 px-3 pb-1 pt-3">
            <div class="flex-1">
              <FormControl
                type="text"
                placeholder="Search by keyword"
                v-model="search"
                :debounce="300"
              />
            </div>
            <Button @click="setRandom">Random</Button>
          </div>
          <div class="w-96"></div>
          <div class="px-3" v-for="(emojis, group) in emojiGroups" :key="group">
            <div
              class="sticky top-0 bg-surface-modal pb-2 pt-3 text-sm text-ink-gray-7"
            >
              {{ group }}
            </div>
            <div class="grid w-96 grid-cols-12 place-items-center">
              <button
                class="h-8 w-8 rounded-md p-1 text-2xl hover:bg-surface-gray-2 focus:outline-none focus:ring focus:ring-blue-200"
                v-for="_emoji in emojis"
                :key="_emoji.description"
                @click="() => (emoji = _emoji.emoji) && togglePopover()"
                :title="_emoji.description"
              >
                {{ _emoji.emoji }}
              </button>
            </div>
          </div>
        </div>
      </div>
    </template>
  </Popover>
</template>
<script setup>
import { ref, computed } from "vue";
import { Popover } from "frappe-ui";
import { gemoji } from "gemoji";

const search = ref("");
const emoji = defineModel();
const reaction = defineModel("reaction");

const reactionEmojis = ref(["👍", "❤️", "😂", "😮", "😢", "🙏"]);

const emojiGroups = computed(() => {
  let groups = {};
  for (let _emoji of gemoji) {
    if (search.value) {
      let keywords = [_emoji.description, ..._emoji.names, ..._emoji.tags]
        .join(" ")
        .toLowerCase();
      if (!keywords.includes(search.value.toLowerCase())) {
        continue;
      }
    }

    let group = groups[_emoji.category];
    if (!group) {
      groups[_emoji.category] = [];
      group = groups[_emoji.category];
    }
    group.push(_emoji);
  }
  if (!Object.keys(groups).length) {
    groups["No results"] = [];
  }
  return groups;
});

function setRandom() {
  let total = gemoji.length;
  let index = randomInt(0, total - 1);
  emoji.value = gemoji[index].emoji;
}

function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

defineExpose({ setRandom });
</script>

```

## /desk/src/components/LayoutHeader.vue

```vue path="/desk/src/components/LayoutHeader.vue" 
<template>
  <Teleport to="#app-header" v-if="showHeader">
    <slot>
      <header class="flex h-10.5 items-center justify-between mx-4 md:mr-0">
        <div class="flex items-center gap-2 max-w-[50%]">
          <slot name="left-header" />
        </div>
        <div class="flex items-center gap-2">
          <slot name="right-header" class="flex items-center gap-2" />
        </div>
      </header>
    </slot>
  </Teleport>
</template>
<script setup>
import { ref, nextTick } from "vue";
const showHeader = ref(false);

nextTick(() => {
  showHeader.value = true;
});
</script>

```

## /desk/src/components/ListRows.vue

```vue path="/desk/src/components/ListRows.vue" 
<template>
  <div class="mx-3 h-full overflow-y-auto sm:mx-5" v-if="showGroupedRows">
    <div v-for="group in groupedRows" :key="group.group">
      <ListGroupHeader :group="group">
        <div
          class="my-2 flex items-center gap-2 text-base font-medium text-ink-gray-8 justify-between w-full mr-1"
        >
          <div class="flex items-center gap-2 w-full">
            <component v-if="group.icon" :is="group.icon" />
            <div
              v-if="group.group.label != ''"
              class="flex items-center gap-1 w-full"
            >
              <span>{{ group.group.label }}</span>
              <span class="text-xs text-ink-gray-5"
                >{{
                  group.rows.length +
                  " Article" +
                  (group.rows.length > 1 ? "s" : "")
                }}
              </span>
            </div>
          </div>
          <Dropdown :options="actions(group)" v-if="groupByActions.length > 0">
            <Button variant="ghost">
              <template #icon>
                <IconMoreHorizontal class="h-4 w-4" />
              </template>
            </Button>
          </Dropdown>
        </div>
      </ListGroupHeader>
      <ListGroupRows :group="group" id="list-rows" class="!mt-0">
        <ListRow
          v-for="row in group.rows"
          :key="row.name"
          v-slot="{ idx, column, item }"
          :row="row"
          class="truncate text-base row"
        >
          <slot v-bind="{ idx, column, item, row }" />
        </ListRow>
      </ListGroupRows>
    </div>
  </div>
  <ListRows class="mx-3 sm:mx-5" v-else id="list-rows">
    <ListRow
      v-for="row in groupedRows"
      :key="row.name"
      v-slot="{ idx, column, item }"
      :row="row"
      class="truncate text-base"
    >
      <slot v-bind="{ idx, column, item, row }" />
    </ListRow>
  </ListRows>
</template>

<script setup>
import { ref, computed, watch } from "vue";
import {
  ListRows,
  ListRow,
  ListGroupHeader,
  ListGroupRows,
  Dropdown,
  Button,
} from "frappe-ui";

import IconMoreHorizontal from "~icons/lucide/more-horizontal";
const props = defineProps({
  rows: {
    type: Array,
    required: true,
  },
  groupByActions: {
    type: Array,
    default: () => [],
  },
});

const groupedRows = ref(props.rows);

const actions = (group) => {
  let _actions = props.groupByActions.map((action) => {
    return {
      ...action,
      onClick: () => action.onClick(group),
    };
  });
  if (group.group.label == "General") {
    _actions = _actions.filter((action) => action.label === "Add New Article");
  }
  return _actions;
};

watch(
  () => props.rows,
  (val) => (groupedRows.value = val)
);

let showGroupedRows = computed(() => {
  return props.rows.every(
    (row) => row.group && row.rows && Array.isArray(row.rows)
  );
});
</script>

<style></style>

```

## /desk/src/components/MultiSelect.vue

```vue path="/desk/src/components/MultiSelect.vue" 
<template>
  <div class="flex flex-wrap gap-2 rounded-lg bg-gray-100 p-2">
    <Pill
      v-for="item in items"
      :key="item.value"
      :label="item.label"
      @click="(i) => remove(i)"
    />

    <Input
      v-model="input"
      class="w-full"
      :placeholder="placeholder"
      @keyup.enter="add({ label: input, value: input })"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, toRefs } from "vue";
import { Input } from "frappe-ui";
import { createToast } from "@/utils";
import Pill from "./Pill.vue";

type Item = {
  label: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  value: any;
};

const props = defineProps({
  items: {
    type: Array<Item>,
    required: true,
  },
  placeholder: {
    type: String,
    required: false,
    default: "Type...",
  },
  validate: {
    type: Function,
    required: false,
    default: () => false,
  },
});

const emit = defineEmits<{
  (event: "update:items", items: Array<Item>): void;
}>();

const { items } = toRefs(props);
const input = ref("");

function add(item: Item) {
  const err = props.validate(item);

  if (err) {
    createToast({
      title: err,
      icon: "x",
      iconClasses: "text-red-500",
    });

    return;
  }

  const res = [...items.value, item];
  emit("update:items", res);
  input.value = "";
}

function remove(item: Item) {
  const res = items.value.filter((i) => i.value !== item);
  emit("update:items", res);
}
</script>

```

## /desk/src/components/MultiSelectInput.vue

```vue path="/desk/src/components/MultiSelectInput.vue" 
<template>
  <div>
    <div class="flex flex-wrap gap-1">
      <Button
        v-for="value in values"
        ref="emails"
        :key="value"
        :label="value"
        theme="gray"
        variant="subtle"
        class="rounded-full"
        @keydown.delete.capture.stop="removeLastValue"
      >
        <template #suffix>
          <FeatherIcon
            class="h-3.5"
            name="x"
            @click.stop="removeValue(value)"
          />
        </template>
      </Button>
      <div class="flex-1">
        <Combobox v-model="selectedValue" nullable>
          <Popover v-model:show="showOptions" class="w-full">
            <template #target="{ togglePopover }">
              <ComboboxInput
                ref="search"
                class="search-input form-input w-full border-none bg-white hover:bg-white focus:border-none focus:!shadow-none focus-visible:!ring-0"
                type="text"
                :value="query"
                autocomplete="off"
                @change="
                  (e) => {
                    query = e.target.value;
                    showOptions = true;
                  }
                "
                @focus="() => togglePopover()"
                @keydown.delete.capture.stop="removeLastValue"
              />
            </template>
            <template #body="{ isOpen }">
              <div v-show="isOpen">
                <div class="mt-1 rounded-lg bg-white py-1 text-base shadow-2xl">
                  <ComboboxOptions
                    class="my-1 max-h-[12rem] overflow-y-auto px-1.5"
                    static
                  >
                    <ComboboxOption
                      v-for="option in options"
                      :key="option.value"
                      v-slot="{ active }"
                      :value="option"
                    >
                      <li
                        :class="[
                          'flex cursor-pointer items-center rounded px-2 py-1 text-base',
                          { 'bg-gray-100': active },
                        ]"
                      >
                        <UserAvatar
                          class="mr-2"
                          :name="option.value"
                          size="lg"
                        />
                        <div class="flex flex-col gap-1 p-1 text-gray-800">
                          <div class="text-base font-medium">
                            {{ option.label }}
                          </div>
                          <div class="text-sm text-gray-600">
                            {{ option.value }}
                          </div>
                        </div>
                      </li>
                    </ComboboxOption>
                  </ComboboxOptions>
                </div>
              </div>
            </template>
          </Popover>
        </Combobox>
      </div>
    </div>
    <ErrorMessage v-if="error" class="mt-2 pl-2" :message="error" />
  </div>
</template>

<script setup lang="ts">
import {
  Combobox,
  ComboboxInput,
  ComboboxOptions,
  ComboboxOption,
} from "@headlessui/vue";
import { UserAvatar } from "@/components/";
import { Popover, createResource } from "frappe-ui";
import { ref, computed, nextTick } from "vue";
import { watchDebounced } from "@vueuse/core";

const props = defineProps({
  validate: {
    type: Function,
    default: null,
  },
  errorMessage: {
    type: Function,
    default: (value) => `${value} is an Invalid value`,
  },
});

const values = defineModel();

const emails = ref([]);
const search = ref(null);
const error = ref(null);
const query = ref("");
const text = ref("");
const showOptions = ref(false);

const selectedValue = computed({
  get: () => query.value || "",
  set: (val) => {
    query.value = "";
    if (val) {
      showOptions.value = false;
    }
    val?.value && addValue(val.value);
  },
});

watchDebounced(
  query,
  (val) => {
    val = val || "";
    if (text.value === val) return;
    text.value = val;
    reload(val);
  },
  { debounce: 300, immediate: true }
);

const filterOptions = createResource({
  url: "frappe.desk.search.search_link",
  method: "POST",
  cache: [text.value, "Contact"],
  params: {
    txt: text.value,
    doctype: "Contact",
  },
  transform: (data) => {
    let allData = data
      .filter((c) => {
        return c.description.split(", ")[1];
      })
      .map((option) => {
        let email = option.description.split(", ")[1];
        return {
          label: option.label || email,
          value: email,
        };
      });
    return allData;
  },
});

const options = computed(() => {
  let searchedContacts = filterOptions.data || [];
  if (!searchedContacts.length && query.value) {
    searchedContacts.push({
      label: query.value,
      value: query.value,
    });
  }
  return searchedContacts;
});

function reload(val) {
  filterOptions.update({
    params: {
      txt: val,
      doctype: "Contact",
    },
  });
  filterOptions.reload();
}

const addValue = (value) => {
  error.value = null;
  if (value) {
    const splitValues = value.split(",");
    splitValues.forEach((value) => {
      value = value.trim();
      if (value) {
        // check if value is not already in the values array
        if (!values.value?.includes(value)) {
          // check if value is valid
          if (value && props.validate && !props.validate(value)) {
            error.value = props.errorMessage(value);
            return;
          }
          // add value to values array
          if (!values.value) {
            values.value = [value];
          } else {
            values.value.push(value);
          }
          value = value.replace(value, "");
        }
      }
    });
    !error.value && (value = "");
  }
};

const removeValue = (value) => {
  values.value = values.value.filter((v) => v !== value);
};

const removeLastValue = () => {
  if (query.value) return;

  let emailRef = emails.value[emails.value.length - 1]?.$el;
  if (document.activeElement === emailRef) {
    values.value.pop();
    nextTick(() => {
      if (values.value.length) {
        emailRef = emails.value[emails.value.length - 1].$el;
        emailRef?.focus();
      } else {
        setFocus();
      }
    });
  } else {
    emailRef?.focus();
  }
};

function setFocus() {
  search.value.$el.focus();
}

defineExpose({ setFocus });
</script>

```

## /desk/src/components/NestedPopover.vue

```vue path="/desk/src/components/NestedPopover.vue" 
<template>
  <Popover v-slot="{ open }">
    <PopoverButton
      ref="reference"
      v-slot="{ open: o }"
      as="div"
      @click="updatePosition"
      @focusin="updatePosition"
      @keydown="updatePosition"
    >
      <slot name="target" :open="o" />
    </PopoverButton>
    <div v-show="open">
      <PopoverPanel
        v-slot="{ open: o, close }"
        ref="popover"
        static
        class="z-[100]"
      >
        <slot name="body" :open="o" :close="close" />
      </PopoverPanel>
    </div>
  </Popover>
</template>

<script setup>
import { nextTick, ref, onBeforeUnmount } from "vue";
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/vue";
import { createPopper } from "@popperjs/core";

const props = defineProps({
  placement: {
    type: String,
    default: "bottom-start",
  },
});

const reference = ref(null);
const popover = ref(null);

let popper = ref(null);

function setupPopper() {
  if (!popper.value) {
    popper.value = createPopper(reference.value.el, popover.value.el, {
      placement: props.placement,
    });
  } else {
    popper.value.update();
  }
}

function updatePosition() {
  nextTick(() => setupPopper());
}

onBeforeUnmount(() => {
  popper.value?.destroy();
});
</script>

```

## /desk/src/components/canned-response/index.js

```js path="/desk/src/components/canned-response/index.js" 
export { default as CannedResponseModal } from "./CannedResponseModal.vue";

```

## /desk/src/composables/index.ts

```ts path="/desk/src/composables/index.ts" 
export { useDevice } from "./device";

```

## /helpdesk/modules.txt

Helpdesk



The content has been capped at 50000 tokens. The user could consider applying other filters to refine the result. The better and more specific the context, the better the LLM can follow instructions. If the context seems verbose, the user can refine the filter using uithub. Thank you for using https://uithub.com - Perfect LLM context for any GitHub repo.
Copied!